<commit_before>
const ajax = require('../common/ajax-functions');

let appUrl = window.location.origin;

//---------------
// Actions
//---------------

let _actionDebug = (info, json) => {
    console.log('[ActionDebug]: ' + info);
    if (json) {
        console.log('[ActionDebug] ' + info + ' json: '
            + JSON.stringify(json));
    }
};

//----------------------------------------------
// THUNK ACTIONS
//----------------------------------------------

// Thunk action to retrieve a list of users
export let getUserList = () => {
    return function(dispatch) {

        dispatch(actionAjaxStart('getUserList'));
        let url = appUrl + '/users/list';

        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('getUserList', json));
            }
        });
    };
};

export let getUserWall = (username) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('getUserWall'));
        let url = appUrl + '/users/wall/' + username;
        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('getUserWall', json));
            }
        });
    };
};

// Thunk action to retrieve user info
export let getUserInfo = () => {
    return function(dispatch) {
        dispatch(actionAjaxStart('getUserInfo'));
        let url = appUrl + '/users';
        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('getUserInfo', json));
            }
        });
    };
};

// Thunk action to send POST to server with image data
export let addImage = (obj) => {
    return function(dispatch) {
        dispatch(fetchImage());
        let url = appUrl + '/images';
        ajax.post(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(receiveImage(json));
            }
        });

    };
};

export let linkImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('linkImage'));
        let url = appUrl + '/images';
        let obj = {image: image, link: true};
        ajax.put(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('linkImage', json));
            }
        });

    };
};

export let unlinkImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('unlinkImage'));
        let url = appUrl + '/images';
        let obj = {image: image, link: true};
        ajax.delete(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('unlinkImage', json));
            }
        });

    };
};

export let likeImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('likeImage'));
        let url = appUrl + '/images';
        let obj = {image: image, like: true};
        ajax.put(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('likeImage', json));
            }
        });

    };
};

export let unlikeImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('unlikeImage'));
        let url = appUrl + '/images';
        let obj = {image: image, like: true};
        ajax.delete(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('unlikeImage', json));
            }
        });

    };
};

// Thunk action to GET all images from the server
export let getAllImages = () => {
    return function(dispatch) {
        dispatch(actionAjaxStart('allImages'));
        let url = appUrl + '/images';
        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('allImages', json));
            }
        });
    };
};

// Thunk action to remove an image from the user profile
export let removeImage = (img) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('removeImage'));
        let url = appUrl + '/images';
        let obj = {image: img};
        ajax.delete(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('removeImage', json));
            }
        });
    };
};

//----------------------------------------------
// SIMPLE ACTIONS
//----------------------------------------------

let actionError = (err) => ({
    type: 'ERROR',
    err: err
});

let actionAjaxStart = (fetchWhat) => {
    _actionDebug(fetchWhat);
    return {
        type: 'AJAX_START',
        what: fetchWhat
    };
};

let actionAjaxDone = (recWhat, json) => {
    _actionDebug(recWhat, json);
    return {
        type: 'AJAX_DONE',
        what: recWhat,
        json
    };
};

let closeUserWall = (username) => ({
    type: 'CLOSE_USER',
    username: username
});

let showUserWall = (username) => ({
    type: 'SHOW_USER_WALL',
    username: username
});

let fetchImage = () => ({
    type: 'FETCH_IMAGE'
});

let receiveImage = (json) => {
    return {
        type: 'RECEIVE_IMAGE',
        json
    };
};

let showUserList = () => {
    return {
        type: 'SHOW_USER_LIST'
    };
};

export {closeUserWall, showUserList, showUserWall};
<commit_msg>Added searchImages and actionChangeTab.<commit_after>
const ajax = require('../common/ajax-functions');

let appUrl = window.location.origin;

//---------------
// Actions
//---------------

let _actionDebug = (info, json) => {
    console.log('[ActionDebug]: ' + info);
    if (json) {
        console.log('[ActionDebug] ' + info + ' json: '
            + JSON.stringify(json));
    }
};

//----------------------------------------------
// THUNK ACTIONS
//----------------------------------------------

// Thunk action to retrieve a list of users
export let getUserList = () => {
    return function(dispatch) {

        dispatch(actionAjaxStart('getUserList'));
        let url = appUrl + '/users/list';

        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('getUserList', json));
            }
        });
    };
};

export let getUserWall = (username) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('getUserWall'));
        let url = appUrl + '/users/wall/' + username;
        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('getUserWall', json));
            }
        });
    };
};

// Thunk action to retrieve user info
export let getUserInfo = () => {
    return function(dispatch) {
        dispatch(actionAjaxStart('getUserInfo'));
        let url = appUrl + '/users';
        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('getUserInfo', json));
            }
        });
    };
};

// Thunk action to send POST to server with image data
export let addImage = (obj) => {
    return function(dispatch) {
        dispatch(fetchImage());
        let url = appUrl + '/images';
        ajax.post(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(receiveImage(json));
            }
        });

    };
};

export let linkImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('linkImage'));
        let url = appUrl + '/images';
        let obj = {image: image, link: true};
        ajax.put(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('linkImage', json));
            }
        });

    };
};

export let unlinkImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('unlinkImage'));
        let url = appUrl + '/images';
        let obj = {image: image, link: true};
        ajax.delete(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('unlinkImage', json));
            }
        });

    };
};

export let likeImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('likeImage'));
        let url = appUrl + '/images';
        let obj = {image: image, like: true};
        ajax.put(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('likeImage', json));
            }
        });

    };
};

export let unlikeImage = (image) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('unlikeImage'));
        let url = appUrl + '/images';
        let obj = {image: image, like: true};
        ajax.delete(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('unlikeImage', json));
            }
        });

    };
};

// Thunk action to GET all images from the server
export let getAllImages = () => {
    return function(dispatch) {
        dispatch(actionAjaxStart('allImages'));
        let url = appUrl + '/images';
        ajax.get(url, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('allImages', json));
            }
        });
    };
};

// Thunk action to remove an image from the user profile
export let removeImage = (img) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('removeImage'));
        let url = appUrl + '/images';
        let obj = {image: img};
        ajax.delete(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('removeImage', json));
            }
        });
    };
};

/* Used when a user sends an image search request.*/
export let searchImages = (query) => {
    return function(dispatch) {
        dispatch(actionAjaxStart('searchImages'));
        let url = appUrl + '/search';
        let obj = {query: query};
        ajax.post(url, obj, (err, respText) => {
            if (err) {
                dispatch(actionError(err));
            }
            else {
                let json = JSON.parse(respText);
                dispatch(actionAjaxDone('searchImages', json));
            }
        });

    };

};

//----------------------------------------------
// SIMPLE ACTIONS
//----------------------------------------------

let actionError = (err) => ({
    type: 'ERROR',
    err: err
});

let actionAjaxStart = (fetchWhat) => {
    _actionDebug(fetchWhat);
    return {
        type: 'AJAX_START',
        what: fetchWhat
    };
};

let actionAjaxDone = (recWhat, json) => {
    _actionDebug(recWhat, json);
    return {
        type: 'AJAX_DONE',
        what: recWhat,
        json
    };
};

export let actionChangeTab = (newTab, oldTab) => ({
    type: 'CHANGE_TAB',
    newTab: newTab,
    oldTab: oldTab
});

let closeUserWall = (username) => ({
    type: 'CLOSE_USER',
    username: username
});

let showUserWall = (username) => ({
    type: 'SHOW_USER_WALL',
    username: username
});

let fetchImage = () => ({
    type: 'FETCH_IMAGE'
});

let receiveImage = (json) => {
    return {
        type: 'RECEIVE_IMAGE',
        json
    };
};

let showUserList = () => {
    return {
        type: 'SHOW_USER_LIST'
    };
};

export {closeUserWall, showUserList, showUserWall};
<|endoftext|>


<commit_before>'use strict';

/**
 * Dependencies
 */
var assert = require('assert')
  , fs = require('fs')
  , wrench = require('wrench')
  , _ = require('lodash')
  , path = require('path')
  , exec = require('child_process').exec;

describe('Generate', function(){
  describe('New application', function(){
    var bin = './bin/koan.js';
    var appName = 'testApp';

    before(function(done) {
      fs.exists(appName, function(exists) {
        if (exists) {
          wrench.rmdirSyncRecursive(appName);
        }
        done();
      });
    });

    after(function(done) {
      fs.exists(appName, function(exists) {
        if (exists) {
          wrench.rmdirSyncRecursive(appName);
        }
        done();
      });
    });

    it('should create a new application', function(done) {
      exec(bin + ' new ' + appName, function(err) {
        if (err)
          return done(new Error(err));

        var nodeModulesPath = path.join(appName, 'node_modules');
        if (fs.existsSync(nodeModulesPath))
          wrench.rmdirSyncRecursive(nodeModulesPath);

        assert(checkGeneratedFiles(appName), 'generated files don\'t match expected files');
        done();
      });
    });

    it('should test the new application successfully', function(done) {
      exec('cd ' + appName + ' && npm install && npm test', function(err) {
        if (err)
          return done(new Error(err));

        assert(!err, 'an error occurred while trying to test a newly created application');
        done();
      });
    });
  });
});

function checkGeneratedFiles(appName) {
  var expectedFiles = [
          '.gitignore',
          'index.js',
          'public',
          'config',
          'package.json',
          'README.md',
          'controllers',
          'controllers/index.js',
          'controllers/pages.js',
          'views',
          'views/home.ejs',
          'views/pages',
          'views/pages/about.ejs',
          'public/images',
          'public/js',
          'public/robots.txt',
          'public/css',
          'public/images/.gitkeep',
          'public/images/define_koan.png',
          'public/js/.gitkeep',
          'public/css/.gitkeep',
          'config/routes.js',
          'config/options.js',
          'config/index.js',
          'config/environments',
          'config/environments/development.js',
          'config/environments/production.js',
          'test',
          'test/index.test.js',
          'test/mocha.opts'
  ];

  // Read actual generated files from disk
  var files = wrench.readdirSyncRecursive(appName);

  // Disregard stupid files
  // (fs-specific, OS-specific, editor-specific, yada yada)
  files = _.reject(files, function(f) {
    return f.match(/^node_modules/) || f.match(/.DS_Store/gi) || f.match(/\*~$/);
  });

  // Generate diff
  var diff = _.difference(files, expectedFiles);

  // Uneven # of files
  if (files.length !== expectedFiles.length) {
    return false;
  }

  // Files don't match
  if (diff.length !== 0) {
    return false;
  }

  // Everything's ok!
  return true;
}
<commit_msg>Test code style improved.<commit_after>'use strict';

