<commit_before>var common      = module.exports = {}
  , configCache = {}
  , env         = process.env.NODE_ENV || 'development';

var config = common.config = function config(name, allowBlank) {
  if (typeof configCache[name] !== 'undefined') { return configCache[name]; }

  try {
    var conf = require('./config/'+name);
  } catch (e) {
    if (allowBlank) { return configCache[name] = null; }
    throw e;
  }

  conf = conf[env];
  if (!conf) {
    if (allowBlank) {
      console.error(name+" config not specified for "+env+" environment");
      return configCache[name] = null;
    }
    throw new Error(env+" enviroment not specified for config/"+name);
  }

  return configCache[name] = conf;
};

common.knex = require('knex')(config('knexfile'));
common.redis = newRedisClient('redis');

common.notifyError = function(err) {
  console.error(err);
};

if (config('sentry', true)) {
  var raven = require('raven');
  var ravenClient = new raven.Client(config('sentry').dsn);
  ravenClient.patchGlobal();
  common.notifyError = function(err, callback) {
    if (!(err instanceof Error)) { err = new Error(err); }
    ravenClient.captureError(err, callback);
  }
}

common.publishEvent = function(event, callback) {
  console.log('Event: ', event);
  return callback && callback();
}

if (config('redis_events', true)) {
  var redis = newRedisClient('redis_events');
  common.publishEvent = function(stats, callback) {
    redis.publish("yodel:events", JSON.stringify(stats), callback);
  }
}

function newRedisClient(configName) {
  var rConfig = config(configName, true) || {};
  rConfig.port = rConfig.port || 6379;
  rConfig.host = rConfig.host || '127.0.0.1';

  // Don't want to overwrite any data in a database for another env
  if (env == 'test' && typeof rConfig.database === 'undefined') {
    rConfig.database = 5;
  }

  var client = require("redis").createClient(
    rConfig.port, rConfig.host, rConfig.options);

  if (!isNaN(config.database)) { client.select(config.database); }

  return client;
}
<commit_msg>stats -> event<commit_after>var common      = module.exports = {}
  , configCache = {}
  , env         = process.env.NODE_ENV || 'development';

var config = common.config = function config(name, allowBlank) {
  if (typeof configCache[name] !== 'undefined') { return configCache[name]; }

  try {
    var conf = require('./config/'+name);
  } catch (e) {
    if (allowBlank) { return configCache[name] = null; }
    throw e;
  }

  conf = conf[env];
  if (!conf) {
    if (allowBlank) {
      console.error(name+" config not specified for "+env+" environment");
      return configCache[name] = null;
    }
    throw new Error(env+" enviroment not specified for config/"+name);
  }

  return configCache[name] = conf;
};

common.knex = require('knex')(config('knexfile'));
common.redis = newRedisClient('redis');

common.notifyError = function(err) {
  console.error(err);
};

if (config('sentry', true)) {
  var raven = require('raven');
  var ravenClient = new raven.Client(config('sentry').dsn);
  ravenClient.patchGlobal();
  common.notifyError = function(err, callback) {
    if (!(err instanceof Error)) { err = new Error(err); }
    ravenClient.captureError(err, callback);
  }
}

common.publishEvent = function(event, callback) {
  console.log('Event: ', event);
  return callback && callback();
}

if (config('redis_events', true)) {
  var redis = newRedisClient('redis_events');
  common.publishEvent = function(event, callback) {
    redis.publish("yodel:events", JSON.stringify(event), callback);
  }
}

function newRedisClient(configName) {
  var rConfig = config(configName, true) || {};
  rConfig.port = rConfig.port || 6379;
  rConfig.host = rConfig.host || '127.0.0.1';

  // Don't want to overwrite any data in a database for another env
  if (env == 'test' && typeof rConfig.database === 'undefined') {
    rConfig.database = 5;
  }

  var client = require("redis").createClient(
    rConfig.port, rConfig.host, rConfig.options);

  if (!isNaN(config.database)) { client.select(config.database); }

  return client;
}
<|endoftext|>


<commit_before>'use strict';

const VirtualDOMNode = require('../virtualDOMNode');

class VirtualDOMElement extends VirtualDOMNode {
  constructor(tagName, props) {
    const domElement = document.createElement(tagName);

    super(props, domElement);
  }

  mount(parent, reference, context) {
    super.mount(parent, reference);

    const childParent = this,
          childReference = null,
          childContext = context;

    this.children.forEach(function(child) {
      child.mount(childParent, childReference, childContext);
    });

    this.applyProps();
  }

  unmount(context) {
    const childContext = context;

    this.children.forEach(function(child) {
      child.unmount(childContext);
    });

    super.unmount();
  }

  getTagName() {
    const domElement = this.getDOMElement(),
          tagName = domElement.tagName;

    return tagName;
  }

  spliceChildren(start, removedChildrenCount, addedChildren, context) {
    const childParent = this,
          childReference = null,
          childContext = context;

    addedChildren.forEach(function(addedChild) {
      addedChild.mount(childParent, childReference, childContext);
    });

    const args = [start, removedChildrenCount].concat(addedChildren),
          removedChildren = Array.prototype.splice.apply(this.children, args);

    removedChildren.forEach(function(removedChild) {
      removedChild.unmount(childContext);
    });
  }

  addChild(child, context) {
    const start = Infinity,
          removedChildrenCount = 0,
          addedChildren = [child];

    this.spliceChildren(start, removedChildrenCount, addedChildren, context);
  }

  removeChild(child, context) {
    const index = this.children.indexOf(child);

    if (index > -1) {
      const start = index,
            removedChildrenCount = 1,
            addedChildren = [];

      this.spliceChildren(start, removedChildrenCount, addedChildren, context);
    }
  }

  setAttribute(name, value) {
    if (name === 'className') {
      name = 'class';
    }

    if (name === 'htmlFor') {
      name = 'for';
    }

    if (false) {

    } else if (typeof value === 'object') {
      const keys = Object.keys(value);

      keys.forEach(function (key) {
        this.domElement[name][key] = value[key];
      }.bind(this));
    } else if (typeof value === 'boolean') {
      if (value) {
        value = name; ///

        this.domElement.setAttribute(name, value);
      }
    } else {
      this.domElement.setAttribute(name, value);
    }
  }

  getAttribute(name) {
    return this.domElement.getAttribute(name);
  }

  clearAttribute(name) {
    this.domElement.removeAttribute(name);
  }

  setClass(className) {
    this.domElement.className = className;
  }

  addClass(className) {
    this.domElement.classList.add(className);
  }

  removeClass(className) {
    this.domElement.classList.remove(className);
  }

  toggleClass(className) {
    this.domElement.classList.toggle(className);
  }

  hasClass(className) {
    return this.domElement.classList.contains(className);
  }

  clearClasses() {
    this.domElement.className = '';
  }

  applyProps() {
    const names = Object.keys(this.props);

    names.forEach(function(name) {
      const value = this.props[name];

      if (isHandlerName(name)) {
        const domElement = this.getDOMElement(),
              eventType = eventTypeFromName(name),
              handler = value;  ///

        domElement.addEventListener(eventType,  handler);
      } else if (name === 'ref') {
        const callback = value, ///
              domElement = this.getDOMElement();

        callback(domElement)
      } else {
        this.setAttribute(name, value);
      }
    }.bind(this));
  }
}

module.exports = VirtualDOMElement;

function isHandlerName(name) {
  return name.match(/^on/);
}

function eventTypeFromName(name) {
  return name.substr(2).toLowerCase();
}
<commit_msg>Cosmetic changes to the VirtualDOMElement class.<commit_after>'use strict';

const VirtualDOMNode = require('../virtualDOMNode');

class VirtualDOMElement extends VirtualDOMNode {
  constructor(tagName, props) {
    const domElement = document.createElement(tagName);

    super(props, domElement);
  }

  mount(parent, reference, context) {
    super.mount(parent, reference);

    const childParent = this,
          childReference = null,
          childContext = context;

    this.children.forEach(function(child) {
      child.mount(childParent, childReference, childContext);
    });

    this.applyProps();
  }

  unmount(context) {
    const childContext = context;

    this.children.forEach(function(child) {
      child.unmount(childContext);
    });

    super.unmount();
  }

  getTagName() {
    const domElement = this.getDOMElement(),
          tagName = domElement.tagName;

    return tagName;
  }

  spliceChildren(start, removedChildrenCount, addedChildren, context) {
    const childParent = this,
          childReference = null,
          childContext = context;

    addedChildren.forEach(function(addedChild) {
      addedChild.mount(childParent, childReference, childContext);
    });

    const args = [start, removedChildrenCount].concat(addedChildren),
          removedChildren = Array.prototype.splice.apply(this.children, args);

    removedChildren.forEach(function(removedChild) {
      removedChild.unmount(childContext);
    });
  }

  addChild(child, context) {
    const start = Infinity,
          removedChildrenCount = 0,
          addedChildren = [child];

    this.spliceChildren(start, removedChildrenCount, addedChildren, context);
  }

  removeChild(child, context) {
    const index = this.children.indexOf(child);

    if (index > -1) {
      const start = index,
            removedChildrenCount = 1,
            addedChildren = [];

      this.spliceChildren(start, removedChildrenCount, addedChildren, context);
    }
  }

  setAttribute(name, value) {
    if (name === 'className') {
      name = 'class';
    }

    if (name === 'htmlFor') {
      name = 'for';
    }

    if (false) {

    } else if (typeof value === 'object') {
      const keys = Object.keys(value);

      keys.forEach(function (key) {
        this.domElement[name][key] = value[key];
      }.bind(this));
    } else if (typeof value === 'boolean') {
      if (value) {
        value = name; ///

        this.domElement.setAttribute(name, value);
      }
    } else {
      this.domElement.setAttribute(name, value);
    }
  }

  getAttribute(name) { return this.domElement.getAttribute(name); }

  clearAttribute(name) { this.domElement.removeAttribute(name); }

  setClass(className) { this.domElement.className = className; }

  addClass(className) { this.domElement.classList.add(className); }

  removeClass(className) { this.domElement.classList.remove(className); }

  toggleClass(className) { this.domElement.classList.toggle(className); }

  hasClass(className) { return this.domElement.classList.contains(className); }

  clearClasses() { this.domElement.className = ''; }

  applyProps() {
    const names = Object.keys(this.props);

    names.forEach(function(name) {
      const value = this.props[name];

      if (isHandlerName(name)) {
        const domElement = this.getDOMElement(),
              eventType = eventTypeFromName(name),
              handler = value;  ///

        domElement.addEventListener(eventType,  handler);
      } else if (name === 'ref') {
        const callback = value, ///
              domElement = this.getDOMElement();

        callback(domElement)
      } else {
        this.setAttribute(name, value);
      }
    }.bind(this));
  }
}

module.exports = VirtualDOMElement;

function isHandlerName(name) {
  return name.match(/^on/);
}

function eventTypeFromName(name) {
  return name.substr(2).toLowerCase();
}
<|endoftext|>


<commit_before>/*
 * errs.js: Simple error creation and passing utilities.
 *
 * (C) 2012, Nodejitsu Inc.
 * MIT LICENSE
 *
 */

var events = require('events'),
    util = require('util');

//
// Container for registered error types.
//
exports.registered = {};

