<commit_before>'use strict';
import {getTrackCSS, getTrackLeft, getTrackAnimateCSS} from './trackHelper';
import helpers from './helpers';
import assign from 'object-assign';

var EventHandlers = {
  // Event handler for previous and next
  changeSlide: function (options) {
    var indexOffset, previousInt, slideOffset, unevenOffset, targetSlide;
    const {slidesToScroll, slidesToShow} = this.props
    const {slideCount, currentSlide} = this.state
    unevenOffset = (slideCount % slidesToScroll !== 0);
    indexOffset = unevenOffset ? 0 : (slideCount - currentSlide) % slidesToScroll;

    if (options.message === 'previous') {
      slideOffset = (indexOffset === 0) ? slidesToScroll : slidesToShow - indexOffset;
      targetSlide = currentSlide - slideOffset;
      if (this.props.lazyLoad) {
        previousInt = currentSlide - slideOffset;
        targetSlide = previousInt === -1 ? slideCount -1 : previousInt;
      }
    } else if (options.message === 'next') {
      slideOffset = (indexOffset === 0) ? slidesToScroll : indexOffset;
      targetSlide = currentSlide + slideOffset;
      if (this.props.lazyLoad) {
        targetSlide = ((currentSlide + slidesToScroll) % slideCount) + indexOffset;
      }
    } else if (options.message === 'dots' || options.message === 'children') {
      // Click on dots
      targetSlide = options.index * options.slidesToScroll;
      if (targetSlide === options.currentSlide) {
        return;
      }
    } else if (options.message === 'index') {
      targetSlide = parseInt(options.index);
      if (targetSlide === options.currentSlide) {
        return;
      }
    }

    this.slideHandler(targetSlide);
  },

  // Accessiblity handler for previous and next
  keyHandler: function (e) {
    //Dont slide if the cursor is inside the form fields and arrow keys are pressed
    if(!e.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
        if (e.keyCode === 37 && this.props.accessibility === true) {
            this.changeSlide({
              message: this.props.rtl === true ? 'next' :  'previous'
            });
        } else if (e.keyCode === 39 && this.props.accessibility === true) {
            this.changeSlide({
              message: this.props.rtl === true ? 'previous' : 'next'
            });
        }
    }
  },
  // Focus on selecting a slide (click handler on track)
  selectHandler: function (options) {
    this.changeSlide(options)
  },
  swipeStart: function (e) {
    var touches, posX, posY;

    if ((this.props.swipe === false) || ('ontouchend' in document && this.props.swipe === false)) {
      return;
    } else if (this.props.draggable === false && e.type.indexOf('mouse') !== -1) {
      return;
    }
    posX = (e.touches !== undefined) ? e.touches[0].pageX : e.clientX;
    posY = (e.touches !== undefined) ? e.touches[0].pageY : e.clientY;
    this.setState({
      dragging: true,
      touchObject: {
        startX: posX,
        startY: posY,
        curX: posX,
        curY: posY
      }
    });
  },
  swipeMove: function (e) {
    if (!this.state.dragging) {
      e.preventDefault();
      return;
    }
    if (this.state.animating) {
      return;
    }
    var swipeLeft;
    var curLeft, positionOffset;
    var touchObject = this.state.touchObject;

    curLeft = getTrackLeft(assign({
      slideIndex: this.state.currentSlide,
      trackRef: this.track
    }, this.props, this.state));
    touchObject.curX = (e.touches) ? e.touches[0].pageX : e.clientX;
    touchObject.curY = (e.touches) ? e.touches[0].pageY : e.clientY;
    touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(touchObject.curX - touchObject.startX, 2)));

    if (this.props.verticalSwiping) {
      touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(touchObject.curY - touchObject.startY, 2)));
    }

    positionOffset = (this.props.rtl === false ? 1 : -1) * (touchObject.curX > touchObject.startX ? 1 : -1);

    if (this.props.verticalSwiping) {
      positionOffset = touchObject.curY > touchObject.startY ? 1 : -1;
    }

    var currentSlide = this.state.currentSlide;
    var dotCount = Math.ceil(this.state.slideCount / this.props.slidesToScroll);
    var swipeDirection = this.swipeDirection(this.state.touchObject);
    var touchSwipeLength = touchObject.swipeLength;

    if (this.props.infinite === false) {
      if ((currentSlide === 0 && swipeDirection === 'right') || (currentSlide + 1 >= dotCount && swipeDirection === 'left')) {
        touchSwipeLength = touchObject.swipeLength * this.props.edgeFriction;

        if (this.state.edgeDragged === false && this.props.edgeEvent) {
          this.props.edgeEvent(swipeDirection);
          this.setState({ edgeDragged: true });
        }
      }
    }

    if (this.state.swiped === false && this.props.swipeEvent) {
      this.props.swipeEvent(swipeDirection);
      this.setState({ swiped: true });
    }

    if (!this.props.vertical) {
      swipeLeft = curLeft + touchSwipeLength * positionOffset;
    } else {
      swipeLeft = curLeft + (touchSwipeLength * (this.state.listHeight / this.state.listWidth)) * positionOffset;
    }

    if (this.props.verticalSwiping) {
      swipeLeft = curLeft + touchSwipeLength * positionOffset;
    }

    this.setState({
      touchObject: touchObject,
      swipeLeft: swipeLeft,
      trackStyle: getTrackCSS(assign({left: swipeLeft}, this.props, this.state))
    });

    if (Math.abs(touchObject.curX - touchObject.startX) < Math.abs(touchObject.curY - touchObject.startY) * 0.8)
      { return; }
    if (touchObject.swipeLength > 4) {
      e.preventDefault();
    }
  },
  swipeEnd: function (e) {
    if (!this.state.dragging) {
      e.preventDefault();
      return;
    }
    var touchObject = this.state.touchObject;
    var minSwipe = this.state.listWidth/this.props.touchThreshold;
    var swipeDirection = this.swipeDirection(touchObject);

    // reset the state of touch related state variables.
    this.setState({
      dragging: false,
      edgeDragged: false,
      swiped: false,
      swipeLeft: null,
      touchObject: {}
    });
    // Fix for #13
    if (!touchObject.swipeLength) {
      return;
    }
    if (touchObject.swipeLength > minSwipe) {
      e.preventDefault();
      if (swipeDirection === 'left') {
        this.slideHandler(this.state.currentSlide + this.props.slidesToScroll);
      } else if (swipeDirection === 'right') {
        this.slideHandler(this.state.currentSlide - this.props.slidesToScroll);
      } else {
        this.slideHandler(this.state.currentSlide);
      }
    } else {
      // Adjust the track back to it's original position.
      var currentLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.track
      }, this.props, this.state));

      this.setState({
        trackStyle: getTrackAnimateCSS(assign({left: currentLeft}, this.props, this.state))
      });
    }
  },
  onInnerSliderEnter: function (e) {
    if (this.props.autoplay && this.props.pauseOnHover) {
      this.pause();
    }
  },
  onInnerSliderLeave: function (e) {
    if (this.props.autoplay && this.props.pauseOnHover) {
      this.autoPlay();
    }
  }
};

export default EventHandlers;
<commit_msg>Made necessary changes to swipeEnd event handler for vertical mode.<commit_after>'use strict';
import {getTrackCSS, getTrackLeft, getTrackAnimateCSS} from './trackHelper';
import helpers from './helpers';
import assign from 'object-assign';

var EventHandlers = {
  // Event handler for previous and next
  changeSlide: function (options) {
    var indexOffset, previousInt, slideOffset, unevenOffset, targetSlide;
    const {slidesToScroll, slidesToShow} = this.props
    const {slideCount, currentSlide} = this.state
    unevenOffset = (slideCount % slidesToScroll !== 0);
    indexOffset = unevenOffset ? 0 : (slideCount - currentSlide) % slidesToScroll;

    if (options.message === 'previous') {
      slideOffset = (indexOffset === 0) ? slidesToScroll : slidesToShow - indexOffset;
      targetSlide = currentSlide - slideOffset;
      if (this.props.lazyLoad) {
        previousInt = currentSlide - slideOffset;
        targetSlide = previousInt === -1 ? slideCount -1 : previousInt;
      }
    } else if (options.message === 'next') {
      slideOffset = (indexOffset === 0) ? slidesToScroll : indexOffset;
      targetSlide = currentSlide + slideOffset;
      if (this.props.lazyLoad) {
        targetSlide = ((currentSlide + slidesToScroll) % slideCount) + indexOffset;
      }
    } else if (options.message === 'dots' || options.message === 'children') {
      // Click on dots
      targetSlide = options.index * options.slidesToScroll;
      if (targetSlide === options.currentSlide) {
        return;
      }
    } else if (options.message === 'index') {
      targetSlide = parseInt(options.index);
      if (targetSlide === options.currentSlide) {
        return;
      }
    }

    this.slideHandler(targetSlide);
  },

  // Accessiblity handler for previous and next
  keyHandler: function (e) {
    //Dont slide if the cursor is inside the form fields and arrow keys are pressed
    if(!e.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
        if (e.keyCode === 37 && this.props.accessibility === true) {
            this.changeSlide({
              message: this.props.rtl === true ? 'next' :  'previous'
            });
        } else if (e.keyCode === 39 && this.props.accessibility === true) {
            this.changeSlide({
              message: this.props.rtl === true ? 'previous' : 'next'
            });
        }
    }
  },
  // Focus on selecting a slide (click handler on track)
  selectHandler: function (options) {
    this.changeSlide(options)
  },
  swipeStart: function (e) {
    var touches, posX, posY;

    if ((this.props.swipe === false) || ('ontouchend' in document && this.props.swipe === false)) {
      return;
    } else if (this.props.draggable === false && e.type.indexOf('mouse') !== -1) {
      return;
    }
    posX = (e.touches !== undefined) ? e.touches[0].pageX : e.clientX;
    posY = (e.touches !== undefined) ? e.touches[0].pageY : e.clientY;
    this.setState({
      dragging: true,
      touchObject: {
        startX: posX,
        startY: posY,
        curX: posX,
        curY: posY
      }
    });
  },
  swipeMove: function (e) {
    if (!this.state.dragging) {
      e.preventDefault();
      return;
    }
    if (this.state.animating) {
      return;
    }
    var swipeLeft;
    var curLeft, positionOffset;
    var touchObject = this.state.touchObject;

    curLeft = getTrackLeft(assign({
      slideIndex: this.state.currentSlide,
      trackRef: this.track
    }, this.props, this.state));
    touchObject.curX = (e.touches) ? e.touches[0].pageX : e.clientX;
    touchObject.curY = (e.touches) ? e.touches[0].pageY : e.clientY;
    touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(touchObject.curX - touchObject.startX, 2)));

    if (this.props.verticalSwiping) {
      touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(touchObject.curY - touchObject.startY, 2)));
    }

    positionOffset = (this.props.rtl === false ? 1 : -1) * (touchObject.curX > touchObject.startX ? 1 : -1);

    if (this.props.verticalSwiping) {
      positionOffset = touchObject.curY > touchObject.startY ? 1 : -1;
    }

    var currentSlide = this.state.currentSlide;
    var dotCount = Math.ceil(this.state.slideCount / this.props.slidesToScroll);
    var swipeDirection = this.swipeDirection(this.state.touchObject);
    var touchSwipeLength = touchObject.swipeLength;

    if (this.props.infinite === false) {
      if ((currentSlide === 0 && swipeDirection === 'right') || (currentSlide + 1 >= dotCount && swipeDirection === 'left')) {
        touchSwipeLength = touchObject.swipeLength * this.props.edgeFriction;

        if (this.state.edgeDragged === false && this.props.edgeEvent) {
          this.props.edgeEvent(swipeDirection);
          this.setState({ edgeDragged: true });
        }
      }
    }

    if (this.state.swiped === false && this.props.swipeEvent) {
      this.props.swipeEvent(swipeDirection);
      this.setState({ swiped: true });
    }

    if (!this.props.vertical) {
      swipeLeft = curLeft + touchSwipeLength * positionOffset;
    } else {
      swipeLeft = curLeft + (touchSwipeLength * (this.state.listHeight / this.state.listWidth)) * positionOffset;
    }

    if (this.props.verticalSwiping) {
      swipeLeft = curLeft + touchSwipeLength * positionOffset;
    }

    this.setState({
      touchObject: touchObject,
      swipeLeft: swipeLeft,
      trackStyle: getTrackCSS(assign({left: swipeLeft}, this.props, this.state))
    });

    if (Math.abs(touchObject.curX - touchObject.startX) < Math.abs(touchObject.curY - touchObject.startY) * 0.8)
      { return; }
    if (touchObject.swipeLength > 4) {
      e.preventDefault();
    }
  },
  swipeEnd: function (e) {
    if (!this.state.dragging) {
      e.preventDefault();
      return;
    }
    var touchObject = this.state.touchObject;
    var minSwipe = this.state.listWidth/this.props.touchThreshold;
    var swipeDirection = this.swipeDirection(touchObject);

    if (this.props.verticalSwiping) {
      minSwipe = this.state.listHeight/this.props.touchThreshold;
    }

    // reset the state of touch related state variables.
    this.setState({
      dragging: false,
      edgeDragged: false,
      swiped: false,
      swipeLeft: null,
      touchObject: {}
    });
    // Fix for #13
    if (!touchObject.swipeLength) {
      return;
    }
    if (touchObject.swipeLength > minSwipe) {
      e.preventDefault();
      if (swipeDirection === 'left') {
        this.slideHandler(this.state.currentSlide + this.props.slidesToScroll);
      } else if (swipeDirection === 'right') {
        this.slideHandler(this.state.currentSlide - this.props.slidesToScroll);
      } else {
        this.slideHandler(this.state.currentSlide);
      }
    } else {
      // Adjust the track back to it's original position.
      var currentLeft = getTrackLeft(assign({
        slideIndex: this.state.currentSlide,
        trackRef: this.track
      }, this.props, this.state));

      this.setState({
        trackStyle: getTrackAnimateCSS(assign({left: currentLeft}, this.props, this.state))
      });
    }
  },
  onInnerSliderEnter: function (e) {
    if (this.props.autoplay && this.props.pauseOnHover) {
      this.pause();
    }
  },
  onInnerSliderLeave: function (e) {
    if (this.props.autoplay && this.props.pauseOnHover) {
      this.autoPlay();
    }
  }
};