/**
 * Dependencies
 */
var assert = require('assert');
var fs = require('fs');
var wrench = require('wrench');
var _ = require('lodash');
var path = require('path');
var exec = require('child_process').exec;

describe('Generate', function() {
  describe('New application', function() {
    var bin = './bin/koan.js';
    var appName = 'testApp';

    before(function(done) {
      fs.exists(appName, function(exists) {
        if (exists) {
          wrench.rmdirSyncRecursive(appName);
        }
        done();
      });
    });

    after(function(done) {
      fs.exists(appName, function(exists) {
        if (exists) {
          wrench.rmdirSyncRecursive(appName);
        }
        done();
      });
    });

    it('should create a new application', function(done) {
      exec(bin + ' new ' + appName, function(err) {
        if (err)
          return done(new Error(err));

        var nodeModulesPath = path.join(appName, 'node_modules');
        if (fs.existsSync(nodeModulesPath))
          wrench.rmdirSyncRecursive(nodeModulesPath);

        assert(checkGeneratedFiles(appName), 'generated files don\'t match expected files');
        done();
      });
    });

    it('should test the new application successfully', function(done) {
      exec('cd ' + appName + ' && npm install && npm test', function(err) {
        if (err)
          return done(new Error(err));

        assert(!err, 'an error occurred while trying to test a newly created application');
        done();
      });
    });
  });
});

function checkGeneratedFiles(appName) {
  var expectedFiles = [
    '.gitignore',
    'index.js',
    'public',
    'config',
    'package.json',
    'README.md',
    'controllers',
    'controllers/index.js',
    'controllers/pages.js',
    'views',
    'views/home.ejs',
    'views/pages',
    'views/pages/about.ejs',
    'public/images',
    'public/js',
    'public/robots.txt',
    'public/css',
    'public/images/.gitkeep',
    'public/images/define_koan.png',
    'public/js/.gitkeep',
    'public/css/.gitkeep',
    'config/routes.js',
    'config/options.js',
    'config/index.js',
    'config/environments',
    'config/environments/development.js',
    'config/environments/production.js',
    'test',
    'test/index.test.js',
    'test/mocha.opts'
  ];

  // Read actual generated files from disk
  var files = wrench.readdirSyncRecursive(appName);

  // Disregard stupid files
  // (fs-specific, OS-specific, editor-specific, yada yada)
  files = _.reject(files, function(f) {
    return f.match(/^node_modules/) || f.match(/.DS_Store/gi) || f.match(/\*~$/);
  });

  // Generate diff
  var diff = _.difference(files, expectedFiles);

  // Uneven # of files
  if (files.length !== expectedFiles.length) {
    return false;
  }

  // Files don't match
  if (diff.length !== 0) {
    return false;
  }

  // Everything's ok!
  return true;
}
<|endoftext|>


<commit_before>exports.tests = {

  notfound_getelementsbyclassname : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.className = "unknown";
      body.appendChild(p);

      var elements = doc.getElementsByClassName("first-p");
      assertEquals("no results", 0, elements.length);
  },

  basic_getelementsbyclassname : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.className = "first-p";
      body.appendChild(p);

      var elements = doc.getElementsByClassName("first-p");
      assertSame("p and first-p", p, elements.item(0));
  },

  multiple_getelementsbyclassname : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.className = "first-p second third";
      body.appendChild(p);

      var first = doc.getElementsByClassName("first-p");
      assertSame("p and first-p", p, first.item(0));

      var second = doc.getElementsByClassName("second");
      assertSame("p and second", p, second.item(0));

      var third = doc.getElementsByClassName("third");
      assertSame("p and third", p, third.item(0));
  },

  testclassnameworksasexpected : function() {
      var doc = new browser.Document();
      var p = doc.createElement("p");
      p.setAttribute("class", "first-p");
      assertSame("class attribute is same as className", p.className,"first-p");

      p.className += " second";
      assertSame("className getter/setter", p.className,"first-p second");
  },

  basic_getelementbyid : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.id = "theid";
      body.appendChild(p);

      var element = doc.getElementById("theid");
      assertSame("p and #theid", p, element);
  },
  nonexistant_getelementbyid : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.id = "theid";
      body.appendChild(p);

      var element = doc.getElementById("non-existant-id");
      assertSame("p and #theid", null, element);
  },
  remove_nonexistantattribute : function() {
      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      exception = false;
      try {
        removedNode = body.removeAttribute("non-existant");
      }
      catch(ex) {
        exception = true;
      }
      assertFalse("setValue_throws_NO_MODIFICATION_ERR", exception);
  },
  render_singletag : function() {
      var doc = new browser.Document();

      var p = doc.createElement("p");

      var img = doc.createElement("img");
      p.appendChild(img);
      var out = p.outerHTML;
      assertNull("end tag not included in output", out.match(/<\/img>/));
  },
  parse_scripttags : function() {
    var doc = new browser.Document();

    var head = doc.createElement("head");
    var scriptHtml = '';
    head.innerHTML = scriptHtml;

    assertEquals("original and processed", head.innerHTML, scriptHtml);

  },
  parse_styletags : function() {
    var doc = new browser.Document();

    var head = doc.createElement("head");
    var styleHtml = '';
    head.innerHTML = styleHtml;

    assertEquals("original and processed", head.innerHTML, styleHtml);

  },
  parse_doublespacetags : function() {
    var doc = new browser.Document();

    var html = '';

    exception = false;
    try {
      doc.innerHTML = html;
    }
    catch(ex) {
      exception = true;
    }
    assertFalse("setValue_throws_INVALID_CHARACTER_ERR", exception);
  },
  serialize_styleattribute : function() {
    var doc = new browser.Document();
    doc.appendChild(doc.createElement('html'));
    doc.documentElement.style.color = 'black';
    doc.documentElement.style.backgroundColor = 'white';
    assertEquals('',
              '\r\n',
              require('../../lib/jsdom/browser/domtohtml').domToHtml(doc));
  },
  innerhtml_removeallchildren: function() {
    var doc = new browser.HTMLDocument();
    doc.write('

');
    doc.body.innerHTML = '';
    assertTrue('still has children', doc.body.childNodes.length == 0);
  },
  serialize_html5_doctype : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('html');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('HTML 5 doctype did not serialize correctly',
        /^\s*<!DOCTYPE html>/.test(document.outerHTML));
  },
  serialize_html4_strict_doctype : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('html',
        '-//W3C//DTD HTML 4.01//EN',
        'http://www.w3.org/TR/html4/strict.dtd');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('HTML 4 strict doctype did not serialize correctly',
        /^\s*<!DOCTYPE html PUBLIC "-\/\/W3C\/\/DTD HTML 4.01\/\/EN" "http:\/\/www.w3.org\/TR\/html4\/strict.dtd">/.
            test(document.outerHTML));
  },
  serialize_system_doctype : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('foo', null, 'foo.dtd');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('Doctype did not serialize correctly',
        /^\s*<!DOCTYPE foo SYSTEM "foo.dtd">/.test(document.outerHTML));
  },
  serialize_doctype_containing_quotes : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('foo', null, 'foo "bar".dtd');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('Doctype did not serialize correctly',
        /^\s*<!DOCTYPE foo SYSTEM \'foo "bar".dtd\'>/.test(document.outerHTML));
  }
};
<commit_msg>added test case to exercise NodeList#indexOf()<commit_after>exports.tests = {

  notfound_getelementsbyclassname : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.className = "unknown";
      body.appendChild(p);

      var elements = doc.getElementsByClassName("first-p");
      assertEquals("no results", 0, elements.length);
  },

  basic_getelementsbyclassname : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.className = "first-p";
      body.appendChild(p);

      var elements = doc.getElementsByClassName("first-p");
      assertSame("p and first-p", p, elements.item(0));
  },

  multiple_getelementsbyclassname : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.className = "first-p second third";
      body.appendChild(p);

      var first = doc.getElementsByClassName("first-p");
      assertSame("p and first-p", p, first.item(0));

      var second = doc.getElementsByClassName("second");
      assertSame("p and second", p, second.item(0));

      var third = doc.getElementsByClassName("third");
      assertSame("p and third", p, third.item(0));
  },

  testclassnameworksasexpected : function() {
      var doc = new browser.Document();
      var p = doc.createElement("p");
      p.setAttribute("class", "first-p");
      assertSame("class attribute is same as className", p.className,"first-p");

      p.className += " second";
      assertSame("className getter/setter", p.className,"first-p second");
  },

  basic_getelementbyid : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.id = "theid";
      body.appendChild(p);

      var element = doc.getElementById("theid");
      assertSame("p and #theid", p, element);
  },
  nonexistant_getelementbyid : function() {

      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      var p = doc.createElement("p");
      p.id = "theid";
      body.appendChild(p);

      var element = doc.getElementById("non-existant-id");
      assertSame("p and #theid", null, element);
  },
  remove_nonexistantattribute : function() {
      var doc = new browser.Document();

      var html = doc.createElement("html");
      doc.appendChild(html);

      var body = doc.createElement("body");
      html.appendChild(body);

      exception = false;
      try {
        removedNode = body.removeAttribute("non-existant");
      }
      catch(ex) {
        exception = true;
      }
      assertFalse("setValue_throws_NO_MODIFICATION_ERR", exception);
  },
  render_singletag : function() {
      var doc = new browser.Document();

      var p = doc.createElement("p");

      var img = doc.createElement("img");
      p.appendChild(img);
      var out = p.outerHTML;
      assertNull("end tag not included in output", out.match(/<\/img>/));
  },
  parse_scripttags : function() {
    var doc = new browser.Document();

    var head = doc.createElement("head");
    var scriptHtml = '';
    head.innerHTML = scriptHtml;

    assertEquals("original and processed", head.innerHTML, scriptHtml);

  },
  parse_styletags : function() {
    var doc = new browser.Document();

    var head = doc.createElement("head");
    var styleHtml = '';
    head.innerHTML = styleHtml;

    assertEquals("original and processed", head.innerHTML, styleHtml);

  },
  parse_doublespacetags : function() {
    var doc = new browser.Document();

    var html = '';

    exception = false;
    try {
      doc.innerHTML = html;
    }
    catch(ex) {
      exception = true;
    }
    assertFalse("setValue_throws_INVALID_CHARACTER_ERR", exception);
  },
  serialize_styleattribute : function() {
    var doc = new browser.Document();
    doc.appendChild(doc.createElement('html'));
    doc.documentElement.style.color = 'black';
    doc.documentElement.style.backgroundColor = 'white';
    assertEquals('',
              '\r\n',
              require('../../lib/jsdom/browser/domtohtml').domToHtml(doc));
  },
  innerhtml_removeallchildren: function() {
    var doc = new browser.HTMLDocument();
    doc.write('

');
    doc.body.innerHTML = '';
    assertTrue('still has children', doc.body.childNodes.length == 0);
  },
  serialize_html5_doctype : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('html');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('HTML 5 doctype did not serialize correctly',
        /^\s*<!DOCTYPE html>/.test(document.outerHTML));
  },
  serialize_html4_strict_doctype : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('html',
        '-//W3C//DTD HTML 4.01//EN',
        'http://www.w3.org/TR/html4/strict.dtd');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('HTML 4 strict doctype did not serialize correctly',
        /^\s*<!DOCTYPE html PUBLIC "-\/\/W3C\/\/DTD HTML 4.01\/\/EN" "http:\/\/www.w3.org\/TR\/html4\/strict.dtd">/.
            test(document.outerHTML));
  },
  serialize_system_doctype : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('foo', null, 'foo.dtd');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('Doctype did not serialize correctly',
        /^\s*<!DOCTYPE foo SYSTEM "foo.dtd">/.test(document.outerHTML));
  },
  serialize_doctype_containing_quotes : function () {
    var dom = new browser.DOMImplementation();
    var doctype = dom.createDocumentType('foo', null, 'foo "bar".dtd');
    var document = dom.createDocument(null, null, doctype);
    assertTrue('Doctype did not serialize correctly',
        /^\s*<!DOCTYPE foo SYSTEM \'foo "bar".dtd\'>/.test(document.outerHTML));
  },
  basic_nodelist_indexOf : function() {
    var doc = new browser.Document();

    var html = doc.createElement("html");
    doc.appendChild(html);

    var body = doc.createElement("body");
    html.appendChild(body);

    var p = doc.createElement("p");
    body.appendChild(p);

    var div = doc.createElement("div");
    body.appendChild(div);

    var span = doc.createElement("span");
    body.appendChild(span);

    var index = body.childNodes.indexOf(span);
    assertEquals("indexOf 'span' in childNodes", 2, index);
  },
  nonexistant_nodelist_indexOf : function() {
    var doc = new browser.Document();

    var html = doc.createElement("html");
    doc.appendChild(html);

    var body = doc.createElement("body");
    html.appendChild(body);

    var p = doc.createElement("p");
    body.appendChild(p);

    var div = doc.createElement("div");
    p.appendChild(div);

    var index = body.childNodes.indexOf(div);
    assertEquals("indexOf 'span' in childNodes", -1, index);
  }
};
<|endoftext|>


