<commit_before>return _cross.bind(function (callback, onerror) {
    var response, responseObject, responseType = "", error;
    var xhr = {
        status: 0,
        readyState: 0,
        method: null,
        url: null,
        http: null,
        headers: {},
        responseHeaders: {},
        get response() {
            if (responseType === "" || responseType === "text") {
                if (this.readyState !== 4) return '';
                return String(response);
            }
            else if (error) return null;
            if (responseObject !== null) return responseObject;
            switch (responseType) {
                case "arraybuffer":
                    return response.buffer;
                case "json":
                    if (!response) return null;
                    responseObject = JSON.parse(String(response));
                    return responseObject;
            }
            return responseObject;

        },
        set response(v) {
            response = v;
        },
        getResponseHeader(key) {
            key = String(key).toLowerCase();
            if (this.responseHeaders[key]) return this.responseHeaders[key];
            if (key === "access-control-expose-headers") {
                return 'set-cookie,location';
            }
            return null;
        },
        send(data) {
            var { hostname, port, path, auth } = parseURL(this.url);
            if (data) {
                data = Buffer.from(data);
                this.headers["Content-Length"] = data.length;
            }
            var req = http.request({
                method: this.method,
                hostname,
                port,
                path,
                auth,
                headers: this.headers,
            }, function (res) {
                var data = [];
                xhr.status = res.statusCode;
                xhr.responseHeaders = res.headers;
                res.on("data", function (chunk) {
                    xhr.readyState = 4;
                    data.push(chunk);
                });
                res.on("end", function () {
                    response = Buffer.concat(data);
                    xhr.readyState = 4;
                    callback();
                });
                res.on("error", function (e) {
                    xhr.readyState = 4;
                    error = e;
                    onerror(e);
                });
                this.readyState = 2;
            });
            this.readyState = 1;
            if (data) req.end(data);
            else req.end();
        },
        open(method, url) {
            this.method = method;
            this.url = url;
            this.status = 0;
            this.readyState = 0;
            response = null;
            responseObject = null;
            error = null;
            var http;
            if (/^https?\:/i.test(url)) {
                http = require("http");
            }
            else {
                http = require("https");
            }
            this.http = http;
        },
        get responseType() {
            return responseType;
        },
        set responseType(v) {
            if (v === "document") return;
            if (this.status !== 0) throw new Error("状态错误");
            responseType = v;
        },
        setRequestHeader(key, value) {
            this.headers[key] = value;
        },

    };
    return xhr;
}, null, undefined);<commit_msg>增加支持自定义的FormData<commit_after>return _cross.bind(function (callback, onerror) {
    var response, responseObject, responseType = "", error;
    var xhr = {
        status: 0,
        readyState: 0,
        method: null,
        url: null,
        http: null,
        headers: {},
        responseHeaders: {},
        get response() {
            if (responseType === "" || responseType === "text") {
                if (this.readyState !== 4) return '';
                return String(response);
            }
            else if (error) return null;
            if (responseObject !== null) return responseObject;
            switch (responseType) {
                case "arraybuffer":
                    return response.buffer;
                case "json":
                    if (!response) return null;
                    responseObject = JSON.parse(String(response));
                    return responseObject;
            }
            return responseObject;

        },
        set response(v) {
            response = v;
        },
        getResponseHeader(key) {
            key = String(key).toLowerCase();
            if (this.responseHeaders[key]) return this.responseHeaders[key];
            if (key === "access-control-expose-headers") {
                return 'set-cookie,location';
            }
            return null;
        },
        send(data) {
            var { hostname, port, path, auth } = parseURL(this.url);
            if (data instanceof FormData) data = String(data);
            if (data) {
                data = Buffer.from(data);
                this.headers["Content-Length"] = data.length;
            }
            var req = http.request({
                method: this.method,
                hostname,
                port,
                path,
                auth,
                headers: this.headers,
            }, function (res) {
                var data = [];
                xhr.status = res.statusCode;
                xhr.responseHeaders = res.headers;
                res.on("data", function (chunk) {
                    xhr.readyState = 4;
                    data.push(chunk);
                });
                res.on("end", function () {
                    response = Buffer.concat(data);
                    xhr.readyState = 4;
                    callback();
                });
                res.on("error", function (e) {
                    xhr.readyState = 4;
                    error = e;
                    onerror(e);
                });
                this.readyState = 2;
            });
            this.readyState = 1;
            if (data) req.end(data);
            else req.end();
        },
        open(method, url) {
            this.method = method;
            this.url = url;
            this.status = 0;
            this.readyState = 0;
            response = null;
            responseObject = null;
            error = null;
            var http;
            if (/^https?\:/i.test(url)) {
                http = require("http");
            }
            else {
                http = require("https");
            }
            this.http = http;
        },
        get responseType() {
            return responseType;
        },
        set responseType(v) {
            if (v === "document") return;
            if (this.status !== 0) throw new Error("状态错误");
            responseType = v;
        },
        setRequestHeader(key, value) {
            this.headers[key] = value;
        },

    };
    return xhr;
}, null, undefined);<|endoftext|>


<commit_before>// datapackage-js does not support loading url in browser
// atm, 'types' are only : Data Package or Resource Schema
import { focusMainWindow } from './windows'
import _ from 'lodash'
import { dataResourceToFormat } from '../renderer/file-formats'
import { dialog } from 'electron'
import { Package } from 'datapackage'
import { Schema } from 'tableschema'

export async function loadPackageFromJson (json) {
  const mainWindow = focusMainWindow()
  const dataPackageJson = await loadGenericFrictionlessFromJsonSource(json, loadPackageJson, 'Data Package')
  try {
    await loadResources(dataPackageJson, mainWindow)
  } catch (error) {
    console.error('There was a problem loading package from json', error)
  }
}

export async function loadResourceSchemaFromJson (json) {
  try {
    const resourceSchema = await loadGenericFrictionlessFromJsonSource(json, loadTableResourceSchemaJson, 'Table Resource Schema')
    const mainWindow = focusMainWindow()
    mainWindow.webContents.send('closeLoadingScreen')
    if (resourceSchema && resourceSchema.descriptor) {
      const mainWindow = focusMainWindow()
      mainWindow.webContents.send('addSchemaToTabAndLock', resourceSchema.descriptor)
    }
  } catch (error) {
    console.error('There was a problem loading resource schema from json', error)
  }
}

async function loadGenericFrictionlessFromJsonSource (jsonSource, callback, frictionlessType) {
  const mainWindow = focusMainWindow()
  mainWindow.webContents.send('closeAndshowLoadingScreen', `Loading ${frictionlessType}..`)
  const frictionlessTypeJson = await callback(jsonSource, mainWindow)
  if (!frictionlessTypeJson) {
    dialog.showMessageBox(mainWindow, {
      type: 'warning',
      title: `Unable to load ${frictionlessType}`,
      message:
        `The ${frictionlessType}, ${jsonSource}, could not be loaded.
  If the ${frictionlessType} is a URL or file, please check that it exists.`
    })
    mainWindow.webContents.send('closeLoadingScreen')
    return
  }
  if (!frictionlessTypeJson.valid) {
    showInvalidMessage(jsonSource, mainWindow, frictionlessType)
    mainWindow.webContents.send('closeLoadingScreen')
    return
  }
  return frictionlessTypeJson
}

function showInvalidMessage (source, mainWindow, frictionlessType) {
  dialog.showMessageBox(mainWindow, {
    type: 'warning',
    title: `Invalid ${frictionlessType}`,
    message:
      `The ${frictionlessType}, at ${source}, is not valid. Please refer to
  https://frictionlessdata.io/specs/
  for more information.`
  })
}

export async function loadPackageJson (source) {
  try {
    const dataPackage = await Package.load(source)
    return dataPackage
  } catch (error) {
    console.error(`There was a problem loading the package: ${source}`, error)
  }
}

async function loadResources (dataPackageJson) {
  const mainWindow = focusMainWindow()
  let packageProperties = _.assign({}, dataPackageJson.descriptor)
  _.unset(packageProperties, 'resources')
  mainWindow.webContents.send('resetPackagePropertiesToObject', packageProperties)
  for (const resource of dataPackageJson.resourceNames) {
    mainWindow.webContents.send('closeAndshowLoadingScreen', 'Loading next resource...')
    const dataResource = dataPackageJson.getResource(resource)
    const format = dataResourceToFormat(dataResource.descriptor)
    let data = await dataResource.read()
    mainWindow.webContents.send('closeLoadingScreen')
    // datapackage-js separates headers - add back to use default DC behaviour
    let dataWithHeaders = _.concat([dataResource.headers], data)
    mainWindow.webContents.send('addTabWithFormattedDataAndDescriptor', dataWithHeaders, format, dataResource.descriptor)
  }
}

async function loadTableResourceSchemaJson (source) {
  try {
    const resourceSchema = await Schema.load(source)
    return resourceSchema
  } catch (error) {
    console.error(`There was a problem loading the table resource schema: ${source}`, error)
  }
}

export async function loadResourceDataFromPackageSource (source, resourceName) {
  const dataPackage = await loadPackageJson(source)
  const rowOfObjects = []
  if (dataPackage && _.indexOf(dataPackage.resourceNames, resourceName) > -1) {
    const dataResource = dataPackage.getResource(resourceName)
    const data = await dataResource.read()
    const headers = dataResource.headers
    for (const row of data) {
      rowOfObjects.push(_.zipObject(headers, row))
    }
  }
  return rowOfObjects
}
<commit_msg>#206: Updated message (when page downloaded as say HTML vs JSON).<commit_after>// datapackage-js does not support loading url in browser
// atm, 'types' are only : Data Package or Resource Schema
import { focusMainWindow } from './windows'
import _ from 'lodash'
import { dataResourceToFormat } from '../renderer/file-formats'
import { dialog } from 'electron'
import { Package } from 'datapackage'
import { Schema } from 'tableschema'

export async function loadPackageFromJson (json) {
  const mainWindow = focusMainWindow()
  const dataPackageJson = await loadGenericFrictionlessFromJsonSource(json, loadPackageJson, 'Data Package')
  try {
    await loadResources(dataPackageJson, mainWindow)
  } catch (error) {
    console.error('There was a problem loading package from json', error)
  }
}

export async function loadResourceSchemaFromJson (json) {
  try {
    const resourceSchema = await loadGenericFrictionlessFromJsonSource(json, loadTableResourceSchemaJson, 'Table Resource Schema')
    const mainWindow = focusMainWindow()
    mainWindow.webContents.send('closeLoadingScreen')
    if (resourceSchema && resourceSchema.descriptor) {
      const mainWindow = focusMainWindow()
      mainWindow.webContents.send('addSchemaToTabAndLock', resourceSchema.descriptor)
    }
  } catch (error) {
    console.error('There was a problem loading resource schema from json', error)
  }
}

async function loadGenericFrictionlessFromJsonSource (jsonSource, callback, frictionlessType) {
  const mainWindow = focusMainWindow()
  mainWindow.webContents.send('closeAndshowLoadingScreen', `Loading ${frictionlessType}..`)
  const frictionlessTypeJson = await callback(jsonSource, mainWindow)
  if (!frictionlessTypeJson) {
    dialog.showMessageBox(mainWindow, {
      type: 'warning',
      title: `Unable to load ${frictionlessType}`,
      message:
        `The ${frictionlessType}, ${jsonSource}, could not be loaded.
  If the ${frictionlessType} is a URL or file, please check that it exists in JSON format.`
    })
    mainWindow.webContents.send('closeLoadingScreen')
    return
  }
  if (!frictionlessTypeJson.valid) {
    showInvalidMessage(jsonSource, mainWindow, frictionlessType)
    mainWindow.webContents.send('closeLoadingScreen')
    return
  }
  return frictionlessTypeJson
}