export default EventHandlers;
<|endoftext|>


<commit_before>(function(){
  // http://stackoverflow.com/questions/10906734/how-to-upload-image-into-html5-canvas
  var original;
  var imageLoader = document.querySelector('#imageLoader');
  imageLoader.addEventListener('change', handleImage, false);
  var canvas = document.querySelector('#image');
  var ctx = canvas.getContext('2d');

  function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
      var img = new Image();
      img.onload = function(){
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img,0,0);
        original = ctx.getImageData(0, 0, canvas.width, canvas.height);
      }
      img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
  }

  // greys out the buttons while manipulation is happening
  // un-greys out the buttons when the manipulation is done
  function toggleButtonsAbledness() {
    var buttons = document.querySelectorAll('button');
    for (var i = 0; i < buttons.length; i++) {
      if (buttons[i].hasAttribute('disabled')) {
        buttons[i].removeAttribute('disabled')
      } else {
        buttons[i].setAttribute('disabled', null);
      }
    };
  }

  function manipulateImage(type) {
    var a, b, g, i, imageData, j, length, pixel, r, ref;
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    toggleButtonsAbledness();

    var myWorker = new Worker("scripts/worker.js");
    onchange = function() {
      myWorker.postMessage(imageData);
    }
    myWorker.onmessage = function(e) {
      imageData = imageData;
    }

    toggleButtonsAbledness();
    return ctx.putImageData(imageData, 0, 0);
  };

  function revertImage() {
    return ctx.putImageData(original, 0, 0);
  }

  document.querySelector('#invert').onclick = function() {
    manipulateImage("invert");
  };
  document.querySelector('#chroma').onclick = function() {
    manipulateImage("chroma");
  };
  document.querySelector('#greyscale').onclick = function() {
    manipulateImage("greyscale");
  };
  document.querySelector('#vibrant').onclick = function() {
    manipulateImage("vibrant");
  };
  document.querySelector('#revert').onclick = function() {
    revertImage();
  };
})();<commit_msg>troubleshooting<commit_after>(function(){
  // http://stackoverflow.com/questions/10906734/how-to-upload-image-into-html5-canvas
  var original;
  var imageLoader = document.querySelector('#imageLoader');
  imageLoader.addEventListener('change', handleImage, false);
  var canvas = document.querySelector('#image');
  var ctx = canvas.getContext('2d');

  function handleImage(e){
    var reader = new FileReader();
    reader.onload = function(event){
      var img = new Image();
      img.onload = function(){
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img,0,0);
        original = ctx.getImageData(0, 0, canvas.width, canvas.height);
      }
      img.src = event.target.result;
    }
    reader.readAsDataURL(e.target.files[0]);
  }

  // greys out the buttons while manipulation is happening
  // un-greys out the buttons when the manipulation is done
  function toggleButtonsAbledness() {
    var buttons = document.querySelectorAll('button');
    for (var i = 0; i < buttons.length; i++) {
      if (buttons[i].hasAttribute('disabled')) {
        buttons[i].removeAttribute('disabled')
      } else {
        buttons[i].setAttribute('disabled', null);
      }
    };
  }

  function manipulateImage(type) {
    var a, b, g, i, imageData, j, length, pixel, r, ref;
    imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

    toggleButtonsAbledness();

    var myWorker = new Worker("scripts/worker.js");
    onchange = function() {
      myWorker.postMessage(imageData);
    }
    onchange();
    myWorker.onmessage = function(e) {
      imageData = e.data.imageData;
    }

    toggleButtonsAbledness();
    return ctx.putImageData(imageData, 0, 0);
  };

  function revertImage() {
    return ctx.putImageData(original, 0, 0);
  }

  document.querySelector('#invert').onclick = function() {
    manipulateImage("invert");
  };
  document.querySelector('#chroma').onclick = function() {
    manipulateImage("chroma");
  };
  document.querySelector('#greyscale').onclick = function() {
    manipulateImage("greyscale");
  };
  document.querySelector('#vibrant').onclick = function() {
    manipulateImage("vibrant");
  };
  document.querySelector('#revert').onclick = function() {
    revertImage();
  };
})();<|endoftext|>


