<commit_before>/*

Edtended handling of date, time and datetime-local type fields.

Works with both string and integer data types. (default only support string type)

Has optional support for using flatpickr datepicker.
All flatpickr options is supported with a few minor differences.
- "enableTime" and "noCalendar" are set automatically, based on the data type.
- Extra config option "errorDateFormat". If this is set, it will replace the format displayed in error messages.
- It is not possible to use "inline" and "wrap" options together.
- When using the "wrap" option, "toggle" and "clear" buttons are automatically added to markup. 2 extra boolean options ("showToggleButton" and "showClearButton") are available to control which buttons to display. Note: not all frameworks supports this. (Works in: Bootstrap and Foundation)
- When using the "inline" option, an extra boolean option ("inlineHideInput") is available to hide the original input field.
- If "mode" is set to either "multiple" or "range", only string data type is supported. Also the result from these is returned as a string not an array.

ToDo:
 - Improve Handling of flatpicker "multiple" and "range" modes. (Currently the values are just added as string values, but the optimal scenario would be to save those as array if possible)

*/
JSONEditor.defaults.editors.datetime = JSONEditor.defaults.editors.string.extend({
  build: function () {
    this._super();
    if(!this.input) return;

    if(window.flatpickr && typeof this.options.flatpickr == 'object') {

      // Make sure that flatpickr settings matches the input type
      this.options.flatpickr.enableTime = this.schema.format == 'date' ? false : true;
      this.options.flatpickr.noCalendar = this.schema.format == 'time' ? true : false;

      // Curently only string can contain range or multiple values
      if (this.schema.type == 'integer') this.options.flatpickr.mode = 'single';

      // Attribute for flatpicker
      this.input.setAttribute('data-input','');

      var input = this.input;

      if (this.options.flatpickr.wrap === true) {

        // Create buttons for input group
        var buttons = [];
        if (this.options.flatpickr.showToggleButton !== false) {
          var toggleButton = this.getButton('',this.schema.format == 'time' ? 'time' :'calendar', this.translate('flatpickr_toggle_button'));
          // Attribute for flatpicker
          toggleButton.setAttribute('data-toggle','');
          buttons.push(toggleButton);
        }
        if (this.options.flatpickr.showClearButton !== false) {
          var clearButton = this.getButton('','clear', this.translate('flatpickr_clear_button'));
          // Attribute for flatpicker
          clearButton.setAttribute('data-clear','');
          buttons.push(clearButton);
        }

        // Save position of input field
        var parentNode = this.input.parentNode, nextSibling = this.input.nextSibling;

        var buttonContainer = this.theme.getInputGroup(this.input, buttons);
        if (buttonContainer !== undefined) {
          // Make sure "inline" option is turned off
          this.options.flatpickr.inline = false;

          // Insert container at same position as input field
          parentNode.insertBefore(buttonContainer, nextSibling);

          input = buttonContainer;
        }
        else {
          this.options.flatpickr.wrap = false;
        }

      }

      this.flatpickr = window.flatpickr(input, this.options.flatpickr);

      if (this.options.flatpickr.inline === true && this.options.flatpickr.inlineHideInput === true) {
          this.input.setAttribute('type','hidden');
      }
    }
  },
  getValue: function() {
    if (!this.dependenciesFulfilled) {
      return undefined;
    }
    if (this.schema.type == 'string') {
      return this.value;
    }
    if (this.value === '' || this.value === undefined) {
      return undefined;
    }

    var value =  this.schema.format == 'time' ? '1970-01-01 ' + this.value : this.value;
    return parseInt(new Date(value).getTime() / 1000);
  },
  setValue: function(value, initial, from_template) {
    if (this.schema.type == 'string') {
      this._super(value, initial, from_template);
      if (this.flatpickr) this.flatpickr.setDate(value);
    }
    else if (value > 0) {
      var dateObj = new Date(value * 1000),
          year = dateObj.getFullYear(),
          month = this.zeroPad(dateObj.getMonth() + 1),
          day = this.zeroPad(dateObj.getDate()),
          hour = this.zeroPad(dateObj.getHours()),
          min = this.zeroPad(dateObj.getMinutes()),
          sec = this.zeroPad(dateObj.getSeconds()),
          date = [year, month, day].join('-'),
          time = [hour, min, sec].join(':'),
          dateValue = date + 'T' + time;

      if (this.schema.format == 'date') dateValue = date;
      else if (this.schema.format == 'time') dateValue = time;

      this.input.value = dateValue;
      if (this.flatpickr) this.flatpickr.setDate(dateValue);
    }
  },
  destroy: function() {
    if (this.flatpickr) this.flatpickr.destroy();
    this.flatpickr = null;
    this._super();
  },
  // helper function
  zeroPad: function(value) {
    return ('0' + value).slice(-2);
  }
});
<commit_msg>Fix datetime integer setValue fails to update internal state<commit_after>/*

Edtended handling of date, time and datetime-local type fields.

Works with both string and integer data types. (default only support string type)

Has optional support for using flatpickr datepicker.
All flatpickr options is supported with a few minor differences.
- "enableTime" and "noCalendar" are set automatically, based on the data type.
- Extra config option "errorDateFormat". If this is set, it will replace the format displayed in error messages.
- It is not possible to use "inline" and "wrap" options together.
- When using the "wrap" option, "toggle" and "clear" buttons are automatically added to markup. 2 extra boolean options ("showToggleButton" and "showClearButton") are available to control which buttons to display. Note: not all frameworks supports this. (Works in: Bootstrap and Foundation)
- When using the "inline" option, an extra boolean option ("inlineHideInput") is available to hide the original input field.
- If "mode" is set to either "multiple" or "range", only string data type is supported. Also the result from these is returned as a string not an array.

ToDo:
 - Improve Handling of flatpicker "multiple" and "range" modes. (Currently the values are just added as string values, but the optimal scenario would be to save those as array if possible)

*/
JSONEditor.defaults.editors.datetime = JSONEditor.defaults.editors.string.extend({
  build: function () {
    this._super();
    if(!this.input) return;

    if(window.flatpickr && typeof this.options.flatpickr == 'object') {

      // Make sure that flatpickr settings matches the input type
      this.options.flatpickr.enableTime = this.schema.format == 'date' ? false : true;
      this.options.flatpickr.noCalendar = this.schema.format == 'time' ? true : false;

      // Curently only string can contain range or multiple values
      if (this.schema.type == 'integer') this.options.flatpickr.mode = 'single';

      // Attribute for flatpicker
      this.input.setAttribute('data-input','');

      var input = this.input;

      if (this.options.flatpickr.wrap === true) {

        // Create buttons for input group
        var buttons = [];
        if (this.options.flatpickr.showToggleButton !== false) {
          var toggleButton = this.getButton('',this.schema.format == 'time' ? 'time' :'calendar', this.translate('flatpickr_toggle_button'));
          // Attribute for flatpicker
          toggleButton.setAttribute('data-toggle','');
          buttons.push(toggleButton);
        }
        if (this.options.flatpickr.showClearButton !== false) {
          var clearButton = this.getButton('','clear', this.translate('flatpickr_clear_button'));
          // Attribute for flatpicker
          clearButton.setAttribute('data-clear','');
          buttons.push(clearButton);
        }

        // Save position of input field
        var parentNode = this.input.parentNode, nextSibling = this.input.nextSibling;

        var buttonContainer = this.theme.getInputGroup(this.input, buttons);
        if (buttonContainer !== undefined) {
          // Make sure "inline" option is turned off
          this.options.flatpickr.inline = false;

          // Insert container at same position as input field
          parentNode.insertBefore(buttonContainer, nextSibling);

          input = buttonContainer;
        }
        else {
          this.options.flatpickr.wrap = false;
        }

      }

      this.flatpickr = window.flatpickr(input, this.options.flatpickr);

      if (this.options.flatpickr.inline === true && this.options.flatpickr.inlineHideInput === true) {
          this.input.setAttribute('type','hidden');
      }
    }
  },
  getValue: function() {
    if (!this.dependenciesFulfilled) {
      return undefined;
    }
    if (this.schema.type == 'string') {
      return this.value;
    }
    if (this.value === '' || this.value === undefined) {
      return undefined;
    }

    var value =  this.schema.format == 'time' ? '1970-01-01 ' + this.value : this.value;
    return parseInt(new Date(value).getTime() / 1000);
  },
  setValue: function(value, initial, from_template) {
    if (this.schema.type == 'string') {
      this._super(value, initial, from_template);
      if (this.flatpickr) this.flatpickr.setDate(value);
    }
    else if (value > 0) {
      var dateObj = new Date(value * 1000),
          year = dateObj.getFullYear(),
          month = this.zeroPad(dateObj.getMonth() + 1),
          day = this.zeroPad(dateObj.getDate()),
          hour = this.zeroPad(dateObj.getHours()),
          min = this.zeroPad(dateObj.getMinutes()),
          sec = this.zeroPad(dateObj.getSeconds()),
          date = [year, month, day].join('-'),
          time = [hour, min, sec].join(':'),
          dateValue = date + 'T' + time;

      if (this.schema.format == 'date') dateValue = date;
      else if (this.schema.format == 'time') dateValue = time;

      this.input.value = dateValue;
      this.refreshValue();
      if (this.flatpickr) this.flatpickr.setDate(dateValue);
    }
  },
  destroy: function() {
    if (this.flatpickr) this.flatpickr.destroy();
    this.flatpickr = null;
    this._super();
  },
  // helper function
  zeroPad: function(value) {
    return ('0' + value).slice(-2);
  }
});
<|endoftext|>


