<commit_before>(function(window, document, ionic) {

  /**
   * @ngdoc utility
   * @name ionic.Platform
   * @module ionic
   */
  ionic.Platform = {

    /**
     * @ngdoc property
     * @name ionic.Platform#isReady
     * @returns {boolean} Whether the device is ready.
     */
    isReady: false,
    /**
     * @ngdoc property
     * @name ionic.Platform#isFullScreen
     * @returns {boolean} Whether the device is fullscreen.
     */
    isFullScreen: false,
    /**
     * @ngdoc property
     * @name ionic.Platform#platforms
     * @returns {Array(string)} An array of all platforms found.
     */
    platforms: null,
    /**
     * @ngdoc property
     * @name ionic.Platform#grade
     * @returns {string} What grade the current platform is.
     */
    grade: null,
    ua: navigator.userAgent,

    /**
     * @ngdoc method
     * @name ionic.Platform#ready
     * @description
     * Trigger a callback once the device is ready,
     * or immediately if the device is already ready.
     * @param {function} callback The function to call.
     */
    ready: function(cb) {
      // run through tasks to complete now that the device is ready
      if(this.isReady) {
        cb();
      } else {
        // the platform isn't ready yet, add it to this array
        // which will be called once the platform is ready
        readyCallbacks.push(cb);
      }
    },

    /**
     * @private
     */
    detect: function() {
      ionic.Platform._checkPlatforms();

      ionic.requestAnimationFrame(function(){
        // only add to the body class if we got platform info
        for(var i = 0; i < ionic.Platform.platforms.length; i++) {
          document.body.classList.add('platform-' + ionic.Platform.platforms[i]);
        }
        document.body.classList.add('grade-' + ionic.Platform.grade);
      });
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#device
     * @description Return the current device (given by cordova).
     * @returns {object} The device object.
     */
    device: function() {
      if(window.device) return window.device;
      if(this.isCordova()) console.error('device plugin required');
      return {};
    },

    _checkPlatforms: function(platforms) {
      this.platforms = [];
      this.grade = 'a';

      if(this.isCordova()) this.platforms.push('cordova');
      if(this.isIPad()) this.platforms.push('ipad');

      var platform = this.platform();
      if(platform) {
        this.platforms.push(platform);

        var version = this.version();
        if(version) {
          var v = version.toString();
          if(v.indexOf('.') > 0) {
            v = v.replace('.', '_');
          } else {
            v += '_0';
          }
          this.platforms.push(platform + v.split('_')[0]);
          this.platforms.push(platform + v);

          if(this.isAndroid() && version < 4.4) {
            this.grade = (version < 4 ? 'c' : 'b');
          }
        }
      }
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#isCordova
     * @returns {boolean} Whether we are running on Cordova.
     */
    isCordova: function() {
      return !(!window.cordova && !window.PhoneGap && !window.phonegap);
    },
    /**
     * @ngdoc method
     * @name ionic.Platform#isIPad
     * @returns {boolean} Whether we are running on iPad.
     */
    isIPad: function() {
      return this.ua.toLowerCase().indexOf('ipad') >= 0;
    },
    /**
     * @ngdoc method
     * @name ionic.Platform#isIOS
     * @returns {boolean} Whether we are running on iOS.
     */
    isIOS: function() {
      return this.is('ios');
    },
    /**
     * @ngdoc method
     * @name ionic.Platform#isAndroid
     * @returns {boolean} Whether we are running on Android.
     */
    isAndroid: function() {
      return this.is('android');
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#platform
     * @returns {string} The name of the current platform.
     */
    platform: function() {
      // singleton to get the platform name
      if(platformName === null) this.setPlatform(this.device().platform);
      return platformName;
    },

    /**
     * @private
     */
    setPlatform: function(n) {
      if(typeof n != 'undefined' && n !== null && n.length) {
        platformName = n.toLowerCase();
      } else if(this.ua.indexOf('Android') > 0) {
        platformName = 'android';
      } else if(this.ua.indexOf('iPhone') > -1 || this.ua.indexOf('iPad') > -1 || this.ua.indexOf('iPod') > -1) {
        platformName = 'ios';
      } else {
        platformName = '';
      }
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#version
     * @returns {string} The version of the current device platform.
     */
    version: function() {
      // singleton to get the platform version
      if(platformVersion === null) this.setVersion(this.device().version);
      return platformVersion;
    },

    /**
     * @private
     */
    setVersion: function(v) {
      if(typeof v != 'undefined' && v !== null) {
        v = v.split('.');
        v = parseFloat(v[0] + '.' + (v.length > 1 ? v[1] : 0));
        if(!isNaN(v)) {
          platformVersion = v;
          return;
        }
      }

      platformVersion = 0;

      // fallback to user-agent checking
      var pName = this.platform();
      var versionMatch = {
        'android': /Android (\d+).(\d+)?/,
        'ios': /OS (\d+)_(\d+)?/
      };
      if(versionMatch[pName]) {
        v = this.ua.match( versionMatch[pName] );
        if(v.length > 2) {
          platformVersion = parseFloat( v[1] + '.' + v[2] );
        }
      }
    },

    // Check if the platform is the one detected by cordova
    is: function(type) {
      type = type.toLowerCase();
      // check if it has an array of platforms
      if(this.platforms) {
        for(var x = 0; x < this.platforms.length; x++) {
          if(this.platforms[x] === type) return true;
        }
      }
      // exact match
      var pName = this.platform();
      if(pName) {
        return pName === type.toLowerCase();
      }

      // A quick hack for to check userAgent
      return this.ua.toLowerCase().indexOf(type) >= 0;
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#exitApp
     * @description Exit the app.
     */
    exitApp: function() {
      this.ready(function(){
        navigator.app && navigator.app.exitApp && navigator.app.exitApp();
      });
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#showStatusBar
     * @description Shows or hides the device status bar (in Cordova).
     * @param {boolean} shouldShow Whether or not to show the status bar.
     */
    showStatusBar: function(val) {
      // Only useful when run within cordova
      this._showStatusBar = val;
      this.ready(function(){
        // run this only when or if the platform (cordova) is ready
        ionic.requestAnimationFrame(function(){
          if(ionic.Platform._showStatusBar) {
            // they do not want it to be full screen
            window.StatusBar && window.StatusBar.show();
            document.body.classList.remove('status-bar-hide');
          } else {
            // it should be full screen
            window.StatusBar && window.StatusBar.hide();
            document.body.classList.add('status-bar-hide');
          }
        });
      });
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#fullScreen
     * @description
     * Sets whether the app is fullscreen or not (in Cordova).
     * @param {boolean=} showFullScreen Whether or not to set the app to fullscreen. Defaults to true.
     * @param {boolean=} showStatusBar Whether or not to show the device's status bar. Defaults to false.
     */
    fullScreen: function(showFullScreen, showStatusBar) {
      // showFullScreen: default is true if no param provided
      this.isFullScreen = (showFullScreen !== false);

      // add/remove the fullscreen classname to the body
      ionic.DomUtil.ready(function(){
        // run this only when or if the DOM is ready
        ionic.requestAnimationFrame(function(){
          if(ionic.Platform.isFullScreen) {
            document.body.classList.add('fullscreen');
          } else {
            document.body.classList.remove('fullscreen');
          }
        });
        // showStatusBar: default is false if no param provided
        ionic.Platform.showStatusBar( (showStatusBar === true) );
      });
    }

  };

  var platformName = null, // just the name, like iOS or Android
  platformVersion = null, // a float of the major and minor, like 7.1
  readyCallbacks = [];

  // setup listeners to know when the device is ready to go
  function onWindowLoad() {
    if(ionic.Platform.isCordova()) {
      // the window and scripts are fully loaded, and a cordova/phonegap
      // object exists then let's listen for the deviceready
      document.addEventListener("deviceready", onPlatformReady, false);
    } else {
      // the window and scripts are fully loaded, but the window object doesn't have the
      // cordova/phonegap object, so its just a browser, not a webview wrapped w/ cordova
      onPlatformReady();
    }
    window.removeEventListener("load", onWindowLoad, false);
  }
  window.addEventListener("load", onWindowLoad, false);

  function onPlatformReady() {
    // the device is all set to go, init our own stuff then fire off our event
    ionic.Platform.isReady = true;
    ionic.Platform.detect();
    for(var x=0; x<readyCallbacks.length; x++) {
      // fire off all the callbacks that were added before the platform was ready
      readyCallbacks[x]();
    }
    readyCallbacks = [];
    ionic.trigger('platformready', { target: document });

    ionic.requestAnimationFrame(function(){
      document.body.classList.add('platform-ready');
    });
  }

})(this, document, ionic);
<commit_msg>docs(platform): Explain ionic.Platform.ready() further<commit_after>(function(window, document, ionic) {

  /**
   * @ngdoc utility
   * @name ionic.Platform
   * @module ionic
   */
  ionic.Platform = {

    /**
     * @ngdoc property
     * @name ionic.Platform#isReady
     * @returns {boolean} Whether the device is ready.
     */
    isReady: false,
    /**
     * @ngdoc property
     * @name ionic.Platform#isFullScreen
     * @returns {boolean} Whether the device is fullscreen.
     */
    isFullScreen: false,
    /**
     * @ngdoc property
     * @name ionic.Platform#platforms
     * @returns {Array(string)} An array of all platforms found.
     */
    platforms: null,
    /**
     * @ngdoc property
     * @name ionic.Platform#grade
     * @returns {string} What grade the current platform is.
     */
    grade: null,
    ua: navigator.userAgent,

    /**
     * @ngdoc method
     * @name ionic.Platform#ready
     * @description
     * Trigger a callback once the device is ready, or immediately
     * if the device is already ready. This method can be ran from
     * anywhere and does not need to be wrapped by any additonal methods.
     * When the app is within a WebView (Cordova), it'll fire
     * the callback once the device is ready. If the app is within
     * a web browser, it'll fire the callback after `window.load`.
     * @param {function} callback The function to call.
     */
    ready: function(cb) {
      // run through tasks to complete now that the device is ready
      if(this.isReady) {
        cb();
      } else {
        // the platform isn't ready yet, add it to this array
        // which will be called once the platform is ready
        readyCallbacks.push(cb);
      }
    },

    /**
     * @private
     */
    detect: function() {
      ionic.Platform._checkPlatforms();

      ionic.requestAnimationFrame(function(){
        // only add to the body class if we got platform info
        for(var i = 0; i < ionic.Platform.platforms.length; i++) {
          document.body.classList.add('platform-' + ionic.Platform.platforms[i]);
        }
        document.body.classList.add('grade-' + ionic.Platform.grade);
      });
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#device
     * @description Return the current device (given by cordova).
     * @returns {object} The device object.
     */
    device: function() {
      if(window.device) return window.device;
      if(this.isCordova()) console.error('device plugin required');
      return {};
    },

    _checkPlatforms: function(platforms) {
      this.platforms = [];
      this.grade = 'a';

      if(this.isCordova()) this.platforms.push('cordova');
      if(this.isIPad()) this.platforms.push('ipad');

      var platform = this.platform();
      if(platform) {
        this.platforms.push(platform);

        var version = this.version();
        if(version) {
          var v = version.toString();
          if(v.indexOf('.') > 0) {
            v = v.replace('.', '_');
          } else {
            v += '_0';
          }
          this.platforms.push(platform + v.split('_')[0]);
          this.platforms.push(platform + v);

          if(this.isAndroid() && version < 4.4) {
            this.grade = (version < 4 ? 'c' : 'b');
          }
        }
      }
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#isCordova
     * @returns {boolean} Whether we are running on Cordova.
     */
    isCordova: function() {
      return !(!window.cordova && !window.PhoneGap && !window.phonegap);
    },
    /**
     * @ngdoc method
     * @name ionic.Platform#isIPad
     * @returns {boolean} Whether we are running on iPad.
     */
    isIPad: function() {
      return this.ua.toLowerCase().indexOf('ipad') >= 0;
    },
    /**
     * @ngdoc method
     * @name ionic.Platform#isIOS
     * @returns {boolean} Whether we are running on iOS.
     */
    isIOS: function() {
      return this.is('ios');
    },
    /**
     * @ngdoc method
     * @name ionic.Platform#isAndroid
     * @returns {boolean} Whether we are running on Android.
     */
    isAndroid: function() {
      return this.is('android');
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#platform
     * @returns {string} The name of the current platform.
     */
    platform: function() {
      // singleton to get the platform name
      if(platformName === null) this.setPlatform(this.device().platform);
      return platformName;
    },

    /**
     * @private
     */
    setPlatform: function(n) {
      if(typeof n != 'undefined' && n !== null && n.length) {
        platformName = n.toLowerCase();
      } else if(this.ua.indexOf('Android') > 0) {
        platformName = 'android';
      } else if(this.ua.indexOf('iPhone') > -1 || this.ua.indexOf('iPad') > -1 || this.ua.indexOf('iPod') > -1) {
        platformName = 'ios';
      } else {
        platformName = '';
      }
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#version
     * @returns {string} The version of the current device platform.
     */
    version: function() {
      // singleton to get the platform version
      if(platformVersion === null) this.setVersion(this.device().version);
      return platformVersion;
    },

    /**
     * @private
     */
    setVersion: function(v) {
      if(typeof v != 'undefined' && v !== null) {
        v = v.split('.');
        v = parseFloat(v[0] + '.' + (v.length > 1 ? v[1] : 0));
        if(!isNaN(v)) {
          platformVersion = v;
          return;
        }
      }

      platformVersion = 0;

      // fallback to user-agent checking
      var pName = this.platform();
      var versionMatch = {
        'android': /Android (\d+).(\d+)?/,
        'ios': /OS (\d+)_(\d+)?/
      };
      if(versionMatch[pName]) {
        v = this.ua.match( versionMatch[pName] );
        if(v.length > 2) {
          platformVersion = parseFloat( v[1] + '.' + v[2] );
        }
      }
    },

    // Check if the platform is the one detected by cordova
    is: function(type) {
      type = type.toLowerCase();
      // check if it has an array of platforms
      if(this.platforms) {
        for(var x = 0; x < this.platforms.length; x++) {
          if(this.platforms[x] === type) return true;
        }
      }
      // exact match
      var pName = this.platform();
      if(pName) {
        return pName === type.toLowerCase();
      }

      // A quick hack for to check userAgent
      return this.ua.toLowerCase().indexOf(type) >= 0;
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#exitApp
     * @description Exit the app.
     */
    exitApp: function() {
      this.ready(function(){
        navigator.app && navigator.app.exitApp && navigator.app.exitApp();
      });
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#showStatusBar
     * @description Shows or hides the device status bar (in Cordova).
     * @param {boolean} shouldShow Whether or not to show the status bar.
     */
    showStatusBar: function(val) {
      // Only useful when run within cordova
      this._showStatusBar = val;
      this.ready(function(){
        // run this only when or if the platform (cordova) is ready
        ionic.requestAnimationFrame(function(){
          if(ionic.Platform._showStatusBar) {
            // they do not want it to be full screen
            window.StatusBar && window.StatusBar.show();
            document.body.classList.remove('status-bar-hide');
          } else {
            // it should be full screen
            window.StatusBar && window.StatusBar.hide();
            document.body.classList.add('status-bar-hide');
          }
        });
      });
    },

    /**
     * @ngdoc method
     * @name ionic.Platform#fullScreen
     * @description
     * Sets whether the app is fullscreen or not (in Cordova).
     * @param {boolean=} showFullScreen Whether or not to set the app to fullscreen. Defaults to true.
     * @param {boolean=} showStatusBar Whether or not to show the device's status bar. Defaults to false.
     */
    fullScreen: function(showFullScreen, showStatusBar) {
      // showFullScreen: default is true if no param provided
      this.isFullScreen = (showFullScreen !== false);

      // add/remove the fullscreen classname to the body
      ionic.DomUtil.ready(function(){
        // run this only when or if the DOM is ready
        ionic.requestAnimationFrame(function(){
          if(ionic.Platform.isFullScreen) {
            document.body.classList.add('fullscreen');
          } else {
            document.body.classList.remove('fullscreen');
          }
        });
        // showStatusBar: default is false if no param provided
        ionic.Platform.showStatusBar( (showStatusBar === true) );
      });
    }

  };

  var platformName = null, // just the name, like iOS or Android
  platformVersion = null, // a float of the major and minor, like 7.1
  readyCallbacks = [];

  // setup listeners to know when the device is ready to go
  function onWindowLoad() {
    if(ionic.Platform.isCordova()) {
      // the window and scripts are fully loaded, and a cordova/phonegap
      // object exists then let's listen for the deviceready
      document.addEventListener("deviceready", onPlatformReady, false);
    } else {
      // the window and scripts are fully loaded, but the window object doesn't have the
      // cordova/phonegap object, so its just a browser, not a webview wrapped w/ cordova
      onPlatformReady();
    }
    window.removeEventListener("load", onWindowLoad, false);
  }
  window.addEventListener("load", onWindowLoad, false);

  function onPlatformReady() {
    // the device is all set to go, init our own stuff then fire off our event
    ionic.Platform.isReady = true;
    ionic.Platform.detect();
    for(var x=0; x<readyCallbacks.length; x++) {
      // fire off all the callbacks that were added before the platform was ready
      readyCallbacks[x]();
    }
    readyCallbacks = [];
    ionic.trigger('platformready', { target: document });

    ionic.requestAnimationFrame(function(){
      document.body.classList.add('platform-ready');
    });
  }

})(this, document, ionic);
<|endoftext|>


<commit_before>// Note: Should be coverted to a bookmarklet with http://ted.mielczarek.org/code/mozilla/bookmarklet.html
// because it properly ignores comments, unlike http://mrcoles.com/bookmarklet/

(function(){

function allowTextSelection() {
  var styles='*,p,div{user-select:text !important;-moz-user-select:text !important;-webkit-user-select:text !important;}';
  jQuery('head').append(jQuery('<style />').html(styles));

  window.console && console.log('allowTextSelection');

  var allowNormal = function(){
    return true;
  };

  window.console && console.log('Elements unbound: '+
    jQuery('*[onselectstart], *[ondragstart], *[oncontextmenu], #songLyricsDiv'
    ).unbind('contextmenu').unbind('selectstart').unbind('dragstart'
    ).unbind('mousedown').unbind('mouseup').unbind('click'
    ).attr('onselectstart',allowNormal).attr('oncontextmenu',allowNormal
    ).attr('ondragstart',allowNormal).size());
}

function allowTextSelectionWhenPossible() {
  window.console && console.log('allowTextSelectionWhenPossible');
  if (window.jQuery) {
    window.console && console.log('jQuery has now loaded');
    allowTextSelection();
  } else {
    window.console && console.log('jQuery still not loaded.');
    window.setTimeout(allowTextSelectionWhenPossible, 100);
  }
}

if (window.jQuery) {
    window.console && console.log('jQuery exists; will use');
  allowTextSelection();
} else {
  window.console && console.log('jQuery not loaded; will include.');
  var s = document.createElement('script');
  s.setAttribute('src',
    // Hard to read, but the intention here is to set a protocol
    // ONLY IF we are *not* running on HTTP or HTTPS already.
    // That is to allow the script to work on e.g. file:/ URLs,
    // but using the protocol-agnosting `//tld/file` format which allows
    // the bookmarklet to run on HTTP & HTTPS pages, both. Should fix issue #2.
    (document.location.toString().substr(0,4) === 'http' ? '' : 'http:') + '//code.jquery.com/jquery-1.9.1.min.js'
  );
  document.getElementsByTagName('body')[0].appendChild(s);
  allowTextSelectionWhenPossible();
}

})();
<commit_msg>Rewrote script at Alan Hogan's invitation to address my concerns: Limitations of the previous version that I've attempted to address with my rewrite:<commit_after>// Note: Should be coverted to a bookmarklet with http://ted.mielczarek.org/code/mozilla/bookmarklet.html
// because it properly ignores comments, unlike http://mrcoles.com/bookmarklet/

(function () {

    function allowTextSelection() {
        window.console && console.log('allowTextSelection');

        //add styles that enable text selection
        var style = document.createElement('style');
        style.type = 'text/css';
        style.innerHTML =
            '*,p,div{user-select:text !important;-moz-user-select:text !important;-webkit-user-select:text !important;}';

        document.head.appendChild(style);

        //Put all of <body> children in a collection
        //Use getElementsByTagName because it has better compatibility (it's older) than querySelectorAll('*')
        var elArray = document.body.getElementsByTagName('*');

        //allow mouse events typically involved in selection
        for(var i=0; i<elArray.length; i++){
            var el = elArray[i];
            el.onselectstart = el.ondragstart = el.ondrag = el.oncontextmenu = el.onmousedown
                = el.onmouseup = function(){return true};

            if(el instanceof HTMLInputElement && el.type == 'text'){
                //enable text inputs (to defeat an easy way to block selection by setting input's 'disabled' attribute)
                el.removeAttribute('disabled');

                //counteract any listener that would block copy&paste keyboard shortcuts. (I can't figure out yet why
                // although this works on the first text input to replace an existing issue, it doesn't work on the 2nd
                el.onkeydown = el.onkeyup = function(){return true};
            }
        }

    }

    allowTextSelection();

})();
<|endoftext|>


<commit_before>// Handles related-objects functionality: lookup link for raw_id_fields
// and Add Another links.

function html_unescape(text) {
    // Unescape a string that was escaped using django.utils.html.escape.
    text = text.replace(/</g, '<');
    text = text.replace(/>/g, '>');
    text = text.replace(/"/g, '"');
    text = text.replace(/'/g, "'");
    text = text.replace(/&/g, '&');
    return text;
}

// IE doesn't accept periods or dashes in the window name, but the element IDs
// we use to generate popup window names may contain them, therefore we map them
// to allowed characters in a reversible way so that we can locate the correct
// element when the popup window is dismissed.
function id_to_windowname(text) {
    text = text.replace(/\./g, '__dot__');
    text = text.replace(/\-/g, '__dash__');
    return text;
}

function windowname_to_id(text) {
    text = text.replace(/__dot__/g, '.');
    text = text.replace(/__dash__/g, '-');
    return text;
}

function showAdminPopup(triggeringLink, name_regexp) {
    var name = triggeringLink.id.replace(name_regexp, '');
    name = id_to_windowname(name);
    var href = triggeringLink.href;
    if (href.indexOf('?') == -1) {
        href += '?_popup=1';
    } else {
        href  += '&_popup=1';
    }

    // Django JET
    showRelatedPopup(name, href);

    return false;
}

function showRelatedObjectLookupPopup(triggeringLink) {
    return showAdminPopup(triggeringLink, /^lookup_/);
}

function dismissRelatedLookupPopup(win, chosenId) {
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
        elem.value += ',' + chosenId;
    } else {
        document.getElementById(name).value = chosenId;
    }

    // Django JET
    closeRelatedPopup(win);
}

function showRelatedObjectPopup(triggeringLink) {
    var name = triggeringLink.id.replace(/^(change|add|delete)_/, '');
    name = id_to_windowname(name);
    var href = triggeringLink.href;

    // Django JET
    showRelatedPopup(name, href);

    return false;
}

function dismissAddRelatedObjectPopup(win, newId, newRepr) {
    // newId and newRepr are expected to have previously been escaped by
    // django.utils.html.escape.
    newId = html_unescape(newId);
    newRepr = html_unescape(newRepr);
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    var o;
    if (elem) {
        var elemName = elem.nodeName.toUpperCase();
        if (elemName == 'SELECT') {
            o = new Option(newRepr, newId);
            elem.options[elem.options.length] = o;
            o.selected = true;
        } else if (elemName == 'INPUT') {
            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
                elem.value += ',' + newId;
            } else {
                elem.value = newId;
            }
        }
        // Trigger a change event to update related links if required.
        django.jQuery(elem).trigger('change');
    } else {
        var toId = name + "_to";
        o = new Option(newRepr, newId);
        SelectBox.add_to_cache(toId, o);
        SelectBox.redisplay(toId);
    }

    // Django JET
    closeRelatedPopup(win);
}

function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
    objId = html_unescape(objId);
    newRepr = html_unescape(newRepr);
    var id = windowname_to_id(win.name).replace(/^edit_/, '');
    var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    var selects = django.jQuery(selectsSelector);
    selects.find('option').each(function() {
        if (this.value == objId) {
            this.innerHTML = newRepr;
            this.value = newId;
        }
    });

    // Django JET
    closeRelatedPopup(win);
};

function dismissDeleteRelatedObjectPopup(win, objId) {
    objId = html_unescape(objId);
    var id = windowname_to_id(win.name).replace(/^delete_/, '');
    var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    var selects = django.jQuery(selectsSelector);
    selects.find('option').each(function() {
        if (this.value == objId) {
            django.jQuery(this).remove();
        }
    }).trigger('change');

    // Django JET
    closeRelatedPopup(win);
};

// Kept for backward compatibility
showAddAnotherPopup = showRelatedObjectPopup;
dismissAddAnotherPopup = dismissAddRelatedObjectPopup;

// Django JET

opener = parent.window;

function showRelatedPopup(name, href) {
    django.jQuery(function($) {
        var $container = $('.related-popup-container');
        var $loading = $container.find('.loading-indicator');
        var $popup = $('<iframe>').attr('name', name).attr('src', href).addClass('related-popup').on('load', function() {
            $popup.add($('.related-popup-back')).fadeIn(200, 'swing', function() {
                $loading.hide();
            });
        });

        $loading.show();
        $container.fadeIn(200, 'swing', function() {
            $('.related-popup-container').append($popup);
        });
        $('body').addClass('non-scrollable');
    });
}

function closeRelatedPopup(win) {
    jet.jQuery('select').trigger('select:init');
    jet.jQuery(win.parent).trigger('related-popup:close');
}<commit_msg>Fix scope<commit_after>// Handles related-objects functionality: lookup link for raw_id_fields
// and Add Another links.

function html_unescape(text) {
    // Unescape a string that was escaped using django.utils.html.escape.
    text = text.replace(/</g, '<');
    text = text.replace(/>/g, '>');
    text = text.replace(/"/g, '"');
    text = text.replace(/'/g, "'");
    text = text.replace(/&/g, '&');
    return text;
}

// IE doesn't accept periods or dashes in the window name, but the element IDs
// we use to generate popup window names may contain them, therefore we map them
// to allowed characters in a reversible way so that we can locate the correct
// element when the popup window is dismissed.
function id_to_windowname(text) {
    text = text.replace(/\./g, '__dot__');
    text = text.replace(/\-/g, '__dash__');
    return text;
}

function windowname_to_id(text) {
    text = text.replace(/__dot__/g, '.');
    text = text.replace(/__dash__/g, '-');
    return text;
}

function showAdminPopup(triggeringLink, name_regexp) {
    var name = triggeringLink.id.replace(name_regexp, '');
    name = id_to_windowname(name);
    var href = triggeringLink.href;
    if (href.indexOf('?') == -1) {
        href += '?_popup=1';
    } else {
        href  += '&_popup=1';
    }

    // Django JET
    showRelatedPopup(name, href);

    return false;
}

function showRelatedObjectLookupPopup(triggeringLink) {
    return showAdminPopup(triggeringLink, /^lookup_/);
}

function dismissRelatedLookupPopup(win, chosenId) {
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
        elem.value += ',' + chosenId;
    } else {
        document.getElementById(name).value = chosenId;
    }

    // Django JET
    closeRelatedPopup(win);
}

function showRelatedObjectPopup(triggeringLink) {
    var name = triggeringLink.id.replace(/^(change|add|delete)_/, '');
    name = id_to_windowname(name);
    var href = triggeringLink.href;

    // Django JET
    showRelatedPopup(name, href);

    return false;
}

function dismissAddRelatedObjectPopup(win, newId, newRepr) {
    // newId and newRepr are expected to have previously been escaped by
    // django.utils.html.escape.
    newId = html_unescape(newId);
    newRepr = html_unescape(newRepr);
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    var o;
    if (elem) {
        var elemName = elem.nodeName.toUpperCase();
        if (elemName == 'SELECT') {
            o = new Option(newRepr, newId);
            elem.options[elem.options.length] = o;
            o.selected = true;
        } else if (elemName == 'INPUT') {
            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
                elem.value += ',' + newId;
            } else {
                elem.value = newId;
            }
        }
        // Trigger a change event to update related links if required.
        django.jQuery(elem).trigger('change');
    } else {
        var toId = name + "_to";
        o = new Option(newRepr, newId);
        SelectBox.add_to_cache(toId, o);
        SelectBox.redisplay(toId);
    }

    // Django JET
    closeRelatedPopup(win);
}

function dismissChangeRelatedObjectPopup(win, objId, newRepr, newId) {
    objId = html_unescape(objId);
    newRepr = html_unescape(newRepr);
    var id = windowname_to_id(win.name).replace(/^edit_/, '');
    var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    var selects = django.jQuery(selectsSelector);
    selects.find('option').each(function() {
        if (this.value == objId) {
            this.innerHTML = newRepr;
            this.value = newId;
        }
    });

    // Django JET
    closeRelatedPopup(win);
};

function dismissDeleteRelatedObjectPopup(win, objId) {
    objId = html_unescape(objId);
    var id = windowname_to_id(win.name).replace(/^delete_/, '');
    var selectsSelector = interpolate('#%s, #%s_from, #%s_to', [id, id, id]);
    var selects = django.jQuery(selectsSelector);
    selects.find('option').each(function() {
        if (this.value == objId) {
            django.jQuery(this).remove();
        }
    }).trigger('change');

    // Django JET
    closeRelatedPopup(win);
};

// Kept for backward compatibility
showAddAnotherPopup = showRelatedObjectPopup;
dismissAddAnotherPopup = dismissAddRelatedObjectPopup;

// Django JET

opener = parent.window;

function showRelatedPopup(name, href) {
    django.jQuery(function($) {
        var $container = $('.related-popup-container', parent.document);
        var $loading = $container.find('.loading-indicator', parent.document);
        var $body = $('body').addClass('non-scrollable', parent.document);
        var $popup = $('<iframe>').attr('name', name).attr('src', href).addClass('related-popup').on('load', function() {
            $popup.add($('.related-popup-back')).fadeIn(200, 'swing', function() {
                $loading.hide();
            });
        });

        $loading.show();
        $container.fadeIn(200, 'swing', function() {
            $container.append($popup);
        });
        $body.addClass('non-scrollable', parent.document);
    });
}

function closeRelatedPopup(win) {
    jet.jQuery('select').trigger('select:init');
    jet.jQuery(win.parent).trigger('related-popup:close');
}<|endoftext|>


<commit_before>var keystone = require('keystone'),
	Types = keystone.Field.Types;

var Post = new keystone.List('Post', {
	map: { name: 'title' },
	autokey: { path: 'slug', from: 'title', unique: true }
});

Post.add({
	title: { type: String, required: true },
	subtitle: { type: String },
	slug: { type: String, index: true },
	state: { type: Types.Select, options: 'draft, published, archived', default: 'draft', index: true },
	author: { type: Types.Relationship, ref: 'User', index: true },
	publishedDate: { type: Types.Date, index: true },
	content: {
		brief: { type: Types.Html, wysiwyg: true, height: 150 },
		extended: { type: Types.Html, wysiwyg: true, height: 400 }
	},
	categories: { type: Types.Relationship, ref: 'PostCategory', many: true }
});

Post.schema.virtual('content.full').get(function() {
	return this.content.extended || this.content.brief;
});

Post.defaultColumns = 'title, state|20%, author|20%, publishedDate|20%';
Post.register();
<commit_msg>Now uses markdown for post creation<commit_after>var keystone = require('keystone'),
	Types = keystone.Field.Types;

var Post = new keystone.List('Post', {
	map: { name: 'title' },
	autokey: { path: 'slug', from: 'title', unique: true }
});

Post.add({
	title: { type: String, required: true },
	subtitle: { type: String },
	slug: { type: String, index: true },
	state: { type: Types.Select, options: 'draft, published, archived', default: 'draft', index: true },
	author: { type: Types.Relationship, ref: 'User', index: true },
	publishedDate: { type: Types.Date, index: true },
	content: {
		brief: { type: Types.Markdown, wysiwyg: true, height: 150 },
		extended: { type: Types.Markdown, wysiwyg: true, height: 400 }
	},
	categories: { type: Types.Relationship, ref: 'PostCategory', many: true }
});

Post.schema.virtual('content.full').get(function() {
	return this.content.extended || this.content.brief;
});

Post.defaultColumns = 'title, state|20%, author|20%, publishedDate|20%';
Post.register();
<|endoftext|>


<commit_before>//sim-board.js
/*
Copyright 2014 Vytroncs.com and Charles Weissman

This file is part of "Vytroncs HMI, the 100% Free, Open-Source SCADA/HMI Initiative"
herein referred to as "Vytronics HMI".

Vytronics HMI is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Vytronics HMI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Vytronics HMI.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
Enables a driver sim mode for development and demo when no board is
connected. TTo enable sim mode set the config.sim_mode property to true.

Suggestion is to use environment vars so that the same config file can
be used in production and for development/demo as follows:

    config: {
        sim_mode: !!vy/env DRIVER_SIM_MODE:false,
        log_level: !!vy/env DRIVER_LOG_LEVEL:all,
        port_name: !!vy/env DRIVER_PORT:COM1,
        sampling_interval: 1000
    }

*/

"use strict";

module.exports.version = '0.0.0';

//Dependencies
var events = require("events");
var firmata = require('firmata');
var common = require('./common');

var Board = function(port, options, callback) {

    console.log('CREATING ARDUINO SIMULATION DRIVER OBJECT.');

    this.fakeit();

    this.emmiter = new events.EventEmitter();
    if (typeof options === "function" || typeof options === "undefined") {
        callback = options;
    }
    //Note that sim ignores options.

    this.port = port; //Just for log messages
    this.ready = 0;

    //Set a timer to simulate ready function
    var self = this;
    setTimeout( function (){
        self.ready = 1;

        //Init a bunch of pins, more than can ever have just to be safe
        for (var i=0; i<50; i++) {
            self.pins.push({
                supportedModes: [],
                mode: self.MODES.UNKNOWN,
                value: 0,
                report: 1
            });

            self.analogPins.push({
                supportedModes: [],
                mode: self.MODES.ANALOG,
                value: 520,
                report: 1
            });
        }
        callback();
    }, 5000);
};

Board.prototype.setSamplingInterval = function(interval) {
  var safeint = interval < 10 ? 10 : (interval > 65535 ? 65535 : interval); // constrained
  this.sampling_interval = safeint;
};

Board.prototype.close = function (callback){
    //TODO - stop all timers
    //this.pins[pin].interval_id

};

Board.prototype.digitalWrite = function(pin, value) {
    this.pins[pin].value = value;

    //Dont have to do anything. arduino driver will do a queryPinState after
    //write but TODO - maybe simulate a pin value event.
};

Board.prototype.queryPinState = function(pin, callback) {
    //Simulate an event
    var self = this;
    setTimeout(function (){
        callback(self.pins[pin].value || 0);
    }, 500);
};

Board.prototype.pinMode = function(pin, mode) {
    if ( ! this.pins[pin] ) this.pins[pin] = { value:0};
    this.pins[pin].mode = mode;
};

Board.prototype.digitalRead = function(pin, callback) {

    //start an interval timer to randomly change value
    var self = this;

    if ( this.pins[pin].mode === this.MODES.OUTPUT) return;

    this.pins[pin].interval_id = setInterval( function (){
        var value = getRandomInt(0, 2);
        self.pins[pin].value = value;
        callback(value);
    }, this.sampling_interval);
};

Board.prototype.analogRead = function(pin, callback) {

    //start an interval timer to randomly change value
    var self = this;
    this.analogPins[pin].interval_id = setInterval( function (){
        var value = self.analogPins[pin].value + getRandomInt(-100, 100);
        value = (value < 0) ? 0 : value;
        value = (value > 1023) ? 0 : value;
        self.analogPins[pin].value = value;

        //Report event
        callback(value);
    }, this.sampling_interval);
};

//Need to imitate a bunch of vars from real firmata board
Board.prototype.fakeit = function () {
  this.MODES = {
    INPUT: 0x00,
    OUTPUT: 0x01,
    ANALOG: 0x02,
    PWM: 0x03,
    SERVO: 0x04,
    SHIFT: 0x05,
    I2C: 0x06,
    ONEWIRE: 0x07,
    STEPPER: 0x08,
    IGNORE: 0x7F,
    UNKOWN: 0x10
  };

  this.I2C_MODES = {
    WRITE: 0x00,
    READ: 1,
    CONTINUOUS_READ: 2,
    STOP_READING: 3
  };

  this.STEPPER = {
    TYPE: {
      DRIVER: 1,
      TWO_WIRE: 2,
      FOUR_WIRE: 4
    },
    RUNSTATE: {
      STOP: 0,
      ACCEL: 1,
      DECEL: 2,
      RUN: 3
    },
    DIRECTION: {
      CCW: 0,
      CW: 1
    }
  };

  this.HIGH = 1;
  this.LOW = 0;
  this.pins = [];
  this.analogPins = [];
};

module.exports = {
    Board: Board
};

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
<commit_msg>Do not emit itemvalue unless value changes.<commit_after>//sim-board.js
/*
Copyright 2014 Vytroncs.com and Charles Weissman

This file is part of "Vytroncs HMI, the 100% Free, Open-Source SCADA/HMI Initiative"
herein referred to as "Vytronics HMI".

Vytronics HMI is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Vytronics HMI is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Vytronics HMI.  If not, see <http://www.gnu.org/licenses/>.
*/

/*
Enables a driver sim mode for development and demo when no board is
connected. TTo enable sim mode set the config.sim_mode property to true.

Suggestion is to use environment vars so that the same config file can
be used in production and for development/demo as follows:

    config: {
        sim_mode: !!vy/env DRIVER_SIM_MODE:false,
        log_level: !!vy/env DRIVER_LOG_LEVEL:all,
        port_name: !!vy/env DRIVER_PORT:COM1,
        sampling_interval: 1000
    }

*/

"use strict";

module.exports.version = '0.0.0';

//Dependencies
var events = require("events");
var firmata = require('firmata');
var common = require('./common');

var Board = function(port, options, callback) {

    console.log('CREATING ARDUINO SIMULATION DRIVER OBJECT.');

    this.fakeit();

    this.emmiter = new events.EventEmitter();
    if (typeof options === "function" || typeof options === "undefined") {
        callback = options;
    }
    //Note that sim ignores options.

    this.port = port; //Just for log messages
    this.ready = 0;

    //Set a timer to simulate ready function
    var self = this;
    setTimeout( function (){
        self.ready = 1;

        //Init a bunch of pins, more than can ever have just to be safe
        for (var i=0; i<50; i++) {
            self.pins.push({
                supportedModes: [],
                mode: self.MODES.UNKNOWN,
                value: 0,
                report: 1
            });

            self.analogPins.push({
                supportedModes: [],
                mode: self.MODES.ANALOG,
                value: 520,
                report: 1
            });
        }
        callback();
    }, 5000);
};

Board.prototype.setSamplingInterval = function(interval) {
  var safeint = interval < 10 ? 10 : (interval > 65535 ? 65535 : interval); // constrained
  this.sampling_interval = safeint;
};

Board.prototype.close = function (callback){
    //TODO - stop all timers
    //this.pins[pin].interval_id

};

Board.prototype.digitalWrite = function(pin, value) {
    this.pins[pin].value = value;

    //Dont have to do anything. arduino driver will do a queryPinState after
    //write but TODO - maybe simulate a pin value event.
};

Board.prototype.queryPinState = function(pin, callback) {
    //Simulate an event
    var self = this;
    setTimeout(function (){
        callback(self.pins[pin].value || 0);
    }, 500);
};

Board.prototype.pinMode = function(pin, mode) {
    if ( ! this.pins[pin] ) this.pins[pin] = { value:0};
    this.pins[pin].mode = mode;
};

Board.prototype.digitalRead = function(pin, callback) {

    //start an interval timer to randomly change value
    var self = this;

    if ( this.pins[pin].mode === this.MODES.OUTPUT) return;

    this.pins[pin].interval_id = setInterval( function (){
        var value = getRandomInt(0, 2);

        //Only report if value changes
        if (value !== self.pins[pin].value){
            self.pins[pin].value = value;
            callback(value);
        }
    }, this.sampling_interval);
};

Board.prototype.analogRead = function(pin, callback) {

    //start an interval timer to randomly change value
    var self = this;
    this.analogPins[pin].interval_id = setInterval( function (){
        var value = self.analogPins[pin].value + getRandomInt(-100, 100);
        value = (value < 0) ? 0 : value;
        value = (value > 1023) ? 0 : value;

        //Only report event if value changes
        if (value !== self.analogPins[pin].value){
            self.analogPins[pin].value = value;
            callback(value);
        }
    }, this.sampling_interval);
};

//Need to imitate a bunch of vars from real firmata board
Board.prototype.fakeit = function () {
  this.MODES = {
    INPUT: 0x00,
    OUTPUT: 0x01,
    ANALOG: 0x02,
    PWM: 0x03,
    SERVO: 0x04,
    SHIFT: 0x05,
    I2C: 0x06,
    ONEWIRE: 0x07,
    STEPPER: 0x08,
    IGNORE: 0x7F,
    UNKOWN: 0x10
  };

  this.I2C_MODES = {
    WRITE: 0x00,
    READ: 1,
    CONTINUOUS_READ: 2,
    STOP_READING: 3
  };

  this.STEPPER = {
    TYPE: {
      DRIVER: 1,
      TWO_WIRE: 2,
      FOUR_WIRE: 4
    },
    RUNSTATE: {
      STOP: 0,
      ACCEL: 1,
      DECEL: 2,
      RUN: 3
    },
    DIRECTION: {
      CCW: 0,
      CW: 1
    }
  };

  this.HIGH = 1;
  this.LOW = 0;
  this.pins = [];
  this.analogPins = [];
};

module.exports = {
    Board: Board
};

function getRandomInt(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}
<|endoftext|>


<commit_before>// import React from 'react'
import React, { PropTypes } from 'react'
import d3 from 'd3'
// import {Chart} from 'vis'
import {Chart} from '../src'
import TopicFlow from '../src/TopicFlow'
import ColorView from '../src/ColorView'
import topicData from './data/topics.json'
// import Tester from '../src/Tester'
import StoryViewer from '../src/StoryViewer'
import eTopics from '../examples/data/for-hci/enduring-topics-listed.json'
import storyData from '../examples/data/for-hci/stories.json'
import eventNames from '../examples/data/for-hci/enduring-22-model.json'

const hTop = 60 * (20 + 15)

// when cursor over bar it spits out data
const toolTipFunction = (tooltipData) => {
  // console.log('toolFData', tooltipData)
  let d = tooltipData
  var toolTip =
    '' + d.label + '' +
    d3.format('n')(d.counts)
  return toolTip
}

// gets unique prefixes
const getPrefixes = (data) => {
  // GET THE PREFIXES
  let fData = data.map((arr, i) => {
    if (arr == null) {
      arr = 'EMPTY'
    }
    let arrPref = arr.split(/:|-/, 1)
    return arrPref[0]
  })
  // FILTER OUT REPEATS
  let noRepeats = fData.filter((arr, i) => {
    return fData.indexOf(arr) === i
  })
  // IF NO EMPTY PREFIX, ADD
  if (noRepeats.indexOf('EMPTY') < 0) {
    noRepeats.push('EMPTY')
  }
  return noRepeats
}
const fakeEventNames = Object.keys(topicData).map(key => { return topicData[key][0] })
const fakePrefixes = getPrefixes(fakeEventNames)
console.log('oldPref', fakePrefixes)
const prefixes = getPrefixes(eventNames.column)

// generates random data based on source
const getRandData = (topicData, amt) => {
  let dataArr = []
  let dataObj = {}
  for (let i = 0; i < amt; i++) {
    // gets random index of source data
    let rand = parseInt(Math.random() * Object.keys(topicData).length)
    if (dataArr.indexOf(rand) <= 0) {
      dataArr.push(rand)
    }
  }
  for (let i = 0; i < dataArr.length; i++) {
    dataObj[i] = topicData[dataArr[i]]
  }
  return dataObj
}

// combining the data into one obj
const allDataComb = (n) => {
  let numData = n
  let comData = []
  for (let i = 0; i < numData; i++) {
    if (i === 0) {
      comData[i] = Object.keys(topicData).map(key => { return topicData[key] })
    } else {
      // generates random number of topics between 15 and 45
      let amt = parseInt(Math.random() * 30 + 15)
      comData[i] = getRandData(topicData, amt)
      comData[i] = Object.keys(comData[i]).map(key => { return comData[i][key] })
    }
  }
  return comData
}

const setUpData = () => {
  let newData = []
  // ADDING FIRST TIMESTEP
  newData.push([])
  let firstData = Object.keys(eTopics[0]).map((scrap, index) => {
    let data = eTopics[0][index]
    newData[0][index] = {events: data, story: [], topicID: index, hour: 0}
    return {events: data, story: []}
  })
  // ADDING REMAINING TIMESTEPS BY USING STORY DATA AS TOPIC FILTER
  let mapData = storyData.map((data, index) => {
    newData.push([])
    // console.log('data', newData[index])
    // GOING THROUGH TOPICS FOR TIMESTEP - INDEX
    return Object.keys(data).map((scrap, key) => {
      let sData = data[key]
      // FROM MERGE || NEW TOPIC [1][?]
      if (sData.length > 1 || sData[0][0] === 1) {
        // START STORY AT EMPTY
        let s = []
        // GOING THROUGH STORIES ([0||1][?], [0||1][?], [0||1][?])
        return sData.map((d, i) => {
          // console.log('hour', index + 1, 'topic', key, 'd', d)
          // IF STORY OF A MERGE TOPIC [0][?], GET STORY [?]
          if (d[0] === 0) {
            s.push(d[1])
            // IF THE PREVIOUS TIMESTEP DOES NOT INCLUDE TOPIC ADD
            if (newData[index][d[1]] == null) {
              let eventInfo = eTopics[index][d[1]]
              // IF THE EVENTS ARE NON-EXISTANT, MAKE IT EMPTY
              if (eventInfo == null) {
                eventInfo = 'EMPTY'
              }
              newData[index][d[1]] = {
                events: eventInfo,
                story: [],
                topicID: d[1],
                hour: index
              }
            }
          }
          // IF THE STORY IS NULL OR ON FIRST INDEX ADD INFO
          if (s[0] != null || i === 0) {
            let eventInfo = eTopics[index + 1][key]
            if (eventInfo == null) {
              eventInfo = 'EMPTY'
            }
            newData[index + 1][key] = {
              events: eventInfo,
              story: s,
              topicID: key,
              hour: index + 1
            }
          }
          return (
            newData[index + 1][key]
          )
        })
      }
    })
  })
  mapData.unshift(firstData)
  // using newData because this.topicData is returning undefined in some cases.
  // might be troublesome later on...
  mapData = newData
  return mapData
}

const makeAdjacencyList = () => {
  let tuneIn = (adjList, story, index) => {
    // console.log('tInIndex', index, 'tInStory', story)
    // console.log(adjList)
    let piece = adjList[index].story
    let sArr = story.concat(index)
    // console.log('tIPiece', adjList[index].story, 'sArr', sArr)
    // if there is a story go to it
    if (piece[0] != null) {
      // update the stories
      // console.log('loop', sArr)
      return tuneIn(adjList, sArr, piece[0])
    } else {
      // console.log('finalsArr', sArr)
      return sArr
    }
  }
  let topics = setUpData()
  let adjacencyList = []
  topics.map((data, index) => {
    Object.keys(data).map((key, i) => {
      let d = data[key]
      let s = []
      // NEITHER NEW TOPIC OR HOUR 0
      if (d.story[0] != null) {
        // MIGHT HAVE MULTIPLE STORIES
        d.story.map((dStory, dI) => {
          // RIGHT NOW STORY IS ONLY PREVIOUS TOPIC INDEX
          adjacencyList.map((aLD, aLI) => {
            if (aLD.topicID === dStory && aLD.hour === index - 1) {
              s.push(aLI)
            }
          })
        })
      }
      adjacencyList.push({
        story: s,
        prevStory: s,
        events: d.events,
        topicID: i,
        hour: d.hour
      })
    })
  })
  let checkGreater = (arr, index) => {
    let notChecked = true
    arr.every((eD, eI) => {
      if (eD > index) {
        notChecked = false
      }
    })
    return notChecked
  }
  for (let i = adjacencyList.length - 1; i >= 0; i--) {
    let d = adjacencyList[i]
    // console.log('forD', d)
    // make check for if the story index is > than the current index
    // that way not doing extra work
    if (d.story[0] != null) {
      // DONT ADD STORIES IF ALREADY ADDED
      if (checkGreater(d.story, i)) {
        d.story.map((sD, sI) => {
          let newS = tuneIn(adjacencyList, [i], sD)
          for (let j = 0; j < newS.length; j++) {
            let s = newS[j]
            let newSCopy = JSON.parse(JSON.stringify(newS))
            newSCopy.splice(j, 1)
            // console.log('sIndex', s, 'copy', newSCopy)
            adjacencyList[s].story = newSCopy
            // console.log('adjListS', adjacencyList[s].story)
          }
        })
      }
    }
  }
  console.log('topicsList', topics)
  console.log('adjacencyList', adjacencyList)
  return adjacencyList
}
const aList = makeAdjacencyList()

const tData = (n, start) => {
  let num = n
  let topics = setUpData()
  if (n + start > topics.length - 1) {
    num = topics.length - 1 - start
  }
  let comData = []
  for (let i = 0; i < num; i++) {
    comData[i] = topics[start + i]
  }
  console.log('tData', comData)
  return comData
}

const nData = 7
const fakeData = allDataComb(nData)
const allData = tData(nData, 0)

class TopicsContainer extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      data: [],
      loading: true,
      status: '',
      clickArray: []
    }
    this.toolTipFunction = toolTipFunction
    this.onClick = this._onBarClick.bind(this)
    this.topicData = []
  }
  _onBarClick (toggleList) {
    // takes toggle list and updates clickArray state
    // console.log('toggleList', toggleList)
    this.setState({clickArray: toggleList}, () => {
      this.refs.updateChart.forceUpdate()
      this.refs.updateChart2.forceUpdate()
    })
  }
  componentWillMount () {
    // console.log('topicData', topicData)
  }
  componentDidMount () {
    let setClickArr = {}
    for (let i = 0; i < this.props.colorDomain.length; i++) {
      setClickArr[this.props.colorDomain[i]] = true
    }
    this.setState({clickArray: setClickArr})
    this.fetchData(this.props)
  }
  shouldComponentUpdate (nextProps, nextState) {
    // this.fetchData(nextProps)
    // return nextState.loading !== this.state.loading
    return true
  }
  componentWillReceiveProps (nextProps) {
    // this.fetchData(this.props)
    this.setState({loading: true})
    return true
  }
  fetchData (nextProps) {
    this.setState({data: [], loading: true, status: ''})
    // doesn't re-render if setting state twice
    // this would be where it updates data..
    // if the data didn't go beyond this ... loading wouldn't be set to false
    // this.props.adjacencyList = aList
    this.setState({data: allData, loading: false, status: 'OK'})
  }
  render () {
    console.log('realData', allData)
    console.log('fakeData', fakeData)
    console.log(aList)
    // this.setUpData()
    let {className, ...props} = this.props
    return (

          <Chart className='col-md-2' ref='updateChart2'{...props} {...this.state} tipFunction={this.toolTipFunction} yAxis={false} xAxis={false} xScaleType='linear' height={600}>
            <ColorView className='col-md-2' {...props} clickArray={this.state.clickArray} ref='colorView' onBarClick={this.onClick} />
          </Chart>
          <Chart className='col-md-10' ref='updateChart' {...props} {...this.state} tipFunction={this.toolTipFunction} yAxis={false} xAxis={false} height={hTop}>
            <TopicFlow className='col-md-10' {...props} clickArray={this.state.clickArray} colorView={this.refs.colorView} onBarClick={this.onClick} />
          </Chart>

          <Chart className='col-md-12' {...props} {...this.state} tipFunction={this.toolTipFunction} yAxis={false} xAxis={false} height={1000} margin={{top: 40, right: 10, bottom: 10, left: 80}} width={5000}>
            <StoryViewer className='col-md-12' {...props} clickArray={this.state.clickArray} colorView={this.refs.colorView} onBarClick={this.onClick} />
          </Chart>

    )
  }
}

TopicsContainer.defaultProps = {
  url: '',
  numTData: nData,
  colorDomain: prefixes,
  className: 'col-md-12',
  adjacencyList: aList
}
TopicsContainer.propTypes = {
  className: PropTypes.string,
  numTData: PropTypes.number,
  url: PropTypes.string,
  colorDomain: PropTypes.array,
  adjacencyList: PropTypes.array
}

export default TopicsContainer
<commit_msg>some comments removed<commit_after>// import React from 'react'
import React, { PropTypes } from 'react'
import d3 from 'd3'
// import {Chart} from 'vis'
import {Chart} from '../src'
import TopicFlow from '../src/TopicFlow'
import ColorView from '../src/ColorView'
import topicData from './data/topics.json'
// import Tester from '../src/Tester'
import StoryViewer from '../src/StoryViewer'
import eTopics from '../examples/data/for-hci/enduring-topics-listed.json'
import storyData from '../examples/data/for-hci/stories.json'
import eventNames from '../examples/data/for-hci/enduring-22-model.json'

const hTop = 60 * (20 + 15)

// when cursor over bar it spits out data
const toolTipFunction = (tooltipData) => {
  // console.log('toolFData', tooltipData)
  let d = tooltipData
  var toolTip =
    '' + d.label + '' +
    d3.format('n')(d.counts)
  return toolTip
}

// gets unique prefixes
const getPrefixes = (data) => {
  // GET THE PREFIXES
  let fData = data.map((arr, i) => {
    if (arr == null) {
      arr = 'EMPTY'
    }
    let arrPref = arr.split(/:|-/, 1)
    return arrPref[0]
  })
  // FILTER OUT REPEATS
  let noRepeats = fData.filter((arr, i) => {
    return fData.indexOf(arr) === i
  })
  // IF NO EMPTY PREFIX, ADD
  if (noRepeats.indexOf('EMPTY') < 0) {
    noRepeats.push('EMPTY')
  }
  return noRepeats
}
const fakeEventNames = Object.keys(topicData).map(key => { return topicData[key][0] })
const fakePrefixes = getPrefixes(fakeEventNames)
console.log('oldPref', fakePrefixes)
const prefixes = getPrefixes(eventNames.column)

// generates random data based on source
const getRandData = (topicData, amt) => {
  let dataArr = []
  let dataObj = {}
  for (let i = 0; i < amt; i++) {
    // gets random index of source data
    let rand = parseInt(Math.random() * Object.keys(topicData).length)
    if (dataArr.indexOf(rand) <= 0) {
      dataArr.push(rand)
    }
  }
  for (let i = 0; i < dataArr.length; i++) {
    dataObj[i] = topicData[dataArr[i]]
  }
  return dataObj
}

// combining the data into one obj
const allDataComb = (n) => {
  let numData = n
  let comData = []
  for (let i = 0; i < numData; i++) {
    if (i === 0) {
      comData[i] = Object.keys(topicData).map(key => { return topicData[key] })
    } else {
      // generates random number of topics between 15 and 45
      let amt = parseInt(Math.random() * 30 + 15)
      comData[i] = getRandData(topicData, amt)
      comData[i] = Object.keys(comData[i]).map(key => { return comData[i][key] })
    }
  }
  return comData
}

const setUpData = () => {
  let newData = []
  // ADDING FIRST TIMESTEP
  newData.push([])
  let firstData = Object.keys(eTopics[0]).map((scrap, index) => {
    let data = eTopics[0][index]
    newData[0][index] = {events: data, story: [], topicID: index, hour: 0}
    return {events: data, story: []}
  })
  // ADDING REMAINING TIMESTEPS BY USING STORY DATA AS TOPIC FILTER
  let mapData = storyData.map((data, index) => {
    newData.push([])
    // console.log('data', newData[index])
    // GOING THROUGH TOPICS FOR TIMESTEP - INDEX
    return Object.keys(data).map((scrap, key) => {
      let sData = data[key]
      // FROM MERGE || NEW TOPIC [1][?]
      if (sData.length > 1 || sData[0][0] === 1) {
        // START STORY AT EMPTY
        let s = []
        // GOING THROUGH STORIES ([0||1][?], [0||1][?], [0||1][?])
        return sData.map((d, i) => {
          // IF STORY OF A MERGE TOPIC [0][?], GET STORY [?]
          if (d[0] === 0) {
            s.push(d[1])
            // IF THE PREVIOUS TIMESTEP DOES NOT INCLUDE TOPIC ADD
            if (newData[index][d[1]] == null) {
              let eventInfo = eTopics[index][d[1]]
              // IF THE EVENTS ARE NON-EXISTANT, MAKE IT EMPTY
              if (eventInfo == null) {
                eventInfo = 'EMPTY'
              }
              newData[index][d[1]] = {
                events: eventInfo,
                story: [],
                topicID: d[1],
                hour: index
              }
            }
          }
          // IF THE STORY IS NULL OR ON FIRST INDEX ADD INFO
          if (s[0] != null || i === 0) {
            let eventInfo = eTopics[index + 1][key]
            if (eventInfo == null) {
              eventInfo = 'EMPTY'
            }
            newData[index + 1][key] = {
              events: eventInfo,
              story: s,
              topicID: key,
              hour: index + 1
            }
          }
          return (
            newData[index + 1][key]
          )
        })
      }
    })
  })
  mapData.unshift(firstData)
  // using newData because this.topicData is returning undefined in some cases.
  // might be troublesome later on...
  mapData = newData
  return mapData
}

const makeAdjacencyList = () => {
  let tuneIn = (adjList, story, index) => {
    let piece = adjList[index].story
    let sArr = story.concat(index)
    // if there is a story go to it
    if (piece[0] != null) {
      // update the stories
      return tuneIn(adjList, sArr, piece[0])
    } else {
      return sArr
    }
  }
  let topics = setUpData()
  let adjacencyList = []
  topics.map((data, index) => {
    Object.keys(data).map((key, i) => {
      let d = data[key]
      let s = []
      // NEITHER NEW TOPIC OR HOUR 0
      if (d.story[0] != null) {
        // MIGHT HAVE MULTIPLE STORIES
        d.story.map((dStory, dI) => {
          // RIGHT NOW STORY IS ONLY PREVIOUS TOPIC INDEX
          adjacencyList.map((aLD, aLI) => {
            if (aLD.topicID === dStory && aLD.hour === index - 1) {
              s.push(aLI)
            }
          })
        })
      }
      adjacencyList.push({
        story: s,
        prevStory: s,
        events: d.events,
        topicID: i,
        hour: d.hour
      })
    })
  })
  // LOOKS FOR A STORY THAT HAS AN INDEX GREATER THAN CURRENT
  let checkGreater = (arr, index) => {
    let notChecked = true
    arr.every((eD, eI) => {
      if (eD > index) {
        notChecked = false
      }
    })
    return notChecked
  }
  for (let i = adjacencyList.length - 1; i >= 0; i--) {
    let d = adjacencyList[i]
    if (d.story[0] != null) {
      // CHECK TO SEE IF STORY FILLED ALREADY
      if (checkGreater(d.story, i)) {
        // LOOPING THROUGH STORIES
        d.story.map((sD, sI) => {
          // CYCLES FOR ALL THE STORIES OF THAT TOPIC
          let newS = tuneIn(adjacencyList, [i], sD)
          for (let j = 0; j < newS.length; j++) {
            let s = newS[j]
            let newSCopy = JSON.parse(JSON.stringify(newS))
            newSCopy.splice(j, 1)
            adjacencyList[s].story = newSCopy
          }
        })
      }
    }
  }
  console.log('topicsList', topics)
  console.log('adjacencyList', adjacencyList)
  return adjacencyList
}
const aList = makeAdjacencyList()

const tData = (n, start) => {
  let num = n
  let topics = setUpData()
  if (n + start > topics.length - 1) {
    num = topics.length - 1 - start
  }
  let comData = []
  for (let i = 0; i < num; i++) {
    comData[i] = topics[start + i]
  }
  console.log('tData', comData)
  return comData
}

const nData = 7
const fakeData = allDataComb(nData)
const allData = tData(nData, 0)

class TopicsContainer extends React.Component {
  constructor (props) {
    super(props)
    this.state = {
      data: [],
      loading: true,
      status: '',
      clickArray: []
    }
    this.toolTipFunction = toolTipFunction
    this.onClick = this._onBarClick.bind(this)
    this.topicData = []
  }
  _onBarClick (toggleList) {
    // takes toggle list and updates clickArray state
    // console.log('toggleList', toggleList)
    this.setState({clickArray: toggleList}, () => {
      this.refs.updateChart.forceUpdate()
      this.refs.updateChart2.forceUpdate()
    })
  }
  componentWillMount () {
    // console.log('topicData', topicData)
  }
  componentDidMount () {
    let setClickArr = {}
    for (let i = 0; i < this.props.colorDomain.length; i++) {
      setClickArr[this.props.colorDomain[i]] = true
    }
    this.setState({clickArray: setClickArr})
    this.fetchData(this.props)
  }
  shouldComponentUpdate (nextProps, nextState) {
    // this.fetchData(nextProps)
    // return nextState.loading !== this.state.loading
    return true
  }
  componentWillReceiveProps (nextProps) {
    // this.fetchData(this.props)
    this.setState({loading: true})
    return true
  }
  fetchData (nextProps) {
    this.setState({data: [], loading: true, status: ''})
    // doesn't re-render if setting state twice
    // this would be where it updates data..
    // if the data didn't go beyond this ... loading wouldn't be set to false
    // this.props.adjacencyList = aList
    this.setState({data: allData, loading: false, status: 'OK'})
  }
  render () {
    console.log('realData', allData)
    console.log('fakeData', fakeData)
    console.log(aList)
    // this.setUpData()
    let {className, ...props} = this.props
    return (

          <Chart className='col-md-2' ref='updateChart2'{...props} {...this.state} tipFunction={this.toolTipFunction} yAxis={false} xAxis={false} xScaleType='linear' height={600}>
            <ColorView className='col-md-2' {...props} clickArray={this.state.clickArray} ref='colorView' onBarClick={this.onClick} />
          </Chart>
          <Chart className='col-md-10' ref='updateChart' {...props} {...this.state} tipFunction={this.toolTipFunction} yAxis={false} xAxis={false} height={hTop}>
            <TopicFlow className='col-md-10' {...props} clickArray={this.state.clickArray} colorView={this.refs.colorView} onBarClick={this.onClick} />
          </Chart>

          <Chart className='col-md-12' {...props} {...this.state} tipFunction={this.toolTipFunction} yAxis={false} xAxis={false} height={1000} margin={{top: 40, right: 10, bottom: 10, left: 80}} width={5000}>
            <StoryViewer className='col-md-12' {...props} clickArray={this.state.clickArray} colorView={this.refs.colorView} onBarClick={this.onClick} />
          </Chart>

    )
  }
}

TopicsContainer.defaultProps = {
  url: '',
  numTData: nData,
  colorDomain: prefixes,
  className: 'col-md-12',
  adjacencyList: aList
}
TopicsContainer.propTypes = {
  className: PropTypes.string,
  numTData: PropTypes.number,
  url: PropTypes.string,
  colorDomain: PropTypes.array,
  adjacencyList: PropTypes.array
}

export default TopicsContainer
<|endoftext|>


<commit_before>Array.matrix = function (m, initial) {
    var a, i, j, mat = [];
    for (i = 0; i < m; i += 1) {
        a = [];
        for (j = 0; j < m; j += 1) {
            a[j] = initial;
        }
        mat[i] = a;
    }
    return mat;
};

var baseBoard = function (spec) {
	var players = ['A', 'B'];
	var playerIndex = 0;
	var board = Array.matrix(spec.size, false);
	var lastMove = null;

	var getCurrentPlayer = function () {
		return players[playerIndex];
	};

	var makeMove = function (move) {
		lastMove = spec.placement(board, move.x, move.y);
	};

	var generateRandomMove = function () {
		var x = Math.floor(Math.random()*spec.size),
			y = Math.floor(Math.random()*spec.size);

		return { x: x, y: y};
	};

	var outputStatus = function () {
		for(var i = 0;i < spec.size;i++) {
			var rowStr = "";
			for(var j = 0; j < spec.size;j++) {
				if (!board[i][j]) {
					rowStr += "-";
				} else {
					rowStr += board[i][j];
				}
			}
			console.log(rowStr);
		}
	};

	var advancePlayer = function () {
		playerIndex = (playerIndex + 1) % players.length;
		return this.player();
	};

	var inBoard
	var contiguousElements = function (direction) {
		var lastPlayer = board[lastMove.x][lastMove.y];
		var origin = { x: lastMove.x, y: lastMove.y };
	};

	return {
		player: function () {
			getCurrentPlayer();
		},

		connectionVertical: function () {
			return contiguousElements({ x: 0, y: 1 }) >= spec.connectionlength;
		},

		gameOver: function () {
			return spec.completion.apply(this);
		},

		play: function (){
			while (!this.gameOver()) {
				makeMove(generateRandomMove());
				outputStatus.apply(this);
				this.advancePlayer();
			}
		}
	};
};

var ticTacToe = baseBoard({
	size: 3,
	connectionLength: 3,
	completion: function () {
		// return this.connectionVertical() || this.connectionDiagonalRight() || this.connectionDiagonalLeft();
		return this.connectionVertical();
	},

	placement: function (board, x, y) {
		board[x][y] = this.player();

		return {x: x, y: y};
	}
});<commit_msg>pushing some test things<commit_after>Array.matrix = function (m, initial) {
    var a, i, j, mat = [];
    for (i = 0; i < m; i += 1) {
        a = [];
        for (j = 0; j < m; j += 1) {
            a[j] = initial;
        }
        mat[i] = a;
    }
    return mat;
};

var baseBoard = function (spec) {
	var players = ['A', 'B'];
	var playerIndex = 0;
	var board = Array.matrix(spec.size, false);
	var lastMove = null;

	var getCurrentPlayer = function () {
		return players[playerIndex];
	};

	var makeMove = function (move) {
		lastMove = spec.placement(board, move.x, move.y);
	};

	var generateRandomMove = function () {
		var x = Math.floor(Math.random()*spec.size),
			y = Math.floor(Math.random()*spec.size);

		return { x: x, y: y };
	};

	var iterateOverBoard = function (fn) {
		for(var i = 0;i < spec.size;i++) {
			for(var j = 0; j < spec.size;j++) {
				fn(board[i][j], x, y);
			}
		}
	}

	var outputStatus = function () {
		return iterateOverBoard(function (val, x, y) {
			if (x === spec.size-1) {

			}
		});
	};

	var advancePlayer = function () {
		playerIndex = (playerIndex + 1) % players.length;
		return this.player();
	};

	var numberInLine = function (origin, direction) {
		var count = 0;
		var comparer = board[origin.x][origin.y];
		var current = { x: origin.x + direction.x, origin.y + direction.y };

		while (board[current.x][current.y] === comparer) {
			count++;
		}

		return count;
	};

	var contiguousElements = function (direction) {
		var lastPlayer = board[lastMove.x][lastMove.y];
		var origin = { x: lastMove.x, y: lastMove.y };

		return 1 + numberInLine(origin, direction) + numberInLine(origin, { x: -1*direction.x, y: -1*direction.y });
	};

	return {
		player: function () {
			getCurrentPlayer();
		},

		connectionVertical: function () {
			return contiguousElements({ x: 0, y: 1 }) >= spec.connectionlength;
		},

		gameOver: function () {
			return spec.completion.apply(this) || ;
		},

		play: function (){
			while (!this.gameOver()) {
				makeMove(generateRandomMove());
				outputStatus.apply(this);
				this.advancePlayer();
			}
		}
	};
};

var ticTacToe = baseBoard({
	size: 3,
	connectionLength: 3,
	completion: function () {
		// return this.connectionVertical() || this.connectionDiagonalRight() || this.connectionDiagonalLeft();
		return this.connectionVertical();
	},

	placement: function (board, x, y) {
		board[x][y] = this.player();

		return {x: x, y: y};
	}
});<|endoftext|>


<commit_before><commit_msg>now automatically sets the firstDomain based on window.location.href<commit_after><|endoftext|>


<commit_before>/*
 * VR Comic Book Reader for Oculus Rift
 */
VRCBR = (function(doc) {
    "use strict";

    var imageIndex = 1;
    var LAST_IMAGE_INDEX = 5;
    var COMIC_FILE_PREFIX = 'resources/';
    var COMIC_FILE_POSTFIX = '.jpg';

    // Setup three.js WebGL renderer
    var renderer = new THREE.WebGLRenderer( { antialias: true } );

    // Append the canvas element created by the renderer to document body element.
    doc.body.appendChild( renderer.domElement );

    // Create a three.js scene
    var scene = new THREE.Scene();

    // Create a three.js camera
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );

    // Apply VR headset positional data to camera.
    var controls = new THREE.VRControls( camera );

    // Apply VR stereo rendering to renderer
    var effect = new THREE.VREffect( renderer );
    effect.setSize( window.innerWidth, window.innerHeight );

    // Create 3d objects
    var geometry = new THREE.BoxGeometry( 20, 30.91, 20 );

    THREE.ImageUtils.crossOrigin = '';
    var material = new THREE.MeshBasicMaterial(
            {map: THREE.ImageUtils.loadTexture( COMIC_FILE_PREFIX + imageIndex + COMIC_FILE_POSTFIX )}
            );

    var cube = new THREE.Mesh( geometry, material );

    // Position cube mesh
    cube.position.z = -20;

    // Add cube mesh to your three.js scene
    scene.add( cube );

    // Request animation frame loop function
    var animate = function() {
        // Update VR headset position and apply to camera.
        controls.update();

        // Render the scene through the VREffect.
        effect.render( scene, camera );

        requestAnimationFrame( animate );
    }

    // Kick off animation loop
    animate();

    // Listen for double click event to enter full-screen VR mode
    document.body.addEventListener( 'dblclick', function() {
        effect.setFullScreen( true );
    });

    // Listen for keyboard event and zero positional sensor on appropriate keypress.
    var onkey = function(event) {
        event.preventDefault();

        var moveValue = 0.2;
        if (event.keyCode == 90) { // z
            controls.zeroSensor();
        } else if (event.keyCode == 32) { // Space
            cube.position.x = 0;
            cube.position.y = -9;
        } else if (event.keyCode == 37) { // Left
            if (imageIndex === 1) {
                imageIndex = LAST_IMAGE_INDEX;
            } else {
                imageIndex--;
            }
            swapComicPage(imageIndex);
        } else if (event.keyCode == 38) { // Up
            cube.position.z = cube.position.z + moveValue;
        } else if (event.keyCode == 39) { // Right
            if (imageIndex === LAST_IMAGE_INDEX) {
                imageIndex = 1;
            } else {
                imageIndex++;
            }
            swapComicPage(imageIndex);
        } else if (event.keyCode == 40) { // Down
            cube.position.z = cube.position.z - moveValue;
        } else if (event.keyCode == 87) { //W
            cube.position.y = cube.position.y - moveValue;
        } else if (event.keyCode == 83) { //S
            cube.position.y = cube.position.y + moveValue;
        } else if (event.keyCode == 65) { //A
            cube.position.x = cube.position.x + moveValue;
        } else if (event.keyCode == 68) { //D
            cube.position.x = cube.position.x - moveValue;
        }

    };

    var swapComicPage = function(index) {
        material.map = THREE.ImageUtils.loadTexture( COMIC_FILE_PREFIX + index + COMIC_FILE_POSTFIX );
        material.needsUpdate = true;
    }

    window.addEventListener("keydown", onkey, true);

    // Handle window resizes
    var onWindowResize = function() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        effect.setSize( window.innerWidth, window.innerHeight );
    }

    window.addEventListener( 'resize', onWindowResize, false );
    return { };
} (document) );
<commit_msg>Code formatting<commit_after>/*
 * VR Comic Book Reader for Oculus Rift
 */
VRCBR = (function(doc) {
    "use strict";

    var imageIndex = 1;
    var LAST_IMAGE_INDEX = 5;
    var COMIC_FILE_PREFIX = 'resources/';
    var COMIC_FILE_POSTFIX = '.jpg';

    // Setup three.js WebGL renderer
    var renderer = new THREE.WebGLRenderer( { antialias: true } );

    // Append the canvas element created by the renderer to document body element.
    doc.body.appendChild( renderer.domElement );

    // Create a three.js scene
    var scene = new THREE.Scene();

    // Create a three.js camera
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );

    // Apply VR headset positional data to camera.
    var controls = new THREE.VRControls( camera );

    // Apply VR stereo rendering to renderer
    var effect = new THREE.VREffect( renderer );
    effect.setSize( window.innerWidth, window.innerHeight );

    // Create 3d objects
    var geometry = new THREE.BoxGeometry( 20, 30.91, 20 );

    THREE.ImageUtils.crossOrigin = '';
    var material = new THREE.MeshBasicMaterial({
        map: THREE.ImageUtils.loadTexture( COMIC_FILE_PREFIX + imageIndex + COMIC_FILE_POSTFIX )
    });

    var cube = new THREE.Mesh( geometry, material );

    // Position cube mesh
    cube.position.z = -20;

    // Add cube mesh to your three.js scene
    scene.add( cube );

    // Request animation frame loop function
    var animate = function() {
        // Update VR headset position and apply to camera.
        controls.update();

        // Render the scene through the VREffect.
        effect.render( scene, camera );

        requestAnimationFrame( animate );
    }

    // Kick off animation loop
    animate();

    // Listen for double click event to enter full-screen VR mode
    document.body.addEventListener( 'dblclick', function() {
        effect.setFullScreen( true );
    });

    // Listen for keyboard event and zero positional sensor on appropriate keypress.
    var onkey = function(event) {
        event.preventDefault();

        var moveValue = 0.2;
        if (event.keyCode == 90) { // z
            controls.zeroSensor();
        } else if (event.keyCode == 32) { // Space
            cube.position.x = 0;
            cube.position.y = -9;
        } else if (event.keyCode == 37) { // Left
            if (imageIndex === 1) {
                imageIndex = LAST_IMAGE_INDEX;
            } else {
                imageIndex--;
            }
            swapComicPage(imageIndex);
        } else if (event.keyCode == 38) { // Up
            cube.position.z = cube.position.z + moveValue;
        } else if (event.keyCode == 39) { // Right
            if (imageIndex === LAST_IMAGE_INDEX) {
                imageIndex = 1;
            } else {
                imageIndex++;
            }
            swapComicPage(imageIndex);
        } else if (event.keyCode == 40) { // Down
            cube.position.z = cube.position.z - moveValue;
        } else if (event.keyCode == 87) { //W
            cube.position.y = cube.position.y - moveValue;
        } else if (event.keyCode == 83) { //S
            cube.position.y = cube.position.y + moveValue;
        } else if (event.keyCode == 65) { //A
            cube.position.x = cube.position.x + moveValue;
        } else if (event.keyCode == 68) { //D
            cube.position.x = cube.position.x - moveValue;
        }

    };

    var swapComicPage = function(index) {
        material.map = THREE.ImageUtils.loadTexture( COMIC_FILE_PREFIX + index + COMIC_FILE_POSTFIX );
        material.needsUpdate = true;
    }

    window.addEventListener("keydown", onkey, true);

    // Handle window resizes
    var onWindowResize = function() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        effect.setSize( window.innerWidth, window.innerHeight );
    }

    window.addEventListener( 'resize', onWindowResize, false );
    return { };
} (document) );
<|endoftext|>


<commit_before>import reducer from 'src/data_explorer/reducers/queryConfigs'
import defaultQueryConfig from 'src/utils/defaultQueryConfig'
import {
  chooseNamespace,
  chooseMeasurement,
  toggleField,
  applyFuncsToField,
  chooseTag,
  groupByTag,
  groupByTime,
  toggleTagAcceptance,
  updateRawQuery,
  editRawQueryStatus,
} from 'src/data_explorer/actions/view'

const fakeAddQueryAction = (panelID, queryID) => {
  return {
    type: 'ADD_QUERY',
    payload: {panelID, queryID},
  }
}

function buildInitialState(queryId, params) {
  return Object.assign({}, defaultQueryConfig(queryId), params)
}

describe('Chronograf.Reducers.queryConfig', () => {
  const queryId = 123

  it('can add a query', () => {
    const state = reducer({}, fakeAddQueryAction('blah', queryId))

    const actual = state[queryId]
    const expected = defaultQueryConfig(queryId)
    expect(actual).to.deep.equal(expected)
  })

  describe('choosing db, rp, and measurement', () => {
    let state
    beforeEach(() => {
      state = reducer({}, fakeAddQueryAction('any', queryId))
    })

    it('sets the db and rp', () => {
      const newState = reducer(state, chooseNamespace(queryId, {
        database: 'telegraf',
        retentionPolicy: 'monitor',
      }))

      expect(newState[queryId].database).to.equal('telegraf')
      expect(newState[queryId].retentionPolicy).to.equal('monitor')
    })

    it('sets the measurement', () => {
      const newState = reducer(state, chooseMeasurement(queryId, 'mem'))

      expect(newState[queryId].measurement).to.equal('mem')
    })
  })

  describe('a query has measurements and fields', () => {
    let state
    beforeEach(() => {
      const one = reducer({}, fakeAddQueryAction('any', queryId))
      const two = reducer(one, chooseNamespace(queryId, {
        database: '_internal',
        retentionPolicy: 'daily',
      }))
      const three = reducer(two, chooseMeasurement(queryId, 'disk'))
      state = reducer(three, toggleField(queryId, {field: 'a great field', funcs: []}))
    })

    describe('choosing a new namespace', () => {
      it('clears out the old measurement and fields', () => { // what about tags?
        expect(state[queryId].measurement).to.exist
        expect(state[queryId].fields.length).to.equal(1)

        const newState = reducer(state, chooseNamespace(queryId, {
          database: 'newdb',
          retentionPolicy: 'newrp',
        }))

        expect(newState[queryId].measurement).not.to.exist
        expect(newState[queryId].fields.length).to.equal(0)
      })
    })

    describe('choosing a new measurement', () => {
      it('leaves the namespace and clears out the old fields', () => { // what about tags?
        expect(state[queryId].fields.length).to.equal(1)

        const newState = reducer(state, chooseMeasurement(queryId, 'newmeasurement'))

        expect(state[queryId].database).to.equal(newState[queryId].database)
        expect(state[queryId].retentionPolicy).to.equal(newState[queryId].retentionPolicy)
        expect(newState[queryId].fields.length).to.equal(0)
      })
    })

    describe('when the query is part of a kapacitor rule', () => {
      it('only allows one field', () => {
        expect(state[queryId].fields.length).to.equal(1)

        const isKapacitorRule = true
        const newState = reducer(state, toggleField(queryId, {field: 'a different field', funcs: []}, isKapacitorRule))

        expect(newState[queryId].fields.length).to.equal(1)
        expect(newState[queryId].fields[0].field).to.equal('a different field')
      })
    })
  })

  describe('APPLY_FUNCS_TO_FIELD', () => {
    it('applies functions to a field without any existing functions', () => {
      const queryId = 123
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [
            {field: 'f1', funcs: ['fn1', 'fn2']},
            {field: 'f2', funcs: ['fn1']},
          ],
        },
      }
      const action = applyFuncsToField(queryId, {
        field: 'f1',
        funcs: ['fn3', 'fn4'],
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].fields).to.eql([
        {field: 'f1', funcs: ['fn3', 'fn4']},
        {field: 'f2', funcs: ['fn1']},
      ])
    })

    it('removes all functions and group by time when one field has no funcs applied', () => {
      const queryId = 123
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [
            {field: 'f1', funcs: ['fn1', 'fn2']},
            {field: 'f2', funcs: ['fn3', 'fn4']},
          ],
          groupBy: {
            time: '1m',
            tags: [],
          },
        },
      }

      const action = applyFuncsToField(queryId, {
        field: 'f1',
        funcs: [],
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].fields).to.eql([
        {field: 'f1', funcs: []},
        {field: 'f2', funcs: []},
      ])
      expect(nextState[queryId].groupBy.time).to.equal(null)
    })
  })

  describe('CHOOSE_TAG', () => {
    it('adds a tag key/value to the query', () => {
      const queryId = 123
      const initialState = {
        [queryId]: buildInitialState(queryId, {
          tags: {
            k1: ['v0'],
            k2: ['foo'],
          },
        }),
      }
      const action = chooseTag(queryId, {
        key: 'k1',
        value: 'v1',
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].tags).to.eql({
        k1: ['v0', 'v1'],
        k2: ['foo'],
      })
    })

    it('creates a new entry if it\'s the first key', () => {
      const queryId = 123
      const initialState = {
        [queryId]: buildInitialState(queryId, {
          tags: {},
        }),
      }
      const action = chooseTag(queryId, {
        key: 'k1',
        value: 'v1',
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].tags).to.eql({
        k1: ['v1'],
      })
    })

    it('removes a value that is already in the list', () => {
      const queryId = 123
      const initialState = {
        [queryId]: buildInitialState(queryId, {
          tags: {
            k1: ['v1'],
          },
        }),
      }
      const action = chooseTag(queryId, {
        key: 'k1',
        value: 'v1',
      })

      const nextState = reducer(initialState, action)

      // TODO: this should probably remove the `k1` property entirely from the tags object
      expect(nextState[queryId].tags).to.eql({})
    })
  })

  describe('GROUP_BY_TAG', () => {
    it('adds a tag key/value to the query', () => {
      const queryId = 123
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [],
          tags: {},
          groupBy: {tags: [], time: null},
        },
      }
      const action = groupByTag(queryId, 'k1')

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].groupBy).to.eql({
        time: null,
        tags: ['k1'],
      })
    })

    it('removes a tag if the given tag key is already in the GROUP BY list', () => {
      const queryId = 123
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [],
          tags: {},
          groupBy: {tags: ['k1'], time: null},
        },
      }
      const action = groupByTag(queryId, 'k1')

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].groupBy).to.eql({
        time: null,
        tags: [],
      })
    })
  })

  describe('TOGGLE_TAG_ACCEPTANCE', () => {
    it('it toggles areTagsAccepted', () => {
      const queryId = 123
      const initialState = {
        [queryId]: buildInitialState(queryId),
      }
      const action = toggleTagAcceptance(queryId)

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].areTagsAccepted).to.equal(!initialState[queryId].areTagsAccepted)
    })
  })

  describe('GROUP_BY_TIME', () => {
    it('applys the appropriate group by time', () => {
      const queryId = 123
      const time = '100y'
      const initialState = {
        [queryId]: buildInitialState(queryId),
      }

      const action = groupByTime(queryId, time)

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].groupBy.time).to.equal(time)
    })
  })

  it('updates a query\'s raw text', () => {
    const queryId = 123
    const initialState = {
      [queryId]: buildInitialState(queryId),
    }
    const text = 'foo'
    const action = updateRawQuery(queryId, text)

    const nextState = reducer(initialState, action)

    expect(nextState[queryId].rawText).to.equal('foo')
  })

  it('updates a query\'s raw status', () => {
    const queryId = 123
    const initialState = {
      [queryId]: buildInitialState(queryId),
    }
    const status = 'your query was sweet'
    const action = editRawQueryStatus(queryId, status)

    const nextState = reducer(initialState, action)

    expect(nextState[queryId].rawStatus).to.equal(status)
  })
})

