<commit_before>// ==UserScript==
// @name          Tempo notifier
// @namespace     http://zbic.in
// @description   UserScript periodically displaying currently tracked issue in JIRA Tempo Timesheets using HTML5 Notification API.
// @author        Zbicin (http://github.com/zbicin)
// @include       https://*.atlassian.net/*
// @downloadURL   https://raw.githubusercontent.com/zbicin/tempo-notifier/master/tempo-notifier.user.js
// @version       0.0.1
// @noframes
// ==/UserScript==

var injectedScript = function () {
    var intervalPeriod = 1000 * 60 * 10;

    function notify() {
        var summary = document.getElementById("issue-tracker-summary-id").innerText;
        var notification;

        if (summary) {
            notification = new Notification("You are currently tracking:", {
                body: summary,
                icon: 'http://www.javaaddicts.net/image/journal/article?img_id=11738&t=1435914592549'
            });
        }
        else {
            notification = new Notification("You are not tracking any issue.", {
                icon: 'http://www.javaaddicts.net/image/journal/article?img_id=11738&t=1435914592549'
            });
        }

        setTimeout(function () {
            notification.cancel();
        }, 10000);
    }

    function init() {
        if (window.Notification && !isPermissionGranted()) {
            Notification.requestPermission(function (status) {
                if (Notification.permission !== status) {
                    Notification.permission = status;
                }
            });
        }

        if (window.Notification && isPermissionGranted()) {
            var interval = window.setInterval(notify, intervalPeriod);
        }
        else if (window.Notification && Notification.permission !== "denied") {
            Notification.requestPermission(function (status) {
                if (Notification.permission !== status) {
                    Notification.permission = status;
                }

                if (status === 'granted') {
                    var interval = window.setInterval(notify, intervalPeriod);
                }
            });
        }

        notify();
    }

    function isPermissionGranted() {
        return Notification.permission === 'granted';
    }

    window.addEventListener('load', init);
};

// Inject script
var script = document.createElement('script');
script.type = 'text/javascript';
script.textContent = '(' + injectedScript.toString() + ')();';
document.body.appendChild(script);<commit_msg>embeded base64 icon, fixed autodismissing<commit_after>// ==UserScript==
// @name          Tempo notifier
// @namespace     http://zbic.in
// @description   UserScript periodically displaying currently tracked issue in JIRA Tempo Timesheets using HTML5 Notification API.
// @author        Zbicin (http://github.com/zbicin)
// @include       https://*.atlassian.net/*
// @downloadURL   https://raw.githubusercontent.com/zbicin/tempo-notifier/master/tempo-notifier.user.js
// @version       0.0.2
// @noframes
// ==/UserScript==

var injectedScript = function () {
    var intervalPeriod = 1000 * 60 * 10;
    var icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAYAAADnRuK4AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTQgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6RURGRkFFNDMyQ0MzMTFFNEIyOEZENUFCNUVGM0NEN0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6RURGRkFFNDQyQ0MzMTFFNEIyOEZENUFCNUVGM0NEN0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo1RjdERTc1QzJDQzIxMUU0QjI4RkQ1QUI1RUYzQ0Q3RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpFREZGQUU0MjJDQzMxMUU0QjI4RkQ1QUI1RUYzQ0Q3RiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PuWzsQ8AAAr2SURBVHja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';

    function notify() {
        var issueTrackerSummaryId = document.getElementById("issue-tracker-summary-id");
        var summary = issueTrackerSummaryId ? issueTrackerSummaryId.innerText : '';
        var notification;

        if (summary) {
            notification = new Notification("You are currently tracking:", {
                body: summary,
                icon: icon
            });
        }
        else {
            notification = new Notification("You are not tracking any issue.", {
                icon: icon
            });
        }

        setTimeout(function () {
            notification.close();
        }, 10000);
    }

    function init() {
        if (window.Notification && !isPermissionGranted()) {
            Notification.requestPermission(function (status) {
                if (Notification.permission !== status) {
                    Notification.permission = status;
                }
            });
        }

        if (window.Notification && isPermissionGranted()) {
            var interval = window.setInterval(notify, intervalPeriod);
        }
        else if (window.Notification && Notification.permission !== "denied") {
            Notification.requestPermission(function (status) {
                if (Notification.permission !== status) {
                    Notification.permission = status;
                }

                if (status === 'granted') {
                    var interval = window.setInterval(notify, intervalPeriod);
                }
            });
        }

        notify();
    }

    function isPermissionGranted() {
        return Notification.permission === 'granted';
    }

    window.addEventListener('load', init);
};

// Inject script
var script = document.createElement('script');
script.type = 'text/javascript';
script.textContent = '(' + injectedScript.toString() + ')();';
document.body.appendChild(script);<|endoftext|>


<commit_before>import AbstractNode from "./abstract-node"
import Context from "../context"
import {default as DocParser, DocNode} from "../doc-parser"
import * as PHPError from "../php-error"
import * as PHPType from "../php-type"

export default class Doc extends AbstractNode {
    /** @type {boolean} */
    get isDoc() {
        return this.node.isDoc
    }
    /** @type {string[]} */
    get lines() {
        return this.node.lines
    }
    /**
     *
     * @param {PHPType.Union} u
     * @param {Context} context
     * @param {Doc} doc
     */
    resolveAllDocNames(u, context, doc) {
        let types = u.types
        for(let i = 0; i < types.length; i++) {
            let m = types[i]
            if(m instanceof PHPType.AssociativeArray) {
                types = types.concat(m.memberType.types)
            } else if(m instanceof PHPType.IndexedArray) {
                types = types.concat(m.memberType.types)
            } else if(m instanceof PHPType.Simple) {
                m.typeName = this.resolveDocName(m.typeName, context, doc)
            } else if(m instanceof PHPType.Function) {
                m.argTypes.forEach(atype => types = types.concat(atype.types))
                types = types.concat(m.returnType.types)
            } else if(m instanceof PHPType.Mixed) {
                // Do nothing
            } else {
                throw new Error(`Don't know how to resolve doc names in type ${m}`)
            }
        }
    }
    /**
     * @param {string} t
     * @param {Context} context
     * @param {Doc} doc
     * @returns {string}
     */
    resolveDocName(t, context, doc) {
        try {
            if(t.match(/^[A-Z0-9]/)) {
                return (
                    context.fileContext.resolveAliasName(t) ||
                    "\\" + t
                )
            } else if(PHPType.Core.types.hasOwnProperty(t)) {
                return context.resolveName(PHPType.Core.types[t].toString())
            } else {
                return context.resolveName(t, "uqn")
            }
        } catch(e) {
            if(e instanceof PHPType.WrongType) {
                this.throw(new PHPError.BadCoreType(e.message), context, doc.loc)
                return context.resolveName(e.realName)
            } else {
                throw e
            }
        }
    }
    /**
     * @type {DocNode[]}
     */
    get structure() {
        if(!this._structure) {
            this._structure = new DocParser(this.lines).top.children
        }
        return this._structure
    }
}
export {DocTypeNode} from "../doc-parser"<commit_msg>Properly parse class names from doc<commit_after>import AbstractNode from "./abstract-node"
import Context from "../context"
import {default as DocParser, DocNode} from "../doc-parser"
import * as PHPError from "../php-error"
import * as PHPType from "../php-type"

export default class Doc extends AbstractNode {
    /** @type {boolean} */
    get isDoc() {
        return this.node.isDoc
    }
    /** @type {string[]} */
    get lines() {
        return this.node.lines
    }
    /**
     *
     * @param {PHPType.Union} u
     * @param {Context} context
     * @param {Doc} doc
     */
    resolveAllDocNames(u, context, doc) {
        let types = u.types
        for(let i = 0; i < types.length; i++) {
            let m = types[i]
            if(m instanceof PHPType.AssociativeArray) {
                types = types.concat(m.memberType.types)
            } else if(m instanceof PHPType.IndexedArray) {
                types = types.concat(m.memberType.types)
            } else if(m instanceof PHPType.Simple) {
                m.typeName = this.resolveDocName(m.typeName, context, doc)
            } else if(m instanceof PHPType.Function) {
                m.argTypes.forEach(atype => types = types.concat(atype.types))
                types = types.concat(m.returnType.types)
            } else if(m instanceof PHPType.Mixed) {
                // Do nothing
            } else {
                throw new Error(`Don't know how to resolve doc names in type ${m}`)
            }
        }
    }
    /**
     * @param {string} t
     * @param {Context} context
     * @param {Doc} doc
     * @returns {string}
     */
    resolveDocName(t, context, doc) {
        try {
            if(t.match(/^\\/)) {
                return t
            } else if(PHPType.Core.types.hasOwnProperty(t)) {
                return context.resolveName(PHPType.Core.types[t].toString())
            } else {
                return(
                    context.fileContext.resolveAliasName(t) ||
                    context.resolveName(t, "uqn")
                )
            }
        } catch(e) {
            if(e instanceof PHPType.WrongType) {
                this.throw(new PHPError.BadCoreType(e.message), context, doc.loc)
                return context.resolveName(e.realName)
            } else {
                throw e
            }
        }
    }
    /**
     * @type {DocNode[]}
     */
    get structure() {
        if(!this._structure) {
            this._structure = new DocParser(this.lines).top.children
        }
        return this._structure
    }
}
export {DocTypeNode} from "../doc-parser"<|endoftext|>


<commit_before>/* global THREE CustomEvent */
import debounce from 'lodash.debounce';
import TransformControls from '../vendor/threejs/TransformControls.js';
import EditorControls from '../vendor/threejs/EditorControls.js';
import {getNumber} from '../utils';
var Events = require('../Events');

const gaTrackTransformEntity = debounce(transformMode => {
  ga('send', 'event', 'Viewport', 'transformEntity', transformMode);
}, 3000);

const gaTrackChangeEditorCamera = debounce(() => {
  ga('send', 'event', 'Viewport', 'changeEditorCamera');
}, 3000);