<commit_before>import * as utils from "../shared/search-utils.js";

export function setup(options) {
  return new Promise((resolve, reject) => {
    let location = options.path.replace(window.location.origin, "");
    console.log("setup location:", options.path);

    let fetchStatus =  () => {
      fetch(`${window.location.origin}/api/search/createIndex?location=${location}`).then( async (response) => {
        let responseJson = await response.json();
        if (responseJson.indexStatus == "available") {
          resolve();
          clearInterval(interval);
        }
      }, () => {
        reject();
      });
    };

    fetchStatus();
    let interval = setInterval(fetchStatus, 5000);
  });
}

export function find(pattern) {
  // find is bound to the mount object, so -this- is the mount
  let location = this.path.replace(window.location.origin, "");

  // test
  return fetch(`${window.location.origin}/api/search/search?q=${pattern}&location=${location}`).then( async (response) => {
    if (response.status != 200) {
      return [];
    }

    let responseJson = await response.json();
    return responseJson.map((res) => {
      res.path = window.location.origin + utils.join(this.path, res.ref);
      res.type = "server";
      return res;
    });
  });
}

export function getStatus(subdir, options) {
  return fetch(`${window.location.origin}/api/search/statusIndex?location=${subdir}`).then((response) => {
    return response.json();
  }).then(responseJson =>{
    return responseJson.indexStatus;
  });
}

export function removeIndex(subdir, options) {
  return fetch(`${window.location.origin}/api/search/removeIndex?location=${subdir}`);
}
<commit_msg>make api calls relative<commit_after>import * as utils from "../shared/search-utils.js";

export function setup(options) {
  return new Promise((resolve, reject) => {
    let location = options.path.replace(window.location.origin, "");
    console.log("setup location:", options.path);

    let fetchStatus =  () => {
      fetch(`api/search/createIndex?location=${location}`).then( async (response) => {
        let responseJson = await response.json();
        if (responseJson.indexStatus == "available") {
          resolve();
          clearInterval(interval);
        }
      }, () => {
        reject();
      });
    };

    fetchStatus();
    let interval = setInterval(fetchStatus, 5000);
  });
}

export function find(pattern) {
  // find is bound to the mount object, so -this- is the mount
  let location = this.path.replace(window.location.origin, "");

  // test
  return fetch(`api/search/search?q=${pattern}&location=${location}`).then( async (response) => {
    if (response.status != 200) {
      return [];
    }

    let responseJson = await response.json();
    return responseJson.map((res) => {
      res.path = window.location.origin + utils.join(this.path, res.ref);
      res.type = "server";
      return res;
    });
  });
}

export function getStatus(subdir, options) {
  return fetch(`api/search/statusIndex?location=${subdir}`).then((response) => {
    return response.json();
  }).then(responseJson =>{
    return responseJson.indexStatus;
  });
}

export function removeIndex(subdir, options) {
  return fetch(`api/search/removeIndex?location=${subdir}`);
}
<|endoftext|>


<commit_before>(function($) {
  "use strict";
  $.fn.multifilter = function(options) {
    var settings = $.extend( {
      'target'        : $('table'),
      'method'    : 'thead' // This can be thead or class
    }, options);

    jQuery.expr[":"].Equals = function(a, i, m) {
      return (a.textContent || a.innerText || "").toUpperCase() === m[3].toUpperCase();
    };

    this.each(function() {
      var $this = $(this);
      var container = settings.target;
      var row_tag = 'tr';
      var item_tag = 'td';
      var rows = container.find($(row_tag));

      if (settings.method === 'thead') {
        // Match the data-col attribute to the text in the thead
        var col = container.find('th:Equals(' + $this.data('col') + ')');
        var col_index = container.find($('thead th')).index(col);
      };

      if (settings.method === 'class') {
        // Match the data-col attribute to the class on each column
        var col = rows.first().find('td.' + $this.data('col') + '');
        var col_index = rows.first().find('td').index(col);
      };

      $this.change(function() {
        var filter = $this.val();
        rows.each(function() {
          var row = $(this);
          var cell = $(row.children(item_tag)[col_index]);
          if (filter) {
            if (cell.text().toLowerCase().indexOf(filter.toLowerCase()) !== -1) {
              cell.attr('data-filtered', 'positive');
            } else {
              cell.attr('data-filtered', 'negative');
            }
            if (row.find(item_tag + "[data-filtered=negative]").size() > 0) {
               row.hide();
            } else {
              if (row.find(item_tag + "[data-filtered=positive]").size() > 0) {
                row.show();
              }
            }
          } else {
            cell.attr('data-filtered', 'positive');
            if (row.find(item_tag + "[data-filtered=negative]").size() > 0) {
              row.hide();
            } else {
              if (row.find(item_tag + "[data-filtered=positive]").size() > 0) {
                row.show();
              }
            }
          }
        });
        return false;
      }).keyup(function() {
        $this.change();
      });
    });
  };
})(jQuery);
<commit_msg>Remove an empty string that we don't need<commit_after>(function($) {
  "use strict";
  $.fn.multifilter = function(options) {
    var settings = $.extend( {
      'target'        : $('table'),
      'method'    : 'thead' // This can be thead or class
    }, options);

    jQuery.expr[":"].Equals = function(a, i, m) {
      return (a.textContent || a.innerText || "").toUpperCase() === m[3].toUpperCase();
    };

    this.each(function() {
      var $this = $(this);
      var container = settings.target;
      var row_tag = 'tr';
      var item_tag = 'td';
      var rows = container.find($(row_tag));

      if (settings.method === 'thead') {
        // Match the data-col attribute to the text in the thead
        var col = container.find('th:Equals(' + $this.data('col') + ')');
        var col_index = container.find($('thead th')).index(col);
      };

      if (settings.method === 'class') {
        // Match the data-col attribute to the class on each column
        var col = rows.first().find('td.' + $this.data('col'));
        var col_index = rows.first().find('td').index(col);
      };

      $this.change(function() {
        var filter = $this.val();
        rows.each(function() {
          var row = $(this);
          var cell = $(row.children(item_tag)[col_index]);
          if (filter) {
            if (cell.text().toLowerCase().indexOf(filter.toLowerCase()) !== -1) {
              cell.attr('data-filtered', 'positive');
            } else {
              cell.attr('data-filtered', 'negative');
            }
            if (row.find(item_tag + "[data-filtered=negative]").size() > 0) {
               row.hide();
            } else {
              if (row.find(item_tag + "[data-filtered=positive]").size() > 0) {
                row.show();
              }
            }
          } else {
            cell.attr('data-filtered', 'positive');
            if (row.find(item_tag + "[data-filtered=negative]").size() > 0) {
              row.hide();
            } else {
              if (row.find(item_tag + "[data-filtered=positive]").size() > 0) {
                row.show();
              }
            }
          }
        });
        return false;
      }).keyup(function() {
        $this.change();
      });
    });
  };
})(jQuery);
<|endoftext|>


<commit_before>var assert = require("chai").assert;
var Duckface = require("../src/duckface.js");

