<commit_before>import { get, getPath, id, noop, overload, Stream, toType, Observable as ObservableStream } from '../../fn/fn.js';
import { append, before, clone, empty, fragmentFromHTML, fragmentFromId, parse, remove } from '../../dom/dom.js';
import { cue } from './frame.js';
import Sparky from './sparky.js';

var DEBUG   = false;
var axios   = window.axios;
var jQuery  = window.jQuery;

var assign  = Object.assign;
var fetch   = window.fetch;
var getData = get('data');
var parseHTML = parse('html');

var cache   = {
    '': {
        '': document
    }
};

var request = axios ? function axiosRequest(url, id) {
    return axios
    .get(url, { responseType: 'document' })
    .then(getData);
} :

// TODO test these functions

jQuery ? function jQueryRequest(url, id) {
    return jQuery
    .get(url)
    .then(getData)
    .then(parseHTML);
} :

fetch ? function fetchRequest(url, id) {
    return fetch(url)
    .then(getData)
    .then(parseHTML);
} :

function errorRequest(url, id) {
    throw new Error('Sparky: no axios, jQuery or fetch found for request "' + url + '"');
} ;

function insertTemplate(sparky, node, scopes, id, template) {
    if (!template) {
        throw new Error('Sparky: template ' + id + ' not found.');
    }

    var run = function first() {
        run = noop;
        var fragment = clone(template);
        empty(node);
        append(node, fragment);
        if (DEBUG) { console.log('Sparky fn=template:', node); }
        sparky.continue();
    };

    var stream = Stream.of();

    scopes.each(function(scope) {
        cue(function() {
            run();
            stream.push(scope);
        });
    });

    return stream;
}

function templateFromCache(sparky, node, scopes, path, id) {
    var doc, elem;
    var template = cache[path][id];

    if (!template) {
        doc  = cache[path][''];

        if (id === '') {
            elem = doc.body;
            template = elem && fragmentFromHTML(elem.innerHTML) ;

        }
        else {
            elem = doc.getElementById(id);
            template = cache[path][id] = doc === document ?
                fragmentFromId(id) :
                elem && fragmentFromHTML(elem.innerHTML) ;
        }
    }

    return insertTemplate(sparky, node, scopes, id, template);
}

function templateFromCache2(sparky, node, scopes, path, id, template) {
    var doc, elem;

    if (!template) {
        doc  = cache[path][''];
        elem = doc.getElementById(id);

        template = cache[path][id] = doc === document ?
            fragmentFromId(id) :
            elem && fragmentFromHTML(elem.innerHTML) ;
    }

    if (!template) {
        throw new Error('Sparky: template ' + id + ' not found.');
    }

    //return scopes.tap(function(scope) {
        var fragment = clone(template);
        empty(node);
        append(node, fragment);
        sparky.continue();
    //});
}

function templateFromDocument(sparky, node, scopes, path, id) {
    var stream = Stream.of();

    request(path)
    .then(function(doc) {
        if (!doc) {
            console.warn('Template not found.');
            return;
        }
        var tapped = templateFromDocument2(sparky, node, scopes, path, id, doc);
        sparky.continue();
        tapped.each(stream.push);
    })
    .catch(function(error) {
        console.warn(error);
    });

    return stream;
}

function templateFromDocument2(sparky, node, scopes, path, id, doc) {
    var template, elem;

    cache[path] = { '': doc };

    if (id) {
        elem = doc.getElementById(id);
        template = cache[path][id] = elem && fragmentFromHTML(elem.innerHTML);
    }
    else {
        template = cache[path][id] = fragmentFromHTML(doc.body.innerHTML);
    }

    return insertTemplate(sparky, node, scopes, id, template);
}

