<commit_before>// classList polyfill for old browsers
require('classlist-polyfill')
// Object.assign polyfill
require('es6-object-assign').polyfill()

// String to DOM function
var domify = require('domify')

// Detect CSS Animation End Support
// https://github.com/limonte/sweetalert2/blob/99bd539f85e15ac170f69d35001d12e092ef0054/src/utils/dom.js#L194
var animationEndEvent = (function () {
  var el = document.createElement('div')
  var eventNames = {
    'WebkitAnimation': 'webkitAnimationEnd',
    'MozAnimation': 'animationend',
    'OAnimation': 'oanimationend',
    'msAnimation': 'MSAnimationEnd',
    'animation': 'animationend'
  }
  for (var i in eventNames) {
    if (el.style[i] !== undefined) {
      return eventNames[i]
    }
  }
  return false
})()

// vex base CSS classes
var baseClassNames = {
  vex: 'vex',
  content: 'vex-content',
  overlay: 'vex-overlay',
  close: 'vex-close',
  closing: 'vex-closing',
  open: 'vex-open'
}

// Private lookup table of all open vex objects, keyed by id
var vexes = {}
var globalId = 1

// vex itself is an object that exposes a simple API to open and close vex objects in various ways
var vex = {
  open: function (opts) {
    // The dialog instance
    var vexInstance = {}

    // Set id
    vexInstance.id = globalId++

    // Store internally
    vexes[vexInstance.id] = vexInstance

    // Set state
    vexInstance.isOpen = true

    // Close function on the vex instance
    // This is how all API functions should close individual vexes
    vexInstance.close = function () {
      // Check state
      if (!this.isOpen) {
        return true
      }

      var options = this.options

      var beforeClose = function () {
        // Call before close callback
        if (options.beforeClose) {
          return options.beforeClose.call(this)
        }
        // Otherwise indicate that it's ok to continue with close
        return true
      }.bind(this)

      var close = function () {
        if (!this.rootEl.parentNode) {
          return
        }
        // Run once
        this.rootEl.removeEventListener(animationEndEvent, close)
        // Remove from lookup table (prevent memory leaks)
        delete vexes[this.id]
        // Remove the dialog from the DOM
        this.rootEl.parentNode.removeChild(this.rootEl)
        // Call after close callback
        if (options.afterClose) {
          options.afterClose.call(this)
        }
        // Remove styling from the body, if no more vexes are open
        if (Object.keys(vexes).length === 0) {
          document.body.classList.remove(baseClassNames.open)
        }
      }.bind(this)

      // If any user-defined validation or anything fails, abort the close
      if (beforeClose() === false) {
        return false
      }

      // Update state
      this.isOpen = false

      // Detect if the content el has any CSS animations defined
      var style = window.getComputedStyle(this.contentEl)
      function hasAnimationPre (prefix) {
        return style.getPropertyValue(prefix + 'animation-name') !== 'none' && style.getPropertyValue(prefix + 'animation-duration') !== '0s'
      }
      var hasAnimation = hasAnimationPre('') || hasAnimationPre('-webkit-') || hasAnimationPre('-moz-') || hasAnimationPre('-o-')

      // Close the vex
      if (animationEndEvent && hasAnimation) {
        // Setup the end event listener, to remove the el from the DOM
        this.rootEl.addEventListener(animationEndEvent, close)
        // Add the closing class to the dialog, showing the close animation
        this.rootEl.classList.add(baseClassNames.closing)
      } else {
        close()
      }

      return true
    }

    // Allow strings as content
    if (typeof opts === 'string') {
      opts = {
        content: opts
      }
    }
    // Store options on instance for future reference
    var options = vexInstance.options = Object.assign({}, vex.defaultOptions, opts)

    // vex root
    var rootEl = vexInstance.rootEl = document.createElement('div')
    rootEl.classList.add(baseClassNames.vex)
    if (options.className) {
      rootEl.classList.add(options.className)
    }

    // Overlay
    var overlayEl = vexInstance.overlayEl = document.createElement('div')
    overlayEl.classList.add(baseClassNames.overlay)
    if (options.overlayClassName) {
      overlayEl.classList.add(options.overlayClassName)
    }
    if (options.overlayClosesOnClick) {
      overlayEl.addEventListener('click', function (e) {
        if (e.target === overlayEl) {
          vexInstance.close()
        }
      })
    }
    rootEl.appendChild(overlayEl)

    // Content
    var contentEl = vexInstance.contentEl = document.createElement('div')
    contentEl.classList.add(baseClassNames.content)
    if (options.contentClassName) {
      contentEl.classList.add(options.contentClassName)
    }
    contentEl.appendChild(options.content instanceof window.Node ? options.content : domify(options.content))
    rootEl.appendChild(contentEl)

    // Close button
    if (options.showCloseButton) {
      var closeEl = vexInstance.closeEl = document.createElement('div')
      closeEl.classList.add(baseClassNames.close)
      if (options.closeClassName) {
        closeEl.classList.add(options.closeClassName)
      }
      closeEl.addEventListener('click', vexInstance.close.bind(vexInstance))
      contentEl.appendChild(closeEl)
    }

    // Add to DOM
    document.querySelector(options.appendLocation).appendChild(rootEl)

    // Call after open callback
    if (options.afterOpen) {
      options.afterOpen.call(vexInstance)
    }

    // Apply styling to the body
    document.body.classList.add(baseClassNames.open)

    // Return the created vex instance
    return vexInstance
  },

  // A top-level vex.close function to close dialogs by reference or id
  close: function (vexOrId) {
    var id
    if (vexOrId.id) {
      id = vexOrId.id
    } else if (typeof vexOrId === 'string') {
      id = vexOrId
    } else {
      throw new TypeError('close requires a vex object or id string')
    }
    if (!vexes[id]) {
      return false
    }
    return vexes[id].close()
  },

  // Close the most recently created/opened vex
  closeTop: function () {
    var ids = Object.keys(vexes)
    if (!ids.length) {
      return false
    }
    return vexes[ids[ids.length - 1]].close()
  },

  // Close every vex!
  closeAll: function () {
    for (var id in vexes) {
      this.close(id)
    }
    return true
  },

  // A getter for the internal lookup table
  getAll: function () {
    return vexes
  },

  // A getter for the internal lookup table
  getById: function (id) {
    return vexes[id]
  }
}

// Close top vex on escape
window.addEventListener('keyup', function (e) {
  if (e.keyCode === 27) {
    vex.closeTop()
  }
})
// Close all vexes on history pop state (useful in single page apps)
window.addEventListener('popstate', vex.closeAll)

vex.defaultOptions = {
  content: '',
  showCloseButton: true,
  escapeButtonCloses: true,
  overlayClosesOnClick: true,
  appendLocation: 'body',
  className: '',
  overlayClassName: '',
  contentClassName: '',
  closeClassName: ''
}

// TODO Loading symbols?

// Plugin system!
vex.registerPlugin = function (pluginFn, name) {
  var plugin = pluginFn(vex)
  var pluginName = name || plugin.name
  if (vex[pluginName]) {
    throw new Error('Plugin ' + name + ' is already registered.')
  }
  vex[pluginName] = plugin
}

module.exports = vex
<commit_msg>No more anonymous functions and better close function organization<commit_after>// classList polyfill for old browsers
require('classlist-polyfill')
// Object.assign polyfill
require('es6-object-assign').polyfill()

// String to DOM function
var domify = require('domify')

// Detect CSS Animation End Support
// https://github.com/limonte/sweetalert2/blob/99bd539f85e15ac170f69d35001d12e092ef0054/src/utils/dom.js#L194
var animationEndEvent = (function detectAnimationEndEvent () {
  var el = document.createElement('div')
  var eventNames = {
    'WebkitAnimation': 'webkitAnimationEnd',
    'MozAnimation': 'animationend',
    'OAnimation': 'oanimationend',
    'msAnimation': 'MSAnimationEnd',
    'animation': 'animationend'
  }
  for (var i in eventNames) {
    if (el.style[i] !== undefined) {
      return eventNames[i]
    }
  }
  return false
})()

// vex base CSS classes
var baseClassNames = {
  vex: 'vex',
  content: 'vex-content',
  overlay: 'vex-overlay',
  close: 'vex-close',
  closing: 'vex-closing',
  open: 'vex-open'
}

// Private lookup table of all open vex objects, keyed by id
var vexes = {}
var globalId = 1

// vex itself is an object that exposes a simple API to open and close vex objects in various ways
var vex = {
  open: function open (opts) {
    // The dialog instance
    var vexInstance = {}

    // Set id
    vexInstance.id = globalId++

    // Store internally
    vexes[vexInstance.id] = vexInstance

    // Set state
    vexInstance.isOpen = true

    // Close function on the vex instance
    // This is how all API functions should close individual vexes
    vexInstance.close = function instanceClose () {
      // Check state
      if (!this.isOpen) {
        return true
      }

      var options = this.options

      // Allow the user to validate any info or abort the close with the beforeClose callback
      var shouldClose = (function shouldClose () {
        // Call before close callback
        if (options.beforeClose) {
          return options.beforeClose.call(this)
        }
        // Otherwise indicate that it's ok to continue with close
        return true
      }.bind(this)())

      // If beforeClose() fails, abort the close
      if (shouldClose === false) {
        return false
      }

      // Update state
      this.isOpen = false

      // Detect if the content el has any CSS animations defined
      var style = window.getComputedStyle(this.contentEl)
      function hasAnimationPre (prefix) {
        return style.getPropertyValue(prefix + 'animation-name') !== 'none' && style.getPropertyValue(prefix + 'animation-duration') !== '0s'
      }
      var hasAnimation = hasAnimationPre('') || hasAnimationPre('-webkit-') || hasAnimationPre('-moz-') || hasAnimationPre('-o-')

      // Define the function that will actually close the instance
      var close = function close () {
        if (!this.rootEl.parentNode) {
          return
        }
        // Run once
        this.rootEl.removeEventListener(animationEndEvent, close)
        // Remove from lookup table (prevent memory leaks)
        delete vexes[this.id]
        // Remove the dialog from the DOM
        this.rootEl.parentNode.removeChild(this.rootEl)
        // Call after close callback
        if (options.afterClose) {
          options.afterClose.call(this)
        }
        // Remove styling from the body, if no more vexes are open
        if (Object.keys(vexes).length === 0) {
          document.body.classList.remove(baseClassNames.open)
        }
      }.bind(this)

      // Close the vex
      if (animationEndEvent && hasAnimation) {
        // Setup the end event listener, to remove the el from the DOM
        this.rootEl.addEventListener(animationEndEvent, close)
        // Add the closing class to the dialog, showing the close animation
        this.rootEl.classList.add(baseClassNames.closing)
      } else {
        close()
      }

      return true
    }

    // Allow strings as content
    if (typeof opts === 'string') {
      opts = {
        content: opts
      }
    }
    // Store options on instance for future reference
    var options = vexInstance.options = Object.assign({}, vex.defaultOptions, opts)

    // vex root
    var rootEl = vexInstance.rootEl = document.createElement('div')
    rootEl.classList.add(baseClassNames.vex)
    if (options.className) {
      rootEl.classList.add(options.className)
    }

    // Overlay
    var overlayEl = vexInstance.overlayEl = document.createElement('div')
    overlayEl.classList.add(baseClassNames.overlay)
    if (options.overlayClassName) {
      overlayEl.classList.add(options.overlayClassName)
    }
    if (options.overlayClosesOnClick) {
      overlayEl.addEventListener('click', function overlayClickListener (e) {
        if (e.target === overlayEl) {
          vexInstance.close()
        }
      })
    }
    rootEl.appendChild(overlayEl)

    // Content
    var contentEl = vexInstance.contentEl = document.createElement('div')
    contentEl.classList.add(baseClassNames.content)
    if (options.contentClassName) {
      contentEl.classList.add(options.contentClassName)
    }
    contentEl.appendChild(options.content instanceof window.Node ? options.content : domify(options.content))
    rootEl.appendChild(contentEl)

    // Close button
    if (options.showCloseButton) {
      var closeEl = vexInstance.closeEl = document.createElement('div')
      closeEl.classList.add(baseClassNames.close)
      if (options.closeClassName) {
        closeEl.classList.add(options.closeClassName)
      }
      closeEl.addEventListener('click', vexInstance.close.bind(vexInstance))
      contentEl.appendChild(closeEl)
    }

    // Add to DOM
    document.querySelector(options.appendLocation).appendChild(rootEl)

    // Call after open callback
    if (options.afterOpen) {
      options.afterOpen.call(vexInstance)
    }

    // Apply styling to the body
    document.body.classList.add(baseClassNames.open)

    // Return the created vex instance
    return vexInstance
  },

  // A top-level vex.close function to close dialogs by reference or id
  close: function close (vexOrId) {
    var id
    if (vexOrId.id) {
      id = vexOrId.id
    } else if (typeof vexOrId === 'string') {
      id = vexOrId
    } else {
      throw new TypeError('close requires a vex object or id string')
    }
    if (!vexes[id]) {
      return false
    }
    return vexes[id].close()
  },

  // Close the most recently created/opened vex
  closeTop: function closeTop () {
    var ids = Object.keys(vexes)
    if (!ids.length) {
      return false
    }
    return vexes[ids[ids.length - 1]].close()
  },

  // Close every vex!
  closeAll: function closeAll () {
    for (var id in vexes) {
      this.close(id)
    }
    return true
  },

  // A getter for the internal lookup table
  getAll: function getAll () {
    return vexes
  },

  // A getter for the internal lookup table
  getById: function getById (id) {
    return vexes[id]
  }
}