describe('Duckface', function(){
    describe('#constructor', function(){
        it('should throw error when no arguments are provided', function(){
            assert.throws(
                function(){
                    var d = new Duckface();
                },
                Error
            );
        });

        it('should throw error when more than 2 arguments are provided', function(){
            assert.throws(
                function(){
                    var d = new Duckface('foo', 'bar', 'baz');
                },
                Error
            );
        });

        it('should throw error when not called as a constructor', function(){
            assert.throws(
                function(){
                    Duckface('foo', 'bar');
                },
                Error
            );
        });

        it('should throw error when first argument is not a string', function(){
            assert.throws(
                function(){
                    var d = new Duckface(123, 'bar');
                },
                Error
            );
        });

        it('should throw error when second argument is not an object or array', function(){
            assert.throws(
                function(){
                    var d = new Duckface('Foo', 'bar');
                },
                Error
            );

            assert.throws(
                function(){
                    var d = new Duckface('Foo', 123);
                },
                Error
            );

            assert.doesNotThrow(
                function(){
                    var d = new Duckface('Foo', []);
                },
                Error
            );

            assert.doesNotThrow(
                function(){
                    var d = new Duckface('Foo', {});
                },
                Error
            );
        });

        it('should throw error when second argument contains a non-string', function(){
            assert.throws(
                function(){
                    var d = new Duckface('Foo', ['bar', 'baz', 123]);
                },
                Error
            );

            assert.doesNotThrow(
                function(){
                    var d = new Duckface('Foo', ['bar', 'baz']);
                },
                Error
            );
        });

        it('should add an object to internal property when a valid method-name is provided', function(){
            var methods = ['bar', 'baz'];
            var d = new Duckface('Foo', methods);
            assert.lengthOf(d.methods, methods.length);
            for (var i =0; i < d.methods.length; i++) {
                assert.isObject(d.methods[i]);
                assert.lengthOf(Object.keys(d.methods[i]), 2);
                assert.property(d.methods[i], 'name');
                assert.property(d.methods[i], 'args');
                assert.equal(d.methods[i].name, methods[i]);
                assert.isNull(d.methods[i].args);
            }
        });

        it('should be an instance of Duckface', function(){
            var d = new Duckface('Foo', []);
            assert.instanceOf(d, Duckface);
        });

        it('should add an object to internal property when a valid method-name and function signature are provided', function() {
            var signatures = {
                'foo':function(bar, baz) {},
                'test':function() {}
            };
            var d = new Duckface('Dummy', signatures);
            var keys = Object.keys(signatures);
            assert.lengthOf(d.methods, keys.length);
            for (var i =0; i < d.methods.length; i++) {
                assert.isObject(d.methods[i]);
                assert.lengthOf(Object.keys(d.methods[i]), 2);
                assert.property(d.methods[i], 'name');
                assert.property(d.methods[i], 'args');
                var key = keys[i];
                assert.equal(d.methods[i].name, key);
                assert.isArray(d.methods[i].args);
                if (i === 0) {
                    assert.sameMembers(
                        d.methods[i].args,
                        ['bar', 'baz']
                    );
                }
                if (i === 1) {
                    assert.lengthOf(d.methods[i].args, 0);
                }
            }
        });
    });
});
<commit_msg>Added extra test<commit_after>var assert = require("chai").assert;
var Duckface = require("../src/duckface.js");

describe('Duckface', function(){
    describe('#constructor', function(){
        it('should throw error when no arguments are provided', function(){
            assert.throws(
                function(){
                    var d = new Duckface();
                },
                Error
            );
        });

        it('should throw error when more than 2 arguments are provided', function(){
            assert.throws(
                function(){
                    var d = new Duckface('foo', 'bar', 'baz');
                },
                Error
            );
        });

        it('should throw error when not called as a constructor', function(){
            assert.throws(
                function(){
                    Duckface('foo', 'bar');
                },
                Error
            );
        });

        it('should throw error when first argument is not a string', function(){
            assert.throws(
                function(){
                    var d = new Duckface(123, 'bar');
                },
                Error
            );
        });

        it('should throw error when second argument is not an object or array', function(){
            assert.throws(
                function(){
                    var d = new Duckface('Foo', 'bar');
                },
                Error
            );

            assert.throws(
                function(){
                    var d = new Duckface('Foo', 123);
                },
                Error
            );

            assert.doesNotThrow(
                function(){
                    var d = new Duckface('Foo', []);
                },
                Error
            );

            assert.doesNotThrow(
                function(){
                    var d = new Duckface('Foo', {});
                },
                Error
            );
        });

        it('should throw error when second argument contains a non-string', function(){
            assert.throws(
                function(){
                    var d = new Duckface('Foo', ['bar', 'baz', 123]);
                },
                Error
            );

            assert.doesNotThrow(
                function(){
                    var d = new Duckface('Foo', ['bar', 'baz']);
                },
                Error
            );
        });

        it('should add an object to internal property when a valid method-name is provided', function(){
            var methods = ['bar', 'baz'];
            var d = new Duckface('Foo', methods);
            assert.lengthOf(d.methods, methods.length);
            for (var i =0; i < d.methods.length; i++) {
                assert.isObject(d.methods[i]);
                assert.lengthOf(Object.keys(d.methods[i]), 2);
                assert.property(d.methods[i], 'name');
                assert.property(d.methods[i], 'args');
                assert.equal(d.methods[i].name, methods[i]);
                assert.isNull(d.methods[i].args);
            }
        });

        it('should be an instance of Duckface', function(){
            var d = new Duckface('Foo', []);
            assert.instanceOf(d, Duckface);
        });

        it('should add an object to internal property when a valid method-name and function signature are provided', function() {
            var signatures = {
                'foo':function(bar, baz) {},
                'test':function() {}
            };
            var d = new Duckface('Dummy', signatures);
            var keys = Object.keys(signatures);
            assert.lengthOf(d.methods, keys.length);
            for (var i =0; i < d.methods.length; i++) {
                assert.isObject(d.methods[i]);
                assert.lengthOf(Object.keys(d.methods[i]), 2);
                assert.property(d.methods[i], 'name');
                assert.property(d.methods[i], 'args');
                var key = keys[i];
                assert.equal(d.methods[i].name, key);
                assert.isArray(d.methods[i].args);
                if (i === 0) {
                    assert.sameMembers(
                        d.methods[i].args,
                        ['bar', 'baz']
                    );
                }
                if (i === 1) {
                    assert.lengthOf(d.methods[i].args, 0);
                }
            }
        });
    });

    describe('#ensureImplements', function() {
        it('should throw error when no arguments are provided', function(){
            assert.throws(
                function(){
                    Duckface.ensureImplements();
                },
                Error
            );
        });
    });
});
<|endoftext|>


<commit_before>
exports.test = (r) => console.log(response[2]);

//exports.newMethod = (r) =>

exports.randHash = (r) => hashtags[Math.floor(Math.random() * hashtags.length)];
//-----------------------------------------------

var doc = " If symptoms persist, seek your healthcare professional."
var response = [
	"Drink lots of fluids and lie down." + doc,
	"Sounds painful! Try drinking some soda or applying a heat pack to the area." + doc,
	"Keep lots of tissues on hand or use a saline nasal spray." + doc,
	"You might have a cold! Try taking some over-the-counter cold medicine." + doc,
	"Stop scratching! Try rubbing some over-the-counter itch ointment on the area." + doc,
	"Stretch and ice after workouts or strenuous activities." + doc,

	];

var symptoms = {
	"head hurts": response[0],
	"headache": response[0],
	"head ache": response[0],
	"head aches": response[0],
	"head is bothering me": response[0],

	"tummy hurts": response[1],
	"tummyache": response[1],
	"tummy ache": response[1],
	"tummy aches": response[1],
	"tummy is bothering me": response[1],

	"stomach hurts": response[1],
	"stomachache": response[1],
	"stomach aches": response[1],
	"stomach ache": response[1],
	"stomach is bothering me": response[1],

	"runny nose": response[2],
	"nose is running": response[2],
	"nose is runny": response[2],

	"cough": response[3],
	"coughing": response[3],
	"itchy throat": response[3],
	"sore throat": response[3],
	"swollen throat": response[3],
	"throat hurts": response[3],
	"throat aches": response[3],
	"irritated throat": response[3],

	"rash": response[4],
	"itchy": response[4],
	"irritated skin": response[4],

	"sore muscles": response[5],
	"sore muscle": response[5],
	"muscles are sore": response[5],
	"muscle is sore": response[5],
};

var hashtags  = [
	"#sick",
	"#ill",
	"#hurts",
	"#health",
	"#healthcare",
	"#medicine",
	"#meds",
	"#medical",
	"#infection",
	];