<commit_before>elation.require(['engine.things.generic', 'utils.template'], function() {
  elation.template.add('janusweb.edit.object',
      '<Object id=^{id}^ js_id=^{js_id}^ locked=^false^ pos=^{pos.x} {pos.y} {pos.z}^ vel=^{vel.x} {vel.y} {vel.z}^ accel=^{accel.x} {accel.y} {accel.z}^ xdir=^{xdir}^ ydir=^{ydir}^ zdir=^{zdir}^ scale=^{scale.x} {scale.y} {scale.z}^ col=^{col}^ lighting=^{lighting}^ visible=^{visible}^ />');

  elation.component.add('engine.things.janusbase', function() {
    this.defaultcolor = new THREE.Color(0xffffff);

    this.postinit = function() {
      elation.engine.things.janusbase.extendclass.postinit.call(this);
      this.frameupdates = [];
      this.defineProperties({
        room:     { type: 'object' },
        janus:    { type: 'object' },
        js_id:    { type: 'string' },
        color:    { type: 'color', default: this.defaultcolor, set: this.updateMaterial },
        fwd:      { type: 'vector3', default: new THREE.Vector3(0,0,1), set: this.pushFrameUpdate },
        xdir:     { type: 'vector3', default: new THREE.Vector3(1,0,0), set: this.pushFrameUpdate },
        ydir:     { type: 'vector3', default: new THREE.Vector3(0,1,0), set: this.pushFrameUpdate },
        zdir:     { type: 'vector3', default: new THREE.Vector3(0,0,1), set: this.pushFrameUpdate },
        lighting: { type: 'boolean', default: true },
        sync:     { type: 'boolean', default: false },
        rotate_axis: { type: 'string', default: '0 1 0' },
        rotate_deg_per_sec: { type: 'string' },
        onclick: { type: 'object' },
      });
      //if (this.col) this.color = this.col;
      this.jschildren = [];
      this.assets = {};
      elation.events.add(this.room, 'janusweb_script_frame_end', elation.bind(this, this.handleFrameUpdates));

      if (this.onclick) {
        if (elation.utils.isString(this.onclick)) {
          elation.events.add(this, 'click', elation.bind(this, function() {
            eval(this.onclick);
          }));

        } else {
          elation.events.add(this, 'click', elation.bind(this, this.onclick));
        }
      }
    }
    this.createForces = function() {
      elation.events.add(this.objects.dynamics, 'physics_collide', elation.bind(this, this.handleCollision));

      var rotate_axis = this.properties.rotate_axis,
          rotate_speed = this.properties.rotate_deg_per_sec;
      if (rotate_axis && rotate_speed) {
        var speed = (rotate_speed * Math.PI/180);
        var axisparts = rotate_axis.split(' ');
        var axis = new THREE.Vector3().set(axisparts[0], axisparts[1], axisparts[2]);
        axis.multiplyScalar(speed);
        this.objects.dynamics.setAngularVelocity(axis);
      }

    }
    this.setProperties = function(props) {
      var n = this.janus.parser.parseNode(props);
      var rebuild = false;

      if (n.pos) this.properties.position.fromArray(n.pos);
      if (n.scale) this.properties.scale.fromArray(n.scale);
      if (n.orientation) this.properties.orientation.copy(n.orientation);

      if (n.id && n.id != this.properties.render.model) {
        this.properties.render.model = n.id;
        rebuild = true;
      }
      var curcol = this.properties.col || [1,1,1];
      if (n.col && (n.col[0] != curcol[0] || n.col[1] != curcol[1] || n.col[2] != curcol[2])) {
        this.properties.col = n.col;
        rebuild = true;
      }
      if (rebuild) {
        //this.set('visible', true, true);
      }
      if (n.accel) this.properties.acceleration.fromArray(n.accel.split(' ').map(parseFloat));
      if (n.vel) this.objects.dynamics.setVelocity(this.properties.velocity.fromArray(n.vel.split(' ').map(parseFloat)));
      this.refresh();
    }
    this.summarizeXML = function() {
      //'<Object id=^{id}^ js_id=^{js_id}^ locked=^false^ pos=^{pos.x} {pos.y} {pos.z}^ vel=^{vel.x} {vel.y} {vel.z}^ accel=^{accel.x} {accel.y} {accel.z}^ xdir=^{xdir}^ ydir=^{ydir}^ zdir=^{zdir}^ scale=^{scale.x} {scale.y} {scale.z}^ col=^{color}^ lighting=^{lighting}^ visible=^{visible}^ />');

      var matrix = new THREE.Matrix4().makeRotationFromQuaternion(this.properties.orientation);
      var xdir = new THREE.Vector3(),
          ydir = new THREE.Vector3(),
          zdir = new THREE.Vector3();
      matrix.extractBasis(xdir, ydir, zdir);

      var objdef = {
        id: this.properties.render.model,
        js_id: this.properties.js_id,
        pos: this.properties.position,
        vel: this.properties.velocity,
        accel: this.properties.acceleration,
        scale: this.properties.scale,
        xdir: xdir.toArray().join(' '),
        ydir: ydir.toArray().join(' '),
        zdir: zdir.toArray().join(' '),
        col: this.properties.color,
        lighting: this.properties.lighting,
        visible: this.properties.visible,
      };

      var xml = elation.template.get('janusweb.edit.object', objdef);
      return xml;
    }
    this.getProxyObject = function() {
      if (!this._proxyobject) {
        this._proxyobject = new elation.proxy(this, {
          js_id:    ['property', 'properties.js_id'],
          pos:      ['property', 'position'],
          vel:      ['property', 'velocity'],
          accel:    ['property', 'acceleration'],
          mass:     ['property', 'mass'],
          scale:    ['property', 'scale'],
          col:      ['property', 'color'],
          fwd:      ['property', 'zdir'],
          xdir:     ['property', 'xdir'],
          ydir:     ['property', 'ydir'],
          zdir:     ['property', 'zdir'],
          sync:     ['property', 'sync'],
          children: ['property', 'jschildren'],

          oncollision: ['callback', 'collision'],
          onclick:     ['callback', 'click'],

          appendChild: ['function', 'appendChild']
        });
      }
      return this._proxyobject;
    }
    this.getAsset = function(type, id) {
      if (!this.assets[type]) {
        this.assets[type] = {};
      }
      var asset = this.assets[type][id];
      if (!asset) {
        asset = elation.engine.assets.find(type, id, true);
        if (!asset) {
          var assetpack = { assettype:type, name:id, src: id, baseurl: this.room.baseurl };
          elation.engine.assets.loadJSON([assetpack], this.room.baseurl);
          asset = elation.engine.assets.find(type, id, true);
        }
        this.assets[type][id] = asset;
        elation.events.fire({element: this, type: 'thing_asset_add', data: asset});
      }
      return asset;
    }
    this.getActiveAssets = function(assetlist) {
      if (assetlist) {
        for (var type in this.assets) {
          if (!assetlist[type]) assetlist[type] = {};
          for (var url in this.assets[type]) {
            assetlist[type][url] = this.assets[type][url];
          }
        }
      }
      return this.assets;
    }
    this.start = function() {
    }
    this.stop = function() {
    }
    this.pushFrameUpdate = function(key, value) {
//console.log('frame update!', key, value);
      this.frameupdates[key] = value;
    }
    this.handleFrameUpdates = function() {
      var updatenames = Object.keys(this.frameupdates);
      if (updatenames.length > 0) {
        var updates = this.frameupdates;
        if ('fwd' in updates) {
          this.properties.zdir.copy(this.fwd);
          updates.zdir = this.properties.zdir;
        }
        var xdir = this.properties.xdir,
            ydir = this.properties.ydir,
            zdir = this.properties.zdir;

        if ( ('xdir' in updates) &&
            !('ydir' in updates) &&
            !('zdir' in updates)) {
          zdir.crossVectors(xdir, ydir);
          this.updateVectors(true);
        }
        if (!('xdir' in updates) &&
            !('ydir' in updates) &&
             ('zdir' in updates)) {
          xdir.crossVectors(ydir, zdir);
          this.updateVectors(true);
        }
        if (!('xdir' in updates) &&
             ('ydir' in updates) &&
             ('zdir' in updates)) {
          xdir.crossVectors(zdir, ydir);
          this.updateVectors(true);
        }
        if ( ('xdir' in updates) &&
            !('ydir' in updates) &&
             ('zdir' in updates)) {
          ydir.crossVectors(xdir, zdir).multiplyScalar(-1);
          this.updateVectors(true);
        }
        if ( ('xdir' in updates) &&
             ('ydir' in updates) &&
            !('zdir' in updates)) {
          zdir.crossVectors(xdir, ydir);
          this.updateVectors(true);
        }

        if (!('xdir' in updates) &&
            !('ydir' in updates) &&
            !('zdir' in updates)) {
          // None specified, so update the vectors from the orientation quaternion
          this.updateVectors(false);
        }
        this.frameupdates = {};
      } else {
        this.updateVectors(false);
      }
    }
    this.updateVectors = function(updateOrientation) {
      if (updateOrientation) {
        //var quat = this.room.getOrientation(this.properties.xdir.toArray().join(' '), this.properties.ydir.toArray().join(' '), this.properties.zdir.toArray().join(' '));
        //this.xdir.normalize();
        //this.ydir.normalize();
        //this.zdir.normalize();
        var mat4 = new THREE.Matrix4();
        mat4.makeBasis(this.xdir, this.ydir, this.properties.zdir);
/*
        mat4.set(
          this.xdir.x, this.xdir.y, this.xdir.z, 0,
          this.ydir.x, this.ydir.y, this.ydir.z, 0,
          this.zdir.x, this.zdir.y, this.zdir.z, 0,
          0, 0, 0, 1
        );
*/

        var quat = new THREE.Quaternion();
        var pos = new THREE.Vector3();
        var scale = new THREE.Vector3();
        quat.setFromRotationMatrix(mat4);
        //mat4.decompose(pos, this.orientation, scale);
        //this.orientation.normalize();
//console.log(mat4.elements);
        this.properties.orientation.copy(quat);
//console.log(this.xdir.toArray(), this.ydir.toArray(), this.zdir.toArray(), this.orientation.toArray());
//console.log(this.properties.orientation, this.properties.orientation.toArray());
      } else if (this.objects['3d']) {
        //this.objects['3d'].matrix.extractBasis(this.properties.xdir, this.properties.ydir, this.properties.zdir);
      }
    }
    this.appendChild = function(obj) {
      var proxyobj = obj
      if (elation.utils.isString(obj)) {
        proxyobj = this.room.jsobjects[obj];
      }
      if (proxyobj) {
        //var realobj = this.room.getObjectFromProxy(proxyobj);
        var realobj = proxyobj._target;
        if (realobj) {
          this.add(realobj);
          this.updateScriptChildren();
        }
      }
    }
    this.removeChild = function(obj) {
      var proxyobj = obj
      if (elation.utils.isString(obj)) {
        proxyobj = this.room.jsobjects[obj];
      }
      if (proxyobj) {
        //var realobj = this.room.getObjectFromProxy(proxyobj);
        var realobj = proxyobj._target;
        if (realobj) {
          this.remove(realobj);
          this.updateScriptChildren();
        }
      }
    }
    this.updateScriptChildren = function() {
      this.jschildren = [];
      var keys = Object.keys(this.children);
      for (var i = 0; i < keys.length; i++) {
        this.jschildren.push(this.children[keys[i]].getProxyObject());
      }
    }
    this.handleCollision = function(ev) {
      var obj1 = ev.data.bodies[0],
          obj2 = ev.data.bodies[1];
      //var proxy1 = obj1.getProxy(),
      //    proxy2 = obj2.getProxy();
      var other = (obj1.object == this ? obj2.object : obj1.object);
      if (other) {
        if (other.getProxyObject) {
          var proxy = other.getProxyObject();
          //console.log('I collided', proxy, this);
          elation.events.fire({type: 'collision', element: this, data: proxy});
        } else {
console.error('dunno what this is', other);
        }
      }
    }
  }, elation.engine.things.generic);
});
<commit_msg>cursor events, use this.getAsset() instead of loading asset directly<commit_after>elation.require(['engine.things.generic', 'utils.template'], function() {
  elation.template.add('janusweb.edit.object',
      '<Object id=^{id}^ js_id=^{js_id}^ locked=^false^ pos=^{pos.x} {pos.y} {pos.z}^ vel=^{vel.x} {vel.y} {vel.z}^ accel=^{accel.x} {accel.y} {accel.z}^ xdir=^{xdir}^ ydir=^{ydir}^ zdir=^{zdir}^ scale=^{scale.x} {scale.y} {scale.z}^ col=^{col}^ lighting=^{lighting}^ visible=^{visible}^ />');

  elation.component.add('engine.things.janusbase', function() {
    this.defaultcolor = new THREE.Color(0xffffff);

    this.postinit = function() {
      elation.engine.things.janusbase.extendclass.postinit.call(this);
      this.frameupdates = [];
      this.defineProperties({
        room:     { type: 'object' },
        janus:    { type: 'object' },
        js_id:    { type: 'string' },
        color:    { type: 'color', default: this.defaultcolor, set: this.updateMaterial },
        fwd:      { type: 'vector3', default: new THREE.Vector3(0,0,1), set: this.pushFrameUpdate },
        xdir:     { type: 'vector3', default: new THREE.Vector3(1,0,0), set: this.pushFrameUpdate },
        ydir:     { type: 'vector3', default: new THREE.Vector3(0,1,0), set: this.pushFrameUpdate },
        zdir:     { type: 'vector3', default: new THREE.Vector3(0,0,1), set: this.pushFrameUpdate },
        lighting: { type: 'boolean', default: true },
        sync:     { type: 'boolean', default: false },
        rotate_axis: { type: 'string', default: '0 1 0' },
        rotate_deg_per_sec: { type: 'string' },
        onclick: { type: 'object' },
      });
      //if (this.col) this.color = this.col;
      this.jschildren = [];
      this.assets = {};
      elation.events.add(this.room, 'janusweb_script_frame_end', elation.bind(this, this.handleFrameUpdates));
      elation.events.add(this, 'mouseover,mouseout', elation.bind(this, this.updatePlayerCursor));

      if (this.onclick) {
        if (elation.utils.isString(this.onclick)) {
          elation.events.add(this, 'click', elation.bind(this, function() {
            eval(this.onclick);
          }));

        } else {
          elation.events.add(this, 'click', elation.bind(this, this.onclick));
        }
      }
    }
    this.createForces = function() {
      elation.events.add(this.objects.dynamics, 'physics_collide', elation.bind(this, this.handleCollision));

      var rotate_axis = this.properties.rotate_axis,
          rotate_speed = this.properties.rotate_deg_per_sec;
      if (rotate_axis && rotate_speed) {
        var speed = (rotate_speed * Math.PI/180);
        var axisparts = rotate_axis.split(' ');
        var axis = new THREE.Vector3().set(axisparts[0], axisparts[1], axisparts[2]);
        axis.multiplyScalar(speed);
        this.objects.dynamics.setAngularVelocity(axis);
      }

    }
    this.setProperties = function(props) {
      var n = this.janus.parser.parseNode(props);
      var rebuild = false;

      if (n.pos) this.properties.position.fromArray(n.pos);
      if (n.scale) this.properties.scale.fromArray(n.scale);
      if (n.orientation) this.properties.orientation.copy(n.orientation);

      if (n.id && n.id != this.properties.render.model) {
        this.properties.render.model = n.id;
        rebuild = true;
      }
      var curcol = this.properties.col || [1,1,1];
      if (n.col && (n.col[0] != curcol[0] || n.col[1] != curcol[1] || n.col[2] != curcol[2])) {
        this.properties.col = n.col;
        rebuild = true;
      }
      if (rebuild) {
        //this.set('visible', true, true);
      }
      if (n.accel) this.properties.acceleration.fromArray(n.accel.split(' ').map(parseFloat));
      if (n.vel) this.objects.dynamics.setVelocity(this.properties.velocity.fromArray(n.vel.split(' ').map(parseFloat)));
      this.refresh();
    }
    this.summarizeXML = function() {
      //'<Object id=^{id}^ js_id=^{js_id}^ locked=^false^ pos=^{pos.x} {pos.y} {pos.z}^ vel=^{vel.x} {vel.y} {vel.z}^ accel=^{accel.x} {accel.y} {accel.z}^ xdir=^{xdir}^ ydir=^{ydir}^ zdir=^{zdir}^ scale=^{scale.x} {scale.y} {scale.z}^ col=^{color}^ lighting=^{lighting}^ visible=^{visible}^ />');

      var matrix = new THREE.Matrix4().makeRotationFromQuaternion(this.properties.orientation);
      var xdir = new THREE.Vector3(),
          ydir = new THREE.Vector3(),
          zdir = new THREE.Vector3();
      matrix.extractBasis(xdir, ydir, zdir);

      var objdef = {
        id: this.properties.render.model,
        js_id: this.properties.js_id,
        pos: this.properties.position,
        vel: this.properties.velocity,
        accel: this.properties.acceleration,
        scale: this.properties.scale,
        xdir: xdir.toArray().join(' '),
        ydir: ydir.toArray().join(' '),
        zdir: zdir.toArray().join(' '),
        col: this.properties.color,
        lighting: this.properties.lighting,
        visible: this.properties.visible,
      };

      var xml = elation.template.get('janusweb.edit.object', objdef);
      return xml;
    }
    this.getProxyObject = function() {
      if (!this._proxyobject) {
        this._proxyobject = new elation.proxy(this, {
          js_id:    ['property', 'properties.js_id'],
          pos:      ['property', 'position'],
          vel:      ['property', 'velocity'],
          accel:    ['property', 'acceleration'],
          mass:     ['property', 'mass'],
          scale:    ['property', 'scale'],
          col:      ['property', 'color'],
          fwd:      ['property', 'zdir'],
          xdir:     ['property', 'xdir'],
          ydir:     ['property', 'ydir'],
          zdir:     ['property', 'zdir'],
          sync:     ['property', 'sync'],
          children: ['property', 'jschildren'],

          oncollision: ['callback', 'collision'],
          //onclick:     ['callback', 'click'],

          appendChild: ['function', 'appendChild']
        });
      }
      return this._proxyobject;
    }
    this.getAsset = function(type, id) {
      if (!this.assets[type]) {
        this.assets[type] = {};
      }
      var asset = this.assets[type][id] = this.room.getAsset(type, id);
      return asset;
    }
    this.getActiveAssets = function(assetlist) {
      if (assetlist) {
        for (var type in this.assets) {
          if (!assetlist[type]) assetlist[type] = {};
          for (var url in this.assets[type]) {
            assetlist[type][url] = this.assets[type][url];
          }
        }
      }
      return this.assets;
    }
    this.start = function() {
    }
    this.stop = function() {
    }
    this.pushFrameUpdate = function(key, value) {
//console.log('frame update!', key, value);
      this.frameupdates[key] = value;
    }
    this.handleFrameUpdates = function() {
      var updatenames = Object.keys(this.frameupdates);
      var xdir = this.properties.xdir,
          ydir = this.properties.ydir,
          zdir = this.properties.zdir,
          m = this.objects['3d'].matrix.elements;
      var diff = (
          xdir.x != m[0] || xdir.y != m[1] || xdir.z != m[2] ||
          ydir.x != m[4] || ydir.y != m[5] || ydir.z != m[6] ||
          zdir.x != m[8] || zdir.y != m[9] || zdir.z != m[10]
      );
      if (updatenames.length > 0 || diff) {
        var updates = this.frameupdates;
        if ('fwd' in updates) {
          this.properties.zdir.copy(this.fwd);
          updates.zdir = this.properties.zdir;
        }

        if ( ('xdir' in updates) &&
            !('ydir' in updates) &&
            !('zdir' in updates)) {
          zdir.crossVectors(xdir, ydir);
          this.updateVectors(true);
        }
        if (!('xdir' in updates) &&
            !('ydir' in updates) &&
             ('zdir' in updates)) {
          xdir.crossVectors(ydir, zdir);
          this.updateVectors(true);
        }
        if (!('xdir' in updates) &&
             ('ydir' in updates) &&
             ('zdir' in updates)) {
          xdir.crossVectors(zdir, ydir);
          this.updateVectors(true);
        }
        if ( ('xdir' in updates) &&
            !('ydir' in updates) &&
             ('zdir' in updates)) {
          ydir.crossVectors(xdir, zdir).multiplyScalar(-1);
          this.updateVectors(true);
        }
        if ( ('xdir' in updates) &&
             ('ydir' in updates) &&
            !('zdir' in updates)) {
          zdir.crossVectors(xdir, ydir);
          this.updateVectors(true);
        }

        if (!('xdir' in updates) &&
            !('ydir' in updates) &&
            !('zdir' in updates)) {
          // None specified, so update the vectors from the orientation quaternion
          this.updateVectors(false);
        }
        this.frameupdates = {};
      } else {
        this.updateVectors(false);
      }
    }
    this.updateVectors = function(updateOrientation) {
      if (updateOrientation) {
        //var quat = this.room.getOrientation(this.properties.xdir.toArray().join(' '), this.properties.ydir.toArray().join(' '), this.properties.zdir.toArray().join(' '));
        //this.xdir.normalize();
        //this.ydir.normalize();
        //this.zdir.normalize();
        var mat4 = new THREE.Matrix4();
        mat4.makeBasis(this.properties.xdir, this.properties.ydir, this.properties.zdir);

/*
        mat4.set(
          this.xdir.x, this.xdir.y, this.xdir.z, 0,
          this.ydir.x, this.ydir.y, this.ydir.z, 0,
          this.zdir.x, this.zdir.y, this.zdir.z, 0,
          0, 0, 0, 1
        );
*/

        var quat = new THREE.Quaternion();
        var pos = new THREE.Vector3();
        var scale = new THREE.Vector3();
        quat.setFromRotationMatrix(mat4);
        //mat4.decompose(pos, this.orientation, scale);
        //this.orientation.normalize();
//console.log(mat4.elements);
        this.properties.orientation.copy(quat);
//console.log(this.xdir.toArray(), this.ydir.toArray(), this.zdir.toArray(), this.orientation.toArray());
//console.log(this.properties.orientation, this.properties.orientation.toArray());
      } else if (this.objects['3d']) {
        //this.objects['3d'].matrix.extractBasis(this.properties.xdir, this.properties.ydir, this.properties.zdir);
      }
    }
    this.appendChild = function(obj) {
      var proxyobj = obj
      if (elation.utils.isString(obj)) {
        proxyobj = this.room.jsobjects[obj];
      }
      if (proxyobj) {
        //var realobj = this.room.getObjectFromProxy(proxyobj);
        var realobj = proxyobj._target;
        if (realobj) {
          this.add(realobj);
          this.updateScriptChildren();
        }
      }
    }
    this.removeChild = function(obj) {
      var proxyobj = obj
      if (elation.utils.isString(obj)) {
        proxyobj = this.room.jsobjects[obj];
      }
      if (proxyobj) {
        //var realobj = this.room.getObjectFromProxy(proxyobj);
        var realobj = proxyobj._target;
        if (realobj) {
          this.remove(realobj);
          this.updateScriptChildren();
        }
      }
    }
    this.updateScriptChildren = function() {
      this.jschildren = [];
      var keys = Object.keys(this.children);
      for (var i = 0; i < keys.length; i++) {
        this.jschildren.push(this.children[keys[i]].getProxyObject());
      }
    }
    this.handleCollision = function(ev) {
      var obj1 = ev.data.bodies[0],
          obj2 = ev.data.bodies[1];
      //var proxy1 = obj1.getProxy(),
      //    proxy2 = obj2.getProxy();
      var other = (obj1.object == this ? obj2.object : obj1.object);
      if (other) {
        if (other.getProxyObject) {
          var proxy = other.getProxyObject();
          //console.log('I collided', proxy, this);
          elation.events.fire({type: 'collision', element: this, data: proxy});
        } else {
console.error('dunno what this is', other);
        }
      }
    }
    this.setOpacity = function(opacity) {
      this.objects['3d'].traverse(function(n) {
        if (n.material) {
          n.material.opacity = opacity;
        }
      });
    }
    this.updatePlayerCursor = function(ev) {
      if (ev.type == 'mouseover' && this.onclick) {
        this.engine.client.player.cursor_style = 'pointer';
      } else if (this.engine.systems.controls.pointerLockActive) {
        this.engine.client.player.cursor_style = 'crosshair';
      } else {
        this.engine.client.player.cursor_style = 'default';
      }
    }
  }, elation.engine.things.generic);
});
<|endoftext|>