//
// Add `Error.prototype.toJSON` if it doesn't exist.
//
if (!Error.prototype.toJSON) {
  Object.defineProperty(Error.prototype, 'toJSON', {
    enumerable: false,
    value: function () {
      return mixin({
        message: this.message,
        stack: this.stack,
        arguments: this.arguments,
        type: this.type
      }, this);
    }
  });
}

//
// ### function create (type, opts)
// #### @type {string} **Optional** Registered error type to create
// #### @opts {string|object|Array|function} Options for creating the error:
//   * `string`:   Message for the error
//   * `object`:   Properties to include on the error
//   * `array`:    Message for the error (' ' joined).
//   * `function`: Function to return error options.
//
// Creates a new error instance for with the specified `type`
// and `options`. If the `type` is not registered then a new
// `Error` instance will be created.
//
exports.create = function createErr(type, opts) {
  if (!arguments[1] && !exports.registered[type]) {
    opts = type;
    type = null;
  }

  //
  // If the `opts` has a `stack` property assume
  // that it is already an error instance.
  //
  if (opts && opts.stack) {
    return opts;
  }

  var message,
      ErrorProto,
      error;

  //
  // Parse arguments liberally for the message
  //
  if (typeof opts === 'function') {
    opts = opts();
  }

  if (Array.isArray(opts)) {
    message = opts.join(' ');
    opts = null;
  }
  else if (opts) {
    switch (typeof opts) {
      case 'string':
        message = opts || 'Unspecified error';
        opts = null;
        break;
      case 'object':
        message = (opts && opts.message) || 'Unspecified error';
        break;
      default:
        message = 'Unspecified error';
        break;
    }
  }

  //
  // Instantiate a new Error instance or a new
  // registered error type (if it exists).
  //
  ErrorProto = type && exports.registered[type] || Error;
  error = new (ErrorProto)(message);

  if (!error.name || error.name === 'Error') {
    error.name = ErrorProto.name || 'Error';
  }

  //
  // Capture a stack trace if it does not already exist and
  // remote the part of the stack trace referencing `errs.js`.
  //
  if (!error.stack) {
    Error.call(error);
    Error.captureStackTrace(error, createErr);
  }
  else {
    error.stack = error.stack.split('\n');
    error.stack.splice(1, 1);
    error.stack = error.stack.join('\n');
  }

  //
  // Copy all options to the new error instance.
  //
  if (opts) {
    Object.keys(opts).forEach(function (key) {
      error[key] = opts[key];
    });
  }

  return error;
};

//
// ### function merge (err, type, opts)
// #### @err  {error} The error to merge
// #### @type {string} **Optional** Registered error type to create
// #### @opts {string|object|Array|function} Options for creating the error:
//   * `string`:   Message for the error
//   * `object`:   Properties to include on the error
//   * `array`:    Message for the error (' ' joined).
//   * `function`: Function to return error options.
//
// Merges an existing error with a new error instance for with
// the specified `type` and `options`.
//
exports.merge = function (err, type, opts) {
  var merged = exports.create(type, opts);

  //
  // optional stuff that might be created by module
  //
  Object.keys(err).forEach(function (key) {
    //
    // in node v0.4 v8 errors where treated differently
    // we need to make sure we aren't merging these properties
    // http://code.google.com/p/v8/issues/detail?id=1215
    //
    if (['stack', 'type', 'arguments', 'message'].indexOf(key)===-1) {
      merged[key] = err[key];
    }
  });

  // merging
  merged.name = merged.name || err.name;
  merged.message = merged.message || err.message;

  // override stack
  merged.stack = err.stack;

  // add human-readable errors
  merged.description = err.message;
  merged.stacktrace = err.stack.split("\n");

  return merged;
};

//
// ### function handle (error, callback)
// #### @error {string|function|Array|object} Error to handle
// #### @callback {function|EventEmitter} **Optional** Continuation or stream to pass the error to.
// #### @stream {EventEmitter} **Optional** Explicit EventEmitter to use.
//
// Attempts to instantiate the given `error`. If the `error` is already a properly
// formed `error` object (with a `stack` property) it will not be modified.
//
// * If `callback` is a function, it is invoked with the `error`.
// * If `callback` is an `EventEmitter`, it emits the `error` event on
//   that emitter and returns it.
// * If no `callback`, return a new `EventEmitter` which emits `error`
//   on `process.nextTick()`.
//
exports.handle = function (error, callback, stream) {
  error = exports.create(error);

  if (typeof callback === 'function') {
    callback(error);
  }

  if (typeof callback !== 'function' || stream) {
    var emitter = stream || callback || new events.EventEmitter();
    process.nextTick(function () { emitter.emit('error', error); });
    return emitter;
  }
};

//
// ### function register (type, proto)
// #### @type {string} **Optional** Type of the error to register.
// #### @proto {function} Constructor function of the error to register.
//
// Registers the specified `proto` to `type` for future calls to
// `errors.create(type, opts)`.
//
exports.register = function (type, proto) {
  if (arguments.length === 1) {
    proto = type;
    type = proto.name.toLowerCase();
  }
  exports.registered[type] = proto;
};

//
// ### function unregister (type)
// #### @type {string} Type of the error to unregister.
//
// Unregisters the specified `type` for future calls to
// `errors.create(type, opts)`.
//
exports.unregister = function (type) {
  delete exports.registered[type];
};

//
// ### function mixin (target [source0, source1, ...])
// Copies enumerable properties from `source0 ... sourceN`
// onto `target` and returns the resulting object.
//
function mixin(target) {
  //
  // Quickly and performantly (in V8) `Arrayify` arguments.
  //
  var len = arguments.length,
      args = new Array(len - 1),
      i = 1;

  for (; i < len; i++) {
    args[i - 1] = arguments[i];
  }

  args.forEach(function (o) {
    Object.keys(o).forEach(function (attr) {
      var getter = o.__lookupGetter__(attr),
          setter = o.__lookupSetter__(attr);

      if (!getter && !setter) {
        target[attr] = o[attr];
      }
      else {
        if (setter) target.__defineSetter__(attr, setter);
        if (getter) target.__defineGetter__(attr, getter);
      }
    });
  });

  return target;
};<commit_msg>[dist] JSHint compliance<commit_after>/*
 * errs.js: Simple error creation and passing utilities.
 *
 * (C) 2012, Nodejitsu Inc.
 * MIT LICENSE
 *
 */

var events = require('events'),
    util = require('util');

//
// Container for registered error types.
//
exports.registered = {};

//
// Add `Error.prototype.toJSON` if it doesn't exist.
//
if (!Error.prototype.toJSON) {
  Object.defineProperty(Error.prototype, 'toJSON', {
    enumerable: false,
    value: function () {
      return mixin({
        message: this.message,
        stack: this.stack,
        arguments: this.arguments,
        type: this.type
      }, this);
    }
  });
}

//
// ### function create (type, opts)
// #### @type {string} **Optional** Registered error type to create
// #### @opts {string|object|Array|function} Options for creating the error:
//   * `string`:   Message for the error
//   * `object`:   Properties to include on the error
//   * `array`:    Message for the error (' ' joined).
//   * `function`: Function to return error options.
//
// Creates a new error instance for with the specified `type`
// and `options`. If the `type` is not registered then a new
// `Error` instance will be created.
//
exports.create = function createErr(type, opts) {
  if (!arguments[1] && !exports.registered[type]) {
    opts = type;
    type = null;
  }

  //
  // If the `opts` has a `stack` property assume
  // that it is already an error instance.
  //
  if (opts && opts.stack) {
    return opts;
  }

  var message,
      ErrorProto,
      error;

  //
  // Parse arguments liberally for the message
  //
  if (typeof opts === 'function') {
    opts = opts();
  }

  if (Array.isArray(opts)) {
    message = opts.join(' ');
    opts = null;
  }
  else if (opts) {
    switch (typeof opts) {
      case 'string':
        message = opts || 'Unspecified error';
        opts = null;
        break;
      case 'object':
        message = (opts && opts.message) || 'Unspecified error';
        break;
      default:
        message = 'Unspecified error';
        break;
    }
  }

  //
  // Instantiate a new Error instance or a new
  // registered error type (if it exists).
  //
  ErrorProto = type && exports.registered[type] || Error;
  error = new (ErrorProto)(message);

  if (!error.name || error.name === 'Error') {
    error.name = ErrorProto.name || 'Error';
  }

  //
  // Capture a stack trace if it does not already exist and
  // remote the part of the stack trace referencing `errs.js`.
  //
  if (!error.stack) {
    Error.call(error);
    Error.captureStackTrace(error, createErr);
  }
  else {
    error.stack = error.stack.split('\n');
    error.stack.splice(1, 1);
    error.stack = error.stack.join('\n');
  }

  //
  // Copy all options to the new error instance.
  //
  if (opts) {
    Object.keys(opts).forEach(function (key) {
      error[key] = opts[key];
    });
  }

  return error;
};

//
// ### function merge (err, type, opts)
// #### @err  {error} The error to merge
// #### @type {string} **Optional** Registered error type to create
// #### @opts {string|object|Array|function} Options for creating the error:
//   * `string`:   Message for the error
//   * `object`:   Properties to include on the error
//   * `array`:    Message for the error (' ' joined).
//   * `function`: Function to return error options.
//
// Merges an existing error with a new error instance for with
// the specified `type` and `options`.
//
exports.merge = function (err, type, opts) {
  var merged = exports.create(type, opts);

  //
  // optional stuff that might be created by module
  //
  Object.keys(err).forEach(function (key) {
    //
    // in node v0.4 v8 errors where treated differently
    // we need to make sure we aren't merging these properties
    // http://code.google.com/p/v8/issues/detail?id=1215
    //
    if (['stack', 'type', 'arguments', 'message'].indexOf(key)===-1) {
      merged[key] = err[key];
    }
  });

  // merging
  merged.name = merged.name || err.name;
  merged.message = merged.message || err.message;

  // override stack
  merged.stack = err.stack;

  // add human-readable errors
  merged.description = err.message;
  merged.stacktrace = err.stack.split("\n");

  return merged;
};

//
// ### function handle (error, callback)
// #### @error {string|function|Array|object} Error to handle
// #### @callback {function|EventEmitter} **Optional** Continuation or stream to pass the error to.
// #### @stream {EventEmitter} **Optional** Explicit EventEmitter to use.
//
// Attempts to instantiate the given `error`. If the `error` is already a properly
// formed `error` object (with a `stack` property) it will not be modified.
//
// * If `callback` is a function, it is invoked with the `error`.
// * If `callback` is an `EventEmitter`, it emits the `error` event on
//   that emitter and returns it.
// * If no `callback`, return a new `EventEmitter` which emits `error`
//   on `process.nextTick()`.
//
exports.handle = function (error, callback, stream) {
  error = exports.create(error);

  if (typeof callback === 'function') {
    callback(error);
  }

  if (typeof callback !== 'function' || stream) {
    var emitter = stream || callback || new events.EventEmitter();
    process.nextTick(function () { emitter.emit('error', error); });
    return emitter;
  }
};

//
// ### function register (type, proto)
// #### @type {string} **Optional** Type of the error to register.
// #### @proto {function} Constructor function of the error to register.
//
// Registers the specified `proto` to `type` for future calls to
// `errors.create(type, opts)`.
//
exports.register = function (type, proto) {
  if (arguments.length === 1) {
    proto = type;
    type = proto.name.toLowerCase();
  }
  exports.registered[type] = proto;
};