/*
var healthTerms = 'Abdominal Pain
	Abdominal Pain in Children
	Acetaminophen Poisoning
	Alcohol Intoxication
	Allergic Reaction
	Altitude/Mountain Sickness
	Amputation (Accidental)
	Animal Bites
	Ankle Fracture
	Ankle Sprain
	Anthrax
	Aspirin Poisoning
	Asthma Attack
	Asthma Attack in Children
	Asthma Attack in Pregnancy
	Battery Ingestion
	Bends/Decompression Syndrome
	Black Eye
	Black Widow Spider Bite
	Bleeding
	Bleeding During Pregnancy
	Bleeding Under Nails
	Blisters
	Blood in Stool
	Blood in the Urine
	Blue Lips (Cyanosis)
	Breathing Problems
	Broken Arm
	Broken Arm in Children
	Broken Collarbone
	Broken Elbow
	Broken Finger
	Broken Finger in Children
	Broken Foot
	Broken Hand
	Broken Hip
	Broken Jaw
	Broken Leg
	Broken Nose
	Broken or Knocked-out Teeth
	Broken Shoulder Blade
	Broken Toe
	Brown Recluse Spider Bite
	Bruises
	Bruises in Children
	Burns
	Burns/Scalds in Children
	Carbon Monoxide Poisoning
	Catfish Sting
	Chemical Burns
	Chemical Eye Burn
	Chest Injury
	Chest Pain
	Chest Pain (Angina)
	Choking
	Choking in Children
	Colds in Children
	Concussion
	Congestion in Children
	Constipation
	Convulsions in Children
	Coughs
	CPR for Adults
	CPR for Children
	Crabs (Pubic Lice)
	Cradle Cap
	Crying/Colic
	Cuts and Bleeding
	Cuts and Bleeding in Children
	Cyanide Poisoning
	Dehydration
	Dehydration in Children
	Diaper Rash
	Diarrhea
	Diarrhea in Children
	Diving Ear Pain
	Dizziness
	Drowning
	Drowning in Children
	Drug Allergy
	Drug Overdose
	Ear Foreign Body
	Ear Infections
	Eczema
	Elbow Dislocation
	Electric Shock
	Exercise-Induced Asthma
	Eye Bleeding (Hyphema)
	Eye Burns/Corneal Burns
	Eye Injuries
	Eye Injuries in Children
	Eye Sores/Corneal Ulcers
	Eyelid Inflammation
	Facial Fracture
	Fainting
	Fever in Adults
	Fever in Children
	Finger Dislocation
	Finger Injuries
	Fishhook Injuries
	Food Poisoning
	Foreign Body in the Eye
	Fracture or Dislocation
	Frostbite
	Gas Pain in Children
	Gastroenteritis Treatment
	Hand Injury
	Head Injury
	Head Injury in Children
	Headache
	Heart Attack
	Heart Palpatations
	Heat Exhaustion
	Heat Rash
	Heat Stroke
	Hiccups
	Hives
	Hives and Angioedema
	How to Operate an Automated External Defibrillator
	Human Bites
	Hyperventilation
	Hypothermia
	Inability to Urinate
	Insect Sting Allergy
	Insect Stings and Bites
	Insulin Reaction
	Iron Poisoning
	Jaundice
	Jellyfish Stings
	Knee Dislocation
	Knee Injury
	Labor
	Lice
	Lightning Strike
	Low Blood Sugar
	Migraine Headache
	Migraine Headache in Children
	Miscarriage
	Muscle Strain
	Nail Injuries
	Neck Strain
	Nose Foreign Body
	Nosebleeds
	Nursemaid Elbow
	Panic Attacks
	Paronychia
	Poison Ivy, Oak, or Sumac
	Poisoning
	Poisoning in Children
	Puncture Wound
	Rabies
	Rape/Sexual Assault
	Rashes
	Rectal Bleeding
	Rectal Foreign Object
	Rectal Pain
	Reflux (GERD) in Children
	Ricin Poisoning
	Ruptured Tendon
	Scratched Eye/Corneal Abrasion
	Seizure
	Seizure in Children
	Severe Allergic Reaction
	Shark Bite
	Shock
	Shock/Electrocution
	Shoulder and Neck Pain
	Shoulder Dislocation
	Shoulder Separation
	Skiers Thumb
	Slipped Disk
	Smoke Inhalation
	Snakebite
	Splinters
	Sprains and Strains
	Stingray Injury
	Stomach Ache/Nausea
	Stroke
	Stroke/TIA
	Sty
	Suicidal Thoughts
	Sunburn
	Swallowed Object
	Swollen Testicles/Orchitis
	Tailbone Injury
	Teething Pain
	Testicle Pain
	Tetanus
	Tick Removal
	Toothache
	Toxic Shock Syndrome
	Travelers Diarrhea
	Vaginal Bleeding
	Vaginal Foreign Body
	Vertigo
	Vomiting and Nausea
	Vomiting During Pregnancy
	Vomiting/Spitting Up in Children
	Whiplash
	Wrist Injury';
*/<commit_msg>Split method added<commit_after>
exports.test = (r) => console.log(response[2]);
exports.symArray = (r) => symptoms.split("\n");

//exports.newMethod = (r) =>

exports.randHash = (r) => hashtags[Math.floor(Math.random() * hashtags.length)];
//-----------------------------------------------

var doc = " If symptoms persist, seek your healthcare professional."
var response = [
	"Drink lots of fluids and lie down." + doc,
	"Sounds painful! Try drinking some soda or applying a heat pack to the area." + doc,
	"Keep lots of tissues on hand or use a saline nasal spray." + doc,
	"You might have a cold! Try taking some over-the-counter cold medicine." + doc,
	"Stop scratching! Try rubbing some over-the-counter itch ointment on the area." + doc,
	"Stretch and ice after workouts or strenuous activities." + doc,

	];

var symptoms = {
	"head hurts": response[0],
	"headache": response[0],
	"head ache": response[0],
	"head aches": response[0],
	"head is bothering me": response[0],

	"tummy hurts": response[1],
	"tummyache": response[1],
	"tummy ache": response[1],
	"tummy aches": response[1],
	"tummy is bothering me": response[1],

	"stomach hurts": response[1],
	"stomachache": response[1],
	"stomach aches": response[1],
	"stomach ache": response[1],
	"stomach is bothering me": response[1],

	"runny nose": response[2],
	"nose is running": response[2],
	"nose is runny": response[2],

	"cough": response[3],
	"coughing": response[3],
	"itchy throat": response[3],
	"sore throat": response[3],
	"swollen throat": response[3],
	"throat hurts": response[3],
	"throat aches": response[3],
	"irritated throat": response[3],

	"rash": response[4],
	"itchy": response[4],
	"irritated skin": response[4],

	"sore muscles": response[5],
	"sore muscle": response[5],
	"muscles are sore": response[5],
	"muscle is sore": response[5],
};

var hashtags  = [
	"#sick",
	"#ill",
	"#hurts",
	"#health",
	"#healthcare",
	"#medicine",
	"#meds",
	"#medical",
	"#infection",
	];

var healthTerms = `Abdominal Pain
	Abdominal Pain in Children
	Acetaminophen Poisoning
	Alcohol Intoxication
	Allergic Reaction
	Altitude/Mountain Sickness
	Amputation (Accidental)
	Animal Bites
	Ankle Fracture
	Ankle Sprain
	Anthrax
	Aspirin Poisoning
	Asthma Attack
	Asthma Attack in Children
	Asthma Attack in Pregnancy
	Battery Ingestion
	Bends/Decompression Syndrome
	Black Eye
	Black Widow Spider Bite
	Bleeding
	Bleeding During Pregnancy
	Bleeding Under Nails
	Blisters
	Blood in Stool
	Blood in the Urine
	Blue Lips (Cyanosis)
	Breathing Problems
	Broken Arm
	Broken Arm in Children
	Broken Collarbone
	Broken Elbow
	Broken Finger
	Broken Finger in Children
	Broken Foot
	Broken Hand
	Broken Hip
	Broken Jaw
	Broken Leg
	Broken Nose
	Broken or Knocked-out Teeth
	Broken Shoulder Blade
	Broken Toe
	Brown Recluse Spider Bite
	Bruises
	Bruises in Children
	Burns
	Burns/Scalds in Children
	Carbon Monoxide Poisoning
	Catfish Sting
	Chemical Burns
	Chemical Eye Burn
	Chest Injury
	Chest Pain
	Chest Pain (Angina)
	Choking
	Choking in Children
	Colds in Children
	Concussion
	Congestion in Children
	Constipation
	Convulsions in Children
	Coughs
	CPR for Adults
	CPR for Children
	Crabs (Pubic Lice)
	Cradle Cap
	Crying/Colic
	Cuts and Bleeding
	Cuts and Bleeding in Children
	Cyanide Poisoning
	Dehydration
	Dehydration in Children
	Diaper Rash
	Diarrhea
	Diarrhea in Children
	Diving Ear Pain
	Dizziness
	Drowning
	Drowning in Children
	Drug Allergy
	Drug Overdose
	Ear Foreign Body
	Ear Infections
	Eczema
	Elbow Dislocation
	Electric Shock
	Exercise-Induced Asthma
	Eye Bleeding (Hyphema)
	Eye Burns/Corneal Burns
	Eye Injuries
	Eye Injuries in Children
	Eye Sores/Corneal Ulcers
	Eyelid Inflammation
	Facial Fracture
	Fainting
	Fever in Adults
	Fever in Children
	Finger Dislocation
	Finger Injuries
	Fishhook Injuries
	Food Poisoning
	Foreign Body in the Eye
	Fracture or Dislocation
	Frostbite
	Gas Pain in Children
	Gastroenteritis Treatment
	Hand Injury
	Head Injury
	Head Injury in Children
	Headache
	Heart Attack
	Heart Palpatations
	Heat Exhaustion
	Heat Rash
	Heat Stroke
	Hiccups
	Hives
	Hives and Angioedema
	How to Operate an Automated External Defibrillator
	Human Bites
	Hyperventilation
	Hypothermia
	Inability to Urinate
	Insect Sting Allergy
	Insect Stings and Bites
	Insulin Reaction
	Iron Poisoning
	Jaundice
	Jellyfish Stings
	Knee Dislocation
	Knee Injury
	Labor
	Lice
	Lightning Strike
	Low Blood Sugar
	Migraine Headache
	Migraine Headache in Children
	Miscarriage
	Muscle Strain
	Nail Injuries
	Neck Strain
	Nose Foreign Body
	Nosebleeds
	Nursemaid Elbow
	Panic Attacks
	Paronychia
	Poison Ivy, Oak, or Sumac
	Poisoning
	Poisoning in Children
	Puncture Wound
	Rabies
	Rape/Sexual Assault
	Rashes
	Rectal Bleeding
	Rectal Foreign Object
	Rectal Pain
	Reflux (GERD) in Children
	Ricin Poisoning
	Ruptured Tendon
	Scratched Eye/Corneal Abrasion
	Seizure
	Seizure in Children
	Severe Allergic Reaction
	Shark Bite
	Shock
	Shock/Electrocution
	Shoulder and Neck Pain
	Shoulder Dislocation
	Shoulder Separation
	Skiers Thumb
	Slipped Disk
	Smoke Inhalation
	Snakebite
	Splinters
	Sprains and Strains
	Stingray Injury
	Stomach Ache/Nausea
	Stroke
	Stroke/TIA
	Sty
	Suicidal Thoughts
	Sunburn
	Swallowed Object
	Swollen Testicles/Orchitis
	Tailbone Injury
	Teething Pain
	Testicle Pain
	Tetanus
	Tick Removal
	Toothache
	Toxic Shock Syndrome
	Travelers Diarrhea
	Vaginal Bleeding
	Vaginal Foreign Body
	Vertigo
	Vomiting and Nausea
	Vomiting During Pregnancy
	Vomiting/Spitting Up in Children
	Whiplash
	Wrist Injury`;
<|endoftext|>


<commit_before>var should = require('should');
var wxr = require('../');
var test = require('./test').test;
var _ = require('underscore');

var site = new wxr.Site();

test('Constructor sets generator', function(){
	site.should.have.property('generator', 'wxr.js');
});

test('Expected properties exist', function(){
	site.should.have.property('title');
	site.should.have.property('link');
	site.should.have.property('description');
	site.should.have.property('language', 'en');
	site.should.have.property('pubDate');
	site.should.have.property('baseSiteURL');
	site.should.have.property('baseBlogURL');

	site.should.have.property('posts');
	site.should.have.property('tags');
	site.should.have.property('categories');

	site.should.respondTo('toWXR');
});