assign(Sparky.fn, {
    template: function(node, scopes, params) {
        var name = params[0];
        var parts, path, hash, stop;

        // If name is not a URL assume it's a path and get html from scope
        if (!/^\.?[#\/]/.test(name)) {
            stop = noop;

            return scopes.map(function(scope) {
                stop();

                stop = ObservableStream(name, scope)
                .map(overload(toType, {
                    string:  fragmentFromHTML,
                    default: id
                }))
                .each(function(fragment) {
                    empty(node);
                    append(node, fragment);
                })
                .stop;
            });
        }

        // Parse urls
        parts = name.split('#');
        path  = parts[0] || '';
        hash  = parts[1] || '';

        if (DEBUG && !hash) {
            throw new Error('Sparky: ' + Sparky.attributePrefix + 'fn="template:url" requires a url with a hash ref. "' + name + '"');
        }

        var sparky = this;
        sparky.interrupt();

        // If the resource is cached, return it as an shiftable
        return cache[path] ?
            templateFromCache(sparky, node, scopes, path, hash) :
            templateFromDocument(sparky, node, scopes, path, hash) ;
    },

    replace: function(node, scopes, params) {
        var name = params[0];
        var parts, path, hash, stop;

        // If name is not a URL assume it's a path and get html from scope
        if (!/#/.test(name)) {
            stop = noop;

            return scopes.map(function(scope) {
                stop();

                stop = ObservableStream(name, scope)
                .map(overload(toType, {
                    string:  fragmentFromHTML,
                    default: id
                }))
                .each(function(fragment) {
                    before(node, fragment);
                    remove(node);
                })
                .stop;
            });
        }

        parts = name.split('#');
        path  = parts[0] || '';
        hash  = parts[1] || '';

        if (DEBUG && !hash) {
            throw new Error('Sparky: ' + Sparky.attributePrefix + 'fn="template:url" requires a url with a hash ref. "' + name + '"');
        }

        var sparky = this;
        sparky.interrupt();

        // If the resource is cached, return it as an shiftable
        return cache[path] ?
            templateFromCache(sparky, node, scopes, path, hash) :
            templateFromDocument(sparky, node, scopes, path, hash) ;
    },

    // TODO: Do this, but better

    'template-from': function(node, scopes, params) {
        var string = params[0];
        var sparky = this;
        var outputScopes = Stream.of();
        sparky.interrupt();

        if (/\$\{([\w._]+)\}/.test(string)) {
            scopes.each(function(scope) {
                var notParsed = false;
                var url = string.replace(/\$\{([\w._]+)\}/g, function($0, $1) {
                    var value = getPath($1, scope);
                    if (value === undefined) { notParsed = true; }
                    return value;
                });

                if (notParsed) {
                    console.log('Sparky: template-from not properly assembled from scope', string, scope);
                    return;
                }

                var parts = url.split('#');
                var path  = parts[0] || '';
                var id    = parts[1] || '';

                if (DEBUG && !id) {
                    throw new Error('Sparky: ' + Sparky.attributePrefix + 'fn="template:url" requires a url with a hash ref. "' + url + '"');
                }

                // If the resource is cached, return it as an shiftable
                if (cache[path]) {
                    templateFromCache2(sparky, node, scopes, path, id, cache[path][id]);
                    outputScopes.push(scope);
                }
                else {
                    request(path)
                    .then(function(doc) {
                        if (!doc) { return; }
                        templateFromDocument(sparky, node, scopes, path, id, doc);
                    })
                    .catch(function(error) {
                        console.warn(error);
                    });
                }
            });

            return outputScopes;
        }

        throw new Error('Sparky: template-from must have ${prop} in the url string');
    }
});
<commit_msg>fn.template accepts multiple template ids<commit_after>import { cache as cacheRequest, get, getPath, id, noop, overload, Stream, toType, Observable as ObservableStream } from '../../fn/fn.js';
import { append, before, clone, empty, fragmentFromHTML, fragmentFromId, parse, remove } from '../../dom/dom.js';
import { cue } from './frame.js';
import Sparky from './sparky.js';

var DEBUG   = true;
var axios   = window.axios;
var jQuery  = window.jQuery;

var assign  = Object.assign;
var fetch   = window.fetch;
var getData = get('data');
var parseHTML = parse('html');

var cache   = {
    '': {
        '': document
    }
};

var request = axios ? function axiosRequest(url, id) {
    return axios
    .get(url, { responseType: 'document' })
    .then(getData);
} :

// TODO test these functions

jQuery ? function jQueryRequest(url, id) {
    return jQuery
    .get(url)
    .then(getData)
    .then(parseHTML);
} :

fetch ? function fetchRequest(url, id) {
    return fetch(url)
    .then(getData)
    .then(parseHTML);
} :

function errorRequest(url, id) {
    throw new Error('Sparky: no axios, jQuery or fetch found for request "' + url + '"');
} ;

function insertTemplate(sparky, node, scopes, id, template) {
    if (!template) {
        throw new Error('Sparky: template ' + id + ' not found.');
    }

    var run = function first() {
        run = noop;
        var fragment = clone(template);
        append(node, fragment);
        if (DEBUG) { console.log('Sparky fn=template:', node); }
        sparky.continue();
    };

    var stream = Stream.of();

    scopes.each(function(scope) {
        cue(function() {
            run();
            stream.push(scope);
        });
    });

    return stream;
}

function templateFromCache(sparky, node, scopes, path, id) {
    var doc, elem;
    var template = cache[path][id];

    if (!template) {
        doc = cache[path][''];

        if (id === '') {
            elem = doc.body;
            template = elem && fragmentFromHTML(elem.innerHTML) ;
        }
        else {
            elem = doc.getElementById(id);
            template = cache[path][id] = doc === document ?
                fragmentFromId(id) :
                elem && fragmentFromHTML(elem.innerHTML) ;
        }
    }

    empty(node);
    return insertTemplate(sparky, node, scopes, id, template);
}

function templateFromCache2(sparky, node, scopes, path, id, template) {
    var doc, elem;

    if (!template) {
        doc  = cache[path][''];
        elem = doc.getElementById(id);

        template = cache[path][id] = doc === document ?
            fragmentFromId(id) :
            elem && fragmentFromHTML(elem.innerHTML) ;
    }

    if (!template) {
        throw new Error('Sparky: template ' + id + ' not found.');
    }

    //return scopes.tap(function(scope) {
        var fragment = clone(template);
        empty(node);
        append(node, fragment);
        sparky.continue();
    //});
}

function templateFromDocument(sparky, node, scopes, path, id) {
    var stream = Stream.of();

    request(path)
    .then(function(doc) {
        if (!doc) {
            console.warn('Template not found.');
            return;
        }
        var tapped = templateFromDocument2(sparky, node, scopes, path, id, doc);
        sparky.continue();
        tapped.each(stream.push);
    })
    .catch(function(error) {
        console.warn(error);
    });

    return stream;
}

function templateFromDocument2(sparky, node, scopes, path, id, doc) {
    var template, elem;

    cache[path] = { '': doc };

    if (id) {
        elem = doc.getElementById(id);
        template = cache[path][id] = elem && fragmentFromHTML(elem.innerHTML);
    }
    else {
        template = cache[path][id] = fragmentFromHTML(doc.body.innerHTML);
    }

    return insertTemplate(sparky, node, scopes, id, template);
}

assign(Sparky.fn, {
    replace: function(node, scopes, params) {
        var name = params[0];
        var parts, path, hash, stop;

        // If name is not a URL assume it's a path and get html from scope
        if (!/#/.test(name)) {
            stop = noop;

            return scopes.map(function(scope) {
                stop();

                stop = ObservableStream(name, scope)
                .map(overload(toType, {
                    string:  fragmentFromHTML,
                    default: id
                }))
                .each(function(fragment) {
                    before(node, fragment);
                    remove(node);
                })
                .stop;
            });
        }

        parts = name.split('#');
        path  = parts[0] || '';
        hash  = parts[1] || '';

        if (DEBUG && !hash) {
            throw new Error('Sparky: ' + Sparky.attributePrefix + 'fn="template:url" requires a url with a hash ref. "' + name + '"');
        }

        var sparky = this;
        sparky.interrupt();

        // If the resource is cached, return it as an shiftable
        return cache[path] ?
            templateFromCache(sparky, node, scopes, path, hash) :
            templateFromDocument(sparky, node, scopes, path, hash) ;
    },

    // TODO: Do this, but better

    'template-from': function(node, scopes, params) {
        var string = params[0];
        var sparky = this;
        var outputScopes = Stream.of();
        sparky.interrupt();

        if (/\$\{([\w._]+)\}/.test(string)) {
            scopes.each(function(scope) {
                var notParsed = false;
                var url = string.replace(/\$\{([\w._]+)\}/g, function($0, $1) {
                    var value = getPath($1, scope);
                    if (value === undefined) { notParsed = true; }
                    return value;
                });

                if (notParsed) {
                    console.log('Sparky: template-from not properly assembled from scope', string, scope);
                    return;
                }

                var parts = url.split('#');
                var path  = parts[0] || '';
                var id    = parts[1] || '';

                if (DEBUG && !id) {
                    throw new Error('Sparky: ' + Sparky.attributePrefix + 'fn="template:url" requires a url with a hash ref. "' + url + '"');
                }

                // If the resource is cached, return it as an shiftable
                if (cache[path]) {
                    templateFromCache2(sparky, node, scopes, path, id, cache[path][id]);
                    outputScopes.push(scope);
                }
                else {
                    request(path)
                    .then(function(doc) {
                        if (!doc) { return; }
                        templateFromDocument(sparky, node, scopes, path, id, doc);
                    })
                    .catch(function(error) {
                        console.warn(error);
                    });
                }
            });

            return outputScopes;
        }

        throw new Error('Sparky: template-from must have ${prop} in the url string');
    }
});

// --------------------------------------------

const documentRequest = Promise.resolve(document);
const fetchDocument = cacheRequest(function fetchDocument(path) {
    return path ?
        request(path)
        .then(function(doc) {
            if (!doc) {
                console.warn('Template not found.');
                return;
            }

            return doc;
        })
        .catch(function(error) {
            console.warn(error);
        }) :
        documentRequest ;
});

function urlToFragment(name) {
    // Parse urls
    const parts = name.split('#');
    const path  = parts[0] || '';
    const id    = parts[1] || '';

    return fetchDocument(path)
    .then(function(doc) {
        let elem;

        if (id) {
            elem = doc.getElementById(id);

            if (DEBUG && !elem) {
                throw new Error('Sparky: ' + Sparky.attributePrefix + 'fn="template:url" id "' + id + '" not found in document "' + path + '"');
            }

            return elem && elem.content ?
                clone(elem.content) :
                fragmentFromHTML(elem.innerHTML);
        }
        else {
            return fragmentFromHTML(doc.body.innerHTML);
        }
    });
}

assign(Sparky.fn, {
    template: function(node, scopes, params) {
        var sparky = this;
        var stop;

        // If name is not a URL assume it's a path and get html from scope
        if (!/^\.?[#\/]/.test(params[0])) {
            stop = noop;

            return scopes.map(function(scope) {
                stop();

                stop = ObservableStream(params[0], scope)
                .map(overload(toType, {
                    string:  fragmentFromHTML,
                    default: id
                }))
                .each(function(fragment) {
                    empty(node);
                    append(node, fragment);
                })
                .stop;
            });
        }

        const output = Stream.of();
        sparky.interrupt();

        // Params is a list of URLs
        Promise
        .all(params.map(urlToFragment))
        .then(function(templates) {
            let run = function first() {
                run = noop;
                empty(node);
                templates.forEach(append(node));
                sparky.continue();
            };

            scopes.each(function(scope) {
                cue(function() {
                    run();
                    output.push(scope);
                });
            });
        });

        return output;
    }
});
<|endoftext|>


<commit_before>FT.Helpers = (function() {

  return {

  }
});<commit_msg>removed empty helpers.js library<commit_after><|endoftext|>


<commit_before>var runInterval;

function assemble() {
	processor.text = [];
	program.data = [];
	program.labels = {};
	processor.reset();

	textarea = document.getElementById("code");
	programCode = program.stripWhiteSpace(textarea.innerText);
	program.readCode(program.splitLines(program.stripComments(programCode)));
	processor.loadProgram(program);
	showInstructions();
	addLineNumbers();
	instructionsList = document.getElementById("instructions");
	instructionsList.children[processor.programCounter].style["backgroundColor"]="hsl(120,27%,90%)";
	codeDiv = document.getElementById("code");
	codeDiv.children[processor.text[processor.programCounter].lineNum].style["backgroundColor"]="hsl(120,27%,90%)";

};

function showInstructions() {
	instructionsList = document.getElementById("instructions");
	while(instructionsList.lastElementChild!=null) {
		instructionsList.lastElementChild.remove();
	}
	for(ii in processor.text) {
		instr = processor.text[ii];
		instructionsList.appendChild(document.createElement("li"));
		instructionsList.lastChild.innerText = instr.op+ " " + instr.params.join(", ") + " (on line " + instr.lineNum.toString()+ ")";
	}
};

function showRegisters() {
	registersList = document.getElementById("registers");
	for(ii in processor.registers) {
		reg = processor.registers[ii];
		registersList.appendChild(document.createElement("tr"));
		registersList.lastChild.appendChild(document.createElement("td"));
		registersList.lastChild.lastChild.innerText = ii;
		registersList.lastChild.appendChild(document.createElement("td"));

		registersList.lastChild.lastChild.innerText = "abd";
		/*if(processor.registerNames[ii]!=undefined) {
			registersList.lastChild.lastChild.innerText = processor.registerNames[ii];
		}*/

		registersList.lastChild.appendChild(document.createElement("td"));
		registersList.lastChild.lastChild.innerText = processor.registers[ii];
	}
};

function updateRegisters () {
	registersList = document.getElementById("registers").lastChild;
	for(ii in registersList.childNodes) {
		if (registersList.children[ii]&&registersList.children[ii].children!=undefined) {
			registersList.children[ii].children[2].innerText = processor.registers[ii];
		}
	}
};

function addLineNumbers() {
	textarea = document.getElementById("code");
	lineNumbers = document.getElementById("lineNumbers");
	lineNumbers.innerText = "";
	for (i = 0; i < textarea.innerText.match(/$/gm).length; i++) {
		lineNumbers.innerText = lineNumbers.innerText+i+"\n";
	}
};

function runStep() {
	if(!processor.running) return;

	instructionsList = document.getElementById("instructions");
	codeDiv = document.getElementById("code");
	instructionsList.children[processor.programCounter].style["backgroundColor"]="white";
	codeDiv.children[processor.text[processor.programCounter].lineNum].style["backgroundColor"]="white";
	processor.runInstr();

	if(!processor.running) return;

	updateRegisters();
	codeDiv.children[processor.text[processor.programCounter].lineNum].style["backgroundColor"]="hsl(120,27%,90%)";
	instructionsList.children[processor.programCounter].style["backgroundColor"]="hsl(120,27%,90%)";
	codeDiv.children[processor.text[processor.programCounter].lineNum].scrollIntoViewIfNeeded();
};

function resume(interval) {
	runInterval = window.setInterval(runStep, interval);
};

function pause() {
	window.clearInterval(runInterval);
};

updateRegisters();

codeBox = document.getElementById("code");
console.log(codeBox);
codeBox.onkeyup = addLineNumbers;
codeBox.onpaste = function(){console.log("a")};

<commit_msg>Removed code that was causing crash.<commit_after>var runInterval;

function assemble() {
	processor.text = [];
	program.data = [];
	program.labels = {};
	processor.reset();

	textarea = document.getElementById("code");
	programCode = program.stripWhiteSpace(textarea.innerText);
	program.readCode(program.splitLines(program.stripComments(programCode)));
	processor.loadProgram(program);
	showInstructions();
	addLineNumbers();
	instructionsList = document.getElementById("instructions");
	instructionsList.children[processor.programCounter].style["backgroundColor"]="hsl(120,27%,90%)";
	codeDiv = document.getElementById("code");

};

function showInstructions() {
	instructionsList = document.getElementById("instructions");
	while(instructionsList.lastElementChild!=null) {
		instructionsList.lastElementChild.remove();
	}
	for(ii in processor.text) {
		instr = processor.text[ii];
		instructionsList.appendChild(document.createElement("li"));
		instructionsList.lastChild.innerText = instr.op+ " " + instr.params.join(", ") + " (on line " + instr.lineNum.toString()+ ")";
	}
};

function showRegisters() {
	registersList = document.getElementById("registers");
	for(ii in processor.registers) {
		reg = processor.registers[ii];
		registersList.appendChild(document.createElement("tr"));
		registersList.lastChild.appendChild(document.createElement("td"));
		registersList.lastChild.lastChild.innerText = ii;
		registersList.lastChild.appendChild(document.createElement("td"));

		registersList.lastChild.lastChild.innerText = "abd";
		/*if(processor.registerNames[ii]!=undefined) {
			registersList.lastChild.lastChild.innerText = processor.registerNames[ii];
		}*/

		registersList.lastChild.appendChild(document.createElement("td"));
		registersList.lastChild.lastChild.innerText = processor.registers[ii];
	}
};

function updateRegisters () {
	registersList = document.getElementById("registers").lastChild;
	for(ii in registersList.childNodes) {
		if (registersList.children[ii]&&registersList.children[ii].children!=undefined) {
			registersList.children[ii].children[2].innerText = processor.registers[ii];
		}
	}
};

function addLineNumbers() {
	textarea = document.getElementById("code");
	lineNumbers = document.getElementById("lineNumbers");
	lineNumbers.innerText = "";
	for (i = 0; i < textarea.innerText.match(/$/gm).length; i++) {
		lineNumbers.innerText = lineNumbers.innerText+i+"\n";
	}
};

function runStep() {
	if(!processor.running) return;

	instructionsList = document.getElementById("instructions");
	codeDiv = document.getElementById("code");
	instructionsList.children[processor.programCounter].style["backgroundColor"]="white";
	processor.runInstr();

	if(!processor.running) return;

	updateRegisters();
	instructionsList.children[processor.programCounter].style["backgroundColor"]="hsl(120,27%,90%)";
};

function resume(interval) {
	runInterval = window.setInterval(runStep, interval);
};

function pause() {
	window.clearInterval(runInterval);
};

updateRegisters();

codeBox = document.getElementById("code");
console.log(codeBox);
codeBox.onkeyup = addLineNumbers;
codeBox.onpaste = function(){console.log("a")};

<|endoftext|>


<commit_before>var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(__dirname + '/db/words.db');

exports.get = function(string, callback) {
  var output = {
    words: [],
    score_total: 0
  };

  var words = [],
      set = [];

  // start timing
  var start = process.hrtime();

  // generate power set
  power(string)
    .forEach(function(element) {
      if(element.length > 1)
        set.push(element.join(''));
    });

  // permutate
  set = set.map(permute);

  // flatten
  for(var i = 0; i < set.length; i++)
    for(var j = 0; j < set[i].length; j++)
      words.push(set[i][j]);

  // remove duplicates
  words = uniq_fast(words);

  // logic exec time
  end = process.hrtime(start);
  var logic_time = end.pop() / 1000000000 + end.pop();

  var query = 'SELECT word, score FROM words WHERE word IN ("' + words.join('", "') + '")';
  db.each(query, function(error, row) {
    if(error)
      throw error;

    if(!row)
      return;

    output.words.push({
      word: row.word,
      score: row.score
    });

    output.score_total += row.score;
  }, function(error, num_rows) {
    // fraction of combinations being valid words
    output.fraction = num_rows / words.length;

    // total exec time
    end = process.hrtime(start);
    var total_time = end.pop() / 1000000000 + end.pop();

    output.query_time = total_time - logic_time;
    output.logic_time = logic_time;

    callback(null, output);

    db.close();
  });
};

// helper to remove duplicates from array
function uniq_fast(a) {
  var seen = {};
  var out = [];
  var len = a.length;
  var j = 0;
  for(var i = 0; i < len; i++) {
    var item = a[i];
    if(seen[item] !== 1) {
      seen[item] = 1;
      out[j++] = item;
    }
  }
  return out;
}

// helper to generate a power set
function power(set) {
	return [].slice.call(set).reduce(
		function(previous, current) {
      var copy = previous.slice(0);
			copy.forEach(function(e) {
				var e2 = e.slice(0);
				e2.push(current);
				previous.push(e2);
			});
			return previous;
		},
		[[]]
	);
}

// helper to generate string permutations
function permute(str){
  var words = [];

  function rearrange(str, prefix) {
    var i, singleChar, balanceStr, word;

    //The first time round, prefix will be empty
    prefix = prefix || '';

    //Loop over the str to separate each single character
    //from the rest of it's characters
    for(i = 0; i < str.length; i++) {
      singleChar = str[i];
      balanceStr = str.slice(0, i) + str.slice(i+1);

      //join the prefix with each of the combinations
      word = prefix + singleChar + balanceStr;

      //Inject this word only if it does not exist
      if(words.indexOf(word) < 0)
        words.push(word);

      //Recursively call this function in case there are balance characters
      if(balanceStr.length > 1)
        rearrange(balanceStr, prefix + singleChar);
    }
  }

  //kick start recursion
  rearrange(str);
  return words;
}<commit_msg>cleanup<commit_after>var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(__dirname + '/db/words.db');

exports.get = function(string, callback) {
  var output = {
    words: [],
    score_total: 0
  };

  var words = [],
      set = [];

  // start timing
  var start = process.hrtime();

  // generate power set with permutations
  power(string).forEach(function(element) {
    if(element.length > 1)
      set.push(permute(element.join('')));
  });

  // flatten set
  for(var i = 0; i < set.length; i++)
    for(var j = 0; j < set[i].length; j++)
      words.push(set[i][j]);

  // remove duplicates
  words = unique(words);

  // logic exec time
  end = process.hrtime(start);
  var logic_time = end.pop() / 1000000000 + end.pop();

  var query = 'SELECT word, score FROM words WHERE word IN ("' + words.join('", "') + '")';
  db.each(query, function(error, row) {
    if(error)
      throw error;

    // not found
    if(!row)
      return;

    output.words.push({
      word: row.word,
      score: row.score
    });

    output.score_total += row.score;
  }, function(error, num_rows) {
    if(error)
      throw error;

    // fraction of combinations being valid words
    output.fraction = num_rows / words.length;

    // total exec time
    end = process.hrtime(start);
    var total_time = end.pop() / 1000000000 + end.pop();

    output.query_time = total_time - logic_time;
    output.logic_time = logic_time;

    callback(null, output);

    db.close();
  });
};

// helper to remove duplicates from array
function unique(array) {
  var seen = {},
      out = [],
      len = array.length,
      j = 0;

  for(var i = 0; i < len; i++) {
    var item = array[i];
    if(seen[item] !== 1) {
      seen[item] = 1;
      out[j++] = item;
    }
  }

  return out;
}

// helper to generate a power set
function power(string) {
  var copy,
      deep_copy;

  return [].slice.call(string).reduce( function(previous, current) {
    copy = previous.slice(0);
    copy.forEach(function(element) {
      deep_copy = element.slice(0);
      deep_copy.push(current);
      previous.push(deep_copy);
    });

    return previous;
  }, [[]]);
}

// helper to generate string permutations
function permute(string){
  var words = [];

  function permute(string, prefix) {
    var balance,
        word,
        i,
        c;

    prefix = prefix || '';

    // loop over str to separate each single character
    for(i = 0; i < string.length; i++) {
      c = string[i];
      balance = string.slice(0, i) + string.slice(i + 1);

      // join the prefix with each of the combinations
      word = prefix + c + balance;

      // inject this word only if it does not exist
      if(words.indexOf(word) < 0)
        words.push(word);

      // recursively call this function in case there are balance characters
      if(balance.length > 1)
        permute(balance, prefix + c);
    }
  }

  permute(string);
  return words;
}<|endoftext|>


<commit_before>
var progressWidth = 500;
var lock = false;
var test_start = null;
var test_down_results = [];
var test_up_results = [];
var current_test = null;

var test_interval = null;
var test_fail = false;
var xreq;
var ko_func = function () {
    this.ko_test_results = ko.observableArray();
}
var ko_obj = new ko_func();
    /*
    [
        {
            kind: upload || download
            ,id: 39812
            ,items: [
                {
                    friendlySize: 1.00MB
                    ,bytes: 1048576
                    ,ms: 1000
                    ,mbps: 99.00Mbps
                }
            ]
        }
    ]
    */
function addTest(kind) {
    var t = {
        kind: kind
        ,id: Date.now()
        ,items: ko.observableArray()
    };
    ko_obj.ko_test_results.push(t);
    return t;
}

function addTestResult(kind, testid, timespan, numbytes, rec) {
    for(var i = 0; i < ko_obj.ko_test_results().length; i++) {
        if(ko_obj.ko_test_results()[i].id != testid) { continue; }
        var fb_pf = "bytes";
        if(numbytes > 1024) fb_pf = "KB";
        if(numbytes > 1048576) fb_pf = "MB";
        if(numbytes > 1073741824) fb_pf = "GB";

        ko_obj.ko_test_results()[i].items.unshift({
            friendlySize: ((numbytes/({"bytes": 1, KB: 1024, MB: 1048576, GB: 1073741824})[fb_pf]).toPrecision(3).toString() + fb_pf)
            ,bytes: numbytes
            ,ms: timespan
            ,mbps: (((numbytes/(timespan/1000))/1048576)*8).toPrecision(3)
        });

        return;
    }
    if(rec === null) {
        addTest(kind)
        addTestResult(kind,testid,timespan,numbytes, 1);
    }
}

$(document).ready(function() {
    try {
        $.get("./ip", function(res) {
            $("#remoteip").text(res)
        });

        $.get("./conf", null, function(conf) {
            for(var prop in conf) {
                var pi = $(document.createElement('div'));
                var ni = $(document.createElement('input')).attr('type', 'text').attr('id', prop).attr('value', conf[prop]);
                var li = $(document.createElement('label')).text(prop).attr("for", prop);

                ni.blur(function(ob) {
                    $(ob.target).val(expandshortcodes($(ob.target).val()));
                });

                pi.append(li);
                pi.append(ni);
                $("#config").append(pi);
            }
        }, 'json');
        $("#jswarning").toggle();
        $("#mainbod").toggle();
    } catch(e) {

    }
    try {
        ko.applyBindings(ko_obj)
    } catch(e){
        console.log(e);
    }
});
function clearresults() {
    $("#result").html("");
}
function stoptests() {
    try {
        xreq.abort();
    } catch(e) {}
}
function rundowntests(target_size, last_test, runupload) {

    runupload = runupload || false;
    if(test_down_results != null && test_down_results.length > 0) {
        var slowest, fastest, average = null;
        for(var i = 0; i < test_down_results.length; i++) {
            slowest = (slowest == null || test_down_results[i].MBps < slowest.MBps) ? test_down_results[i] : slowest;
            fastest = (fastest == null || test_down_results[i].MBps > fastest.MBps) ? test_down_results[i] : fastest;
            average += test_down_results[i].MBps;
        }
        $("#stat_download_slowest span").text((slowest.MBps*8).toFixed(2) + "Mbps ("+(slowest.TargetSize/1024/1024).toFixed(2)+"MB)");
        $("#stat_download_fastest span").text((fastest.MBps*8).toFixed(2) + "Mbps ("+(fastest.TargetSize/1024/1024).toFixed(2)+"MB)")
        $("#stat_download_average span").text(((average/test_down_results.length)*8).toFixed(2) + "Mbps");
        $("#uploadStartSize").val(Math.round((fastest.TargetSize/8> $("#maxUploadSize").val())? $("#maxUploadSize").val():fastest.TargetSize/8));
    }

    if(test_fail == true || target_size > $("#maxDownloadSize").val() || (last_test != null && last_test.Diff > $("#maxDownloadTime").val()* 1000)) {

        //end of all things;
        var ttime = ((new Date()).getTime() -test_start.getTime());
        //$("#current").html("");
        //$("#result").append("
Finished download tests in "+ ttime/1000 + "s
");

        test_start = null;
        current_test = null;
        test_down_results = [];
        test_fail = false;
        if(runupload) {
            runuptests($('#uploadStartSize').val(), null);
        }
        return;
    }

    if(test_start == null) {
        test_start = new Date();
        current_test = addTest('download');
    }

    //$("#current").html("Running "+(target_size/1024/1024).toFixed(2) +"MB download test ");
    //$("#current").append("

");
    var r = {}; //results
    var start = new Date();
    xreq = $.ajax('./download?size=' + target_size, {
        progress: function(e) {
            var curspeed =  (e.loaded/(((new Date()).getTime() - start.getTime())))/1000
            r.ActualSize = e.total;
            r.Loaded = e.loaded;
            //$("#currentper").html(Math.ceil((e.loaded/e.total)*100).toString() + "% @ "+Math.round(curspeed*8*100)/100+"Mbps ("+Math.round(e.loaded/1024)+"/"+e.total/1024+"KB)");
            //$("#current div:first").css('border-left', Math.ceil((e.loaded/e.total)*100*(progressWidth/100)).toString() +"px solid green");
            //$("#current div:first").css('border-right', (progressWidth-Math.ceil((e.loaded/e.total)*100*(progressWidth/100))).toString() +"px solid red");

        }
    }).error(function(e) {
        console.log(e);
        test_fail = true;
    }).done(function() {
        var end = new Date();

        r.Start = start;
        r.End = end;
        r.Diff = end.getTime() - start.getTime();
        var MBps = ((target_size)/(r.Diff/1000));
        r.MBps = MBps/1024/1024;
        r.TargetSize = target_size;
        test_down_results.push(r);

        //$('#result').append("
"+(target_size/1024/1024).toFixed(2) +"MB in "+r.Diff+"s @ "+(r.MBps*8).toFixed(2)+"Mbps ("+r.MBps.toFixed(2)+"MBps)
");

        addTestResult('download', current_test.id, r.Diff, target_size);

        setTimeout(rundowntests.bind({}, Math.ceil(target_size*$('#downloadSizeModifier').val()), r, runupload), $("#restInterval").val());
    }).always(function() {
        clearInterval(test_interval);
        test_interval = null;
    });
}
var upload_data = [];
var createdataInterval = null;
function runuptests(target_size, last_test) {
    //var d = [];

    if(test_start == null) {
        test_start = new Date();
    }

    if(test_fail == true || test_up_results.length >= parseInt($("#maxUploadInterations").val()) || target_size > parseInt($("#maxUploadSize").val()) || (last_test != null && last_test.Diff != null && last_test.Diff > parseInt($("#maxUploadTime").val())*1000)) {
        var ttime = ((new Date()).getTime() -test_start.getTime());
        //("#current").html("");
        //$("#result").append("
Finished upload tests in "+ ttime/1000 + "s
");
        test_up_results = [];
        test_fail = false;
        return;
    }

    if(test_up_results.length > 0) {
        var slowest, fastest, average = null;

        for(var i = 0; i < test_up_results.length; i++) {
            slowest = (slowest == null || test_up_results[i].MBps < slowest.MBps) ? test_up_results[i] : slowest;
            fastest = (fastest == null || test_up_results[i].MBps > fastest.MBps) ? test_up_results[i] : fastest;
            average += test_up_results[i].MBps;
        }

        //$("#stat_upload_slowest span").text(Math.round(slowest.MBps*8*100)/100 + "Mbps ("+slowest.TargetSize/1024/1024+"MB)");
        //$("#stat_upload_fastest span").text(Math.round(fastest.MBps*8*100)/100 + "Mbps ("+fastest.TargetSize/1024/1024+"MB)")
        //$("#stat_upload_average span").text(Math.round((average/test_up_results.length)*8*100)/100 + "Mbps");
    }

    if(upload_data.length > target_size) {
        upload_data = upload_data.slice(0, target_size);
    }
    for(var i = 0; upload_data.length < target_size; i++) {
        upload_data.push(0);
    }
    if(createdataInterval == null) {
         createdataInterval = setInterval(function() {
            if(upload_data.length >= target_size) {
                clearInterval(createdataInterval);
                createdataInterval = null;

                //$("#current").html("Running "+(target_size/1024/1024).toFixed(2) +"MB upload test ");
                //$("#current").append("

");
                var r = {};
                var start = new Date();
                xreq = $.ajax('./upload?size=' + target_size, {
                    type: "post"
                    ,processData: false
                    ,contentType: "image/png"
                    ,headers: {}
                    ,progress: function(e) {
                        var curspeed =  (e.loaded/(((new Date()).getTime() - start.getTime())))/1000
                        r.ActualSize = e.total;
                        r.Loaded = e.loaded;
                        //$("#currentper").html(Math.ceil((e.loaded/e.total)*100).toString() + "% @ "+Math.round(curspeed*8*100)/100+"Mbps ("+Math.round(e.loaded/1024)+"/"+e.total/1024+"KB)");
                        //$("#current div:first").css('border-left', Math.ceil((e.loaded/e.total)*100*(progressWidth/100)).toString() +"px solid green");
                        //$("#current div:first").css('border-right', (progressWidth-Math.ceil((e.loaded/e.total)*100*(progressWidth/100))).toString() +"px solid red");
                    }
                    ,data: upload_data.join("")
                }).error(function() {
                    test_fail = true;
                }).done(function() {
                    var end = new Date();
                    r.Start = start;
                    r.End = end;
                    r.Diff = end.getTime() - start.getTime();
                    var MBps = ((target_size)/(r.Diff))/1000;
                    r.MBps = MBps;
                    r.TargetSize = target_size;
                    test_up_results.push(r);
                    //$('#result').append("
"+(target_size/1024/1024).toFixed(2) +"MB in "+(r.Diff).toFixed(2)+"s @ "+(MBps*8).toFixed(2)+"Mbps ("+MBps.toString().substring(0,5)+"MBps)
");
                }).always(function() {
                    //runuptests(Math.round(target_size*$("#uploadSizeModifier").val()), r);
                    setTimeout(runuptests.bind({}, Math.ceil(target_size*$('#uploadSizeModifier').val()), r), $("#restInterval").val());
                });
            }
        }, 10);
    }
}

function togglesettings() {
    $("#config").toggle(500);
}

function expandshortcodes(str) {
    //replace M K, etc with appropriate bytes
    //mega
    var res = 0;
    try {
        var meg = str.match(/([0-9\.]+)m/i);
        res += parseFloat(meg[1])*1024*1024;
    } catch(e){}

    //kilo
    try {
        var meg = str.match(/([0-9\.]+)k/i);
        res += parseFloat(meg[1])*1024;
    } catch(e){}

    //byte
    try {
        var meg = str.match(/([0-9\.]+)b/i);
        res += parseFloat(meg[1]);
    } catch(e){}
    try {
        var meg = str.match(/([0-9\.]+)$/i);
        res += parseFloat(meg[1]);
    } catch(e){}
    return res;
}<commit_msg>fix: 1MB result looked weird.<commit_after>
var progressWidth = 500;
var lock = false;
var test_start = null;
var test_down_results = [];
var test_up_results = [];
var current_test = null;

var test_interval = null;
var test_fail = false;
var xreq;
var ko_func = function () {
    this.ko_test_results = ko.observableArray();
}
var ko_obj = new ko_func();
    /*
    [
        {
            kind: upload || download
            ,id: 39812
            ,items: [
                {
                    friendlySize: 1.00MB
                    ,bytes: 1048576
                    ,ms: 1000
                    ,mbps: 99.00Mbps
                }
            ]
        }
    ]
    */
function addTest(kind) {
    var t = {
        kind: kind
        ,id: Date.now()
        ,items: ko.observableArray()
    };
    ko_obj.ko_test_results.push(t);
    return t;
}

function addTestResult(kind, testid, timespan, numbytes, rec) {
    for(var i = 0; i < ko_obj.ko_test_results().length; i++) {
        if(ko_obj.ko_test_results()[i].id != testid) { continue; }
        var fb_pf = "bytes";
        if(numbytes >= 1024) fb_pf = "KB";
        if(numbytes >= 1048576) fb_pf = "MB";
        if(numbytes >= 1073741824) fb_pf = "GB";

        ko_obj.ko_test_results()[i].items.unshift({
            friendlySize: ((numbytes/({"bytes": 1, KB: 1024, MB: 1048576, GB: 1073741824})[fb_pf]).toPrecision(3).toString() + fb_pf)
            ,bytes: numbytes
            ,ms: timespan
            ,mbps: (((numbytes/(timespan/1000))/1048576)*8).toPrecision(3)
        });

        return;
    }
    if(rec === null) {
        addTest(kind)
        addTestResult(kind,testid,timespan,numbytes, 1);
    }
}

$(document).ready(function() {
    try {
        $.get("./ip", function(res) {
            $("#remoteip").text(res)
        });

        $.get("./conf", null, function(conf) {
            for(var prop in conf) {
                var pi = $(document.createElement('div'));
                var ni = $(document.createElement('input')).attr('type', 'text').attr('id', prop).attr('value', conf[prop]);
                var li = $(document.createElement('label')).text(prop).attr("for", prop);

                ni.blur(function(ob) {
                    $(ob.target).val(expandshortcodes($(ob.target).val()));
                });

                pi.append(li);
                pi.append(ni);
                $("#config").append(pi);
            }
        }, 'json');
        $("#jswarning").toggle();
        $("#mainbod").toggle();
    } catch(e) {

    }
    try {
        ko.applyBindings(ko_obj)
    } catch(e){
        console.log(e);
    }
});
function clearresults() {
    $("#result").html("");
}
function stoptests() {
    try {
        xreq.abort();
    } catch(e) {}
}
function rundowntests(target_size, last_test, runupload) {

    runupload = runupload || false;
    if(test_down_results != null && test_down_results.length > 0) {
        var slowest, fastest, average = null;
        for(var i = 0; i < test_down_results.length; i++) {
            slowest = (slowest == null || test_down_results[i].MBps < slowest.MBps) ? test_down_results[i] : slowest;
            fastest = (fastest == null || test_down_results[i].MBps > fastest.MBps) ? test_down_results[i] : fastest;
            average += test_down_results[i].MBps;
        }
        $("#stat_download_slowest span").text((slowest.MBps*8).toFixed(2) + "Mbps ("+(slowest.TargetSize/1024/1024).toFixed(2)+"MB)");
        $("#stat_download_fastest span").text((fastest.MBps*8).toFixed(2) + "Mbps ("+(fastest.TargetSize/1024/1024).toFixed(2)+"MB)")
        $("#stat_download_average span").text(((average/test_down_results.length)*8).toFixed(2) + "Mbps");
        $("#uploadStartSize").val(Math.round((fastest.TargetSize/8> $("#maxUploadSize").val())? $("#maxUploadSize").val():fastest.TargetSize/8));
    }

    if(test_fail == true || target_size > $("#maxDownloadSize").val() || (last_test != null && last_test.Diff > $("#maxDownloadTime").val()* 1000)) {

        //end of all things;
        var ttime = ((new Date()).getTime() -test_start.getTime());
        //$("#current").html("");
        //$("#result").append("
Finished download tests in "+ ttime/1000 + "s
");

        test_start = null;
        current_test = null;
        test_down_results = [];
        test_fail = false;
        if(runupload) {
            runuptests($('#uploadStartSize').val(), null);
        }
        return;
    }

    if(test_start == null) {
        test_start = new Date();
        current_test = addTest('download');
    }

    //$("#current").html("Running "+(target_size/1024/1024).toFixed(2) +"MB download test ");
    //$("#current").append("

");
    var r = {}; //results
    var start = new Date();
    xreq = $.ajax('./download?size=' + target_size, {
        progress: function(e) {
            var curspeed =  (e.loaded/(((new Date()).getTime() - start.getTime())))/1000
            r.ActualSize = e.total;
            r.Loaded = e.loaded;
            //$("#currentper").html(Math.ceil((e.loaded/e.total)*100).toString() + "% @ "+Math.round(curspeed*8*100)/100+"Mbps ("+Math.round(e.loaded/1024)+"/"+e.total/1024+"KB)");
            //$("#current div:first").css('border-left', Math.ceil((e.loaded/e.total)*100*(progressWidth/100)).toString() +"px solid green");
            //$("#current div:first").css('border-right', (progressWidth-Math.ceil((e.loaded/e.total)*100*(progressWidth/100))).toString() +"px solid red");

        }
    }).error(function(e) {
        console.log(e);
        test_fail = true;
    }).done(function() {
        var end = new Date();

        r.Start = start;
        r.End = end;
        r.Diff = end.getTime() - start.getTime();
        var MBps = ((target_size)/(r.Diff/1000));
        r.MBps = MBps/1024/1024;
        r.TargetSize = target_size;
        test_down_results.push(r);

        //$('#result').append("
"+(target_size/1024/1024).toFixed(2) +"MB in "+r.Diff+"s @ "+(r.MBps*8).toFixed(2)+"Mbps ("+r.MBps.toFixed(2)+"MBps)
");

        addTestResult('download', current_test.id, r.Diff, target_size);

        setTimeout(rundowntests.bind({}, Math.ceil(target_size*$('#downloadSizeModifier').val()), r, runupload), $("#restInterval").val());
    }).always(function() {
        clearInterval(test_interval);
        test_interval = null;
    });
}
var upload_data = [];
var createdataInterval = null;
function runuptests(target_size, last_test) {
    //var d = [];

    if(test_start == null) {
        test_start = new Date();
    }

    if(test_fail == true || test_up_results.length >= parseInt($("#maxUploadInterations").val()) || target_size > parseInt($("#maxUploadSize").val()) || (last_test != null && last_test.Diff != null && last_test.Diff > parseInt($("#maxUploadTime").val())*1000)) {
        var ttime = ((new Date()).getTime() -test_start.getTime());
        //("#current").html("");
        //$("#result").append("
Finished upload tests in "+ ttime/1000 + "s
");
        test_up_results = [];
        test_fail = false;
        return;
    }

    if(test_up_results.length > 0) {
        var slowest, fastest, average = null;

        for(var i = 0; i < test_up_results.length; i++) {
            slowest = (slowest == null || test_up_results[i].MBps < slowest.MBps) ? test_up_results[i] : slowest;
            fastest = (fastest == null || test_up_results[i].MBps > fastest.MBps) ? test_up_results[i] : fastest;
            average += test_up_results[i].MBps;
        }

        //$("#stat_upload_slowest span").text(Math.round(slowest.MBps*8*100)/100 + "Mbps ("+slowest.TargetSize/1024/1024+"MB)");
        //$("#stat_upload_fastest span").text(Math.round(fastest.MBps*8*100)/100 + "Mbps ("+fastest.TargetSize/1024/1024+"MB)")
        //$("#stat_upload_average span").text(Math.round((average/test_up_results.length)*8*100)/100 + "Mbps");
    }

    if(upload_data.length > target_size) {
        upload_data = upload_data.slice(0, target_size);
    }
    for(var i = 0; upload_data.length < target_size; i++) {
        upload_data.push(0);
    }
    if(createdataInterval == null) {
         createdataInterval = setInterval(function() {
            if(upload_data.length >= target_size) {
                clearInterval(createdataInterval);
                createdataInterval = null;

                //$("#current").html("Running "+(target_size/1024/1024).toFixed(2) +"MB upload test ");
                //$("#current").append("

");
                var r = {};
                var start = new Date();
                xreq = $.ajax('./upload?size=' + target_size, {
                    type: "post"
                    ,processData: false
                    ,contentType: "image/png"
                    ,headers: {}
                    ,progress: function(e) {
                        var curspeed =  (e.loaded/(((new Date()).getTime() - start.getTime())))/1000
                        r.ActualSize = e.total;
                        r.Loaded = e.loaded;
                        //$("#currentper").html(Math.ceil((e.loaded/e.total)*100).toString() + "% @ "+Math.round(curspeed*8*100)/100+"Mbps ("+Math.round(e.loaded/1024)+"/"+e.total/1024+"KB)");
                        //$("#current div:first").css('border-left', Math.ceil((e.loaded/e.total)*100*(progressWidth/100)).toString() +"px solid green");
                        //$("#current div:first").css('border-right', (progressWidth-Math.ceil((e.loaded/e.total)*100*(progressWidth/100))).toString() +"px solid red");
                    }
                    ,data: upload_data.join("")
                }).error(function() {
                    test_fail = true;
                }).done(function() {
                    var end = new Date();
                    r.Start = start;
                    r.End = end;
                    r.Diff = end.getTime() - start.getTime();
                    var MBps = ((target_size)/(r.Diff))/1000;
                    r.MBps = MBps;
                    r.TargetSize = target_size;
                    test_up_results.push(r);
                    //$('#result').append("
"+(target_size/1024/1024).toFixed(2) +"MB in "+(r.Diff).toFixed(2)+"s @ "+(MBps*8).toFixed(2)+"Mbps ("+MBps.toString().substring(0,5)+"MBps)
");
                }).always(function() {
                    //runuptests(Math.round(target_size*$("#uploadSizeModifier").val()), r);
                    setTimeout(runuptests.bind({}, Math.ceil(target_size*$('#uploadSizeModifier').val()), r), $("#restInterval").val());
                });
            }
        }, 10);
    }
}

function togglesettings() {
    $("#config").toggle(500);
}

function expandshortcodes(str) {
    //replace M K, etc with appropriate bytes
    //mega
    var res = 0;
    try {
        var meg = str.match(/([0-9\.]+)m/i);
        res += parseFloat(meg[1])*1024*1024;
    } catch(e){}

    //kilo
    try {
        var meg = str.match(/([0-9\.]+)k/i);
        res += parseFloat(meg[1])*1024;
    } catch(e){}

    //byte
    try {
        var meg = str.match(/([0-9\.]+)b/i);
        res += parseFloat(meg[1]);
    } catch(e){}
    try {
        var meg = str.match(/([0-9\.]+)$/i);
        res += parseFloat(meg[1]);
    } catch(e){}
    return res;
}<|endoftext|>


<commit_before>(function ($, count, window) {

    var ef = function () {},
    methods = {
        init: function (opts) {
            var T = this;
            if (!T.length || T.data('streamcomplete')) {
                // There are no elements or this object has already been initialised
                return T;
            } else if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete(opts);
                });
                return T;
            }
            var data = {
                instanceid: ++count,
                s: $.fn.extend({
                    delay: 250,
                    minlength: 2,
                    onajaxerror: ef,
                    onbeforeajaxsearch: ef,
                    onbeforesearch: ef,
                    onclose: ef,
                    onerror: ef,
                    oninit: ef,
                    onresponse: ef,
                    onsearch: ef,
                    onselect: ef,
                    src: []
                }, opts),
                searchterm: null
            },
            searchinterval = false,
            clear = false,
            keycodes = {
                DOWN: 40,
                ENTER: 13,
                SPACE: 32,
                TAB: 9,
                UP: 38,
                ESC: 27
            },
            selectpos = -1,
            cancelkeypress = false;

            /**
             * Render a single result
             * @param {object(plain)} desc An object with necessary properties. The obejct MUST have the properties 'id' and 'value'
             * @returns {Element} The rendered element, in this case a div
             */
            data.renderResult = function (desc) {
                var elem = document.createElement('div');
                $(elem).html(desc.value).data('sc-desc', desc).addClass('streamcomplete-result');
                return elem;
            };

            /**
             * Render the full autocomplete
             * @param {array} results An array of objects in the form [{id: int, value: value}, ...], or an array of values
             */
            data.render = function (results) {
                var output = $('.streamcomplete-body').show(),
                offset = T.offset(),
                rect = T[0].getBoundingClientRect();
                output.css({width: T.width(), top: offset.top + rect.height, left: offset.left}).empty();
                for (var i = 0; results ? i < results.length : 0; i++) {
                    var desc = results[i];
                    if (Object.prototype.toString.call(desc) !== '[object Object]') {
                        // The result is not an object, make it one
                        desc = {id: i, value: desc};
                    }
                    var res = data.renderResult(desc);
                    output.append(res);
                }
            };

            /**
             * The after render function. Seperate from the render function because the render function can be customised, whereas
             *  everything in this function is more or less always required. Makes customising the output easier
             */
            data.afterRender = function () {
                var output = $('.streamcomplete-body'),
                results = output.data('sc-results');
                output.data('sc-results', results);
                $('body').unbind('click.streamcomplete').bind('click.streamcomplete', data.close);
            };

            /**
             *
             * @param {type} e
             */
            data.close = function (e) {
                var selection = null;
                if (e) {
                    // This function was called as a result of an event
                    var target = $(e.target);
                    if (target.closest('.streamcomplete-body').length) {
                        // The user has clicked on one of the selections
                        var selection = target.data('sc-desc');
                        if (data.s.onselect.call(T, selection) === false) {
                            // The caller has prevented continuation
                            return false;
                        }
                        T[0].value = selection.value;
                        T.attr({'data-value': selection.id});
                    }
                }
                data.s.onclose.call(T, {selection: selection, results: $('.streamcomplete-body').hide().data('sc-results')});
            };

            T.keydown(function (e) {
                // If there is need to return false, then the keyboard event listener has to be onkeydown.
                if (inObj(keycodes, e.which)) {
                    // The user is navigating using the keyboard
                    var ans = keyboardAction(e.which);
                    if (ans === false) {
                        // The keyboard action returned false, so prevent the default action
                        e.preventDefault();
                        cancelkeypress = true;
                        return false;
                    }
                }
            });

            T.keyup(function () {
                if (cancelkeypress) {
                    // The keydown event listener says that the keyup event should not be registered
                    cancelkeypress = false;
                    return false;
                }
                data.searchterm = this.value;
                var payload = {
                    term: data.searchterm
                };
                selectpos = -1;
                if (data.s.onbeforesearch.call(T, payload) === false) {
                    // The caller cancelled the search: return
                    return false;
                }
                if (this.value.length >= +data.s.minlength) {
                    clear = false;
                    if (searchinterval !== false) {
                        // Clear the search interval
                        window.clearTimeout(searchinterval);
                    }
                    searchinterval = window.setTimeout(function () {
                        // Only perform searches in intervals as specified by the settings
                        if (clear) {
                            // A clear was called during the timeout
                            clear = false;
                            return;
                        }
                        var isarr = false;
                        switch (Object.prototype.toString.call(data.s.src)) {
                            case '[object String]':
                                // Assume that the given string is a URL to resolve
                                getDataAjax(data.s.src, payload);
                                break;
                            case '[object Array]':
                                // Note that the current item is an array and then do the same as would be done for a function
                                isarr = true;
                            case '[object Function]':
                                var results = isarr ? data.s.src : data.s.src();
                                if (data.s.onsearch.call(T, results) === false) {
                                    return false;
                                }
                                data.render(results);
                                data.afterRender();
                                break;
                        }
                    }, +data.s.delay);
                } else {
                    // No need to show the results because they are now wrong
                    clear = true;
                    data.close();
                }
                T.data('streamcomplete', data);
            });

            /**
             * Get data for the autocomplete via AJAX
             * @param {string} url The url to get the AJAX results from
             * @param {object(plain)} payload The payload to pass to as post data
             */
            var getDataAjax = function (url, payload) {
                $.ajax({
                    url: url,
                    type: 'post',
                    dataType: 'json',
                    beforeSend: function (e) {
                        data.s.onbeforeajaxsearch.call(T, e);
                    },
                    data: {payload: JSON.stringify(payload)}
                }).done(function (e) {
                    if (e.result === 'OK') {
                        if (clear) {
                            // A clear was called during the request
                            clear = false;
                            return;
                        }
                        if (data.s.onresponse.call(T, e) === false) {
                            return false;
                        };
                        searchinterval = false;
                        if (data.s.onsearch.call(T, e.data) === false) {
                            return false;
                        }
                        data.render(e.data);
                        data.afterRender();
                    } else {
                        data.s.onerror.call(T, e);
                    }
                }).fail(function (e) {
                    data.s.onajaxerror.call(T, e);
                });
            };

            /**
             * Perform a strict comparison with object values to determine whether a value exists in an object
             * @param {object} obj The object to look in
             * @param {mixed} val  The value to search for
             * @returns {Boolean} True if the value is in the object
             */
            var inObj = function (obj, val) {
                for (var x in obj) {
                    if (obj[x] === val) {
                        return true;
                    }
                }
                return false;
            };

            /**
             * Process keyboard navigation
             * @param {int} which The id of the key that was pressed
             * @returns {Boolean} False if the navigation require
             */
            var keyboardAction = function (which) {
                var resultlist = $('.streamcomplete-result'),
                len = resultlist.length;
                switch (which) {
                    case keycodes.UP:
                        selectpos = (selectpos - 1 < 0 ? len : selectpos) - 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.DOWN:
                        selectpos = selectpos + 1 === len ? 0 : selectpos + 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.SPACE:
                    case keycodes.ENTER:
                    case keycodes.TAB:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            data.close({target: res[0]});
                            return false;
                        }
                        return true;
                    case keycodes.ESC:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            selectpos = -1;
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            return false;
                        }
                        return true;
                }
            };

            // Catch all focusin events
            T.focusin(data.s.onfocusin);
            T.change(data.s.onchange);
            T.focusout(data.onfocusout);
            T.data('streamcomplete', data);
            draw();
            data.s.oninit.call(T);
            return T;
        },
        /**
         * Set the value for this autocomplete
         * @param {object} data An object with at least two properties, value (the human readable value for the input) and id
         *  (the system value). Any more properties will be added into data attributes of the given key
         * @returns {jQUery}
         */
        setValue: function (data) {
            // Test to see whether the plugin has been initialised here first
            var scdata = this.data('streamcomplete');
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            this[0].value = data.value;
            this.data('value', data.id);
            // Delete the known properties in this object and then add in data attributes for all of the other ones
            delete data.value;
            delete data.id;
            for (var x in data) {
                this.data(x, data[x]);
            }
            return this;
        }
    };

    /**
     * StreamConfirm exception handler
     * @param {string} exceptiontype The name of the exception to replace xxx in the string "Uncaught StreamComplete::xxx - message"
     * @param {string} message The exception message
     * @returns {StreamComplete::Exception}
     */
    function ex(exceptiontype, message) {
        return {
            name: 'StreamComplete::' + exceptiontype,
            level: "Cannot continue",
            message: message,
            htmlMessage: message,
            toString: function() {
                return ['StreamComplete::', exceptiontype, ' - ', message].join('');
            }
        };
    };

    /**
     *
     * @returns {undefined}
     */
    function draw() {
        if ($('.streamcomplete-body').length) {
            // The body has already been drawn
            return;
        }
        $('body').append('

');
    }

    $.fn.streamComplete = function(methodOrOpts) {
        var T = this;
        if (methods[methodOrOpts]) {
            // The first option passed is a method, therefore call this method
            return methods[methodOrOpts].apply(T, Array.prototype.slice.call(arguments, 1));
        } else if (Object.prototype.toString.call(methodOrOpts) === '[object Object]' || !methodOrOpts) {
            // The default action is to call the init function
            return methods.init.apply(T, arguments);
        } else {
            // The user has passed us something dodgy, throw an error
            $.error(['The method ', methodOrOpts, ' does not exist'].join(''));
        }
    };

})(jQuery, 0, this);<commit_msg>Fixed a bug. Added an onchange at the end of the setValue method<commit_after>(function ($, count, window) {

    var ef = function () {},
    methods = {
        init: function (opts) {
            var T = this;
            if (!T.length || T.data('streamcomplete')) {
                // There are no elements or this object has already been initialised
                return T;
            } else if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete(opts);
                });
                return T;
            }
            var data = {
                instanceid: ++count,
                s: $.fn.extend({
                    delay: 250,
                    minlength: 2,
                    onajaxerror: ef,
                    onbeforeajaxsearch: ef,
                    onbeforesearch: ef,
                    onclose: ef,
                    onerror: ef,
                    oninit: ef,
                    onresponse: ef,
                    onsearch: ef,
                    onselect: ef,
                    src: []
                }, opts),
                searchterm: null
            },
            searchinterval = false,
            clear = false,
            keycodes = {
                DOWN: 40,
                ENTER: 13,
                SPACE: 32,
                TAB: 9,
                UP: 38,
                ESC: 27
            },
            selectpos = -1,
            cancelkeypress = false;

            /**
             * Render a single result
             * @param {object(plain)} desc An object with necessary properties. The obejct MUST have the properties 'id' and 'value'
             * @returns {Element} The rendered element, in this case a div
             */
            data.renderResult = function (desc) {
                var elem = document.createElement('div');
                $(elem).html(desc.value).data('sc-desc', desc).addClass('streamcomplete-result');
                return elem;
            };

            /**
             * Render the full autocomplete
             * @param {array} results An array of objects in the form [{id: int, value: value}, ...], or an array of values
             */
            data.render = function (results) {
                var output = $('.streamcomplete-body').show(),
                offset = T.offset(),
                rect = T[0].getBoundingClientRect();
                output.css({width: T.width(), top: offset.top + rect.height, left: offset.left}).empty();
                for (var i = 0; results ? i < results.length : 0; i++) {
                    var desc = results[i];
                    if (Object.prototype.toString.call(desc) !== '[object Object]') {
                        // The result is not an object, make it one
                        desc = {id: i, value: desc};
                    }
                    var res = data.renderResult(desc);
                    output.append(res);
                }
            };

            /**
             * The after render function. Seperate from the render function because the render function can be customised, whereas
             *  everything in this function is more or less always required. Makes customising the output easier
             */
            data.afterRender = function () {
                var output = $('.streamcomplete-body'),
                results = output.data('sc-results');
                output.data('sc-results', results);
                $('body').unbind('click.streamcomplete').bind('click.streamcomplete', data.close);
            };

            /**
             *
             * @param {type} e
             */
            data.close = function (e) {
                var selection = null;
                if (e) {
                    // This function was called as a result of an event
                    var target = $(e.target);
                    if (target.closest('.streamcomplete-body').length) {
                        // The user has clicked on one of the selections
                        var selection = target.data('sc-desc');
                        if (data.s.onselect.call(T, selection) === false) {
                            // The caller has prevented continuation
                            return false;
                        }
                        T[0].value = selection.value;
                        T.attr({'data-value': selection.id});
                    }
                }
                data.s.onclose.call(T, {selection: selection, results: $('.streamcomplete-body').hide().data('sc-results')});
            };

            T.keydown(function (e) {
                // If there is need to return false, then the keyboard event listener has to be onkeydown.
                if (inObj(keycodes, e.which)) {
                    // The user is navigating using the keyboard
                    var ans = keyboardAction(e.which);
                    if (ans === false) {
                        // The keyboard action returned false, so prevent the default action
                        e.preventDefault();
                        cancelkeypress = true;
                        return false;
                    }
                }
            });

            T.keyup(function () {
                if (cancelkeypress) {
                    // The keydown event listener says that the keyup event should not be registered
                    cancelkeypress = false;
                    return false;
                }
                data.searchterm = this.value;
                var payload = {
                    term: data.searchterm
                };
                selectpos = -1;
                if (data.s.onbeforesearch.call(T, payload) === false) {
                    // The caller cancelled the search: return
                    return false;
                }
                if (this.value.length >= +data.s.minlength) {
                    clear = false;
                    if (searchinterval !== false) {
                        // Clear the search interval
                        window.clearTimeout(searchinterval);
                    }
                    searchinterval = window.setTimeout(function () {
                        // Only perform searches in intervals as specified by the settings
                        if (clear) {
                            // A clear was called during the timeout
                            clear = false;
                            return;
                        }
                        var isarr = false;
                        switch (Object.prototype.toString.call(data.s.src)) {
                            case '[object String]':
                                // Assume that the given string is a URL to resolve
                                getDataAjax(data.s.src, payload);
                                break;
                            case '[object Array]':
                                // Note that the current item is an array and then do the same as would be done for a function
                                isarr = true;
                            case '[object Function]':
                                var results = isarr ? data.s.src : data.s.src();
                                if (data.s.onsearch.call(T, results) === false) {
                                    return false;
                                }
                                data.render(results);
                                data.afterRender();
                                break;
                        }
                    }, +data.s.delay);
                } else {
                    // No need to show the results because they are now wrong
                    clear = true;
                    data.close();
                }
                T.data('streamcomplete', data);
            });

            /**
             * Get data for the autocomplete via AJAX
             * @param {string} url The url to get the AJAX results from
             * @param {object(plain)} payload The payload to pass to as post data
             */
            var getDataAjax = function (url, payload) {
                $.ajax({
                    url: url,
                    type: 'post',
                    dataType: 'json',
                    beforeSend: function (e) {
                        data.s.onbeforeajaxsearch.call(T, e);
                    },
                    data: {payload: JSON.stringify(payload)}
                }).done(function (e) {
                    if (e.result === 'OK') {
                        if (clear) {
                            // A clear was called during the request
                            clear = false;
                            return;
                        }
                        if (data.s.onresponse.call(T, e) === false) {
                            return false;
                        };
                        searchinterval = false;
                        if (data.s.onsearch.call(T, e.data) === false) {
                            return false;
                        }
                        data.render(e.data);
                        data.afterRender();
                    } else {
                        data.s.onerror.call(T, e);
                    }
                }).fail(function (e) {
                    data.s.onajaxerror.call(T, e);
                });
            };

            /**
             * Perform a strict comparison with object values to determine whether a value exists in an object
             * @param {object} obj The object to look in
             * @param {mixed} val  The value to search for
             * @returns {Boolean} True if the value is in the object
             */
            var inObj = function (obj, val) {
                for (var x in obj) {
                    if (obj[x] === val) {
                        return true;
                    }
                }
                return false;
            };

            /**
             * Process keyboard navigation
             * @param {int} which The id of the key that was pressed
             * @returns {Boolean} False if the navigation require
             */
            var keyboardAction = function (which) {
                var resultlist = $('.streamcomplete-result'),
                len = resultlist.length;
                switch (which) {
                    case keycodes.UP:
                        selectpos = (selectpos - 1 < 0 ? len : selectpos) - 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.DOWN:
                        selectpos = selectpos + 1 === len ? 0 : selectpos + 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.SPACE:
                    case keycodes.ENTER:
                    case keycodes.TAB:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            data.close({target: res[0]});
                            return false;
                        }
                        return true;
                    case keycodes.ESC:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            selectpos = -1;
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            return false;
                        }
                        return true;
                }
            };

            // Catch all focusin events
            T.focusin(data.s.onfocusin);
            T.change(data.s.onchange);
            T.focusout(data.onfocusout);
            T.data('streamcomplete', data);
            draw();
            data.s.oninit.call(T);
            return T;
        },
        /**
         * Set the value for this autocomplete
         * @param {object} data An object with at least two properties, value (the human readable value for the input) and id
         *  (the system value). Any more properties will be added into data attributes of the given key
         * @returns {jQUery}
         */
        setValue: function (data) {
            // Test to see whether the plugin has been initialised here first
            var scdata = this.data('streamcomplete');
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            this[0].value = data.value;
            this.data('value', data.id);
            // Add in data attributes for all of the other ones
            for (var x in data) {
                if (x !== 'id' && x !== 'value') {
                    this.data(x, data[x]);
                }
            }
            return this.change();
        }
    };

    /**
     * StreamConfirm exception handler
     * @param {string} exceptiontype The name of the exception to replace xxx in the string "Uncaught StreamComplete::xxx - message"
     * @param {string} message The exception message
     * @returns {StreamComplete::Exception}
     */
    function ex(exceptiontype, message) {
        return {
            name: 'StreamComplete::' + exceptiontype,
            level: "Cannot continue",
            message: message,
            htmlMessage: message,
            toString: function() {
                return ['StreamComplete::', exceptiontype, ' - ', message].join('');
            }
        };
    };

    /**
     *
     * @returns {undefined}
     */
    function draw() {
        if ($('.streamcomplete-body').length) {
            // The body has already been drawn
            return;
        }
        $('body').append('

');
    }

    $.fn.streamComplete = function(methodOrOpts) {
        var T = this;
        if (methods[methodOrOpts]) {
            // The first option passed is a method, therefore call this method
            return methods[methodOrOpts].apply(T, Array.prototype.slice.call(arguments, 1));
        } else if (Object.prototype.toString.call(methodOrOpts) === '[object Object]' || !methodOrOpts) {
            // The default action is to call the init function
            return methods.init.apply(T, arguments);
        } else {
            // The user has passed us something dodgy, throw an error
            $.error(['The method ', methodOrOpts, ' does not exist'].join(''));
        }
    };

})(jQuery, 0, this);<|endoftext|>