// Close top vex on escape
window.addEventListener('keyup', function vexKeyupListener (e) {
  if (e.keyCode === 27) {
    vex.closeTop()
  }
})
// Close all vexes on history pop state (useful in single page apps)
window.addEventListener('popstate', vex.closeAll)

vex.defaultOptions = {
  content: '',
  showCloseButton: true,
  escapeButtonCloses: true,
  overlayClosesOnClick: true,
  appendLocation: 'body',
  className: '',
  overlayClassName: '',
  contentClassName: '',
  closeClassName: ''
}

// TODO Loading symbols?

// Plugin system!
vex.registerPlugin = function registerPlugin (pluginFn, name) {
  var plugin = pluginFn(vex)
  var pluginName = name || plugin.name
  if (vex[pluginName]) {
    throw new Error('Plugin ' + name + ' is already registered.')
  }
  vex[pluginName] = plugin
}

module.exports = vex
<|endoftext|>


<commit_before>/*global SixSpeed */
var _ = require('lodash'),
    ChildProcess = require('child_process'),
    DataStore = require('./data-store'),
    Fs = require('fs'),
    Path = require('path');

var nodeTestPath = require.resolve('./node-test');

require('./runner');

var testDir = Path.join(__dirname, '..', 'build/tests'),
    browserLog = [];

Fs.readdirSync(testDir).forEach(function(test) {
  try {
    require(Path.join(testDir, test));
  } catch (err) {
    var msg = 'Failed to load ' + test + ' ' + err;
    browserLog.push(msg);
    console.log(msg);
  }
});

var vms = {};

SixSpeed.bench({
  concurrency: 2,

  done: function() {
    let tag = process.versions.node;
    if (/^(0\.\d+)/.exec(tag)) {
      tag = RegExp.$1;
    } else if (/^(\d+\.)/.exec(tag)) {
      tag = RegExp.$1 + 'x';
    }
    DataStore.store('node', tag, process.versions.node, SixSpeed.stats);

    _.each(vms, function(vm) {
      vm.kill();
    });
  },

  runTest: function(name, type, complete) {
    var vm = vms[type];
    if (!vm) {
      vm = vms[type] = ChildProcess.fork(nodeTestPath, [type]);
    }

    vm.once('message', function(m) {
      complete(m.result);
    });
    vm.send({name: name});
  }
});
<commit_msg>Fix let reference in node exec<commit_after>/*global SixSpeed */
var _ = require('lodash'),
    ChildProcess = require('child_process'),
    DataStore = require('./data-store'),
    Fs = require('fs'),
    Path = require('path');

var nodeTestPath = require.resolve('./node-test');

require('./runner');

var testDir = Path.join(__dirname, '..', 'build/tests'),
    browserLog = [];

Fs.readdirSync(testDir).forEach(function(test) {
  try {
    require(Path.join(testDir, test));
  } catch (err) {
    var msg = 'Failed to load ' + test + ' ' + err;
    browserLog.push(msg);
    console.log(msg);
  }
});

var vms = {};

SixSpeed.bench({
  concurrency: 2,

  done: function() {
    var tag = process.versions.node;
    if (/^(0\.\d+)/.exec(tag)) {
      tag = RegExp.$1;
    } else if (/^(\d+\.)/.exec(tag)) {
      tag = RegExp.$1 + 'x';
    }
    DataStore.store('node', tag, process.versions.node, SixSpeed.stats);

    _.each(vms, function(vm) {
      vm.kill();
    });
  },

  runTest: function(name, type, complete) {
    var vm = vms[type];
    if (!vm) {
      vm = vms[type] = ChildProcess.fork(nodeTestPath, [type]);
    }

    vm.once('message', function(m) {
      complete(m.result);
    });
    vm.send({name: name});
  }
});
<|endoftext|>


<commit_before>/*!
 * Fallwall.js
 *
 * Copyright © 2015 Eddie Wen | MIT license
 * https://github.com/EddieWen-Taiwan/Fallwall.js
 */

(function(root, factory) {
	'use strict';
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
	typeof define === 'function' && define.amd ? define(['jquery'], factory) :
	root.Fallwall = factory(jQuery)
}(this, function($) {
	'use strict';

	var defaults = {
		gridNumber: 20,
		columnNumber: 1,
		defaultClass: '',
		html_template: '',
		dataArray: null,
		currentGrid: 0
	},

	_setContentAtFirst = function( dataArray, callback_func ) {

		for( var i = 0; i < defaults.gridNumber; i++ ) {
			if( typeof dataArray[i] != "undefined" ) {
				_createGrid( dataArray[i], 'down' );
				defaults.currentGrid = i;
			}
			else {
				break;
			}
		}

		if( callback_func ) {
			if( typeof callback_func == 'function' )
				callback_func();
			else
				console.error(callback_func+' is not a function');
		}

	},

	/**
	 * Add new grid
	 * direction: up/down => grid is added at the top/bottom
	 */
	_createGrid = function( obj, direction ) {

		var thisCode = defaults.html_template;

		for( var j = 0; j < Object.keys(obj).length; j++ ) {
			thisCode = thisCode.replace( 'fallwall_#'+(j+1), obj[j] );
		}

		var targetColumn = $('.fw_column').eq( _getShortestCol() );
		var creatingElement;
		if( direction == 'up' ) {
			targetColumn.prepend( thisCode );
			creatingElement = targetColumn.find('.fw_grid').first();
		}
		else {
			targetColumn.append( thisCode );
			creatingElement = targetColumn.find('.fw_grid').last();
		}

		/**
		 * Add extra class
		 * like animation class
		 */
		if( defaults.defaultClass != '' ) {
			creatingElement.addClass( defaults.defaultClass );
		}

	},

	/**
	 * Return the shortest fw_column to append a new grid
	 */
	_getShortestCol = function() {

		var heightArray = [];

		$.each( $('.fw_column'), function(index, element) {
			heightArray.push( element.offsetHeight );
		});

		var minColumn = Math.min.apply( null, heightArray );
		return $.inArray( minColumn, heightArray );

	};

	/**
	 * Fallwall construtcor
	 * Setup template and data source
	 */
	$.fn.fallwall_init = function( template, dataArray, options, callback_func ) {

		/**
		 * check required parameters
		 */
		if( template == null || dataArray == null ) {
			throw new Error('You missed some parameters while initializing');
		}

		// Store data from user
		defaults = $.extend({
			gridNumber: 20,
			columnNumber: 1,
			defaultClass: '',
			html_template: '
'+template+'
',
			dataArray: dataArray,
			currentGrid: 0
		}, options);

		// Add columns
		var colElements = '';
		for( var i = 0; i < defaults.columnNumber; i++ ) {
			colElements += '

';
		}
		this.append( colElements );

		// Prepare CSS
		this.find('.fw_column').css({
			'display': 'inline-block',
			'vertical-align': 'top',
			'width': (100/defaults.columnNumber)+'%'
		});

		// Add grids at first
		_setContentAtFirst( dataArray, callback_func );

	};

	/**
	 * load more data and append them
	 */
	$.fn.loadMoreFw = function( callback_func ) {

		if( defaults.currentGrid +1 < defaults.dataArray.length ) {

			defaults.currentGrid++;
			var limitNum = defaults.currentGrid + defaults.gridNumber;
			for( var i = defaults.currentGrid; i < limitNum; i++ ) {

				if( typeof defaults.dataArray[i] != "undefined" ) {

					_createGrid( defaults.dataArray[i], 'down' );
					defaults.currentGrid = i;

				}
				else {
					// Data is exhausted before last run in loop
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(callback_func+' is not a function');
					}
					return "NO_MORE_DATA";
				}

				// Last run in loop
				if( i == limitNum-1 ) {
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(callback_func+' is not a function');
					}
					return "FINISHED";
				}

			}

		}

		/***
		 * There is no more data.
		 * All is displayed.
		***/
		return "NO_MORE_DATA";

	};

	/**
	 * directly append a new grid at the top of one column
	 */
	$.fn.addFwGrid = function( data, callback_func ) {

		if( typeof data == 'object' ) {
			// Add a new grid
			_createGrid( data, 'up' );

			if( callback_func ) {
				if( typeof callback_func == 'function' )
					callback_func();
				else
					console.error(callback_func+' is not a function');
			}
		}
		else {
			throw new Error('First parameter of addFwGrid(): '+data+' must be Object');
		}

	};

}));
<commit_msg>Rename private functions<commit_after>/*!
 * Fallwall.js
 *
 * Copyright © 2015 Eddie Wen | MIT license
 * https://github.com/EddieWen-Taiwan/Fallwall.js
 */