test('XML Nodes created', function(){
	var site = new wxr.Site();

	site.title = 'my site title';
	site.link = 'http://blahblahblah.com';

	var doc = site.toWXR();

	doc.should.have.property('children');
	doc.children[0].should.have.property('name', '?xml');

	var rootNode = doc.children[1];
	rootNode.should.have.property('name', 'channel');

	var titleNode = _(rootNode.children)
					.detect(function(c){ return c.name == 'title';});

	should.exist(titleNode);

	var valueNode = titleNode.children[0];
	valueNode.should.have.property('value', '<![CDATA[my site title]]>');

	var linkNode = _(rootNode.children)
					.detect(function(c){ return c.name == 'link';});

	should.exist(linkNode);

	valueNode = linkNode.children[0];

	valueNode.should.have.property('value', site.link);

	var descNode = _(rootNode.children)
					.detect(function(c){ return c.name == 'description';});

	should.exist(descNode);

	valueNode = descNode.children[0];
	valueNode.should.have.property('value', '<![CDATA[]]>');

});
<commit_msg>More site tests<commit_after>var should = require('should');
var wxr = require('../');
var test = require('./test').test;
var _ = require('underscore');

var site = new wxr.Site();

test('Constructor sets generator', function(){
	site.should.have.property('generator', 'wxr.js');
});

test('Expected properties exist', function(){
	site.should.have.property('title');
	site.should.have.property('link');
	site.should.have.property('description');
	site.should.have.property('language', 'en');
	site.should.have.property('pubDate');
	site.should.have.property('baseSiteURL');
	site.should.have.property('baseBlogURL');

	site.should.have.property('posts');
	site.should.have.property('tags');
	site.should.have.property('categories');

	site.should.respondTo('toWXR');
});

test('XML node created', function(){
	var site = new wxr.Site();

	var doc = site.toWXR();

	doc.should.have.property('children');
	doc.children[0].should.have.property('name', '?xml');
});

test('Channel node created', function(){

	var site = new wxr.Site();
	var doc = site.toWXR();

	var rootNode = doc.children[1];
	rootNode.should.have.property('name', 'channel');
});

test('Title node created', function(){
	var site = new wxr.Site();

	site.title = 'my site title';
	var doc = site.toWXR();

	var rootNode = doc.children[1];

	var titleNode = _(rootNode.children)
					.detect(function(c){ return c.name == 'title';});

	should.exist(titleNode);

	var valueNode = titleNode.children[0];
	valueNode.should.have.property('value', '<![CDATA[my site title]]>');
});
test('Link node created', function(){
	var site = new wxr.Site();

	site.link = 'http://blahblahblah.com';

	var doc = site.toWXR();

	var rootNode = doc.children[1];

	var linkNode = _(rootNode.children)
					.detect(function(c){ return c.name == 'link';});

	should.exist(linkNode);

	valueNode = linkNode.children[0];

	valueNode.should.have.property('value', site.link);
});

test('Description node created', function(){
	var site = new wxr.Site();

	site.description = "Ben's awesome site";

	var doc = site.toWXR();

	var rootNode = doc.children[1];

	var descNode = _(rootNode.children)
					.detect(function(c){ return c.name == 'description';});

	should.exist(descNode);

	valueNode = descNode.children[0];
	valueNode.should.have.property('value', "<![CDATA[Ben\'s awesome site]]>");
});
<|endoftext|>


<commit_before>
var bloodWhenTakeMine = 0.3;
var bloodWhenInjured = 0.7;
var bloodWhenKilled = 1.4;

// In move number
var bloodUnderFootPersistence = 2;

// In turn number
var bloodySoilPersistence = 200;
var footprintPersistence = 40;
var footprintBloodPersistence = 40;

function GameModel (state, previousState) {
  this.id = state.id;
  this.board = state.board;
  this.finished = state.finished;
  this.heroes = state.heroes;
  this.maxTurns = state.maxTurns;
  this.turn = state.turn;

  this.tilesArray = this.board.tiles.match(/.{2}/g);

  this.previous = previousState;
  if (previousState) {
    if (!(previousState instanceof GameModel)) throw new Error("previousState must be an instance of GameModel");
    this.meta = this.aggregateMeta(previousState);
  }
  else {
    this.meta = this.initialMeta();
  }
}

function sortByGold(heroA, heroB) {
  return heroB.gold - heroA.gold;
}

function cloneObject (obj) {
  var copy = {};
  for (var k in obj) {
    copy[k] = obj[k];
  }
  return copy;
}

function genEmptyArray (length, fill) {
  var t = [];
  for (var i=0; i<length; ++i)
    t.push(fill);
  return t;
}

function orientationForDelta (dx, dy) {
  if (dx === 1 && dy === 0) {
    return 1;
  }
  else if (dx === -1 && dy === 0) {
    return 3;
  }
  else if (dx === 0 && dy === 1) {
    return 2;
  }
  else if (dx === 0 && dy === -1) {
    return 0;
  }
  return null;
}

GameModel.prototype = {
  initialMeta: function () {
    var game = this;
    return {
      bloodyGroundFactor: genEmptyArray(this.tilesArray.length, 0),
      footprintFactor: genEmptyArray(this.tilesArray.length, { orientation: 0, foot: 0, blood: 0 }),
      heroes: [1,2,3,4].map(function (id, i) {
        return {
          myturn: false,
          from: null,
          to: game.heroes[i],
          orientation: [0],
          move: null,
          attack: null,
          attacked: null,
          kill: null,
          killed: null,
          takeMine: null,
          drink: null,
          winning: false,
          bloodUnderFoot: 0
        };
      })
    };
  },

  aggregateMeta: function (previous) {
    if (previous.turn !== this.turn-1) throw new Error("aggregateMeta: game does not follow! "+previous.turn+"->"+this.turn);

    var winner = this.getWinner();

    var meta = cloneObject(previous.meta);
    meta.heroes = previous.meta.heroes.map(cloneObject);
    meta.heroes.forEach(function (hero, i) {
      if (this.turn % 4 === 0) // We only refresh at the end of a turn to avoid blink effect
        hero.winning = winner === i+1;
      hero.myturn = false;
      hero.move = null;
      hero.takeMine = null;
      hero.drink = null;
      hero.kill = null;
      hero.attack = null;
      hero.killed = null;
      hero.attacked = null;
      hero.orientation = [hero.orientation[hero.orientation.length-1]];
      hero.from = previous.heroes[i];
      hero.to = this.heroes[i];
    }, this);

    // Compute last hero meta
    var heroIndex = previous.turn % 4;
    var hero = this.heroes[heroIndex];
    var previousHero = previous.heroes[heroIndex];
    var heroMeta = cloneObject(meta.heroes[heroIndex]);
    var previousHeroMeta = previous.meta.heroes[heroIndex];
    var previousPositionIndex = previous.indexForPosition(previousHero.pos.x, previousHero.pos.y);
    var previousNeighborsIndexes = previous.neighborsIndexes(previousHero.pos.x, previousHero.pos.y);

    var touchingTaverns = previousNeighborsIndexes
      .map(function (i) { return previous.tilesArray[i] === "[]" ? i : null; })
      .filter(function (tile) { return tile !== null; });

    var touchingMines = previousNeighborsIndexes
      .map(function (i) {
        var tile = previous.tilesArray[i];
        return tile && tile[0] === "$" ? i : null; })
      .filter(function (tile) { return tile !== null; });

    var takenMines = touchingMines.filter(function (i) {
      var heroId = hero.id.toString();
      return previous.tilesArray[i][1] !== heroId && this.tilesArray[i][1] === heroId;
    }, this);

    var opponents = [1,2,3,4].filter(function (id) {
      return id !== hero.id;
    });

    var opponentsInjured = opponents.filter(function (i) {
      var prevOpponent = previous.heroes[i-1];
      var opponent = this.heroes[i-1];
      return opponent.life < prevOpponent.life-1;
    }, this);

    var opponentsKilled = opponents.filter(function (i) {
      var prevOpponent = previous.heroes[i-1];
      var opponent = this.heroes[i-1];
      return opponent.life === 100 && prevOpponent.life <= 20;
    }, this);

    var opponentsAttacked = opponentsInjured.concat(opponentsKilled);

    var p;
    var dx = hero.pos.x - previousHero.pos.x;
    var dy = hero.pos.y - previousHero.pos.y;

    // Creating the current hero meta

    heroMeta.myturn = true;

    heroMeta.drink = touchingTaverns.length && hero.life > previousHero.life && touchingTaverns || null;
    heroMeta.move = !(dx===0 && dy===0) && { dx: dx, dy: dy } || null;
    heroMeta.takeMine = takenMines.length && takenMines || null;
    heroMeta.attack = opponentsAttacked.length && opponentsAttacked || null;
    heroMeta.kill = opponentsKilled.length && opponentsKilled || null;

    var motionOrientation = orientationForDelta(dx, dy);
    var orientation = [];
    orientation.push(motionOrientation);
    if (heroMeta.attack) {
      p = previous.heroes[opponentsAttacked[0]-1].pos;
      orientation.push(orientationForDelta(p.x - previousHero.pos.x, p.y - previousHero.pos.y));
    }
    if (heroMeta.drink) {
      p = previous.indexToPosition(touchingTaverns[0]);
      orientation.push(orientationForDelta(p.x - previousHero.pos.x, p.y - previousHero.pos.y));
    }
    orientation = orientation.filter(function (o) { return o !== null; });
    if (orientation.length === 0) orientation.push(previousHeroMeta.orientation[previousHeroMeta.orientation.length-1]);

    heroMeta.orientation = orientation;

    // Record metas

    meta.heroes[hero.id-1] = heroMeta;
    opponentsAttacked.forEach(function (id) {
      meta.heroes[id-1].attacked = hero.id;
    });
    opponentsKilled.forEach(function (id) {
      meta.heroes[id-1].killed = hero.id;
      meta.heroes[id-1].bloodUnderFoot = 0;
    });

    meta.bloodyGroundFactor = meta.bloodyGroundFactor.map(function (v) {
      return Math.max(0, v - 1 / bloodySoilPersistence);
    });
    opponentsInjured.forEach(function (id) {
      var pos = previous.heroes[id-1].pos;
      meta.bloodyGroundFactor[previous.indexForPosition(pos.x, pos.y)] += bloodWhenInjured;
    });
    opponentsKilled.forEach(function (id) {
      var pos = previous.heroes[id-1].pos;
      meta.bloodyGroundFactor[previous.indexForPosition(pos.x, pos.y)] += bloodWhenKilled;
    });
    if (heroMeta.takeMine) {
      meta.bloodyGroundFactor[previousPositionIndex] += bloodWhenTakeMine;
    }

    meta.footprintFactor = meta.footprintFactor.map(function (v) {
      var foot = Math.max(0, v.foot - 1 / footprintPersistence);
      var blood = Math.max(0, v.blood - 1 / footprintBloodPersistence);
      return {
        orientation: v.orientation,
        foot: foot,
        blood: blood
      };
    });
    if (heroMeta.move) {
      heroMeta.bloodUnderFoot = Math.max(meta.bloodyGroundFactor[previousPositionIndex], heroMeta.bloodUnderFoot - 1 / bloodUnderFootPersistence);
      meta.footprintFactor[previousPositionIndex] = {
        orientation: motionOrientation,
        foot: 1,
        blood: heroMeta.bloodUnderFoot
      };
    }

    return meta;
  },
  isOver: function () {
    return this.finished;
  },
  getWinner: function () {
    var heroes = this.heroes.slice();
    heroes.sort(sortByGold);
    if(heroes[0].gold === heroes[1].gold) return -1;
    else return heroes[0].id;
  },

  forEachTile: function (f, ctx) {
    var size = this.board.size;
    this.tilesArray.forEach(function (tile, i) {
      var x = i % size;
      var y = Math.floor(i / size);
      f.call(this, tile, i, x, y);
    }, ctx || this);
  },

  tileAt: function (x, y) {
    return this.tilesArray[this.indexForPosition(x, y)];
  },

  wallAt: function (x, y) {
    var tile = this.tileAt(x, y);
    return tile === undefined || tile === "##";
  },

  indexToPosition: function (i) {
    return {
      x: i % this.board.size,
      y: Math.floor(i / this.board.size)
    };
  },

  indexForPosition: function (x, y) {
    var size = this.board.size;
    if (x < 0 || x >= size || y < 0 || y >= size)
      return null;
    return x + size * y;
  },

  neighborsIndexes: function (x, y) {
    return [
      this.indexForPosition(x, y-1), // TOP
      this.indexForPosition(x+1, y), // RIGHT
      this.indexForPosition(x, y+1), // BOTTOM
      this.indexForPosition(x-1, y) // LEFT
    ];
  },

  neighbors: function (x, y) {
    return this.neighborsIndexes(x, y).map(function (i) {
      if (i === null) return null;
      return this.tilesArray[i];
    }, this);
  },

  getWallStatus: function (x, y) {
    var hasWallNeighbors =
      this.neighborsIndexes(x, y)
      .filter(function (i) { return i !== null && this.tilesArray[i] === "##"; }, this)
      .length > 0;
    return !hasWallNeighbors ? "alone" : "";
  }

};