//
// ### function unregister (type)
// #### @type {string} Type of the error to unregister.
//
// Unregisters the specified `type` for future calls to
// `errors.create(type, opts)`.
//
exports.unregister = function (type) {
  delete exports.registered[type];
};

//
// ### function mixin (target [source0, source1, ...])
// Copies enumerable properties from `source0 ... sourceN`
// onto `target` and returns the resulting object.
//
function mixin(target) {
  //
  // Quickly and performantly (in V8) `Arrayify` arguments.
  //
  var len = arguments.length,
      args = new Array(len - 1),
      i = 1;

  for (; i < len; i++) {
    args[i - 1] = arguments[i];
  }

  args.forEach(function (o) {
    Object.keys(o).forEach(function (attr) {
      var getter = o.__lookupGetter__(attr),
          setter = o.__lookupSetter__(attr);

      if (!getter && !setter) {
        target[attr] = o[attr];
      }
      else {
        if (setter) { target.__defineSetter__(attr, setter) }
        if (getter) { target.__defineGetter__(attr, getter) }
      }
    });
  });

  return target;
}<|endoftext|>


<commit_before>/* global renderMathInElement */
'use strict';

const $ = require( 'jquery' );
const MarkdownIt = require('markdown-it');
var md = new MarkdownIt();

/* global TimelineMax: true */
require("gsap-tween-max");

const katex = require( 'katex' );
require('katex-auto-render');

var Examination = {};

Examination.ResponsiveDesign = function() {
  var self = this;

  this.hrs = [600, 800, 1024, 1280, 1400, 1900];  // horizontal ranges

  this.horizontal_setting = function() {

    self.HR = 0;

    for (var i = 0; i < self.hrs.length; i++) {
      if (self.width > self.hrs[i])
          self.HR = i;
      }

    switch(self.HR)
        {
        case 0:
        break;

        case 1:
        break;

        case 2:

        break;

        case 3:
        break;

        case 4:
        break;

        case 5:
        break;
        }

  };

  this.vertical_setting = function() {
    console.log("VERTICAL");

  };

  this.init = function() {
    self.width = window.innerWidth;
    self.height = window.innerHeight;

    if (self.width > self.height) self.horizontal_setting();
    else                          self.vertical_setting();

    };

  self.init();
  };

Examination.Session = function(qa, opts, callback) {

    this.evaluation = qa.evaluation;
    this.sequence = qa.sequence;

    if ( opts === undefined ) {
        opts = {};
    }
    this.opts = opts;

    if ( !opts.math ) {
        this.mathOptions = [
            {left: "$$", right: "$$", display: true},
            {left: "\\[", right: "\\]", display: true},
            {left: "\\(", right: "\\)", display: false},
        ];
    } else {
        if ( !Array.isArray(opts.math) ) {
            throw new TypeError( `Math option has to be an array of delimiters. Value: ${opts.math} `);
        }
        opts.math.forEach( rule => {
            if ( !('left' in rule && 'right' in rule && 'display' in rule) ) {
                throw new TypeError( `Each delimiter has to have properties left, right and display. Value: ${rule} `);
            }
        });
        this.mathOptions = opts.math;
    }

	var self = this;
	var it   = 0;

	this.dynamic_change = function(node) {

		var name =  self.opts.div + "_node_item_" + node.id;

		/// Animation //
		var el = document.getElementById(name);
		var tl = new TimelineMax({  });
		tl.pause();

		tl.to(el, 0, {
					 left: '-100%',
					 opacity: 1,
					 }, "start" );

		if (node.id > 0) {

			var fname = self.opts.div + "_node_item_" + (node.id - 1);
			var former = document.getElementById(fname);

			tl.to(former, 1, {
				left: '100%',
			}, "go" );

		}

		tl.to(el, 1, {
					 left: '0',
					 opacity: 1,
					 }, "go" );

		tl.play();

	};

	this.top_down_change = function(node) {
		var name = self.opts.div + "_node_item_" + node.id;

		/// Animation //
		var el = document.getElementById(name);
		var tl = new TimelineMax({  });
		tl.pause();

		tl.to(el, 0, {
			 top: '-100%',
			 opacity: 0,
		}, "start" );

		if (node.id > 0) {

			var fname = self.opts.div + "_node_item_" + (node.id - 1);
			var former = document.getElementById(fname);

			tl.to(former, 1, {
						 top: '100%',
						 }, "go" );

		}

		tl.to(el, 1, {
					 top: '0',
					 opacity: 1,
					 }, "go" );

		tl.play();
	};

	this.bottom_up_change = function(node) {
		var name = self.opts.div + "_node_item_" + node.id;

		/// Animation //
		var el = document.getElementById(name);
		var tl = new TimelineMax({  });
		tl.pause();

		tl.to(el, 0, {
					 top: '100%',
					 opacity: 0,
					 }, "start" );

		if (node.id > 0) {

			var fname = self.opts.div + "_node_item_" + (node.id - 1);
			var former = document.getElementById(fname);

			tl.to(former, 1, {
						 top: '-100%',
						 }, "go" );

		}

		tl.to(el, 1, {
					 top: '0',
					 opacity: 1,
					 }, "go" );

		tl.play();
	};

	this.page_change = function(node) {

		if ( !node.transition_in ) {
			node.transition_in = "default";
		}

		switch(node.transition_in) {

			case "static":

			break;

			case "dynamic":
			  self.dynamic_change(node);
			break;

			case "top_down":
			  self.top_down_change(node);
			break;

			case "bottom_up":
			  self.bottom_up_change(node);
			break;

			default:

			break;
		}

	};

	this.input = function(node) {
	    var s = "";

	    var name = self.opts.div + "_node_item_" + node.id;

	    s += `<div id = "${name}" class = "node_area">`;
        s += `<div class = "mc_question">${md.render( node.question)}</div>`;

        var ip_name = self.opts.div + "_ip_input_" + node.id;

        s += '<input class = "ip_input" name="vorname" type="text" value="TYPE IN YOUR ANSWER - confirm with RETURN">';

        // TIMER
        var timer = "timer_" + node.id;

        if ( node.duration > 0 ) {
            s += `<div id = "${timer}" class = "timer"></div>`;
        }
        // END TIMER

        s += '
';

        $(self.div).append(s);
        renderMathInElement( document.body, self.mathOptions );

        if (node.duration > 0) {
            self.set_timer(node);
        }

        var ipdiv = "#" + name + " .ip_input";

        $(ipdiv).click(function() {
           $(this).val("");
        });

        $(ipdiv).change(function() {
            node.given_answer = $(this).val();

            if (node.duration > 0) {
                self.deactivate_timer(node);
            }

            self.decision(node);
        });

	};

	this.multiple_choice = function(node) {
		var s = "";

		var name = self.opts.div + "_node_item_" + node.id;
		var form = self.opts.div + "_node_form_" + node.id;

		s += '
';
		s += '
' + md.render( node.question)  + '
';

		s += '
';

		s += '<form id = "' + form + '" name = "' + form + '">';

		for (var i = 0; i < node.answers.length; i++) {

			s += '
';
			s += '<input class = "clicked_answer" type="radio" name="mpanswers" value="' + i + '">';
			s += '
' + node.answers[i].text + '
';
      s += '
';

		}

		s += '</form>';

		s += '
';

        // TIMER
        var timer = "timer_" + node.id;
        if ( node.duration > 0 ) {
            s += '

';
        }
        // END TIMER

		s += '
';

		$(self.div).append(s);
        renderMathInElement( document.body, self.mathOptions );

        if (node.duration > 0) {
            self.set_timer(node);
        }

		self.page_change(node);

		/////////////////////////////////////

		$("#" + self.opts.div + " .clicked_answer").click(function(){

			var actual_form = document.getElementById(form);
			node.chosen = parseInt( actual_form.mpanswers.value);
            console.log(node.chosen);

            self.deactivate_timer(node);

			it ++;

			var beta = self.sequence.nodes[it];

			if  (it < self.sequence.nodes.length) {
				self.play_node(beta);
			}
			else {
				self.result();
			}
		});

	};

	this.get_max_points = function() {

		var maximal = 0;

		for (var i = 0; i < self.sequence.nodes.length; i++) {

			var actual =  self.sequence.nodes[i];
			switch(actual.type) {

				case "multiple_choice":
				var tmax = 0;

				for (var j = 0; j < actual.answers.length; j++) {
					if ( actual.answers[j].points > tmax ) {
						tmax = actual.answers[j].points;
					}
				}

				maximal += tmax;

				break;

				case "input":
				 maximal += actual.points;
				break;

				}

		}

	return maximal;
	};

	this.result = function() {

		var res = { points: 0, text: "", right_answers: 0, questions: self.sequence.nodes.length};

		for (var i = 0; i < self.sequence.nodes.length; i++) {

		  var actual =  self.sequence.nodes[i];

		  switch(actual.type) {
		  		case "multiple_choice":
            if (actual.chosen === actual.right_value) res.right_answers += 1;

				  	var answer = actual.answers[actual.chosen];
				  	if (answer)  {
				   	res.points += parseInt( answer.points );
				  	if (answer.assessment !== "ASSESSMENT") {

            res.text += answer.assessment + " ";
            console.log(res.text);
					   }
					}
					else
					   {
					   res.points += 0;
					   }

			  	break;

			  	case "input":
			  	  // alert( actual.given_answer);
                    if ( actual.given_answer === actual.right_answer ) {
                        res.points += actual.points;
                        res.right_answers += 1;
                    }
			  	break;
		  	}
		  }

		res.max = self.get_max_points();

		res.percentage = res.points / res.max;

		var s =
            `

RESULT

You have answered ${res.right_answers} of ${res.questions} questions correctly

You have reached ${res.points} of ${res.max} points

Percentage: ${(res.percentage*100).toFixed(2)}%

Evaluation

${self.get_evaluation(res.percentage)}

Assessment

${res.text}

`;

		$(self.div).append(s);

	};

	this.get_evaluation = function(percentage) {

		for (var i = 0; i < self.evaluation.ranges.length; i++) {
			var r = self.evaluation.ranges[i];

		    if ( percentage > r.start && percentage <= r.end ) {
                return r.text;
            }

		}
		return "no evaluation";
	};

    this.deactivate_timer = function(node) {
        window.clearInterval(self.interval);
    };

    this.refresh_time = function() {

        var t = "#timer_" + self.timed_node.id;
        self.timed_node.actual_time -= 50;

        var sec  = parseInt( self.timed_node.actual_time / 1000);
        var msec = (self.timed_node.actual_time % 1000)/10;

        if (sec < 10) {
            sec = "0" + sec;
        }
        if (msec < 10) {
            msec = "0" + msec;
        }

        var s = sec + ":" + msec;

        // ENDE Bedingung = 0
        if (self.timed_node.actual_time <= 0 )
            {
            window.clearInterval(self.interval);
            self.decision(self.timed_node);

            }

        $(t).html(s);
    };

    self.decision = function(node) {

        node.chosen = -1;
        it ++;

        var beta = self.sequence.nodes[it];

        if  (it < self.sequence.nodes.length) {
            self.play_node(beta);
        } else {
            self.result();
        }

    };

    this.set_timer = function(node) {
        var t = "#timer_" + node.id;
        node.actual_time = node.duration * 1000;
        $(t).html("20:00");

        self.timed_node = node;
        self.interval = window.setInterval(self.refresh_time, 100);
    };

	this.play_node = function(node) {

		switch(node.type) {
			case "multiple_choice":
			    console.log("multiple_choice");
				self.multiple_choice(node);
			break;

			case "input":
			    // alert("Hier kommt ein Input");
			    self.input(node);
			break;
		}
	};

	this.play = function() {
		self.play_node ( self.sequence.nodes[it] );
	};

    this.injectCSS = function() {

        var cssPath;

        if ( self.opts.css === undefined || self.opts.css === '' ) {
            cssPath = './css/exam.css';
        }

        var cssExam = '<link href="' + cssPath + '" media="screen" rel="stylesheet" type="text/css" />';
        $('head').append(cssExam);

        var cssKatex = '<link href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min.css" media="screen" rel="stylesheet" type="text/css" />';
        $('head').append(cssKatex);

    };

	this.init = function() {

    self.responsive = new Examination.ResponsiveDesign();

		window._exam = this;

        $(document).ready(function(){

            // inject exam.css
            self.injectCSS();

            var s = '

';
            $("#" + self.opts.div).append(s);

            self.div =  "#" + self.opts.div + " .exam_panel";

            if (self.opts.exit === true) {
                var divExit = '
&#x274c
';
                var divPanel= "#" + self.opts.div + " .exam_panel";
                $(divPanel).append(divExit);
                $(divPanel + " #exit").click(function(){
                    $(divPanel).fadeOut(200, function(){
                        if (self.opts.div === "qapreview") {
                            $("#" + self.opts.div).html("");
                            $("#" + self.opts.div).hide();
                        } else {
                            $(divPanel).remove();
                        }
                    });
                });
            }

    		self.play();

        });

	};

	self.init();
};