<commit_before>easyXDM.Transport = {
    // #ifdef debug
    /**
     * @class easyXDM.Transport.ITransport
     * The interface implemented by all transport classes.

     * Only available in debug mode.
     * @namespace easyXDM.Transport
     */
    ITransport: {
        /**
         * Sends the message
         * @param {String} message The message to send
         */
        postMessage: function(message){
        },
        /**
         * Breaks down the connection and tries to clean up the dom.
         */
        destroy: function(){
        }
    },
    // #endif
    /**
     * @class easyXDM.Transport.BestAvailableTransport
     * @extends easyXDM.Transport.ITransport
     * BestAvailableTransport is a transport class that uses the best transport available.
     * Currently it will select among PostMessageTransport and HashTransport.
     * @constructor
     * @param {easyXDM.Transport.TransportConfiguration} config The transports configuration.
     * @param {Function} onReady A method that should be called when the transport is ready
     * @namespace easyXDM.Transport
     */
    BestAvailableTransport: function(config, onReady){
        // #ifdef debug
        easyXDM.Debug.trace("easyXDM.Transport.BestAvailableTransport.constructor");
        // #endif
        if (config.local) {
            config.channel = (config.channel) ? config.channel : "default";
        }
        else {
            var query = easyXDM.Url.Query();
            config.channel = query.channel;
            config.remote = query.endpoint;
        }
        var type = "HashTransport";
        if (window.postMessage) {
            type = "PostMessageTransport";
        }
        return new easyXDM.Transport[type](config, onReady);

    },
    /**
     * @class easyXDM.Transport.PostMessageTransport
     * @extends easyXDM.Transport.ITransport
     * PostMessageTransport is a transport class that uses HTML5 postMessage for communication
     * http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx
     * https://developer.mozilla.org/en/DOM/window.postMessage
     * @constructor
     * @param {easyXDM.Transport.TransportConfiguration} config The transports configuration.
     * @param {Function} onReady A method that should be called when the transport is ready
     * @namespace easyXDM.Transport
     */
    PostMessageTransport: function(config, onReady){
        // #ifdef debug
        easyXDM.Debug.trace("easyXDM.Transport.PostMessageTransport.constructor");
        // #endif
        var _targetOrigin = easyXDM.Url.getLocation(config.remote);
        var _callerWindow;

        /**
         * Resolves the origin from the event object
         * @param {Object} event The messageevent
         * @return {String} The scheme, host and port of the origin
         */
        function _getOrigin(event){
            if (event.origin) {
                // This is the standardized property
                return event.origin;
            }
            if (event.uri) {
                // From earlier implementations
                return easyXDM.Url.getLocation(event.uri);
            }
            if (event.domain) {
                // This is the last option and will fail if the
                //origin is not using the same schema as we are
                return location.protocol + "//" + event.domain;
            }
            throw "Unable to retrieve the origin of the event";
        }

        /**
         * Delays calling onReady until the class has been returned
         */
        function _onReady(){
            if (onReady) {
                window.setTimeout(onReady, 5);
            }
        }

        /**
         * This will at any time point to the real implementation of the onMessage handler
         */
        var _window_onMessageImplementation;

        /**
         * The main onMessage handler. This will pass on the event to the real implementation
         * @ignore
         * @param {Object} event The messageevent
         */
        function _window_onMessage(event){
            // #ifdef debug
            easyXDM.Debug.trace("onMessage");
            // #endif
            _window_onMessageImplementation(event);
        }
        easyXDM.DomHelper.addEventListener(window, "message", _window_onMessage);

        /**
         * This is the main implementation for the onMessage event.

         * It checks the validity of the origin and passes the message on if appropriate.
         * @param {Object} event The messageevent
         */
        function _handleMessage(event){
            var origin = _getOrigin(event);
            // #ifdef debug
            easyXDM.Debug.trace("received message '" + event.data + "' from " + origin);
            // #endif
            if (origin == _targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
                config.onMessage(event.data.substring(config.channel.length + 1), origin);
            }
        }

        /**
         * Used by local to fire the onReady method.
         * After being notified by the remote, this method will replace the
         * onMessage handler with _handleMessage and fire onReady
         * @param {Object} event The messageevent
         */
        function _waitForReady(event){
            if (event.data == config.channel + "-ready") {
                // #ifdef debug
                easyXDM.Debug.trace("firing onReady");
                // #endif
                // We use memoization to avoid having to run this check each time
                _window_onMessageImplementation = _handleMessage;
                _onReady();
            }
            // #ifdef debug
            else {
                easyXDM.Debug.trace("received unexpected message: " + event.data);
            }
            // #endif
        }

        /**
         * Sends the message using the postMethod method available on the window object
         * @param {String} message The message to send
         */
        this.postMessage = function(message){
        };
        /**
         * Destroy all that we can destroy :)
         */
        this.destroy = function(){
            // #ifdef debug
            easyXDM.Debug.trace("destroying transport");
            // #endif
            easyXDM.DomHelper.removeEventListener(window, "message", _window_onMessage);
            if (config.local) {
                _callerWindow.parentNode.removeChild(_callerWindow);
                _callerWindow = null;
            }
        };

        // Set up the messaging differently depending on being local or remote
        if (config.local) {
            this.postMessage = function(message){
                // #ifdef debug
                easyXDM.Debug.trace("sending message '" + message + "' to iframe " + _targetOrigin);
                // #endif
                _callerWindow.contentWindow.postMessage(config.channel + " " + message, _targetOrigin);
            };
            _window_onMessageImplementation = _waitForReady;
            _callerWindow = easyXDM.DomHelper.createFrame(config.remote + "?endpoint=" + easyXDM.Url.resolveUrl(config.local) + "&channel=" + config.channel, "", config.container);
        }
        else {
            this.postMessage = function(message){
                // #ifdef debug
                easyXDM.Debug.trace("sending message '" + message + "' to parent " + _targetOrigin);
                // #endif
                window.parent.postMessage(config.channel + " " + message, _targetOrigin);
            };
            _window_onMessageImplementation = _handleMessage;
            // #ifdef debug
            easyXDM.Debug.trace("firing onReady");
            // #endif
            window.parent.postMessage(config.channel + "-ready", _targetOrigin);
            _onReady();
        }
    },
    /**
     * @class easyXDM.Transport.HashTransport
     * @extends easyXDM.Transport.ITransport
     * HashTransport is a transport class that uses the IFrame URL Technique for communication
     * http://msdn.microsoft.com/en-us/library/bb735305.aspx
     * @constructor
     * @param {easyXDM.Transport.TransportConfiguration} config The transports configuration.
     * @param {Function} onReady A method that should be called when the transport is ready
     * @namespace easyXDM.Transport
     */
    HashTransport: function(config, onReady){
        // #ifdef debug
        easyXDM.Debug.trace("easyXDM.Transport.HashTransport.constructor");
        // #endif
        var _timer = null;
        var _lastMsg = "#" + config.channel, _msgNr = 0;
        var _listenerWindow = (!config.local) ? window : null, _callerWindow;
        var _remoteUrl = config.remote;
        if (config.local) {
            _remoteUrl += "?endpoint=" + easyXDM.Url.resolveUrl(config.local) + "&channel=" + config.channel;
        }
        else {
            _remoteUrl += "#" + config.channel;
        }
        var _remoteOrigin = easyXDM.Url.getLocation(config.remote);
        var _pollInterval = (config.interval) ? config.interval : 300;

        function _checkForMessage(){
            ///
            /// Checks location.hash for a new message and relays this to the receiver.
            /// </summary
            /// <remark>
            /// We have no way of knowing if messages have passed in between the checks.
            /// We could possibly device a way of reporting back the message number read
            /// so that the sender can concatenate multiple messages if previous message
            /// are unread.
            /// </remark>
            if (!_listenerWindow) {
                _listenerWindow = easyXDM.Transport.HashTransport.getWindow(config.channel);
                if (!_listenerWindow) {
                    throw "Not able to get a reference to the iframe";
                }
            }
            if (_listenerWindow.location.hash && _listenerWindow.location.hash != _lastMsg) {
                _lastMsg = _listenerWindow.location.hash;
                // #ifdef debug
                easyXDM.Debug.trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
                // #endif
                config.onMessage(decodeURIComponent(_lastMsg.substring(_lastMsg.indexOf("_") + 1)), _remoteOrigin);
            }
        }

        function _onReady(){
            ///
            /// Calls the supplied onReady method
            /// </summary
            /// <remark>
            /// We delay this so that the the call to createChannel or
            /// createTransport will have completed
            /// </remark>
            _timer = window.setInterval(function(){
                _checkForMessage();
            }, _pollInterval);
            if (onReady) {
                window.setTimeout(onReady, 10);
            }
        }
        if (config.local) {
            // Register onReady callback in the library so that
            // it can be called when hash.html has loaded.
            easyXDM.Transport.HashTransport.registerOnReady(config.channel, _onReady);
        }
        _callerWindow = easyXDM.DomHelper.createFrame(_remoteUrl, ((config.local) ? "" : "xss_" + config.channel), config.container, (config.local) ? null : _onReady);
        /**
         * Sends a message by encoding and placing it in the hash part of _callerWindows url.
         * We include a message number so that identical messages will be read as separate messages.
         * @param {String} message The message to send
         */
        this.postMessage = function(message){
            // #ifdef debug
            easyXDM.Debug.trace("sending message '" + message + "' to " + _remoteOrigin);
            // #endif
            _callerWindow.src = _remoteUrl + "#" + (_msgNr++) + "_" + encodeURIComponent(message);
        };
        /**
         *
         */
        this.destroy = function(){
            // #ifdef debug
            easyXDM.Debug.trace("destroying transport");
            // #endif
            window.clearInterval(_timer);
            _callerWindow.parentNode.removeChild(_callerWindow);
            _callerWindow = null;
        };
    }
};