module.exports = GameModel;
<commit_msg>Adjust persistence parameters<commit_after>
var bloodWhenTakeMine = 0.3;
var bloodWhenInjured = 0.8;
var bloodWhenKilled = 1.6;

// In move number
var bloodUnderFootPersistence = 2;

// In turn number
var bloodySoilPersistence = 300;
var footprintPersistence = 80;
var footprintBloodPersistence = 60;

function GameModel (state, previousState) {
  this.id = state.id;
  this.board = state.board;
  this.finished = state.finished;
  this.heroes = state.heroes;
  this.maxTurns = state.maxTurns;
  this.turn = state.turn;

  this.tilesArray = this.board.tiles.match(/.{2}/g);

  this.previous = previousState;
  if (previousState) {
    if (!(previousState instanceof GameModel)) throw new Error("previousState must be an instance of GameModel");
    this.meta = this.aggregateMeta(previousState);
  }
  else {
    this.meta = this.initialMeta();
  }
}

function sortByGold(heroA, heroB) {
  return heroB.gold - heroA.gold;
}

function cloneObject (obj) {
  var copy = {};
  for (var k in obj) {
    copy[k] = obj[k];
  }
  return copy;
}

function genEmptyArray (length, fill) {
  var t = [];
  for (var i=0; i<length; ++i)
    t.push(fill);
  return t;
}

function orientationForDelta (dx, dy) {
  if (dx === 1 && dy === 0) {
    return 1;
  }
  else if (dx === -1 && dy === 0) {
    return 3;
  }
  else if (dx === 0 && dy === 1) {
    return 2;
  }
  else if (dx === 0 && dy === -1) {
    return 0;
  }
  return null;
}

GameModel.prototype = {
  initialMeta: function () {
    var game = this;
    return {
      bloodyGroundFactor: genEmptyArray(this.tilesArray.length, 0),
      footprintFactor: genEmptyArray(this.tilesArray.length, { orientation: 0, foot: 0, blood: 0 }),
      heroes: [1,2,3,4].map(function (id, i) {
        return {
          myturn: false,
          from: null,
          to: game.heroes[i],
          orientation: [0],
          move: null,
          attack: null,
          attacked: null,
          kill: null,
          killed: null,
          takeMine: null,
          drink: null,
          winning: false,
          bloodUnderFoot: 0
        };
      })
    };
  },

  aggregateMeta: function (previous) {
    if (previous.turn !== this.turn-1) throw new Error("aggregateMeta: game does not follow! "+previous.turn+"->"+this.turn);

    var winner = this.getWinner();

    var meta = cloneObject(previous.meta);
    meta.heroes = previous.meta.heroes.map(cloneObject);
    meta.heroes.forEach(function (hero, i) {
      if (this.turn % 4 === 0) // We only refresh at the end of a turn to avoid blink effect
        hero.winning = winner === i+1;
      hero.myturn = false;
      hero.move = null;
      hero.takeMine = null;
      hero.drink = null;
      hero.kill = null;
      hero.attack = null;
      hero.killed = null;
      hero.attacked = null;
      hero.orientation = [hero.orientation[hero.orientation.length-1]];
      hero.from = previous.heroes[i];
      hero.to = this.heroes[i];
    }, this);

    // Compute last hero meta
    var heroIndex = previous.turn % 4;
    var hero = this.heroes[heroIndex];
    var previousHero = previous.heroes[heroIndex];
    var heroMeta = cloneObject(meta.heroes[heroIndex]);
    var previousHeroMeta = previous.meta.heroes[heroIndex];
    var previousPositionIndex = previous.indexForPosition(previousHero.pos.x, previousHero.pos.y);
    var previousNeighborsIndexes = previous.neighborsIndexes(previousHero.pos.x, previousHero.pos.y);

    var touchingTaverns = previousNeighborsIndexes
      .map(function (i) { return previous.tilesArray[i] === "[]" ? i : null; })
      .filter(function (tile) { return tile !== null; });

    var touchingMines = previousNeighborsIndexes
      .map(function (i) {
        var tile = previous.tilesArray[i];
        return tile && tile[0] === "$" ? i : null; })
      .filter(function (tile) { return tile !== null; });

    var takenMines = touchingMines.filter(function (i) {
      var heroId = hero.id.toString();
      return previous.tilesArray[i][1] !== heroId && this.tilesArray[i][1] === heroId;
    }, this);

    var opponents = [1,2,3,4].filter(function (id) {
      return id !== hero.id;
    });

    var opponentsInjured = opponents.filter(function (i) {
      var prevOpponent = previous.heroes[i-1];
      var opponent = this.heroes[i-1];
      return opponent.life < prevOpponent.life-1;
    }, this);

    var opponentsKilled = opponents.filter(function (i) {
      var prevOpponent = previous.heroes[i-1];
      var opponent = this.heroes[i-1];
      return opponent.life === 100 && prevOpponent.life <= 20;
    }, this);

    var opponentsAttacked = opponentsInjured.concat(opponentsKilled);

    var p;
    var dx = hero.pos.x - previousHero.pos.x;
    var dy = hero.pos.y - previousHero.pos.y;

    // Creating the current hero meta

    heroMeta.myturn = true;

    heroMeta.drink = touchingTaverns.length && hero.life > previousHero.life && touchingTaverns || null;
    heroMeta.move = !(dx===0 && dy===0) && { dx: dx, dy: dy } || null;
    heroMeta.takeMine = takenMines.length && takenMines || null;
    heroMeta.attack = opponentsAttacked.length && opponentsAttacked || null;
    heroMeta.kill = opponentsKilled.length && opponentsKilled || null;

    var motionOrientation = orientationForDelta(dx, dy);
    var orientation = [];
    orientation.push(motionOrientation);
    if (heroMeta.attack) {
      p = previous.heroes[opponentsAttacked[0]-1].pos;
      orientation.push(orientationForDelta(p.x - previousHero.pos.x, p.y - previousHero.pos.y));
    }
    if (heroMeta.drink) {
      p = previous.indexToPosition(touchingTaverns[0]);
      orientation.push(orientationForDelta(p.x - previousHero.pos.x, p.y - previousHero.pos.y));
    }
    orientation = orientation.filter(function (o) { return o !== null; });
    if (orientation.length === 0) orientation.push(previousHeroMeta.orientation[previousHeroMeta.orientation.length-1]);

    heroMeta.orientation = orientation;

    // Record metas

    meta.heroes[hero.id-1] = heroMeta;
    opponentsAttacked.forEach(function (id) {
      meta.heroes[id-1].attacked = hero.id;
    });
    opponentsKilled.forEach(function (id) {
      meta.heroes[id-1].killed = hero.id;
      meta.heroes[id-1].bloodUnderFoot = 0;
    });

    meta.bloodyGroundFactor = meta.bloodyGroundFactor.map(function (v) {
      return Math.max(0, v - 1 / bloodySoilPersistence);
    });
    opponentsInjured.forEach(function (id) {
      var pos = previous.heroes[id-1].pos;
      meta.bloodyGroundFactor[previous.indexForPosition(pos.x, pos.y)] += bloodWhenInjured;
    });
    opponentsKilled.forEach(function (id) {
      var pos = previous.heroes[id-1].pos;
      meta.bloodyGroundFactor[previous.indexForPosition(pos.x, pos.y)] += bloodWhenKilled;
    });
    if (heroMeta.takeMine) {
      meta.bloodyGroundFactor[previousPositionIndex] += bloodWhenTakeMine;
    }

    meta.footprintFactor = meta.footprintFactor.map(function (v) {
      var foot = Math.max(0, v.foot - 1 / footprintPersistence);
      var blood = Math.max(0, v.blood - 1 / footprintBloodPersistence);
      return {
        orientation: v.orientation,
        foot: foot,
        blood: blood
      };
    });
    if (heroMeta.move) {
      heroMeta.bloodUnderFoot = Math.max(meta.bloodyGroundFactor[previousPositionIndex], heroMeta.bloodUnderFoot - 1 / bloodUnderFootPersistence);
      meta.footprintFactor[previousPositionIndex] = {
        orientation: motionOrientation,
        foot: 1,
        blood: heroMeta.bloodUnderFoot
      };
    }

    return meta;
  },
  isOver: function () {
    return this.finished;
  },
  getWinner: function () {
    var heroes = this.heroes.slice();
    heroes.sort(sortByGold);
    if(heroes[0].gold === heroes[1].gold) return -1;
    else return heroes[0].id;
  },

  forEachTile: function (f, ctx) {
    var size = this.board.size;
    this.tilesArray.forEach(function (tile, i) {
      var x = i % size;
      var y = Math.floor(i / size);
      f.call(this, tile, i, x, y);
    }, ctx || this);
  },

  tileAt: function (x, y) {
    return this.tilesArray[this.indexForPosition(x, y)];
  },

  wallAt: function (x, y) {
    var tile = this.tileAt(x, y);
    return tile === undefined || tile === "##";
  },

  indexToPosition: function (i) {
    return {
      x: i % this.board.size,
      y: Math.floor(i / this.board.size)
    };
  },

  indexForPosition: function (x, y) {
    var size = this.board.size;
    if (x < 0 || x >= size || y < 0 || y >= size)
      return null;
    return x + size * y;
  },

  neighborsIndexes: function (x, y) {
    return [
      this.indexForPosition(x, y-1), // TOP
      this.indexForPosition(x+1, y), // RIGHT
      this.indexForPosition(x, y+1), // BOTTOM
      this.indexForPosition(x-1, y) // LEFT
    ];
  },

  neighbors: function (x, y) {
    return this.neighborsIndexes(x, y).map(function (i) {
      if (i === null) return null;
      return this.tilesArray[i];
    }, this);
  },

  getWallStatus: function (x, y) {
    var hasWallNeighbors =
      this.neighborsIndexes(x, y)
      .filter(function (i) { return i !== null && this.tilesArray[i] === "##"; }, this)
      .length > 0;
    return !hasWallNeighbors ? "alone" : "";
  }

};