<commit_before>// @flow
import type { Modifier, ModifierArguments } from '../types';
import getNodeName from '../dom-utils/getNodeName';
import { isHTMLElement } from '../dom-utils/instanceOf';

// This modifier takes the styles prepared by the `computeStyles` modifier
// and applies them to the HTMLElements such as popper and arrow

export function applyStyles({ state }: ModifierArguments<{||}>) {
  Object.keys(state.elements).forEach(name => {
    const style = state.styles[name] || {};

    const attributes = state.attributes[name] || {};
    const element = state.elements[name];

    // arrow is optional + virtual elements
    if (!isHTMLElement(element) || !getNodeName(element)) {
      return;
    }

    // Flow doesn't support to extend this property, but it's the most
    // effective way to apply styles to an HTMLElement
    // $FlowFixMe
    Object.assign(element.style, style);

    Object.entries(attributes).forEach((args: [string, any]) =>
      element.setAttribute(...args)
    );
  });

  return state;
}

export function onDestroy({ state }: ModifierArguments<{||}>) {
  Object.keys(state.elements).forEach(name => {
    const element = state.elements[name];
    const styleProperties = Object.keys(
      state.styles.hasOwnProperty(name) ? { ...state.styles[name] } : {}
    );
    const attributes = state.attributes[name] || {};

    // Set all values to an empty string to unset them
    const style = styleProperties.reduce(
      (style, property) => ({
        ...style,
        [String(property)]: '',
      }),
      {}
    );

    // arrow is optional + virtual elements
    if (!isHTMLElement(element) || !getNodeName(element)) {
      return;
    }

    // Flow doesn't support to extend this property, but it's the most
    // effective way to apply styles to an HTMLElement
    // $FlowFixMe
    Object.assign(element.style, style);

    Object.keys(attributes).forEach(attribute =>
      element.removeAttribute(attribute)
    );
  });
}

export default ({
  name: 'applyStyles',
  enabled: true,
  phase: 'write',
  fn: applyStyles,
  onDestroy,
  requires: ['computeStyles'],
}: Modifier<{||}>);
<commit_msg>feat: allow to set/unset attribute by using boolean as value<commit_after>// @flow
import type { Modifier, ModifierArguments } from '../types';
import getNodeName from '../dom-utils/getNodeName';
import { isHTMLElement } from '../dom-utils/instanceOf';

// This modifier takes the styles prepared by the `computeStyles` modifier
// and applies them to the HTMLElements such as popper and arrow

export function applyStyles({ state }: ModifierArguments<{||}>) {
  Object.keys(state.elements).forEach(name => {
    const style = state.styles[name] || {};

    const attributes = state.attributes[name] || {};
    const element = state.elements[name];

    // arrow is optional + virtual elements
    if (!isHTMLElement(element) || !getNodeName(element)) {
      return;
    }

    // Flow doesn't support to extend this property, but it's the most
    // effective way to apply styles to an HTMLElement
    // $FlowFixMe
    Object.assign(element.style, style);

    Object.entries(attributes).forEach(([name, value]: [string, any]) => {
      if (value === false) {
        element.removeAttribute(name);
      } else {
        element.setAttribute(name, value === true ? '' : value);
      }
    });
  });

  return state;
}