<commit_msg>Lint tests<commit_after>import reducer from 'src/data_explorer/reducers/queryConfigs'
import defaultQueryConfig from 'src/utils/defaultQueryConfig'
import {
  chooseNamespace,
  chooseMeasurement,
  toggleField,
  applyFuncsToField,
  chooseTag,
  groupByTag,
  groupByTime,
  toggleTagAcceptance,
  updateRawQuery,
  editQueryStatus,
} from 'src/data_explorer/actions/view'

const fakeAddQueryAction = (panelID, queryID) => {
  return {
    type: 'ADD_QUERY',
    payload: {panelID, queryID},
  }
}

function buildInitialState(queryId, params) {
  return Object.assign({}, defaultQueryConfig(queryId), params)
}

describe('Chronograf.Reducers.queryConfig', () => {
  const queryId = 123

  it('can add a query', () => {
    const state = reducer({}, fakeAddQueryAction('blah', queryId))

    const actual = state[queryId]
    const expected = defaultQueryConfig(queryId)
    expect(actual).to.deep.equal(expected)
  })

  describe('choosing db, rp, and measurement', () => {
    let state
    beforeEach(() => {
      state = reducer({}, fakeAddQueryAction('any', queryId))
    })

    it('sets the db and rp', () => {
      const newState = reducer(state, chooseNamespace(queryId, {
        database: 'telegraf',
        retentionPolicy: 'monitor',
      }))

      expect(newState[queryId].database).to.equal('telegraf')
      expect(newState[queryId].retentionPolicy).to.equal('monitor')
    })

    it('sets the measurement', () => {
      const newState = reducer(state, chooseMeasurement(queryId, 'mem'))

      expect(newState[queryId].measurement).to.equal('mem')
    })
  })

  describe('a query has measurements and fields', () => {
    let state
    beforeEach(() => {
      const one = reducer({}, fakeAddQueryAction('any', queryId))
      const two = reducer(one, chooseNamespace(queryId, {
        database: '_internal',
        retentionPolicy: 'daily',
      }))
      const three = reducer(two, chooseMeasurement(queryId, 'disk'))
      state = reducer(three, toggleField(queryId, {field: 'a great field', funcs: []}))
    })

    describe('choosing a new namespace', () => {
      it('clears out the old measurement and fields', () => { // what about tags?
        expect(state[queryId].measurement).to.exist
        expect(state[queryId].fields.length).to.equal(1)

        const newState = reducer(state, chooseNamespace(queryId, {
          database: 'newdb',
          retentionPolicy: 'newrp',
        }))

        expect(newState[queryId].measurement).not.to.exist
        expect(newState[queryId].fields.length).to.equal(0)
      })
    })

    describe('choosing a new measurement', () => {
      it('leaves the namespace and clears out the old fields', () => { // what about tags?
        expect(state[queryId].fields.length).to.equal(1)

        const newState = reducer(state, chooseMeasurement(queryId, 'newmeasurement'))

        expect(state[queryId].database).to.equal(newState[queryId].database)
        expect(state[queryId].retentionPolicy).to.equal(newState[queryId].retentionPolicy)
        expect(newState[queryId].fields.length).to.equal(0)
      })
    })

    describe('when the query is part of a kapacitor rule', () => {
      it('only allows one field', () => {
        expect(state[queryId].fields.length).to.equal(1)

        const isKapacitorRule = true
        const newState = reducer(state, toggleField(queryId, {field: 'a different field', funcs: []}, isKapacitorRule))

        expect(newState[queryId].fields.length).to.equal(1)
        expect(newState[queryId].fields[0].field).to.equal('a different field')
      })
    })
  })

  describe('APPLY_FUNCS_TO_FIELD', () => {
    it('applies functions to a field without any existing functions', () => {
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [
            {field: 'f1', funcs: ['fn1', 'fn2']},
            {field: 'f2', funcs: ['fn1']},
          ],
        },
      }
      const action = applyFuncsToField(queryId, {
        field: 'f1',
        funcs: ['fn3', 'fn4'],
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].fields).to.eql([
        {field: 'f1', funcs: ['fn3', 'fn4']},
        {field: 'f2', funcs: ['fn1']},
      ])
    })

    it('removes all functions and group by time when one field has no funcs applied', () => {
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [
            {field: 'f1', funcs: ['fn1', 'fn2']},
            {field: 'f2', funcs: ['fn3', 'fn4']},
          ],
          groupBy: {
            time: '1m',
            tags: [],
          },
        },
      }

      const action = applyFuncsToField(queryId, {
        field: 'f1',
        funcs: [],
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].fields).to.eql([
        {field: 'f1', funcs: []},
        {field: 'f2', funcs: []},
      ])
      expect(nextState[queryId].groupBy.time).to.equal(null)
    })
  })

  describe('CHOOSE_TAG', () => {
    it('adds a tag key/value to the query', () => {
      const initialState = {
        [queryId]: buildInitialState(queryId, {
          tags: {
            k1: ['v0'],
            k2: ['foo'],
          },
        }),
      }
      const action = chooseTag(queryId, {
        key: 'k1',
        value: 'v1',
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].tags).to.eql({
        k1: ['v0', 'v1'],
        k2: ['foo'],
      })
    })

    it('creates a new entry if it\'s the first key', () => {
      const initialState = {
        [queryId]: buildInitialState(queryId, {
          tags: {},
        }),
      }
      const action = chooseTag(queryId, {
        key: 'k1',
        value: 'v1',
      })

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].tags).to.eql({
        k1: ['v1'],
      })
    })

    it('removes a value that is already in the list', () => {
      const initialState = {
        [queryId]: buildInitialState(queryId, {
          tags: {
            k1: ['v1'],
          },
        }),
      }
      const action = chooseTag(queryId, {
        key: 'k1',
        value: 'v1',
      })

      const nextState = reducer(initialState, action)

      // TODO: this should probably remove the `k1` property entirely from the tags object
      expect(nextState[queryId].tags).to.eql({})
    })
  })

  describe('GROUP_BY_TAG', () => {
    it('adds a tag key/value to the query', () => {
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [],
          tags: {},
          groupBy: {tags: [], time: null},
        },
      }
      const action = groupByTag(queryId, 'k1')

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].groupBy).to.eql({
        time: null,
        tags: ['k1'],
      })
    })

    it('removes a tag if the given tag key is already in the GROUP BY list', () => {
      const initialState = {
        [queryId]: {
          id: 123,
          database: 'db1',
          measurement: 'm1',
          fields: [],
          tags: {},
          groupBy: {tags: ['k1'], time: null},
        },
      }
      const action = groupByTag(queryId, 'k1')

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].groupBy).to.eql({
        time: null,
        tags: [],
      })
    })
  })

  describe('TOGGLE_TAG_ACCEPTANCE', () => {
    it('it toggles areTagsAccepted', () => {
      const initialState = {
        [queryId]: buildInitialState(queryId),
      }
      const action = toggleTagAcceptance(queryId)

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].areTagsAccepted).to.equal(!initialState[queryId].areTagsAccepted)
    })
  })

  describe('GROUP_BY_TIME', () => {
    it('applys the appropriate group by time', () => {
      const time = '100y'
      const initialState = {
        [queryId]: buildInitialState(queryId),
      }

      const action = groupByTime(queryId, time)

      const nextState = reducer(initialState, action)

      expect(nextState[queryId].groupBy.time).to.equal(time)
    })
  })

  it('updates a query\'s raw text', () => {
    const initialState = {
      [queryId]: buildInitialState(queryId),
    }
    const text = 'foo'
    const action = updateRawQuery(queryId, text)

    const nextState = reducer(initialState, action)

    expect(nextState[queryId].rawText).to.equal('foo')
  })

  it('updates a query\'s raw status', () => {
    const initialState = {
      [queryId]: buildInitialState(queryId),
    }
    const status = 'your query was sweet'
    const action = editQueryStatus(queryId, status)

    const nextState = reducer(initialState, action)

    expect(nextState[queryId].status).to.equal(status)
  })
})

<|endoftext|>