function showInvalidMessage (source, mainWindow, frictionlessType) {
  dialog.showMessageBox(mainWindow, {
    type: 'warning',
    title: `Invalid ${frictionlessType}`,
    message:
      `The ${frictionlessType}, at ${source}, is not valid. Please refer to
  https://frictionlessdata.io/specs/
  for more information.`
  })
}

export async function loadPackageJson (source) {
  try {
    const dataPackage = await Package.load(source)
    return dataPackage
  } catch (error) {
    console.error(`There was a problem loading the package: ${source}`, error)
  }
}

async function loadResources (dataPackageJson) {
  const mainWindow = focusMainWindow()
  let packageProperties = _.assign({}, dataPackageJson.descriptor)
  _.unset(packageProperties, 'resources')
  mainWindow.webContents.send('resetPackagePropertiesToObject', packageProperties)
  for (const resource of dataPackageJson.resourceNames) {
    mainWindow.webContents.send('closeAndshowLoadingScreen', 'Loading next resource...')
    const dataResource = dataPackageJson.getResource(resource)
    const format = dataResourceToFormat(dataResource.descriptor)
    let data = await dataResource.read()
    mainWindow.webContents.send('closeLoadingScreen')
    // datapackage-js separates headers - add back to use default DC behaviour
    let dataWithHeaders = _.concat([dataResource.headers], data)
    mainWindow.webContents.send('addTabWithFormattedDataAndDescriptor', dataWithHeaders, format, dataResource.descriptor)
  }
}

async function loadTableResourceSchemaJson (source) {
  try {
    const resourceSchema = await Schema.load(source)
    return resourceSchema
  } catch (error) {
    console.error(`There was a problem loading the table resource schema: ${source}`, error)
  }
}

export async function loadResourceDataFromPackageSource (source, resourceName) {
  const dataPackage = await loadPackageJson(source)
  const rowOfObjects = []
  if (dataPackage && _.indexOf(dataPackage.resourceNames, resourceName) > -1) {
    const dataResource = dataPackage.getResource(resourceName)
    const data = await dataResource.read()
    const headers = dataResource.headers
    for (const row of data) {
      rowOfObjects.push(_.zipObject(headers, row))
    }
  }
  return rowOfObjects
}
<|endoftext|>


<commit_before>const nodemailer = require('nodemailer');
const config = require('./config/config.js');
// --------------------------------------------------------------------------------------
function set_up_mailer()
{
  // create transporter
  var transporter = nodemailer.createTransport({
    host: 'localhost',
    port: 25,
    secure: false,
    requireTLS : false,
    ignoreTLS : true
  });

  // setup e-mail data with unicode symbols
  var mail_options = {
    from: 'etlog@etlog.cesnet.cz <etlog@etlog.cesnet.cz>', // sender address
    //cc: 'vac.mach@sh.cvut.cz',  // copy
  };

  return {
    transporter : transporter,
    mail_options : mail_options
  };
}
// --------------------------------------------------------------------------------------
// send mail with defined subject and data
// --------------------------------------------------------------------------------------
module.exports.send_mail = function (subject, recipients, data)
{
  var mailer = set_up_mailer();     // set up
  mailer.mail_options.subject = subject;  // set mail subject
  mailer.mail_options.text = data;  // set mail text
  mailer.mail_options.to = recipients;   // set recipients

  // send mail with defined transport object
  mailer.transporter.sendMail(mailer.mail_options, function(error, info) {
    if(error) {
      return console.error(error);
    }
    console.log('Message sent: ' + info.response);
  });
}
// --------------------------------------------------------------------------------------
// send mail to all defined realm admins
// params:
// 1) database
// 2) mail subject
// 3) function which returns data - mail contents
// 4) optional limit for data function
// --------------------------------------------------------------------------------------
module.exports.send_mail_to_realm_admins = function (database, data_func, limit)
{
  database.realm_admins.find({}, { realm : 1, admins : 1, _id : 0 },
  function(err, items) {
    for(var dict in items) {
      // items[dict].realm contains domain part of username - eg "fit.cvut.cz"
      module.exports.send_mail(config.failed_logins_subj, items[dict].admins, data_func(database, items[dict].realm, limit));
    }
  });
}
// --------------------------------------------------------------------------------------
module.exports.send_error_report = function (data)
{
  var subj = "hlášení o chybě";
  recipients = [ 'machv@cesnet.cz' ];
  var mail_data = "";

  for(var item in data) {
    mail_data += data[item].stack + "\n";
  }

  module.exports.send_mail(subj, recipients, mail_data);
}
// --------------------------------------------------------------------------------------
// send error report about detected service problem
// --------------------------------------------------------------------------------------
module.exports.send_service_problem_notification = function(database, realm, data)
{
  var subj = "problém fungování služby eduroam";

  database.realm_admins.find({ realm : realm  }, { admins : 1, _id : 0 },
  function(err, items) {
    for(var dict in items) {
      module.exports.send_mail(subj, items[dict].admins, data);
    }
  });
}
// --------------------------------------------------------------------------------------
<commit_msg>use new realm_admins schema<commit_after>const nodemailer = require('nodemailer');
const config = require('./config/config.js');
// --------------------------------------------------------------------------------------
function set_up_mailer()
{
  // create transporter
  var transporter = nodemailer.createTransport({
    host: 'localhost',
    port: 25,
    secure: false,
    requireTLS : false,
    ignoreTLS : true
  });

  // setup e-mail data with unicode symbols
  var mail_options = {
    from: 'etlog@etlog.cesnet.cz <etlog@etlog.cesnet.cz>', // sender address
    //cc: 'vac.mach@sh.cvut.cz',  // copy
  };

  return {
    transporter : transporter,
    mail_options : mail_options
  };
}
// --------------------------------------------------------------------------------------
// send mail with defined subject and data
// --------------------------------------------------------------------------------------
module.exports.send_mail = function (subject, recipients, data)
{
  var mailer = set_up_mailer();     // set up
  mailer.mail_options.subject = subject;  // set mail subject
  mailer.mail_options.text = data;  // set mail text
  mailer.mail_options.to = recipients;   // set recipients

  // send mail with defined transport object
  mailer.transporter.sendMail(mailer.mail_options, function(error, info) {
    if(error) {
      return console.error(error);
    }
    console.log('Message sent: ' + info.response);
  });
}
// --------------------------------------------------------------------------------------
// send mail to all defined realm admins
// params:
// 1) database
// 2) mail subject
// 3) function which returns data - mail contents
// 4) optional limit for data function
// --------------------------------------------------------------------------------------
module.exports.send_mail_to_realm_admins = function (database, data_func, limit)
{
  database.realm_admins.find({}, { realm : 1, admin : 1, notify_enabled : 1, _id : 0 },
  function(err, items) {
    for(var dict in items) {
      if(items[dict].notify_enabled) {
        // items[dict].realm contains domain part of username - eg "fit.cvut.cz"
        module.exports.send_mail(config.failed_logins_subj, items[dict].admin, data_func(database, items[dict].realm, limit));
      }
    }
  });
}
// --------------------------------------------------------------------------------------
module.exports.send_error_report = function (data)
{
  var subj = "hlášení o chybě";
  recipients = [ 'machv@cesnet.cz' ];
  var mail_data = "";

  for(var item in data) {
    mail_data += data[item].stack + "\n";
  }

  module.exports.send_mail(subj, recipients, mail_data);
}
// --------------------------------------------------------------------------------------
// send error report about detected service problem
// --------------------------------------------------------------------------------------
module.exports.send_service_problem_notification = function(database, realm, data)
{
  var subj = "problém fungování služby eduroam";

  database.realm_admins.find({ realm : realm  }, { admins : 1, _id : 0 },
  function(err, items) {
    for(var dict in items) {
      module.exports.send_mail(subj, items[dict].admins, data);
    }
  });
}
// --------------------------------------------------------------------------------------
<|endoftext|>


<commit_before>$(document).foundation();

var RosterObject = {
    buildListItem: function(studentName) {
        var item = document.createElement('li');
        //var text = document.createTextNode(studentName);
        item.innerText = studentName;
        return item;
    },

    // handleSumbit
    addStudent: function(event) {
        event.preventDefault();
        // currentTarget is the thing the event fired on (i.e the studentForm).
        var f = event.currentTarget;
        var studentName = f.name.value;
        var item = this.buildListItem(studentName);
        // Now get the list element to append item to.
        var list = document.querySelector('#studentList');
        list.appendChild(item);
    },

    // Sets up event listeners.
    setupEventListeners: function() {
        // this sets up addStudent to be the event that happens on `onsubmit`
        document.querySelector('#studentForm').onsubmit =
            // we use bind here to retain the this member in addStudent
            this.addStudent.bind(this);
    },

    // Get the ball rolling.
    init: function() {
        this.setupEventListeners();
    },
};

RosterObject.init();
<commit_msg>reset the form and focus<commit_after>$(document).foundation();

var RosterObject = {
    buildListItem: function(studentName) {
        var item = document.createElement('li');
        //var text = document.createTextNode(studentName);
        item.innerText = studentName;
        return item;
    },

    // handleSumbit
    addStudent: function(event) {
        event.preventDefault();
        // currentTarget is the thing the event fired on (i.e the studentForm).
        var f = event.currentTarget;
        var studentName = f.name.value;
        var item = this.buildListItem(studentName);
        // Now get the list element to append item to.
        var list = document.querySelector('#studentList');
        list.appendChild(item);
        // Reset the form
        f.reset();
        // Focus is now stuck on the form.
        f.name.focus();
    },

    // Sets up event listeners.
    setupEventListeners: function() {
        // this sets up addStudent to be the event that happens on `onsubmit`
        document.querySelector('#studentForm').onsubmit =
            // we use bind here to retain the this member in addStudent
            this.addStudent.bind(this);
    },

    // Get the ball rolling.
    init: function() {
        this.setupEventListeners();
    },
};

RosterObject.init();
<|endoftext|>


<commit_before>
const code = `
Flexio.pipe()
  .input('https://raw.githubusercontent.com/flexiodata/data/master/mockaroo/names-and-ip-addresses.csv')
  .convert('delimited', 'json')
  .run(function(err, result) {
    console.log(result)
  })`

const fn = (Flexio, callback) => {
  Flexio.pipe()
    .input('https://raw.githubusercontent.com/flexiodata/data/master/mockaroo/names-and-ip-addresses.csv')
    .convert('delimited', 'json')
    .run(callback)
}

export default {
  title: 'Dead-simple CSV to JSON conversion in two lines of code',
  code,
  fn
}
<commit_msg>Changed 'input' to 'request' in one of the examples.<commit_after>
const code = `
Flexio.pipe()
  .request('https://raw.githubusercontent.com/flexiodata/data/master/mockaroo/names-and-ip-addresses.csv')
  .convert('delimited', 'json')
  .run(function(err, result) {
    console.log(result)
  })`

const fn = (Flexio, callback) => {
  Flexio.pipe()
    .request('https://raw.githubusercontent.com/flexiodata/data/master/mockaroo/names-and-ip-addresses.csv')
    .convert('delimited', 'json')
    .run(callback)
}

export default {
  title: 'Dead-simple CSV to JSON conversion in two lines of code',
  code,
  fn
}
<|endoftext|>