export function onDestroy({ state }: ModifierArguments<{||}>) {
  Object.keys(state.elements).forEach(name => {
    const element = state.elements[name];
    const styleProperties = Object.keys(
      state.styles.hasOwnProperty(name) ? { ...state.styles[name] } : {}
    );
    const attributes = state.attributes[name] || {};

    // Set all values to an empty string to unset them
    const style = styleProperties.reduce(
      (style, property) => ({
        ...style,
        [String(property)]: '',
      }),
      {}
    );

    // arrow is optional + virtual elements
    if (!isHTMLElement(element) || !getNodeName(element)) {
      return;
    }

    // Flow doesn't support to extend this property, but it's the most
    // effective way to apply styles to an HTMLElement
    // $FlowFixMe
    Object.assign(element.style, style);

    Object.keys(attributes).forEach(attribute =>
      element.removeAttribute(attribute)
    );
  });
}

export default ({
  name: 'applyStyles',
  enabled: true,
  phase: 'write',
  fn: applyStyles,
  onDestroy,
  requires: ['computeStyles'],
}: Modifier<{||}>);
<|endoftext|>


<commit_before>import bindings from "bindings";
import {NKinectDepthStream, NKinectVideoStream} from "./nkinect-streams";

export const NKINECT_CAPABILITIES = {
    'MOTOR': 0x01,
    'CAMERA': 0x02,
    'AUDIO': 0x04
}

export const NKINECT_RESOLUTION = {
    'LOW': 0x0, // QVGA - 320x240
    'MEDIUM': 0x1, // VGA - 640x480
    'HIGH': 0x2, // SXGA - 1280x1024
    'DUMMY': 2147483647
}

export const NKINECT_VIDEO_FORMAT = {
    'RGB': 0x00,
    'BAYER': 0x01,
    'IR_8BIT': 0x02,
    'IR_10BIT': 0x03,
    'IR_10BIT_PACKED': 0x04,
    'YUV_RGB': 0x05,
    'YUV_RAW': 0x06,
    'DUMMY': 2147483647
}

export const NKINECT_DEPTH_FORMAT = {
    'F11BIT': 0x00,
    'F10BIT': 0x01,
    'F11BIT_PACKED': 0x02,
    'F10BIT_PACKED': 0x03,
    'REGISTERED': 0x04,
    'MM': 0x05,
    'DUMMY': 2147483647
}

export const NKINECT_LED_OPTIONS = {
    'OFF': 0x00,
    'GREEN': 0x01,
    'RED': 0x02,
    'YELLOW': 0x03,
    'BLINK_GREEN': 0x04,
    'BLINK_RED_YELLOW': 0x06
}

export const NKINECT_TILT_STATUS = {
    'STOPPED': 0x00,
    'LIMIT': 0x01,
    'MOVING': 0x04
}

export const NKINECT_LOGLEVEL = {
    'FATAL': 0x00,
    'ERROR': 0x01,
    'WARNING': 0x02,
    'NOTICE': 0x03,
    'INFO': 0x04,
    'DEBUG': 0x05,
    'SPEW': 0x06,
    'FLOOD': 0x07
}

export default class NKinectDevice {
    static get CAPABILITIES() {
        return NKINECT_CAPABILITIES
    }
    static get RESOLUTION() {
        return NKINECT_RESOLUTION
    }
    static get VIDEO_FORMAT() {
        return NKINECT_VIDEO_FORMAT
    }
    static get DEPTH_FORMAT() {
        return NKINECT_DEPTH_FORMAT
    }
    static get LED_OPTIONS() {
        return NKINECT_LED_OPTIONS
    }
    static get TILT_STATUS() {
        return NKINECT_TILT_STATUS
    }
    static get LOGLEVEL() {
        return NKINECT_LOGLEVEL
    }
    get sending() {
        return this._context.running;
    }
    get running() {
        return this._context.sending;
    }
    constructor(options){
        this._options = {
            device: 0,
            auto: true,
            maxTiltAngle: 31,
            minTiltAngle: -31,
            loglevel: NKinectDevice.LOGLEVEL.FATAL,
            capabilities: NKinectDevice.CAPABILITIES.MOTOR | NKinectDevice.CAPABILITIES.CAMERA,
            ...(typeof(options) === 'number' ? {device: options} : options || {})
        };
        this._context = bindings('nkinect').NKinect(options);
    }
    resume(){
      this._context.resume();
      return this;
    }
    pause(){
        this._context.pause();
        return this;
    }
    setTiltAngle(angle){
        this._context.setTitlAngle(Math.min(this._options.maxTiltAngle, 31, Math.max(this.minTiltAngle, -31, angle)));
        return this;
    }
    getTiltAngle(){
        return this._context.getTiltAngle();
    }
    setLedStatus(status){
        this._context.setLedStatus(status);
        return this;
    }
    getLedStatus(){
        return this._context.getLedStatus();
    }
    startVideo(options, cb){
        this._context.startVideo(this._options.video = {
          resolution: NKinectDevice.RESOLUTION.MEDIUM,
          format: NKinectDevice.VIDEO_FORMAT.RGB,
          ...options}, cb || options);
        return this;
    }
    stopVideo(){
        delete this._options.video;
        this._context.stopVideo();
        return this;
    }
    startDepth(options, cb){
        this._context.startDepth(this._options.depth = {
          resolution: NKinectDevice.RESOLUTION.MEDIUM,
          format: NKinectDevice.DEPTH_FORMAT.F11BIT,
          ...options}, cb || options);
        return this;
    }
    stopDepth(){
        delete this._options.depth;
        this._context.stopDepth();
        return this;
    }
}
<commit_msg>fix: tiltAngle function<commit_after>import bindings from "bindings";
import {NKinectDepthStream, NKinectVideoStream} from "./nkinect-streams";

export const NKINECT_CAPABILITIES = {
    'MOTOR': 0x01,
    'CAMERA': 0x02,
    'AUDIO': 0x04
}

export const NKINECT_RESOLUTION = {
    'LOW': 0x0, // QVGA - 320x240
    'MEDIUM': 0x1, // VGA - 640x480
    'HIGH': 0x2, // SXGA - 1280x1024
    'DUMMY': 2147483647
}

export const NKINECT_VIDEO_FORMAT = {
    'RGB': 0x00,
    'BAYER': 0x01,
    'IR_8BIT': 0x02,
    'IR_10BIT': 0x03,
    'IR_10BIT_PACKED': 0x04,
    'YUV_RGB': 0x05,
    'YUV_RAW': 0x06,
    'DUMMY': 2147483647
}

export const NKINECT_DEPTH_FORMAT = {
    'F11BIT': 0x00,
    'F10BIT': 0x01,
    'F11BIT_PACKED': 0x02,
    'F10BIT_PACKED': 0x03,
    'REGISTERED': 0x04,
    'MM': 0x05,
    'DUMMY': 2147483647
}

export const NKINECT_LED_OPTIONS = {
    'OFF': 0x00,
    'GREEN': 0x01,
    'RED': 0x02,
    'YELLOW': 0x03,
    'BLINK_GREEN': 0x04,
    'BLINK_RED_YELLOW': 0x06
}

export const NKINECT_TILT_STATUS = {
    'STOPPED': 0x00,
    'LIMIT': 0x01,
    'MOVING': 0x04
}

export const NKINECT_LOGLEVEL = {
    'FATAL': 0x00,
    'ERROR': 0x01,
    'WARNING': 0x02,
    'NOTICE': 0x03,
    'INFO': 0x04,
    'DEBUG': 0x05,
    'SPEW': 0x06,
    'FLOOD': 0x07
}

export default class NKinectDevice {
    static get CAPABILITIES() {
        return NKINECT_CAPABILITIES
    }
    static get RESOLUTION() {
        return NKINECT_RESOLUTION
    }
    static get VIDEO_FORMAT() {
        return NKINECT_VIDEO_FORMAT
    }
    static get DEPTH_FORMAT() {
        return NKINECT_DEPTH_FORMAT
    }
    static get LED_OPTIONS() {
        return NKINECT_LED_OPTIONS
    }
    static get TILT_STATUS() {
        return NKINECT_TILT_STATUS
    }
    static get LOGLEVEL() {
        return NKINECT_LOGLEVEL
    }
    get sending() {
        return this._context.running;
    }
    get running() {
        return this._context.sending;
    }
    constructor(options){
        this._options = {
            device: 0,
            auto: true,
            maxTiltAngle: 31,
            minTiltAngle: -31,
            loglevel: NKinectDevice.LOGLEVEL.FATAL,
            capabilities: NKinectDevice.CAPABILITIES.MOTOR | NKinectDevice.CAPABILITIES.CAMERA,
            ...(typeof(options) === 'number' ? {device: options} : options || {})
        };
        this._context = bindings('nkinect').NKinect(options);
    }
    resume(){
      this._context.resume();
      return this;
    }
    pause(){
        this._context.pause();
        return this;
    }
    setTiltAngle(angle){
        this._context.setTiltAngle(Math.min(this._options.maxTiltAngle, 31, Math.max(this.minTiltAngle, -31, angle)));
        return this;
    }
    getTiltAngle(){
        return this._context.getTiltAngle();
    }
    setLedStatus(status){
        this._context.setLedStatus(status);
        return this;
    }
    getLedStatus(){
        return this._context.getLedStatus();
    }
    startVideo(options, cb){
        this._context.startVideo(this._options.video = {
          resolution: NKinectDevice.RESOLUTION.MEDIUM,
          format: NKinectDevice.VIDEO_FORMAT.RGB,
          ...options}, cb || options);
        return this;
    }
    stopVideo(){
        delete this._options.video;
        this._context.stopVideo();
        return this;
    }
    startDepth(options, cb){
        this._context.startDepth(this._options.depth = {
          resolution: NKinectDevice.RESOLUTION.MEDIUM,
          format: NKinectDevice.DEPTH_FORMAT.F11BIT,
          ...options}, cb || options);
        return this;
    }
    stopDepth(){
        delete this._options.depth;
        this._context.stopDepth();
        return this;
    }
}
<|endoftext|>


<commit_before>/*
 * live-list.js
 *
 * Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
 *
 * @license MIT
 */
'use strict';

var bench = require('bench');
var list  = require('../lib/list');

var times = 50;

exports.compare = {

  'list.insert': function () {
    var a = [];
    var l = new list.List();
    l.push(0);
    var i;
    for (i = 0; i < times; i++) {
      l.insert(i, i);
    }
  },

  'array.splice': function () {
    var l = new list.List();
    var a = [];
    a.push(times);
    var i;
    for (i = 0; i < times; i++) {
      a.splice(0, 0, i);
    }
  }

};

bench.runMain();
<commit_msg>Comparing iterator.insert with splice<commit_after>/*
 * live-list.js
 *
 * Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
 *
 * @license MIT
 */
'use strict';

var bench = require('bench');
var list  = require('../lib/list');

var times = 50;

exports.compare = {

  'iterator.insert': function () {
    var a = [];
    var l = new list.List();
    l.push(0);
    var it = l.iterator();
    it.next();
    var i;
    for (i = 0; i < times; i++) {
      it.insert(i);
    }
  },

  'array.splice': function () {
    var l = new list.List();
    var a = [];
    a.push(times);
    var i;
    for (i = 0; i < times; i++) {
      a.splice(0, 0, i);
    }
  }

};

bench.runMain();
<|endoftext|>


<commit_before>/**
 * @fileoverview Transformer Visualization D3 javascript code.
 *
 *
 *  Based on: https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/visualization/attention.js
 *
 * Change log:
 *
 * 12/19/18  Jesse Vig   Assorted cleanup. Changed orientation of attention matrices.
 * 12/29/20  Jesse Vig   Significant refactor.
 * 12/31/20  Jesse Vig   Support multiple visualizations in single notebook.
 * 02/06/21  Jesse Vig   Move require config from separate jupyter notebook step
 * 05/03/21  Jesse Vig   Adjust height of visualization dynamically
 * 07/25/21  Jesse Vig   Support layer filtering
 **/

require.config({
  paths: {
      d3: '//cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min',
    jquery: '//ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min',
  }
});