/**
 * Contains the callbacks used to notify local that the remote end is ready
 */
easyXDM.Transport.HashTransport.callbacks = {};
/**
 * Contains the proxy windows used to read messages from remote when
 * using HashTransport.
 */
easyXDM.Transport.HashTransport.windows = {};

/**
 * Register a callback that should be called when the remote end of a channel is ready
 * @param {String} channel
 * @param {Function} callback
 */
easyXDM.Transport.HashTransport.registerOnReady = function(channel, callback){
    // #ifdef debug
    easyXDM.Debug.trace("registering onReady callback for channel " + channel);
    // #endif
    easyXDM.Transport.HashTransport.callbacks[channel] = callback;
};

/**
 * Notify that a channel is ready and register a window to be used for reading messages
 * for on the channel.
 * @param {String} channel
 * @param {Window} contentWindow
 */
easyXDM.Transport.HashTransport.channelReady = function(channel, contentWindow){
    easyXDM.Transport.HashTransport.windows[channel] = contentWindow;
    // #ifdef debug
    easyXDM.Debug.trace("executing onReady callback for channel " + channel);
    // #endif
    var fn = easyXDM.Transport.HashTransport.callbacks[channel];
    if (fn) {
        fn();
        delete easyXDM.Transport.HashTransport.callbacks[channel];
    }

};

/**
 * Returns the window associated with a channel
 * @param {String} channel
 * @return {Window} The window
 */
easyXDM.Transport.HashTransport.getWindow = function(channel){
    return easyXDM.Transport.HashTransport.windows[channel];
};
<commit_msg>Fixed comments to improve the quality of the documentation<commit_after>easyXDM.Transport = {
    // #ifdef debug
    /**
     * @class easyXDM.Transport.ITransport
     * The interface implemented by all transport classes.

     * Only available in debug mode.
     * @namespace easyXDM.Transport
     */
    ITransport: {
        /**
         * Sends the message
         * @param {String} message The message to send
         */
        postMessage: function(message){
        },
        /**
         * Breaks down the connection and tries to clean up the dom.
         */
        destroy: function(){
        }
    },
    // #endif
    /**
     * @class easyXDM.Transport.BestAvailableTransport
     * @extends easyXDM.Transport.ITransport
     * BestAvailableTransport is a transport class that uses the best transport available.
     * Currently it will select among PostMessageTransport and HashTransport.
     * @constructor
     * @param {easyXDM.Transport.TransportConfiguration} config The transports configuration.
     * @param {Function} onReady A method that should be called when the transport is ready
     * @namespace easyXDM.Transport
     */
    BestAvailableTransport: function(config, onReady){
        // #ifdef debug
        easyXDM.Debug.trace("easyXDM.Transport.BestAvailableTransport.constructor");
        // #endif
        if (config.local) {
            config.channel = (config.channel) ? config.channel : "default";
        }
        else {
            var query = easyXDM.Url.Query();
            config.channel = query.channel;
            config.remote = query.endpoint;
        }
        var type = "HashTransport";
        if (window.postMessage) {
            type = "PostMessageTransport";
        }
        return new easyXDM.Transport[type](config, onReady);

    },
    /**
     * @class easyXDM.Transport.PostMessageTransport
     * @extends easyXDM.Transport.ITransport
     * PostMessageTransport is a transport class that uses HTML5 postMessage for communication
     * http://msdn.microsoft.com/en-us/library/ms644944(VS.85).aspx
     * https://developer.mozilla.org/en/DOM/window.postMessage
     * @constructor
     * @param {easyXDM.Transport.TransportConfiguration} config The transports configuration.
     * @param {Function} onReady A method that should be called when the transport is ready
     * @namespace easyXDM.Transport
     */
    PostMessageTransport: function(config, onReady){
        // #ifdef debug
        easyXDM.Debug.trace("easyXDM.Transport.PostMessageTransport.constructor");
        // #endif
        var _targetOrigin = easyXDM.Url.getLocation(config.remote);
        var _callerWindow;

        /**
         * Resolves the origin from the event object
         * @private
         * @param {Object} event The messageevent
         * @return {String} The scheme, host and port of the origin
         */
        function _getOrigin(event){
            if (event.origin) {
                // This is the standardized property
                return event.origin;
            }
            if (event.uri) {
                // From earlier implementations
                return easyXDM.Url.getLocation(event.uri);
            }
            if (event.domain) {
                // This is the last option and will fail if the
                //origin is not using the same schema as we are
                return location.protocol + "//" + event.domain;
            }
            throw "Unable to retrieve the origin of the event";
        }
        /**
         * Delays calling onReady until the class has been returned
         * @private
         */
        function _onReady(){
            if (onReady) {
                window.setTimeout(onReady, 5);
            }
        }

        // This will at any time point to the real implementation of the onMessage handler
        var _window_onMessageImplementation;

        /**
         * The main onMessage handler. This will pass on the event to the real implementation
         * @private
         * @param {Object} event The messageevent
         */
        function _window_onMessage(event){
            // #ifdef debug
            easyXDM.Debug.trace("onMessage");
            // #endif
            _window_onMessageImplementation(event);
        }
        easyXDM.DomHelper.addEventListener(window, "message", _window_onMessage);

        /**
         * This is the main implementation for the onMessage event.

         * It checks the validity of the origin and passes the message on if appropriate.
         * @private
         * @param {Object} event The messageevent
         */
        function _handleMessage(event){
            var origin = _getOrigin(event);
            // #ifdef debug
            easyXDM.Debug.trace("received message '" + event.data + "' from " + origin);
            // #endif
            if (origin == _targetOrigin && event.data.substring(0, config.channel.length + 1) == config.channel + " ") {
                config.onMessage(event.data.substring(config.channel.length + 1), origin);
            }
        }

        /**
         * Used by local to fire the onReady method.
         * After being notified by the remote, this method will replace the
         * onMessage handler with _handleMessage and fire onReady
         * @private
         * @param {Object} event The messageevent
         */
        function _waitForReady(event){
            if (event.data == config.channel + "-ready") {
                // #ifdef debug
                easyXDM.Debug.trace("firing onReady");
                // #endif
                // We use memoization to avoid having to run this check each time
                _window_onMessageImplementation = _handleMessage;
                _onReady();
            }
            // #ifdef debug
            else {
                easyXDM.Debug.trace("received unexpected message: " + event.data);
            }
            // #endif
        }

        /**
         * Sends the message using the postMethod method available on the window object
         * @param {String} message The message to send
         */
        this.postMessage = function(message){
        };
        /**
         * Destroy all that we can destroy :)
         */
        this.destroy = function(){
            // #ifdef debug
            easyXDM.Debug.trace("destroying transport");
            // #endif
            easyXDM.DomHelper.removeEventListener(window, "message", _window_onMessage);
            if (config.local) {
                _callerWindow.parentNode.removeChild(_callerWindow);
                _callerWindow = null;
            }
        };

        // Set up the messaging differently depending on being local or remote
        if (config.local) {
            this.postMessage = function(message){
                // #ifdef debug
                easyXDM.Debug.trace("sending message '" + message + "' to iframe " + _targetOrigin);
                // #endif
                _callerWindow.contentWindow.postMessage(config.channel + " " + message, _targetOrigin);
            };
            _window_onMessageImplementation = _waitForReady;
            _callerWindow = easyXDM.DomHelper.createFrame(config.remote + "?endpoint=" + easyXDM.Url.resolveUrl(config.local) + "&channel=" + config.channel, "", config.container);
        }
        else {
            this.postMessage = function(message){
                // #ifdef debug
                easyXDM.Debug.trace("sending message '" + message + "' to parent " + _targetOrigin);
                // #endif
                window.parent.postMessage(config.channel + " " + message, _targetOrigin);
            };
            _window_onMessageImplementation = _handleMessage;
            // #ifdef debug
            easyXDM.Debug.trace("firing onReady");
            // #endif
            window.parent.postMessage(config.channel + "-ready", _targetOrigin);
            _onReady();
        }
    },
    /**
     * @class easyXDM.Transport.HashTransport
     * @extends easyXDM.Transport.ITransport
     * HashTransport is a transport class that uses the IFrame URL Technique for communication
     * http://msdn.microsoft.com/en-us/library/bb735305.aspx
     * @constructor
     * @param {easyXDM.Transport.TransportConfiguration} config The transports configuration.
     * @param {Function} onReady A method that should be called when the transport is ready
     * @namespace easyXDM.Transport
     */
    HashTransport: function(config, onReady){
        // #ifdef debug
        easyXDM.Debug.trace("easyXDM.Transport.HashTransport.constructor");
        // #endif
        var _timer = null;
        var _lastMsg = "#" + config.channel, _msgNr = 0;
        var _listenerWindow = (!config.local) ? window : null, _callerWindow;
        var _remoteUrl = config.remote;
        if (config.local) {
            _remoteUrl += "?endpoint=" + easyXDM.Url.resolveUrl(config.local) + "&channel=" + config.channel;
        }
        else {
            _remoteUrl += "#" + config.channel;
        }
        var _remoteOrigin = easyXDM.Url.getLocation(config.remote);
        var _pollInterval = (config.interval) ? config.interval : 300;

        function _checkForMessage(){
            ///
            /// Checks location.hash for a new message and relays this to the receiver.
            /// </summary
            /// <remark>
            /// We have no way of knowing if messages have passed in between the checks.
            /// We could possibly device a way of reporting back the message number read
            /// so that the sender can concatenate multiple messages if previous message
            /// are unread.
            /// </remark>
            if (!_listenerWindow) {
                _listenerWindow = easyXDM.Transport.HashTransport.getWindow(config.channel);
                if (!_listenerWindow) {
                    throw "Not able to get a reference to the iframe";
                }
            }
            if (_listenerWindow.location.hash && _listenerWindow.location.hash != _lastMsg) {
                _lastMsg = _listenerWindow.location.hash;
                // #ifdef debug
                easyXDM.Debug.trace("received message '" + _lastMsg + "' from " + _remoteOrigin);
                // #endif
                config.onMessage(decodeURIComponent(_lastMsg.substring(_lastMsg.indexOf("_") + 1)), _remoteOrigin);
            }
        }

        function _onReady(){
            ///
            /// Calls the supplied onReady method
            /// </summary
            /// <remark>
            /// We delay this so that the the call to createChannel or
            /// createTransport will have completed
            /// </remark>
            _timer = window.setInterval(function(){
                _checkForMessage();
            }, _pollInterval);
            if (onReady) {
                window.setTimeout(onReady, 10);
            }
        }
        if (config.local) {
            // Register onReady callback in the library so that
            // it can be called when hash.html has loaded.
            easyXDM.Transport.HashTransport.registerOnReady(config.channel, _onReady);
        }
        _callerWindow = easyXDM.DomHelper.createFrame(_remoteUrl, ((config.local) ? "" : "xss_" + config.channel), config.container, (config.local) ? null : _onReady);
        /**
         * Sends a message by encoding and placing it in the hash part of _callerWindows url.
         * We include a message number so that identical messages will be read as separate messages.
         * @param {String} message The message to send
         */
        this.postMessage = function(message){
            // #ifdef debug
            easyXDM.Debug.trace("sending message '" + message + "' to " + _remoteOrigin);
            // #endif
            _callerWindow.src = _remoteUrl + "#" + (_msgNr++) + "_" + encodeURIComponent(message);
        };
        /**
         *
         */
        this.destroy = function(){
            // #ifdef debug
            easyXDM.Debug.trace("destroying transport");
            // #endif
            window.clearInterval(_timer);
            _callerWindow.parentNode.removeChild(_callerWindow);
            _callerWindow = null;
        };
    }
};

