diff --git a/sheetnode.css b/sheetnode.css
deleted file mode 100644
index 55b61bd..0000000
--- a/sheetnode.css
+++ /dev/null
@@ -1,70 +0,0 @@
-
-.sheetview {
-  padding-top: 10px;
-  margin-bottom: 30px;
-}
-
-.sheetview table, 
-.sheetview table tr, 
-.sheetview table tr td, 
-.sheetview table tr th {
-  padding: 0;
-  margin: 0;
-  line-height: normal;
-  border-width: 0;
-  border-top: 0;
-  border-left: 0;
-  border-right: 0;
-  border-bottom: 0;
-  border-collapse: separate;
-  width: auto;
-  background: transparent;
-  vertical-align: top;
-}
-
-.sheetview img {
-  display: inline !important;
-}
-
-.sheetview input {
-  display: inline !important;
-  width: auto !important;
-}
-
-.sheetview #te_griddiv {
-  background-image: url('images/stripe.png');
-}
-
-.sheetview #te_griddiv table {
-  background: #fff;
-}
-
-.sheetview-fullscreen {
-  display: block;
-  position: absolute;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  z-index: 9999;
-  margin: 0;
-  padding: 0;
-  background: inherit;
-}
-
-body:last-child .sheetview .defaultPeer {
-    border-collapse: separate;
-    filter: none;
-}
-
-.sheetview .defaultPeer {
-    box-shadow: inset 0 0 0 2px blue;
-    -webkit-box-shadow: inset 0 0 0 2px blue;
-    -moz-box-shadow: inset 0 0 0 2px blue;
-    *background: white;
-    filter: progid:DXImageTransform.Microsoft.DropShadow(OffX=1, OffY=1, Color=#0000ff),
-            progid:DXImageTransform.Microsoft.DropShadow(OffX=-1, OffY=1, Color=#0000ff),
-            progid:DXImageTransform.Microsoft.DropShadow(OffX=1, OffY=-1, Color=#0000ff),
-            progid:DXImageTransform.Microsoft.DropShadow(OffX=-1, OffY=-1, Color=#0000ff),
-            progid:DXImageTransform.Microsoft.Chroma(Color=#FFFFFF);
-}
diff --git a/sheetnode.info b/sheetnode.info
index bb85813..70fc6c0 100644
--- a/sheetnode.info
+++ b/sheetnode.info
@@ -5,7 +5,7 @@ core = 7.x
 configure = admin/config/content/sheetnode
 
 stylesheets[all][] = socialcalc/socialcalc.css
-stylesheets[all][] = sheetnode.css
+stylesheets[all][] = css/sheetnode.css
 
 files[] = views/sheetnode_handler_field_cell.inc
 files[] = views/sheetnode_handler_field_range.inc
diff --git a/sheetnode.js b/sheetnode.js
deleted file mode 100644
index bbf21dc..0000000
--- a/sheetnode.js
+++ /dev/null
@@ -1,429 +0,0 @@
-(function ($) {
-// START jQuery
-
-Drupal.behaviors.sheetnode = {
-  attach: function(context, settings) {
-    // Abort early if sheetnode settings not in place (which happens in case of Views style settings).
-    if (typeof(settings.sheetnode) == 'undefined') return;
-
-    $(".sheetview", context).not(".sheetview-processed").each(function() {
-      if (typeof(settings.sheetnode[$(this).attr('id')]) != 'undefined') {
-        Drupal.sheetnode.sheetviews.push(new Drupal.sheetnode(settings.sheetnode[$(this).attr('id')], this, context));
-      }
-    });
-  }
-}
-
-Drupal.sheetnode = function(settings, container, context) {
-  this.settings = settings;
-  this.$container = $(container);
-  this.context = context;
-  var self = this;
-  window.setTimeout(function(){ self.start(); }, 1);
-}
-
-Drupal.sheetnode.sheetviews = [];
-
-Drupal.sheetnode.prototype.functionsSetup = function() {
-  // Abort if we were already here.
-  if (typeof(SocialCalc.Formula.FunctionList["ORG.DRUPAL.FIELD"]) != 'undefined') return;
-
-  var self = this;
-
-  // ORG.DRUPAL.FIELD server-side function.
-  SocialCalc.Formula.FunctionList["ORG.DRUPAL.FIELD"] = [function(fname, operand, foperand, sheet) {
-    var scf = SocialCalc.Formula;
-    var oid, entity_type, field;
-
-    field = scf.OperandValueAndType(sheet, foperand);
-    oid = scf.OperandValueAndType(sheet, foperand);
-    entity_type = scf.OperandValueAndType(sheet, foperand);
-    if (isNaN(parseInt(oid.value))) {
-      oid.value = self.settings.context['oid'];
-      entity_type.value = self.settings.context['entity-type'];
-    }
-
-    $.ajax({
-      type: 'POST',
-      url: Drupal.settings.basePath+'sheetnode/field',
-      data: {
-        oid: oid.value,
-        entity_type: entity_type.value,
-        field: field.value
-      },
-      dataType: 'json',
-      async: false,
-      success: function (data) {
-        operand.push(data);
-      }
-    });
-  }, -1, "drupalfield", "", "drupal"];
-  SocialCalc.Constants["s_fdef_ORG.DRUPAL.FIELD"] = 'Returns a field from the specified Drupal entity (node, user, etc.)';
-  SocialCalc.Constants.s_farg_drupalfield = 'field-name, [oid, entity-type]';
-
-  // ORG.DRUPAL.TOKEN server-side function.
-  SocialCalc.Formula.FunctionList["ORG.DRUPAL.TOKEN"] = [function(fname, operand, foperand, sheet) {
-    var scf = SocialCalc.Formula;
-    var oid, entity_type, token;
-
-    token = scf.OperandValueAndType(sheet, foperand);
-    oid = scf.OperandValueAndType(sheet, foperand);
-    entity_type = scf.OperandValueAndType(sheet, foperand);
-    if (isNaN(parseInt(oid.value))) {
-      oid.value = self.settings.context['oid'];
-      entity_type.value = self.settings.context['entity-type'];
-    }
-
-    $.ajax({
-      type: 'POST',
-      url: Drupal.settings.basePath+'sheetnode/token',
-      data: {
-        oid: oid.value,
-        entity_type: entity_type.value,
-        token: token.value
-      },
-      dataType: 'json',
-      async: false,
-      success: function (data) {
-        operand.push(data);
-      }
-    });
-  }, -1, "drupaltoken", "", "drupal"];
-  SocialCalc.Constants["s_fdef_ORG.DRUPAL.TOKEN"] = 'Returns a token value from the specified Drupal entity (node, user, etc.)';
-  SocialCalc.Constants.s_farg_drupaltoken = 'token, [oid, entity-type]';
-
-  // ORG.DRUPAL.URLQUERY client-side function.
-  SocialCalc.Formula.FunctionList["ORG.DRUPAL.PARSEURL"] = [function(fname, operand, foperand, sheet) {
-    var scf = SocialCalc.Formula;
-    var key = scf.OperandValueAndType(sheet, foperand);
-    var parse = parseUri(location.href);
-    var PushOperand = function(t, v) {operand.push({type: t, value: v});};
-    if (typeof(parse.queryKey[key.value]) == 'undefined') {
-      PushOperand("e#VALUE!", 0);
-    }
-    else {
-      PushOperand(isNaN(parseInt(parse.queryKey[key.value])) ? 't' : 'n', parse.queryKey[key.value]);
-    }
-  }, 1, "drupalparseurl", "", "drupal"];
-  SocialCalc.Constants["s_fdef_ORG.DRUPAL.PARSEURL"] = 'Returns the value of a key in the current URL query string.';
-  SocialCalc.Constants.s_farg_drupalparseurl = 'key';
-
-  // Update function classes.
-  SocialCalc.Constants.function_classlist.push('drupal');
-  SocialCalc.Constants.s_fclass_drupal = "Drupal";
-}
-
-Drupal.sheetnode.prototype.loadsheetSetup = function() {
-  var self = this;
-  SocialCalc.RecalcInfo.LoadSheet = function(sheetname) {
-    var found = false;
-
-    // Avoid returning this sheet.
-    if (self.settings.aliases.indexOf(sheetname) != -1) {
-      // TODO: Should really return true and inform SocialCalc that this is the same sheet.
-      // However SocialCalc does not support aliases currently.
-      return false;
-    }
-
-    // First examine on-screen spreadsheets.
-    $.each(Drupal.sheetnode.sheetviews, function(index, sheetnode) {
-      if (sheetnode.settings.aliases.indexOf(sheetname) != -1) {
-        var data = sheetnode.spreadsheet.CreateSpreadsheetSave();
-        var parts = sheetnode.spreadsheet.DecodeSpreadsheetSave(data);
-        if (parts.sheet) {
-          data = data.substring(parts.sheet.start, parts.sheet.end);
-          SocialCalc.RecalcLoadedSheet(sheetname, data, false, true);
-          found = true;
-        }
-      }
-    });
-    if (found) return true;
-
-    // Next call backend to find the reference.
-    data = $.ajax({
-      type: 'POST',
-      url: Drupal.settings.basePath+'sheetnode/load',
-      data: {
-        sheetname: sheetname
-      },
-      dataType: 'text',
-      async: false
-    }).responseText;
-    if (data !== null) {
-      SocialCalc.RecalcLoadedSheet(sheetname, data, true);
-      found = true;
-    }
-
-    return found;
-  }
-}
-
-Drupal.sheetnode.prototype.focusSetup = function() {
-  $(document.body).delegate('.form-text:not(.socialcalc-input),.form-textarea:not(.socialcalc-input),.form-select:not(.socialcalc-input)', 'focus', function(e) {
-    SocialCalc.CmdGotFocus(this);
-  });
-}
-
-Drupal.sheetnode.prototype.callbackSetup = function() {
-  var self = this;
-  this.spreadsheet.editor.StatusCallback.sheetnode = {
-    func: function(editor, status, arg, params) {
-      if (status == 'calcfinished') {
-        if (!self.settings.saveElement && self.settings.viewMode == Drupal.sheetnode.viewModes.htmlTable) {
-          self.$container.html(SocialCalc.SpreadsheetViewerCreateSheetHTML(self.spreadsheet));
-        }
-      }
-      if (status == 'doneposcalc' && self.settings.saveElement) {
-        window.setTimeout(function() {
-          $('#'+self.settings.saveElement, self.$form).val(self.spreadsheet.CreateSpreadsheetSave());
-        }, 0);
-      }
-    },
-    params: {}
-  };
-}
-
-Drupal.sheetnode.viewModes = {
-  readOnly: 0,
-  fiddleMode: 1,
-  htmlTable: 2
-}
-
-Drupal.sheetnode.prototype.start = function() {
-  var self = this;
-  var showEditor = this.settings.saveElement || this.settings.viewMode == Drupal.sheetnode.viewModes.fiddleMode;
-  var showToolbar = this.settings.saveElement || (this.settings.showToolbar && this.settings.viewMode == Drupal.sheetnode.viewModes.fiddleMode);
-  
-  // SocialCalc initialization.
-  SocialCalc.ConstantsSetImagePrefix(this.settings.imagePrefix);
-  SocialCalc.Constants.defaultCommentClass = "cellcomment";
-  SocialCalc.Constants.defaultReadonlyClass = "readonly";
-  this.spreadsheet = showEditor ? new SocialCalc.SpreadsheetControl(this.settings.containerElement+"-") : new SocialCalc.SpreadsheetViewer(this.settings.containerElement+"-");
-  if (showToolbar) {
-    // Remove unwanted tabs.
-    this.spreadsheet.tabs.splice(this.spreadsheet.tabnums.clipboard, 1);
-    this.spreadsheet.tabs.splice(this.spreadsheet.tabnums.audit, 1);
-    if (!this.settings.permissions['edit sheetnode settings']) {
-      this.spreadsheet.tabs.splice(this.spreadsheet.tabnums.settings, 1);
-    }
-    this.spreadsheet.tabnums = {};
-    for (var i=0; i<this.spreadsheet.tabs.length; i++) {
-      this.spreadsheet.tabnums[this.spreadsheet.tabs[i].name] = i;
-    }
-  }
-  else {
-    this.spreadsheet.tabbackground="display:none;";
-    this.spreadsheet.toolbarbackground="display:none;";
-  }
-
-  // Trigger event to alert plugins that we've created the spreadsheet.
-  this.$container.trigger('sheetnodeCreated', {spreadsheet: this.spreadsheet});
-
-  // Read in data and recompute.
-  if (typeof(this.settings.value) == 'string') {
-    var parts = this.spreadsheet.DecodeSpreadsheetSave(this.settings.value);
-    if (parts && parts.sheet) {
-      this.spreadsheet.ParseSheetSave(this.settings.value.substring(parts.sheet.start, parts.sheet.end));
-    }
-  }
-  if (self.settings.saveElement || self.settings.viewMode != Drupal.sheetnode.viewModes.htmlTable) {
-    if (showEditor) {
-      this.spreadsheet.InitializeSpreadsheetControl(this.settings.containerElement, 700, this.$container.width());
-    }
-    else {
-      this.spreadsheet.InitializeSpreadsheetViewer(this.settings.containerElement, 700, this.$container.width());
-    }
-    if (parts && parts.edit) {
-      this.spreadsheet.editor.LoadEditorSettings(this.settings.value.substring(parts.edit.start, parts.edit.end));
-    }
-  }
-
-  // Call our setup functions.
-  this.focusSetup();
-  this.functionsSetup();
-  this.loadsheetSetup();
-  this.callbackSetup();
-
-  // DOM initialization.
-  if (this.settings.saveElement) {
-    this.$form = this.$container.parents('form').submit(function() {
-      self.save();
-      return true;
-    });
-    // Special handling for Views AJAX.
-    try {
-      $('input[type=submit]', Drupal.settings.views.ajax.id).click(function() {
-        self.save();
-      });
-    }
-    catch (e) {
-      // Do nothing.
-    }
-  }
-  $(window).resize(function() {
-    self.resize();
-  });
-  $('div#SocialCalc-edittools', this.$container).parent('div').attr('id', 'SocialCalc-toolbar');
-  $('td#SocialCalc-edittab', this.$container).parents('div:eq(0)').attr('id', 'SocialCalc-tabbar');
-  $('input:text', this.$container).addClass('form-text socialcalc-input');
-  $('input:radio', this.$container).addClass('form-radio socialcalc-input');
-  $('input:checkbox', this.$container).addClass('form-checkbox socialcalc-input');
-  $('textarea', this.$container).addClass('form-textarea socialcalc-input');
-  $('select', this.$container).addClass('form-select socialcalc-input');
-  $('input:button', this.$container).addClass('form-submit socialcalc-input');
-  $('div#SocialCalc-sorttools td:first', this.$container).css('width', 'auto');
-  $('div#SocialCalc-settingsview', this.$container).css('border', 'none').css('width', 'auto').css('height', 'auto');
-
-  // Lock cells requires special permission.
-  if (showToolbar && !this.settings.permissions['edit sheetnode settings']) {
-    $('span#SocialCalc-locktools', this.$container).css('display', 'none');
-  }
-
-  // Prepare for fullscreen handling when clicking the SocialCalc icon.
-  $('td#'+SocialCalc.Constants.defaultTableEditorIDPrefix+'logo img', this.$container).attr('title', Drupal.t('Fullscreen')).click(function() { self.fullscreen() });
-
-  // If we're in a jQuery UI dialog, disable closeOnEscape and unbind the keypress event that interferes with our keyboard handling.
-  if ($('.ui-dialog-content').length) {
-    $('.ui-dialog-content').dialog('option', 'closeOnEscape', false);
-    $(document).unbind('keydown.dialog-overlay');
-  }
-  
-  // Signal that we've processed this instance of sheetnode.
-  this.$container.addClass('sheetview-processed');
-
-  // Trigger event to alert plugins that we've built the spreadsheet.
-  this.$container.trigger('sheetnodeReady', {spreadsheet: this.spreadsheet});
-
-  // Force a recalc to refresh all values and scrollbars.
-  this.spreadsheet.editor.EditorScheduleSheetCommands('recalc');
-}
-
-Drupal.sheetnode.prototype.fullscreen = function() {
-  if (this.$container.hasClass('sheetview-fullscreen')) { // Going back to normal:
-    // Restore saved values.
-    this.$container.removeClass('sheetview-fullscreen');
-    if (this.beforeFullscreen.index >= this.beforeFullscreen.parentElement.children().length) {
-      this.beforeFullscreen.parentElement.append(this.$container);
-    } else {
-      this.$container.insertBefore(this.beforeFullscreen.parentElement.children().get(this.beforeFullscreen.index));
-    }
-    this.spreadsheet.requestedHeight = this.beforeFullscreen.requestedHeight;
-    this.resize();
-    $(document.body).css('overflow', 'auto');
-    window.scroll(this.beforeFullscreen.x, this.beforeFullscreen.y);
-  }
-  else { // Going fullscreen:
-    // Save current values.
-    this.beforeFullscreen = {
-      parentElement: this.$container.parent(),
-      index: this.$container.parent().children().index(this.$container),
-      x: $(window).scrollLeft(), y: $(window).scrollTop(),
-      requestedHeight: this.spreadsheet.requestedHeight
-    };
-
-    // Set values needed to go fullscreen.
-    $(document.body).append(this.$container).css('overflow', 'hidden');
-    this.$container.addClass('sheetview-fullscreen');
-    this.resize();
-    window.scroll(0,0);
-  }
-}
-
-Drupal.sheetnode.prototype.resize = function() {
-  // Adjust width and height if needed.
-  if (this.$container.hasClass('sheetview-fullscreen')) {
-    this.spreadsheet.requestedHeight = this.$container.height();
-  }
-  this.spreadsheet.requestedWidth = this.$container.width();
-  this.spreadsheet.DoOnResize();
-}
-
-Drupal.sheetnode.prototype.save = function() {
-  var self = this;
-  $('#'+this.settings.saveElement, this.$form).val(this.spreadsheet.CreateSpreadsheetSave());
-  $('#edit-log', this.$form).each(function() {
-    var audit = self.spreadsheet.sheet.CreateAuditString();
-    var log = $(this).val();
-    if (!log.length) {
-      $(this).val(audit);
-    }
-    else {
-      $(this).val(log + '\n' + audit);
-    }
-  });
-}
-
-// END jQuery
-})(jQuery);
-
-// parseUri 1.2.2
-// (c) Steven Levithan <stevenlevithan.com>
-// MIT License
-// http://blog.stevenlevithan.com/archives/parseuri
-
-// Sublicensed as GPL by infojunkie <karim.ratib@gmail.com>
-// http://programmers.stackexchange.com/questions/105912/can-you-change-code-distributed-under-the-mit-license-and-re-distribute-it-unde
-
-function parseUri (str) {
-  var o   = parseUri.options,
-    m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
-    uri = {},
-    i   = 14;
-
-  while (i--) uri[o.key[i]] = m[i] || "";
-
-  uri[o.q.name] = {};
-  uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
-    if ($1) uri[o.q.name][$1] = $2;
-  });
-
-  return uri;
-};
-
-parseUri.options = {
-  strictMode: false,
-  key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
-  q:   {
-    name:   "queryKey",
-    parser: /(?:^|&)([^&=]*)=?([^&]*)/g
-  },
-  parser: {
-    strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
-    loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
-  }
-};
-
-// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf#Compatibility
-if (!Array.prototype.indexOf) {
-  Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
-    "use strict";
-    if (this == null) {
-      throw new TypeError();
-    }
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (len === 0) {
-      return -1;
-    }
-    var n = 0;
-    if (arguments.length > 0) {
-      n = Number(arguments[1]);
-      if (n != n) { // shortcut for verifying if it's NaN
-          n = 0;
-      } else if (n != 0 && n != Infinity && n != -Infinity) {
-          n = (n > 0 || -1) * Math.floor(Math.abs(n));
-      }
-    }
-    if (n >= len) {
-      return -1;
-    }
-    var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
-    for (; k < len; k++) {
-      if (k in t && t[k] === searchElement) {
-        return k;
-      }
-    }
-    return -1;
-  }
-}
-
diff --git a/sheetnode.module b/sheetnode.module
index 9d957c7..6c4f1f2 100644
--- a/sheetnode.module
+++ b/sheetnode.module
@@ -211,9 +211,9 @@ function _sheetnode_inject($sheet_id, $sheet_aliases, $value, $save_element, $co
   drupal_add_js($path . '/socialcalc/socialcalcpopup.js', array('weight' => 4));
   drupal_add_js($path . '/socialcalc/socialcalcspreadsheetcontrol.js', array('weight' => 5));
   drupal_add_js($path . '/socialcalc/socialcalcviewer.js', array('weight' => 5));
-  drupal_add_js($path . '/sheetnode.js', array('weight' => 6));
+  drupal_add_js($path . '/js/sheetnode.js', array('weight' => 6));
   drupal_add_css($path . '/socialcalc/socialcalc.css');
-  drupal_add_css($path . '/sheetnode.css');
+  drupal_add_css($path . '/css/sheetnode.css');
 
   // Allow other modules to add their own JS/CSS.
   module_invoke_all('sheetnode_plugins', $value, $save_element, $context);
diff --git a/sheetnode.views.inc b/sheetnode.views.inc
index f05d98e..6fb14e2 100644
--- a/sheetnode.views.inc
+++ b/sheetnode.views.inc
@@ -25,7 +25,7 @@ function sheetnode_views_plugins() {
           $path . '/socialcalc/socialcalcpopup.js',
           $path . '/socialcalc/socialcalcspreadsheetcontrol.js',
           $path . '/socialcalc/socialcalcviewer.js',
-          $path . '/sheetnode.js',
+          $path . '/js/sheetnode.js',
         ),
       ),
       'sheet_raw' => array(
diff --git a/views/sheetnode_plugin_style.inc b/views/sheetnode_plugin_style.inc
index 1a07ec4..184151c 100644
--- a/views/sheetnode_plugin_style.inc
+++ b/views/sheetnode_plugin_style.inc
@@ -486,12 +486,12 @@ class sheetnode_plugin_style extends views_plugin_style {
       $path . '/socialcalc/socialcalcpopup.js' => array('weight' => 4),
       $path . '/socialcalc/socialcalcspreadsheetcontrol.js' => array('weight' => 5),
       $path . '/socialcalc/socialcalcviewer.js' => array('weight' => 5),
-      $path . '/sheetnode.js' => array('weight' => 6),
+      $path . '/js/sheetnode.js' => array('weight' => 6),
       array('data' => $setting, 'type' => 'setting'),
     );
     $element['#attached']['css'] = array(
       $path . '/socialcalc/socialcalc.css',
-      $path . '/sheetnode.css',
+      $path . '/css/sheetnode.css',
     );
 
     module_invoke_all('sheetnode_plugins', $value, $save_element, $context);