module.exports = GameModel;
<|endoftext|>


<commit_before>// toID()
function toID(str) { return str.toLowerCase().replace(/[^a-z0-9]/g,''); }

// Data Definitions
Data = Data || exports || {};
Data.Pokedex = Data.BattlePokedex;
Data.Movedex = Data.BattleMovedex;
Data.Abilities = Data.BattleAbilities;
Data.Items = Data.BattleItems;
Data.Learnsets = Data.BattleLearnsets;
Data.StatTable = {
	hp:"HP",
	atk:"Atk",
	def:"Def",
	spa:"SpA",
	spd:"SpD",
	spe:"Spe"
};
Data.Statuses = { // Unfortunately we cant just nab this one from Pokemon Showdown :P
	brn:{name:'Burn'},
	par:{name:'Paralyze'},
	psn:{name:'Poison'},
	tox:{name:'Toxic'},
	slp:{name:'Sleep'},
	frz:{name:'Frozen'}
}
Data.Natures = {
	Adamant: {name:"Adamant", plus:'atk', minus:'spa'},
	Bashful: {name:"Bashful"},
	Bold: {name:"Bold", plus:'def', minus:'atk'},
	Brave: {name:"Brave", plus:'atk', minus:'spe'},
	Calm: {name:"Calm", plus:'spd', minus:'atk'},
	Careful: {name:"Careful", plus:'spd', minus:'spa'},
	Docile: {name:"Docile"},
	Gentle: {name:"Gentle", plus:'spd', minus:'def'},
	Hardy: {name:"Hardy"},
	Hasty: {name:"Hasty", plus:'spe', minus:'def'},
	Impish: {name:"Impish", plus:'def', minus:'spa'},
	Jolly: {name:"Jolly", plus:'spe', minus:'spa'},
	Lax: {name:"Lax", plus:'def', minus:'spd'},
	Lonely: {name:"Lonely", plus:'atk', minus:'def'},
	Mild: {name:"Mild", plus:'spa', minus:'def'},
	Modest: {name:"Modest", plus:'spa', minus:'atk'},
	Naive: {name:"Naive", plus:'spe', minus:'spd'},
	Naughty: {name:"Naughty", plus:'atk', minus:'spd'},
	Quiet: {name:"Quiet", plus:'spa', minus:'spe'},
	Quirky: {name:"Quirky"},
	Rash: {name:"Rash", plus:'spa', minus:'spd'},
	Relaxed: {name:"Relaxed", plus:'def', minus:'spe'},
	Sassy: {name:"Sassy", plus:'spd', minus:'spe'},
	Serious: {name:"Serious"},
	Timid: {name:"Timid", plus:'spe', minus:'atk'}
};

// Data Functions
Data.getLearnset = function(pokemon) {
	if (!Data.Learnsets) return null;
	if (!Data.Pokedex[pokemon]) return false;
	if (!Data.Learnsets[pokemon]) {
		pokemon = toID(Data.Pokedex[pokemon].baseSpecies);
	}
	if (!Data.Learnsets[pokemon].learnset) return false;
	return Data.Learnsets[pokemon].learnset;
};
<commit_msg>Define `Data.TypeChart`<commit_after>// toID()
function toID(str) { return str.toLowerCase().replace(/[^a-z0-9]/g,''); }

// Data Definitions
Data = Data || exports || {};
Data.Pokedex = Data.BattlePokedex;
Data.Movedex = Data.BattleMovedex;
Data.Abilities = Data.BattleAbilities;
Data.Items = Data.BattleItems;
Data.Learnsets = Data.BattleLearnsets;
Data.TypeChart = Data.BattleTypeChart;
Data.StatTable = {
	hp:"HP",
	atk:"Atk",
	def:"Def",
	spa:"SpA",
	spd:"SpD",
	spe:"Spe"
};
Data.Statuses = { // Unfortunately we cant just nab this one from Pokemon Showdown :P
	brn:{name:'Burn'},
	par:{name:'Paralyze'},
	psn:{name:'Poison'},
	tox:{name:'Toxic'},
	slp:{name:'Sleep'},
	frz:{name:'Frozen'}
}
Data.Natures = {
	Adamant: {name:"Adamant", plus:'atk', minus:'spa'},
	Bashful: {name:"Bashful"},
	Bold: {name:"Bold", plus:'def', minus:'atk'},
	Brave: {name:"Brave", plus:'atk', minus:'spe'},
	Calm: {name:"Calm", plus:'spd', minus:'atk'},
	Careful: {name:"Careful", plus:'spd', minus:'spa'},
	Docile: {name:"Docile"},
	Gentle: {name:"Gentle", plus:'spd', minus:'def'},
	Hardy: {name:"Hardy"},
	Hasty: {name:"Hasty", plus:'spe', minus:'def'},
	Impish: {name:"Impish", plus:'def', minus:'spa'},
	Jolly: {name:"Jolly", plus:'spe', minus:'spa'},
	Lax: {name:"Lax", plus:'def', minus:'spd'},
	Lonely: {name:"Lonely", plus:'atk', minus:'def'},
	Mild: {name:"Mild", plus:'spa', minus:'def'},
	Modest: {name:"Modest", plus:'spa', minus:'atk'},
	Naive: {name:"Naive", plus:'spe', minus:'spd'},
	Naughty: {name:"Naughty", plus:'atk', minus:'spd'},
	Quiet: {name:"Quiet", plus:'spa', minus:'spe'},
	Quirky: {name:"Quirky"},
	Rash: {name:"Rash", plus:'spa', minus:'spd'},
	Relaxed: {name:"Relaxed", plus:'def', minus:'spe'},
	Sassy: {name:"Sassy", plus:'spd', minus:'spe'},
	Serious: {name:"Serious"},
	Timid: {name:"Timid", plus:'spe', minus:'atk'}
};

// Data Functions
Data.getLearnset = function(pokemon) {
	if (!Data.Learnsets) return null;
	if (!Data.Pokedex[pokemon]) return false;
	if (!Data.Learnsets[pokemon]) {
		pokemon = toID(Data.Pokedex[pokemon].baseSpecies);
	}
	if (!Data.Learnsets[pokemon].learnset) return false;
	return Data.Learnsets[pokemon].learnset;
};
<|endoftext|>


<commit_before>'use strict';

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);
var expect = chai.expect;

describe('no protractor at all', function() {
    it('should still do normal tests', function() {
        expect(true).to.equal(true);
    });
});

describe('protractor library', function() {
    it.skip('should be able to skip tests', function() {
        expect(true).to.equal(false);
    });

    it('should expose the correct global variables', function() {
        expect(protractor).to.exist;
        expect(browser).to.exist;
        expect(by).to.exist;
        expect(element).to.exist;
        expect($).to.exist;
    });

    it('should be able to redirect', function() {
        browser.get('/');
        expect(browser.getLocationAbsUrl()).to.eventually.equal("/home");
    });

    it('should wrap webdriver', function() {
        // Mocha will report the spec as slow if it goes over this time in ms.
        this.slow(6000);
        browser.get('/home');
        expect(browser.getTitle()).to.eventually.equal('Angular Seed');
    });
});
<commit_msg>Fixed end to end test<commit_after>'use strict';

var chai = require('chai');
var chaiAsPromised = require('chai-as-promised');

chai.use(chaiAsPromised);
var expect = chai.expect;

describe('no protractor at all', function() {
    it('should still do normal tests', function() {
        expect(true).to.equal(true);
    });
});

describe('protractor library', function() {
    it('should expose the correct global variables', function() {
        expect(protractor).to.exist;
        expect(browser).to.exist;
        expect(by).to.exist;
        expect(element).to.exist;
        expect($).to.exist;
    });

    it('should be able to redirect', function() {
        browser.get('/');
        expect(browser.getLocationAbsUrl()).to.eventually.equal("/home");
    });

    it('should wrap webdriver', function() {
        // Mocha will report the spec as slow if it goes over this time in ms.
        this.slow(6000);
        browser.get('/home');
        expect(browser.getTitle()).to.eventually.equal('Angular Seed');
    });
});
<|endoftext|>