(function(root, factory) {
	'use strict';
	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('jquery')) :
	typeof define === 'function' && define.amd ? define(['jquery'], factory) :
	root.Fallwall = factory(jQuery)
}(this, function($) {
	'use strict';

	var defaults = {
		gridNumber: 20,
		columnNumber: 1,
		defaultClass: '',
		html_template: '',
		dataArray: null,
		currentGrid: 0
	},

	/**
	 * call after initializing Fallwall
	 * append grids in the zfirst round
	 */
	_setFirstRoundContent = function( dataArray, callback_func ) {

		for( var i = 0; i < defaults.gridNumber; i++ ) {
			if( typeof dataArray[i] != "undefined" ) {
				_appendGrids( dataArray[i], 'down' );
				defaults.currentGrid = i;
			}
			else {
				break;
			}
		}

		if( callback_func ) {
			if( typeof callback_func == 'function' )
				callback_func();
			else
				console.error(callback_func+' is not a function');
		}

	},

	/**
	 * Add new grid
	 * direction: up/down => grid is added at the top/bottom
	 */
	_appendGrids = function( obj, direction ) {

		var thisCode = defaults.html_template;

		for( var j = 0; j < Object.keys(obj).length; j++ ) {
			thisCode = thisCode.replace( 'fallwall_#'+(j+1), obj[j] );
		}

		var targetColumn = $('.fw_column').eq( _getShortestColumn() );
		var creatingElement;
		if( direction == 'up' ) {
			targetColumn.prepend( thisCode );
			creatingElement = targetColumn.find('.fw_grid').first();
		}
		else {
			targetColumn.append( thisCode );
			creatingElement = targetColumn.find('.fw_grid').last();
		}

		/**
		 * Add extra class
		 * like animation class
		 */
		if( defaults.defaultClass != '' ) {
			creatingElement.addClass( defaults.defaultClass );
		}

	},

	/**
	 * Return the shortest fw_column to append a new grid
	 */
	_getShortestColumn = function() {

		var heightArray = [];

		$.each( $('.fw_column'), function(index, element) {
			heightArray.push( element.offsetHeight );
		});

		var minColumn = Math.min.apply( null, heightArray );
		return $.inArray( minColumn, heightArray );

	};

	/**
	 * Fallwall construtcor
	 * Setup template and data source
	 */
	$.fn.fallwall_init = function( template, dataArray, options, callback_func ) {

		/**
		 * check required parameters
		 */
		if( template == null || dataArray == null ) {
			throw new Error('You missed some parameters while initializing');
		}

		// Store data from user
		defaults = $.extend({
			gridNumber: 20,
			columnNumber: 1,
			defaultClass: '',
			html_template: '
'+template+'
',
			dataArray: dataArray,
			currentGrid: 0
		}, options);

		// Add columns
		var colElements = '';
		for( var i = 0; i < defaults.columnNumber; i++ ) {
			colElements += '

';
		}
		this.append( colElements );

		// Prepare CSS
		this.find('.fw_column').css({
			'display': 'inline-block',
			'vertical-align': 'top',
			'width': (100/defaults.columnNumber)+'%'
		});

		// Add grids at first
		_setFirstRoundContent( dataArray, callback_func );

	};

	/**
	 * load more data and append them
	 */
	$.fn.loadMoreFw = function( callback_func ) {

		if( defaults.currentGrid +1 < defaults.dataArray.length ) {

			defaults.currentGrid++;
			var limitNum = defaults.currentGrid + defaults.gridNumber;
			for( var i = defaults.currentGrid; i < limitNum; i++ ) {

				if( typeof defaults.dataArray[i] != "undefined" ) {

					_appendGrids( defaults.dataArray[i], 'down' );
					defaults.currentGrid = i;

				}
				else {
					// Data is exhausted before last run in loop
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(callback_func+' is not a function');
					}
					return "NO_MORE_DATA";
				}

				// Last run in loop
				if( i == limitNum-1 ) {
					if( callback_func ) {
						if( typeof callback_func == 'function' )
							callback_func();
						else
							console.error(callback_func+' is not a function');
					}
					return "FINISHED";
				}

			}

		}

		/***
		 * There is no more data.
		 * All is displayed.
		***/
		return "NO_MORE_DATA";

	};

	/**
	 * directly append a new grid at the top of one column
	 */
	$.fn.addFwGrid = function( data, callback_func ) {

		if( typeof data == 'object' ) {
			// Add a new grid
			_appendGrids( data, 'up' );

			if( callback_func ) {
				if( typeof callback_func == 'function' )
					callback_func();
				else
					console.error(callback_func+' is not a function');
			}
		}
		else {
			throw new Error('First parameter of addFwGrid(): '+data+' must be Object');
		}

	};

}));
<|endoftext|>


<commit_before>var Fs = require('fs'),
    Path = require('path');

require('./runner');

var testDir = Path.join(__dirname, '..', 'build/tests');

Fs.readdirSync(testDir).forEach(function(test) {
  try {
    require(Path.join(testDir, test));
  } catch (err) {
    console.log('Failed to load', test, err);
  }
});

SixSpeed.run();
<commit_msg>Output node test exec data to data store<commit_after>/*global SixSpeed */
var DataStore = require('./data-store'),
    Fs = require('fs'),
    Path = require('path');

require('./runner');

var testDir = Path.join(__dirname, '..', 'build/tests'),
    browserLog = [];

Fs.readdirSync(testDir).forEach(function(test) {
  try {
    require(Path.join(testDir, test));
  } catch (err) {
    var msg = 'Failed to load ' + test + ' ' + err;
    browserLog.push(msg);
    console.log(msg);
  }
});

SixSpeed.run(undefined, undefined, function() {
  DataStore.store('node', process.versions.node, {
    stats: SixSpeed.stats,
    log: browserLog
  });
});
<|endoftext|>


<commit_before>/**
 * Appends the objects necessary for a new class to extend a base class.
 */
Function.prototype.extends = function(base){
  if(base.constructor == Function){
    // normal inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base.prototype;
  }
  else {
    // virtual inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base;
  }
  return this;
}

var svg = {
  ns: "http://www.w3.org/2000/svg",
}

/*******************************************************************************
 * A node is the root base class for all classes in the svg namespace. It
 * provides methods for working with attributes and children.
 */
svg.node = function(){
  this.root = null;
  this.element = null;
}

/**
 * This function sets the value of an attribute on an element.
 *
 * @param key   - the name of the attribute
 * @param value - the value the attribute should be set to
 *
 * @return a reference to this object
 */
svg.node.prototype.attr = function(key, value){
  this.element.setAttributeNS(null, key, value);
  return this;
}

/**
 * This function sets the values of one or more attributes on an element.
 *
 * @param attrs - an object literal containg the attributes to modify
 *
 * @return a reference to this object
 */
svg.node.prototype.attrs = function(attrs){
  for(var key in attrs){
    this.element.setAttributeNS(null, key, attrs[key]);
  }
  return this;
}

/**
 * Returns the value of the specified attribute.
 *
 * @param key - the name of the attribute to return.
 *
 * @return the value of the attribute
 */
svg.node.prototype.get = function(key){
  return this.element.getAttributeNS(null, key);
}

/**
 * Adds an SVG as a child of this element.
 *
 * @param child - the element to add.
 *
 * @return a reference to this object
 */
svg.node.prototype.add = function(child){
  this.element.appendChild(child.element);
  return this;
}

/**
 * Returns a list of the children contained in this SVG element.
 *
 * @return a NodeList of children.
 */
svg.node.prototype.children = function(){
  return this.element.childNodes;
}

/*******************************************************************************
 * The element class defines an interface that is common to all of the SVG
 * classes.
 */
svg.element = function(){
  this.root = null;
  this.element = null;
}

svg.element.extends(svg.node);

/**
 * Sets the 'click' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onclick = function(cb){
  this.element.onclick = cb;
}

/**
 * Sets the 'mouse over' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onmouseover = function(cb){
  this.element.onmouseover = cb;
}

/**
 * Translates this element.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 */