function Viewport (inspector) {
  var container = {
    dom: inspector.container
  };

  var prevActivedCameraEl = inspector.currentCameraEl;
  inspector.sceneEl.addEventListener('camera-set-active', event => {
    if (inspector.enabled) {
      // If we're in edit mode, just save the current active camera for later and activate again the editorCamera
      if (event.detail.cameraEl !== inspector.inspectorCameraEl) {
        prevActivedCameraEl = event.detail.cameraEl;
      }
      inspector.inspectorCameraEl.setAttribute('camera', 'active', 'true');
    }
  });

  // helpers
  var sceneHelpers = inspector.sceneHelpers;
  var objects = [];

  var grid = new THREE.GridHelper(30, 1);
  sceneHelpers.add(grid);

  var camera = inspector.inspectorCameraEl.getObject3D('camera');

  var selectionBox = new THREE.BoxHelper();
  selectionBox.material.depthTest = false;
  selectionBox.material.transparent = true;
  selectionBox.material.color.set(0x1faaf2);
  selectionBox.visible = false;
  sceneHelpers.add(selectionBox);

  var objectPositionOnDown = null;
  var objectRotationOnDown = null;
  var objectScaleOnDown = null;

  /**
   * Update the helpers of the object and it childrens
   * @param  {object3D} object Object to update
   */
  function updateHelpers (object) {
    for (var i = 0; i < object.children.length; i++) {
      var child = object.children[i];
      if (inspector.helpers[child.id] !== undefined) {
        inspector.helpers[child.id].update();
      }
    }
  }

  const transformControls = new THREE.TransformControls(camera, inspector.container);
  transformControls.addEventListener('change', () => {
    const object = transformControls.object;
    if (object === undefined) { return; }

    selectionBox.update(object);

    updateHelpers(object);

    const transformMode = transformControls.getMode();
    switch (transformMode) {
      case 'translate':
        object.el.setAttribute('position', {
          x: getNumber(object.position.x),
          y: getNumber(object.position.y),
          z: getNumber(object.position.z)
        });
        break;
      case 'rotate':
        object.el.setAttribute('rotation', {
          x: THREE.Math.radToDeg(getNumber(object.rotation.x)),
          y: THREE.Math.radToDeg(getNumber(object.rotation.y)),
          z: THREE.Math.radToDeg(getNumber(object.rotation.z))
        });
        break;
      case 'scale':
        object.el.setAttribute('scale', {
          x: getNumber(object.scale.x),
          y: getNumber(object.scale.y),
          z: getNumber(object.scale.z)
        });
        break;
    }
    Events.emit('refreshSidebarObject3D', object);
    gaTrackTransformEntity(transformMode);
  });

  transformControls.addEventListener('mouseDown', () => {
    var object = transformControls.object;

    objectPositionOnDown = object.position.clone();
    objectRotationOnDown = object.rotation.clone();
    objectScaleOnDown = object.scale.clone();

    controls.enabled = false;
  });

  transformControls.addEventListener('mouseUp', () => {
    var object = transformControls.object;
    if (object !== null) {
      switch (transformControls.getMode()) {
        case 'translate':

          if (!objectPositionOnDown.equals(object.position)) {
            // @todo
          }
          break;

        case 'rotate':
          if (!objectRotationOnDown.equals(object.rotation)) {
            // @todo
          }
          break;

        case 'scale':
          if (!objectScaleOnDown.equals(object.scale)) {
            // @todo
          }
          break;
      }
    }
    controls.enabled = true;
  });

  sceneHelpers.add(transformControls);
/*
  signals.objectSelected.add(function (object) {
    selectionBox.visible = false;
    if (!inspector.selected) {
      // if (!inspector.selected || inspector.selected.el.helper) {
      return;
    }

    if (object !== null) {
      if (object.geometry !== undefined &&
        object instanceof THREE.Sprite === false) {
        selectionBox.update(object);
        selectionBox.visible = true;
      }

      transformControls.attach(object);
    }
  });
*/

  Events.on('objectChanged', () => {
    if (inspector.selectedEntity.object3DMap['mesh']) {
      selectionBox.update(inspector.selected);
    }
  });

  // object picking
  var raycaster = new THREE.Raycaster();
  var mouse = new THREE.Vector2();

  // events
  function getIntersects (point, objects) {
    mouse.set((point.x * 2) - 1, -(point.y * 2) + 1);
    raycaster.setFromCamera(mouse, camera);
    return raycaster.intersectObjects(objects);
  }

  var onDownPosition = new THREE.Vector2();
  var onUpPosition = new THREE.Vector2();
  var onDoubleClickPosition = new THREE.Vector2();

  function getMousePosition (dom, x, y) {
    var rect = dom.getBoundingClientRect();
    return [ (x - rect.left) / rect.width, (y - rect.top) / rect.height ];
  }

  function handleClick () {
    if (onDownPosition.distanceTo(onUpPosition) === 0) {
      var intersects = getIntersects(onUpPosition, objects);
      if (intersects.length > 0) {
        var object = intersects[ 0 ].object;
        if (object.userData.object !== undefined) {
          // helper
          inspector.selectEntity(object.userData.object.el);
        } else {
          inspector.selectEntity(object.el);
        }
      } else {
        inspector.selectEntity(null);
      }
    }
  }

  function onMouseDown (event) {
    if (event instanceof CustomEvent) {
      return;
    }

    event.preventDefault();

    var array = getMousePosition(inspector.container, event.clientX, event.clientY);
    onDownPosition.fromArray(array);

    document.addEventListener('mouseup', onMouseUp, false);
  }

  function onMouseUp (event) {
    if (event instanceof CustomEvent) {
      return;
    }

    var array = getMousePosition(inspector.container, event.clientX, event.clientY);
    onUpPosition.fromArray(array);
    handleClick();

    document.removeEventListener('mouseup', onMouseUp, false);
  }

  function onTouchStart (event) {
    var touch = event.changedTouches[ 0 ];
    var array = getMousePosition(inspector.container, touch.clientX, touch.clientY);
    onDownPosition.fromArray(array);

    document.addEventListener('touchend', onTouchEnd, false);
  }

  function onTouchEnd (event) {
    var touch = event.changedTouches[ 0 ];
    var array = getMousePosition(inspector.container, touch.clientX, touch.clientY);
    onUpPosition.fromArray(array);
    handleClick();
    document.removeEventListener('touchend', onTouchEnd, false);
  }

  function onDoubleClick (event) {
    var array = getMousePosition(inspector.container, event.clientX, event.clientY);
    onDoubleClickPosition.fromArray(array);

    var intersects = getIntersects(onDoubleClickPosition, objects);

    if (intersects.length > 0) {
      var intersect = intersects[ 0 ];
      Events.emit('objectFocused', intersect.object);
    }
  }

  // controls need to be added *after* main logic,
  // otherwise controls.enabled doesn't work.
  var controls = new THREE.EditorControls(camera, inspector.container);

  function disableControls () {
    inspector.container.removeEventListener('mousedown', onMouseDown);
    inspector.container.removeEventListener('touchstart', onTouchStart);
    inspector.container.removeEventListener('dblclick', onDoubleClick);
    controls.enabled = false;
  }

  function enableControls () {
    inspector.container.addEventListener('mousedown', onMouseDown, false);
    inspector.container.addEventListener('touchstart', onTouchStart, false);
    inspector.container.addEventListener('dblclick', onDoubleClick, false);
    controls.enabled = true;
  }
  enableControls();

  controls.addEventListener('change', () => {
    transformControls.update();
    gaTrackChangeEditorCamera();
    // inspector.signals.cameraChanged.dispatch(camera);
  });

  Events.on('inspectorCleared', () => {
    controls.center.set(0, 0, 0);
  });

  Events.on('transformModeChanged', mode => {
    transformControls.setMode(mode);
  });

  Events.on('snapChanged', dist => {
    transformControls.setTranslationSnap(dist);
  });

  Events.on('spaceChanged', space => {
    transformControls.setSpace(space);
  });

  Events.on('objectSelected', object => {
    selectionBox.visible = false;
    transformControls.detach();
    if (object && object.el) {
      if (object.el.getObject3D('mesh')) {
        selectionBox.update(object);
        selectionBox.visible = true;
      }

      transformControls.attach(object);
    }
  });

  Events.on('objectFocused', object => {
    controls.focus(object);
    ga('send', 'event', 'Viewport', 'selectEntity');
  });

  Events.on('geometryChanged', object => {
    if (object !== null) {
      selectionBox.update(object);
    }
  });

  Events.on('objectAdded', object => {
    object.traverse(child => {
      objects.push(child);
    });
  });

  Events.on('objectChanged', object => {
    if (inspector.selected === object) {
      // Hack because object3D always has geometry :(
      if (object.geometry && object.geometry.vertices && object.geometry.vertices.length > 0) {
        selectionBox.update(object);
      }
      // transformControls.update();
    }

    transformControls.update();
    if (object instanceof THREE.PerspectiveCamera) {
      object.updateProjectionMatrix();
    }

    updateHelpers(object);
  });

  Events.on('selectedEntityComponentChanged', () => {
    Events.emit('objectChanged', inspector.selectedEntity.object3D);
  });

  Events.on('objectRemoved', object => {
    object.traverse(child => {
      objects.splice(objects.indexOf(child), 1);
    });
  });
  Events.on('helperAdded', object => {
    objects.push(object.getObjectByName('picker'));
  });
  Events.on('helperRemoved', object => {
    objects.splice(objects.indexOf(object.getObjectByName('picker')), 1);
  });
  Events.on('windowResize', () => {
    camera.aspect = container.dom.offsetWidth / container.dom.offsetHeight;
    camera.updateProjectionMatrix();
    // renderer.setSize(container.dom.offsetWidth, container.dom.offsetHeight);
  });
  Events.on('showGridChanged', showGrid => {
    grid.visible = showGrid;
  });

  Events.on('inspectorModeChanged', active => {
    if (active) {
      enableControls();
      inspector.inspectorCameraEl.setAttribute('camera', 'active', 'true');
      Array.prototype.slice.call(document.querySelectorAll('.a-enter-vr,.rs-base')).forEach(element => {
        element.style.display = 'none';
      });
    } else {
      disableControls();
      prevActivedCameraEl.setAttribute('camera', 'active', 'true');
      Array.prototype.slice.call(document.querySelectorAll('.a-enter-vr,.rs-base')).forEach(element => {
        element.style.display = 'block';
      });
    }
    ga('send', 'event', 'Viewport', 'toggleEditor', active);
  });
}

module.exports = Viewport;
<commit_msg>Fixes #318 Prevent editor camera from being hijacked when new camera is added<commit_after>/* global THREE CustomEvent */
import debounce from 'lodash.debounce';
import TransformControls from '../vendor/threejs/TransformControls.js';
import EditorControls from '../vendor/threejs/EditorControls.js';
import {getNumber} from '../utils';
var Events = require('../Events');

const gaTrackTransformEntity = debounce(transformMode => {
  ga('send', 'event', 'Viewport', 'transformEntity', transformMode);
}, 3000);