<commit_before>(function(root) {

  'use strict';

  // Sentinel to indicate that the playlist is currently stopped.
  var STOPPED = -1;

  // Sentinel to indicate that shuffling is turned off.
  var NOT_SHUFFLING = false;

  //
  // Swaps `arr[i]` and `arr[j]` in place.
  //
  var swap = function(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    return arr;
  };

  //
  // Generate an integer in the specified range.
  //
  var rand = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  };

  //
  // Constructor.
  //
  var Jockey = function(items) {

    // Allow `Jockey` to be called without the `new` keyword.
    if (!(this instanceof Jockey)) {
      return new Jockey(items);
    }

    // The items in the playlist.
    this.items = items || [];

    // If shuffling, this is a merely a shallow copy of the items in
    // `this.items`, but in a shuffled order.
    this.shuffled = NOT_SHUFFLING;

    // If not playing: `this.i` equals `STOPPED`.
    // If playing and shuffling, `this.i` refers to an item in `this.shuffled`,
    // ie. the currently-playing item is `this.shuffled[this.i]`.
    // If playing and not shuffling, `this.i` refers to an item in
    // `this.items`, ie. the currently-playing item is `this.items[this.i]`.
    this.i = STOPPED;

    // This flag will be `true` if we are repeating the playlist.
    this.repeatFlag = false;
  };

  // Store a reference to the Jockey `prototype` to facilitate minification.
  var j = Jockey.prototype;

  //
  // Add `item` to `this.items`.
  //
  j.add = function(item) {

    // Throw if no item.
    if (item == null) {
      throw new Error('need an item');
    }

    // Add `item` to `this.items`.
    this.items.push(item);

    // Add `item` to `this.shuffled`.
    if (this.isShuffling()) {
      this.shuffled.push(item);

      // Shuffle the "unplayed" subarray of `this.shuffled`.
      if (this.isPlaying()) {
        this._s(this.shuffled, this.i);
      }
    }
  };

  //
  // Remove the item at index `i` of `this.items`.
  //
  j.remove = function(i) {

    // Throw for invalid `i`.
    this._c(i);

    // Keep track of the currently-playing item.
    var currentItem = this.getCurrent();

    // Remove `item` from `this.items`.
    var item = this.items[i];
    this.items.splice(i, 1);

    // Remove `item` from `this.shuffled`. Update `i` to refer to an element
    // in `this.shuffled`.
    if (this.isShuffling()) {
      i = this.shuffled.indexOf(item);
      this.shuffled.splice(i, 1);
    }

    // Decrement `this.i` if the removed `item` occurs before the
    // current-playing item. If shuffling, `i` refers to an item in
    // `this.shuffled`. Else `i` refers to an item in `this.items`.
    if (i < this.i) {
      this.i--;
      return;
    }

    // Stop playing if the removed `item` is the currently-playing item.
    if (item == currentItem) {
      this.stop();
    }
  };

  //
  // Returns the playlist size.
  //
  j.size = function() {
    return this.items.length;
  };

  //
  // If no `i` specified, returns all the items in the playlist. Else returns
  // the item at index `i` of the playlist.
  //
  j.get = function(i) {

    // Return `this.items`.
    if (i == null) {
      return this.items;
    }

    // Throw for invalid `i`, else returns the item at index `i`.
    this._c(i);
    return this.items[i];
  };

  //
  // If playing, returns the index of the currently-playing item in
  // `this.items`. Else returns `STOPPED`.
  //
  j.getCurrentIndex = function() {
    if (this.isPlaying()) {
      // If shuffling, lookup the index of the currently-playing element
      // in `this.items`, else just return `this.i`.
      return this.isShuffling() ?
        this.items.indexOf(this.getCurrent()) :
        this.i;
    }
    return STOPPED;
  };

  //
  // If playing, returns the currently-playing item. Else returns `null`.
  //
  j.getCurrent = function() {
    if (this.isPlaying()) {
      return this.isShuffling() ?
        this.shuffled[this.i] :
        this.items[this.i];
    }
    return null;
  };

  //
  // Returns `true` if playing.
  //
  j.isPlaying = function() {
    return this.i != STOPPED;
  };

  //
  // If no `i` specified: If shuffling, plays the item at index 0 of
  // `this.shuffled`, else plays the item at index 0 of `this.items`.
  // If `i` specified: Plays the item at index `i` of `this.items`.
  //
  j.play = function(i) {
    i = i || 0;
    this._c(i);
    this.i = i;
  };

  //
  // Stop playing.
  //
  j.stop = function() {

    // Generate a new shuffle if shuffling.
    if (this.isShuffling()) {
      this.shuffled = this._s(this.items.slice());
    }
    this.i = STOPPED;
  };

  //
  // Toggle the `repeatFlag`.
  //
  j.repeat = function() {
    this.repeatFlag = !this.repeatFlag;
  };

  //
  // Returns `true` if repeating.
  //
  j.isRepeating = function() {
    return this.repeatFlag;
  };

  //
  // Toggle shuffling.
  //
  j.shuffle = function() {

    if (this.isShuffling()) {

      // Get the index of the currently-playing item in `this.items`, and
      // update `this.i` accordingly. Now, because we are no longer shuffling,
      // `this.i` refers to an index in `this.items`.
      if (this.isPlaying()) {
        this.i = this.getCurrentIndex();
      }

      // Clean out `this.shuffled`.
      this.shuffled = NOT_SHUFFLING;
      return;
    }

    // Here we are not shuffling.
    if (this.isPlaying()) {

      // Make a shallow copy of `this.items`, and swap the currently-playing
      // item (at index `this.i`) to index 0.
      this.shuffled = this.items.slice();
      var item = this.shuffled[this.i];
      this.shuffled[this.i] = this.shuffled[0];
      this.shuffled[0] = item;

      // Sort `this.shuffled` from index 1 and up.
      this._s(this.shuffled, 1);

      // Set `this.i` to point to the first item in `this.shuffled`.
      this.i = 0;
      return;
    }

    // Here we are neither shuffling nor playing. So just make a shallow copy
    // of `this.items`, and shuffle it.
    this.shuffled = this._s(this.items.slice());

  };

  //
  // Returns `true` if shuffling.
  //
  j.isShuffling = function() {
    return this.shuffled != NOT_SHUFFLING;
  };

  //
  // Decrement `this.i` if playing, wrapping to the end of the playlist if
  // repeating. Else stops.
  //
  j.previous = function() {

    // Do nothing if we are not playing, or if the playlist is empty.
    var len = this.items.length;
    if (!this.isPlaying() || !len) {
      return;
    }

    // A previous item exists, so just decrement `this.i`.
    if (this.i > 0) {
      this.i--;
      return;
    }

    // We are currently at the first item. Stop if not repeating.
    if (!this.isRepeating()) {
      return this.stop();
    }

    // If shuffling, generate a new shuffle.
    if (this.isShuffling()) {
      var currentItem = this.getCurrent();
      this.shuffled = this._s(this.items.slice());

      // If the currently-playing item was placed at index `len-1`, we need to
      // swap it with a random item taken from the rest of `this.items`. (This
      // is because `this.i` will be set to `len-1`, and the previous item must
      // be different from the currently-playing item!)
      if (len > 1 && this.shuffled[len-1] === currentItem) {
        var swapIndex = rand(0, this.items.length-2);
        swap(this.shuffled, len-1, swapIndex);
      }
    }

    // Since we're repeating, wraparound to the last element.
    this.i = len - 1;

  };

  //
  // Increment `this.i` if playing, wrapping to the end of the playlist if
  // repeating. Else stops.
  //
  j.next = function() {

    // Do nothing if we are not playing, or if the playlist is empty.
    var len = this.items.length;
    if (!this.isPlaying() || !len) {
      return;
    }

    // A next item exists, so just increment `this.i`.
    if (this.i < len - 1) {
      this.i++;
      return;
    }

    // We are currently at the last item. Stop if not repeating.
    if (!this.isRepeating()) {
      return this.stop();
    }

    // If shuffling, generate a new shuffle.
    if (this.isShuffling()) {
      var currentItem = this.getCurrent();
      this.shuffled = this._s(this.items.slice());

      // If the currently-playing item was placed at index 0, we need to swap
      // it with a random item taken from the rest of `this.items`. (This
      // is because `this.i` will be set to 0, and the next item must be
      // different from the currently-playing item!)
      if (len > 1 && this.shuffled[len-1] === currentItem) {
        var swapIndex = rand(0, this.items.length-2);
        swap(this.shuffled, len-1, swapIndex);
      }
    }

    // Since we're repeating, wraparound to the first element.
    this.i = 0;

  };

  //
  // Move the item at `oldIndex` in `this.items` to `newIndex`.
  //
  j.reorder = function(oldIndex, newIndex) {

    // Throw for invalid `oldIndex` or `newIndex`.
    this._c(oldIndex);
    this._c(newIndex);

    // Remove the item, and insert it at the `newIndex`.
    var item = this.items.splice(oldIndex, 1)[0];
    this.items.splice(newIndex, 0, item);

    // We do not need to adjust `this.i` if we are shuffling.
    if (this.isPlaying() && !this.isShuffling()) {

      // The item being moved is the currently-playing item.
      if (this.i == oldIndex) {
        this.i = newIndex;
        return;
      }

      // The item is being moved from after the currently-playing item to
      // before the currently-playing item.
      if (oldIndex <= this.i && newIndex >= this.i) {
        this.i--;
      } else {

        // The item is being moved from before the currently-playing item to
        // after the currently-playing item.
        if (oldIndex >= this.i && newIndex <= this.i) {
          this.i++;
        }
      }
    }

  };

  //
  // Throws if `i` is an invalid index.
  //
  j._c = function(i, len) {
    if (i < 0 || (i >= (len || this.items.length))) {
      throw new Error('invalid index: ' + i);
    }
  };

  //
  // Shuffles a subarray of `arr` in place, from the specified `startIndex` up
  // to `arr.length - 1`. Shuffles the entire `arr` if no `startIndex` was
  // specified. This is based on the Knuth shuffle.
  //
  j._s = function(arr, startIndex) {
    startIndex = startIndex || 0;
    var i = arr.length - 1;
    while (i > startIndex) {
      var j = Math.max(startIndex, Math.floor(Math.random() * (i + 1)));
      swap(arr, i, j);
      i--;
    }
    return arr;
  };

  /* istanbul ignore else */
  if (typeof module == 'object') {
    module.exports = Jockey;
  } else {
    root.jockey = Jockey;
  }

})(this);
<commit_msg>Use `===`<commit_after>(function(root) {

  'use strict';

  // Sentinel to indicate that the playlist is currently stopped.
  var STOPPED = -1;

  // Sentinel to indicate that shuffling is turned off.
  var NOT_SHUFFLING = false;

  //
  // Swaps `arr[i]` and `arr[j]` in place.
  //
  var swap = function(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
    return arr;
  };

  //
  // Generate an integer in the specified range.
  //
  var rand = function(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
  };

  //
  // Constructor.
  //
  var Jockey = function(items) {

    // Allow `Jockey` to be called without the `new` keyword.
    if (!(this instanceof Jockey)) {
      return new Jockey(items);
    }

    // The items in the playlist.
    this.items = items || [];

    // If shuffling, this is a merely a shallow copy of the items in
    // `this.items`, but in a shuffled order.
    this.shuffled = NOT_SHUFFLING;

    // If not playing: `this.i` equals `STOPPED`.
    // If playing and shuffling: `this.i` refers to an item in `this.shuffled`,
    // ie. the currently-playing item is `this.shuffled[this.i]`.
    // If playing and not shuffling: `this.i` refers to an item in
    // `this.items`, ie. the currently-playing item is `this.items[this.i]`.
    this.i = STOPPED;

    // This flag will be `true` if we are repeating the playlist.
    this.repeatFlag = false;
  };

  // Store a reference to the Jockey `prototype` to facilitate minification.
  var j = Jockey.prototype;

  //
  // Add `item` to `this.items`.
  //
  j.add = function(item) {

    // Throw if no `item`.
    if (item == null) {
      throw new Error('need an item');
    }

    // Add `item` to `this.items`.
    this.items.push(item);

    // Add `item` to `this.shuffled`.
    if (this.isShuffling()) {
      this.shuffled.push(item);

      // Shuffle the "unplayed" subarray of `this.shuffled`.
      if (this.isPlaying()) {
        this._s(this.shuffled, this.i);
      }
    }
  };

  //
  // Remove the item at index `i` of `this.items`.
  //
  j.remove = function(i) {

    // Throw for invalid `i`.
    this._c(i);

    // Keep track of the currently-playing item.
    var currentItem = this.getCurrent();

    // Remove `item` from `this.items`.
    var item = this.items[i];
    this.items.splice(i, 1);

    // Remove `item` from `this.shuffled`. Update `i` to refer to an element
    // in `this.shuffled`.
    if (this.isShuffling()) {
      i = this.shuffled.indexOf(item);
      this.shuffled.splice(i, 1);
    }

    // Decrement `this.i` if the removed `item` occurs before the
    // current-playing item. If shuffling, `i` refers to an item in
    // `this.shuffled`. Else `i` refers to an item in `this.items`.
    if (i < this.i) {
      this.i--;
      return;
    }

    // Stop playing if the removed `item` is the currently-playing item.
    if (item == currentItem) {
      this.stop();
    }
  };

  //
  // Returns the playlist size.
  //
  j.size = function() {
    return this.items.length;
  };

  //
  // If no `i` specified, returns all the items in the playlist. Else returns
  // the item at index `i` of the playlist.
  //
  j.get = function(i) {

    // Return `this.items`.
    if (i == null) {
      return this.items;
    }

    // Throw for invalid `i`, else returns the item at index `i`.
    this._c(i);
    return this.items[i];
  };

  //
  // If playing, returns the index of the currently-playing item in
  // `this.items`. Else returns `STOPPED`.
  //
  j.getCurrentIndex = function() {
    if (this.isPlaying()) {
      // If shuffling, lookup the index of the currently-playing element
      // in `this.items`, else just return `this.i`.
      return this.isShuffling() ?
        this.items.indexOf(this.getCurrent()) :
        this.i;
    }
    return STOPPED;
  };

  //
  // If playing, returns the currently-playing item. Else returns `null`.
  //
  j.getCurrent = function() {
    if (this.isPlaying()) {
      return this.isShuffling() ?
        this.shuffled[this.i] :
        this.items[this.i];
    }
    return null;
  };

  //
  // Returns `true` if playing.
  //
  j.isPlaying = function() {
    return this.i !== STOPPED;
  };

  //
  // If no `i` specified: If shuffling, plays the item at index 0 of
  // `this.shuffled`, else plays the item at index 0 of `this.items`.
  // If `i` specified: Plays the item at index `i` of `this.items`.
  //
  j.play = function(i) {
    i = i || 0;
    this._c(i);
    this.i = i;
  };

  //
  // Stop playing.
  //
  j.stop = function() {

    // Generate a new shuffle if shuffling.
    if (this.isShuffling()) {
      this.shuffled = this._s(this.items.slice());
    }
    this.i = STOPPED;
  };

  //
  // Toggle the `repeatFlag`.
  //
  j.repeat = function() {
    this.repeatFlag = !this.repeatFlag;
  };

  //
  // Returns `true` if repeating.
  //
  j.isRepeating = function() {
    return this.repeatFlag;
  };

  //
  // Toggle shuffling.
  //
  j.shuffle = function() {

    if (this.isShuffling()) {

      // Get the index of the currently-playing item in `this.items`, and
      // update `this.i` accordingly. Now, because we are no longer shuffling,
      // `this.i` refers to an index in `this.items`.
      if (this.isPlaying()) {
        this.i = this.getCurrentIndex();
      }

      // Clean out `this.shuffled`.
      this.shuffled = NOT_SHUFFLING;
      return;
    }

    // Here we are not shuffling.
    if (this.isPlaying()) {

      // Make a shallow copy of `this.items`, and swap the currently-playing
      // item (at index `this.i`) to index 0.
      this.shuffled = this.items.slice();
      var item = this.shuffled[this.i];
      this.shuffled[this.i] = this.shuffled[0];
      this.shuffled[0] = item;

      // Sort `this.shuffled` from index 1 and up.
      this._s(this.shuffled, 1);

      // Set `this.i` to point to the first item in `this.shuffled`.
      this.i = 0;
      return;
    }

    // Here we are neither shuffling nor playing. So just make a shallow copy
    // of `this.items`, and shuffle it.
    this.shuffled = this._s(this.items.slice());

  };

  //
  // Returns `true` if shuffling.
  //
  j.isShuffling = function() {
    return this.shuffled !== NOT_SHUFFLING;
  };

  //
  // Decrement `this.i` if playing, wrapping to the end of the playlist if
  // repeating. Else stops.
  //
  j.previous = function() {

    // Do nothing if we are not playing, or if the playlist is empty.
    var len = this.items.length;
    if (!this.isPlaying() || !len) {
      return;
    }

    // A previous item exists, so just decrement `this.i`.
    if (this.i > 0) {
      this.i--;
      return;
    }

    // We are currently at the first item. Stop if not repeating.
    if (!this.isRepeating()) {
      return this.stop();
    }

    // If shuffling, generate a new shuffle.
    if (this.isShuffling()) {
      var currentItem = this.getCurrent();
      this.shuffled = this._s(this.items.slice());

      // If the currently-playing item was placed at index `len-1`, we need to
      // swap it with a random item taken from the rest of `this.items`. (This
      // is because `this.i` will be set to `len-1`, and the previous item must
      // be different from the currently-playing item!)
      if (len > 1 && this.shuffled[len-1] === currentItem) {
        var swapIndex = rand(0, this.items.length-2);
        swap(this.shuffled, len-1, swapIndex);
      }
    }

    // Since we're repeating, wraparound to the last element.
    this.i = len - 1;

  };

  //
  // Increment `this.i` if playing, wrapping to the end of the playlist if
  // repeating. Else stops.
  //
  j.next = function() {

    // Do nothing if we are not playing, or if the playlist is empty.
    var len = this.items.length;
    if (!this.isPlaying() || !len) {
      return;
    }

    // A next item exists, so just increment `this.i`.
    if (this.i < len - 1) {
      this.i++;
      return;
    }

    // We are currently at the last item. Stop if not repeating.
    if (!this.isRepeating()) {
      return this.stop();
    }

    // If shuffling, generate a new shuffle.
    if (this.isShuffling()) {
      var currentItem = this.getCurrent();
      this.shuffled = this._s(this.items.slice());

      // If the currently-playing item was placed at index 0, we need to swap
      // it with a random item taken from the rest of `this.items`. (This
      // is because `this.i` will be set to 0, and the next item must be
      // different from the currently-playing item!)
      if (len > 1 && this.shuffled[len-1] === currentItem) {
        var swapIndex = rand(0, this.items.length-2);
        swap(this.shuffled, len-1, swapIndex);
      }
    }

    // Since we're repeating, wraparound to the first element.
    this.i = 0;

  };

  //
  // Move the item at `oldIndex` in `this.items` to `newIndex`.
  //
  j.reorder = function(oldIndex, newIndex) {

    // Throw for invalid `oldIndex` or `newIndex`.
    this._c(oldIndex);
    this._c(newIndex);

    // Remove the item, and insert it at the `newIndex`.
    var item = this.items.splice(oldIndex, 1)[0];
    this.items.splice(newIndex, 0, item);

    // We do not need to adjust `this.i` if we are shuffling.
    if (this.isPlaying() && !this.isShuffling()) {

      // The item being moved is the currently-playing item.
      if (this.i === oldIndex) {
        this.i = newIndex;
        return;
      }

      // The item is being moved from after the currently-playing item to
      // before the currently-playing item.
      if (oldIndex <= this.i && newIndex >= this.i) {
        this.i--;
      } else {

        // The item is being moved from before the currently-playing item to
        // after the currently-playing item.
        if (oldIndex >= this.i && newIndex <= this.i) {
          this.i++;
        }
      }
    }

  };

  //
  // Throws if `i` is an invalid index.
  //
  j._c = function(i, len) {
    if (i < 0 || (i >= (len || this.items.length))) {
      throw new Error('invalid index: ' + i);
    }
  };

  //
  // Shuffles a subarray of `arr` in place, from the specified `startIndex` up
  // to `arr.length - 1`. Shuffles the entire `arr` if no `startIndex` was
  // specified. This is based on the Knuth shuffle.
  //
  j._s = function(arr, startIndex) {
    startIndex = startIndex || 0;
    var i = arr.length - 1;
    while (i > startIndex) {
      var j = Math.max(startIndex, Math.floor(Math.random() * (i + 1)));
      swap(arr, i, j);
      i--;
    }
    return arr;
  };

  /* istanbul ignore else */
  if (typeof module === 'object') {
    module.exports = Jockey;
  } else {
    root.jockey = Jockey;
  }

})(this);
<|endoftext|>