<commit_before>export default function update() {
  checkControls.call(this);
}

function checkControls() {
  const keys = this.game.state.states.Game.keys;

  const upPressed = keys.UP.justPressed();
  const leftPressed = keys.LEFT.justPressed();
  const downPressed = keys.DOWN.justPressed();
  const rightPressed = keys.RIGHT.justPressed();

  const { tileHeight, tileWidth } = this.game.state.states.Game.map;

  if (upPressed) {
    tryMove.call(this, {
      x: this.x,
      y: this.y - tileHeight,
    });
  }
  if (leftPressed) {
    tryMove.call(this, {
      x: this.x - tileWidth,
      y: this.y,
    });
  }
  if (downPressed) {
    tryMove.call(this, {
      x: this.x,
      y: this.y + tileHeight,
    });
  }
  if (rightPressed) {
    tryMove.call(this, {
      x: this.x + tileWidth,
      y: this.y,
    });
  }
}

function tryMove(nextCoord) {
  const game = this.game.state.states.Game;

  const nextTile = game.map.getTileWorldXY(nextCoord.x, nextCoord.y, 32, 32, 'foreground');

  if (nextTile !== null) {
    tweenMove.call(this, nextCoord);
  }
}

function tweenMove(nextCoord) {
  const move = this.game.add.tween(this);

  move.to(nextCoord, 50, null, true);
}
<commit_msg>Change player frame on move press<commit_after>import frames from '../../sprite-frames';