const gaTrackChangeEditorCamera = debounce(() => {
  ga('send', 'event', 'Viewport', 'changeEditorCamera');
}, 3000);

function Viewport (inspector) {
  var container = {
    dom: inspector.container
  };

  var prevActivedCameraEl = inspector.currentCameraEl;
  inspector.sceneEl.addEventListener('camera-set-active', event => {
    if (inspector.opened) {
      // If we're in edit mode, just save the current active camera for later and activate again the editorCamera
      if (event.detail.cameraEl !== inspector.inspectorCameraEl) {
        prevActivedCameraEl = event.detail.cameraEl;
      }
      inspector.inspectorCameraEl.setAttribute('camera', 'active', 'true');
    }
  });

  // helpers
  var sceneHelpers = inspector.sceneHelpers;
  var objects = [];

  var grid = new THREE.GridHelper(30, 1);
  sceneHelpers.add(grid);

  var camera = inspector.inspectorCameraEl.getObject3D('camera');

  var selectionBox = new THREE.BoxHelper();
  selectionBox.material.depthTest = false;
  selectionBox.material.transparent = true;
  selectionBox.material.color.set(0x1faaf2);
  selectionBox.visible = false;
  sceneHelpers.add(selectionBox);

  var objectPositionOnDown = null;
  var objectRotationOnDown = null;
  var objectScaleOnDown = null;

  /**
   * Update the helpers of the object and it childrens
   * @param  {object3D} object Object to update
   */
  function updateHelpers (object) {
    for (var i = 0; i < object.children.length; i++) {
      var child = object.children[i];
      if (inspector.helpers[child.id] !== undefined) {
        inspector.helpers[child.id].update();
      }
    }
  }

  const transformControls = new THREE.TransformControls(camera, inspector.container);
  transformControls.addEventListener('change', () => {
    const object = transformControls.object;
    if (object === undefined) { return; }

    selectionBox.update(object);

    updateHelpers(object);

    const transformMode = transformControls.getMode();
    switch (transformMode) {
      case 'translate':
        object.el.setAttribute('position', {
          x: getNumber(object.position.x),
          y: getNumber(object.position.y),
          z: getNumber(object.position.z)
        });
        break;
      case 'rotate':
        object.el.setAttribute('rotation', {
          x: THREE.Math.radToDeg(getNumber(object.rotation.x)),
          y: THREE.Math.radToDeg(getNumber(object.rotation.y)),
          z: THREE.Math.radToDeg(getNumber(object.rotation.z))
        });
        break;
      case 'scale':
        object.el.setAttribute('scale', {
          x: getNumber(object.scale.x),
          y: getNumber(object.scale.y),
          z: getNumber(object.scale.z)
        });
        break;
    }
    Events.emit('refreshSidebarObject3D', object);
    gaTrackTransformEntity(transformMode);
  });

  transformControls.addEventListener('mouseDown', () => {
    var object = transformControls.object;

    objectPositionOnDown = object.position.clone();
    objectRotationOnDown = object.rotation.clone();
    objectScaleOnDown = object.scale.clone();

    controls.enabled = false;
  });

  transformControls.addEventListener('mouseUp', () => {
    var object = transformControls.object;
    if (object !== null) {
      switch (transformControls.getMode()) {
        case 'translate':

          if (!objectPositionOnDown.equals(object.position)) {
            // @todo
          }
          break;

        case 'rotate':
          if (!objectRotationOnDown.equals(object.rotation)) {
            // @todo
          }
          break;

        case 'scale':
          if (!objectScaleOnDown.equals(object.scale)) {
            // @todo
          }
          break;
      }
    }
    controls.enabled = true;
  });

  sceneHelpers.add(transformControls);
/*
  signals.objectSelected.add(function (object) {
    selectionBox.visible = false;
    if (!inspector.selected) {
      // if (!inspector.selected || inspector.selected.el.helper) {
      return;
    }

    if (object !== null) {
      if (object.geometry !== undefined &&
        object instanceof THREE.Sprite === false) {
        selectionBox.update(object);
        selectionBox.visible = true;
      }

      transformControls.attach(object);
    }
  });
*/

  Events.on('objectChanged', () => {
    if (inspector.selectedEntity.object3DMap['mesh']) {
      selectionBox.update(inspector.selected);
    }
  });

  // object picking
  var raycaster = new THREE.Raycaster();
  var mouse = new THREE.Vector2();

  // events
  function getIntersects (point, objects) {
    mouse.set((point.x * 2) - 1, -(point.y * 2) + 1);
    raycaster.setFromCamera(mouse, camera);
    return raycaster.intersectObjects(objects);
  }

  var onDownPosition = new THREE.Vector2();
  var onUpPosition = new THREE.Vector2();
  var onDoubleClickPosition = new THREE.Vector2();

  function getMousePosition (dom, x, y) {
    var rect = dom.getBoundingClientRect();
    return [ (x - rect.left) / rect.width, (y - rect.top) / rect.height ];
  }

  function handleClick () {
    if (onDownPosition.distanceTo(onUpPosition) === 0) {
      var intersects = getIntersects(onUpPosition, objects);
      if (intersects.length > 0) {
        var object = intersects[ 0 ].object;
        if (object.userData.object !== undefined) {
          // helper
          inspector.selectEntity(object.userData.object.el);
        } else {
          inspector.selectEntity(object.el);
        }
      } else {
        inspector.selectEntity(null);
      }
    }
  }

  function onMouseDown (event) {
    if (event instanceof CustomEvent) {
      return;
    }

    event.preventDefault();

    var array = getMousePosition(inspector.container, event.clientX, event.clientY);
    onDownPosition.fromArray(array);

    document.addEventListener('mouseup', onMouseUp, false);
  }

  function onMouseUp (event) {
    if (event instanceof CustomEvent) {
      return;
    }

    var array = getMousePosition(inspector.container, event.clientX, event.clientY);
    onUpPosition.fromArray(array);
    handleClick();

    document.removeEventListener('mouseup', onMouseUp, false);
  }

  function onTouchStart (event) {
    var touch = event.changedTouches[ 0 ];
    var array = getMousePosition(inspector.container, touch.clientX, touch.clientY);
    onDownPosition.fromArray(array);

    document.addEventListener('touchend', onTouchEnd, false);
  }

  function onTouchEnd (event) {
    var touch = event.changedTouches[ 0 ];
    var array = getMousePosition(inspector.container, touch.clientX, touch.clientY);
    onUpPosition.fromArray(array);
    handleClick();
    document.removeEventListener('touchend', onTouchEnd, false);
  }

  function onDoubleClick (event) {
    var array = getMousePosition(inspector.container, event.clientX, event.clientY);
    onDoubleClickPosition.fromArray(array);

    var intersects = getIntersects(onDoubleClickPosition, objects);

    if (intersects.length > 0) {
      var intersect = intersects[ 0 ];
      Events.emit('objectFocused', intersect.object);
    }
  }

  // controls need to be added *after* main logic,
  // otherwise controls.enabled doesn't work.
  var controls = new THREE.EditorControls(camera, inspector.container);

  function disableControls () {
    inspector.container.removeEventListener('mousedown', onMouseDown);
    inspector.container.removeEventListener('touchstart', onTouchStart);
    inspector.container.removeEventListener('dblclick', onDoubleClick);
    controls.enabled = false;
  }

  function enableControls () {
    inspector.container.addEventListener('mousedown', onMouseDown, false);
    inspector.container.addEventListener('touchstart', onTouchStart, false);
    inspector.container.addEventListener('dblclick', onDoubleClick, false);
    controls.enabled = true;
  }
  enableControls();

  controls.addEventListener('change', () => {
    transformControls.update();
    gaTrackChangeEditorCamera();
    // inspector.signals.cameraChanged.dispatch(camera);
  });

  Events.on('inspectorCleared', () => {
    controls.center.set(0, 0, 0);
  });

  Events.on('transformModeChanged', mode => {
    transformControls.setMode(mode);
  });

  Events.on('snapChanged', dist => {
    transformControls.setTranslationSnap(dist);
  });

  Events.on('spaceChanged', space => {
    transformControls.setSpace(space);
  });

  Events.on('objectSelected', object => {
    selectionBox.visible = false;
    transformControls.detach();
    if (object && object.el) {
      if (object.el.getObject3D('mesh')) {
        selectionBox.update(object);
        selectionBox.visible = true;
      }

      transformControls.attach(object);
    }
  });

  Events.on('objectFocused', object => {
    controls.focus(object);
    ga('send', 'event', 'Viewport', 'selectEntity');
  });

  Events.on('geometryChanged', object => {
    if (object !== null) {
      selectionBox.update(object);
    }
  });

  Events.on('objectAdded', object => {
    object.traverse(child => {
      objects.push(child);
    });
  });

  Events.on('objectChanged', object => {
    if (inspector.selected === object) {
      // Hack because object3D always has geometry :(
      if (object.geometry && object.geometry.vertices && object.geometry.vertices.length > 0) {
        selectionBox.update(object);
      }
      // transformControls.update();
    }

    transformControls.update();
    if (object instanceof THREE.PerspectiveCamera) {
      object.updateProjectionMatrix();
    }

    updateHelpers(object);
  });

  Events.on('selectedEntityComponentChanged', () => {
    Events.emit('objectChanged', inspector.selectedEntity.object3D);
  });

  Events.on('objectRemoved', object => {
    object.traverse(child => {
      objects.splice(objects.indexOf(child), 1);
    });
  });
  Events.on('helperAdded', object => {
    objects.push(object.getObjectByName('picker'));
  });
  Events.on('helperRemoved', object => {
    objects.splice(objects.indexOf(object.getObjectByName('picker')), 1);
  });
  Events.on('windowResize', () => {
    camera.aspect = container.dom.offsetWidth / container.dom.offsetHeight;
    camera.updateProjectionMatrix();
    // renderer.setSize(container.dom.offsetWidth, container.dom.offsetHeight);
  });
  Events.on('showGridChanged', showGrid => {
    grid.visible = showGrid;
  });

  Events.on('inspectorModeChanged', active => {
    if (active) {
      enableControls();
      inspector.inspectorCameraEl.setAttribute('camera', 'active', 'true');
      Array.prototype.slice.call(document.querySelectorAll('.a-enter-vr,.rs-base')).forEach(element => {
        element.style.display = 'none';
      });
    } else {
      disableControls();
      prevActivedCameraEl.setAttribute('camera', 'active', 'true');
      Array.prototype.slice.call(document.querySelectorAll('.a-enter-vr,.rs-base')).forEach(element => {
        element.style.display = 'block';
      });
    }
    ga('send', 'event', 'Viewport', 'toggleEditor', active);
  });
}