module.exports = exports = Examination;
<commit_msg>input object is now animnated<commit_after>/* global renderMathInElement */
'use strict';

const $ = require( 'jquery' );
const MarkdownIt = require('markdown-it');
var md = new MarkdownIt();

/* global TimelineMax: true */
require("gsap-tween-max");

const katex = require( 'katex' );
require('katex-auto-render');

var Examination = {};

Examination.ResponsiveDesign = function() {
  var self = this;

  this.hrs = [600, 800, 1024, 1280, 1400, 1900];  // horizontal ranges

  this.horizontal_setting = function() {

    self.HR = 0;

    for (var i = 0; i < self.hrs.length; i++) {
      if (self.width > self.hrs[i])
          self.HR = i;
      }

    switch(self.HR)
        {
        case 0:
        break;

        case 1:
        break;

        case 2:

        break;

        case 3:
        break;

        case 4:
        break;

        case 5:
        break;
        }

  };

  this.vertical_setting = function() {
    console.log("VERTICAL");

  };

  this.init = function() {
    self.width = window.innerWidth;
    self.height = window.innerHeight;

    if (self.width > self.height) self.horizontal_setting();
    else                          self.vertical_setting();

    };

  self.init();
  };

Examination.Session = function(qa, opts, callback) {

    this.evaluation = qa.evaluation;
    this.sequence = qa.sequence;

    if ( opts === undefined ) {
        opts = {};
    }
    this.opts = opts;

    if ( !opts.math ) {
        this.mathOptions = [
            {left: "$$", right: "$$", display: true},
            {left: "\\[", right: "\\]", display: true},
            {left: "\\(", right: "\\)", display: false},
        ];
    } else {
        if ( !Array.isArray(opts.math) ) {
            throw new TypeError( `Math option has to be an array of delimiters. Value: ${opts.math} `);
        }
        opts.math.forEach( rule => {
            if ( !('left' in rule && 'right' in rule && 'display' in rule) ) {
                throw new TypeError( `Each delimiter has to have properties left, right and display. Value: ${rule} `);
            }
        });
        this.mathOptions = opts.math;
    }

	var self = this;
	var it   = 0;

	this.dynamic_change = function(node) {

		var name =  self.opts.div + "_node_item_" + node.id;

		/// Animation //
		var el = document.getElementById(name);
		var tl = new TimelineMax({  });
		tl.pause();

		tl.to(el, 0, {
					 left: '-100%',
					 opacity: 1,
					 }, "start" );

		if (node.id > 0) {

			var fname = self.opts.div + "_node_item_" + (node.id - 1);
			var former = document.getElementById(fname);

			tl.to(former, 1, {
				left: '100%',
			}, "go" );

		}

		tl.to(el, 1, {
					 left: '0',
					 opacity: 1,
					 }, "go" );

		tl.play();

	};

	this.top_down_change = function(node) {
		var name = self.opts.div + "_node_item_" + node.id;

		/// Animation //
		var el = document.getElementById(name);
		var tl = new TimelineMax({  });
		tl.pause();

		tl.to(el, 0, {
			 top: '-100%',
			 opacity: 0,
		}, "start" );

		if (node.id > 0) {

			var fname = self.opts.div + "_node_item_" + (node.id - 1);
			var former = document.getElementById(fname);

			tl.to(former, 1, {
						 top: '100%',
						 }, "go" );

		}

		tl.to(el, 1, {
					 top: '0',
					 opacity: 1,
					 }, "go" );

		tl.play();
	};

	this.bottom_up_change = function(node) {
		var name = self.opts.div + "_node_item_" + node.id;

		/// Animation //
		var el = document.getElementById(name);
		var tl = new TimelineMax({  });
		tl.pause();

		tl.to(el, 0, {
					 top: '100%',
					 opacity: 0,
					 }, "start" );

		if (node.id > 0) {

			var fname = self.opts.div + "_node_item_" + (node.id - 1);
			var former = document.getElementById(fname);

			tl.to(former, 1, {
						 top: '-100%',
						 }, "go" );

		}

		tl.to(el, 1, {
					 top: '0',
					 opacity: 1,
					 }, "go" );

		tl.play();
	};

	this.page_change = function(node) {

		if ( !node.transition_in ) {
			node.transition_in = "default";
		}

		switch(node.transition_in) {

			case "static":

			break;

			case "dynamic":
			  self.dynamic_change(node);
			break;

			case "top_down":
			  self.top_down_change(node);
			break;

			case "bottom_up":
			  self.bottom_up_change(node);
			break;

			default:

			break;
		}

	};

	this.input = function(node) {
	    var s = "";

	    var name = self.opts.div + "_node_item_" + node.id;

	    s += `<div id = "${name}" class = "node_area">`;
        s += `<div class = "mc_question">${md.render( node.question)}</div>`;

        var ip_name = self.opts.div + "_ip_input_" + node.id;

        s += '<input class = "ip_input" name="vorname" type="text" value="TYPE IN YOUR ANSWER - confirm with RETURN">';

        // TIMER
        var timer = "timer_" + node.id;

        if ( node.duration > 0 ) {
            s += `<div id = "${timer}" class = "timer"></div>`;
        }
        // END TIMER

        s += '
';

        $(self.div).append(s);
        renderMathInElement( document.body, self.mathOptions );

        if (node.duration > 0) {
            self.set_timer(node);
        }

        self.page_change(node);

        var ipdiv = "#" + name + " .ip_input";

        $(ipdiv).click(function() {
           $(this).val("");
        });

        $(ipdiv).change(function() {
            node.given_answer = $(this).val();

            if (node.duration > 0) {
                self.deactivate_timer(node);
            }

            self.decision(node);
        });

	};

	this.multiple_choice = function(node) {
		var s = "";

		var name = self.opts.div + "_node_item_" + node.id;
		var form = self.opts.div + "_node_form_" + node.id;

		s += '
';
		s += '
' + md.render( node.question)  + '
';

		s += '
';

		s += '<form id = "' + form + '" name = "' + form + '">';

		for (var i = 0; i < node.answers.length; i++) {

			s += '
';
			s += '<input class = "clicked_answer" type="radio" name="mpanswers" value="' + i + '">';
			s += '
' + node.answers[i].text + '
';
      s += '
';

		}

		s += '</form>';

		s += '
';

        // TIMER
        var timer = "timer_" + node.id;
        if ( node.duration > 0 ) {
            s += '

';
        }
        // END TIMER

		s += '
';

		$(self.div).append(s);
        renderMathInElement( document.body, self.mathOptions );

        if (node.duration > 0) {
            self.set_timer(node);
        }

		self.page_change(node);

		/////////////////////////////////////

		$("#" + self.opts.div + " .clicked_answer").click(function(){

			var actual_form = document.getElementById(form);
			node.chosen = parseInt( actual_form.mpanswers.value);
            console.log(node.chosen);

            self.deactivate_timer(node);

			it ++;

			var beta = self.sequence.nodes[it];

			if  (it < self.sequence.nodes.length) {
				self.play_node(beta);
			}
			else {
				self.result();
			}
		});

	};

	this.get_max_points = function() {

		var maximal = 0;

		for (var i = 0; i < self.sequence.nodes.length; i++) {

			var actual =  self.sequence.nodes[i];
			switch(actual.type) {

				case "multiple_choice":
				var tmax = 0;

				for (var j = 0; j < actual.answers.length; j++) {
					if ( actual.answers[j].points > tmax ) {
						tmax = actual.answers[j].points;
					}
				}

				maximal += tmax;

				break;

				case "input":
				 maximal += actual.points;
				break;

				}

		}

	return maximal;
	};

	this.result = function() {

		var res = { points: 0, text: "", right_answers: 0, questions: self.sequence.nodes.length};

		for (var i = 0; i < self.sequence.nodes.length; i++) {

		  var actual =  self.sequence.nodes[i];

		  switch(actual.type) {
		  		case "multiple_choice":
            if (actual.chosen === actual.right_value) res.right_answers += 1;

				  	var answer = actual.answers[actual.chosen];
				  	if (answer)  {
				   	res.points += parseInt( answer.points );
				  	if (answer.assessment !== "ASSESSMENT") {

            res.text += answer.assessment + " ";
            console.log(res.text);
					   }
					}
					else
					   {
					   res.points += 0;
					   }

			  	break;

			  	case "input":
			  	  // alert( actual.given_answer);
                    if ( actual.given_answer === actual.right_answer ) {
                        res.points += actual.points;
                        res.right_answers += 1;
                    }
			  	break;
		  	}
		  }

		res.max = self.get_max_points();

		res.percentage = res.points / res.max;

		var s =
            `

RESULT

You have answered ${res.right_answers} of ${res.questions} questions correctly

You have reached ${res.points} of ${res.max} points

Percentage: ${(res.percentage*100).toFixed(2)}%

Evaluation

${self.get_evaluation(res.percentage)}

Assessment

${res.text}

`;

		$(self.div).append(s);

	};

	this.get_evaluation = function(percentage) {

		for (var i = 0; i < self.evaluation.ranges.length; i++) {
			var r = self.evaluation.ranges[i];

		    if ( percentage > r.start && percentage <= r.end ) {
                return r.text;
            }

		}
		return "no evaluation";
	};

    this.deactivate_timer = function(node) {
        window.clearInterval(self.interval);
    };

    this.refresh_time = function() {

        var t = "#timer_" + self.timed_node.id;
        self.timed_node.actual_time -= 50;

        var sec  = parseInt( self.timed_node.actual_time / 1000);
        var msec = (self.timed_node.actual_time % 1000)/10;

        if (sec < 10) {
            sec = "0" + sec;
        }
        if (msec < 10) {
            msec = "0" + msec;
        }

        var s = sec + ":" + msec;

        // ENDE Bedingung = 0
        if (self.timed_node.actual_time <= 0 )
            {
            window.clearInterval(self.interval);
            self.decision(self.timed_node);

            }

        $(t).html(s);
    };

    self.decision = function(node) {

        node.chosen = -1;
        it ++;

        var beta = self.sequence.nodes[it];

        if  (it < self.sequence.nodes.length) {
            self.play_node(beta);
        } else {
            self.result();
        }

    };

    this.set_timer = function(node) {
        var t = "#timer_" + node.id;
        node.actual_time = node.duration * 1000;
        $(t).html("20:00");

        self.timed_node = node;
        self.interval = window.setInterval(self.refresh_time, 100);
    };

	this.play_node = function(node) {

		switch(node.type) {
			case "multiple_choice":
			    console.log("multiple_choice");
				self.multiple_choice(node);
			break;

			case "input":
			    // alert("Hier kommt ein Input");
			    self.input(node);
			break;
		}
	};

	this.play = function() {
		self.play_node ( self.sequence.nodes[it] );
	};

    this.injectCSS = function() {

        var cssPath;

        if ( self.opts.css === undefined || self.opts.css === '' ) {
            cssPath = './css/exam.css';
        }

        var cssExam = '<link href="' + cssPath + '" media="screen" rel="stylesheet" type="text/css" />';
        $('head').append(cssExam);

        var cssKatex = '<link href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min.css" media="screen" rel="stylesheet" type="text/css" />';
        $('head').append(cssKatex);

    };

	this.init = function() {

    self.responsive = new Examination.ResponsiveDesign();

		window._exam = this;

        $(document).ready(function(){

            // inject exam.css
            self.injectCSS();

            var s = '

';
            $("#" + self.opts.div).append(s);

            self.div =  "#" + self.opts.div + " .exam_panel";

            if (self.opts.exit === true) {
                var divExit = '
&#x274c
';
                var divPanel= "#" + self.opts.div + " .exam_panel";
                $(divPanel).append(divExit);
                $(divPanel + " #exit").click(function(){
                    $(divPanel).fadeOut(200, function(){
                        if (self.opts.div === "qapreview") {
                            $("#" + self.opts.div).html("");
                            $("#" + self.opts.div).hide();
                        } else {
                            $(divPanel).remove();
                        }
                    });
                });
            }

    		self.play();

        });

	};

	self.init();
};