<commit_before>define(
  'ephox.echo.api.AriaRegister',

  [
    'ephox.classify.Type',
    'ephox.epithet.Id',
    'ephox.sugar.api.Attr'
  ],

  function (Type, Id, Attr) {
    var editor = function (element) {
      Attr.set(element, 'role', 'application');
      var id = Id.generate('');
      Attr.set(element, 'aria-label', 'Textbox.io Rich Text Editor - ' + id);
    };

    var toolbar = function (element) {
      Attr.set(element, 'role', 'toolbar');
      Attr.set(element, 'aria-label', 'Rich Text Editor Toolbar');
    };

    var menu = function (element, label) {
      Attr.set(element, 'role', 'menu');
      Attr.set(element, 'aria-label', label);
    };

    var toolbarButton = function (element, label, hasPopup, isToggle) {
      Attr.set(element, 'role', 'button');
      Attr.set(element, 'aria-label', label);
      if (isToggle) Attr.set(element, 'aria-pressed', 'false');
      Attr.set(element, 'aria-haspopup', '' + hasPopup);
      if (hasPopup) {
        Attr.set(element, 'aria-expanded', 'false');
      }
    };

    var toolbarGroup = function (element, label) {
      // TODO: duplicated from 'ephox.polish.alien.Query', consolidate this
      var isEmpty = function (val) {
        // TODO: Move to compass Arr and violin Strings
        return (val === null) || (val === undefined) || (val === '') || (Type.isArray(val) && val.length === 0);
      };
      // End TODO

      if (!isEmpty(label))
        Attr.set(element, 'aria-label', label);
    };

    var menuItem = function (element, label, hasPopup) {
      Attr.set(element, 'role', 'menuitem');
      Attr.set(element, 'aria-label', label);
      Attr.set(element, 'aria-haspopup', hasPopup === true ? 'true' : 'false');
    };

    var dialog = function (element, label) {
      Attr.set(element, 'role', 'dialog');
      Attr.set(element, 'aria-label', label);
    };

    // TODO: Implement form ARIA support
    // var form = function (element, label) {
    //   throw 'Form ARIA support not implemented yet.';
    // };

    var input = function (element, label, required) {
      Attr.set(element, 'aria-label', label);
    };

    // TODO: Implement textarea ARIA support
    // var textarea = function (element, label, required) {
    //   throw 'Textarea ARIA support not implemented yet.';
    // };

    // TODO: Implement link ARIA support
    // var link = function (element) {
    //   throw 'Link ARIA support not implemented yet.';
    // };

    // TODO: Implement other ARIA support
    // var other = function () {
    //   throw 'Other ARIA support not implemented yet.';
    // };

    return {
      editor: editor,
      toolbar: toolbar,
      toolbarGroup: toolbarGroup,
      toolbarButton: toolbarButton,
      menu: menu,
      menuItem: menuItem,
      dialog: dialog,
      input: input
    };
  }
);<commit_msg>TBIO-2082: cleanup<commit_after>define(
  'ephox.echo.api.AriaRegister',

  [
    'ephox.classify.Type',
    'ephox.epithet.Id',
    'ephox.sugar.api.Attr'
  ],

  function (Type, Id, Attr) {
    var editor = function (element) {
      Attr.set(element, 'role', 'application');
      var id = Id.generate('');
      Attr.set(element, 'aria-label', 'Textbox.io Rich Text Editor - ' + id);
    };

    var toolbar = function (element) {
      Attr.set(element, 'role', 'toolbar');
      Attr.set(element, 'aria-label', 'Rich Text Editor Toolbar');
    };

    var menu = function (element, label) {
      Attr.set(element, 'role', 'menu');
      Attr.set(element, 'aria-label', label);
    };

    var toolbarButton = function (element, label, hasPopup, isToggle) {
      Attr.set(element, 'role', 'button');
      Attr.set(element, 'aria-label', label);
      if (isToggle) Attr.set(element, 'aria-pressed', 'false');
      Attr.set(element, 'aria-haspopup', '' + hasPopup);
      if (hasPopup) {
        Attr.set(element, 'aria-expanded', 'false');
      }
    };

    var toolbarGroup = function (element, label) {
      // TODO: duplicated from 'ephox.polish.alien.Query', consolidate isEmpty();
      var isEmpty = function (val) {
        // TODO: Move to compass Arr and violin Strings
        return (val === null) || (val === undefined) || (val === '') || (Type.isArray(val) && val.length === 0);
      };
      // End TODO

      if (!isEmpty(label))
        Attr.set(element, 'aria-label', label);
    };

    var menuItem = function (element, label, hasPopup) {
      Attr.set(element, 'role', 'menuitem');
      Attr.set(element, 'aria-label', label);
      Attr.set(element, 'aria-haspopup', hasPopup === true ? 'true' : 'false');
    };

    var dialog = function (element, label) {
      Attr.set(element, 'role', 'dialog');
      Attr.set(element, 'aria-label', label);
    };

    // TODO: Implement form ARIA support
    // var form = function (element, label) {
    //   throw 'Form ARIA support not implemented yet.';
    // };

    var input = function (element, label, required) {
      Attr.set(element, 'aria-label', label);
    };

    // TODO: Implement textarea ARIA support
    // var textarea = function (element, label, required) {
    //   throw 'Textarea ARIA support not implemented yet.';
    // };

    // TODO: Implement link ARIA support
    // var link = function (element) {
    //   throw 'Link ARIA support not implemented yet.';
    // };

    // TODO: Implement other ARIA support
    // var other = function () {
    //   throw 'Other ARIA support not implemented yet.';
    // };

    return {
      editor: editor,
      toolbar: toolbar,
      toolbarGroup: toolbarGroup,
      toolbarButton: toolbarButton,
      menu: menu,
      menuItem: menuItem,
      dialog: dialog,
      input: input
    };
  }
);<|endoftext|>