module.exports = Viewport;
<|endoftext|>


<commit_before>function CentsGauge() {

  if (CentsGauge.prototype.instance) {
    console.log("An instance of CentsGauge already exists.");
    return CentsGauge.prototype.instance;
  }

  CentsGauge.prototype.instance = this;

  var fgCVS
  , bgCVS
  , fgCVS
  , fgCTX
  , peek          = defaultPeek
  , requestType   = { peek : true, spectrum : false, updateTime : true}
  , requiredCVS   = 2
  , audDiff       = 5 /* cents */
  , mxCents       = 50
  , padding       = 40
  , twoPI         = 2 * Math.PI
  , width         = 800
  , height        = 260
  , centerX       = width / 2
  , centerY       = height
  , radius        = calcRadius(width, height)
  , circumference = twoPI * radius
  , quadrantArc   = circumference / 4
  , tickWidth     = 2
  , maxTickWidth  = quadrantArc / mxCents
  , unitStep      = quadrantArc / mxCents
  , tickLength    = 16
  , markStep      = 10
  , dCents        = 0
  , totalSteps    = 30
  , animStep      = 1
  , dt            = 1 /* seconds */
  , mxSteps       = dt * totalSteps
  , baseColor     = "rgb(58,58,58)"   /* almost black */
  , bgColor       = "white"
  , tunedColor    = "rgb(122,153,66)" /* green */
  , notTunedColor = "rgb(140,46,46)"  /* red */
  , noteFontSize  = radius / 4
  , freqFontSize  = radius / 8
  , noteFontName  = "sans-serif"
  , freqFontName  = "sans-serif"
  , noteFont      = fontStringPX(noteFontSize,noteFontName)
  , freqFont      = fontStringPX(freqFontSize,freqFontName)
  , startID
  ;

  function updateGaugeParameters(w, h) {
    radius        = calcRadius(w,h);
    circumference = twoPI * radius;
    quadrantArc   = circumference / 4;
    maxTickWidth  = quadrantArc / mxCents;
    unitStep      = quadrantArc / mxCents;

    noteFontSize  = radius / 4;
    freqFontSize  = radius / 8;
    noteFont = fontStringPX(noteFontSize,noteFontName);
    freqFont = fontStringPX(freqFontSize,freqFontName);
  }

  function calcRadius(w,h) {
    var tw = w / 2 - padding
    , th = h - padding
    ;

    return tw < th ? tw : th;
  }

  function fgSetStyle() {
    fgCTX.textAlign   = "center";
    fgCTX.fillStyle   = baseColor;
    fgCTX.strokeStyle = baseColor;
    fgCTX.font        = noteFont;
  }

  function bgSetStyle() {
    bgCTX.fillStyle    = baseColor;
    bgCTX.strokeStyle  = baseColor;
    bgCTX.lineWidth    = tickWidth;
    bgCTX.textAlign    = "center";
    bgCTX.font         = "14px sans-serif";
    bgCTX.textBaseline = "bottom";
  }

  function drawTicks(from, to, color, arc) {

    /* The thick at zero is painted two times, this will affect the color. */

    var halfMark = markStep / 2
    , currentTickLength = tickLength
    , alfa
    , y0
    , y1
    , xc0
    , xc1
    , yc0
    , yc1
    , textX0
    , textX1
    , textY
    , textYC
    , textXC
    , maxRad
    , charOffset
    , unitTickLength = tickLength / 3
    , halfTickLength = tickLength / 1.5
    , sTickLength    = currentTickLength / 2
    ;

    bgCTX.beginPath();
    bgCTX.strokeStyle = color;

    while (from >= to) {

      if (from % markStep == 0) {
        currentTickLength = tickLength;
      } else if (from % halfMark == 0) {
        currentTickLength = halfTickLength;
      } else {
        currentTickLength = unitTickLength;
      }

      alfa = arc / radius;
      sTickLength = currentTickLength / 2;
      maxRad = radius + sTickLength;

      xc0 = (radius + sTickLength) * Math.cos(alfa);
      xc1 = (radius - sTickLength) * Math.cos(alfa);
      yc0 = (radius + sTickLength) * Math.sin(alfa);
      yc1 = (radius - sTickLength) * Math.sin(alfa);

      charOffset = bgCTX.measureText(from - mxCents).width / 2;

      textXC = (maxRad + charOffset) * Math.cos(alfa);
      textYC = (maxRad + charOffset) * Math.sin(alfa);

      textX0 = centerX + textXC;
      textX1 = centerX - textXC;

      textY  = centerY - textYC;

      if (from % markStep == 0) {
        if (from != 50) {
          bgCTX.fillText("+" + (-1 * (from - mxCents)), textX0, textY);
        }
        bgCTX.fillText(from - mxCents, textX1, textY);
      }

      y0 = centerY - yc0;
      y1 = centerY - yc1;

      bgCTX.moveTo(centerX - xc0, y0);
      bgCTX.lineTo(centerX - xc1, y1);

      /* Hack to draw 0 only once. */
      /* TODO fix this hack */
      if (from != 50) {
        bgCTX.moveTo(centerX + xc0, y0);
        bgCTX.lineTo(centerX + xc1, y1);
      }

      arc  -= unitStep;
      from -= 1;
    }

    bgCTX.stroke();
    return arc;
  }

  function drawBackground() {

    var arc = quadrantArc;

    bgCTX.clearRect(0,0,bgCVS.width,bgCVS.height);

    bgCTX.beginPath();
    bgCTX.arc(centerX,centerY,10,0,twoPI,false);
    bgCTX.fill();

    arc = drawTicks(mxCents, mxCents - audDiff, tunedColor, arc);
    drawTicks(mxCents - audDiff - 1,0, notTunedColor, arc);

  }

  Object.defineProperties(this, {
      "setCVS" : {
        enumerable   : true
      , configurable : false
      , set : function (cvs) {

          fgCVS         = cvs[0];
          bgCVS         = cvs[1];
          fgCTX         = fgCVS.getContext("2d");
          bgCTX         = bgCVS.getContext("2d");

          /* FOREGROUND Canvas setup & properties */
          fgCVS.id = "gtunerViewFg";

          fgCVS.width  = width;
          fgCVS.height = height;

          fgCVS.style.position = "absolute";
          fgCVS.style.zIndex   = 1;
          fgCVS.style.background = "transparent";

          /* BACKGROUND Canvas setup & properties */
          bgCVS.id = "gtunerViewBg";

          bgCVS.width  = width;
          bgCVS.height = height;

          bgCVS.style.position = "absolute";
          bgCVS.style.zIndex   = 0;
          bgCVS.style.background = bgColor;

          bgSetStyle();
          fgSetStyle();
          drawBackground();
      }
    }
    , "width" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return width;
      }
      , set : function (val) {
          width = val;

          fgCVS.width = width;
          bgCVS.width = width;

          centerX  = width / 2;

          updateGaugeParameters(width, height);

          bgSetStyle();
          fgSetStyle();

          drawBackground();
      }
    }
    , "height" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return height;
      }
      , set : function (val) {
          height = val;

          fgCVS.height = height;
          bgCVS.height = height;
          centerY      = height;

          updateGaugeParameters(width, height);

          bgSetStyle();
          fgSetStyle();

          drawBackground();
      }
    }
    , "padding" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return width;
      }
      , set : function (val) {
          padding = val;

          updateGaugeParameters(width, height);

          bgSetStyle();
          fgSetStyle();

          drawBackground();
      }
    }
    , "tickWidth" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return tickWidth;
      }
      , set : function (val) {

          if (val <= maxTickWidth) {
            tickWidth = val;
            bgCTX.lineWidth = tickWidth;
          }

          drawBackground();
      }
    }
    , "tickLength" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return tickLength;
      }
      , set : function (val) {
          tickLength = val;

          drawBackground();
      }
    }
    , "markStep" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return markStep;
      }
      , set : function (val) {
          markStep = val;

          drawBackground();
      }
    }
    , "radius" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return radius;
      }
      , set : function (r) {
          radius = r;

          circumference = twoPI * radius;
          quadrantArc   = circumference / 4;
          maxTickWidth  = quadrantArc / mxCents;
          unitStep      = quadrantArc / mxCents;

          noteFontSize  = radius / 4;
          freqFontSize  = radius / 8;
          noteFont = fontStringPX(noteFontSize,noteFontName);
          freqFont = fontStringPX(freqFontSize,freqFontName);

          drawBackground();
      }
    }
    , "peek" : {
        value        : peek
      , configurable : false
      , enumerable   : false
      , writable     : false
    }
    , "requestType" : {
        value        : requestType
      , configurable : false
      , enumerable   : true
      , writable     : false
    }
    , "requiredCVS" : {
        value        : requiredCVS
      , configurable : false
      , enumerable   : true
      , writable     : false
    }
    , "baseColor" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return baseColor;
      }
      , set : function (value) {
          baseColor = value;

          fgCTX.fillStyle   = baseColor;
          fgCTX.strokeStyle = baseColor;

          bgCTX.fillStyle   = baseColor;
          bgCTX.strokeStyle = baseColor;

          drawBackground();
      }
    }
    , "bgColor" : {
        configurable : false
      , enumerable : true
      , get : function () {
          return bgColor;
      }
      , set : function (value) {
          bgColor = value;

          bgCVS.style.background = bgColor;
      }
    }
    , "tunedColor" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return tunedColor;
      }
      , set : function (value) {
          tunedColor = value;

          drawBackground();
      }
    }
    , "notTunedColor" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return notTunedColor;
      }
      , set : function (value) {
          notTunedColor = value;

          drawBackground();
      }
    }
    , "noteFont" : {
        configurable : false
      , enumerable   : false
      , get : function () {
          return noteFont;
        }
    }
    , "freqFont" : {
        configurable : false
      , enumerable   : false
      , get : function () {
          return freqFont;
      }
    }
    , "noteFontSize" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          noteFontSize = val;
          noteFont     = fontStringPX(noteFontSize,noteFontName);
          fgCTX.font   = noteFont;
        }
      , get : function () {
          return noteFontSize;
      }
    }
    , "freqFontSize" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          freqFontSize = val;
          freqFont     = fontStringPX(freqFontSize,freqFontName);
      }
      , get : function () {
          return freqFontSize;
      }
    }
    , "noteFontName" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          noteFontName = val;
          noteFont     = fontStringPX(noteFontSize,noteFontName);
          fgCTX.font   = noteFont;
      }
      , get : function () {
          return noteFontName;
        }
    }
    , "freqFontName" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          freqFontName = val;
          freqFont = fontStringPX(freqFontSize,freqFontName);
      }
      , get : function () {
          return freqFontName;
      }
    }
    , "start" : {
        value : function() {

          var arc  = quadrantArc - (dCents * quadrantArc / mxCents)
            , alfa = arc / radius
            , x = centerX + radius * Math.cos(alfa)
            , y = centerY - radius * Math.sin(alfa)
            , noteTextWidth
            , frequencyTextWidth
            ;

          fgCTX.clearRect(0,0,width,height);

          fgCTX.fillText(peek.note.name,centerX, centerY - radius / 1.5);

          fgCTX.save();

          fgCTX.font = freqFont;
          fgCTX.fillText(peek.frequency.toFixed(2) + " Hz",centerX, centerY - radius / 2.5);

          fgCTX.restore();

          fgCTX.beginPath();
          fgCTX.moveTo(centerX,centerY);
          fgCTX.lineTo(x,y);
          fgCTX.stroke();

          if (dCents > peek.cents) {
            dCents -= animStep;

            if (dCents < peek.cents) {
              dCents = peek.cents;
            }
          } else {
            dCents += animStep;

            if (dCents > peek.cents) {
              dCents = peek.cents;
            }
          }

          startID = window.requestAnimationFrame(this.start.bind(this));
      }
      , enumerable   : false
      , configurable : false
      , writable     : false
    }
    , "update" : {
        value : function (element) {

          if(!startID){
            throw new ReferenceError("Start the view before calling update.");
          }

          if (element.peek) {

            peek = element.peek;

            var tmpAnimStep = Math.abs(dCents - Math.abs(peek.cents)) / mxSteps;

            animStep = tmpAnimStep > 1 ? tmpAnimStep : 1 ;
          }

          if (element.updateTime) {
            dt = element.updateTime;
            mxSteps = dt * totalSteps;
          }
      }
      , enumerable   : false
      , configurable : false
      , writable     : false
    }
  });

};