svg.element.prototype.translate = function(dx, dy){
  var transform = this.root.translate(dx, dy);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Rotate this element about a point.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 */
svg.element.prototype.rotate = function(angle, x, y){
  var transform = this.root.rotation(angle, x, y);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Scale this element.
 *
 * @param factor - the scaling factor
 */
svg.element.prototype.scale = function(factor){
  var transform = this.root.scale(factor);
  this.element.transform.baseVal.insertItemBefore(transform,0);
}

/*******************************************************************************
 * This class is used to wrap an existing SVG element, rather than creating
 * one.
 */
svg.proxy = function(element){
  this.root = new svg.root(element.ownerSVGElement);
  this.element = element;
}

svg.proxy.extends(svg.node);

/*******************************************************************************
 * This class is specifically for elements that represent root nodes. It
 * exposes functionality that can only be obtained from the root note. In
 * particular, it is necessary to provide consist access to transformation
 * objects.
 */
svg.root = function(element){
  if(!(element instanceof SVGSVGElement))
    throw "A root element must be of type SVGSVGElement";

  this.element = element;
}

svg.root.extends(svg.proxy);

/**
 * Create an SVGTransform object. This is intended for use (internally) by the
 * other SVG elements (path, rect, or group).
 */
svg.root.prototype.transform = function(){
  return this.element.createSVGTransform();
}

/**
 * Create a translation transform.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 *
 * @return a translation transform
 */
svg.root.prototype.translate = function(dx, dy){
  var transform = this.transform();
  transform.setTranslate(dx, dy);
  return transform;
}

/**
 * Create a rotation transform.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 *
 * @return a rotation transform
 */
svg.root.prototype.rotation = function(angle, x, y){
  var transform = this.transform();
  transform.setRotate(angle, x, y);
  return transform;
}

/**
 * Create a scale transform.
 *
 * @param factor - the scaling factor
 *
 * @return a scale transform
 */
svg.root.prototype.scale = function(factor){
  var transform = this.transform();
  transform.setScale(factor, factor);
  return transform;
}

/*******************************************************************************
 * This class provides the interface to the 'group' element. The group element
 * is a composite of other elements (even other group elements). It is useful
 * for applying a transformation to a set of related elements.
 */
svg.group = function(root){
  if(root instanceof SVGSVGElement)
    this.root = new svg.root(root);
  else
    this.root = root;
  this.element = document.createElementNS(svg.ns, "g");
}

svg.group.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'rect' element.
 */
svg.rect = function(root, x, y, w, h){
  this.root = root;
  this.element = document.createElementNS(svg.ns, "rect");
  this.attrs({x: x, y: y, width: w, height: h});
}

svg.rect.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'path' element.
 */
svg.path = function(root, path){
  this.root = root;
  this.element = document.createElementNS(svg.ns, "path");
  this.attr('d', path || '');
}

svg.path.extends(svg.element);

/**
 * Appends a move instruction to the path.
 *
 * @param x - the x absolute position to move to
 * @param y - the y absolute position to move to
 */
svg.path.prototype.move_to = function(x, y){
  this.attr('d', this.get('d') + ' M ' + x.toString() + ' ' + y.toString());
}

/**
 * Append a line instruction to the path.
 *
 * @param x - the x absolute position to draw to
 * @param y - the y absolute position to draw to
 */
svg.path.prototype.line_to = function(x, y){
  this.attr('d', this.get('d') + ' L ' + x.toString() + ' ' + y.toString());
}
<commit_msg>svg: added 'close' function to svg.path<commit_after>/**
 * Appends the objects necessary for a new class to extend a base class.
 */
Function.prototype.extends = function(base){
  if(base.constructor == Function){
    // normal inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base.prototype;
  }
  else {
    // virtual inheritance
    this.prototype = Object.create(base.prototype);
    this.prototype.constructor = this;
    this.prototype.base = base;
  }
  return this;
}

var svg = {
  ns: "http://www.w3.org/2000/svg",
}

/*******************************************************************************
 * A node is the root base class for all classes in the svg namespace. It
 * provides methods for working with attributes and children.
 */
svg.node = function(){
  this.root = null;
  this.element = null;
}

/**
 * This function sets the value of an attribute on an element.
 *
 * @param key   - the name of the attribute
 * @param value - the value the attribute should be set to
 *
 * @return a reference to this object
 */
svg.node.prototype.attr = function(key, value){
  this.element.setAttributeNS(null, key, value);
  return this;
}

/**
 * This function sets the values of one or more attributes on an element.
 *
 * @param attrs - an object literal containg the attributes to modify
 *
 * @return a reference to this object
 */
svg.node.prototype.attrs = function(attrs){
  for(var key in attrs){
    this.element.setAttributeNS(null, key, attrs[key]);
  }
  return this;
}

/**
 * Returns the value of the specified attribute.
 *
 * @param key - the name of the attribute to return.
 *
 * @return the value of the attribute
 */
svg.node.prototype.get = function(key){
  return this.element.getAttributeNS(null, key);
}

/**
 * Adds an SVG as a child of this element.
 *
 * @param child - the element to add.
 *
 * @return a reference to this object
 */
svg.node.prototype.add = function(child){
  this.element.appendChild(child.element);
  return this;
}

/**
 * Returns a list of the children contained in this SVG element.
 *
 * @return a NodeList of children.
 */
svg.node.prototype.children = function(){
  return this.element.childNodes;
}

/*******************************************************************************
 * The element class defines an interface that is common to all of the SVG
 * classes.
 */
svg.element = function(){
  this.root = null;
  this.element = null;
}

svg.element.extends(svg.node);

/**
 * Sets the 'click' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onclick = function(cb){
  this.element.onclick = cb;
}

/**
 * Sets the 'mouse over' callback
 *
 * @param cb - a callback function
 */
svg.element.prototype.onmouseover = function(cb){
  this.element.onmouseover = cb;
}

/**
 * Translates this element.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 */
svg.element.prototype.translate = function(dx, dy){
  var transform = this.root.translate(dx, dy);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Rotate this element about a point.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 */
svg.element.prototype.rotate = function(angle, x, y){
  var transform = this.root.rotation(angle, x, y);
  this.element.transform.baseVal.insertItemBefore(transform, 0);
}

/**
 * Scale this element.
 *
 * @param factor - the scaling factor
 */
svg.element.prototype.scale = function(factor){
  var transform = this.root.scale(factor);
  this.element.transform.baseVal.insertItemBefore(transform,0);
}

/*******************************************************************************
 * This class is used to wrap an existing SVG element, rather than creating
 * one.
 */
svg.proxy = function(element){
  this.root = new svg.root(element.ownerSVGElement);
  this.element = element;
}

svg.proxy.extends(svg.node);

/*******************************************************************************
 * This class is specifically for elements that represent root nodes. It
 * exposes functionality that can only be obtained from the root note. In
 * particular, it is necessary to provide consist access to transformation
 * objects.
 */
svg.root = function(element){
  if(!(element instanceof SVGSVGElement))
    throw "A root element must be of type SVGSVGElement";

  this.element = element;
}

svg.root.extends(svg.proxy);

/**
 * Create an SVGTransform object. This is intended for use (internally) by the
 * other SVG elements (path, rect, or group).
 */
svg.root.prototype.transform = function(){
  return this.element.createSVGTransform();
}

/**
 * Create a translation transform.
 *
 * @param dx - the amount to move in the x co-ordinate
 * @param dy - the amount to move in the y co-ordinate
 *
 * @return a translation transform
 */
svg.root.prototype.translate = function(dx, dy){
  var transform = this.transform();
  transform.setTranslate(dx, dy);
  return transform;
}

/**
 * Create a rotation transform.
 *
 * @param angle - the amount to rotate the element by (degrees)
 * @param x     - the x co-ordinate to rotate about
 * @param y     - the y co-ordinate to rotate about
 *
 * @return a rotation transform
 */
svg.root.prototype.rotation = function(angle, x, y){
  var transform = this.transform();
  transform.setRotate(angle, x, y);
  return transform;
}

/**
 * Create a scale transform.
 *
 * @param factor - the scaling factor
 *
 * @return a scale transform
 */
svg.root.prototype.scale = function(factor){
  var transform = this.transform();
  transform.setScale(factor, factor);
  return transform;
}

/*******************************************************************************
 * This class provides the interface to the 'group' element. The group element
 * is a composite of other elements (even other group elements). It is useful
 * for applying a transformation to a set of related elements.
 */
svg.group = function(root){
  if(root instanceof SVGSVGElement)
    this.root = new svg.root(root);
  else
    this.root = root;
  this.element = document.createElementNS(svg.ns, "g");
}

svg.group.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'rect' element.
 */
svg.rect = function(root, x, y, w, h){
  this.root = root;
  this.element = document.createElementNS(svg.ns, "rect");
  this.attrs({x: x, y: y, width: w, height: h});
}

svg.rect.extends(svg.element);

/*******************************************************************************
 * This class provides the interface to the 'path' element.
 */
svg.path = function(root, path){
  this.root = root;
  this.element = document.createElementNS(svg.ns, "path");
  this.attr('d', path || '');
}

svg.path.extends(svg.element);

/**
 * Appends a move instruction to the path.
 *
 * @param x - the x absolute position to move to
 * @param y - the y absolute position to move to
 */
svg.path.prototype.move_to = function(x, y){
  this.attr('d', this.get('d') + ' M ' + x.toString() + ' ' + y.toString());
}

/**
 * Append a line instruction to the path.
 *
 * @param x - the x absolute position to draw to
 * @param y - the y absolute position to draw to
 */
svg.path.prototype.line_to = function(x, y){
  this.attr('d', this.get('d') + ' L ' + x.toString() + ' ' + y.toString());
}

/**
 * Close the path.
 *
 */
svg.path.prototype.close = function(){
  this.attr('d', this.get('d') + ' z');
}
<|endoftext|>


<commit_before>'use strict'

const debug = require('debug')('nuxt:render')
const _ = require('lodash')
const co = require('co')
const fs = require('fs-extra')
const pify = require('pify')
const ansiHTML = require('ansi-html')
const serialize = require('serialize-javascript')
const build = require('./build')
const generate = require('./generate')
const serveStatic = require('serve-static')
const { resolve, join } = require('path')
const { urlJoin } = require('./utils')
const { encodeHtml, getContext, setAnsiColors } = require('./utils')
setAnsiColors(ansiHTML)

class Nuxt {

  constructor (options = {}, cb) {
    var defaults = {
      // special options
      _renderer: true,
      _build: true,
      // general options
      dev: true,
      env: {},
      head: {},
      plugins: [],
      css: [],
      cache: false,
      loading: {
        color: 'black',
        failedColor: 'red',
        height: '2px',
        duration: 5000
      },
      transition: {
        name: 'page',
        mode: 'out-in'
      },
      router: {
        base: '/',
        linkActiveClass: 'router-link-active',
        routes: []
      },
      build: {
        filenames: {
          css: 'style.css'
        }
      }
    }
    if (options.loading === true) delete options.loading
    if (typeof options.transition === 'string') options.transition = { name: options.transition }
    this.options = _.defaultsDeep(options, defaults)
    // Env variables
    this.dev = this.options.dev
    this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
    // If store defined, update store options to true
    if (fs.existsSync(join(this.dir, 'store', 'index.js'))) {
      this.options.store = true
    }
    // Template
    this.appTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'app.html'), 'utf8'), {
      imports: { serialize }
    })
    this.errorTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'error.html'), 'utf8'), {
      imports: { ansiHTML, encodeHtml }
    })
    // renderer used by Vue.js (via createBundleRenderer)
    this.renderer = null
    // For serving static/ files to /
    this.serveStatic = pify(serveStatic(resolve(this.dir, 'static')))
    // For serving .nuxt/dist/ files
    this._nuxtRegexp = /^\/_nuxt\//
    this.serveStaticNuxt = pify(serveStatic(resolve(this.dir, '.nuxt', 'dist')))
    // Add this.build
    this.build = build.bind(this)
    // Add this.generate
    this.generate = generate.bind(this)
    // Launch build and set this.renderer
    return co(this.build)
    .then(() => {
      if (typeof cb === 'function') cb(null, this)
      return this
    })
    .catch((err) => {
      if (typeof cb === 'function') cb(err)
      return Promise.reject(err)
    })
  }

  render (req, res) {
    if (!this.renderer) {
      setTimeout(() => {
        this.render(req, res)
      }, 1000)
      return
    }
    const self = this
    const context = getContext(req, res)
    co(function * () {
      if (self.dev) {
        // Call webpack middlewares only in development
        yield self.webpackDevMiddleware(req, res)
        yield self.webpackHotMiddleware(req, res)
      }
      // If base in req.url, remove it for the middlewares and vue-router
      if (self.options.router.base !== '/' && req.url.indexOf(self.options.router.base) === 0) {
        // Compatibility with base url for dev server
        req.url = req.url.replace(self.options.router.base, '/')
      }
      // Serve static/ files
      yield self.serveStatic(req, res)
      // Serve .nuxt/dist/ files (only for production)
      if (!self.dev && self._nuxtRegexp.test(req.url)) {
        const url = req.url
        req.url = req.url.replace(self._nuxtRegexp, '/')
        yield self.serveStaticNuxt(req, res)
        req.url = url
      }
    })
    .then(() => {
      if (this.dev && this._nuxtRegexp.test(req.url) && req.url.includes('.hot-update.json')) {
        res.statusCode = 404
        return res.end()
      }
      return this.renderRoute(req.url, context)
    })
    .then(({ html, error }) => {
      if (error) {
        res.statusCode = context.nuxt.error.statusCode || 500
      }
      res.setHeader('Content-Type', 'text/html; charset=utf-8')
      res.end(html, 'utf8')
    })
    .catch((err) => {
      res.statusCode = 500
      res.end(this.errorTemplate({ err }), 'utf8')
    })
  }

  renderRoute (url, context = {}) {
    debug(`Rendering url ${url}`)
    // Add url and isSever to the context
    context.url = url
    context.isServer = true
    // Call rendertoSting from the bundleRenderer and generate the HTML (will update the context as well)
    const self = this
    return co(function * () {
      let app = yield self.renderToString(context)
      if (context.nuxt && context.nuxt.error instanceof Error) {
        context.nuxt.error = { statusCode: 500, message: context.nuxt.error.message }
      }
      if (context.redirected) {
        app = '

'
      }
      const html = self.appTemplate({
        dev: self.dev, // Use to add the extracted CSS <link> in production
        baseUrl: self.options.router.base,
        APP: app,
        context: context,
        files: {
          css: urlJoin(self.options.router.base, '/_nuxt/', self.options.build.filenames.css),
          vendor: urlJoin(self.options.router.base, '/_nuxt/', self.options.build.filenames.vendor),
          app: urlJoin(self.options.router.base, '/_nuxt/', self.options.build.filenames.app)
        }
      })
      return {
        html,
        error: context.nuxt.error,
        redirected: context.redirected
      }
    })
  }

  close (callback) {
    let promises = []
    if (this.webpackDevMiddleware) {
      const p = new Promise((resolve, reject) => {
        this.webpackDevMiddleware.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.webpackServerWatcher) {
      const p = new Promise((resolve, reject) => {
        this.webpackServerWatcher.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.pagesFilesWatcher) {
      this.pagesFilesWatcher.close()
    }
    return co(function * () {
      yield promises
    })
    .then(function () {
      if (typeof callback === 'function') callback()
    })
  }

}

module.exports = Nuxt
<commit_msg>Add Content-Length header<commit_after>'use strict'

const debug = require('debug')('nuxt:render')
const _ = require('lodash')
const co = require('co')
const fs = require('fs-extra')
const pify = require('pify')
const ansiHTML = require('ansi-html')
const serialize = require('serialize-javascript')
const build = require('./build')
const generate = require('./generate')
const serveStatic = require('serve-static')
const { resolve, join } = require('path')
const { urlJoin } = require('./utils')
const { encodeHtml, getContext, setAnsiColors } = require('./utils')
setAnsiColors(ansiHTML)

class Nuxt {

  constructor (options = {}, cb) {
    var defaults = {
      // special options
      _renderer: true,
      _build: true,
      // general options
      dev: true,
      env: {},
      head: {},
      plugins: [],
      css: [],
      cache: false,
      loading: {
        color: 'black',
        failedColor: 'red',
        height: '2px',
        duration: 5000
      },
      transition: {
        name: 'page',
        mode: 'out-in'
      },
      router: {
        base: '/',
        linkActiveClass: 'router-link-active',
        routes: []
      },
      build: {
        filenames: {
          css: 'style.css'
        }
      }
    }
    if (options.loading === true) delete options.loading
    if (typeof options.transition === 'string') options.transition = { name: options.transition }
    this.options = _.defaultsDeep(options, defaults)
    // Env variables
    this.dev = this.options.dev
    this.dir = (typeof options.rootDir === 'string' && options.rootDir ? options.rootDir : process.cwd())
    // If store defined, update store options to true
    if (fs.existsSync(join(this.dir, 'store', 'index.js'))) {
      this.options.store = true
    }
    // Template
    this.appTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'app.html'), 'utf8'), {
      imports: { serialize }
    })
    this.errorTemplate = _.template(fs.readFileSync(resolve(__dirname, 'views', 'error.html'), 'utf8'), {
      imports: { ansiHTML, encodeHtml }
    })
    // renderer used by Vue.js (via createBundleRenderer)
    this.renderer = null
    // For serving static/ files to /
    this.serveStatic = pify(serveStatic(resolve(this.dir, 'static')))
    // For serving .nuxt/dist/ files
    this._nuxtRegexp = /^\/_nuxt\//
    this.serveStaticNuxt = pify(serveStatic(resolve(this.dir, '.nuxt', 'dist')))
    // Add this.build
    this.build = build.bind(this)
    // Add this.generate
    this.generate = generate.bind(this)
    // Launch build and set this.renderer
    return co(this.build)
    .then(() => {
      if (typeof cb === 'function') cb(null, this)
      return this
    })
    .catch((err) => {
      if (typeof cb === 'function') cb(err)
      return Promise.reject(err)
    })
  }

  render (req, res) {
    if (!this.renderer) {
      setTimeout(() => {
        this.render(req, res)
      }, 1000)
      return
    }
    const self = this
    const context = getContext(req, res)
    co(function * () {
      if (self.dev) {
        // Call webpack middlewares only in development
        yield self.webpackDevMiddleware(req, res)
        yield self.webpackHotMiddleware(req, res)
      }
      // If base in req.url, remove it for the middlewares and vue-router
      if (self.options.router.base !== '/' && req.url.indexOf(self.options.router.base) === 0) {
        // Compatibility with base url for dev server
        req.url = req.url.replace(self.options.router.base, '/')
      }
      // Serve static/ files
      yield self.serveStatic(req, res)
      // Serve .nuxt/dist/ files (only for production)
      if (!self.dev && self._nuxtRegexp.test(req.url)) {
        const url = req.url
        req.url = req.url.replace(self._nuxtRegexp, '/')
        yield self.serveStaticNuxt(req, res)
        req.url = url
      }
    })
    .then(() => {
      if (this.dev && this._nuxtRegexp.test(req.url) && req.url.includes('.hot-update.json')) {
        res.statusCode = 404
        return res.end()
      }
      return this.renderRoute(req.url, context)
    })
    .then(({ html, error }) => {
      if (error) {
        res.statusCode = context.nuxt.error.statusCode || 500
      }
      res.setHeader('Content-Type', 'text/html; charset=utf-8')
      res.setHeader('Content-Length', Buffer.byteLength(html))
      res.end(html, 'utf8')
    })
    .catch((err) => {
      res.statusCode = 500
      res.end(this.errorTemplate({ err }), 'utf8')
    })
  }

  renderRoute (url, context = {}) {
    debug(`Rendering url ${url}`)
    // Add url and isSever to the context
    context.url = url
    context.isServer = true
    // Call rendertoSting from the bundleRenderer and generate the HTML (will update the context as well)
    const self = this
    return co(function * () {
      let app = yield self.renderToString(context)
      if (context.nuxt && context.nuxt.error instanceof Error) {
        context.nuxt.error = { statusCode: 500, message: context.nuxt.error.message }
      }
      if (context.redirected) {
        app = '

'
      }
      const html = self.appTemplate({
        dev: self.dev, // Use to add the extracted CSS <link> in production
        baseUrl: self.options.router.base,
        APP: app,
        context: context,
        files: {
          css: urlJoin(self.options.router.base, '/_nuxt/', self.options.build.filenames.css),
          vendor: urlJoin(self.options.router.base, '/_nuxt/', self.options.build.filenames.vendor),
          app: urlJoin(self.options.router.base, '/_nuxt/', self.options.build.filenames.app)
        }
      })
      return {
        html,
        error: context.nuxt.error,
        redirected: context.redirected
      }
    })
  }

  close (callback) {
    let promises = []
    if (this.webpackDevMiddleware) {
      const p = new Promise((resolve, reject) => {
        this.webpackDevMiddleware.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.webpackServerWatcher) {
      const p = new Promise((resolve, reject) => {
        this.webpackServerWatcher.close(() => resolve())
      })
      promises.push(p)
    }
    if (this.pagesFilesWatcher) {
      this.pagesFilesWatcher.close()
    }
    return co(function * () {
      yield promises
    })
    .then(function () {
      if (typeof callback === 'function') callback()
    })
  }

}

module.exports = Nuxt
<|endoftext|>


<commit_before>var asyncMap = require('slide').asyncMap
var drompii = require('./drompii.js')
var upload = require('./upload.js')
var through = require('through2')
var D = require('./dombii.js')
var path = require('path')
var fs = require('fs')

var r = require('./router.js')
var _ = require('underscore')

var LOGIN = fs.readFileSync(__dirname + '/login.hogan', 'utf8')
var ERROR = fs.readFileSync(__dirname + '/error.hogan', 'utf8')
var OMNI = fs.readFileSync(__dirname + '/omni.hogan', 'utf8')
var GRIFTER = fs.readFileSync(__dirname + '/grifter.hogan', 'utf8')

module.exports = function Omni (opts) {
  var frameList = null
  var frame = null
  var svg = null
  var blob = {}
  var scale = 0.45
  function url () { return window.location.pathname.replace('/','') }

  var s = through.obj(IO)

  var db = r()
             .on('data', function (d) {  s.push(d) })

  if (!localStorage[opts.id]) {
    var dx = {x:10,y:10}
    localStorage[opts.id] = JSON.stringify({data:dx})
  } else
    var dx = JSON.parse(localStorage[opts.id]).data

  dx.lib = _.values(opts.lib)
  dx.cvs = (window.location.pathname==='/@'||window.location.pathname==='/')
    ? 'home'
    : window.location.pathname.replace('/','')

  var editor = new D({
    template : GRIFTER,
    parent : document.body,
    drag : true,
    events : [
      ['.grifter textarea', 'keyup', editOUT],
      ['.grifter textarea', 'keydown', editIN],
      ['.grifter .rm', 'click', function (e) {
        cancel(e); s.push('-'+blob.cuid); editor.erase()
      }],
      ['.grifter .reup', 'click', function (e) {
        cancel(e); s.push('!'+blob.cuid); editor.erase()
      }]
    ]
  })

  var err = new D({
    name : 'error',
    template : ERROR,
    parent : document.body,
    events : [
      ['span','click',function (e){e.preventDefault();err.erase()}]
    ]
  })

  var login = new D({
    name : 'login',
    id : opts.id,
    drag : true,
    template : LOGIN,
    parent : document.body,
    events : [['.login', 'submit', function (e) {
      e.preventDefault()
      s.push('+@edit '+e.target[0].value+'/'+opts.id)
      e.target[0].value = ''
    }]]
  })

  var omni = new D({
    name : 'omni',
    id : opts.id,
    drag : true,
    template : OMNI,
    parent : document.body,
    events : [
      ['.lib li','dragstart',dragModule],
      ['.blackbox input','keyup',blackbox],
      ['.canvasName','keyup',saveCanvas],
      [window,'contextmenu', grifter],
      ['.exit','click', function (e) { cancel(e);s.push('-@edit/'+opts.id) }]
    ]
  })

  // MODULE DRAG+DROP
  function dragModule (e) {
    cmd = '+'+e.target.innerHTML.split('')[1]
    e.dataTransfer.setData('cmd',cmd)
  }
  document.addEventListener('drop', function (e) { // symbols ◼ ψ
    cancel(e)
    cmd = null
    if (e.dataTransfer.files.length > 0) {
      upload(e, function (ndata) { }) // cmd = str // console.log(ndata) })
    } else cmd = e.dataTransfer.getData('cmd')
    if (cmd) s.push(cmd+'/'+opts.id)
    else return false
  },false)
  document.addEventListener('dragover', cancel, false)

  // LOGIN
  if (sessionStorage['edit'])
    s.push('+@edit '+sessionStorage['edit']+'/'+opts.id)

  // GLOBAL KEY SHORTCUTS
  window.addEventListener('keydown', function (e) {
    if (e.keyCode === 13 && e.ctrlKey) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault()
        if(!document.querySelector('.login')&&!document.querySelector('.omni')){
          login.draw(JSON.parse(localStorage[opts.id]).data)
          document.querySelector('.login input').focus()
        } else login.erase()
      }
    }
  })

  // EVENTS
  var lastModified
  function IO (d, enc, next) {  // USE MUXDEMUX HERE TOO!
    var self = this

    if (d.timestamp) console.log(d.timestamp)

    if (!lastModified && d.timestamp){ lastModified = d.timestamp; saveCanvas() }
    if (d.timestamp && d.timestamp !== lastModified) saveCanvas()

    db.write(d)

    if (d.code === 1) { // ERROR
      next()
      if (!login.data) login.draw(JSON.parse(localStorage[opts.id]).data)
      err.draw({x : login.data.x+8, y : login.data.y + 36, msg : d.message})
      _.delay(err.erase,2200)
      return null
    } else if (!d.key) { next(); return null }

    var tkn = (d.key.split(':').length > 1)
      ? d.key.split(':')[1]
      : d.key

    if (tkn && tkn === opts.id) { // smart routing or filtering carbuncle needed
      if (d.key.split(':')[0] === '@edit') { // LOGIN
        sessionStorage['edit'] = d.value
        login.erase()
        omni.draw(dx)
      } else if (d.value === '-edit') omni.erase() // LOGOUT
    }

    next()
  }

  function saveCanvas (e) {
    var c
    if (e && e.keyCode === 13) { // try to grab data first!
      cancel(e)
      dx.cvs = e.target.value
      db.get('?#'+e.target.value, function (d) {
        if (d instanceof Error) {
          s.push('+#'+e.target.value+'/'+opts.id)
          ps(e.target.value)
          e.target.blur()
        } else {
          s.push('!#'+e.target.value+'/'+opts.id)
          ps(e.target.value)
          e.target.blur()
        }
      })
    } else if (!e) {
      s.push('+#'+dx.cvs+'/'+opts.id)
    }
  }

  function blackbox (e) {
    var val = e.target.value
    if (e.keyCode === 13 || e.key === 'Enter') {
      e.preventDefault()
      e.target.value = ''
      s.push(val+'/'+opts.id)
    }
  }

  function grifter (e) {
    cancel(e)
    blob = {}

    editor.erase()

    var d = {
      x : e.clientX+window.pageXOffset,
      y : (e.clientY-20)+window.pageYOffset,
      props : []
    }

    if (e.target.className === 'canvasName') {
      d.props.push({key : '+copy', value : ''})
      editor.draw(d)
      return false
    } else if (e.target.tagName === 'HTML') {
      db.get('?$settings', function (d) { // use this to pull canvas!
        d.props = []
        d.type = 'canvas'
        d.props.push({key:'icon',value:'/files/1x1.png'})
        editor.draw(d)
      })
    } else {
      blob = drompii(e)

      if (!blob) return false

      _.each(blob.edit.value,function (v,k) {
        var prop = {key:k,value:v}
        d.props.push(prop)
      })

      d.name = blob.name
      d.cuid = blob.cuid
      d.rm = true
      d.reup = true
    }

    editor.draw(d)
  }

  function editOUT (e) { // some intelligent feedback / filtering
    var cmd

    var key = e.target.parentElement.children[1].innerHTML
    var val = e.target.value.replace(/[\n\r]/g,'')

    if (e.keyCode === 13) {
      if (key==='+copy') {
        var c = window.location.pathname.replace('/','')
        s.push('&#'+c+' '+val)
        editor.erase()
      } else {
        blob.data[key] = val
        s.push({key : '+$'+blob.cuid+'/'+opts.id, value:blob.data})
        editor.erase()
      }
    }
  }
  function editIN (e) { if (e.keyCode === 13) cancel(e) }

  function ps (link) {
    dx.cvs = link
    if (link==='home') link = '/'
    history.pushState({'cmd':'!#'+dx.cvs},'',link)
  }

  return s
}