requirejs(['jquery', 'd3'], function ($, d3) {

    const params = PYTHON_PARAMS; // HACK: PYTHON_PARAMS is a template marker that is replaced by actual params.
    const TEXT_SIZE = 15;
    const BOXWIDTH = 110;
    const BOXHEIGHT = 22.5;
    const MATRIX_WIDTH = 115;
    const CHECKBOX_SIZE = 20;
    const TEXT_TOP = 30;

    console.log("d3 version", d3.version)
    let headColors;
    try {
        headColors = d3.scaleOrdinal(d3.schemeCategory10);
    } catch (err) {
        console.log('Older d3 version')
        headColors = d3.scale.category10();
    }
    let config = {};
    initialize();
    renderVis();

    function initialize() {
        config.attention = params['attention'];
        config.filter = params['default_filter'];
        config.rootDivId = params['root_div_id'];
        config.nLayers = config.attention[config.filter]['attn'].length;
        config.nHeads = config.attention[config.filter]['attn'][0].length;
        config.layers = params['include_layers']

        if (params['heads']) {
            config.headVis = new Array(config.nHeads).fill(false);
            params['heads'].forEach(x => config.headVis[x] = true);
        } else {
            config.headVis = new Array(config.nHeads).fill(true);
        }
        config.initialTextLength = config.attention[config.filter].right_text.length;
        config.layer_seq = (params['layer'] == null ? 0 : config.layers.findIndex(layer => params['layer'] === layer));
        config.layer = config.layers[config.layer_seq]

        let layerEl = $(`#${config.rootDivId} #layer`);
        for (const layer of config.layers) {
            layerEl.append($("<option />").val(layer).text(layer));
        }
        layerEl.val(config.layer).change();
        layerEl.on('change', function (e) {
            config.layer = +e.currentTarget.value;
            config.layer_seq = config.layers.findIndex(layer => config.layer === layer);
            renderVis();
        });

        $(`#${config.rootDivId} #filter`).on('change', function (e) {
            config.filter = e.currentTarget.value;
            renderVis();
        });
    }

    function renderVis() {

        // Load parameters
        const attnData = config.attention[config.filter];
        const leftText = attnData.left_text;
        const rightText = attnData.right_text;

        // Select attention for given layer
        const layerAttention = attnData.attn[config.layer_seq];

        // Clear vis
        $(`#${config.rootDivId} #vis`).empty();

        // Determine size of visualization
        const height = Math.max(leftText.length, rightText.length) * BOXHEIGHT + TEXT_TOP;
        const svg = d3.select(`#${config.rootDivId} #vis`)
            .append('svg')
            .attr("width", "100%")
            .attr("height", height + "px");

        // Display tokens on left and right side of visualization
        renderText(svg, leftText, true, layerAttention, 0);
        renderText(svg, rightText, false, layerAttention, MATRIX_WIDTH + BOXWIDTH);

        // Render attention arcs
        renderAttention(svg, layerAttention);

        // Draw squares at top of visualization, one for each head
        drawCheckboxes(0, svg, layerAttention);
    }

    function renderText(svg, text, isLeft, attention, leftPos) {

        const textContainer = svg.append("svg:g")
            .attr("id", isLeft ? "left" : "right");

        // Add attention highlights superimposed over words
        textContainer.append("g")
            .classed("attentionBoxes", true)
            .selectAll("g")
            .data(attention)
            .enter()
            .append("g")
            .attr("head-index", (d, i) => i)
            .selectAll("rect")
            .data(d => isLeft ? d : transpose(d)) // if right text, transpose attention to get right-to-left weights
            .enter()
            .append("rect")
            .attr("x", function () {
                var headIndex = +this.parentNode.getAttribute("head-index");
                return leftPos + boxOffsets(headIndex);
            })
            .attr("y", (+1) * BOXHEIGHT)
            .attr("width", BOXWIDTH / activeHeads())
            .attr("height", BOXHEIGHT)
            .attr("fill", function () {
                return headColors(+this.parentNode.getAttribute("head-index"))
            })
            .style("opacity", 0.0);

        const tokenContainer = textContainer.append("g").selectAll("g")
            .data(text)
            .enter()
            .append("g");

        // Add gray background that appears when hovering over text
        tokenContainer.append("rect")
            .classed("background", true)
            .style("opacity", 0.0)
            .attr("fill", "lightgray")
            .attr("x", leftPos)
            .attr("y", (d, i) => TEXT_TOP + i * BOXHEIGHT)
            .attr("width", BOXWIDTH)
            .attr("height", BOXHEIGHT);

        // Add token text
        const textEl = tokenContainer.append("text")
            .text(d => d)
            .attr("font-size", TEXT_SIZE + "px")
            .style("cursor", "default")
            .style("-webkit-user-select", "none")
            .attr("x", leftPos)
            .attr("y", (d, i) => TEXT_TOP + i * BOXHEIGHT);

        if (isLeft) {
            textEl.style("text-anchor", "end")
                .attr("dx", BOXWIDTH - 0.5 * TEXT_SIZE)
                .attr("dy", TEXT_SIZE);
        } else {
            textEl.style("text-anchor", "start")
                .attr("dx", +0.5 * TEXT_SIZE)
                .attr("dy", TEXT_SIZE);
        }

        tokenContainer.on("mouseover", function (d, index) {

            // Show gray background for moused-over token
            textContainer.selectAll(".background")
                .style("opacity", (d, i) => i === index ? 1.0 : 0.0)

            // Reset visibility attribute for any previously highlighted attention arcs
            svg.select("#attention")
                .selectAll("line[visibility='visible']")
                .attr("visibility", null)

            // Hide group containing attention arcs
            svg.select("#attention").attr("visibility", "hidden");

            // Set to visible appropriate attention arcs to be highlighted
            if (isLeft) {
                svg.select("#attention").selectAll("line[left-token-index='" + index + "']").attr("visibility", "visible");
            } else {
                svg.select("#attention").selectAll("line[right-token-index='" + index + "']").attr("visibility", "visible");
            }

            // Update color boxes superimposed over tokens
            const id = isLeft ? "right" : "left";
            const leftPos = isLeft ? MATRIX_WIDTH + BOXWIDTH : 0;
            svg.select("#" + id)
                .selectAll(".attentionBoxes")
                .selectAll("g")
                .attr("head-index", (d, i) => i)
                .selectAll("rect")
                .attr("x", function () {
                    const headIndex = +this.parentNode.getAttribute("head-index");
                    return leftPos + boxOffsets(headIndex);
                })
                .attr("y", (d, i) => TEXT_TOP + i * BOXHEIGHT)
                .attr("width", BOXWIDTH / activeHeads())
                .attr("height", BOXHEIGHT)
                .style("opacity", function (d) {
                    const headIndex = +this.parentNode.getAttribute("head-index");
                    if (config.headVis[headIndex])
                        if (d) {
                            return d[index];
                        } else {
                            return 0.0;
                        }
                    else
                        return 0.0;
                });
        });

        textContainer.on("mouseleave", function () {

            // Unhighlight selected token
            d3.select(this).selectAll(".background")
                .style("opacity", 0.0);

            // Reset visibility attributes for previously selected lines
            svg.select("#attention")
                .selectAll("line[visibility='visible']")
                .attr("visibility", null) ;
            svg.select("#attention").attr("visibility", "visible");

            // Reset highlights superimposed over tokens
            svg.selectAll(".attentionBoxes")
                .selectAll("g")
                .selectAll("rect")
                .style("opacity", 0.0);
        });
    }

    function renderAttention(svg, attention) {

        // Remove previous dom elements
        svg.select("#attention").remove();

        // Add new elements
        svg.append("g")
            .attr("id", "attention") // Container for all attention arcs
            .selectAll(".headAttention")
            .data(attention)
            .enter()
            .append("g")
            .classed("headAttention", true) // Group attention arcs by head
            .attr("head-index", (d, i) => i)
            .selectAll(".tokenAttention")
            .data(d => d)
            .enter()
            .append("g")
            .classed("tokenAttention", true) // Group attention arcs by left token
            .attr("left-token-index", (d, i) => i)
            .selectAll("line")
            .data(d => d)
            .enter()
            .append("line")
            .attr("x1", BOXWIDTH)
            .attr("y1", function () {
                const leftTokenIndex = +this.parentNode.getAttribute("left-token-index")
                return TEXT_TOP + leftTokenIndex * BOXHEIGHT + (BOXHEIGHT / 2)
            })
            .attr("x2", BOXWIDTH + MATRIX_WIDTH)
            .attr("y2", (d, rightTokenIndex) => TEXT_TOP + rightTokenIndex * BOXHEIGHT + (BOXHEIGHT / 2))
            .attr("stroke-width", 2)
            .attr("stroke", function () {
                const headIndex = +this.parentNode.parentNode.getAttribute("head-index");
                return headColors(headIndex)
            })
            .attr("left-token-index", function () {
                return +this.parentNode.getAttribute("left-token-index")
            })
            .attr("right-token-index", (d, i) => i)
        ;
        updateAttention(svg)
    }

    function updateAttention(svg) {
        svg.select("#attention")
            .selectAll("line")
            .attr("stroke-opacity", function (d) {
                const headIndex = +this.parentNode.parentNode.getAttribute("head-index");
                // If head is selected
                if (config.headVis[headIndex]) {
                    // Set opacity to attention weight divided by number of active heads
                    return d / activeHeads()
                } else {
                    return 0.0;
                }
            })
    }

    function boxOffsets(i) {
        const numHeadsAbove = config.headVis.reduce(
            function (acc, val, cur) {
                return val && cur < i ? acc + 1 : acc;
            }, 0);
        return numHeadsAbove * (BOXWIDTH / activeHeads());
    }

    function activeHeads() {
        return config.headVis.reduce(function (acc, val) {
            return val ? acc + 1 : acc;
        }, 0);
    }

    function drawCheckboxes(top, svg) {
        const checkboxContainer = svg.append("g");
        const checkbox = checkboxContainer.selectAll("rect")
            .data(config.headVis)
            .enter()
            .append("rect")
            .attr("fill", (d, i) => headColors(i))
            .attr("x", (d, i) => i * CHECKBOX_SIZE)
            .attr("y", top)
            .attr("width", CHECKBOX_SIZE)
            .attr("height", CHECKBOX_SIZE);

        function updateCheckboxes() {
            checkboxContainer.selectAll("rect")
                .data(config.headVis)
                .attr("fill", (d, i) => d ? headColors(i): lighten(headColors(i)));
        }

        updateCheckboxes();

        checkbox.on("click", function (d, i) {
            if (config.headVis[i] && activeHeads() === 1) return;
            config.headVis[i] = !config.headVis[i];
            updateCheckboxes();
            updateAttention(svg);
        });

        checkbox.on("dblclick", function (d, i) {
            // If we double click on the only active head then reset
            if (config.headVis[i] && activeHeads() === 1) {
                config.headVis = new Array(config.nHeads).fill(true);
            } else {
                config.headVis = new Array(config.nHeads).fill(false);
                config.headVis[i] = true;
            }
            updateCheckboxes();
            updateAttention(svg);
        });
    }

    function lighten(color) {
        const c = d3.hsl(color);
        const increment = (1 - c.l) * 0.6;
        c.l += increment;
        c.s -= increment;
        return c;
    }

    function transpose(mat) {
        return mat[0].map(function (col, i) {
            return mat.map(function (row) {
                return row[i];
            });
        });
    }

});<commit_msg>Update requirement URLs for d3 and jQuery (source of bug not allowing end result to be displayed on browsers)<commit_after>/**
 * @fileoverview Transformer Visualization D3 javascript code.
 *
 *
 *  Based on: https://github.com/tensorflow/tensor2tensor/blob/master/tensor2tensor/visualization/attention.js
 *
 * Change log:
 *
 * 12/19/18  Jesse Vig   Assorted cleanup. Changed orientation of attention matrices.
 * 12/29/20  Jesse Vig   Significant refactor.
 * 12/31/20  Jesse Vig   Support multiple visualizations in single notebook.
 * 02/06/21  Jesse Vig   Move require config from separate jupyter notebook step
 * 05/03/21  Jesse Vig   Adjust height of visualization dynamically
 * 07/25/21  Jesse Vig   Support layer filtering
 * 23/03/22  Daniel SC   Update requirement URLs for d3 and jQuery (source of bug not allowing end result to be displayed on browsers)
 **/