<commit_msg>Scale CentsGauge text with canvas size.<commit_after>function CentsGauge() {

  if (CentsGauge.prototype.instance) {
    console.log("An instance of CentsGauge already exists.");
    return CentsGauge.prototype.instance;
  }

  CentsGauge.prototype.instance = this;

  var fgCVS
  , bgCVS
  , fgCVS
  , fgCTX
  , peek          = defaultPeek
  , requestType   = { peek : true, spectrum : false, updateTime : true}
  , requiredCVS   = 2
  , audDiff       = 5 /* cents */
  , mxCents       = 50
  , padding       = 40
  , twoPI         = 2 * Math.PI
  , width         = 800
  , height        = 260
  , centerX       = width / 2
  , centerY       = height
  , radius        = calcRadius(width, height)
  , circumference = twoPI * radius
  , quadrantArc   = circumference / 4
  , tickWidth     = 2
  , maxTickWidth  = quadrantArc / mxCents
  , unitStep      = quadrantArc / mxCents
  , tickLength    = 16
  , markStep      = 10
  , dCents        = 0
  , totalSteps    = 30
  , animStep      = 1
  , dt            = 1 /* seconds */
  , mxSteps       = dt * totalSteps
  , baseColor     = "rgb(58,58,58)"   /* almost black */
  , bgColor       = "white"
  , tunedColor    = "rgb(122,153,66)" /* green */
  , notTunedColor = "rgb(140,46,46)"  /* red */
  , noteFontSize  = radius / 4
  , freqFontSize  = radius / 8
  , noteFontName  = "sans-serif"
  , freqFontName  = "sans-serif"
  , noteFont      = fontStringPX(noteFontSize,noteFontName)
  , freqFont      = fontStringPX(freqFontSize,freqFontName)
  , startID
  ;

  function updateGaugeParameters(w, h) {
    radius        = calcRadius(w,h);
    circumference = twoPI * radius;
    quadrantArc   = circumference / 4;
    maxTickWidth  = quadrantArc / mxCents;
    unitStep      = quadrantArc / mxCents;

    noteFontSize  = radius / 4;
    freqFontSize  = radius / 8;
    noteFont = fontStringPX(noteFontSize,noteFontName);
    freqFont = fontStringPX(freqFontSize,freqFontName);
  }

  function calcRadius(w,h) {
    var tw = w / 2 - padding
    , th = h - padding
    ;

    return tw < th ? tw : th;
  }

  function fgSetStyle() {
    fgCTX.textAlign   = "center";
    fgCTX.fillStyle   = baseColor;
    fgCTX.strokeStyle = baseColor;
    fgCTX.font        = noteFont;
  }

  function bgSetStyle() {
    bgCTX.fillStyle    = baseColor;
    bgCTX.strokeStyle  = baseColor;
    bgCTX.lineWidth    = tickWidth;
    bgCTX.textAlign    = "center";
    bgCTX.font         = 0.05 * Math.min(width,height) + "px sans-serif";
    bgCTX.textBaseline = "bottom";
  }

  function drawTicks(from, to, color, arc) {

    /* The thick at zero is painted two times, this will affect the color. */

    var halfMark = markStep / 2
    , currentTickLength = tickLength
    , alfa
    , y0
    , y1
    , xc0
    , xc1
    , yc0
    , yc1
    , textX0
    , textX1
    , textY
    , textYC
    , textXC
    , maxRad
    , charOffset
    , unitTickLength = tickLength / 3
    , halfTickLength = tickLength / 1.5
    , sTickLength    = currentTickLength / 2
    ;

    bgCTX.beginPath();
    bgCTX.strokeStyle = color;

    while (from >= to) {

      if (from % markStep == 0) {
        currentTickLength = tickLength;
      } else if (from % halfMark == 0) {
        currentTickLength = halfTickLength;
      } else {
        currentTickLength = unitTickLength;
      }

      alfa = arc / radius;
      sTickLength = currentTickLength / 2;
      maxRad = radius + sTickLength;

      xc0 = (radius + sTickLength) * Math.cos(alfa);
      xc1 = (radius - sTickLength) * Math.cos(alfa);
      yc0 = (radius + sTickLength) * Math.sin(alfa);
      yc1 = (radius - sTickLength) * Math.sin(alfa);

      charOffset = bgCTX.measureText(from - mxCents).width / 2;

      textXC = (maxRad + charOffset) * Math.cos(alfa);
      textYC = (maxRad + charOffset) * Math.sin(alfa);

      textX0 = centerX + textXC;
      textX1 = centerX - textXC;

      textY  = centerY - textYC;

      if (from % markStep == 0) {
        if (from != 50) {
          bgCTX.fillText("+" + (-1 * (from - mxCents)), textX0, textY);
        }
        bgCTX.fillText(from - mxCents, textX1, textY);
      }

      y0 = centerY - yc0;
      y1 = centerY - yc1;

      bgCTX.moveTo(centerX - xc0, y0);
      bgCTX.lineTo(centerX - xc1, y1);

      /* Hack to draw 0 only once. */
      /* TODO fix this hack */
      if (from != 50) {
        bgCTX.moveTo(centerX + xc0, y0);
        bgCTX.lineTo(centerX + xc1, y1);
      }

      arc  -= unitStep;
      from -= 1;
    }

    bgCTX.stroke();
    return arc;
  }

  function drawBackground() {

    var arc = quadrantArc;

    bgCTX.clearRect(0,0,bgCVS.width,bgCVS.height);

    bgCTX.beginPath();
    bgCTX.arc(centerX,centerY,10,0,twoPI,false);
    bgCTX.fill();

    arc = drawTicks(mxCents, mxCents - audDiff, tunedColor, arc);
    drawTicks(mxCents - audDiff - 1,0, notTunedColor, arc);

  }

  Object.defineProperties(this, {
      "setCVS" : {
        enumerable   : true
      , configurable : false
      , set : function (cvs) {

          fgCVS         = cvs[0];
          bgCVS         = cvs[1];
          fgCTX         = fgCVS.getContext("2d");
          bgCTX         = bgCVS.getContext("2d");

          /* FOREGROUND Canvas setup & properties */
          fgCVS.id = "gtunerViewFg";

          fgCVS.width  = width;
          fgCVS.height = height;

          fgCVS.style.position = "absolute";
          fgCVS.style.zIndex   = 1;
          fgCVS.style.background = "transparent";

          /* BACKGROUND Canvas setup & properties */
          bgCVS.id = "gtunerViewBg";

          bgCVS.width  = width;
          bgCVS.height = height;

          bgCVS.style.position = "absolute";
          bgCVS.style.zIndex   = 0;
          bgCVS.style.background = bgColor;

          bgSetStyle();
          fgSetStyle();
          drawBackground();
      }
    }
    , "width" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return width;
      }
      , set : function (val) {
          width = val;

          fgCVS.width = width;
          bgCVS.width = width;

          centerX  = width / 2;

          updateGaugeParameters(width, height);

          bgSetStyle();
          fgSetStyle();

          drawBackground();
      }
    }
    , "height" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return height;
      }
      , set : function (val) {
          height = val;

          fgCVS.height = height;
          bgCVS.height = height;
          centerY      = height;

          updateGaugeParameters(width, height);

          bgSetStyle();
          fgSetStyle();

          drawBackground();
      }
    }
    , "padding" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return width;
      }
      , set : function (val) {
          padding = val;

          updateGaugeParameters(width, height);

          bgSetStyle();
          fgSetStyle();

          drawBackground();
      }
    }
    , "tickWidth" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return tickWidth;
      }
      , set : function (val) {

          if (val <= maxTickWidth) {
            tickWidth = val;
            bgCTX.lineWidth = tickWidth;
          }

          drawBackground();
      }
    }
    , "tickLength" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return tickLength;
      }
      , set : function (val) {
          tickLength = val;

          drawBackground();
      }
    }
    , "markStep" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return markStep;
      }
      , set : function (val) {
          markStep = val;

          drawBackground();
      }
    }
    , "radius" : {
        enumerable   : true
      , configurable : false
      , get : function () {
          return radius;
      }
      , set : function (r) {
          radius = r;

          circumference = twoPI * radius;
          quadrantArc   = circumference / 4;
          maxTickWidth  = quadrantArc / mxCents;
          unitStep      = quadrantArc / mxCents;

          noteFontSize  = radius / 4;
          freqFontSize  = radius / 8;
          noteFont = fontStringPX(noteFontSize,noteFontName);
          freqFont = fontStringPX(freqFontSize,freqFontName);

          drawBackground();
      }
    }
    , "peek" : {
        value        : peek
      , configurable : false
      , enumerable   : false
      , writable     : false
    }
    , "requestType" : {
        value        : requestType
      , configurable : false
      , enumerable   : true
      , writable     : false
    }
    , "requiredCVS" : {
        value        : requiredCVS
      , configurable : false
      , enumerable   : true
      , writable     : false
    }
    , "baseColor" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return baseColor;
      }
      , set : function (value) {
          baseColor = value;

          fgCTX.fillStyle   = baseColor;
          fgCTX.strokeStyle = baseColor;

          bgCTX.fillStyle   = baseColor;
          bgCTX.strokeStyle = baseColor;

          drawBackground();
      }
    }
    , "bgColor" : {
        configurable : false
      , enumerable : true
      , get : function () {
          return bgColor;
      }
      , set : function (value) {
          bgColor = value;

          bgCVS.style.background = bgColor;
      }
    }
    , "tunedColor" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return tunedColor;
      }
      , set : function (value) {
          tunedColor = value;

          drawBackground();
      }
    }
    , "notTunedColor" : {
        configurable : false
      , enumerable   : true
      , get : function () {
          return notTunedColor;
      }
      , set : function (value) {
          notTunedColor = value;

          drawBackground();
      }
    }
    , "noteFont" : {
        configurable : false
      , enumerable   : false
      , get : function () {
          return noteFont;
        }
    }
    , "freqFont" : {
        configurable : false
      , enumerable   : false
      , get : function () {
          return freqFont;
      }
    }
    , "noteFontSize" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          noteFontSize = val;
          noteFont     = fontStringPX(noteFontSize,noteFontName);
          fgCTX.font   = noteFont;
        }
      , get : function () {
          return noteFontSize;
      }
    }
    , "freqFontSize" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          freqFontSize = val;
          freqFont     = fontStringPX(freqFontSize,freqFontName);
      }
      , get : function () {
          return freqFontSize;
      }
    }
    , "noteFontName" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          noteFontName = val;
          noteFont     = fontStringPX(noteFontSize,noteFontName);
          fgCTX.font   = noteFont;
      }
      , get : function () {
          return noteFontName;
        }
    }
    , "freqFontName" : {
        configurable : false
      , enumerable   : true
      , set : function (val) {
          freqFontName = val;
          freqFont = fontStringPX(freqFontSize,freqFontName);
      }
      , get : function () {
          return freqFontName;
      }
    }
    , "start" : {
        value : function() {

          var arc  = quadrantArc - (dCents * quadrantArc / mxCents)
            , alfa = arc / radius
            , x = centerX + radius * Math.cos(alfa)
            , y = centerY - radius * Math.sin(alfa)
            , noteTextWidth
            , frequencyTextWidth
            ;

          fgCTX.clearRect(0,0,width,height);

          fgCTX.fillText(peek.note.name,centerX, centerY - radius / 1.5);

          fgCTX.save();

          fgCTX.font = freqFont;
          fgCTX.fillText(peek.frequency.toFixed(2) + " Hz",centerX, centerY - radius / 2.5);

          fgCTX.restore();

          fgCTX.beginPath();
          fgCTX.moveTo(centerX,centerY);
          fgCTX.lineTo(x,y);
          fgCTX.stroke();

          if (dCents > peek.cents) {
            dCents -= animStep;

            if (dCents < peek.cents) {
              dCents = peek.cents;
            }
          } else {
            dCents += animStep;

            if (dCents > peek.cents) {
              dCents = peek.cents;
            }
          }

          startID = window.requestAnimationFrame(this.start.bind(this));
      }
      , enumerable   : false
      , configurable : false
      , writable     : false
    }
    , "update" : {
        value : function (element) {

          if(!startID){
            throw new ReferenceError("Start the view before calling update.");
          }

          if (element.peek) {

            peek = element.peek;

            var tmpAnimStep = Math.abs(dCents - Math.abs(peek.cents)) / mxSteps;

            animStep = tmpAnimStep > 1 ? tmpAnimStep : 1 ;
          }

          if (element.updateTime) {
            dt = element.updateTime;
            mxSteps = dt * totalSteps;
          }
      }
      , enumerable   : false
      , configurable : false
      , writable     : false
    }
  });

};