<commit_before>module.exports = {
    disabled: false,
    //Global vars - use variables defined in globalsModule.js file by client.global.VARIABLE_NAME
    'Access URL': function(client) {
        client
            .url(client.launchUrl)
            .waitForElementVisible('body', 3000);
        //.maximizeWindow();
    },
    'Enter Search': function(client) {
        client
            .verify.elementPresent(client.globals.srchbxID)
            .setValue(client.globals.srchbxID, client.globals.srchCrit2)
            .assert.valueContains(client.globals.srchbxID, client.globals.srchCrit2);
    },
    'Verify Search term displayed on page': function(client) {
        client
            .click(client.globals.srchbtnID)
            .waitForElementPresent('#main-content h1', 1000)
            .verify.containsText('#main-content h1', client.globals.srchCrit2);
            // .pause(100)
            // .verify.elementPresent(client.globals.loadingIndicatorID)
            // .pause(5000);
    },

    'Verify Search header is getting displayed on the side panel': function(client) {
        client
            .verify.containsText('#sidebar .search-title', client.globals.srchhdrtitle);
        // pause(1000);
    },

    'Enter drug brand in search panel': function(client) {
        client
            .setValue(client.globals.sbSrchBxID, client.globals.srchCrit4)
            .click(client.globals.sbSrchBtnID)
            .useCss() //Repointing to the default locator
            .verify.containsText('h1', client.globals.srchCrit4)
    },

    'Enter drug substance in search panel': function(client) {
        client
            .setValue(client.globals.sbSrchBxID, client.globals.srchCrit3)
            .click(client.globals.sbSrchBtnID)
            .useCss()
            .verify.containsText('h1', client.globals.srchCrit3)
    },

    'Close Client': function(client) {
        client.end();
    }

};<commit_msg>debug test cases<commit_after>module.exports = {
    disabled: false,
    //Global vars - use variables defined in globalsModule.js file by client.global.VARIABLE_NAME
    'Access URL': function(client) {
        client
            .url(client.launchUrl)
            .waitForElementVisible('body', 3000);
        //.maximizeWindow();
    },
    'Enter Search': function(client) {
        client
            .verify.elementPresent(client.globals.srchbxID)
            .setValue(client.globals.srchbxID, client.globals.srchCrit2)
            .assert.valueContains(client.globals.srchbxID, client.globals.srchCrit2);
    },
    'Verify Search term displayed on page': function(client) {
        client
            .click(client.globals.srchbtnID)
            .pause(5000)
            .waitForElementPresent('#main-content h1', 1000)
            .pause(5000)
            .verify.containsText('#main-content h1', client.globals.srchCrit2);
            // .pause(100)
            // .verify.elementPresent(client.globals.loadingIndicatorID)
            // .pause(5000);
    },

    'Verify Search header is getting displayed on the side panel': function(client) {
        client
            .pause(5000)
            .verify.containsText('#sidebar .search-title', client.globals.srchhdrtitle);
        // pause(1000);
    },

    'Enter drug brand in search panel': function(client) {
        client
            .setValue(client.globals.sbSrchBxID, client.globals.srchCrit4)
            .click(client.globals.sbSrchBtnID)
            .pause(5000)
            .useCss() //Repointing to the default locator
            .verify.containsText('h1', client.globals.srchCrit4)
    },

    'Enter drug substance in search panel': function(client) {
        client
            .setValue(client.globals.sbSrchBxID, client.globals.srchCrit3)
            .click(client.globals.sbSrchBtnID)
            .pause(5000)
            .useCss()
            .verify.containsText('h1', client.globals.srchCrit3)
    },

    'Close Client': function(client) {
        client.end();
    }

};<|endoftext|>