module.exports = exports = Examination;
<|endoftext|>


<commit_before>//
// Eyes.js - a customizable value inspector for Node.js
//
//   usage:
//
//       var inspect = require('eyes').inspector({styles: {all: 'magenta'}});
//       inspect(something); // inspect with the settings passed to `inspector`
//
//     or
//
//       var eyes = require('eyes');
//       eyes.inspect(something); // inspect with the default settings
//
var eyes = {
    defaults: {
        styles: {                 // Styles applied to stdout
            all:     'cyan',      // Overall style applied to everything
            label:   'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`
            other:   'inverted',  // Objects which don't have a literal representation, such as functions
            key:     'bold',      // The keys in object literals, like 'a' in `{a: 1}`
            special: 'blue',      // null, undefined...
            string:  'green',
            number:  'magenta',
            bool:    'blue',      // true false
            regexp:  'green',     // /\d+/
            array:   'bold'       // [] (brackets part)
        },
        hideFunctions: false,
        writer: process.stdout,
        maxLength: 2048          // Truncate output if longer
    },

    // Return a curried inspect() function, with the `options` argument filled in.
    inspector: function (options) {
        var that = this;
        return function (obj, label, opts) {
            return that.inspect(obj, label,
                merge(options || {}, opts || {}));
        };
    },

    // If we have a `writer` defined, use it to print a styled string,
    // if not, we just return the stringified object with no styling.
    inspect: function (obj, label, options) {
        options = merge(this.defaults, options || {});
        if (options.writer) {
            return this.print(this.stringify(obj, options), label, options);
        } else {
            options.styles = {};
            return this.stringify(obj, options);
        }
    },

    // Output using the 'writer', and an optional label
    // Loop through `str`, and truncate it after `options.maxLength` has been reached.
    // Because escape sequences are, at this point embeded within
    // the output string, we can't measure the length of the string
    // in a useful way, without separating what is an escape sequence,
    // versus a printable character (`c`). So we resort to counting the
    // length manually.
    print: function (str, label, options) {
        for (var c = 0, i = 0; i < str.length; i++) {
            if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5
            else if (c === options.maxLength) {
               str = str.slice(0, i - 1) + '…';
               break;
            } else { c++ }
        }
        return options.writer.write.call(options.writer, (label ?
            this.stylize(label, options.styles.label, options.styles) + ': ' : '') +
            this.stylize(str,   options.styles.all, options.styles) + '\033[0m' + "\n");
    },

    // Convert any object to a string, ready for output.
    // When an 'array' or an 'object' are encountered, they are
    // passed to specialized functions, which can then recursively call
    // stringify().
    stringify: function (obj, options) {
        var that = this, stylize = function (str, style) {
            return that.stylize(str, options.styles[style], options.styles)
        };

        switch (typeOf(obj)) {
            case "string":
                obj = (obj.length === 1 ? "'" + obj + "'" : '"' + obj + '"')
                      .replace(/\n/g, '\\n');
                return stylize(obj, 'string');
            case "regexp"   : return stylize('/' + obj.source + '/', 'regexp');
            case "number"   : return stylize(obj + '',    'number');
            case "function" : return options.writer ? stylize("Function",  'other') : '[Function]';
            case "null"     : return stylize("null",      'special');
            case "undefined": return stylize("undefined", 'special');
            case "boolean"  : return stylize(obj + '',    'bool');
            case "date"     : return stylize(obj.toString());
            case "array"    : return this.stringifyArray(obj,  options);
            case "object"   : return this.stringifyObject(obj, options);
        }
    },

    // Convert an array to a string, such as [1, 2, 3].
    // This function calls stringify() for each of the elements
    // in the array.
    stringifyArray: function (ary, options) {
        var out = [];

        for (var i = 0; i < ary.length; i++) {
            out.push(this.stringify(ary[i], options));
        }
        return this.stylize('[', options.styles.array, options) +
               out.join(', ') +
               this.stylize(']', options.styles.array, options);
    },

    // Convert an object to a string, such as {a: 1}.
    // This function calls stringify() for each of its values,
    // and does not output functions or prototype values.
    stringifyObject: function (obj, options) {
        var out = [];

        for (var k in obj) {
            if (obj.hasOwnProperty(k) && !(obj[k] instanceof Function && options.hideFunctions)) {
                out.push(this.stylize(k, options.styles.key, options.styles) + ': ' +
                         this.stringify(obj[k], options));
            }
        }
        return "{" + out.join(', ') + "}";
    },

    // Apply a style to a string, eventually,
    // I'd like this to support passing multiple
    // styles.
    stylize: function (str, style, styles) {
        var codes = {
            'bold'      : [1,  22],
            'underline' : [4,  24],
            'inverse'   : [7,  27],
            'cyan'      : [36, 39],
            'magenta'   : [35, 39],
            'blue'      : [34, 39],
            'yellow'    : [33, 39],
            'green'     : [32, 39],
            'red'       : [31, 39]
        }, endCode;

        if (style && codes[style]) {
            endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0]
                                                             : codes[style][1];
            return '\033[' + codes[style][0] + 'm' + str +
                   '\033[' + endCode + 'm';
        } else { return str }
    }
};

// CommonJS module support
for (var e in eyes) exports[e] = eyes[e];

// A better `typeof`
function typeOf(value) {
    var s = typeof(value),
        types = [Object, Array, String, RegExp, Number, Function, Boolean, Date];

    if (s === 'object' || s === 'function') {
        if (value) {
            types.forEach(function (t) {
                if (value instanceof t) { s = t.name.toLowerCase() }
            });
        } else { s = 'null' }
    }
    return s;
}

function merge(/* variable args */) {
    var objs = Array.prototype.slice.call(arguments);
    var target = { styles: {} };

    objs.forEach(function (o) {
        for (var s in o.styles) { target.styles[s] = o.styles[s] || target.styles[s] }
        target.hideFunctions = o.hideFunctions || target.hideFunctions;
        target.writer = o.writer || target.writer;
        target.maxLength = o.maxLength || target.maxLength;
    });
    return target;
}

<commit_msg>better merge function<commit_after>//
// Eyes.js - a customizable value inspector for Node.js
//
//   usage:
//
//       var inspect = require('eyes').inspector({styles: {all: 'magenta'}});
//       inspect(something); // inspect with the settings passed to `inspector`
//
//     or
//
//       var eyes = require('eyes');
//       eyes.inspect(something); // inspect with the default settings
//
var eyes = {
    defaults: {
        styles: {                 // Styles applied to stdout
            all:     'cyan',      // Overall style applied to everything
            label:   'underline', // Inspection labels, like 'array' in `array: [1, 2, 3]`
            other:   'inverted',  // Objects which don't have a literal representation, such as functions
            key:     'bold',      // The keys in object literals, like 'a' in `{a: 1}`
            special: 'blue',      // null, undefined...
            string:  'green',
            number:  'magenta',
            bool:    'blue',      // true false
            regexp:  'green',     // /\d+/
            array:   'bold'       // [] (brackets part)
        },
        hideFunctions: false,
        writer: process.stdout,
        maxLength: 2048          // Truncate output if longer
    },

    // Return a curried inspect() function, with the `options` argument filled in.
    inspector: function (options) {
        var that = this;
        return function (obj, label, opts) {
            return that.inspect(obj, label,
                merge(options || {}, opts || {}));
        };
    },

    // If we have a `writer` defined, use it to print a styled string,
    // if not, we just return the stringified object with no styling.
    inspect: function (obj, label, options) {
        options = merge(this.defaults, options || {});
        if (options.writer) {
            return this.print(this.stringify(obj, options), label, options);
        } else {
            options.styles = {};
            return this.stringify(obj, options);
        }
    },

    // Output using the 'writer', and an optional label
    // Loop through `str`, and truncate it after `options.maxLength` has been reached.
    // Because escape sequences are, at this point embeded within
    // the output string, we can't measure the length of the string
    // in a useful way, without separating what is an escape sequence,
    // versus a printable character (`c`). So we resort to counting the
    // length manually.
    print: function (str, label, options) {
        for (var c = 0, i = 0; i < str.length; i++) {
            if (str.charAt(i) === '\033') { i += 4 } // `4` because '\033[25m'.length + 1 == 5
            else if (c === options.maxLength) {
               str = str.slice(0, i - 1) + '…';
               break;
            } else { c++ }
        }
        return options.writer.write.call(options.writer, (label ?
            this.stylize(label, options.styles.label, options.styles) + ': ' : '') +
            this.stylize(str,   options.styles.all, options.styles) + '\033[0m' + "\n");
    },

    // Convert any object to a string, ready for output.
    // When an 'array' or an 'object' are encountered, they are
    // passed to specialized functions, which can then recursively call
    // stringify().
    stringify: function (obj, options) {
        var that = this, stylize = function (str, style) {
            return that.stylize(str, options.styles[style], options.styles)
        };

        switch (typeOf(obj)) {
            case "string":
                obj = (obj.length === 1 ? "'" + obj + "'" : '"' + obj + '"')
                      .replace(/\n/g, '\\n');
                return stylize(obj, 'string');
            case "regexp"   : return stylize('/' + obj.source + '/', 'regexp');
            case "number"   : return stylize(obj + '',    'number');
            case "function" : return options.writer ? stylize("Function",  'other') : '[Function]';
            case "null"     : return stylize("null",      'special');
            case "undefined": return stylize("undefined", 'special');
            case "boolean"  : return stylize(obj + '',    'bool');
            case "date"     : return stylize(obj.toString());
            case "array"    : return this.stringifyArray(obj,  options);
            case "object"   : return this.stringifyObject(obj, options);
        }
    },

    // Convert an array to a string, such as [1, 2, 3].
    // This function calls stringify() for each of the elements
    // in the array.
    stringifyArray: function (ary, options) {
        var out = [];

        for (var i = 0; i < ary.length; i++) {
            out.push(this.stringify(ary[i], options));
        }
        return this.stylize('[', options.styles.array, options) +
               out.join(', ') +
               this.stylize(']', options.styles.array, options);
    },

    // Convert an object to a string, such as {a: 1}.
    // This function calls stringify() for each of its values,
    // and does not output functions or prototype values.
    stringifyObject: function (obj, options) {
        var out = [];

        for (var k in obj) {
            if (obj.hasOwnProperty(k) && !(obj[k] instanceof Function && options.hideFunctions)) {
                out.push(this.stylize(k, options.styles.key, options.styles) + ': ' +
                         this.stringify(obj[k], options));
            }
        }
        return "{" + out.join(', ') + "}";
    },

    // Apply a style to a string, eventually,
    // I'd like this to support passing multiple
    // styles.
    stylize: function (str, style, styles) {
        var codes = {
            'bold'      : [1,  22],
            'underline' : [4,  24],
            'inverse'   : [7,  27],
            'cyan'      : [36, 39],
            'magenta'   : [35, 39],
            'blue'      : [34, 39],
            'yellow'    : [33, 39],
            'green'     : [32, 39],
            'red'       : [31, 39]
        }, endCode;

        if (style && codes[style]) {
            endCode = (codes[style][1] === 39 && styles.all) ? codes[styles.all][0]
                                                             : codes[style][1];
            return '\033[' + codes[style][0] + 'm' + str +
                   '\033[' + endCode + 'm';
        } else { return str }
    }
};