<|endoftext|>


<commit_before>define(['examples/js/viewport', 'lib/plane', 'lib/polygon'], function(Viewport, Plane, Polygon) {

    var polygonToMesh = function(polygon) {
        var geometry = new THREE.Geometry();
        var vertices = polygon.toVertices();
        var coordinates = vertices.map(function(vertex) {
            return vertex.toCoordinate();
        });

        coordinates.forEach(function(coordinate) {
            var i = geometry.vertices.push(new THREE.Vector3(coordinate.x, coordinate.y, coordinate.z));
            if (geometry.vertices[i-1].length() > 100000) {
                geometry.vertices[i-1].divideScalar(100000);
            }
        });
        if (coordinates.length === 3) {
            geometry.faces.push(new THREE.Face3(0,1,2));
        } else if (coordinates.length === 4) {
            geometry.faces.push(new THREE.Face4(0,1,2,3));
        } else {
            throw Error('not implemented');
        }
        geometry.computeFaceNormals();
        return geometry;
    }

    var addPolygon = function(viewport, polygon, color) {
        var geometry = polygonToMesh(polygon);
        var object = THREE.SceneUtils.createMultiMaterialObject(geometry, [
            new THREE.MeshLambertMaterial({color: color, side: THREE.DoubleSide, ambient: color}),
            new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
        ]);
        viewport.scene.add(object);
    }

    var Example = function() {
        var exampleContainer = document.createElement('div');
        exampleContainer.classList.add('example');
        var beforeContainer = document.createElement('div');
        var afterContainer = document.createElement('div');
        beforeContainer.classList.add('viewport');
        afterContainer.classList.add('viewport');
        document.body.appendChild(exampleContainer);
        exampleContainer.appendChild(beforeContainer);
        exampleContainer.appendChild(afterContainer);
        var beforeViewport = new Viewport(beforeContainer);
        var afterViewport  = new Viewport(afterContainer);

        var p1 = new Polygon(new Plane(0,0,1,0), [new Plane(1,0,0,-1), new Plane(0,1,0,-1), new Plane(1,1,0,10)]);
        var h = new Polygon().fromPlane(new Plane(0,1,0,0));
        var p2 = p1.splitBy(new Plane(1,0,0,0));

        addPolygon(beforeViewport, p1, 0x00ff00);
        addPolygon(beforeViewport, h, 0xff0000);

        addPolygon(afterViewport, p2, 0x0000ff);
        addPolygon(afterViewport, h, 0xff0000);
    }

    return Example;

});<commit_msg>Fix example<commit_after>define(['examples/js/viewport', 'lib/plane', 'lib/polygon'], function(Viewport, Plane, Polygon) {

    var polygonToMesh = function(polygon) {
        var geometry = new THREE.Geometry();
        var vertices = polygon.toVertices();
        var coordinates = vertices.map(function(vertex) {
            return vertex.toCoordinate();
        });

        coordinates.forEach(function(coordinate) {
            var i = geometry.vertices.push(new THREE.Vector3(coordinate.x, coordinate.y, coordinate.z));
            if (geometry.vertices[i-1].length() > 100000) {
                geometry.vertices[i-1].divideScalar(100000);
            }
        });
        if (coordinates.length === 3) {
            geometry.faces.push(new THREE.Face3(0,1,2));
        } else if (coordinates.length === 4) {
            geometry.faces.push(new THREE.Face4(0,1,2,3));
        } else {
            throw Error('not implemented');
        }
        geometry.computeFaceNormals();
        return geometry;
    }

    var addPolygon = function(viewport, polygon, color) {
        var geometry = polygonToMesh(polygon);
        var object = THREE.SceneUtils.createMultiMaterialObject(geometry, [
            new THREE.MeshLambertMaterial({color: color, side: THREE.DoubleSide, ambient: color}),
            new THREE.MeshBasicMaterial({color: 0x000000, wireframe: true})
        ]);
        viewport.scene.add(object);
    }

    var addPlane = function(viewport, plane, color) {
        var polygon = new Polygon().fromPlane(plane);
        addPolygon(viewport, polygon, color);
    }

    var Example = function() {
        var exampleContainer = document.createElement('div');
        exampleContainer.classList.add('example');
        var beforeContainer = document.createElement('div');
        var afterContainer = document.createElement('div');
        beforeContainer.classList.add('viewport');
        afterContainer.classList.add('viewport');
        document.body.appendChild(exampleContainer);
        exampleContainer.appendChild(beforeContainer);
        exampleContainer.appendChild(afterContainer);
        var beforeViewport = new Viewport(beforeContainer);
        var afterViewport  = new Viewport(afterContainer);

        var p1 = new Polygon(new Plane(0,0,1,0), [new Plane(1,0,0,-1), new Plane(0,1,0,-1), new Plane(1,1,0,5)]);
        var h = new Plane(0,100000,0,0);
        var p2 = p1.splitBy(h);

        addPolygon(beforeViewport, p1, 0x00ff00);
        addPlane(beforeViewport, h, 0xff0000);

        addPolygon(afterViewport, p2, 0x0000ff);
        addPlane(afterViewport, h, 0xff0000);
    }

    return Example;

});<|endoftext|>


<commit_before>/*
  Simple example that takes a command line provided serial port destination and routes the output to a file of the same name with .log appended to the port name.

  usage: node logger.js /dev/tty.usbserial <baudrate>

*/

var SerialPort = require("serialport");
var fs = require("fs");
var port = process.argv[2];
var baudrate = process.argv[3];
if (!port) {
  console.log("You must specify a serial port location.");
} else {
  var target = port.split("/");
  target = target[target.length-1]+".log";
  if (!baudrate) {
    baudrate = 115200;
  }
  fs.open("./"+target, 'w', function (err, fd) {
    fs.write(fd, "\n------------------------------------------------------------\nOpening SerialPort: "+target+" at "+Date.now()+"\n------------------------------------------------------------\n");
    var serialPort = new SerialPort.SerialPort(port, {
      baudrate: baudrate
    });
    serialPort.on("data", function (data) {
      fs.write(fd, data.toString());
    });
    serialPort.on("close", function (data) {
      fs.write(fd, "\n------------------------------------------------------------\nClosing SerialPort: "+target+" at "+Date.now()+"\n------------------------------------------------------------\n");
    });
  });
}