/**
 * Contains the callbacks used to notify local that the remote end is ready
 */
easyXDM.Transport.HashTransport.callbacks = {};
/**
 * Contains the proxy windows used to read messages from remote when
 * using HashTransport.
 */
easyXDM.Transport.HashTransport.windows = {};

/**
 * Register a callback that should be called when the remote end of a channel is ready
 * @param {String} channel
 * @param {Function} callback
 */
easyXDM.Transport.HashTransport.registerOnReady = function(channel, callback){
    // #ifdef debug
    easyXDM.Debug.trace("registering onReady callback for channel " + channel);
    // #endif
    easyXDM.Transport.HashTransport.callbacks[channel] = callback;
};

/**
 * Notify that a channel is ready and register a window to be used for reading messages
 * for on the channel.
 * @param {String} channel
 * @param {Window} contentWindow
 */
easyXDM.Transport.HashTransport.channelReady = function(channel, contentWindow){
    easyXDM.Transport.HashTransport.windows[channel] = contentWindow;
    // #ifdef debug
    easyXDM.Debug.trace("executing onReady callback for channel " + channel);
    // #endif
    var fn = easyXDM.Transport.HashTransport.callbacks[channel];
    if (fn) {
        fn();
        delete easyXDM.Transport.HashTransport.callbacks[channel];
    }

};

/**
 * Returns the window associated with a channel
 * @param {String} channel
 * @return {Window} The window
 */
easyXDM.Transport.HashTransport.getWindow = function(channel){
    return easyXDM.Transport.HashTransport.windows[channel];
};
<|endoftext|>


<commit_before>'use strict';

const BaseEmbed = require('./BaseEmbed.js');

/**
 * Generates enemy embeds
 */
class EnemyEmbed extends BaseEmbed {
  /**
   * @param {Genesis} bot - An instance of Genesis
   * @param {Array.<PersistentEnemy>} enemies - The persistentEnemies to be included in the embed
   * @param {string} platform - platform
   */
  constructor(bot, enemies, platform) {
    super();

    this.thumbnail = {
      url: 'http://i.imgur.com/pMRt2Cp.png',
    };
    this.title = `[${platform.toUpperCase()}] Acolytes`;
    if (enemies.length > 1) {
      this.color = enemies.length > 2 ? 0x00ff00 : 0xff0000;
      this.fields = enemies.map(e => ({
        name: e.agentType,
        value: `Last discovered at ${e.lastDiscoveredAt}.\n` +
          `It has ${(100 * Number(e.healthPercent)).toFixed(2)}% health remaining ` +
          `and is currently ${e.isDiscovered ? 'discovered' : 'not discovered'}`,
      }));
    } else if (enemies.length === 1) {
      const e = enemies[0];
      this.title = `[${platform.toUpperCase()}] ${e.agentType}`;
      this.description = `Enemy ${e.discovered ? 'Discovered' : 'Hiding'}!`;
      this.color = 0xaf5b4b;
      this.fields = [{ name: '_ _', value: `**${e.discovered ? '' : 'Last '}Discovered At:** ${e.lastDiscoveredAt}` },
      { name: '_ _', value: `**Health Remaining:** ${(100 * Number(e.healthPercent)).toFixed(2)}%` },
      { name: '_ _', value: `Will flee after ${e.fleeDamage} damage.\nGet after the Acolyte, Tenno!` }];
    } else {
      this.color = 0xaf5b4b;
      this.fields = [{ name: 'There are currently no enemies to combat', value: '_ _' }];
    }
  }
}

module.exports = EnemyEmbed;
<commit_msg>add url to help title stand out<commit_after>'use strict';

const BaseEmbed = require('./BaseEmbed.js');

/**
 * Generates enemy embeds
 */
class EnemyEmbed extends BaseEmbed {
  /**
   * @param {Genesis} bot - An instance of Genesis
   * @param {Array.<PersistentEnemy>} enemies - The persistentEnemies to be included in the embed
   * @param {string} platform - platform
   */
  constructor(bot, enemies, platform) {
    super();

    this.thumbnail = {
      url: 'http://i.imgur.com/pMRt2Cp.png',
    };
    this.url = 'https://ws.warframestat.us/';
    this.title = `[${platform.toUpperCase()}] Acolytes`;
    if (enemies.length > 1) {
      this.color = enemies.length > 2 ? 0x00ff00 : 0xff0000;
      this.fields = enemies.map(e => ({
        name: e.agentType,
        value: `Last discovered at ${e.lastDiscoveredAt}.\n` +
          `It has ${(100 * Number(e.healthPercent)).toFixed(2)}% health remaining ` +
          `and is currently ${e.isDiscovered ? 'discovered' : 'not discovered'}`,
      }));
    } else if (enemies.length === 1) {
      const e = enemies[0];
      this.title = `[${platform.toUpperCase()}] ${e.agentType}`;
      this.description = `Enemy ${e.discovered ? 'Discovered' : 'Hiding'}!`;
      this.color = 0xaf5b4b;
      this.fields = [{ name: '_ _', value: `**${e.discovered ? '' : 'Last '}Discovered At:** ${e.lastDiscoveredAt}` },
      { name: '_ _', value: `**Health Remaining:** ${(100 * Number(e.healthPercent)).toFixed(2)}%` },
      { name: '_ _', value: `Will flee after ${e.fleeDamage} damage.\nGet after the Acolyte, Tenno!` }];
    } else {
      this.color = 0xaf5b4b;
      this.fields = [{ name: 'There are currently no enemies to combat', value: '_ _' }];
    }
  }
}

module.exports = EnemyEmbed;
<|endoftext|>


<commit_before>'use strict'

var Web3 = require('web3')
var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager
var EthJSVM = require('ethereumjs-vm')
var ethUtil = require('ethereumjs-util')
var StateManager = require('ethereumjs-vm/lib/stateManager')
var Web3VMProvider = remixLib.vm.Web3VMProvider
var rlp = ethUtil.rlp
var modalDialogCustom = require('./app/ui/modal-dialog-custom')