function cancel (e) { e.preventDefault() }
<commit_msg>log data in<commit_after>var asyncMap = require('slide').asyncMap
var drompii = require('./drompii.js')
var upload = require('./upload.js')
var through = require('through2')
var D = require('./dombii.js')
var path = require('path')
var fs = require('fs')

var r = require('./router.js')
var _ = require('underscore')

var LOGIN = fs.readFileSync(__dirname + '/login.hogan', 'utf8')
var ERROR = fs.readFileSync(__dirname + '/error.hogan', 'utf8')
var OMNI = fs.readFileSync(__dirname + '/omni.hogan', 'utf8')
var GRIFTER = fs.readFileSync(__dirname + '/grifter.hogan', 'utf8')

module.exports = function Omni (opts) {
  var frameList = null
  var frame = null
  var svg = null
  var blob = {}
  var scale = 0.45
  function url () { return window.location.pathname.replace('/','') }

  var s = through.obj(IO)

  var db = r()
             .on('data', function (d) {  s.push(d) })

  if (!localStorage[opts.id]) {
    var dx = {x:10,y:10}
    localStorage[opts.id] = JSON.stringify({data:dx})
  } else
    var dx = JSON.parse(localStorage[opts.id]).data

  dx.lib = _.values(opts.lib)
  dx.cvs = (window.location.pathname==='/@'||window.location.pathname==='/')
    ? 'home'
    : window.location.pathname.replace('/','')

  var editor = new D({
    template : GRIFTER,
    parent : document.body,
    drag : true,
    events : [
      ['.grifter textarea', 'keyup', editOUT],
      ['.grifter textarea', 'keydown', editIN],
      ['.grifter .rm', 'click', function (e) {
        cancel(e); s.push('-'+blob.cuid); editor.erase()
      }],
      ['.grifter .reup', 'click', function (e) {
        cancel(e); s.push('!'+blob.cuid); editor.erase()
      }]
    ]
  })

  var err = new D({
    name : 'error',
    template : ERROR,
    parent : document.body,
    events : [
      ['span','click',function (e){e.preventDefault();err.erase()}]
    ]
  })

  var login = new D({
    name : 'login',
    id : opts.id,
    drag : true,
    template : LOGIN,
    parent : document.body,
    events : [['.login', 'submit', function (e) {
      e.preventDefault()
      s.push('+@edit '+e.target[0].value+'/'+opts.id)
      e.target[0].value = ''
    }]]
  })

  var omni = new D({
    name : 'omni',
    id : opts.id,
    drag : true,
    template : OMNI,
    parent : document.body,
    events : [
      ['.lib li','dragstart',dragModule],
      ['.blackbox input','keyup',blackbox],
      ['.canvasName','keyup',saveCanvas],
      [window,'contextmenu', grifter],
      ['.exit','click', function (e) { cancel(e);s.push('-@edit/'+opts.id) }]
    ]
  })

  // MODULE DRAG+DROP
  function dragModule (e) {
    cmd = '+'+e.target.innerHTML.split('')[1]
    e.dataTransfer.setData('cmd',cmd)
  }
  document.addEventListener('drop', function (e) { // symbols ◼ ψ
    cancel(e)
    cmd = null
    if (e.dataTransfer.files.length > 0) {
      upload(e, function (ndata) { }) // cmd = str // console.log(ndata) })
    } else cmd = e.dataTransfer.getData('cmd')
    if (cmd) s.push(cmd+'/'+opts.id)
    else return false
  },false)
  document.addEventListener('dragover', cancel, false)

  // LOGIN
  if (sessionStorage['edit'])
    s.push('+@edit '+sessionStorage['edit']+'/'+opts.id)

  // GLOBAL KEY SHORTCUTS
  window.addEventListener('keydown', function (e) {
    if (e.keyCode === 13 && e.ctrlKey) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault()
        if(!document.querySelector('.login')&&!document.querySelector('.omni')){
          login.draw(JSON.parse(localStorage[opts.id]).data)
          document.querySelector('.login input').focus()
        } else login.erase()
      }
    }
  })

  // EVENTS
  var lastModified
  function IO (d, enc, next) {  // USE MUXDEMUX HERE TOO!
    var self = this

    console.log(d)

    if (d.timestamp) console.log(d.timestamp)

    if (!lastModified && d.timestamp){ lastModified = d.timestamp; saveCanvas() }
    if (d.timestamp && d.timestamp !== lastModified) saveCanvas()

    db.write(d)

    if (d.code === 1) { // ERROR
      next()
      if (!login.data) login.draw(JSON.parse(localStorage[opts.id]).data)
      err.draw({x : login.data.x+8, y : login.data.y + 36, msg : d.message})
      _.delay(err.erase,2200)
      return null
    } else if (!d.key) { next(); return null }

    var tkn = (d.key.split(':').length > 1)
      ? d.key.split(':')[1]
      : d.key

    if (tkn && tkn === opts.id) { // smart routing or filtering carbuncle needed
      if (d.key.split(':')[0] === '@edit') { // LOGIN
        sessionStorage['edit'] = d.value
        login.erase()
        omni.draw(dx)
      } else if (d.value === '-edit') omni.erase() // LOGOUT
    }

    next()
  }

  function saveCanvas (e) {
    var c
    if (e && e.keyCode === 13) { // try to grab data first!
      cancel(e)
      dx.cvs = e.target.value
      db.get('?#'+e.target.value, function (d) {
        if (d instanceof Error) {
          s.push('+#'+e.target.value+'/'+opts.id)
          ps(e.target.value)
          e.target.blur()
        } else {
          s.push('!#'+e.target.value+'/'+opts.id)
          ps(e.target.value)
          e.target.blur()
        }
      })
    } else if (!e) {
      s.push('+#'+dx.cvs+'/'+opts.id)
    }
  }

  function blackbox (e) {
    var val = e.target.value
    if (e.keyCode === 13 || e.key === 'Enter') {
      e.preventDefault()
      e.target.value = ''
      s.push(val+'/'+opts.id)
    }
  }

  function grifter (e) {
    cancel(e)
    blob = {}

    editor.erase()

    var d = {
      x : e.clientX+window.pageXOffset,
      y : (e.clientY-20)+window.pageYOffset,
      props : []
    }

    if (e.target.className === 'canvasName') {
      d.props.push({key : '+copy', value : ''})
      editor.draw(d)
      return false
    } else if (e.target.tagName === 'HTML') {
      db.get('?$settings', function (d) { // use this to pull canvas!
        d.props = []
        d.type = 'canvas'
        d.props.push({key:'icon',value:'/files/1x1.png'})
        editor.draw(d)
      })
    } else {
      blob = drompii(e)

      if (!blob) return false

      _.each(blob.edit.value,function (v,k) {
        var prop = {key:k,value:v}
        d.props.push(prop)
      })

      d.name = blob.name
      d.cuid = blob.cuid
      d.rm = true
      d.reup = true
    }

    editor.draw(d)
  }

  function editOUT (e) { // some intelligent feedback / filtering
    var cmd

    var key = e.target.parentElement.children[1].innerHTML
    var val = e.target.value.replace(/[\n\r]/g,'')

    if (e.keyCode === 13) {
      if (key==='+copy') {
        var c = window.location.pathname.replace('/','')
        s.push('&#'+c+' '+val)
        editor.erase()
      } else {
        blob.data[key] = val
        s.push({key : '+$'+blob.cuid+'/'+opts.id, value:blob.data})
        editor.erase()
      }
    }
  }
  function editIN (e) { if (e.keyCode === 13) cancel(e) }

  function ps (link) {
    dx.cvs = link
    if (link==='home') link = '/'
    history.pushState({'cmd':'!#'+dx.cvs},'',link)
  }

  return s
}