<commit_before>var BrowserView = function(args) {
  var gridCanvas = document.querySelector('canvas#tetris-grid');
  var previewCanvas = document.querySelector('canvas#tetris-preview');

  this.tableOverlay = document.querySelector('canvas#table-overlay');
  this.tableCanvas = document.querySelector('canvas#tetris-table');

  BLOCK_SPACING_HEIGHT = gridCanvas.getAttribute('height') / 20;
  BLOCK_SPACING_WIDTH = gridCanvas.getAttribute('width') / 10;
  BLOCK_HEIGHT = BLOCK_SPACING_HEIGHT - 10;
  BLOCK_WIDTH = BLOCK_SPACING_WIDTH - 10;

  this.elementDescrip = document.getElementById('element-description');
  this.elementName = document.getElementById('element-name');
  this.atomicNumDisplay = document.getElementById('atomic-number');
  this.elementLink = document.getElementById('element-link');

  this.staticPlayerScore = document.getElementById('player-score-static');
  this.staticHighScore = document.getElementById('high-score-static');
  this.staticGameLevel = document.getElementById('game-level-static');
  this.staticGameMode = document.getElementById('game-mode-static');

  this.playerScore = document.getElementById('player-score');
  this.highScore = document.getElementById('high-score');
  this.gameLevel = document.getElementById('game-level');
  this.gameLevel.innerHTML = genLevelMenu(0);

  this.gameModeContainer = document.getElementById('game-mode');
  this.gameModeContainer.innerHTML = genModeMenu(0);

  this.gameMode = GAME_MODES[document.getElementById('game-mode-dropdown').selectedIndex];
  this.level = 0;

  this.gridContext = gridCanvas.getContext('2d');
  this.previewContext = previewCanvas.getContext('2d');
  this.tableContext = this.tableCanvas.getContext('2d');
  this.overlayContext = this.tableOverlay.getContext('2d');

  this.overlayContext.fillStyle = 'rgba(255, 255, 255, 0.5)';

  this.gameBoard = args.gameBoard;
  this.previewBoard = new PreviewBoard();
  this.tableBoard = new PeriodicTable();

  this.cycleDropBlock = args.cycleDropBlock;
  this.isPaused = true;
  this.pressed = {
    slide: false,
    drop: false,
    rotate: false
  };
  this.interval = {
    slide: null,
    rotate: null
  };

  addEventListener('keydown', this.keyDown.bind(this));
  addEventListener('keyup', this.keyUp.bind(this));

  document.querySelector('#level-right').addEventListener('mousedown', this.buttonDown.bind(this));
  document.querySelector('#level-right').addEventListener('mouseup', this.buttonUp.bind(this));

  this.tableOverlay.addEventListener('mousedown', function(event) {
    var mouseX = Math.floor((event.layerX - this.tableOverlay.offsetLeft) / (540 / 18));
    var mouseY = Math.floor((event.layerY - this.tableOverlay.offsetTop) / (270 / 9));
    var element = 0

    if(mouseX >= 0 && mouseY >= 0) {
      element = this.tableBoard.board[mouseY][mouseX];
    }

    if(element > 0) {
      this.updateElementDescrip(element);
    }
  }.bind(this));
  this.tableOverlay.addEventListener('mousemove', function(event) {
    var mouseX = Math.floor((event.layerX - this.tableOverlay.offsetLeft) / (540 / 18));
    var mouseY = Math.floor((event.layerY - this.tableOverlay.offsetTop) / (270 / 9));
    var element = 0;

    if(mouseX >= 0 && mouseY >= 0) {
      element = this.tableBoard.board[mouseY][mouseX];
    }

    if(element > 0) {
      this.overlayContext.clearRect(0, 0, 540, 270);
      this.overlayContext.fillRect((mouseX * BLOCK_SPACING_WIDTH) + 5, (mouseY * BLOCK_SPACING_HEIGHT) + 5, BLOCK_WIDTH, BLOCK_HEIGHT);
    }
    else {
      this.overlayContext.clearRect(0, 0, 540, 270);
    }
  }.bind(this));

  this.tableOverlay.addEventListener('mouseout', function(event) {
    this.overlayContext.clearRect(0, 0, 540, 270);
  }.bind(this));
}
BrowserView.prototype.keyDown = function(event) {
  var pressedKey = KEY_CODES[event.keyCode];
  if(this.isPaused) {
    if(pressedKey == 'space') {
      event.preventDefault();
      this.isPaused = false;
      this.cycleDropBlock(DROP_DELAY[this.level]);
    }
  }
  else {
    if(pressedKey == 'left' || pressedKey == 'right') {
      event.preventDefault();
      if(this.pressed.slide == false) {
        this.pressed.slide = pressedKey;
        clearInterval(this.interval.slide);
        this.gameBoard.slideBlock(this.pressed.slide);
        this.interval.slide = setInterval(this.gameBoard.slideBlock.bind(this.gameBoard, this.pressed.slide), SLIDE_DELAY);
      }
    }
    else if(pressedKey == 'down') {
      event.preventDefault();
      if(this.pressed.drop == false) {
        this.pressed.drop = true;
        clearTimeout(this.dropTimeout);
        this.cycleDropBlock(FAST_DROP);
      }
    }
    else if(pressedKey == 'up') {
      event.preventDefault();
      if(this.pressed.rotate == false) {
        this.pressed.rotate = true;
        clearInterval(this.interval.rotate);
        this.gameBoard.rotateBlock('clock');
        this.interval.rotate = setInterval(this.gameBoard.rotateBlock.bind(this.gameBoard, 'clock'), ROTATE_DELAY);
      }
    }
    else if(pressedKey == 'space') {
      event.preventDefault();
      clearTimeout(this.gameBoard.dropInterval);
      clearTimeout(this.dropTimeout);
      clearInterval(this.interval.rotate);
      clearInterval(this.interval.slide);
      this.isPaused = true;
    }
  }
};
BrowserView.prototype.keyUp = function(event){
  var releasedKey = KEY_CODES[event.keyCode];
  if(this.isPaused === false) {
    if(releasedKey == 'left' || releasedKey == 'right') {
      event.preventDefault();
      clearInterval(this.interval.slide);
      this.pressed.slide = false;
    }
    if(releasedKey == 'down') {
      event.preventDefault();
      clearTimeout(this.dropTimeout);
      this.pressed.drop = false;
      this.cycleDropBlock(DROP_DELAY[this.level]);
    }
    if(releasedKey == 'up') {
      event.preventDefault();
      clearInterval(this.interval.rotate);
      this.pressed.rotate = false;
    }
  }
};
BrowserView.prototype.buttonDown = function(event) {
  if(event.target.nodeName == "BUTTON") {
    var buttonPressed = event.target.dataset.key;
    if(this.isPaused) {
      if(buttonPressed == 'space') {
        this.isPaused = false;
        this.cycleDropBlock(DROP_DELAY[this.level]);
      }
    }
    else {
      if(buttonPressed == 'left' || buttonPressed == 'right') {
        if(this.pressed.slide == false) {
          this.pressed.slide = buttonPressed;
          clearInterval(this.interval.slide);
          this.interval.slide = setInterval(this.handleInput.bind(this), SLIDE_DELAY);
        }
      }
      else if(buttonPressed == 'down') {
        if(this.pressed.drop == false) {
          this.pressed.drop = true;
          clearTimeout(this.dropTimeout);
          this.cycleDropBlock(FAST_DROP);
        }
      }
      else if(buttonPressed == 'up') {
        if(this.pressed.rotate == false) {
          this.pressed.rotate = true;
          clearInterval(this.interval.rotate);
          this.interval.rotate = setInterval(this.handleInput.bind(this), ROTATE_DELAY);
        }
      }
      else if(buttonPressed == 'space') {
        clearTimeout(this.gameBoard.dropInterval);
        clearTimeout(this.dropTimeout);
        clearInterval(this.interval.rotate);
        clearInterval(this.interval.slide);
        this.isPaused = true;
      }
      this.handleInput();
    }
  }
};
BrowserView.prototype.buttonUp = function(event) {
  if(this.isPaused === false) {
    if(this.pressed.drop) {
      clearTimeout(this.dropTimeout);
      this.cycleDropBlock(DROP_DELAY[this.level]);
    }
    clearInterval(this.interval.slide);
    clearInterval(this.interval.rotate);
    this.releaseAllKeys();
  }
};
BrowserView.prototype.handleInput = function() {
  if(this.pressed.slide) {
    this.gameBoard.slideBlock(this.pressed.slide);
  }
  else if(this.pressed.rotate) {
    this.gameBoard.rotateBlock('clock');
  }
};
BrowserView.prototype.releaseAllKeys = function() {
  this.pressed = {
    slide: false,
    drop: false,
    rotate: false
  };
};
BrowserView.prototype.drawBoard = function(board, context) {
  var gridContext = context;
  gridContext.lineWidth = 4;

  board.forEach(function(row, rIndex) {
    row.forEach(function(col, cIndex) {
      gridContext.fillStyle = CHEMICAL_ELEMENTS[col]['background-color'];
      gridContext.strokeStyle = CHEMICAL_ELEMENTS[col]['border-color'];

      var xPos = (cIndex * BLOCK_SPACING_WIDTH) + 5;
      var yPos = (rIndex * BLOCK_SPACING_HEIGHT) + 5;
      var textX = (cIndex * BLOCK_SPACING_WIDTH) + (BLOCK_SPACING_WIDTH / 2);
      var textY = (rIndex * BLOCK_SPACING_HEIGHT) + (BLOCK_SPACING_HEIGHT / 2) + 4;

      var textLen = CHEMICAL_ELEMENTS[col].symbol.length;
      if(textLen == 1) {
        gridContext.font = FONT_SIZE + BLOCK_FONT;
        textX -= 3;
      }
      else if(textLen == 2) {
        gridContext.font = FONT_SIZE + BLOCK_FONT;
        textX -= 7;
      }
      else if(textLen == 3) {
        gridContext.font = (FONT_SIZE - 2) + BLOCK_FONT;
        textX -= 7;
      }

      gridContext.fillRect(xPos, yPos, BLOCK_WIDTH, BLOCK_HEIGHT);
      gridContext.strokeRect(xPos, yPos, BLOCK_WIDTH, BLOCK_HEIGHT);
      gridContext.fillStyle = CHEMICAL_ELEMENTS[col]['color'];
      gridContext.fillText(CHEMICAL_ELEMENTS[col].symbol, textX, textY);
    });
  });
};
BrowserView.prototype.drawAllBoards = function() {
  this.drawBoard(this.gameBoard.board, this.gridContext);
  this.drawBoard(this.previewBoard.board, this.previewContext);
  this.drawBoard(this.tableBoard.board, this.tableContext);
};
BrowserView.prototype.animateGame = function() {
  var lastTime = null;
  var progress = true;

  var animate = function(time) {
    if(lastTime) {
      var timeStep = Math.min(time - lastTime, 100) / 1000;
      progress = timeStep < 1000;
    }
    lastTime = time;

    if(progress) {
      this.drawAllBoards();
      this.updatePlayerScore(this.gameBoard.score);
      this.updateGameLevel();
      requestAnimationFrame(animate.bind(this));
    }
  }
  requestAnimationFrame(animate.bind(this));
};
BrowserView.prototype.updateElementDescrip = function(element) {
  this.elementName.innerHTML = CHEMICAL_ELEMENTS[element].name + ' [' + CHEMICAL_ELEMENTS[element].symbol + ']';
  this.atomicNumDisplay.innerHTML = element;
  this.elementDescrip.innerHTML = CHEMICAL_ELEMENTS[element].descrip;

  this.elementLink.href = CHEMISTRY_URL + CHEMICAL_ELEMENTS[element].name.toLowerCase();
  this.elementLink.innerHTML = 'Learn more about ' + CHEMICAL_ELEMENTS[element].name.toLowerCase();
};
BrowserView.prototype.updatePlayerScore = function(score) {
  this.playerScore.innerHTML = score;
};
BrowserView.prototype.updateGameLevel = function() {
  var newLevel = scoreToLevel(this.gameBoard.score);
  if(this.gameMode != 'Fixed Level' && this.level != newLevel) {
    this.level = newLevel;
    this.staticGameLevel.innerHTML = this.level;
    clearTimeout(this.dropTimeout);
    this.cycleDropBlock(DROP_DELAY[this.level]);
  }
};
BrowserView.prototype.disableMenus = function() {
  var modeIndex = document.getElementById('game-mode-dropdown').selectedIndex;
  var levelIndex = document.getElementById('game-level-dropdown').selectedIndex;

  this.gameMode = GAME_MODES[modeIndex];

  this.staticGameMode.innerHTML = GAME_MODES[modeIndex];

  if(this.gameMode == 'Fixed Level') {
    this.level = levelIndex;
  }
  else {
    this.level = 0;
  }
  this.staticGameLevel.innerHTML = this.level + ": ";

  this.gameLevel.style = 'display:none;';
  this.gameModeContainer.style = 'display:none;';
  this.staticGameLevel.style = 'display:initial;';
  this.staticGameMode.style = 'display:initial;';
};
BrowserView.prototype.resetDisplay = function() {
  this.staticGameLevel.style = 'display:none;';
  this.staticGameMode.style = 'display:none;';

  this.gameModeContainer.style = 'display:initial;';
  this.gameModeContainer.innerHTML = genModeMenu(this.gameMode);
  this.gameLevel.style = 'display:initial;';
  if(this.highScore.innerHTML < this.gameBoard.score) {
    this.highScore.innerHTML = this.gameBoard.score;
  }
  this.gameLevel.innerHTML = genLevelMenu(this.level);
};
<commit_msg>Update level number rendering to include colon<commit_after>var BrowserView = function(args) {
  var gridCanvas = document.querySelector('canvas#tetris-grid');
  var previewCanvas = document.querySelector('canvas#tetris-preview');

  this.tableOverlay = document.querySelector('canvas#table-overlay');
  this.tableCanvas = document.querySelector('canvas#tetris-table');

  BLOCK_SPACING_HEIGHT = gridCanvas.getAttribute('height') / 20;
  BLOCK_SPACING_WIDTH = gridCanvas.getAttribute('width') / 10;
  BLOCK_HEIGHT = BLOCK_SPACING_HEIGHT - 10;
  BLOCK_WIDTH = BLOCK_SPACING_WIDTH - 10;

  this.elementDescrip = document.getElementById('element-description');
  this.elementName = document.getElementById('element-name');
  this.atomicNumDisplay = document.getElementById('atomic-number');
  this.elementLink = document.getElementById('element-link');

  this.staticPlayerScore = document.getElementById('player-score-static');
  this.staticHighScore = document.getElementById('high-score-static');
  this.staticGameLevel = document.getElementById('game-level-static');
  this.staticGameMode = document.getElementById('game-mode-static');

  this.playerScore = document.getElementById('player-score');
  this.highScore = document.getElementById('high-score');
  this.gameLevel = document.getElementById('game-level');
  this.gameLevel.innerHTML = genLevelMenu(0);

  this.gameModeContainer = document.getElementById('game-mode');
  this.gameModeContainer.innerHTML = genModeMenu(0);

  this.gameMode = GAME_MODES[document.getElementById('game-mode-dropdown').selectedIndex];
  this.level = 0;

  this.gridContext = gridCanvas.getContext('2d');
  this.previewContext = previewCanvas.getContext('2d');
  this.tableContext = this.tableCanvas.getContext('2d');
  this.overlayContext = this.tableOverlay.getContext('2d');

  this.overlayContext.fillStyle = 'rgba(255, 255, 255, 0.5)';

  this.gameBoard = args.gameBoard;
  this.previewBoard = new PreviewBoard();
  this.tableBoard = new PeriodicTable();

  this.cycleDropBlock = args.cycleDropBlock;
  this.isPaused = true;
  this.pressed = {
    slide: false,
    drop: false,
    rotate: false
  };
  this.interval = {
    slide: null,
    rotate: null
  };

  addEventListener('keydown', this.keyDown.bind(this));
  addEventListener('keyup', this.keyUp.bind(this));

  document.querySelector('#level-right').addEventListener('mousedown', this.buttonDown.bind(this));
  document.querySelector('#level-right').addEventListener('mouseup', this.buttonUp.bind(this));

  this.tableOverlay.addEventListener('mousedown', function(event) {
    var mouseX = Math.floor((event.layerX - this.tableOverlay.offsetLeft) / (540 / 18));
    var mouseY = Math.floor((event.layerY - this.tableOverlay.offsetTop) / (270 / 9));
    var element = 0

    if(mouseX >= 0 && mouseY >= 0) {
      element = this.tableBoard.board[mouseY][mouseX];
    }

    if(element > 0) {
      this.updateElementDescrip(element);
    }
  }.bind(this));
  this.tableOverlay.addEventListener('mousemove', function(event) {
    var mouseX = Math.floor((event.layerX - this.tableOverlay.offsetLeft) / (540 / 18));
    var mouseY = Math.floor((event.layerY - this.tableOverlay.offsetTop) / (270 / 9));
    var element = 0;

    if(mouseX >= 0 && mouseY >= 0) {
      element = this.tableBoard.board[mouseY][mouseX];
    }

    if(element > 0) {
      this.overlayContext.clearRect(0, 0, 540, 270);
      this.overlayContext.fillRect((mouseX * BLOCK_SPACING_WIDTH) + 5, (mouseY * BLOCK_SPACING_HEIGHT) + 5, BLOCK_WIDTH, BLOCK_HEIGHT);
    }
    else {
      this.overlayContext.clearRect(0, 0, 540, 270);
    }
  }.bind(this));

  this.tableOverlay.addEventListener('mouseout', function(event) {
    this.overlayContext.clearRect(0, 0, 540, 270);
  }.bind(this));
}
BrowserView.prototype.keyDown = function(event) {
  var pressedKey = KEY_CODES[event.keyCode];
  if(this.isPaused) {
    if(pressedKey == 'space') {
      event.preventDefault();
      this.isPaused = false;
      this.cycleDropBlock(DROP_DELAY[this.level]);
    }
  }
  else {
    if(pressedKey == 'left' || pressedKey == 'right') {
      event.preventDefault();
      if(this.pressed.slide == false) {
        this.pressed.slide = pressedKey;
        clearInterval(this.interval.slide);
        this.gameBoard.slideBlock(this.pressed.slide);
        this.interval.slide = setInterval(this.gameBoard.slideBlock.bind(this.gameBoard, this.pressed.slide), SLIDE_DELAY);
      }
    }
    else if(pressedKey == 'down') {
      event.preventDefault();
      if(this.pressed.drop == false) {
        this.pressed.drop = true;
        clearTimeout(this.dropTimeout);
        this.cycleDropBlock(FAST_DROP);
      }
    }
    else if(pressedKey == 'up') {
      event.preventDefault();
      if(this.pressed.rotate == false) {
        this.pressed.rotate = true;
        clearInterval(this.interval.rotate);
        this.gameBoard.rotateBlock('clock');
        this.interval.rotate = setInterval(this.gameBoard.rotateBlock.bind(this.gameBoard, 'clock'), ROTATE_DELAY);
      }
    }
    else if(pressedKey == 'space') {
      event.preventDefault();
      clearTimeout(this.gameBoard.dropInterval);
      clearTimeout(this.dropTimeout);
      clearInterval(this.interval.rotate);
      clearInterval(this.interval.slide);
      this.isPaused = true;
    }
  }
};
BrowserView.prototype.keyUp = function(event){
  var releasedKey = KEY_CODES[event.keyCode];
  if(this.isPaused === false) {
    if(releasedKey == 'left' || releasedKey == 'right') {
      event.preventDefault();
      clearInterval(this.interval.slide);
      this.pressed.slide = false;
    }
    if(releasedKey == 'down') {
      event.preventDefault();
      clearTimeout(this.dropTimeout);
      this.pressed.drop = false;
      this.cycleDropBlock(DROP_DELAY[this.level]);
    }
    if(releasedKey == 'up') {
      event.preventDefault();
      clearInterval(this.interval.rotate);
      this.pressed.rotate = false;
    }
  }
};
BrowserView.prototype.buttonDown = function(event) {
  if(event.target.nodeName == "BUTTON") {
    var buttonPressed = event.target.dataset.key;
    if(this.isPaused) {
      if(buttonPressed == 'space') {
        this.isPaused = false;
        this.cycleDropBlock(DROP_DELAY[this.level]);
      }
    }
    else {
      if(buttonPressed == 'left' || buttonPressed == 'right') {
        if(this.pressed.slide == false) {
          this.pressed.slide = buttonPressed;
          clearInterval(this.interval.slide);
          this.interval.slide = setInterval(this.handleInput.bind(this), SLIDE_DELAY);
        }
      }
      else if(buttonPressed == 'down') {
        if(this.pressed.drop == false) {
          this.pressed.drop = true;
          clearTimeout(this.dropTimeout);
          this.cycleDropBlock(FAST_DROP);
        }
      }
      else if(buttonPressed == 'up') {
        if(this.pressed.rotate == false) {
          this.pressed.rotate = true;
          clearInterval(this.interval.rotate);
          this.interval.rotate = setInterval(this.handleInput.bind(this), ROTATE_DELAY);
        }
      }
      else if(buttonPressed == 'space') {
        clearTimeout(this.gameBoard.dropInterval);
        clearTimeout(this.dropTimeout);
        clearInterval(this.interval.rotate);
        clearInterval(this.interval.slide);
        this.isPaused = true;
      }
      this.handleInput();
    }
  }
};
BrowserView.prototype.buttonUp = function(event) {
  if(this.isPaused === false) {
    if(this.pressed.drop) {
      clearTimeout(this.dropTimeout);
      this.cycleDropBlock(DROP_DELAY[this.level]);
    }
    clearInterval(this.interval.slide);
    clearInterval(this.interval.rotate);
    this.releaseAllKeys();
  }
};
BrowserView.prototype.handleInput = function() {
  if(this.pressed.slide) {
    this.gameBoard.slideBlock(this.pressed.slide);
  }
  else if(this.pressed.rotate) {
    this.gameBoard.rotateBlock('clock');
  }
};
BrowserView.prototype.releaseAllKeys = function() {
  this.pressed = {
    slide: false,
    drop: false,
    rotate: false
  };
};
BrowserView.prototype.drawBoard = function(board, context) {
  var gridContext = context;
  gridContext.lineWidth = 4;

  board.forEach(function(row, rIndex) {
    row.forEach(function(col, cIndex) {
      gridContext.fillStyle = CHEMICAL_ELEMENTS[col]['background-color'];
      gridContext.strokeStyle = CHEMICAL_ELEMENTS[col]['border-color'];

      var xPos = (cIndex * BLOCK_SPACING_WIDTH) + 5;
      var yPos = (rIndex * BLOCK_SPACING_HEIGHT) + 5;
      var textX = (cIndex * BLOCK_SPACING_WIDTH) + (BLOCK_SPACING_WIDTH / 2);
      var textY = (rIndex * BLOCK_SPACING_HEIGHT) + (BLOCK_SPACING_HEIGHT / 2) + 4;

      var textLen = CHEMICAL_ELEMENTS[col].symbol.length;
      if(textLen == 1) {
        gridContext.font = FONT_SIZE + BLOCK_FONT;
        textX -= 3;
      }
      else if(textLen == 2) {
        gridContext.font = FONT_SIZE + BLOCK_FONT;
        textX -= 7;
      }
      else if(textLen == 3) {
        gridContext.font = (FONT_SIZE - 2) + BLOCK_FONT;
        textX -= 7;
      }

      gridContext.fillRect(xPos, yPos, BLOCK_WIDTH, BLOCK_HEIGHT);
      gridContext.strokeRect(xPos, yPos, BLOCK_WIDTH, BLOCK_HEIGHT);
      gridContext.fillStyle = CHEMICAL_ELEMENTS[col]['color'];
      gridContext.fillText(CHEMICAL_ELEMENTS[col].symbol, textX, textY);
    });
  });
};
BrowserView.prototype.drawAllBoards = function() {
  this.drawBoard(this.gameBoard.board, this.gridContext);
  this.drawBoard(this.previewBoard.board, this.previewContext);
  this.drawBoard(this.tableBoard.board, this.tableContext);
};
BrowserView.prototype.animateGame = function() {
  var lastTime = null;
  var progress = true;

  var animate = function(time) {
    if(lastTime) {
      var timeStep = Math.min(time - lastTime, 100) / 1000;
      progress = timeStep < 1000;
    }
    lastTime = time;

    if(progress) {
      this.drawAllBoards();
      this.updatePlayerScore(this.gameBoard.score);
      this.updateGameLevel();
      requestAnimationFrame(animate.bind(this));
    }
  }
  requestAnimationFrame(animate.bind(this));
};
BrowserView.prototype.updateElementDescrip = function(element) {
  this.elementName.innerHTML = CHEMICAL_ELEMENTS[element].name + ' [' + CHEMICAL_ELEMENTS[element].symbol + ']';
  this.atomicNumDisplay.innerHTML = element;
  this.elementDescrip.innerHTML = CHEMICAL_ELEMENTS[element].descrip;

  this.elementLink.href = CHEMISTRY_URL + CHEMICAL_ELEMENTS[element].name.toLowerCase();
  this.elementLink.innerHTML = 'Learn more about ' + CHEMICAL_ELEMENTS[element].name.toLowerCase();
};
BrowserView.prototype.updatePlayerScore = function(score) {
  this.playerScore.innerHTML = score;
};
BrowserView.prototype.updateGameLevel = function() {
  var newLevel = scoreToLevel(this.gameBoard.score);
  if(this.gameMode != 'Fixed Level' && this.level != newLevel) {
    this.level = newLevel;
    this.staticGameLevel.innerHTML = this.level + ": ";
    clearTimeout(this.dropTimeout);
    this.cycleDropBlock(DROP_DELAY[this.level]);
  }
};
BrowserView.prototype.disableMenus = function() {
  var modeIndex = document.getElementById('game-mode-dropdown').selectedIndex;
  var levelIndex = document.getElementById('game-level-dropdown').selectedIndex;

  this.gameMode = GAME_MODES[modeIndex];

  this.staticGameMode.innerHTML = GAME_MODES[modeIndex];

  if(this.gameMode == 'Fixed Level') {
    this.level = levelIndex;
  }
  else {
    this.level = 0;
  }
  this.staticGameLevel.innerHTML = this.level + ": ";

  this.gameLevel.style = 'display:none;';
  this.gameModeContainer.style = 'display:none;';
  this.staticGameLevel.style = 'display:initial;';
  this.staticGameMode.style = 'display:initial;';
};
BrowserView.prototype.resetDisplay = function() {
  this.staticGameLevel.style = 'display:none;';
  this.staticGameMode.style = 'display:none;';

  this.gameModeContainer.style = 'display:initial;';
  this.gameModeContainer.innerHTML = genModeMenu(this.gameMode);
  this.gameLevel.style = 'display:initial;';
  if(this.highScore.innerHTML < this.gameBoard.score) {
    this.highScore.innerHTML = this.gameBoard.score;
  }
  this.gameLevel.innerHTML = genLevelMenu(this.level);
};
<|endoftext|>