var injectedProvider

var web3
if (typeof window.web3 !== 'undefined') {
  injectedProvider = window.web3.currentProvider
  web3 = new Web3(injectedProvider)
} else {
  web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
}

var blankWeb3 = new Web3()

/*
  extend vm state manager and instanciate VM
*/

class StateManagerCommonStorageDump extends StateManager {
  constructor (arg) {
    super(arg)
    this.keyHashes = {}
  }

  putContractStorage (address, key, value, cb) {
    this.keyHashes[ethUtil.sha3(key).toString('hex')] = ethUtil.bufferToHex(key)
    super.putContractStorage(address, key, value, cb)
  }

  dumpStorage (address, cb) {
    var self = this
    this._getStorageTrie(address, function (err, trie) {
      if (err) {
        return cb(err)
      }
      var storage = {}
      var stream = trie.createReadStream()
      stream.on('data', function (val) {
        var value = rlp.decode(val.value)
        storage['0x' + val.key.toString('hex')] = {
          key: self.keyHashes[val.key.toString('hex')],
          value: '0x' + value.toString('hex')
        }
      })
      stream.on('end', function () {
        cb(storage)
      })
    })
  }
}

var stateManager = new StateManagerCommonStorageDump({})
var vm = new EthJSVM({
  enableHomestead: true,
  activatePrecompiles: true
})

// FIXME: move state manager in EthJSVM ctr
vm.stateManager = stateManager
vm.blockchain = stateManager.blockchain
vm.trie = stateManager.trie
vm.stateManager.checkpoint()

var web3VM = new Web3VMProvider()
web3VM.setVM(vm)

/*
  trigger contextChanged, web3EndpointChanged
*/
function ExecutionContext () {
  var self = this
  this.event = new EventManager()
  var executionContext = 'vm'

  this.getProvider = function () {
    return executionContext
  }

  this.isVM = function () {
    return executionContext === 'vm'
  }

  this.web3 = function () {
    return this.isVM() ? web3VM.web3 : web3
  }

  this.detectNetwork = function (callback) {
    this.web3().version.getNetwork((err, id) => {
      var name = null
      if (err) name = 'Unknown'
      // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
      else if (id === '1') name = 'Main'
      else if (id === '2') name = 'Morden (deprecated)'
      else if (id === '3') name = 'Ropsten'
      else if (id === '4') name = 'Rinkeby'
      else if (id === '42') name = 'Kovan'
      else name = 'Unknown'
      callback(err, { id, name })
    })
  }

  this.internalWeb3 = function () {
    return web3
  }

  this.blankWeb3 = function () {
    return blankWeb3
  }

  this.vm = function () {
    return vm
  }

  this.setContext = function (context, endPointUrl) {
    executionContext = context
    this.executionContextChange(context, endPointUrl)
  }

  this.executionContextChange = function (context, endPointUrl, cb) {
    if (!cb) cb = () => {}
    function runPrompt () {
      if (!endPointUrl) {
        endPointUrl = 'http://localhost:8545'
      }
      modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', endPointUrl, (target) => {
        setProviderFromEndpoint(target, context, cb)
      }, () => {
        cb()
      })
    }

    if (context === 'vm') {
      executionContext = context
      vm.stateManager.revert(function () {
        vm.stateManager.checkpoint()
      })
      self.event.trigger('contextChanged', ['vm'])
      cb()
    }

    if (context === 'injected') {
      if (injectedProvider === undefined) {
        var alertMsg = 'No injected Web3 provider found. '
        alertMsg += 'Make sure your provider (e.g. MetaMask) is active and running '
        alertMsg += '(when recently activated you may have to reload the page).'
        modalDialogCustom.alert(alertMsg)
        cb()
      } else {
        executionContext = context
        web3.setProvider(injectedProvider)
        self.event.trigger('contextChanged', ['injected'])
        cb()
      }
    }

    if (context === 'web3') {
      modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?',
        () => { runPrompt(endPointUrl) }, () => { cb() }
      )
    }
  }

  this.currentblockGasLimit = function () {
    return this.blockGasLimit
  }

  this.blockGasLimitDefault = 4300000
  this.blockGasLimit = this.blockGasLimitDefault
  setInterval(() => {
    if (this.getProvider() !== 'vm') {
      web3.eth.getBlock('latest', (err, block) => {
        if (!err) {
          // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506
          this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault
        } else {
          this.blockGasLimit = this.blockGasLimitDefault
        }
      })
    }
  }, 15000)

  function setProviderFromEndpoint (endpoint, context, cb) {
    var oldProvider = web3.currentProvider

    if (endpoint === 'ipc') {
      web3.setProvider(new web3.providers.IpcProvider())
    } else {
      web3.setProvider(new web3.providers.HttpProvider(endpoint))
    }
    if (web3.isConnected()) {
      executionContext = context
      self.event.trigger('contextChanged', ['web3'])
      self.event.trigger('web3EndpointChanged')
      cb()
    } else {
      web3.setProvider(oldProvider)
      var alertMsg = 'Not possible to connect to the Web3 provider. '
      alertMsg += 'Make sure the provider is running and a connection is open (via IPC or RPC).'
      modalDialogCustom.alert(alertMsg)
      cb()
    }
  }
}

module.exports = new ExecutionContext()
<commit_msg>add VM type<commit_after>'use strict'

var Web3 = require('web3')
var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager
var EthJSVM = require('ethereumjs-vm')
var ethUtil = require('ethereumjs-util')
var StateManager = require('ethereumjs-vm/lib/stateManager')
var Web3VMProvider = remixLib.vm.Web3VMProvider
var rlp = ethUtil.rlp
var modalDialogCustom = require('./app/ui/modal-dialog-custom')

var injectedProvider

var web3
if (typeof window.web3 !== 'undefined') {
  injectedProvider = window.web3.currentProvider
  web3 = new Web3(injectedProvider)
} else {
  web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'))
}

var blankWeb3 = new Web3()

/*
  extend vm state manager and instanciate VM
*/

class StateManagerCommonStorageDump extends StateManager {
  constructor (arg) {
    super(arg)
    this.keyHashes = {}
  }

  putContractStorage (address, key, value, cb) {
    this.keyHashes[ethUtil.sha3(key).toString('hex')] = ethUtil.bufferToHex(key)
    super.putContractStorage(address, key, value, cb)
  }

  dumpStorage (address, cb) {
    var self = this
    this._getStorageTrie(address, function (err, trie) {
      if (err) {
        return cb(err)
      }
      var storage = {}
      var stream = trie.createReadStream()
      stream.on('data', function (val) {
        var value = rlp.decode(val.value)
        storage['0x' + val.key.toString('hex')] = {
          key: self.keyHashes[val.key.toString('hex')],
          value: '0x' + value.toString('hex')
        }
      })
      stream.on('end', function () {
        cb(storage)
      })
    })
  }
}

var stateManager = new StateManagerCommonStorageDump({})
var vm = new EthJSVM({
  enableHomestead: true,
  activatePrecompiles: true
})

// FIXME: move state manager in EthJSVM ctr
vm.stateManager = stateManager
vm.blockchain = stateManager.blockchain
vm.trie = stateManager.trie
vm.stateManager.checkpoint()

var web3VM = new Web3VMProvider()
web3VM.setVM(vm)

/*
  trigger contextChanged, web3EndpointChanged
*/
function ExecutionContext () {
  var self = this
  this.event = new EventManager()
  var executionContext = 'vm'

  this.getProvider = function () {
    return executionContext
  }

  this.isVM = function () {
    return executionContext === 'vm'
  }

  this.web3 = function () {
    return this.isVM() ? web3VM.web3 : web3
  }

  this.detectNetwork = function (callback) {
    if (this.isVM()) {
      callback(null, { id: '-', name: 'VM' })
    } else {
      this.web3().version.getNetwork((err, id) => {
        var name = null
        if (err) name = 'Unknown'
        // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md
        else if (id === '1') name = 'Main'
        else if (id === '2') name = 'Morden (deprecated)'
        else if (id === '3') name = 'Ropsten'
        else if (id === '4') name = 'Rinkeby'
        else if (id === '42') name = 'Kovan'
        else name = 'Custom'
        callback(err, { id, name })
      })
    }
  }

  this.internalWeb3 = function () {
    return web3
  }

  this.blankWeb3 = function () {
    return blankWeb3
  }

  this.vm = function () {
    return vm
  }

  this.setContext = function (context, endPointUrl) {
    executionContext = context
    this.executionContextChange(context, endPointUrl)
  }

  this.executionContextChange = function (context, endPointUrl, cb) {
    if (!cb) cb = () => {}
    function runPrompt () {
      if (!endPointUrl) {
        endPointUrl = 'http://localhost:8545'
      }
      modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', endPointUrl, (target) => {
        setProviderFromEndpoint(target, context, cb)
      }, () => {
        cb()
      })
    }

    if (context === 'vm') {
      executionContext = context
      vm.stateManager.revert(function () {
        vm.stateManager.checkpoint()
      })
      self.event.trigger('contextChanged', ['vm'])
      cb()
    }

    if (context === 'injected') {
      if (injectedProvider === undefined) {
        var alertMsg = 'No injected Web3 provider found. '
        alertMsg += 'Make sure your provider (e.g. MetaMask) is active and running '
        alertMsg += '(when recently activated you may have to reload the page).'
        modalDialogCustom.alert(alertMsg)
        cb()
      } else {
        executionContext = context
        web3.setProvider(injectedProvider)
        self.event.trigger('contextChanged', ['injected'])
        cb()
      }
    }

    if (context === 'web3') {
      modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?',
        () => { runPrompt(endPointUrl) }, () => { cb() }
      )
    }
  }

  this.currentblockGasLimit = function () {
    return this.blockGasLimit
  }

  this.blockGasLimitDefault = 4300000
  this.blockGasLimit = this.blockGasLimitDefault
  setInterval(() => {
    if (this.getProvider() !== 'vm') {
      web3.eth.getBlock('latest', (err, block) => {
        if (!err) {
          // we can't use the blockGasLimit cause the next blocks could have a lower limit : https://github.com/ethereum/remix/issues/506
          this.blockGasLimit = (block && block.gasLimit) ? Math.floor(block.gasLimit - (5 * block.gasLimit) / 1024) : this.blockGasLimitDefault
        } else {
          this.blockGasLimit = this.blockGasLimitDefault
        }
      })
    }
  }, 15000)

  function setProviderFromEndpoint (endpoint, context, cb) {
    var oldProvider = web3.currentProvider

    if (endpoint === 'ipc') {
      web3.setProvider(new web3.providers.IpcProvider())
    } else {
      web3.setProvider(new web3.providers.HttpProvider(endpoint))
    }
    if (web3.isConnected()) {
      executionContext = context
      self.event.trigger('contextChanged', ['web3'])
      self.event.trigger('web3EndpointChanged')
      cb()
    } else {
      web3.setProvider(oldProvider)
      var alertMsg = 'Not possible to connect to the Web3 provider. '
      alertMsg += 'Make sure the provider is running and a connection is open (via IPC or RPC).'
      modalDialogCustom.alert(alertMsg)
      cb()
    }
  }
}