// CommonJS module support
for (var e in eyes) exports[e] = eyes[e];

// A better `typeof`
function typeOf(value) {
    var s = typeof(value),
        types = [Object, Array, String, RegExp, Number, Function, Boolean, Date];

    if (s === 'object' || s === 'function') {
        if (value) {
            types.forEach(function (t) {
                if (value instanceof t) { s = t.name.toLowerCase() }
            });
        } else { s = 'null' }
    }
    return s;
}

function merge(/* variable args */) {
    var objs = Array.prototype.slice.call(arguments);
    var target = { styles: {} };

    objs.forEach(function (o) {
        Object.keys(o).forEach(function (k) {
            if (k === 'styles') {
                for (var s in o.styles) {
                    target.styles[s] = o.styles[s];
                }
            } else {
                target[k] = o[k];
            }
        });
    });
    return target;
}

<|endoftext|>


<commit_before>
var App = (function(){
	var state = {
		currentTableName: '',
		fields: [],
		records: [],
		selectedId: 0
	};

	var init = function() {
		$('select[name=table]').on('change', function() {
			getTable($(this).val());
		});
	}

	var getTable = function(table) {
		if (table != "") {
			$.ajax({
				url: '/admin/api/' + table + '/',
				dataType: 'json',
				success: function(json) {
					state.currentTableName = table;
					state.fields = json.fields;
					state.records = json.records;
					render();
				}
			});
		} else {
			state.currentTableName = '';
			state.fields = [];
			state.records = [];
			state.selectedId = 0;
			render();
		}
	}

	var getFormHtml = function(fieldname, fieldtype) {
		var html = '';
		switch (fieldtype) {
			case "INTEGER" :
				html += '<input type="number" name="' + fieldname + '" />';
				break;
			case "TEXT" :
				html += '<input type="text" name="' + fieldname + '" />';
				break;
			case "DEFAULT" :

		}
		return html;
	}

	var render = function() {
		// render #tablecontent
		$('.editBtn').off('click');
		$('.deleteBtn').off('click');

		if (state.selectedId == 0) {
			var html = '';
			html += '
';
			html += '
';
			html += '
';
			for (var field in state.fields) {
				html += '' + field + '	';
			}
			html += '			actions	';
			html += '
';
			html += '
';
			html += '
';
			for (var record in state.records) {
				html += '
';
				for (var field in state.fields) {
					html += '' + state.records[record][field] + '	';
				}
				html += '	<button class="btn editBtn">edit</button><button class="btn deleteBtn">delete</button>	';
				html += '
';
			}
			html += '
';
			html += '
';
			$('#tablecontent').html(html).show();

			$('.editBtn').on('click', function() {
				state.selectedId = $(this).closest('tr').data('id');
				render(['table']);
			});

			$('.deleteBtn').on('click', function() {

			});
		} else {
			$('#tablecontent').html('').hide();
		}

		// render #breadcrumb
		if (state.selectedId == 0) {
			$('#breadcrumb').html('').hide();
		} else {
			var html = '';
			html += '<button class="goToTableBtn">' + state.currentTableName + '</button>';
			html += ' / ' + state.selectedId;
			$('#breadcrumb').html(html).show();

			$('.goToTableBtn').on('click', function() {
				state.selectedId = 0;
				render();
			});
		}

		// render #detailform
		if (state.selectedId == 0) {
			$('#detailform').html('').hide();
		} else {
			var html = '';
			html += '<form action="#" method="post">';
			for (var field in state.fields) {
				html += '
';
				html += '
' + field + '
';
				html += '
' + getFormHtml(field, state.fields[field]) + '
';
				html += '
';
			}
			html += '</form>';
			$('#detailform').html(html).show();

			// populate fields
			var record = state.records[state.selectedId];
			for (var field in state.fields) {
				$('input[name=' + field + ']').val(record[field]);
			}

			$('.goToTableBtn').on('click', function() {
				state.selectedId = 0;
				render();
			});
		}

	}

	init();
})();<commit_msg>admin panel<commit_after>
var App = (function(){
	var state = {
		currentTableName: '',
		fields: [],
		records: [],
		selectedId: 0,
		pendingUpdates: 0
	};

	var init = function() {
		$('select[name=table]').on('change', function() {
			getTable($(this).val());
		});
	}

	var getTable = function(table) {
		if (table != "") {
			$.ajax({
				url: '/admin/api/' + table + '/',
				dataType: 'json',
				success: function(json) {
					state.currentTableName = table;
					state.fields = json.fields;
					state.records = json.records;
					render();
				}
			});
		} else {
			state.currentTableName = '';
			state.fields = [];
			state.records = [];
			state.selectedId = 0;
			render();
		}
	}

	var getFormHtml = function(fieldname, fieldtype) {
		var html = '';
		switch (fieldtype) {
			case "INTEGER" :
				html += '<input type="number" name="' + fieldname + '" />';
				break;
			case "TEXT" :
				html += '<input type="text" name="' + fieldname + '" />';
				break;
			case "DEFAULT" :

		}
		return html;
	}

	var render = function() {
		// render #tablecontent
		$('.editBtn').off('click');
		$('.deleteBtn').off('click');

		if (state.selectedId == 0) {
			var html = '';
			html += '
';
			html += '
';
			html += '
';
			for (var field in state.fields) {
				html += '' + field + '	';
			}
			html += '			actions	';
			html += '
';
			html += '
';
			html += '
';
			for (var record in state.records) {
				html += '
';
				for (var field in state.fields) {
					html += '' + state.records[record][field] + '	';
				}
				html += '	<button class="btn editBtn">edit</button><button class="btn deleteBtn">delete</button>	';
				html += '
';
			}
			html += '
';
			html += '
';
			$('#tablecontent').html(html).show();

			$('.editBtn').on('click', function() {
				state.selectedId = $(this).closest('tr').data('id');
				render(['table']);
			});

			$('.deleteBtn').on('click', function() {

			});
		} else {
			$('#tablecontent').html('').hide();
		}

		// render #breadcrumb
		$('.goToTableBtn').off('click');

		if (state.selectedId == 0) {
			$('#breadcrumb').html('').hide();
		} else {
			var html = '';
			html += '<button class="goToTableBtn">' + state.currentTableName + '</button>';
			html += ' / ' + state.selectedId;
			$('#breadcrumb').html(html).show();

			$('.goToTableBtn').on('click', function() {
				state.selectedId = 0;
				render();
			});
		}

		// render #detailform
		$('#detailform form').off('submit');

		if (state.selectedId == 0) {
			$('#detailform').html('').hide();
		} else {
			var html = '';
			html += '<form action="#" method="post">';
			for (var field in state.fields) {
				html += '
';
				html += '
' + field + '
';
				html += '
' + getFormHtml(field, state.fields[field]) + '
';
				html += '
';
			}
			html += '	<button>submit</button>';
			html += '</form>';
			$('#detailform').html(html).show();

			// populate fields
			var record = state.records[state.selectedId];
			for (var field in state.fields) {
				$('#detailform input[name=' + field + ']').val(record[field]);
			}

			$('#detailform form').on('submit', function(evt) {
				evt.preventDefault();
				var arr = $(this).serializeArray();
				var data = {};
				for (var i = 0; i < arr.length; i++) {
					data[arr[i].name] = arr[i].value;
				}

				state.pendingUpdates++;
				$.ajax({
					url: '/admin/api/' + table + '/',
					type: 'post',
					data: data,
					success: function() {
						state.pendingUpdates--;
						// real update
					}
				});

				// optimistic update
			});
		}

	}

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


<commit_before>var fs = require('fs')
  , path = require('path')
  , mkdirp = require('mkdirp')
  , os = require('os')
  , Handlebars = require('handlebars')
  , marked = require('marked')
  , hljs = require("highlight.js")
  , config = JSON.parse(fs.readFileSync('./_config.json', 'utf8'))
  , _ = require('lodash')
  , site = require('./site')

marked.setOptions({
  highlight: function(code, lang) {
    return lang
      ? hljs.highlight(lang, code).value
      : hljs.highlightAuto(code).value
  }
})

function transformContent(content, extension) {

}

function renderRecursive(filename, content) {
  var file = getFileData(filename)
    , layout = getFileData('./_layouts/' + file.data.layout + '.html')
    , data = { site: config, page: file.data }

  // add the content if passed from a recursive call
  if (content) data.content = content

  // render this files content before recursing
  data.content = Handlebars.compile(file.content)(data)

  if (layout.data) {
    // recurse
    return renderRecursive('./_layouts/' + file.data.layout + '.html', data.content)
  } else {
    // return
    return Handlebars.compile(layout.content)(data)
  }
}

function getFileData(filename) {
  var file = fs.readFileSync(filename, 'utf8')
  if (file.indexOf("<!--") !== 0) {
    return {
      data: null,
      content: file
    }
  }
  var data = ''
    , lines = file.split(os.EOL).slice(1)
    , line
  while ((line = lines.shift()) != null) {
    if (line != '-->') {
      data += line
    } else {
      return {
        data: JSON.parse(data),
        content: lines.join(os.EOL)
      }
    }
  }
}

function File(filename) {

  var fileData = getFileData(filename)

  this.data = fileData.data
  this.rawContent = fileData.content
  this.source = filename
  this.extension = path.extname(this.source)
  this.destination = path.join('./_site', this.source)

  // only transform files with JSON data
  // all other files are copied as-is
  if (this.data) {
    this.transform()
  } else {
    this.copy()
  }
}

File.prototype.copy = function() {
  mkdirp.sync(path.dirname(this.destination))
  fs.writeFileSync(this.destination, fs.readFileSync(this.source))
  console.log("Copying " + this.source + " to " + this.destination)
}

File.prototype.transform = function() {
  if (this.data.url) {
    this.destination = path.join('./_site', this.data.url)
  }

  var content = renderRecursive(this.source)

  mkdirp.sync(path.dirname(this.destination))
  fs.writeFileSync(this.destination, content)
  console.log("Transforming " + this.source + " to " + this.destination)
}

File.prototype.render = function(_layout) {
  var layout = getFileData('./_layouts/' + this.data.layout + '.html')
    , data = { site: config, page: this.data }

  data.content = this.content = Handlebars.compile(this.content || this.rawContent)(data)

  if (layout.data) {
    // recurse
    return renderFile('./_layouts/' + file.data.layout + '.html', data.content)
  } else {
    // return
    return Handlebars.compile(layout.content)(data)
  }
}

module.exports = File
<commit_msg>Update recursive rendering.<commit_after>var fs = require('fs')
  , path = require('path')
  , mkdirp = require('mkdirp')
  , os = require('os')
  , Handlebars = require('handlebars')
  , marked = require('marked')
  , hljs = require("highlight.js")
  , config = JSON.parse(fs.readFileSync('./_config.json', 'utf8'))
  , _ = require('lodash')
  , site = require('./site')

marked.setOptions({
  highlight: function(code, lang) {
    return lang
      ? hljs.highlight(lang, code).value
      : hljs.highlightAuto(code).value
  }
})

function transformContent(content, extension) {

}

function renderRecursive(filename, data) {
  var file = getFileData(filename)
    , layout = getFileData('./_layouts/' + file.data.layout + '.html')

  // render this files content before recursing
  data.content = Handlebars.compile(file.content)(data)

  if (layout.data) {
    // recurse
    return renderRecursive('./_layouts/' + file.data.layout + '.html', data)
  } else {
    // return
    return Handlebars.compile(layout.content)(data)
  }
}

function getFileData(filename) {
  var file = fs.readFileSync(filename, 'utf8')
  if (file.indexOf("<!--") !== 0) {
    return {
      data: null,
      content: file
    }
  }
  var data = ''
    , lines = file.split(os.EOL).slice(1)
    , line
  while ((line = lines.shift()) != null) {
    if (line != '-->') {
      data += line
    } else {
      return {
        data: JSON.parse(data),
        content: lines.join(os.EOL)
      }
    }
  }
}

function File(filename) {

  var fileData = getFileData(filename)

  this.data = fileData.data
  this.rawContent = fileData.content
  this.source = filename
  this.extension = path.extname(this.source)
  this.destination = path.join('./_site', this.source)

  // only transform files with JSON data
  // all other files are copied as-is
  if (this.data) {
    this.transform()
  } else {
    this.copy()
  }
}

File.prototype.copy = function() {
  mkdirp.sync(path.dirname(this.destination))
  fs.writeFileSync(this.destination, fs.readFileSync(this.source))
  console.log("Copying " + this.source + " to " + this.destination)
}

File.prototype.transform = function() {
  if (this.data.url) {
    this.destination = path.join('./_site', this.data.url)
  }

  var data = { site: config, page: this.data, content: this.rawContent }
  var content = renderRecursive(this.source, data)

  mkdirp.sync(path.dirname(this.destination))
  fs.writeFileSync(this.destination, content)
  console.log("Transforming " + this.source + " to " + this.destination)
}

module.exports = File
<|endoftext|>


<commit_before>/*global imagesLoaded, jQuery */

/******************************************
 * jQuery FitFrame
 *
 * A lightweight, easy-to-use jQuery plugin for responsive slide layout.
 *
 * Author          @jenkins118 (https://fabrik.io)
 * Copyright       Copyright (c) 2015 Phil Jenkins.
 * License         MIT
 * Version         0.0.0.1
 *
 ******************************************/

(function ($, window, undefined) {

  var PLUGIN_NAME = "fabrikStrip",
      INSTANCE_KEY = "plugin_" + PLUGIN_NAME;

  var originalWindowHeight, originalWindowWidth;

  function FabrikStrip(element, options, defaults) {
      this.element = $(element);
      this.options = $.extend({}, defaults, options);
      this._defaults = defaults;
      this._init();
  }

  FabrikStrip.prototype = {

      goTo: function (index) {
          // Go to specific blade

          var self = this,
              bladesCount = $(self.options.bladesSelector).length;

          if (index > bladesCount - 1) {
              return;
          }

          $('button', $(self.options.pagerSelector)).show();

          if (index <= 0) {
              self.goToFirst();
          }
          else if (index >= bladesCount - 1) {
              self.goToLast();
          }
          else {
              var beforeWidth = 0;

              $(self.options.bladesSelector).each(function () {
                  var $blade = $(this);

                  if ($blade.index() < index) {
                      beforeWidth += $blade.width();
                  }
              });

              var viewableWidth = $(self.element[0]).width(),
                  halfView = (viewableWidth - $(self.options.bladesSelector).eq(index).width()) / 2,
                  pull = beforeWidth - halfView;

              this._setActive(index);
              this._setPull(-pull);

              this.options.afterChange(index);
              return index;
          }
      },

      goToFirst: function () {
          // Go to first blade
          $('.left', $(this.options.pagerSelector)).hide();
          this._setActive(0);
          this._setPull(0);

          this.options.afterChange(0);
          return 0;
      },

      goToLast: function () {
          // Go to last blade
          $('.right', $(this.options.pagerSelector)).hide();
          var pull = $(this.options.innerStripSelector).width() - $(this.element[0]).width(),
              index = $(this.options.bladesSelector).length - 1;

          this._setActive(index);
          this._setPull(-pull);

          this.options.afterChange(index);
          return index;
      },

      _init: function () {
          $('html').addClass('fabrik-strip');
          this._bind();
          this._setSizes();
          this._setActive(this.options.startIndex);
      },

      _windowResize: function () {

          var self = this;
          var h = $(window).height();
          var w = $(window).width();

          var heightChangeFactor = (h - originalWindowHeight) / originalWindowHeight;
          var widthChangeFactor = (w - originalWindowWidth) / originalWindowWidth;

          var containerHeight = $(self.element[0]).data('height');
          var newHeight = containerHeight + (containerHeight * heightChangeFactor);

          $(self.element[0]).css({ 'height': newHeight, 'max-height': newHeight });
          $(self.options.bladesSelector).removeAttr('style');
          $(self.options.innerStripSelector).width('999em');

          var totalWidth = 0;

          $(self.options.bladesSelector).each(function () {

              var $blade = $(this),
                  bladeDataWidth = $blade.data('width'),
                  bladeWidth = bladeDataWidth + (bladeDataWidth * widthChangeFactor);

              // limit blade width
              $blade.width(bladeWidth);

              // limit total width
              totalWidth += bladeWidth;
          });

          $(self.options.innerStripSelector).width(totalWidth);
      },

      _setSizes: function () {

          var self = this,
              windowHeight = $(window).height(),
              windowWidth = $(window).width();

          originalWindowHeight = windowHeight;
          originalWindowWidth = windowWidth;

          if ($(self.options.headerSelector).length) {
              windowHeight -= $(self.options.headerSelector).height();
          }

          $(self.element[0]).data('height', windowHeight).css({ 'height': windowHeight, 'max-height': windowHeight });
          $(self.options.bladesSelector).removeAttr('style');
          $(self.options.innerStripSelector).width('999em');

          // after images are loaded get the widths of the blades so we can set parent container

          var container = self.element[0];

          //var images = container.getElementsByTagName("img");
          //var videos = container.getElementsByTagName("video");

          //var howManyToLoad = images.length + videos.length;

          var imagesAreLoaded = function () {

              var width = 0;

              $(self.options.bladesSelector).each(function () {

                  var $blade = $(this),
                      bladewidth = $(this).width(),
                      $img = $('img', $blade),
                      $video = $('video', $blade);

                  if ($img.length) {
                      bladewidth = $img.width();
                      $blade.data('width', bladewidth).data('height', $img.height());
                  }

                  if ($video.length) {
                      bladewidth = $video.width();
                      $blade.data('width', bladewidth).data('height', $video.height());
                  }

                  // limit blade width
                  $blade.width(bladewidth);

                  // limit total width
                  width += bladewidth;
              });

              $(self.options.innerStripSelector).width(width).addClass('blades-loaded');

          };

          //container.addEventListener('load', update, true);
          container.addEventListener('loadeddata', imagesAreLoaded, true);

          // if (imagesLoaded !== undefined) {
          //   imagesLoaded(self.element[0], function () {
          //     var width = 0;

          //     $(self.options.bladesSelector).each(function () {

          //       var $blade = $(this),
          //           bladewidth = $(this).width(),
          //           $img = $('img', $blade);

          //       if ($img.length) {
          //         bladewidth = $img.width();
          //       }

          //       $blade.width(bladewidth);
          //       width += bladewidth;
          //     });

          //     $(self.options.innerStripSelector).width(width).addClass('blades-loaded');
          //   });
          // }
          // else {
          //   console.info("You need to add images Loaded plugin http://imagesloaded.desandro.com/");
          // }

          var pagerWidth = $('.left').outerWidth(true),
              infoWidth = windowWidth - pagerWidth;

          if (windowWidth >= 1200) {
              infoWidth = $(self.element[0]).width() / 2;
          }

          $('.project-info-blade').width(infoWidth);

      },

      _setPull: function (int) {
          $(this.options.innerStripSelector).css({
              "-webkit-transform": "translate3d(" + int + "px, 0px, 0px)",
              "-moz-transform": "translate3d(" + int + "px, 0px, 0px)",
              "-ms-transform": "translate3d(" + int + "px, 0px, 0px)",
              "-o-transform": "translate3d(" + int + "px, 0px, 0px)",
              "transform": "translate3d(" + int + "px, 0px, 0px)"
          });
      },

      _setActive: function (index) {
          $(this.options.bladesSelector).removeClass('active');
          // Get the new active blade
          var $blade = $(this.options.bladesSelector).eq(index);
          $blade.addClass('active');

          $(this.element[0]).data('activeIndex', index);
      },

      _goToOnResize: function (index) {
          var self = this;

          setTimeout(function () {
              self.goTo(index);
          }, 200);
      },

      _bind: function () {
          // debounced resizing
          var self = this, t;

          $('button', $(self.options.pagerSelector)).on('click', function (e) {
              e.preventDefault();

              var activeIndex = $(self.element[0]).data('activeIndex'),
                  index = activeIndex + 1;

              if ($(this).hasClass('left')) {
                  index = activeIndex - 1;
              }

              self.options.beforeChange(activeIndex);

              self.goTo(index);
          });

          $(self.options.bladesSelector).on('click', function (e) {

              if (!$(this).hasClass('active')) {
                  e.preventDefault();
                  var activeIndex = $(self.element[0]).data('activeIndex');
                  self.options.beforeChange(activeIndex);
                  self.goTo($(this).index());
              }
          });

          $(window).on('resize.' + PLUGIN_NAME, function () {
              clearTimeout(t);
              t = setTimeout(function () {
                  // On resize set the sizes
                  self._windowResize();
                  self._goToOnResize($(self.element[0]).data('activeIndex'));
              }, 200);
          });

          $(document.documentElement).keyup(function (event) {
              var activeIndex = 0,
                  index = 0;

              // handle cursor keys
              if (event.keyCode == 37) {
                  // go left
                  activeIndex = $(self.element[0]).data('activeIndex');
                  index = activeIndex - 1;

                  self.options.beforeChange(activeIndex);
                  self.goTo(index);
              } else if (event.keyCode == 39) {
                  // go right
                  activeIndex = $(self.element[0]).data('activeIndex');
                  index = activeIndex + 1;

                  self.options.beforeChange(activeIndex);
                  self.goTo(index);
              }
          });

      }

  };

  $.fn[PLUGIN_NAME] = function (options) {

      var args = arguments,
          returns;

      this.each(function () {

          var instance = $.data(this, INSTANCE_KEY);

          if (instance) {
              // check if invoking public methods
              if (typeof (options) === 'string' && options[0] !== '_') {
                  var method = instance[options];
                  if (typeof (method) === 'function') {
                      returns = method.apply(instance, Array.prototype.slice.call(args, 1));
                  } else {
                      // method missing
                      $.error('Public method \'' + options + '\' does not exist on jQuery.' + PLUGIN_NAME);
                  }
              }

          } else {
              $.data(this, INSTANCE_KEY, new FabrikStrip(this, options, $.fn[PLUGIN_NAME].defaults));
          }
      });

      // if the earlier cached method has a value return it, otherwise return this to preserve chainability
      return returns !== undefined ? returns : this;
  };

  $.fn[PLUGIN_NAME].defaults = {
      bladesSelector: '.blade',
      innerStripSelector: '.strip',
      headerSelector: null,
      pagerSelector: '.strip-pagers',
      startIndex: 0,
      afterChange: function () { },
      beforeChange: function () { },
  };

})(jQuery, window);<commit_msg>load call<commit_after>/*global imagesLoaded, jQuery */

/******************************************
 * jQuery FabrikStrip
 *
 * A lightweight, easy-to-use jQuery plugin for responsive slide layout.
 *
 * Author          @jenkins118 (https://fabrik.io)
 * Copyright       Copyright (c) 2015 Phil Jenkins.
 * License         MIT
 * Version         0.0.0.1
 *
 ******************************************/

(function ($, window, undefined) {

  var PLUGIN_NAME = "fabrikStrip",
      INSTANCE_KEY = "plugin_" + PLUGIN_NAME;

  var originalWindowHeight, originalWindowWidth;

  function FabrikStrip(element, options, defaults) {
      this.element = $(element);
      this.options = $.extend({}, defaults, options);
      this._defaults = defaults;
      this._init();
  }

  FabrikStrip.prototype = {

      goTo: function (index) {
          // Go to specific blade

          var self = this,
              bladesCount = $(self.options.bladesSelector).length;

          if (index > bladesCount - 1) {
              return;
          }

          $('button', $(self.options.pagerSelector)).show();

          if (index <= 0) {
              self.goToFirst();
          }
          else if (index >= bladesCount - 1) {
              self.goToLast();
          }
          else {
              var beforeWidth = 0;

              $(self.options.bladesSelector).each(function () {
                  var $blade = $(this);

                  if ($blade.index() < index) {
                      beforeWidth += $blade.width();
                  }
              });

              var viewableWidth = $(self.element[0]).width(),
                  halfView = (viewableWidth - $(self.options.bladesSelector).eq(index).width()) / 2,
                  pull = beforeWidth - halfView;

              this._setActive(index);
              this._setPull(-pull);

              this.options.afterChange(index);
              return index;
          }
      },

      goToFirst: function () {
          // Go to first blade
          $('.left', $(this.options.pagerSelector)).hide();
          this._setActive(0);
          this._setPull(0);

          this.options.afterChange(0);
          return 0;
      },

      goToLast: function () {
          // Go to last blade
          $('.right', $(this.options.pagerSelector)).hide();
          var pull = $(this.options.innerStripSelector).width() - $(this.element[0]).width(),
              index = $(this.options.bladesSelector).length - 1;

          this._setActive(index);
          this._setPull(-pull);

          this.options.afterChange(index);
          return index;
      },

      _init: function () {
          $('html').addClass('fabrik-strip');
          this._bind();
          this._setSizes();
          this._setActive(this.options.startIndex);
      },

      _windowResize: function () {

          var self = this;
          var h = $(window).height();
          var w = $(window).width();

          var heightChangeFactor = (h - originalWindowHeight) / originalWindowHeight;
          var widthChangeFactor = (w - originalWindowWidth) / originalWindowWidth;

          var containerHeight = $(self.element[0]).data('height');
          var newHeight = containerHeight + (containerHeight * heightChangeFactor);

          $(self.element[0]).css({ 'height': newHeight, 'max-height': newHeight });
          $(self.options.bladesSelector).removeAttr('style');
          $(self.options.innerStripSelector).width('999em');

          var totalWidth = 0;

          $(self.options.bladesSelector).each(function () {

              var $blade = $(this),
                  bladeDataWidth = $blade.data('width'),
                  bladeWidth = bladeDataWidth + (bladeDataWidth * widthChangeFactor);

              // limit blade width
              $blade.width(bladeWidth);

              // limit total width
              totalWidth += bladeWidth;
          });

          $(self.options.innerStripSelector).width(totalWidth);
      },

      _setSizes: function () {

          var self = this,
              windowHeight = $(window).height(),
              windowWidth = $(window).width();

          originalWindowHeight = windowHeight;
          originalWindowWidth = windowWidth;

          if ($(self.options.headerSelector).length) {
              windowHeight -= $(self.options.headerSelector).height();
          }

          $(self.element[0]).data('height', windowHeight).css({ 'height': windowHeight, 'max-height': windowHeight });
          $(self.options.bladesSelector).removeAttr('style');
          $(self.options.innerStripSelector).width('999em');

          // after images are loaded get the widths of the blades so we can set parent container

          var container = self.element[0];

          //var images = container.getElementsByTagName("img");
          //var videos = container.getElementsByTagName("video");

          //var howManyToLoad = images.length + videos.length;

          var imagesAreLoaded = function () {

              var width = 0;

              $(self.options.bladesSelector).each(function () {

                  var $blade = $(this),
                      bladewidth = $(this).width(),
                      $img = $('img', $blade),
                      $video = $('video', $blade);

                  if ($img.length) {
                      bladewidth = $img.width();
                      $blade.data('width', bladewidth).data('height', $img.height());
                  }

                  if ($video.length) {
                      bladewidth = $video.width();
                      $blade.data('width', bladewidth).data('height', $video.height());
                  }

                  // limit blade width
                  $blade.width(bladewidth);

                  // limit total width
                  width += bladewidth;
              });

              $(self.options.innerStripSelector).width(width).addClass('blades-loaded');

          };

          container.addEventListener('load', imagesAreLoaded, true);
          container.addEventListener('loadeddata', imagesAreLoaded, true);

          // if (imagesLoaded !== undefined) {
          //   imagesLoaded(self.element[0], function () {
          //     var width = 0;

          //     $(self.options.bladesSelector).each(function () {

          //       var $blade = $(this),
          //           bladewidth = $(this).width(),
          //           $img = $('img', $blade);

          //       if ($img.length) {
          //         bladewidth = $img.width();
          //       }

          //       $blade.width(bladewidth);
          //       width += bladewidth;
          //     });

          //     $(self.options.innerStripSelector).width(width).addClass('blades-loaded');
          //   });
          // }
          // else {
          //   console.info("You need to add images Loaded plugin http://imagesloaded.desandro.com/");
          // }

          var pagerWidth = $('.left').outerWidth(true),
              infoWidth = windowWidth - pagerWidth;

          if (windowWidth >= 1200) {
              infoWidth = $(self.element[0]).width() / 2;
          }

          $('.project-info-blade').width(infoWidth);

      },

      _setPull: function (int) {
          $(this.options.innerStripSelector).css({
              "-webkit-transform": "translate3d(" + int + "px, 0px, 0px)",
              "-moz-transform": "translate3d(" + int + "px, 0px, 0px)",
              "-ms-transform": "translate3d(" + int + "px, 0px, 0px)",
              "-o-transform": "translate3d(" + int + "px, 0px, 0px)",
              "transform": "translate3d(" + int + "px, 0px, 0px)"
          });
      },

      _setActive: function (index) {
          $(this.options.bladesSelector).removeClass('active');
          // Get the new active blade
          var $blade = $(this.options.bladesSelector).eq(index);
          $blade.addClass('active');

          $(this.element[0]).data('activeIndex', index);
      },

      _goToOnResize: function (index) {
          var self = this;

          setTimeout(function () {
              self.goTo(index);
          }, 200);
      },

      _bind: function () {
          // debounced resizing
          var self = this, t;

          $('button', $(self.options.pagerSelector)).on('click', function (e) {
              e.preventDefault();

              var activeIndex = $(self.element[0]).data('activeIndex'),
                  index = activeIndex + 1;

              if ($(this).hasClass('left')) {
                  index = activeIndex - 1;
              }

              self.options.beforeChange(activeIndex);

              self.goTo(index);
          });

          $(self.options.bladesSelector).on('click', function (e) {

              if (!$(this).hasClass('active')) {
                  e.preventDefault();
                  var activeIndex = $(self.element[0]).data('activeIndex');
                  self.options.beforeChange(activeIndex);
                  self.goTo($(this).index());
              }
          });

          $(window).on('resize.' + PLUGIN_NAME, function () {
              clearTimeout(t);
              t = setTimeout(function () {
                  // On resize set the sizes
                  self._windowResize();
                  self._goToOnResize($(self.element[0]).data('activeIndex'));
              }, 200);
          });

          $(document.documentElement).keyup(function (event) {
              var activeIndex = 0,
                  index = 0;

              // handle cursor keys
              if (event.keyCode == 37) {
                  // go left
                  activeIndex = $(self.element[0]).data('activeIndex');
                  index = activeIndex - 1;

                  self.options.beforeChange(activeIndex);
                  self.goTo(index);
              } else if (event.keyCode == 39) {
                  // go right
                  activeIndex = $(self.element[0]).data('activeIndex');
                  index = activeIndex + 1;

                  self.options.beforeChange(activeIndex);
                  self.goTo(index);
              }
          });

      }

  };

  $.fn[PLUGIN_NAME] = function (options) {

      var args = arguments,
          returns;

      this.each(function () {

          var instance = $.data(this, INSTANCE_KEY);

          if (instance) {
              // check if invoking public methods
              if (typeof (options) === 'string' && options[0] !== '_') {
                  var method = instance[options];
                  if (typeof (method) === 'function') {
                      returns = method.apply(instance, Array.prototype.slice.call(args, 1));
                  } else {
                      // method missing
                      $.error('Public method \'' + options + '\' does not exist on jQuery.' + PLUGIN_NAME);
                  }
              }

          } else {
              $.data(this, INSTANCE_KEY, new FabrikStrip(this, options, $.fn[PLUGIN_NAME].defaults));
          }
      });

      // if the earlier cached method has a value return it, otherwise return this to preserve chainability
      return returns !== undefined ? returns : this;
  };

  $.fn[PLUGIN_NAME].defaults = {
      bladesSelector: '.blade',
      innerStripSelector: '.strip',
      headerSelector: null,
      pagerSelector: '.strip-pagers',
      startIndex: 0,
      afterChange: function () { },
      beforeChange: function () { },
  };

})(jQuery, window);<|endoftext|>