function cancel (e) { e.preventDefault() }
<|endoftext|>


<commit_before>var asyncMap = require('slide').asyncMap
var drompii = require('./drompii.js')
var pjs = require('./paper-core.js')
var upload = require('./upload.js')
var through = require('through2')
var D = require('./dombii.js')
var path = require('path')
var fs = require('fs')

var r = require('./router.js')
var _ = require('underscore')

var LOGIN = fs.readFileSync(__dirname + '/login.hogan', 'utf8')
var ERROR = fs.readFileSync(__dirname + '/error.hogan', 'utf8')
var OMNI = fs.readFileSync(__dirname + '/omni.hogan', 'utf8')
var GRIFTER = fs.readFileSync(__dirname + '/grifter.hogan', 'utf8')

module.exports = function Omni (opts) {
  var frameList = null
  var frame = null
  var svg = null
  var blob
  var metaBlob
  var scale = 0.45

  function url () {
    return window.location.pathname.replace('/','')
  }

  var s = through.obj(IO)

  var db = r()
             .on('data', function (d) {  s.push(d) })

  if (!localStorage[opts.id]) {
    var dx = {x : 10, y : 10}
    localStorage[opts.id] = JSON.stringify({data:dx})
  } else
    var dx = JSON.parse(localStorage[opts.id]).data

  dx.showSettings = false
  dx.lib = _.values(opts.lib)
  dx.cvs = (window.location.pathname==='/@'||window.location.pathname==='/')
    ? 'home'
    : window.location.pathname.replace('/','')

  var editor = new D({
    template : GRIFTER,
    name : 'grifter',
    parent : document.body,
    drag : true,
    events : [
      ['.tags','keydown',editIN],
      ['.tags','keyup',editOUT],
      ['.grifter textarea', 'keyup', editOUT],
      ['.grifter textarea', 'keydown', editIN],
      ['.grifter .del', 'click', function (e) {
        cancel(e); s.push('-'+blob.cuid); editor.erase()
      }],
      ['.grifter .reset', 'click', function (e) {
        cancel(e); s.push('!'+blob.cuid); editor.erase()
      }]
    ]
  })

  var err = new D({
    name : 'error',
    template : ERROR,
    parent : document.body,
    events : [
      ['span','click', function (e) { e.preventDefault(); err.erase() } ]
    ]
  })

  var login = new D({
    name : 'login',
    id : opts.id,
    drag : true,
    template : LOGIN,
    parent : document.body,
    events : [['.login', 'submit', function (e) {
      e.preventDefault()
      s.push('+@edit '+e.target[0].value+'/'+opts.id)
      e.target[0].value = ''
    }]]
  })

  var omni = new D({
    name : 'omni',
    id : opts.id,
    drag : true,
    template : OMNI,
    parent : document.body,
    events : [
      ['.lib li','dragstart',dragModule],
      ['.settings input','keyup',updateSettings],
      ['.file','click',toggleSettings],
      ['.blackbox input','keyup',blackbox],
      ['.canvasName','keyup',saveCanvas],
      [window,'contextmenu', grifter],
      ['.exit','click', function (e) { cancel(e);s.push('-@edit/'+opts.id) }]
    ]
  })

  function toggleSettings (e) {
    cancel(e)
    var el = e.target
    if (!dx.showSettings) db.get('?$settings', function (e,d) {
      dx.showSettings = true
      dx.title = d.title
      dx.favicon = d.favicon
      omni.draw(dx)
      el.style.background = '#CBD4DD'
      blob = {
        cuid : 'settings',
        edit : { key : 'favicon' },
        data : d
      }
    })
    if (dx.showSettings) {
      dx.showSettings = false
      omni.draw(dx)
      el.style.background = 'transparent'
    }
  }

  function updateSettings (e) {
    if (e.keyCode === 13) {
      cancel(e)
      var type = e.target.className

      if (type==='save') {
        s.push('+#'+e.target.value)
        return false
      }
      if (type==='new') {
        s.push({key:'+$settings',value:nd});
        return false
      } if (type==='title' || type==='favicon') {
        blob.data[type] = e.target.value
        console.log(blob)
        s.push({key:'+$settings',value:blob.data})
      }
    }
  }

  function dragModule (e) {
    cmd = '+'+e.target.innerHTML.split('')[1]
    e.dataTransfer.setData('cmd',cmd)
  }
  document.addEventListener('drop', function (e) { // symbols ◼ ψ
    cancel(e)
    cmd = null
    if (e.dataTransfer.files.length > 0) {
      editor.erase()
      upload(e, blob, function (d) {
        if (d.cuid==='settings'&&dx.showSettings) {
          dx.favicon = d.data.favicon
          dx.title = d.data.title
          omni.draw(dx)
        }
        updateData()
      })
    } else cmd = e.dataTransfer.getData('cmd')
    if (cmd) s.push(cmd+'/'+opts.id)
    else return false
  },false)
  document.addEventListener('dragover', cancel, false)

  if (sessionStorage['edit']) // LOGIN
    s.push('+@edit '+sessionStorage['edit']+'/'+opts.id)

  window.addEventListener('keydown', function (e) { // KEYS
    if (e.keyCode === 13 && e.ctrlKey) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault()
        if(!document.querySelector('.login')&&!document.querySelector('.omni')){
          login.draw(JSON.parse(localStorage[opts.id]).data)
          document.querySelector('.login input').focus()
        } else login.erase()
      }
    }
  })

  function pjsInit () {
    pjs.setup(document.querySelector('.bones'))

    var LtabBG = new pjs.Path([
      [0,0],
      [0,15],
      [130,15],
      [115,0]
    ])
    var LtabTXT = new pjs.PointText({
      point : [0,0],
      content : 'Pallette',
      fontFamily : 'Andale Mono',
      fontSize : 10,
      opacity : 0.75
    })
    var Ltab = new pjs.Group([LtabBG,LtabTXT])
    var Rtab = Ltab.clone()

    Ltab.children[1].position = tabCenter(Ltab)

    Rtab.children[0].segments = [
      [85,0],
      [70,15],
      [200,15],
      [200,0]
    ]
    Rtab.children[1].content = 'Skeleton'
    Rtab.children[1].position = tabCenter(Rtab)

    Ltab.onClick = function (e) {tablle(Ltab)}
    Rtab.onClick = function (e) {tablle(Rtab)}

    function tabCenter (group) {
      var segs = group.children[0].segments
      var x = ((segs[2].point.x - segs[1].point.x)/2) + segs[1].point.x
      var y = segs[1].point.y/2
      return [x,y]
    }

    function tablle (group) {
      var selected, unselected

      if (group.children[1].content === 'Skeleton') {
        selected = Rtab
        unselected = Ltab
        document.querySelector('.omni .lib').style.display = 'none'
      } else {
        selected = Ltab
        unselected = Rtab
        document.querySelector('.omni .lib').style.display = 'block'
      }

      selected.children[0].fillColor = '#EBEEFB'
      selected.children[1].fillColor = 'black'
      unselected.children[0].fillColor = '#CBD5DF'
      unselected.children[1].fillColor = '#333'
      selected.bringToFront()
      pjs.view.draw()
    }

    tablle(Ltab)
  }

  var lastModified

  function IO (d, enc, next) {
    var self = this

    if (d.cmd && typeof d.cmd === 'string' && d.cmd.slice(0,2)==='!#')
      if (document.querySelector('.omni')) {
        dx.cvs = d.cmd.slice(2).split('/')[0]
        omni.draw(dx)
      }

    if (!lastModified && d.timestamp){lastModified = d.timestamp;saveCanvas()}
    if (d.timestamp && d.timestamp !== lastModified) saveCanvas()

    db.write(d)

    if (d.code === 1) { // ERROR
      next()

      if (!login.data)
        login.draw(JSON.parse(localStorage[opts.id]).data)

      err.draw({x : login.data.x+8, y : login.data.y + 36, msg : d.message})

      _.delay(err.erase,2200)

      return null
    } else if (!d.key) { next(); return null }

    var tkn = (d.key.split(':').length > 1)
      ? d.key.split(':')[1]
      : d.key

    if (tkn && tkn === opts.id) {
      if (d.key.split(':')[0] === '@edit') {
        sessionStorage['edit'] = d.value
        login.erase()
        omni.draw(dx, pjsInit)
        document.body.className = 'edit'
      } else if (d.value==='-edit') {omni.erase(); document.body.className=''}
    }

    next()
  }

  function saveCanvas (e) {
    var c
    if (e && e.keyCode === 13) {
      cancel(e)
      dx.cvs = e.target.value
      db.get('?#'+e.target.value, function (e, d) {
        if (d instanceof Error) {
          s.push('+#'+e.target.value+'/'+opts.id)
          openUrl.write('/'+e.target.value)
          e.target.blur()
        } else {
          openUrl.write('/'+e.target.value)
          e.target.blur()
        }
      })
    } else if (!e) {
      s.push('+#'+dx.cvs+'/'+opts.id)
    }
  }

  function blackbox (e) {
    var val = e.target.value
    if (e.keyCode === 13 || e.key === 'Enter') {
      e.preventDefault()
      e.target.value = ''
      s.push(val+'/'+opts.id)
    }
  }

  function grifter (e) {
    cancel(e)
    blob = {}
    metaBlob = {}

    editor.erase()

    var d = {
      x : e.clientX+window.pageXOffset,
      y : (e.clientY-20)+window.pageYOffset,
      props : []
    }

    if (e.target.className !== 'canvasName' || e.target.tagName !== 'HTML') {
      blob = drompii(e)

      if (!blob) return false

      if (typeof blob.edit.index === 'number') {
        for (p in blob.edit.value) {
          var prop = {key:p,value:blob.edit.value[p]}
          d.props.push(prop)
        }
      } else d.props.push(blob.edit)

      d.name = blob.name
      d.cuid = blob.cuid
      d.tags = metaBlob.tags

      db.get('?~'+blob.cuid, function (e, data) {
        console.log(e)
        console.log(data)
        if (!e) { metaBlob = data; d.tags = metaBlob.tags }
        editor.draw(d)
      })
    }

  }

  function editOUT (e) { // some intelligent feedback / filtering
    var cmd

    var key = e.target.parentElement.children[1].innerHTML
    var val = e.target.value.replace(/[\n\r]/g,'')

    if (e.keyCode === 13) {
      cancel(e)
      if (key === 'tags') {
        metaBlob.tags = val
        updateData(true)
        editor.erase()
      } else {
        if (typeof blob.edit.index === 'number') {
          blob.data[blob.edit.key][blob.edit.index][key] = val
        } else blob.data[key] = val
        updateData()
        editor.erase()
      }
    }
  }

  function editIN (e) { if (e.keyCode === 13) cancel(e) }

  function updateData (pip) {
    metaBlob.freshness = new Date().getTime()
    metaBlob.name = blob.name
    if (!pip) s.push({key:'+$'+blob.cuid+'/'+opts.id,value:blob.data})
    s.push({key:'+~'+blob.cuid+'/'+opts.id,value:metaBlob})
  }

  return s
}