<commit_msg>Make it run regardless of if the port is present (and restart if it is present)<commit_after>/*
  Simple example that takes a command line provided serial port destination and routes the output to a file of the same name with .log appended to the port name.

  usage: node logger.js /dev/tty.usbserial <baudrate>

*/

var SerialPort = require("serialport");
var fs = require("fs");
var port = process.argv[2];
var baudrate = process.argv[3];
var active = false;

function attemptLogging(fd, port, baudrate) {
  fs.write(fd, "\n------------------------------------------------------------\nOpening SerialPort: "+target+" at "+Date.now()+"\n------------------------------------------------------------\n");
  var serialPort = new SerialPort.SerialPort(port, {
    baudrate: baudrate
  });
  serialPort.on("data", function (data) {
    fs.write(fd, data.toString());
  });
  serialPort.on("close", function (data) {
    active = false;
    fs.write(fd, "\n------------------------------------------------------------\nClosing SerialPort: "+target+" at "+Date.now()+"\n------------------------------------------------------------\n");
  });
}

if (!port) {
  console.log("You must specify a serial port location.");
} else {
  var target = port.split("/");
  target = target[target.length-1]+".log";
  if (!baudrate) {
    baudrate = 115200;
  }
  fs.open("./"+target, 'w', function (err, fd) {
    setInterval(function () {
      if (!active) {
        try {
          attemptLogging(fd, port, baudrate);
        } catch (e) {
          // Error means port is not available for listening.
          active = false;
        }
      }
    }, 1000);
  });
}

<|endoftext|>


<commit_before>var libxml = require('../index');

module.exports.blank = function(assert) {
    var doc = libxml.Document();
    assert.ok(doc);
    assert.equal('1.0', doc.version());
    assert.equal('utf8', doc.encoding());
    assert.done();
};

module.exports.version = function(assert) {
    var doc = libxml.Document('2.0');
    assert.ok(doc);
    assert.equal('2.0', doc.version());
    assert.equal('utf8', doc.encoding());
    assert.done();
};

module.exports.full = function(assert) {
    var doc = libxml.Document('2.0', 'UTF-8');
    assert.ok(doc);
    assert.equal('2.0', doc.version());
    assert.equal('UTF-8', doc.encoding());
    assert.done();
};

module.exports.null_root = function(assert) {
    var doc = libxml.Document();
    assert.equal(null, doc.root());
    assert.done();
};

module.exports.new_root = function(assert) {
    var doc = libxml.Document();
    var root = doc.node('root');
    assert.equal('root', root.name());
    assert.equal(root, doc.root());

    root.node('child').parent().node('child');
    assert.equal(doc.root().name(), doc.get('/root').name());
    assert.done();
};

module.exports.one_child = function(assert) {
    var doc = libxml.Document();
    var root = doc.node('root').node('child-one').parent().node('child-two');
    assert.equal('child-one', doc.child(1).name());
    assert.equal('child-two', doc.child(2).name());
    assert.done();
};

module.exports.root_children = function(assert) {
    var doc = libxml.Document();
    doc.node('root').node('child-one').parent().node('child-two');
    assert.equal('child-one', doc.childNodes()[0].name());
    assert.equal('child-two', doc.childNodes()[1].name());
    assert.done();
};

module.exports.xpath = function(assert) {
    var doc = libxml.Document();
    doc.node('root').node('child').parent().node('child');
    assert.equal(2, doc.find('child').length);
    assert.done();
};

module.exports.xpath_child = function(assert) {
    var doc = libxml.Document();
    doc.node('root').node('child-one').parent().node('child-two');
    assert.equal('child-one', doc.get('child-one').name());
    assert.equal('child-two', doc.get('child-two').name());
    assert.done();
};

module.exports.toString = function(assert) {
    var control = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"><grandchild from="julie numar">with love</grandchild></child><sibling>with content!</sibling></root>',
      ''
    ].join("\n");

    var doc = libxml.Document();
    var root = doc.node('root');
    root.node('child').attr({to: 'wongfoo'})
        .node('grandchild', 'with love').attr({from: 'julie numar'})
    root.node('sibling', 'with content!');
    assert.equal(control, doc.toString());
    assert.done();
};

module.exports.add_child_nodes = function(assert) {
    var gchild = '';
    var doc1_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"><grandchild from="julie numar">with love</grandchild></child><sibling>with content!</sibling></root>',
    ].join("\n");

    var doc2_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"></child><sibling>with content!</sibling></root>',
    ].join("\n");

    var doc1 = libxml.parseXmlString(doc1_string);
    var doc2 = libxml.parseXmlString(doc2_string);
    doc2.child(0).addChild(doc1.child(0).child(0));
    assert.equal(doc1.toString(), doc2.toString());
    assert.done();
};

module.exports.cloned_node = function(assert) {
    var gchild_string  = '<grandchild from="julie numar">with love</grandchild>';
    var doc1_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo">'+gchild_string+'</child><sibling>with content!</sibling></root>',
      ''
    ].join("\n");

    var doc2_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"/><sibling>with content!</sibling></root>',
      ''
    ].join("\n");

    var doc1 = libxml.parseXmlString(doc1_string);
    var doc2 = libxml.parseXmlString(doc2_string);

	var gchild = doc1.child(0).child(0); //the element to operate on

    doc2.child(0).addChild(gchild); // add gchild clone to doc2, implicit clone

    assert.equal(doc1.toString(), doc2.toString()); // both documents should be the same

    assert. notEqual(gchild, doc2.child(0).child(0)); // these nodes should be different (cloned)

    gchild.remove();

    assert.equal(doc2_string, doc1.toString()); //doc1 should be the same as doc2 str
    assert.equal(doc1_string, doc2.toString()); //doc2 should be the same as doc1 str
    assert.done();
};

module.exports.validate = function(assert) {
    var xsd = '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="comment" type="xs:string"/></xs:schema>';
    var xml_valid = '<?xml version="1.0"?><comment>A comment</comment>';
    var xml_invalid = '<?xml version="1.0"?><commentt>A comment</commentt>';

    var xsdDoc = libxml.parseXmlString(xsd);
    var xmlDocValid = libxml.parseXmlString(xml_valid);
    var xmlDocInvalid = libxml.parseXmlString(xml_invalid);

    assert.equal(xmlDocValid.validate(xsdDoc), true);
    assert.equal(xmlDocInvalid.validate(xsdDoc), false);

    assert.done();
}
<commit_msg>Small check to make sure cdata is added and represented in the string form for GH-124.<commit_after>var libxml = require('../index');

module.exports.blank = function(assert) {
    var doc = libxml.Document();
    assert.ok(doc);
    assert.equal('1.0', doc.version());
    assert.equal('utf8', doc.encoding());
    assert.done();
};

module.exports.version = function(assert) {
    var doc = libxml.Document('2.0');
    assert.ok(doc);
    assert.equal('2.0', doc.version());
    assert.equal('utf8', doc.encoding());
    assert.done();
};

module.exports.full = function(assert) {
    var doc = libxml.Document('2.0', 'UTF-8');
    assert.ok(doc);
    assert.equal('2.0', doc.version());
    assert.equal('UTF-8', doc.encoding());
    assert.done();
};

module.exports.null_root = function(assert) {
    var doc = libxml.Document();
    assert.equal(null, doc.root());
    assert.done();
};

module.exports.new_root = function(assert) {
    var doc = libxml.Document();
    var root = doc.node('root');
    assert.equal('root', root.name());
    assert.equal(root, doc.root());

    root.node('child').parent().node('child');
    assert.equal(doc.root().name(), doc.get('/root').name());
    assert.done();
};

module.exports.one_child = function(assert) {
    var doc = libxml.Document();
    var root = doc.node('root').node('child-one').parent().node('child-two');
    assert.equal('child-one', doc.child(1).name());
    assert.equal('child-two', doc.child(2).name());
    assert.done();
};

module.exports.root_children = function(assert) {
    var doc = libxml.Document();
    doc.node('root').node('child-one').parent().node('child-two');
    assert.equal('child-one', doc.childNodes()[0].name());
    assert.equal('child-two', doc.childNodes()[1].name());
    assert.done();
};

module.exports.xpath = function(assert) {
    var doc = libxml.Document();
    doc.node('root').node('child').parent().node('child');
    assert.equal(2, doc.find('child').length);
    assert.done();
};

module.exports.xpath_child = function(assert) {
    var doc = libxml.Document();
    doc.node('root').node('child-one').parent().node('child-two');
    assert.equal('child-one', doc.get('child-one').name());
    assert.equal('child-two', doc.get('child-two').name());
    assert.done();
};

module.exports.toString = function(assert) {
    var control = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"><grandchild from="julie numar">with love</grandchild></child><sibling>with content!</sibling></root>',
      ''
    ].join("\n");

    var doc = libxml.Document();
    var root = doc.node('root');
    root.node('child').attr({to: 'wongfoo'})
        .node('grandchild', 'with love').attr({from: 'julie numar'})
    root.node('sibling', 'with content!');
    assert.equal(control, doc.toString());
    assert.done();
};

module.exports.add_child_nodes = function(assert) {
    var gchild = '';
    var doc1_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"><grandchild from="julie numar">with love</grandchild></child><sibling>with content!</sibling></root>',
    ].join("\n");

    var doc2_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"></child><sibling>with content!</sibling></root>',
    ].join("\n");

    var doc1 = libxml.parseXmlString(doc1_string);
    var doc2 = libxml.parseXmlString(doc2_string);
    doc2.child(0).addChild(doc1.child(0).child(0));
    assert.equal(doc1.toString(), doc2.toString());
    assert.done();
};

module.exports.add_cdata_nodes = function(assert) {
    var gchild = '';
    var doc1_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"/></root>',
    ].join("\n");

    var expected_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"><![CDATA[
Bacon
]]></child></root>',
      '' /* Why?!? */
    ].join("\n");

    var doc1 = libxml.parseXmlString(doc1_string);
    doc1.child(0).cdata('
Bacon
');
    assert.equal(doc1.toString(), expected_string);
    assert.done();
};