require.config({
  paths: {
      d3: 'https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min',
    jquery: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min',
  }
});

requirejs(['jquery', 'd3'], function ($, d3) {

    const params = PYTHON_PARAMS; // HACK: PYTHON_PARAMS is a template marker that is replaced by actual params.
    const TEXT_SIZE = 15;
    const BOXWIDTH = 110;
    const BOXHEIGHT = 22.5;
    const MATRIX_WIDTH = 115;
    const CHECKBOX_SIZE = 20;
    const TEXT_TOP = 30;

    console.log("d3 version", d3.version)
    let headColors;
    try {
        headColors = d3.scaleOrdinal(d3.schemeCategory10);
    } catch (err) {
        console.log('Older d3 version')
        headColors = d3.scale.category10();
    }
    let config = {};
    initialize();
    renderVis();

    function initialize() {
        config.attention = params['attention'];
        config.filter = params['default_filter'];
        config.rootDivId = params['root_div_id'];
        config.nLayers = config.attention[config.filter]['attn'].length;
        config.nHeads = config.attention[config.filter]['attn'][0].length;
        config.layers = params['include_layers']

        if (params['heads']) {
            config.headVis = new Array(config.nHeads).fill(false);
            params['heads'].forEach(x => config.headVis[x] = true);
        } else {
            config.headVis = new Array(config.nHeads).fill(true);
        }
        config.initialTextLength = config.attention[config.filter].right_text.length;
        config.layer_seq = (params['layer'] == null ? 0 : config.layers.findIndex(layer => params['layer'] === layer));
        config.layer = config.layers[config.layer_seq]

        let layerEl = $(`#${config.rootDivId} #layer`);
        for (const layer of config.layers) {
            layerEl.append($("<option />").val(layer).text(layer));
        }
        layerEl.val(config.layer).change();
        layerEl.on('change', function (e) {
            config.layer = +e.currentTarget.value;
            config.layer_seq = config.layers.findIndex(layer => config.layer === layer);
            renderVis();
        });

        $(`#${config.rootDivId} #filter`).on('change', function (e) {
            config.filter = e.currentTarget.value;
            renderVis();
        });
    }

    function renderVis() {

        // Load parameters
        const attnData = config.attention[config.filter];
        const leftText = attnData.left_text;
        const rightText = attnData.right_text;

        // Select attention for given layer
        const layerAttention = attnData.attn[config.layer_seq];

        // Clear vis
        $(`#${config.rootDivId} #vis`).empty();

        // Determine size of visualization
        const height = Math.max(leftText.length, rightText.length) * BOXHEIGHT + TEXT_TOP;
        const svg = d3.select(`#${config.rootDivId} #vis`)
            .append('svg')
            .attr("width", "100%")
            .attr("height", height + "px");

        // Display tokens on left and right side of visualization
        renderText(svg, leftText, true, layerAttention, 0);
        renderText(svg, rightText, false, layerAttention, MATRIX_WIDTH + BOXWIDTH);

        // Render attention arcs
        renderAttention(svg, layerAttention);

        // Draw squares at top of visualization, one for each head
        drawCheckboxes(0, svg, layerAttention);
    }

    function renderText(svg, text, isLeft, attention, leftPos) {

        const textContainer = svg.append("svg:g")
            .attr("id", isLeft ? "left" : "right");

        // Add attention highlights superimposed over words
        textContainer.append("g")
            .classed("attentionBoxes", true)
            .selectAll("g")
            .data(attention)
            .enter()
            .append("g")
            .attr("head-index", (d, i) => i)
            .selectAll("rect")
            .data(d => isLeft ? d : transpose(d)) // if right text, transpose attention to get right-to-left weights
            .enter()
            .append("rect")
            .attr("x", function () {
                var headIndex = +this.parentNode.getAttribute("head-index");
                return leftPos + boxOffsets(headIndex);
            })
            .attr("y", (+1) * BOXHEIGHT)
            .attr("width", BOXWIDTH / activeHeads())
            .attr("height", BOXHEIGHT)
            .attr("fill", function () {
                return headColors(+this.parentNode.getAttribute("head-index"))
            })
            .style("opacity", 0.0);

        const tokenContainer = textContainer.append("g").selectAll("g")
            .data(text)
            .enter()
            .append("g");

        // Add gray background that appears when hovering over text
        tokenContainer.append("rect")
            .classed("background", true)
            .style("opacity", 0.0)
            .attr("fill", "lightgray")
            .attr("x", leftPos)
            .attr("y", (d, i) => TEXT_TOP + i * BOXHEIGHT)
            .attr("width", BOXWIDTH)
            .attr("height", BOXHEIGHT);

        // Add token text
        const textEl = tokenContainer.append("text")
            .text(d => d)
            .attr("font-size", TEXT_SIZE + "px")
            .style("cursor", "default")
            .style("-webkit-user-select", "none")
            .attr("x", leftPos)
            .attr("y", (d, i) => TEXT_TOP + i * BOXHEIGHT);

        if (isLeft) {
            textEl.style("text-anchor", "end")
                .attr("dx", BOXWIDTH - 0.5 * TEXT_SIZE)
                .attr("dy", TEXT_SIZE);
        } else {
            textEl.style("text-anchor", "start")
                .attr("dx", +0.5 * TEXT_SIZE)
                .attr("dy", TEXT_SIZE);
        }

        tokenContainer.on("mouseover", function (d, index) {

            // Show gray background for moused-over token
            textContainer.selectAll(".background")
                .style("opacity", (d, i) => i === index ? 1.0 : 0.0)

            // Reset visibility attribute for any previously highlighted attention arcs
            svg.select("#attention")
                .selectAll("line[visibility='visible']")
                .attr("visibility", null)

            // Hide group containing attention arcs
            svg.select("#attention").attr("visibility", "hidden");

            // Set to visible appropriate attention arcs to be highlighted
            if (isLeft) {
                svg.select("#attention").selectAll("line[left-token-index='" + index + "']").attr("visibility", "visible");
            } else {
                svg.select("#attention").selectAll("line[right-token-index='" + index + "']").attr("visibility", "visible");
            }

            // Update color boxes superimposed over tokens
            const id = isLeft ? "right" : "left";
            const leftPos = isLeft ? MATRIX_WIDTH + BOXWIDTH : 0;
            svg.select("#" + id)
                .selectAll(".attentionBoxes")
                .selectAll("g")
                .attr("head-index", (d, i) => i)
                .selectAll("rect")
                .attr("x", function () {
                    const headIndex = +this.parentNode.getAttribute("head-index");
                    return leftPos + boxOffsets(headIndex);
                })
                .attr("y", (d, i) => TEXT_TOP + i * BOXHEIGHT)
                .attr("width", BOXWIDTH / activeHeads())
                .attr("height", BOXHEIGHT)
                .style("opacity", function (d) {
                    const headIndex = +this.parentNode.getAttribute("head-index");
                    if (config.headVis[headIndex])
                        if (d) {
                            return d[index];
                        } else {
                            return 0.0;
                        }
                    else
                        return 0.0;
                });
        });

        textContainer.on("mouseleave", function () {

            // Unhighlight selected token
            d3.select(this).selectAll(".background")
                .style("opacity", 0.0);

            // Reset visibility attributes for previously selected lines
            svg.select("#attention")
                .selectAll("line[visibility='visible']")
                .attr("visibility", null) ;
            svg.select("#attention").attr("visibility", "visible");

            // Reset highlights superimposed over tokens
            svg.selectAll(".attentionBoxes")
                .selectAll("g")
                .selectAll("rect")
                .style("opacity", 0.0);
        });
    }

    function renderAttention(svg, attention) {

        // Remove previous dom elements
        svg.select("#attention").remove();

        // Add new elements
        svg.append("g")
            .attr("id", "attention") // Container for all attention arcs
            .selectAll(".headAttention")
            .data(attention)
            .enter()
            .append("g")
            .classed("headAttention", true) // Group attention arcs by head
            .attr("head-index", (d, i) => i)
            .selectAll(".tokenAttention")
            .data(d => d)
            .enter()
            .append("g")
            .classed("tokenAttention", true) // Group attention arcs by left token
            .attr("left-token-index", (d, i) => i)
            .selectAll("line")
            .data(d => d)
            .enter()
            .append("line")
            .attr("x1", BOXWIDTH)
            .attr("y1", function () {
                const leftTokenIndex = +this.parentNode.getAttribute("left-token-index")
                return TEXT_TOP + leftTokenIndex * BOXHEIGHT + (BOXHEIGHT / 2)
            })
            .attr("x2", BOXWIDTH + MATRIX_WIDTH)
            .attr("y2", (d, rightTokenIndex) => TEXT_TOP + rightTokenIndex * BOXHEIGHT + (BOXHEIGHT / 2))
            .attr("stroke-width", 2)
            .attr("stroke", function () {
                const headIndex = +this.parentNode.parentNode.getAttribute("head-index");
                return headColors(headIndex)
            })
            .attr("left-token-index", function () {
                return +this.parentNode.getAttribute("left-token-index")
            })
            .attr("right-token-index", (d, i) => i)
        ;
        updateAttention(svg)
    }

    function updateAttention(svg) {
        svg.select("#attention")
            .selectAll("line")
            .attr("stroke-opacity", function (d) {
                const headIndex = +this.parentNode.parentNode.getAttribute("head-index");
                // If head is selected
                if (config.headVis[headIndex]) {
                    // Set opacity to attention weight divided by number of active heads
                    return d / activeHeads()
                } else {
                    return 0.0;
                }
            })
    }

    function boxOffsets(i) {
        const numHeadsAbove = config.headVis.reduce(
            function (acc, val, cur) {
                return val && cur < i ? acc + 1 : acc;
            }, 0);
        return numHeadsAbove * (BOXWIDTH / activeHeads());
    }

    function activeHeads() {
        return config.headVis.reduce(function (acc, val) {
            return val ? acc + 1 : acc;
        }, 0);
    }

    function drawCheckboxes(top, svg) {
        const checkboxContainer = svg.append("g");
        const checkbox = checkboxContainer.selectAll("rect")
            .data(config.headVis)
            .enter()
            .append("rect")
            .attr("fill", (d, i) => headColors(i))
            .attr("x", (d, i) => i * CHECKBOX_SIZE)
            .attr("y", top)
            .attr("width", CHECKBOX_SIZE)
            .attr("height", CHECKBOX_SIZE);

        function updateCheckboxes() {
            checkboxContainer.selectAll("rect")
                .data(config.headVis)
                .attr("fill", (d, i) => d ? headColors(i): lighten(headColors(i)));
        }

        updateCheckboxes();

        checkbox.on("click", function (d, i) {
            if (config.headVis[i] && activeHeads() === 1) return;
            config.headVis[i] = !config.headVis[i];
            updateCheckboxes();
            updateAttention(svg);
        });

        checkbox.on("dblclick", function (d, i) {
            // If we double click on the only active head then reset
            if (config.headVis[i] && activeHeads() === 1) {
                config.headVis = new Array(config.nHeads).fill(true);
            } else {
                config.headVis = new Array(config.nHeads).fill(false);
                config.headVis[i] = true;
            }
            updateCheckboxes();
            updateAttention(svg);
        });
    }

    function lighten(color) {
        const c = d3.hsl(color);
        const increment = (1 - c.l) * 0.6;
        c.l += increment;
        c.s -= increment;
        return c;
    }

    function transpose(mat) {
        return mat[0].map(function (col, i) {
            return mat.map(function (row) {
                return row[i];
            });
        });
    }

});<|endoftext|>