function cancel (e) { e.preventDefault() }
<commit_msg>rough skeleton scaling<commit_after>var asyncMap = require('slide').asyncMap
var drompii = require('./drompii.js')
var pjs = require('./paper-core.js')
var upload = require('./upload.js')
var through = require('through2')
var D = require('./dombii.js')
var path = require('path')
var fs = require('fs')

var r = require('./router.js')
var _ = require('underscore')

var LOGIN = fs.readFileSync(__dirname + '/login.hogan', 'utf8')
var ERROR = fs.readFileSync(__dirname + '/error.hogan', 'utf8')
var OMNI = fs.readFileSync(__dirname + '/omni.hogan', 'utf8')
var GRIFTER = fs.readFileSync(__dirname + '/grifter.hogan', 'utf8')

module.exports = function Omni (opts) {
  var frameList = null
  var frame = null
  var svg = null
  var blob
  var metaBlob
  var scale = 0.45

  function url () {
    return window.location.pathname.replace('/','')
  }

  var s = through.obj(IO)

  var db = r()
             .on('data', function (d) {  s.push(d) })

  if (!localStorage[opts.id]) {
    var dx = {x : 10, y : 10}
    localStorage[opts.id] = JSON.stringify({data:dx})
  } else
    var dx = JSON.parse(localStorage[opts.id]).data

  dx.showSettings = false
  dx.lib = _.values(opts.lib)
  dx.cvs = (window.location.pathname==='/@'||window.location.pathname==='/')
    ? 'home'
    : window.location.pathname.replace('/','')

  var editor = new D({
    template : GRIFTER,
    name : 'grifter',
    parent : document.body,
    drag : true,
    events : [
      ['.tags','keydown',editIN],
      ['.tags','keyup',editOUT],
      ['.grifter textarea', 'keyup', editOUT],
      ['.grifter textarea', 'keydown', editIN],
      ['.grifter .del', 'click', function (e) {
        cancel(e); s.push('-'+blob.cuid); editor.erase()
      }],
      ['.grifter .reset', 'click', function (e) {
        cancel(e); s.push('!'+blob.cuid); editor.erase()
      }]
    ]
  })

  var err = new D({
    name : 'error',
    template : ERROR,
    parent : document.body,
    events : [
      ['span','click', function (e) { e.preventDefault(); err.erase() } ]
    ]
  })

  var login = new D({
    name : 'login',
    id : opts.id,
    drag : true,
    template : LOGIN,
    parent : document.body,
    events : [['.login', 'submit', function (e) {
      e.preventDefault()
      s.push('+@edit '+e.target[0].value+'/'+opts.id)
      e.target[0].value = ''
    }]]
  })

  var omni = new D({
    name : 'omni',
    id : opts.id,
    drag : true,
    template : OMNI,
    parent : document.body,
    events : [
      ['.lib li','dragstart',dragModule],
      ['.settings .favicon','keyup',updateSettings],
      ['.settings .title','keyup',updateSettings],
      ['.settings .save','keyup',saveCanvas],
      ['.file','click',toggleSettings],
      ['.blackbox input','keyup',blackbox],
      ['.canvasName','keyup',saveCanvas],
      [window,'contextmenu', grifter],
      ['.exit','click', function (e) { cancel(e);s.push('-@edit/'+opts.id) }]
    ]
  })

  function toggleSettings (e) {
    cancel(e)
    var el = e.target
    if (!dx.showSettings) db.get('?$settings', function (e,d) {
      dx.showSettings = true
      dx.title = d.title
      dx.favicon = d.favicon
      omni.draw(dx)
      el.style.background = '#CBD4DD'
      blob = {
        cuid : 'settings',
        edit : { key : 'favicon' },
        data : d
      }
    })
    if (dx.showSettings) {
      dx.showSettings = false
      omni.draw(dx)
      el.style.background = 'transparent'
    }
  }

  function updateSettings (e) {
    if (e.keyCode === 13) {
      cancel(e)
      var type = e.target.className
      blob.data[type] = e.target.value
      if (type==='title' || type==='favicon')
        s.push({key:'+$settings',value:blob.data})
    }
  }

  function dragModule (e) {
    cmd = '+'+e.target.innerHTML.split('')[1]
    e.dataTransfer.setData('cmd',cmd)
  }
  document.addEventListener('drop', function (e) { // symbols ◼ ψ
    cancel(e)
    cmd = null
    if (e.dataTransfer.files.length > 0) {
      editor.erase()
      upload(e, blob, function (d) {
        if (d.cuid==='settings'&&dx.showSettings) {
          dx.favicon = d.data.favicon
          dx.title = d.data.title
          omni.draw(dx)
        }
        updateData()
      })
    } else cmd = e.dataTransfer.getData('cmd')
    if (cmd) s.push(cmd+'/'+opts.id)
    else return false
  },false)
  document.addEventListener('dragover', cancel, false)

  if (sessionStorage['edit']) // LOGIN
    s.push('+@edit '+sessionStorage['edit']+'/'+opts.id)

  window.addEventListener('keydown', function (e) { // KEYS
    if (e.keyCode === 13 && e.ctrlKey) {
      if (e.ctrlKey || e.metaKey) {
        e.preventDefault()
        if(!document.querySelector('.login')&&!document.querySelector('.omni')){
          login.draw(JSON.parse(localStorage[opts.id]).data)
          document.querySelector('.login input').focus()
        } else login.erase()
      }
    }
  })

  function pjsInit () {
    pjs.setup(document.querySelector('.bones'))

    var LtabBG = new pjs.Path([
      [0,0],
      [0,15],
      [130,15],
      [115,0]
    ])
    var LtabTXT = new pjs.PointText({
      point : [0,0],
      content : 'Pallette',
      fontFamily : 'Andale Mono',
      fontSize : 10,
      opacity : 0.75
    })
    var Ltab = new pjs.Group([LtabBG,LtabTXT])
    var Rtab = Ltab.clone()

    Ltab.children[1].position = tabCenter(Ltab)

    Rtab.children[0].segments = [
      [85,0],
      [70,15],
      [200,15],
      [200,0]
    ]
    Rtab.children[1].content = 'Skeleton'
    Rtab.children[1].position = tabCenter(Rtab)

    Ltab.onClick = function (e) {tablle(Ltab)}
    Rtab.onClick = function (e) {tablle(Rtab)}

    var skeleton

    function pageHeight () {
      return  Math.max(
        document.body.scrollHeight,
        document.body.offsetHeight,
        document.documentElement.clientHeight,
        document.documentElement.scrollHeight,
        document.documentElement.offsetHeight
      )
    }

    function pageWidth () {
      return  Math.max(
        document.body.scrollWidth,
        document.body.offsetWidth,
        document.documentElement.clientWidth,
        document.documentElement.scrollWidth,
        document.documentElement.offsetWidth
      )
    }

    function drawSkeleton () {
      var scaleX = pjs.view.bounds.width/pageWidth()
      var scaleY = (pjs.view.bounds.height-15)/pageHeight()//15=tabHeight

      if (skeleton) skeleton.remove()

      skeleton = new pjs.Layer({
        position : [0.0]
      })

      var bg = new pjs.Shape.Rectangle({
        point : [4, 20],
        size : [192, 100],
        fillColor : 'rgba(255,255,255,0.5)'
      })

      var Xoff = window.innerWidth/bg.bounds.width
      var Yoff = window.innerHeight/bg.bounds.height

      skeleton.addChild(bg)

      skeleton.visible = true
      _.each(frame, function (v,k) {
        var el = document.getElementById(k).firstChild
        // var dim = [el.offsetWidth,el.offsetHeight]
        var pos = [
          (el.offsetLeft+(el.offsetWidth/2))*scaleX,
          (el.offsetTop+(el.offsetHeight/2))*scaleY
        ]

        console.log(pos)

        var m = new pjs.Shape.Circle({
          center : pos,
          radius : 10,
          fillColor : 'red',
          strokeWidth : 0
        })
        skeleton.addChild(m)
      })
      pjs.view.draw()
    }

    function scrollSkeleton (e) {

    }

    window.onscroll = scrollSkeleton

    window.s = skeleton
    window.pjs = pjs

    function tabCenter (group) {
      var segs = group.children[0].segments
      var x = ((segs[2].point.x - segs[1].point.x)/2) + segs[1].point.x
      var y = segs[1].point.y/2
      return [x,y]
    }

    function tablle (group) {
      var selected, unselected

      if (group.children[1].content === 'Skeleton') {
        selected = Rtab
        unselected = Ltab
        document.querySelector('.omni .lib').style.display = 'none'
        drawSkeleton()
      } else {
        selected = Ltab
        unselected = Rtab
        document.querySelector('.omni .lib').style.display = 'block'
        skeleton.visible = false
      }

      selected.children[0].fillColor = '#EBEEFB'
      selected.children[1].fillColor = 'black'
      unselected.children[0].fillColor = '#CBD5DF'
      unselected.children[1].fillColor = '#333'
      selected.bringToFront()
      pjs.view.draw()
    }

    tablle(Rtab)
  }

  var lastModified

  function IO (d, enc, next) {
    var self = this

    if (d.cmd && d.cmd[1]==='#') frame = d.value

    if (d.cmd && typeof d.cmd === 'string' && d.cmd.slice(0,2)==='!#')
      if (document.querySelector('.omni')) {
        dx.cvs = d.cmd.slice(2).split('/')[0]
        omni.draw(dx)
      }

    if (!lastModified && d.timestamp){lastModified = d.timestamp;saveCanvas()}
    if (d.timestamp && d.timestamp !== lastModified) saveCanvas()

    db.write(d)

    if (d.code === 1) { // ERROR
      next()

      if (!login.data)
        login.draw(JSON.parse(localStorage[opts.id]).data)

      err.draw({x : login.data.x+8, y : login.data.y + 36, msg : d.message})

      _.delay(err.erase,2200)

      return null
    } else if (!d.key) { next(); return null }

    var tkn = (d.key.split(':').length > 1)
      ? d.key.split(':')[1]
      : d.key

    if (tkn && tkn === opts.id) {
      if (d.key.split(':')[0] === '@edit') {
        sessionStorage['edit'] = d.value
        login.erase()
        omni.draw(dx, pjsInit)
        document.body.className = 'edit'
      } else if (d.value==='-edit') {
        omni.erase()
        grifter.erase()
        document.body.className=''
      }
    }

    next()
  }

  function saveCanvas (e) {
    var c
    if (e && e.keyCode === 13) {
      cancel(e)
      dx.cvs = e.target.value
      db.get('?#'+e.target.value, function (err, d) {
        if (err) {
          s.push('+#'+e.target.value+'/'+opts.id)
          openUrl.write('/'+e.target.value)
          e.target.blur()
        } else {
          openUrl.write('/'+e.target.value)
          e.target.blur()
        }
      })
    } else if (!e) {
      s.push('+#'+dx.cvs+'/'+opts.id)
    }
  }

  function blackbox (e) {
    var val = e.target.value
    if (e.keyCode === 13 || e.key === 'Enter') {
      e.preventDefault()
      e.target.value = ''
      s.push(val+'/'+opts.id)
    }
  }

  function grifter (e) {
    cancel(e)
    blob = {}
    metaBlob = {}

    editor.erase()

    var d = {
      x : e.clientX+window.pageXOffset,
      y : (e.clientY-20)+window.pageYOffset,
      props : []
    }

    if (e.target.className !== 'canvasName' || e.target.tagName !== 'HTML') {
      blob = drompii(e)

      if (!blob) return false

      if (typeof blob.edit.index === 'number') {
        for (p in blob.edit.value) {
          var prop = {key:p,value:blob.edit.value[p]}
          d.props.push(prop)
        }
      } else d.props.push(blob.edit)

      d.name = blob.name
      d.cuid = blob.cuid
      d.tags = metaBlob.tags

      db.get('?~'+blob.cuid, function (e, data) {
        console.log(e)
        console.log(data)
        if (!e) { metaBlob = data; d.tags = metaBlob.tags }
        editor.draw(d)
      })
    }

  }

  function editOUT (e) { // some intelligent feedback / filtering
    var cmd

    var key = e.target.parentElement.children[1].innerHTML
    var val = e.target.value.replace(/[\n\r]/g,'')

    if (e.keyCode === 13) {
      cancel(e)
      if (key === 'tags') {
        metaBlob.tags = val
        updateData(true)
        editor.erase()
      } else {
        if (typeof blob.edit.index === 'number') {
          blob.data[blob.edit.key][blob.edit.index][key] = val
        } else blob.data[key] = val
        updateData()
        editor.erase()
      }
    }
  }

  function editIN (e) { if (e.keyCode === 13) cancel(e) }

  function updateData (pip) {
    metaBlob.freshness = new Date().getTime()
    metaBlob.name = blob.name
    if (!pip) s.push({key:'+$'+blob.cuid+'/'+opts.id,value:blob.data})
    s.push({key:'+~'+blob.cuid+'/'+opts.id,value:metaBlob})
  }

  return s
}

function cancel (e) { e.preventDefault() }
<|endoftext|>