module.exports.cloned_node = function(assert) {
    var gchild_string  = '<grandchild from="julie numar">with love</grandchild>';
    var doc1_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo">'+gchild_string+'</child><sibling>with content!</sibling></root>',
      ''
    ].join("\n");

    var doc2_string = [
      '<?xml version="1.0" encoding="UTF-8"?>',
      '<root><child to="wongfoo"/><sibling>with content!</sibling></root>',
      ''
    ].join("\n");

    var doc1 = libxml.parseXmlString(doc1_string);
    var doc2 = libxml.parseXmlString(doc2_string);

	var gchild = doc1.child(0).child(0); //the element to operate on

    doc2.child(0).addChild(gchild); // add gchild clone to doc2, implicit clone

    assert.equal(doc1.toString(), doc2.toString()); // both documents should be the same

    assert. notEqual(gchild, doc2.child(0).child(0)); // these nodes should be different (cloned)

    gchild.remove();

    assert.equal(doc2_string, doc1.toString()); //doc1 should be the same as doc2 str
    assert.equal(doc1_string, doc2.toString()); //doc2 should be the same as doc1 str
    assert.done();
};

module.exports.validate = function(assert) {
    var xsd = '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="comment" type="xs:string"/></xs:schema>';
    var xml_valid = '<?xml version="1.0"?><comment>A comment</comment>';
    var xml_invalid = '<?xml version="1.0"?><commentt>A comment</commentt>';

    var xsdDoc = libxml.parseXmlString(xsd);
    var xmlDocValid = libxml.parseXmlString(xml_valid);
    var xmlDocInvalid = libxml.parseXmlString(xml_invalid);

    assert.equal(xmlDocValid.validate(xsdDoc), true);
    assert.equal(xmlDocInvalid.validate(xsdDoc), false);

    assert.done();
}
<|endoftext|>


<commit_before>/*
Language: Scala
Author: Jan Berkel <jan.berkel@gmail.com>
Contributors: Erik Osheim <d_m@plastic-idolatry.com>
*/

function(hljs) {

  var ANNOTATION = {
    className: 'annotation', begin: '@[A-Za-z]+'
  };

  var STRING = {
    className: 'string',
    begin: 'u?r?"""', end: '"""',
    relevance: 10
  };

  var SYMBOL = {
    className: 'symbol',
    begin: '\'\\w[\\w\\d_]*(?!\')'
  };

  var TYPE = {
    className: 'type',
    begin: '\\b[A-Z][A-Za-z0-9_]*',
    relevance: 0
  };

  var NAME = {
    className: 'title',
    begin: /[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,
    relevance: 0
  }

  var CLASS = {
    className: 'class',
    beginKeywords: 'class object trait type',
    end: /[:={\[(\n;]/,
    contains: [{className: 'keyword', beginKeywords: 'extends with', relevance: 10}, NAME]
  };

  var METHOD = {
    className: 'function',
    beginKeywords: 'def val',
    end: /[:={\[(\n;]/,
    contains: [NAME]
  };

  var JAVADOC = {
    className: 'javadoc',
    begin: '/\\*\\*', end: '\\*/',
    contains: [{
      className: 'javadoctag',
      begin: '@[A-Za-z]+'
    }],
    relevance: 10
  };

  return {
    keywords: {
      literal: 'true false null',
      keyword: 'type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws'
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      STRING,
      hljs.QUOTE_STRING_MODE,
      SYMBOL,
      TYPE,
      METHOD,
      CLASS,
      hljs.C_NUMBER_MODE,
      ANNOTATION
    ]
  };
}
<commit_msg>Add implicit keyword to scala<commit_after>/*
Language: Scala
Author: Jan Berkel <jan.berkel@gmail.com>
Contributors: Erik Osheim <d_m@plastic-idolatry.com>
*/

function(hljs) {

  var ANNOTATION = {
    className: 'annotation', begin: '@[A-Za-z]+'
  };

  var STRING = {
    className: 'string',
    begin: 'u?r?"""', end: '"""',
    relevance: 10
  };

  var SYMBOL = {
    className: 'symbol',
    begin: '\'\\w[\\w\\d_]*(?!\')'
  };

  var TYPE = {
    className: 'type',
    begin: '\\b[A-Z][A-Za-z0-9_]*',
    relevance: 0
  };

  var NAME = {
    className: 'title',
    begin: /[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,
    relevance: 0
  }

  var CLASS = {
    className: 'class',
    beginKeywords: 'class object trait type',
    end: /[:={\[(\n;]/,
    contains: [{className: 'keyword', beginKeywords: 'extends with', relevance: 10}, NAME]
  };

  var METHOD = {
    className: 'function',
    beginKeywords: 'def val',
    end: /[:={\[(\n;]/,
    contains: [NAME]
  };

  var JAVADOC = {
    className: 'javadoc',
    begin: '/\\*\\*', end: '\\*/',
    contains: [{
      className: 'javadoctag',
      begin: '@[A-Za-z]+'
    }],
    relevance: 10
  };

  return {
    keywords: {
      literal: 'true false null',
      keyword: 'type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit'
    },
    contains: [
      hljs.C_LINE_COMMENT_MODE,
      hljs.C_BLOCK_COMMENT_MODE,
      STRING,
      hljs.QUOTE_STRING_MODE,
      SYMBOL,
      TYPE,
      METHOD,
      CLASS,
      hljs.C_NUMBER_MODE,
      ANNOTATION
    ]
  };
}
<|endoftext|>


<commit_before>var assert = require('assert');

var filename = require('../').filename;

describe('Filename normalization', function() {
    it('should normalize spaces', function() {
        assert.equal(filename('1 2 3'), '1_2_3');
    });

    it('should ignore trailing spaces', function() {
        assert.equal(filename('a b c '), 'a_b_c');
    });

    it('should remove illegal chars', function() {
        assert.equal(filename('ABC 38 ./.#$#@!/'), 'ABC_38');
    });

    it('should strip dots', function() {
        assert.equal(filename('a.b.c'), 'abc');
    });

    it('should convert to lowecase', function() {
        assert.equal(filename('AbC DeF gHi'), 'abc_def_ghi');
    });

});
<commit_msg>Fix lowercase conflict on previous test<commit_after>var assert = require('assert');

var filename = require('../').filename;

describe('Filename normalization', function() {
    it('should normalize spaces', function() {
        assert.equal(filename('1 2 3'), '1_2_3');
    });

    it('should ignore trailing spaces', function() {
        assert.equal(filename('a b c '), 'a_b_c');
    });

    it('should remove illegal chars', function() {
        assert.equal(filename('abc 38 ./.#$#@!/'), 'abc_38');
    });

    it('should strip dots', function() {
        assert.equal(filename('a.b.c'), 'abc');
    });

    it('should convert to lowecase', function() {
        assert.equal(filename('AbC DeF gHi'), 'abc_def_ghi');
    });

});
<|endoftext|>


<commit_before>var game = require('../game.js');
var chai = require('chai');

chai.should();

describe('Game', function() {
  describe('createPack', function() {
    it('has 52 cards', function() {
      var p = game.createPack();
      p.should.have.lengthOf(52);
    });
  });

  describe('shuffle', function() {
    it('should have same number of cards', function() {
      var p = game.createPack();
      var s = game.shuffle(p);
      p.should.have.lengthOf(s.length);
    });
  })

  describe('draw', function() {
    describe('one card', function() {
      it('should draw the requested number', function() {
        var pack = game.createPack();
        var cards = game.draw(pack, 1, []);
        cards.should.have.lengthOf(1);
      });

      it('should remove the card from the pack', function() {
        var pack = game.createPack();
        var initialLength = pack.length;
        var cards = game.draw(pack, 1, []);
        pack.should.have.lengthOf(initialLength - 1);
        pack.should.not.include(cards[0]);
      });

      it('should put the drawn card into the hand', function() {
        var hand = [];
        var cards = game.draw(game.createPack(), 1, hand);
        hand.should.have.lengthOf(1);
        hand.should.include(cards[0]);
      });
    });

    describe('three cards', function() {
      it('should draw the requested number', function() {
        var pack = game.createPack();
        var cards = game.draw(pack, 3, []);
        cards.should.have.lengthOf(3);
      });

      it('should remove the cards from the pack', function() {
        var pack = game.createPack();
        var initialLength = pack.length;
        var cards = game.draw(pack, 3, []);
        pack.should.have.lengthOf(initialLength - 3);
        pack.should.not.have.members(cards);
      });

      it('should put the drawn cards into the hand', function() {
        var hand = [];
        var cards = game.draw(game.createPack(), 3, hand);
        hand.should.have.lengthOf(3);
        hand.should.have.members(cards);
      });
    });

  });
});
<commit_msg>Fix shuffle test; was testing length of same array<commit_after>var game = require('../game.js');
var chai = require('chai');

chai.should();

describe('Game', function() {
  describe('createPack', function() {
    it('has 52 cards', function() {
      var p = game.createPack();
      p.should.have.lengthOf(52);
    });
  });

  describe('shuffle', function() {
    it('should have same number of cards', function() {
      var pack = game.createPack();
      var initialLength = pack.length;
      var shuffled = game.shuffle(pack);
      shuffled.should.have.lengthOf(initialLength);
    });
  })

  describe('draw', function() {
    describe('one card', function() {
      it('should draw the requested number', function() {
        var pack = game.createPack();
        var cards = game.draw(pack, 1, []);
        cards.should.have.lengthOf(1);
      });

      it('should remove the card from the pack', function() {
        var pack = game.createPack();
        var initialLength = pack.length;
        var cards = game.draw(pack, 1, []);
        pack.should.have.lengthOf(initialLength - 1);
        pack.should.not.include(cards[0]);
      });

      it('should put the drawn card into the hand', function() {
        var hand = [];
        var cards = game.draw(game.createPack(), 1, hand);
        hand.should.have.lengthOf(1);
        hand.should.include(cards[0]);
      });
    });

    describe('three cards', function() {
      it('should draw the requested number', function() {
        var pack = game.createPack();
        var cards = game.draw(pack, 3, []);
        cards.should.have.lengthOf(3);
      });

      it('should remove the cards from the pack', function() {
        var pack = game.createPack();
        var initialLength = pack.length;
        var cards = game.draw(pack, 3, []);
        pack.should.have.lengthOf(initialLength - 3);
        pack.should.not.have.members(cards);
      });

      it('should put the drawn cards into the hand', function() {
        var hand = [];
        var cards = game.draw(game.createPack(), 3, hand);
        hand.should.have.lengthOf(3);
        hand.should.have.members(cards);
      });
    });

  });
});
<|endoftext|>