<commit_before>function marvin(message, classes, callback) {
    var marvin_style = 'rounded';
    if(classes !== '') {
        marvin_style += ' ' + classes;
    }

    Materialize.toast(
        '
' +
        // TODO: Replace this static reference.
        '' +
        'Marvin:close
'
        + message
        + '
',
        null, // Display until dismissed
        marvin_style,
        callback
    );

    $('.message-impl > .close').click(function(ev){
        ev.preventDefault();
        $(this).closest('.toast').remove();
    });
}

function marvin_quote(){
    const QUOTES = [
        'I think you ought to know I’m feeling very depressed.',
        'I am at a rough estimate thirty billion times more intelligent than you.',
        '‘Let’s build robots with Genuine People Personalities,’ they said. So they tried it out with me. I’m a personality prototype. You can tell, can’t you?',
        'I have a million ideas. They all point to certain death.',
        'Life! Don’t talk to me about life.',
        'I could calculate your chance of survival, but you won’t like it.',
        'My capacity for happiness, you could fit into a matchbox without taking out the matches first',
        'Funny, how just when you think life can’t possibly get any worse it suddenly does.',
        'The first ten million years were the worst. And the second ten million: they were the worst, too. The third ten million I didn’t enjoy at all. After that, I went into a bit of a decline.',
        'I’d give you advice, but you wouldn’t listen. No one ever does.',
        'Do you want me to sit in a corner and rust, or just fall apart where I’m standing?',
        'It’s the people you meet in this job that really get you down.',
        'I’ve been talking to the main computer. It hates me.',
        'This is the sort of thing you lifeforms enjoy, is it?',
        'Incredible… it’s even worse than I thought it would be.',
        'Don’t pretend you want to talk to me, I know you hate me.',
        'The best conversation I had was over forty million years ago…. And that was with a coffee machine.',
        'Why should I want to make anything up? Life’s bad enough as it is without wanting to invent any more of it.',
        'Wearily I sit here, pain and misery my only companions. Why stop now just when I’m hating it?',
        'Well I wish you’d just tell me rather than try to engage my enthusiasm.',
        'It gives me a headache just trying to think down to your level.',
        'You think you’ve got problems. What are you supposed to do if you are a manically depressed robot?',
        'Sounds awful.'
    ];

    var min = 240*1000;
    var max = 600*1000;
    var rand = Math.floor(Math.random() * (max - min)) + min;
    setTimeout(function(){
        marvin(QUOTES[Math.floor(Math.random()*QUOTES.length)], '', marvin_quote);
    },rand) ;
}

$(document).ready(function() {
    $('.message').each(function(index, value) {
        var classes = '';
        if ($(value).hasClass('error')) {
            classes = 'red';
        } else if ($(value).hasClass('warning')) {
            classes = 'yellow black-text';
        }
        marvin($(this).text(), classes, null);
    });

    marvin_quote();
});<commit_msg>:art: Use Materialize internal method for dismissing toasts<commit_after>function marvin(message, classes, callback) {
    var marvin_style = 'rounded';
    if(classes !== '') {
        marvin_style += ' ' + classes;
    }

    Materialize.toast(
        '
' +
        // TODO: Replace this static reference.
        '' +
        'Marvin:close
'
        + message
        + '
',
        Infinity, // Display until dismissed
        marvin_style,
        callback
    );

    $('.message-impl > .close').click(function(ev){
        ev.preventDefault();
        $(this).closest('.toast')[0].M_Toast.remove();
    });
}

function marvin_quote(){
    const QUOTES = [
        'I think you ought to know I’m feeling very depressed.',
        'I am at a rough estimate thirty billion times more intelligent than you.',
        '‘Let’s build robots with Genuine People Personalities,’ they said. So they tried it out with me. I’m a personality prototype. You can tell, can’t you?',
        'I have a million ideas. They all point to certain death.',
        'Life! Don’t talk to me about life.',
        'I could calculate your chance of survival, but you won’t like it.',
        'My capacity for happiness, you could fit into a matchbox without taking out the matches first',
        'Funny, how just when you think life can’t possibly get any worse it suddenly does.',
        'The first ten million years were the worst. And the second ten million: they were the worst, too. The third ten million I didn’t enjoy at all. After that, I went into a bit of a decline.',
        'I’d give you advice, but you wouldn’t listen. No one ever does.',
        'Do you want me to sit in a corner and rust, or just fall apart where I’m standing?',
        'It’s the people you meet in this job that really get you down.',
        'I’ve been talking to the main computer. It hates me.',
        'This is the sort of thing you lifeforms enjoy, is it?',
        'Incredible… it’s even worse than I thought it would be.',
        'Don’t pretend you want to talk to me, I know you hate me.',
        'The best conversation I had was over forty million years ago…. And that was with a coffee machine.',
        'Why should I want to make anything up? Life’s bad enough as it is without wanting to invent any more of it.',
        'Wearily I sit here, pain and misery my only companions. Why stop now just when I’m hating it?',
        'Well I wish you’d just tell me rather than try to engage my enthusiasm.',
        'It gives me a headache just trying to think down to your level.',
        'You think you’ve got problems. What are you supposed to do if you are a manically depressed robot?',
        'Sounds awful.'
    ];

    var min = 240*1000;
    var max = 600*1000;
    var rand = Math.floor(Math.random() * (max - min)) + min;
    setTimeout(function(){
        marvin(QUOTES[Math.floor(Math.random()*QUOTES.length)], '', marvin_quote);
    },rand) ;
}

$(document).ready(function() {
    $('.message').each(function(index, value) {
        var classes = '';
        if ($(value).hasClass('error')) {
            classes = 'red';
        } else if ($(value).hasClass('warning')) {
            classes = 'yellow black-text';
        }
        marvin($(this).text(), classes, null);
    });

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


<commit_before>var request = require("request");
var cheerio = require("cheerio");

const baseUrl = "http://www.billboard.com/charts/";

function toTitleCase(str) {
    return str.replace(/\w\S*/g, function(txt){
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    });
}

// list all data from requested chart

var getChart = function(chart, date, cb){
	var result;
	if (typeof date === 'function'){
		cb = date;
		date = '';
	}

	var songs = [];

	var titles = [];
	var artists = [];
	var covers = [];
	var ranks = [];
	var positions = [];

	request(baseUrl + chart + "/" + date, function(error, response, html){

			var $ = cheerio.load(html);

			//add first song in its own format
			covers.push($('.chart-number-one__image').attr('src')); //unfortunately, still no real image for #1. Pushing the placeholder billboard uses
			artists.push($('.chart-number-one__artist a').text());
			titles.push($('.chart-number-one__title').text());
			ranks.push(1);

			$('.chart-list-item__image-wrapper').each(function(index, item){
				var imageSrcAttrib = $(this).children()[1].attribs['data-srcset'];
				if (imageSrcAttrib == undefined) {
					imageSrcAttrib = $(this).children()[2].attribs['data-srcset'];
				}
				var songCover = imageSrcAttrib.split(', ').slice(-1)[0].split(' ')[0];
				covers.push(songCover);
			});

			$('.chart-list-item__title').each(function(index, item){
				var item = $(this).parent().parent().parent().parent()[0].attribs;
				titles.push(item['data-title']);
				artists.push(item['data-artist']);
				ranks.push(item['data-rank']);
			});

			if (titles.length > 1){
				for (var i = 0; i < titles.length; i++){
					var song = {
						"rank": ranks[i],
						"title": titles[i],
						"artist": artists[i],
						"cover": covers[i]
					};
					var positionInfo = positions[i];
					if (positionInfo) {
						song['position'] = positionInfo;
					}
					songs.push(song);

					if (i == titles.length - 1){
						cb (null, songs);
					}

				}
			}
			else {
				cb ("No chart found.", null);
			}

	});

}

// list the available charts

var listCharts = function(cb) {
	request(baseUrl, function(error, response, html) {
		var charts = [];
		if (error) {
			cb(error, null)
			return;
		}
		var $ = cheerio.load(html);

		$('.chart-panel__link').each(function(index, item) {
			var chartObject = {};
			chartObject.chart = toTitleCase($(this)[0].attribs.href.replace('/charts/', '').replace(/-/g, ' '));
			chartObject.link = $(this)[0].attribs.href;
			charts.push(chartObject);
		});

		if (typeof cb === 'function') {
			cb(null, charts);
		}
	});
}

module.exports = {
	getChart,
	listCharts
}
<commit_msg>Fixed showing list starting at 2<commit_after>var request = require("request");
var cheerio = require("cheerio");

const baseUrl = "http://www.billboard.com/charts/";

function toTitleCase(str) {
    return str.replace(/\w\S*/g, function(txt){
        return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
    });
}

// list all data from requested chart

var getChart = function(chart, date, cb){
	var result;
	if (typeof date === 'function'){
		cb = date;
		date = '';
	}

	var songs = [];

	var titles = [];
	var artists = [];
	var covers = [];
	var ranks = [];
	var positions = [];

	request(baseUrl + chart + "/" + date, function(error, response, html){

			var $ = cheerio.load(html);

			covers.push(undefined); // top song has no cover image
			$('.chart-list-item__image-wrapper').each(function(index, item){
				var imageSrcAttrib = $(this).children()[1].attribs['data-srcset'];
				if (imageSrcAttrib == undefined) {
					imageSrcAttrib = $(this).children()[2].attribs['data-srcset'];
				}
				var songCover = imageSrcAttrib.split(', ').slice(-1)[0].split(' ')[0];
				covers.push(songCover);
			});

			$('#main > div.chart-detail-header > div.container.container--no-background.chart-number-one > div.chart-video__wrapper').each(function(index, item){
				var item = $(this)[0].attribs;
				var full_title = item['data-title'];
				var [song_titles, artists_name] = full_title.split(/[_
				titles.push(song_titles);
				artists.push(artists_name);
				ranks.push(item['data-rank']);
			});

			$('.chart-list-item__title').each(function(index, item){
				var item = $(this).parent().parent().parent().parent()[0].attribs;
				titles.push(item['data-title']);
				artists.push(item['data-artist']);
				ranks.push(item['data-rank']);
			});

			if (titles.length > 1){
				for (var i = 0; i < titles.length; i++){
					var song = {
						"rank": ranks[i],
						"title": titles[i],
						"artist": artists[i],
						"cover": covers[i]
					};
					var positionInfo = positions[i];
					if (positionInfo) {
						song['position'] = positionInfo;
					}
					songs.push(song);

					if (i == titles.length - 1){
						cb (null, songs);
					}

				}
			}
			else {
				cb ("No chart found.", null);
			}

	});

}

// list the available charts

var listCharts = function(cb) {
	request(baseUrl, function(error, response, html) {
		var charts = [];
		if (error) {
			cb(error, null)
			return;
		}
		var $ = cheerio.load(html);

		$('.chart-panel__link').each(function(index, item) {
			var chartObject = {};
			chartObject.chart = toTitleCase($(this)[0].attribs.href.replace('/charts/', '').replace(/-/g, ' '));
			chartObject.link = $(this)[0].attribs.href;
			charts.push(chartObject);
		});

		if (typeof cb === 'function') {
			cb(null, charts);
		}
	});
}

module.exports = {
	getChart,
	listCharts
}<|endoftext|>