export default function update() {
  checkControls.call(this);
}

function checkControls() {
  const keys = this.game.state.states.Game.keys;

  const upPressed = keys.UP.justPressed();
  const leftPressed = keys.LEFT.justPressed();
  const downPressed = keys.DOWN.justPressed();
  const rightPressed = keys.RIGHT.justPressed();

  const { tileHeight, tileWidth } = this.game.state.states.Game.map;

  if (upPressed) {
    this.frame = frames.GUY.STAND_UP;
    tryMove.call(this, {
      x: this.x,
      y: this.y - tileHeight,
    });
  }
  if (leftPressed) {
    this.frame = frames.GUY.STAND_LEFT;
    tryMove.call(this, {
      x: this.x - tileWidth,
      y: this.y,
    });
  }
  if (downPressed) {
    this.frame = frames.GUY.STAND_DOWN;
    tryMove.call(this, {
      x: this.x,
      y: this.y + tileHeight,
    });
  }
  if (rightPressed) {
    this.frame = frames.GUY.STAND_RIGHT;
    tryMove.call(this, {
      x: this.x + tileWidth,
      y: this.y,
    });
  }
}

function tryMove(nextCoord) {
  const game = this.game.state.states.Game;

  const nextTile = game.map.getTileWorldXY(nextCoord.x, nextCoord.y, 32, 32, 'foreground');

  if (nextTile !== null) {
    tweenMove.call(this, nextCoord);
  }
}

function tweenMove(nextCoord) {
  const move = this.game.add.tween(this);

  move.to(nextCoord, 50, null, true);
}
<|endoftext|>