<commit_before>const BurgerMenu = require('react-burger-menu').slide;
const Dropzone = require('react-dropzone');

require('./images/open_file.png');
require('./images/map.png');
require('./images/movie.png');
require('./images/python.png');
require('./styles/menu.css');

class Menu extends React.Component {
  render() {
    let menuStyles = {
      bmBurgerButton: {
        position: 'fixed',
        width: '2em',
        height: '2em',
        left: '1em',
        top: '1em'
      },
      bmBurgerBars: {
        background: '#373a47'
      },
      bmCrossButton: {
        height: '1em',
        width: '1em'
      },
      bmCross: {
        background: '#bdc3c7'
      },
      bmMenu: {
        background: '#373a47',
        padding: '0 0 0',
        fontSize: '1.30em'
      },
      bmMorphShape: {
        fill: '#373a47'
      },
      bmItemList: {
        color: '#b8b7ad',
        padding: '1.8em'
      },
      bmOverlay: {
        background: 'rgba(0, 0, 0, 0.2)'
      }
    }

    let menuItems = [
      {
        class: 'mapButton',
        tooltip: 'Overall concept design'
      },
      {
        class: 'animationButton',
        tooltip: 'Animate the simulated results'
      },
      {
        class: 'pythonButton',
        tooltip: 'Simulate using Python code'
      }
    ];

    let myFunc = () => {
      debugger;
    };

    let onDrop = (files) => {
      debugger;
    };

    let dropZoneStyles = {
      width: "2em",
      height: "2em"
    };

    return (<BurgerMenu styles={menuStyles} width={150}>

          <Dropzone className="menuButton fileOpenButton" onDrop={onDrop}/>

        {
          menuItems.map(function(item) {
            let classNames = "menuButton tooltip " + item.class;
            return (

              <input type="button" onClick={myFunc} className={classNames}/>

);
          })
        }
    </BurgerMenu>);
  }
}