module.exports = new ExecutionContext()
<|endoftext|>


<commit_before>jQuery(document).ready(function() {
  var _debug = jQuery('#output');

  module("Overview");

  test("Created canvas", function() {
    _debug.append('

');

    var opts = {
      injectInto: 'utilitiestest0',
      layout: 'ForceDirected',
      Navigation: {
        enable: true,
        panning: true,
        zooming: 40
      },
      Node: {
        overridable: true,
        dim: 20,
        lineWidth: 5
      },
      Edge: {
        overridable: true,
        color: '#23A4FF',
        lineWidth: 3,
        type: 'line'
      },
      Label: {
        type: 'SVG'
      }
    };

    var main = new $jit.NetworkMap(opts);

    main.loadJSON([
      {
        id: 'id1',
        adjacencies: [
          { nodeTo: 'id2' }, { nodeTo: 'id3' }
        ]
      }
    ]);
    main.refresh();

    var container = jQuery('

').appendTo(_debug);
    var over = new $NetworkMap.Views.Overview(main, { injectInto: 'utilitiestest1' }, 0);

    ok(true, 'created overview');
  });

});
<commit_msg>Add tests for overview manager<commit_after>jQuery(document).ready(function() {
  var _debug = jQuery('#output');

  module("Overview");

  test("Created canvas", function() {
    _debug.append('

');

    var opts = {
      injectInto: 'utilitiestest0',
      layout: 'ForceDirected',
      Navigation: {
        enable: true,
        panning: true,
        zooming: 40
      },
      Node: {
        overridable: true,
        dim: 20,
        lineWidth: 5
      },
      Edge: {
        overridable: true,
        color: '#23A4FF',
        lineWidth: 3,
        type: 'line'
      },
      Label: {
        type: 'SVG'
      }
    };

    var main = new $jit.NetworkMap(opts);

    main.loadJSON([
      {
        id: 'id1',
        adjacencies: [
          { nodeTo: 'id2' }, { nodeTo: 'id3' }
        ]
      }
    ]);
    main.refresh();

    var container = jQuery('

').appendTo(_debug);
    var over = new $NetworkMap.Views.Overview(main, { injectInto: 'utilitiestest1' }, 0);

    ok(true, 'created overview');
  });

  test("Overview Manager Test", function() {
    _debug.append('

');

    var opts = {
      injectInto: 'utilitiestest2',
      layout: 'ForceDirected',
      Navigation: {
        enable: true,
        panning: true,
        zooming: 40
      },
      Node: {
        overridable: true,
        dim: 20,
        lineWidth: 5
      },
      Edge: {
        overridable: true,
        color: '#23A4FF',
        lineWidth: 3,
        type: 'line'
      },
      Label: {
        type: 'SVG'
      }
    };

    var main = new $jit.NetworkMap(opts);

    main.loadJSON([
      {
        id: 'id1',
        adjacencies: [
          { nodeTo: 'id2' }, { nodeTo: 'id3' }
        ]
      }
    ]);
    main.refresh();

    var container = jQuery('

').appendTo(_debug);
    var manager = new $NetworkMap.Views.OverviewManager(main, container, 640, 150);

    ok(true, 'created overview');
  });

});
<|endoftext|>


<commit_before>var container, scene, camera, rendererMain, raycaster, objects = [];
var myKeyState = {};
var sphere;

var player, playerId, moveSpeed, turnSpeed;

var planeMesh;

var playerData;
var cssScene,rendererCSS;
var otherPlayers = [], otherPlayersId = [];

var loadWorld = function(){

    init();
    animate();

    function init(){

        //Setup------------------------------------------
        container = document.getElementById('container');
        var newName1 = document.createElement("TH");

        newName1.innerHTML = "<input type='text'  name='site' id='site' value='cell value'>";

        scene = new THREE.Scene();

        cssScene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.z = 5;
        //camera.lookAt( new THREE.Vector3(0,0,0));

        rendererCSS	= new THREE.CSS3DRenderer();
        rendererCSS.setSize( window.innerWidth, window.innerHeight );
        rendererCSS.domElement.style.position	= 'absolute';
        rendererCSS.domElement.style.top	= 0;
        rendererCSS.domElement.style.margin	= 0;
        rendererCSS.domElement.style.padding	= 0;
        document.body.appendChild( rendererCSS.domElement );

        rendererMain = new THREE.WebGLRenderer( { alpha: true} );
        rendererMain.setSize( window.innerWidth, window.innerHeight );
        rendererMain.domElement.style.position	= 'absolute';
        rendererMain.domElement.style.top	= 0;
        rendererMain.domElement.style.zIndex	= 1;
        rendererCSS.domElement.appendChild( rendererMain.domElement );

        raycaster = new THREE.Raycaster();
        //Add Objects To the Scene HERE-------------------

        var geometry = new THREE.PlaneGeometry( 20, 20, 32 );
        var material = new THREE.MeshBasicMaterial( {color: 0xCCFFFF, side: THREE.DoubleSide} );
        var plane = new THREE.Mesh( geometry, material );
        plane.rotation.x=(90*Math.PI/180);
        plane.position.y=0;

        scene.add( plane );

        var directionalLight = new THREE.DirectionalLight( 0xffffff, .1 );
        directionalLight.position.set(.3, 1, 0 );
        scene.add( directionalLight );

        var light = new THREE.AmbientLight( 0x444444 ); // soft white light
        scene.add( light );
        //Events------------------------------------------
        document.addEventListener('click', onMouseClick, false );
        document.addEventListener('mousedown', onMouseDown, false);
        document.addEventListener('mouseup', onMouseUp, false);
        document.addEventListener('mousemove', onMouseMove, false);
        document.addEventListener('mouseout', onMouseOut, false);
        document.addEventListener('keydown', onKeyDown, false );
        document.addEventListener('keyup', onKeyUp, false );
        window.addEventListener( 'resize', onWindowResize, false );

        //Final touches-----------------------------------

         var tag = document.createElement('script');

         tag.src = "https://www.youtube.com/iframe_api";
         vplayer = document.createElement( 'iframe' );
         var firstScriptTag = document.getElementsByTagName('script')[0];
         firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        //document.body.appendChild( container );

        var material = new THREE.MeshBasicMaterial({color: 0x000000,side: THREE.DoubleSide});
        material.color.set('black')
        material.opacity   = 0;
        material.blending  = THREE.NoBlending;
        var geometry = new THREE.PlaneGeometry(1.33333333*5,5,30);
        planeMesh= new THREE.Mesh( geometry, material );
        planeMesh.position.y +=2.5;
        // add it to the WebGL scene
        scene.add(planeMesh);

       	vplayer.style.width = '640px';
        vplayer.style.height = '480px';
       	vplayer.style.border = '0px';
        vplayer.style.border = '0px';

        var cssObject = new THREE.CSS3DObject( vplayer );
        // we reference the same position and rotation
        cssObject.position = planeMesh.position;
        cssObject.position.y+=2.5;
        cssObject.rotation = planeMesh.rotation;
        cssObject.scale.x= .0105;
        cssObject.scale.y=.0105;

        // add it to the css scene
        cssScene.add(cssObject);

    }

    function animate(){
        requestAnimationFrame( animate );
        render();
    }
    function render(){

        if ( player ){

            updateCameraPosition();

            checkKeyStates(myKeyState,player);
            updatePlayerData();
            socket.emit('updatePosition', playerData);
            for(var i=0; i<otherPlayers.length; i++){
                somePlayer=otherPlayers[i];
                checkKeyStates(somePlayer.keyState,somePlayer);
            }

            camera.lookAt( player.position );
            //camera.lookAt(planeMesh);
        }

        //Render Scene---------------------------------------
        rendererMain.clear();
        rendererMain.render( scene , camera );
        rendererCSS.render(cssScene,camera);

    }

    function onMouseClick(){
        intersects = calculateIntersects( event );

        if ( intersects.length > 0 ){
            //If object is intersected by mouse pointer, do something
            if (intersects[0].object == sphere){
                alert("This is a sphere!");
            }
        }
    }
    function onMouseDown(){

    }
    function onMouseUp(){

    }
    function onMouseMove(){

    }
    function onMouseOut(){

    }
    function onKeyDown( event ){

        //event = event || window.event;

        myKeyState[event.keyCode || event.which] = true;

    }

    function onKeyUp( event ){

        //event = event || window.event;

        myKeyState[event.keyCode || event.which] = false;

    }
    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize( window.innerWidth, window.innerHeight );

    }
    function calculateIntersects( event ){

        //Determine objects intersected by raycaster
        event.preventDefault();

        var vector = new THREE.Vector3();
        vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
        vector.unproject( camera );

        raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );

        var intersects = raycaster.intersectObjects( objects );

        return intersects;
    }

};

var createPlayer = function(data){

    playerData = data;

    //var cube_geometry = new THREE.BoxGeometry(data.sizeX, data.sizeY, data.sizeZ);
    var icosa_geometry = new THREE.DodecahedronGeometry(1);
    var cube_material = new THREE.MeshPhongMaterial({color: 0xffCCff, wireframe: false, shading: THREE.FlatShading, emissive: 0x9999FF});
    player = new THREE.Mesh(icosa_geometry, cube_material);

    player.rotation.set(0,0,0);

    player.position.x = data.x;
    player.position.y = data.y;
    player.position.z = data.z;

    playerId = data.playerId;
    moveSpeed = data.speed;
    turnSpeed = data.turnSpeed;

    updateCameraPosition();

    objects.push( player );
    scene.add( player );

    camera.lookAt( player.position );
};

var updateCameraPosition = function(){

    camera.position.x = player.position.x + 6 * Math.sin( player.rotation.y );
    camera.position.y = player.position.y + 3;
    camera.position.z = player.position.z + 6 * Math.cos( player.rotation.y );

};

var updatePlayerPosition = function(data){

    var somePlayer = playerForId(data.playerId);

    somePlayer.position.x = data.x;
    somePlayer.position.y = data.y;
    somePlayer.position.z = data.z;

    somePlayer.keyState = data.keyState;

    somePlayer.rotation.x = data.r_x;
    somePlayer.rotation.y = data.r_y;
    somePlayer.rotation.z = data.r_z;

};

var updatePlayerData = function(){
    playerData.x = player.position.x;
    playerData.y = player.position.y;
    playerData.z = player.position.z;
    playerData.keyState=myKeyState;

    playerData.r_x = player.rotation.x;
    playerData.r_y = player.rotation.y;
    playerData.r_z = player.rotation.z;

};
var checkKeyStates = function(keyState, somePlayer){

    if (keyState[38] || keyState[87]) {
        // up arrow or 'w' - move forward
        somePlayer.position.x -= moveSpeed * Math.sin(somePlayer.rotation.y);
        somePlayer.position.z -= moveSpeed * Math.cos(somePlayer.rotation.y);

    }
    if (keyState[40] || keyState[83]) {
        // down arrow or 's' - move backward
        somePlayer.position.x += moveSpeed * Math.sin(somePlayer.rotation.y);
        somePlayer.position.z += moveSpeed * Math.cos(somePlayer.rotation.y);

    }
    if (keyState[37] || keyState[65]) {
        // left arrow or 'a' - rotate left
        somePlayer.rotation.y += turnSpeed;
    }
    if (keyState[39] || keyState[68]) {
        // right arrow or 'd' - rotate right
        somePlayer.rotation.y -= turnSpeed;
    }
    if (keyState[81]) {
        // 'q' - strafe left
        somePlayer.position.x -= moveSpeed * Math.cos(somePlayer.rotation.y);
        somePlayer.position.z += moveSpeed * Math.sin(somePlayer.rotation.y);
    }
    if (keyState[69]) {
        // 'e' - strage right
        somePlayer.position.x += moveSpeed * Math.cos(somePlayer.rotation.y);
        somePlayer.position.z -= moveSpeed * Math.sin(somePlayer.rotation.y);
    }

};

var addOtherPlayer = function(data){
    var cube_geometry = new THREE.BoxGeometry(data.sizeX, data.sizeY, data.sizeZ);
    var cube_material = new THREE.MeshLambertMaterial({color: 0xCCCCFF, wireframe: false});
    var otherPlayer = new THREE.Mesh(cube_geometry, cube_material);

    otherPlayer.position.x = data.x;
    otherPlayer.position.y = data.y;
    otherPlayer.position.z = data.z;
    otherPlayer.keyState={};

    otherPlayersId.push( data.playerId );
    otherPlayers.push( otherPlayer );
    objects.push( otherPlayer );
    scene.add( otherPlayer );

};

var removeOtherPlayer = function(data){

    scene.remove( playerForId(data.playerId) );

};

 function onYouTubeIframeAPIReady() {
        vplayer = new YT.Player('player', {
          height: '200',
          width: '120',
          videoId: '9iahS41FBWc',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });

       /*	vplayer.style.width = '640px';
        vplayer.style.height = '480px';
       	vplayer.style.border = '0px';
        vplayer.style.border = '0px';

        var cssObject = new THREE.CSS3DObject( vplayer );
        // we reference the same position and rotation
        cssObject.position = planeMesh.position;
        cssObject.position.y+=2.5;
        cssObject.rotation = planeMesh.rotation;
        cssObject.scale.x= .0105;
        cssObject.scale.y=.0105;

        // add it to the css scene
        cssScene.add(cssObject);*/
 }

 function onPlayerReady(event) {
         event.target.playVideo();
         vplayer=document.getElementById('player');
         vplayer.style.width = '640px';
         vplayer.style.height = '480px';
         vplayer.style.border = '0px';
         vplayer.style.border = '0px';

         var cssObject = new THREE.CSS3DObject( vplayer );
         // we reference the same position and rotation
         cssObject.position = planeMesh.position;
         cssObject.position.y+=2.5;
         cssObject.rotation = planeMesh.rotation;
         cssObject.scale.x= .0105;
         cssObject.scale.y=.0105;

         // add it to the css scene
         cssScene.add(cssObject);
 }
       function stopVideo() {
         player.stopVideo();
       }

      function onPlayerStateChange(event) {

      }
var playerForId = function(id){
    var index;
    for (var i = 0; i < otherPlayersId.length; i++){
        if (otherPlayersId[i] == id){
            index = i;
            break;
        }
    }
    return otherPlayers[index];
};<commit_msg>jumpman<commit_after>var container, scene, camera, rendererMain, raycaster, objects = [];
var myKeyState = {};
var sphere;

var player, playerId, moveSpeed, turnSpeed;

var planeMesh;

var playerData;
var cssScene,rendererCSS;
var otherPlayers = [], otherPlayersId = [];

var loadWorld = function(){

    init();
    animate();

    function init(){

        //Setup------------------------------------------
        container = document.getElementById('container');
        var newName1 = document.createElement("TH");

        newName1.innerHTML = "<input type='text'  name='site' id='site' value='cell value'>";

        scene = new THREE.Scene();

        cssScene = new THREE.Scene();

        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.z = 5;
        //camera.lookAt( new THREE.Vector3(0,0,0));

        rendererCSS	= new THREE.CSS3DRenderer();
        rendererCSS.setSize( window.innerWidth, window.innerHeight );
        rendererCSS.domElement.style.position	= 'absolute';
        rendererCSS.domElement.style.top	= 0;
        rendererCSS.domElement.style.margin	= 0;
        rendererCSS.domElement.style.padding	= 0;
        document.body.appendChild( rendererCSS.domElement );

        rendererMain = new THREE.WebGLRenderer( { alpha: true} );
        rendererMain.setSize( window.innerWidth, window.innerHeight );
        rendererMain.domElement.style.position	= 'absolute';
        rendererMain.domElement.style.top	= 0;
        rendererMain.domElement.style.zIndex	= 1;
        rendererCSS.domElement.appendChild( rendererMain.domElement );

        raycaster = new THREE.Raycaster();
        //Add Objects To the Scene HERE-------------------

        var geometry = new THREE.PlaneGeometry( 20, 20, 32 );
        var material = new THREE.MeshBasicMaterial( {color: 0xCCFFFF, side: THREE.DoubleSide} );
        var plane = new THREE.Mesh( geometry, material );
        plane.rotation.x=(90*Math.PI/180);
        plane.position.y=0;

        scene.add( plane );

        var directionalLight = new THREE.DirectionalLight( 0xffffff, .1 );
        directionalLight.position.set(.3, 1, 0 );
        scene.add( directionalLight );

        var light = new THREE.AmbientLight( 0x444444 ); // soft white light
        scene.add( light );
        //Events------------------------------------------
        document.addEventListener('click', onMouseClick, false );
        document.addEventListener('mousedown', onMouseDown, false);
        document.addEventListener('mouseup', onMouseUp, false);
        document.addEventListener('mousemove', onMouseMove, false);
        document.addEventListener('mouseout', onMouseOut, false);
        document.addEventListener('keydown', onKeyDown, false );
        document.addEventListener('keyup', onKeyUp, false );
        window.addEventListener( 'resize', onWindowResize, false );

        //Final touches-----------------------------------

         var tag = document.createElement('script');

         tag.src = "https://www.youtube.com/iframe_api";
         vplayer = document.createElement( 'iframe' );
         var firstScriptTag = document.getElementsByTagName('script')[0];
         firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

        //document.body.appendChild( container );

        var material = new THREE.MeshBasicMaterial({color: 0x000000,side: THREE.DoubleSide});
        material.color.set('black')
        material.opacity   = 0;
        material.blending  = THREE.NoBlending;
        var geometry = new THREE.PlaneGeometry(1.33333333*5,5,30);
        planeMesh= new THREE.Mesh( geometry, material );
        planeMesh.position.y +=2.5;
        // add it to the WebGL scene
        scene.add(planeMesh);

       	vplayer.style.width = '640px';
        vplayer.style.height = '480px';
       	vplayer.style.border = '0px';
        vplayer.style.border = '0px';

        var cssObject = new THREE.CSS3DObject( vplayer );
        // we reference the same position and rotation
        cssObject.position = planeMesh.position;
        cssObject.position.y+=2.5;
        cssObject.rotation = planeMesh.rotation;
        cssObject.scale.x= .0105;
        cssObject.scale.y=.0105;

        // add it to the css scene
        cssScene.add(cssObject);

    }

    function animate(){
        requestAnimationFrame( animate );
        render();
    }
    function render(){

        if ( player ){

            updateCameraPosition();

            checkKeyStates(myKeyState,player);
            updatePlayerData();
            socket.emit('updatePosition', playerData);
            for(var i=0; i<otherPlayers.length; i++){
                somePlayer=otherPlayers[i];
                checkKeyStates(somePlayer.keyState,somePlayer);
            }

            camera.lookAt( player.position );
            //camera.lookAt(planeMesh);
        }

        //Render Scene---------------------------------------
        rendererMain.clear();
        rendererMain.render( scene , camera );
        rendererCSS.render(cssScene,camera);

    }

    function onMouseClick(){
        intersects = calculateIntersects( event );

        if ( intersects.length > 0 ){
            //If object is intersected by mouse pointer, do something
            if (intersects[0].object == sphere){
                alert("This is a sphere!");
            }
        }
    }
    function onMouseDown(){

    }
    function onMouseUp(){

    }
    function onMouseMove(){

    }
    function onMouseOut(){

    }
    function onKeyDown( event ){

        //event = event || window.event;

        myKeyState[event.keyCode || event.which] = true;

    }

    function onKeyUp( event ){

        //event = event || window.event;

        myKeyState[event.keyCode || event.which] = false;

    }
    function onWindowResize() {

        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();

        renderer.setSize( window.innerWidth, window.innerHeight );

    }
    function calculateIntersects( event ){

        //Determine objects intersected by raycaster
        event.preventDefault();

        var vector = new THREE.Vector3();
        vector.set( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
        vector.unproject( camera );

        raycaster.ray.set( camera.position, vector.sub( camera.position ).normalize() );

        var intersects = raycaster.intersectObjects( objects );

        return intersects;
    }

};

var createPlayer = function(data){

    playerData = data;

    //var cube_geometry = new THREE.BoxGeometry(data.sizeX, data.sizeY, data.sizeZ);
    var icosa_geometry = new THREE.DodecahedronGeometry(1);
    var cube_material = new THREE.MeshPhongMaterial({color: 0xffCCff, wireframe: false, shading: THREE.FlatShading, emissive: 0x9999FF});
    player = new THREE.Mesh(icosa_geometry, cube_material);

    player.rotation.set(0,0,0);

    player.position.x = data.x;
    player.position.y = data.y;
    player.position.z = data.z;

    playerId = data.playerId;
    moveSpeed = data.speed;
    turnSpeed = data.turnSpeed;

    updateCameraPosition();

    objects.push( player );
    scene.add( player );

    camera.lookAt( player.position );
};

var updateCameraPosition = function(){

    camera.position.x = player.position.x + 6 * Math.sin( player.rotation.y );
    camera.position.y = player.position.y + 3;
    camera.position.z = player.position.z + 6 * Math.cos( player.rotation.y );

};

var updatePlayerPosition = function(data){

    var somePlayer = playerForId(data.playerId);

    somePlayer.position.x = data.x;
    somePlayer.position.y = data.y;
    somePlayer.position.z = data.z;

    somePlayer.keyState = data.keyState;

    somePlayer.rotation.x = data.r_x;
    somePlayer.rotation.y = data.r_y;
    somePlayer.rotation.z = data.r_z;

};

var updatePlayerData = function(){
    playerData.x = player.position.x;
    playerData.y = player.position.y;
    playerData.z = player.position.z;
    playerData.keyState=myKeyState;

    playerData.r_x = player.rotation.x;
    playerData.r_y = player.rotation.y;
    playerData.r_z = player.rotation.z;

};
var checkKeyStates = function(keyState, somePlayer){

    if (keyState[38] || keyState[87]) {
        // up arrow or 'w' - move forward
        somePlayer.position.x -= moveSpeed * Math.sin(somePlayer.rotation.y);
        somePlayer.position.z -= moveSpeed * Math.cos(somePlayer.rotation.y);

    }
    if (keyState[40] || keyState[83]) {
        // down arrow or 's' - move backward
        somePlayer.position.x += moveSpeed * Math.sin(somePlayer.rotation.y);
        somePlayer.position.z += moveSpeed * Math.cos(somePlayer.rotation.y);

    }
    if (keyState[37] || keyState[65]) {
        // left arrow or 'a' - rotate left
        somePlayer.rotation.y += turnSpeed;
    }
    if (keyState[39] || keyState[68]) {
        // right arrow or 'd' - rotate right
        somePlayer.rotation.y -= turnSpeed;
    }
    if (keyState[81]) {
        // 'q' - strafe left
        somePlayer.position.x -= moveSpeed * Math.cos(somePlayer.rotation.y);
        somePlayer.position.z += moveSpeed * Math.sin(somePlayer.rotation.y);
    }
    if (keyState[69]) {
        // 'e' - strage right
        somePlayer.position.x += moveSpeed * Math.cos(somePlayer.rotation.y);
        somePlayer.position.z -= moveSpeed * Math.sin(somePlayer.rotation.y);
    }

};

var addOtherPlayer = function(data){
    var cube_geometry = new THREE.BoxGeometry(data.sizeX, data.sizeY, data.sizeZ);
    var cube_material = new THREE.MeshLambertMaterial({color: 0xCCCCFF, wireframe: false});
    var otherPlayer = new THREE.Mesh(cube_geometry, cube_material);

    otherPlayer.position.x = data.x;
    otherPlayer.position.y = data.y;
    otherPlayer.position.z = data.z;
    otherPlayer.keyState={};

    otherPlayersId.push( data.playerId );
    otherPlayers.push( otherPlayer );
    objects.push( otherPlayer );
    scene.add( otherPlayer );

};

var removeOtherPlayer = function(data){

    scene.remove( playerForId(data.playerId) );

};

 function onYouTubeIframeAPIReady() {
        vplayer = new YT.Player('player', {
          height: '200',
          width: '120',
          videoId: 'JsgU4t8EAEU',
          events: {
            'onReady': onPlayerReady,
            'onStateChange': onPlayerStateChange
          }
        });

       /*	vplayer.style.width = '640px';
        vplayer.style.height = '480px';
       	vplayer.style.border = '0px';
        vplayer.style.border = '0px';

        var cssObject = new THREE.CSS3DObject( vplayer );
        // we reference the same position and rotation
        cssObject.position = planeMesh.position;
        cssObject.position.y+=2.5;
        cssObject.rotation = planeMesh.rotation;
        cssObject.scale.x= .0105;
        cssObject.scale.y=.0105;

        // add it to the css scene
        cssScene.add(cssObject);*/
 }

 function onPlayerReady(event) {
         event.target.playVideo();
         vplayer=document.getElementById('player');
         vplayer.style.width = '640px';
         vplayer.style.height = '480px';
         vplayer.style.border = '0px';
         vplayer.style.border = '0px';

         var cssObject = new THREE.CSS3DObject( vplayer );
         // we reference the same position and rotation
         cssObject.position = planeMesh.position;
         cssObject.position.y+=2.5;
         cssObject.rotation = planeMesh.rotation;
         cssObject.scale.x= .0105;
         cssObject.scale.y=.0105;

         // add it to the css scene
         cssScene.add(cssObject);
 }
       function stopVideo() {
         player.stopVideo();
       }

      function onPlayerStateChange(event) {

      }
var playerForId = function(id){
    var index;
    for (var i = 0; i < otherPlayersId.length; i++){
        if (otherPlayersId[i] == id){
            index = i;
            break;
        }
    }
    return otherPlayers[index];
};<|endoftext|>