export default Menu;
<commit_msg>comments in menu<commit_after>const BurgerMenu = require('react-burger-menu').slide;
const Dropzone = require('react-dropzone');

require('./images/open_file.png');
require('./images/map.png');
require('./images/movie.png');
require('./images/python.png');
require('./styles/menu.css');

class Menu extends React.Component {
  render() {
    let menuStyles = {
      bmBurgerButton: {
        position: 'fixed',
        width: '2em',
        height: '2em',
        left: '1em',
        top: '1em'
      },
      bmBurgerBars: {
        background: '#373a47'
      },
      bmCrossButton: {
        height: '1em',
        width: '1em'
      },
      bmCross: {
        background: '#bdc3c7'
      },
      bmMenu: {
        background: '#373a47',
        padding: '0 0 0',
        fontSize: '1.30em'
      },
      bmMorphShape: {
        fill: '#373a47'
      },
      bmItemList: {
        color: '#b8b7ad',
        padding: '1.8em'
      },
      bmOverlay: {
        background: 'rgba(0, 0, 0, 0.2)'
      }
    }

    let menuItems = [
      {
        class: 'mapButton',
        tooltip: 'Overall concept design'
      },
      {
        class: 'animationButton',
        tooltip: 'Animate the simulated results'
      },
      {
        class: 'pythonButton',
        tooltip: 'Python code for simulating the system'
      }
    ];

    let myFunc = () => {
      debugger;
    };

    let onDrop = (files) => {
      debugger;
    };

    let dropZoneStyles = {
      width: "2em",
      height: "2em"
    };

    return (<BurgerMenu styles={menuStyles} width={150}>

          <Dropzone className="menuButton fileOpenButton" onDrop={onDrop}/>

        {
          menuItems.map(function(item) {
            let classNames = "menuButton tooltip " + item.class;
            return (

              <input type="button" onClick={myFunc} className={classNames}/>

);
          })
        }
    </BurgerMenu>);
  }
}

export default Menu;
<|endoftext|>


<commit_before><commit_msg>Normalize path.<commit_after><|endoftext|>


<commit_before>// ==UserScript==
// @name        Stack Exchange Pronoun Assistant
// @namespace   https://github.com/Glorfindel83/
// @description Displays users' pronouns (mentioned in their profiles) in chat
// @author      Glorfindel
// @contributor ArtOfCode
// @updateURL   https://raw.githubusercontent.com/Glorfindel83/SE-Userscripts/master/pronoun-assistant/pronoun-assistant.user.js
// @downloadURL https://raw.githubusercontent.com/Glorfindel83/SE-Userscripts/master/pronoun-assistant/pronoun-assistant.user.js
// @supportURL  https://stackapps.com/questions/8440/pronoun-assistant
// @version     1.2
// @match       *://chat.stackexchange.com/rooms/*
// @match       *://chat.stackoverflow.com/rooms/*
// @match       *://chat.meta.stackexchange.com/rooms/*
// @grant       GM_addStyle
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// ==/UserScript==

/* global $, waitForKeyElements */

// NICETOHAVE: on main/meta sites as well; right now, there are very few users
// who have indicated their pronouns in their main/meta profile.

GM_addStyle(`
.tiny-signature {
  display: inline-flex;
  flex-direction: row-reverse;
  align-items: center;
}

.username {
  height: unset !important;
}

.pronouns {
  color: #777;
}
`)

// List of pronouns to look out for
let allPronouns = [
  "him", "his",
  "she", "her?", // that covers 'he' as well
  "they", "them", "their",
  "ze", "hir", "zir",
  "xey", "xem", "xyr"
].join("|");
let pronounListRegex = new RegExp('\\W*((' + allPronouns + ')(\\s*/\\s*(' + allPronouns + '))+)\\W*', 'i');
let myPronounIsRegex = /(https?:\/\/)?(my\.)?pronoun\.is\/[\w/]+/i;
let explicitPronounsRegex = /pronouns:\s*([^.\n]*)(\.|\n|$)/im;

// Keys:   user IDs
// Values: either a list of DOM elements (specifically, the anchors to chat profiles)
//         or a string with pronouns.
var users = {};
// TODO: cache in local storage

// Adds pronoun information to a user's 'signature' in chat.
function showPronouns(element, pronouns) {
  if (pronouns == "") {
    return;
  }
  // the element might contain both a tiny and a full signature
  element.find("div.username").each(function (index, usernameElement) {
    usernameElement.innerHTML = '' + usernameElement.innerHTML + '
'
      + '' + pronouns + '';
  });
}

// Check the user's 'about' in their chat profile for pronoun indicators
function getPronouns(aboutMe) {
  // Link to Pronoun Island, e.g.
  // http://my.pronoun.is/she
  var match = myPronounIsRegex.exec(aboutMe);
  if (match != null) {
    return match[0];
  }

  // Explicit pronouns specification, e.g.
  // Pronouns: he/him.
  // The end is indicated by a dot, a newline, or simply the end of the text.
  match = explicitPronounsRegex.exec(aboutMe);
  if (match != null) {
    return match[1];
  }

  // Check for pronouns (see above for the list) joined by a forward slash, e.g.
  // she/her
  // (he/him/his)
  // they / them
  match = pronounListRegex.exec(aboutMe);
  if (match != null) {
    return match[1];
  }

  // No pronouns found
  return "";
}

waitForKeyElements("a.signature", function(jNode) {
  let userID = jNode.attr("href").split("/users/")[1];
  if (!users.hasOwnProperty(userID)) {
    users[userID] = [];
    users[userID].push(jNode);
    // Read chat profile
    $.get("https://" + location.host + "/users/thumbs/" + userID + "?showUsage=true", function(data) {
      let pronouns = data.user_message == null ? "" : getPronouns(data.user_message);
      users[userID].forEach(function (element) {
        showPronouns(element, pronouns);
      });
      users[userID] = pronouns;
    });
  } else if (typeof users[userID] == 'string') {
    showPronouns(jNode, users[userID]);
  } else {
    users[userID].push(jNode);
  }
});
<commit_msg>Pronoun Assistant v1.3<commit_after>// ==UserScript==
// @name        Stack Exchange Pronoun Assistant
// @namespace   https://github.com/Glorfindel83/
// @description Displays users' pronouns (mentioned in their profiles) in chat
// @author      Glorfindel
// @contributor ArtOfCode
// @updateURL   https://raw.githubusercontent.com/Glorfindel83/SE-Userscripts/master/pronoun-assistant/pronoun-assistant.user.js
// @downloadURL https://raw.githubusercontent.com/Glorfindel83/SE-Userscripts/master/pronoun-assistant/pronoun-assistant.user.js
// @supportURL  https://stackapps.com/questions/8440/pronoun-assistant
// @version     1.3
// @match       *://chat.stackexchange.com/rooms/*
// @match       *://chat.stackoverflow.com/rooms/*
// @match       *://chat.meta.stackexchange.com/rooms/*
// @grant       GM_addStyle
// @require     https://gist.github.com/raw/2625891/waitForKeyElements.js
// ==/UserScript==

/* global $, waitForKeyElements */

// NICETOHAVE: on main/meta sites as well; right now, there are very few users
// who have indicated their pronouns in their main/meta profile.

GM_addStyle(`
.tiny-signature {
  display: inline-flex;
  flex-direction: row-reverse;
  align-items: center;
  width: 100%;
}

.username {
  height: unset !important;
}

.pronouns {
  color: #777;
}
`)

// List of pronouns to look out for
let allPronouns = [
  "him", "his",
  "she", "her?", // that covers 'he' as well
  "they", "them", "their",
  "ze", "hir", "zir",
  "xey", "xem", "xyr"
].join("|");
let pronounListRegex = new RegExp('\\W*((' + allPronouns + ')(\\s*/\\s*(' + allPronouns + '))+)\\W*', 'i');
let myPronounIsRegex = /(https?:\/\/)?(my\.)?pronoun\.is\/[\w/]+/i;
let explicitPronounsRegex = /pronouns:\s*([^.\n]*)(\.|\n|$)/im;

// Keys:   user IDs
// Values: either a list of DOM elements (specifically, the anchors to chat profiles)
//         or a string with pronouns.
var users = {};
// TODO: cache in local storage

// Adds pronoun information to a user's 'signature' in chat.
function showPronouns(element, pronouns) {
  if (pronouns == "") {
    return;
  }
  // the element might contain both a tiny and a full signature
  element.find("div.username").each(function (index, usernameElement) {
    usernameElement.innerHTML = '' + usernameElement.innerHTML + '
'
      + '' + pronouns + '';
  });
}

// Check the user's 'about' in their chat profile for pronoun indicators
function getPronouns(aboutMe) {
  // Link to Pronoun Island, e.g.
  // http://my.pronoun.is/she
  var match = myPronounIsRegex.exec(aboutMe);
  if (match != null) {
    return match[0];
  }

  // Explicit pronouns specification, e.g.
  // Pronouns: he/him.
  // The end is indicated by a dot, a newline, or simply the end of the text.
  match = explicitPronounsRegex.exec(aboutMe);
  if (match != null) {
    return match[1];
  }

  // Check for pronouns (see above for the list) joined by a forward slash, e.g.
  // she/her
  // (he/him/his)
  // they / them
  match = pronounListRegex.exec(aboutMe);
  if (match != null) {
    return match[1];
  }

  // No pronouns found
  return "";
}

waitForKeyElements("a.signature", function(jNode) {
  let userID = jNode.attr("href").split("/users/")[1];
  if (!users.hasOwnProperty(userID)) {
    users[userID] = [];
    users[userID].push(jNode);
    // Read chat profile
    $.get("https://" + location.host + "/users/thumbs/" + userID + "?showUsage=true", function(data) {
      let pronouns = data.user_message == null ? "" : getPronouns(data.user_message);
      users[userID].forEach(function (element) {
        showPronouns(element, pronouns);
      });
      users[userID] = pronouns;
    });
  } else if (typeof users[userID] == 'string') {
    showPronouns(jNode, users[userID]);
  } else {
    users[userID].push(jNode);
  }
});
<|endoftext|>


<commit_before><commit_msg>Test that the accept-version header is sent<commit_after><|endoftext|>


<commit_before><commit_msg>Removed debugging console log<commit_after><|endoftext|>


<commit_before><commit_msg>Don't use "done()" in config test<commit_after><|endoftext|>