<commit_before> /*unused:false*/
'use strict'; 

require.config({
  baseUrl: 'scripts',
  paths: {
    'pubsub': '../vendor/pubsub',
    'three': '../vendor/three',
    'threejs-controls/OrbitControls': '../vendor/threejs-controls/OrbitControls',
    'threejs-controls/OrbitAndPanControls': '../vendor/threejs-controls/OrbitAndPanControls',
    'underscore': '../vendor/underscore',
    'jquery': '../vendor/jquery',
    'jquery-ui': '../vendor/jquery-ui/jquery-ui',
    'csg': '../vendor/csg',
    'threeCSG': '../vendor/ThreeCSG',
    'keyboardState': '../vendor/keyboardState',
    'rStats': '../vendor/rStats',
    'rStatsExtras': '../vendor/rStatsExtras',
    'leapMotion': '../vendor/leap-0.6.4',
    'icheck': '../vendor/icheck/icheck',
    'jquery.matchHeight': '../vendor/jquery-match-height/jquery.matchHeight-min',
    'bootstrap-select': '../vendor/bootstrap-select/dist/js/bootstrap-select.min',
    'jquery.mCustomScrollbar.concat.min': '../vendor/malihu-custom-scrollbar/jquery.mCustomScrollbar.concat.min',
    'bootstrap': '../vendor/bootstrap/assets/javascripts/bootstrap',
    'jColor': '../vendor/colorpicker/spectrum'
  },
  shim: {
    'three': { exports: 'THREE' },
    'threejs-controls/OrbitControls': { deps: [ 'three' ] },
    'keyboardState': { deps: [ 'three' ] },
    'threejs-controls/OrbitAndPanControls': { deps: [ 'three' ] },
    'scg': { deps: [ 'three' ] },
    'threeCSG': { deps: [ 'three' ] },
    'rStats': { deps: [ 'three' ] }
  }
});

require([
  'pubsub', 
  'underscore', 
  'three', 
  'explorer', 
  'renderer', 
  'orbit', 
  'menu', 
  'lattice', 
  'snapshot',
  'navArrowsHud',
  'navCubeHud',
  'motifeditor',
  'unitCellExplorer',
  'motifExplorer',
  'mouseEvents',
  'navArrows',
  'navCube',
  'crystalMouseEvents',
  'storeProject',
  'restoreCWstate',
  'sound',
  'animate',
  'gearTour',
  'doll', 
  'dollExplorer',
  'keyboardKeys',
  'keyboardState',
  'fullScreen',
  'sceneResizer',
  'rStats', 
  'rStatsExtras', 
  'leapMotionHandler',
  'renderingMode',
  'tabActions'
], function(
  PubSub, 
  _, 
  THREE,
  Explorer, 
  Renderer, 
  Orbit, 
  Menu, 
  Lattice, 
  Snapshot, 
  NavArrowsHud, 
  NavCubeHud, 
  Motifeditor, 
  UnitCellExplorer, 
  MotifExplorer, 
  MouseEvents, 
  NavArrows, 
  NavCube, 
  CrystalMouseEvents, 
  StoreProject, 
  RestoreCWstate, 
  Sound, 
  Animate, 
  GearTour, 
  Doll, 
  DollExplorer, 
  KeyboardKeys, 
  KeyboardState, 
  FullScreen, 
  SceneResizer, 
  RStats, 
  RStatsExtras, 
  LeapMotionHandler,
  RenderingMode,
  TabActions
) {
  var menu = new Menu();
  
  // Scenes 
  var crystalScene = Explorer.getInstance();
  crystalScene.menu = menu;

  var unitCellScene = UnitCellExplorer.getInstance();
  var motifScene = MotifExplorer.getInstance();
 
  var height,width;

  var crystalRenderer = new Renderer(crystalScene, 'crystalRenderer', 'crystal' ); 
  crystalRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 30,30,60, 15);

  // crystal scene stats
  var glS = new glStats();
  var tS = new threeStats( crystalRenderer.renderer );

  var rS = rStats(  {
    values: {
      frame: { caption: 'Total frame time (ms)', over: 16 },
      fps: { caption: 'Framerate (FPS)', below: 30 },
      calls: { caption: 'Calls (three.js)', over: 3000 },
      raf: { caption: 'Time since last rAF (ms)' },
      rstats: { caption: 'rStats update (ms)' }
    },
    groups: [
      { caption: 'Framerate', values: [ 'fps', 'raf' ] },
      { caption: 'Frame Budget', values: [ 'frame', 'texture', 'setup', 'render' ] }
    ],
    fractions: [
      { base: 'frame', steps: [ 'texture', 'setup', 'render' ] }
    ],
    plugins: [
      tS,
      glS
    ]
  } );

  crystalRenderer.rS = rS;
  crystalRenderer.glS = glS;

  // sound & animations
  var animationMachine = new Animate(crystalScene);
  var soundMachine = new Sound(animationMachine); 
  animationMachine.soundMachine = soundMachine;
  crystalRenderer.externalFunctions.push(animationMachine.animation.bind(animationMachine));
  
  var lattice = new Lattice(menu, soundMachine);
  
  // HUD  
  var navArrowsScene = NavArrowsHud.getInstance();  
  var hudArrows = new NavArrows(navArrowsScene.object3d, lattice);
  
  var navCubeScene = NavCubeHud.getInstance();  
  var hudCube = new NavCube(navCubeScene.object3d, lattice);
 
  //  WebGL Renderers and cameras
  var displayFactor = 6 ; // changes how big or small will be the Hud 
  crystalRenderer.initHud(navArrowsScene.object3d, navCubeScene.object3d, displayFactor);

  var unitCellRenderer = new Renderer(unitCellScene, 'unitCellRenderer', 'cell');
  unitCellRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 20,20,40, 15);

  var motifRenderer = new Renderer(motifScene, 'motifRenderer','motif'); 
  motifRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 0,0,50, 15);
  motifRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 50,0,0, 15);
  motifRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 0,50,0, 15);

  crystalRenderer.startAnimation();  
  
  var canvasSnapshot = new Snapshot(crystalRenderer);

  var orbitCrystal = new Orbit(
    crystalRenderer.getMainCamera(), 
    '#crystalRendererMouse',   
    "perspective",  
    false, 
    'crystal', 
    undefined,
    [crystalRenderer.getHudCameraCube(), crystalRenderer.getHudCamera()]
    ); 
    
  soundMachine.crystalCameraOrbit = orbitCrystal ;
   
  var orbitUnitCell = new Orbit(unitCellRenderer.getMainCamera(), '#unitCellRendererMouse',  "perspective",  false, 'cell');
 
  orbitUnitCell.setSyncedCamControl(orbitCrystal);
  orbitCrystal.setSyncedCamControl(orbitUnitCell); 

  var motifCamX = new Orbit(motifRenderer.getSpecificCamera(0), '#motifPosX', "perspective", true, 'motif'   );
  var motifCamY = new Orbit(motifRenderer.getSpecificCamera(1), '#motifPosY', "perspective", true, 'motif'   );
  var motifCamZ = new Orbit(motifRenderer.getSpecificCamera(2), '#motifPosZ', "perspective", true, 'motif'   );

  crystalRenderer.onAnimationUpdate(orbitCrystal.update.bind(orbitCrystal));

  unitCellRenderer.onAnimationUpdate(orbitUnitCell.update.bind(orbitUnitCell)); 

  motifRenderer.onAnimationUpdate(motifCamX.update.bind(motifCamX));
  motifRenderer.onAnimationUpdate(motifCamY.update.bind(motifCamY));
  motifRenderer.onAnimationUpdate(motifCamZ.update.bind(motifCamZ));

  // Motif editor
  var motifEditor = new Motifeditor(menu, soundMachine); 
 
  var dragNdropXevent = new MouseEvents(motifEditor, 'dragNdrop', motifRenderer.getSpecificCamera(0), 'motifPosX');
  var dragNdropYevent = new MouseEvents(motifEditor, 'dragNdrop', motifRenderer.getSpecificCamera(1), 'motifPosY');
  var dragNdropZevent = new MouseEvents(motifEditor, 'dragNdrop', motifRenderer.getSpecificCamera(2), 'motifPosZ');

  // navigation cube
  var CubeEvent = new MouseEvents(lattice, 'navCubeDetect', crystalRenderer.hudCameraCube, 'hudRendererCube',  [orbitUnitCell,orbitCrystal], soundMachine, hudCube );
 
  // storing mechanism  
  var storingMachine = new StoreProject( lattice, motifEditor, crystalRenderer.getMainCamera(), unitCellRenderer.getMainCamera(),motifRenderer.getSpecificCamera(0),motifRenderer.getSpecificCamera(1),motifRenderer.getSpecificCamera(2), crystalRenderer );

  // Gear Bar Tour
  var gearTour = new GearTour(crystalScene, motifEditor, lattice, menu);
 
  // handel keyboard keys
  var keyboard = new KeyboardKeys(new THREEx.KeyboardState(), crystalScene, orbitCrystal, motifEditor, crystalRenderer);
  animationMachine.keyboard = keyboard;
  crystalRenderer.externalFunctions.push(keyboard.handleKeys.bind(keyboard));
  crystalRenderer.externalFunctions.push(crystalScene.updateXYZlabelPos.bind(crystalScene, crystalRenderer.getMainCamera()));

  // CW Doll
  var dollScene = DollExplorer.getInstance();  
  crystalRenderer.setDoll(dollScene.object3d ); 
  var dollEditor = new Doll(crystalRenderer.dollCamera, orbitCrystal, lattice, animationMachine, keyboard, soundMachine, gearTour);
  crystalRenderer.setDoll(undefined, dollEditor.doll);  
  dollEditor.rePosition(); 
  orbitCrystal.dollOnDocumentMouseDown(dollEditor.onDocumentMouseDown.bind(dollEditor)) ;

  // mouse events happen in crytal screen 
  var crystalScreenEvents = new CrystalMouseEvents(lattice, 'info', crystalRenderer.getMainCamera(), 'crystalRendererMouse', 'default', dollEditor);

  // full screen
  var fullScreen = new FullScreen();

  // resizer
  var sceneResizer = new SceneResizer(crystalRenderer, motifRenderer, unitCellRenderer, displayFactor, dollEditor, hudCube);
  $( document ).ready(function() {
    sceneResizer.resize( 'crystal');
  });
  window.addEventListener('resize', function () {
    sceneResizer.resize( crystalScreenEvents.state);
  }, false);

  // leap motion
  var leapM = new LeapMotionHandler( motifEditor, lattice, orbitCrystal, soundMachine, dollEditor, keyboard);

  // rendering modes
  var renderingModes = new RenderingMode(crystalScene, unitCellScene, motifScene);
  var tabActionsManager = new TabActions(lattice, motifEditor, crystalRenderer, unitCellRenderer,crystalScreenEvents, motifRenderer, dollEditor, hudCube, hudArrows, CubeEvent, sceneResizer, gearTour);

  // lattice events binding
  menu.onLatticeChange(function(message, latticeName) {
    lattice.load(latticeName);
  });
  menu.onLatticeParameterChange(function(message, latticeParameters) { 
    lattice.setParameters(latticeParameters); 
    motifEditor.updateFixedDimensions(latticeParameters);
  });
  menu.onLatticeParameterChangeForHud(function(message, latticeParameters) {  
    hudArrows.updateLengths(latticeParameters);
    hudArrows.updateAngles(latticeParameters);  
    hudCube.updateAngles(latticeParameters);
    crystalScene.updateAbcAxes(latticeParameters, crystalRenderer.getMainCamera());
  });
  // grade
  menu.onGradeParameterChange(function(message, gradeParameters) {
    lattice.setGrade(gradeParameters);
  });
  menu.onGradeChoices(function(message, gradeChoices) {
    lattice.setGradeChoices(gradeChoices);
  });

  // miller
  menu.onDirectionalSubmit(function(message, millerParameters) {  
    lattice.millerParameters = millerParameters ;
    lattice.submitDirectional(millerParameters);
  });
  menu.onPlaneSubmit(function(message, millerParameters) {
    lattice.millerParameters = millerParameters ;
    lattice.submitPlane(millerParameters);
  });
  menu.directionSelection(function(message, which) {
    lattice.selectDirection(which);
  });
  menu.directionParameterChange(function(message, arg) {  
    lattice.directionParameterChange(arg);
  });
  menu.planeParameterChange(function(message, arg) { 
    lattice.planeParameterChange(arg);
  });
  menu.planeSelection(function(message, which) {
    lattice.selectPlane(which);
  });
  menu.onPlaneVisibility(function(message, arg) {
    lattice.planeVisibility(arg);
  });
  menu.onDirectionVisibility(function(message, arg) {
    lattice.directionVisibility(arg);
  });
  lattice.onPlaneStateChange(function(message, state) {
    lattice._planeState(state);
  });
  lattice.onDirectionStateChange(function(message, state) {
    lattice.directionState(state);
  });  
  menu.setAnaglyph(function(message, arg) {
    crystalRenderer.setAnaglyph(arg);
    motifRenderer.setAnaglyph(arg);
    unitCellRenderer.setAnaglyph(arg);
  }); 
  menu.onSoundsSet(function(message, arg) { 
    soundMachine.switcher(arg.sounds); 
  });
  menu.onRadiusToggle(function(message, arg) { 
    lattice.toggleRadius(arg); 
  });
  menu.onAtomPosModeChange(function(message, arg) {   
    motifEditor.atomPosMode(arg); 
  });
  menu.onLightsSet(function(message, arg) { 
     
    if(arg.lights){
      crystalScene.AmbLight.color.setHex( 0x4D4D4C ); 
      crystalScene.light.intensity = 1 ;
      crystalScene.light.castShadow = true;  

      unitCellScene.AmbLight.color.setHex( 0x4D4D4C ); 
      unitCellScene.light.intensity = 1 ;
      unitCellScene.light.castShadow = true;  
    }
    else{
      crystalScene.AmbLight.color.setHex( 0xffffff ); 
      crystalScene.light.intensity = 0 ;
      crystalScene.light.castShadow = false;  

      unitCellScene.AmbLight.color.setHex( 0xffffff ); 
      unitCellScene.light.intensity = 0.0;
      unitCellScene.light.castShadow = false;   
    }  
  });
  menu.onLeapMotionSet(function(message, arg) {  
    leapM.toggle(arg.leap);
  });
  menu.onFogParameterChange(function(message, arg) { 
    if(crystalScene.fogActive === true){ 
      if(!_.isUndefined(arg.fogColor)){
        crystalScene.object3d.fog.color.setHex( "0x"+arg.fogColor );  
      }
      else if(!_.isUndefined(arg.fogDensity)){
        crystalScene.object3d.fog.density = parseInt(arg.fogDensity)/3000 ;
      }
    }
  });
  menu.onFogChange(function(message, arg) { 
    crystalScene.fogActive = arg.fog ;
    if(arg.fog === true){  
      crystalScene.object3d.fog.density = parseInt($('#fogDensity').val())/2000;
      crystalScene.object3d.fog.color.setHex( "0x"+($('#fogColor').val()) );  
    }
    else{ 
      crystalScene.object3d.fog.density = 0 ;
    } 
  });
  menu.onRendererColorChange(function(message, arg) { 

    if(!_.isUndefined(arg.crystalScreenColor)){ 
      crystalRenderer.backgroundColor = ('#'+arg.crystalScreenColor);
    }
    else if(!_.isUndefined(arg.cellScreenColor)){
      unitCellRenderer.backgroundColor = ('#'+arg.cellScreenColor);
    } 
    else if(!_.isUndefined(arg.motifXScreenColor)){ 
      motifRenderer.viewportColors[0] = ('#'+arg.motifXScreenColor);
    } 
    else if(!_.isUndefined(arg.motifYScreenColor)){  
      motifRenderer.viewportColors[1] = ('#'+arg.motifYScreenColor);
    } 
    else if(!_.isUndefined(arg.motifZScreenColor)){  
      motifRenderer.viewportColors[2] = ('#'+arg.motifZScreenColor);
    } 
  });
  
  // motif editor events binding
  $("#list li").click(function(e) {
    tabActionsManager.tabClick($(this).attr('id'));
  }); 
  menu.atomSelection(function(message , arg) {
    motifEditor.selectElem(arg); 
    var parameters = motifEditor.getDimensions() ;
    lattice.setMotif(motifEditor.getMotif(), parameters)  ;
  }); 
  motifEditor.onEditorStateChange(function(message, state) {
    motifEditor.editorState_(state);
  });
  motifEditor.onViewStateChange(function(message, state) {
    motifEditor.viewState_(state);
  });
  menu.onAtomSubmit(function(message, atomParam) {
 
    if(atomParam.button === 'saveChanges'){
      var parameters = motifEditor.getDimensions() ;
      lattice.setMotif(motifEditor.getMotif(), parameters)  ;
      
      var params = {
        alpha : parameters.alpha,
        beta : parameters.beta,
        gamma : parameters.gamma, 
        scaleX : parameters.x,
        scaleY : parameters.y,
        scaleZ : parameters.z,
      }
      hudArrows.updateLengths(params);
      hudArrows.updateAngles(params); 
      hudArrows.setVisibility();
      hudCube.updateAngles(params);
      crystalScene.updateAbcAxes(params, crystalRenderer.getMainCamera());
      motifEditor.submitAtom(atomParam); 
    }
    else if(atomParam.button === 'deleteAtom'){
      motifEditor.submitAtom(atomParam);
      var parameters = motifEditor.getDimensions() ;
      lattice.setMotif(motifEditor.getMotif(), parameters)  ;
      
      var params = {
        alpha : parameters.alpha,
        beta : parameters.beta,
        gamma : parameters.gamma, 
        scaleX : parameters.x,
        scaleY : parameters.y,
        scaleZ : parameters.z,
      }
      hudArrows.updateLengths(params);
      hudArrows.updateAngles(params); 
      hudArrows.setVisibility();
      hudCube.updateAngles(params);
      crystalScene.updateAbcAxes(params, crystalRenderer.getMainCamera());
    }
    
  });
  menu.savedAtomSelection(function(message, which) { 
    motifEditor.selectAtom(which);
  });
  menu.onTangentR(function(message, arg) { 
    motifEditor.changeTangentR(arg);
  });
  menu.onAtomParameterChange(function(message, param) { 
    motifEditor.setAtomsParameter(param);
  });
  menu.onAtomPositionChange(function(message, param) {  
    motifEditor.setAtomsPosition(param);
  }); 
  menu.onManuallyCellVolumeChange(function(message, param) { 
    motifEditor.setManuallyCellVolume(param);
  });
  menu.onManuallyCellAnglesChange(function(message, param) { 
    motifEditor.setManuallyCellAngles(param);
  });
  menu.onAtomTangencyChange(function(message, param) { 
    motifEditor.setAtomsTangency(param);
  });
  menu.onAtomVisibility(function(message, param) { 
    motifEditor.atomVisibility(param); 
    lattice.atomVisibility(param); 
  });
  menu.setDimsManually(function(message, param) { 
    motifEditor.setDimsManually(param);
  });
  menu.setAnglesManually(function(message, param) { 
    motifEditor.setAnglesManually(param);
  });
  menu.onFixedLengthChange(function(message, param) {  
    motifEditor.padlockMode(param); 
  }); 
  menu.padlockSet(function(message, param) {  
    motifEditor.padlockMode(param); 
  });  <commit_msg>updates<commit_after> /*unused:false*/
'use strict'; 

require.config({
  baseUrl: 'scripts',
  paths: {
    'pubsub': '../vendor/pubsub',
    'three': '../vendor/three',
    'threejs-controls/OrbitControls': '../vendor/threejs-controls/OrbitControls',
    'threejs-controls/OrbitAndPanControls': '../vendor/threejs-controls/OrbitAndPanControls',
    'underscore': '../vendor/underscore',
    'jquery': '../vendor/jquery',
    'jquery-ui': '../vendor/jquery-ui/jquery-ui',
    'csg': '../vendor/csg',
    'threeCSG': '../vendor/ThreeCSG',
    'keyboardState': '../vendor/keyboardState',
    'rStats': '../vendor/rStats',
    'rStatsExtras': '../vendor/rStatsExtras',
    'leapMotion': '../vendor/leap-0.6.4',
    'icheck': '../vendor/icheck/icheck',
    'jquery.matchHeight': '../vendor/jquery-match-height/jquery.matchHeight-min',
    'bootstrap-select': '../vendor/bootstrap-select/dist/js/bootstrap-select.min',
    'jquery.mCustomScrollbar.concat.min': '../vendor/malihu-custom-scrollbar/jquery.mCustomScrollbar.concat.min',
    'bootstrap': '../vendor/bootstrap/assets/javascripts/bootstrap',
    'jColor': '../vendor/colorpicker/spectrum'
  },
  shim: {
    'three': { exports: 'THREE' },
    'threejs-controls/OrbitControls': { deps: [ 'three' ] },
    'keyboardState': { deps: [ 'three' ] },
    'threejs-controls/OrbitAndPanControls': { deps: [ 'three' ] },
    'scg': { deps: [ 'three' ] },
    'threeCSG': { deps: [ 'three' ] },
    'rStats': { deps: [ 'three' ] }
  }
});

require([
  'pubsub', 
  'underscore', 
  'three', 
  'explorer', 
  'renderer', 
  'orbit', 
  'menu', 
  'lattice', 
  'snapshot',
  'navArrowsHud',
  'navCubeHud',
  'motifeditor',
  'unitCellExplorer',
  'motifExplorer',
  'mouseEvents',
  'navArrows',
  'navCube',
  'crystalMouseEvents',
  'storeProject',
  'restoreCWstate',
  'sound',
  'animate',
  'gearTour',
  'doll', 
  'dollExplorer',
  'keyboardKeys',
  'keyboardState',
  'fullScreen',
  'sceneResizer',
  'rStats', 
  'rStatsExtras', 
  'leapMotionHandler',
  'renderingMode',
  'tabActions'
], function(
  PubSub, 
  _, 
  THREE,
  Explorer, 
  Renderer, 
  Orbit, 
  Menu, 
  Lattice, 
  Snapshot, 
  NavArrowsHud, 
  NavCubeHud, 
  Motifeditor, 
  UnitCellExplorer, 
  MotifExplorer, 
  MouseEvents, 
  NavArrows, 
  NavCube, 
  CrystalMouseEvents, 
  StoreProject, 
  RestoreCWstate, 
  Sound, 
  Animate, 
  GearTour, 
  Doll, 
  DollExplorer, 
  KeyboardKeys, 
  KeyboardState, 
  FullScreen, 
  SceneResizer, 
  RStats, 
  RStatsExtras, 
  LeapMotionHandler,
  RenderingMode,
  TabActions
) {
  var menu = new Menu();
  
  // Scenes 
  var crystalScene = Explorer.getInstance();
  crystalScene.menu = menu;

  var unitCellScene = UnitCellExplorer.getInstance();
  var motifScene = MotifExplorer.getInstance();
 
  var height,width;

  var crystalRenderer = new Renderer(crystalScene, 'crystalRenderer', 'crystal' ); 
  crystalRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 30,30,60, 15);

  // crystal scene stats
  var glS = new glStats();
  var tS = new threeStats( crystalRenderer.renderer );

  var rS = rStats(  {
    values: {
      frame: { caption: 'Total frame time (ms)', over: 16 },
      fps: { caption: 'Framerate (FPS)', below: 30 },
      calls: { caption: 'Calls (three.js)', over: 3000 },
      raf: { caption: 'Time since last rAF (ms)' },
      rstats: { caption: 'rStats update (ms)' }
    },
    groups: [
      { caption: 'Framerate', values: [ 'fps', 'raf' ] },
      { caption: 'Frame Budget', values: [ 'frame', 'texture', 'setup', 'render' ] }
    ],
    fractions: [
      { base: 'frame', steps: [ 'texture', 'setup', 'render' ] }
    ],
    plugins: [
      tS,
      glS
    ]
  } );

  crystalRenderer.rS = rS;
  crystalRenderer.glS = glS;

  // sound & animations
  var animationMachine = new Animate(crystalScene);
  var soundMachine = new Sound(animationMachine); 
  animationMachine.soundMachine = soundMachine;
  crystalRenderer.externalFunctions.push(animationMachine.animation.bind(animationMachine));
  
  var lattice = new Lattice(menu, soundMachine);
  
  // HUD  
  var navArrowsScene = NavArrowsHud.getInstance();  
  var hudArrows = new NavArrows(navArrowsScene.object3d, lattice);
  
  var navCubeScene = NavCubeHud.getInstance();  
  var hudCube = new NavCube(navCubeScene.object3d, lattice);
 
  //  WebGL Renderers and cameras
  var displayFactor = 6 ; // changes how big or small will be the Hud 
  crystalRenderer.initHud(navArrowsScene.object3d, navCubeScene.object3d, displayFactor);

  var unitCellRenderer = new Renderer(unitCellScene, 'unitCellRenderer', 'cell');
  unitCellRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 20,20,40, 15);

  var motifRenderer = new Renderer(motifScene, 'motifRenderer','motif'); 
  motifRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 0,0,50, 15);
  motifRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 50,0,0, 15);
  motifRenderer.createPerspectiveCamera(new THREE.Vector3(0,0,0), 0,50,0, 15);

  crystalRenderer.startAnimation();  
  
  var canvasSnapshot = new Snapshot(crystalRenderer);

  var orbitCrystal = new Orbit(
    crystalRenderer.getMainCamera(), 
    '#crystalRendererMouse',   
    "perspective",  
    false, 
    'crystal', 
    undefined,
    [crystalRenderer.getHudCameraCube(), crystalRenderer.getHudCamera()]
    ); 
    
  soundMachine.crystalCameraOrbit = orbitCrystal ;
   
  var orbitUnitCell = new Orbit(unitCellRenderer.getMainCamera(), '#unitCellRendererMouse',  "perspective",  false, 'cell');
 
  orbitUnitCell.setSyncedCamControl(orbitCrystal);
  orbitCrystal.setSyncedCamControl(orbitUnitCell); 

  var motifCamX = new Orbit(motifRenderer.getSpecificCamera(0), '#motifPosX', "perspective", true, 'motif'   );
  var motifCamY = new Orbit(motifRenderer.getSpecificCamera(1), '#motifPosY', "perspective", true, 'motif'   );
  var motifCamZ = new Orbit(motifRenderer.getSpecificCamera(2), '#motifPosZ', "perspective", true, 'motif'   );

  crystalRenderer.onAnimationUpdate(orbitCrystal.update.bind(orbitCrystal));

  unitCellRenderer.onAnimationUpdate(orbitUnitCell.update.bind(orbitUnitCell)); 

  motifRenderer.onAnimationUpdate(motifCamX.update.bind(motifCamX));
  motifRenderer.onAnimationUpdate(motifCamY.update.bind(motifCamY));
  motifRenderer.onAnimationUpdate(motifCamZ.update.bind(motifCamZ));

  // Motif editor
  var motifEditor = new Motifeditor(menu, soundMachine); 
 
  var dragNdropXevent = new MouseEvents(motifEditor, 'dragNdrop', motifRenderer.getSpecificCamera(0), 'motifPosX');
  var dragNdropYevent = new MouseEvents(motifEditor, 'dragNdrop', motifRenderer.getSpecificCamera(1), 'motifPosY');
  var dragNdropZevent = new MouseEvents(motifEditor, 'dragNdrop', motifRenderer.getSpecificCamera(2), 'motifPosZ');

  // navigation cube
  var CubeEvent = new MouseEvents(lattice, 'navCubeDetect', crystalRenderer.hudCameraCube, 'hudRendererCube',  [orbitUnitCell,orbitCrystal], soundMachine, hudCube );
 
  // storing mechanism  
  var storingMachine = new StoreProject( lattice, motifEditor, crystalRenderer.getMainCamera(), unitCellRenderer.getMainCamera(),motifRenderer.getSpecificCamera(0),motifRenderer.getSpecificCamera(1),motifRenderer.getSpecificCamera(2), crystalRenderer );

  // Gear Bar Tour
  var gearTour = new GearTour(crystalScene, motifEditor, lattice, menu);
 
  // handel keyboard keys
  var keyboard = new KeyboardKeys(new THREEx.KeyboardState(), crystalScene, orbitCrystal, motifEditor, crystalRenderer);
  animationMachine.keyboard = keyboard;
  crystalRenderer.externalFunctions.push(keyboard.handleKeys.bind(keyboard));
  crystalRenderer.externalFunctions.push(crystalScene.updateXYZlabelPos.bind(crystalScene, crystalRenderer.getMainCamera()));

  // CW Doll
  var dollScene = DollExplorer.getInstance();  
  crystalRenderer.setDoll(dollScene.object3d ); 
  var dollEditor = new Doll(crystalRenderer.dollCamera, orbitCrystal, lattice, animationMachine, keyboard, soundMachine, gearTour);
  crystalRenderer.setDoll(undefined, dollEditor.doll);  
  dollEditor.rePosition(); 
  orbitCrystal.dollOnDocumentMouseDown(dollEditor.onDocumentMouseDown.bind(dollEditor)) ;

  // mouse events happen in crytal screen 
  var crystalScreenEvents = new CrystalMouseEvents(lattice, 'info', crystalRenderer.getMainCamera(), 'crystalRendererMouse', 'default', dollEditor);

  // full screen
  var fullScreen = new FullScreen();

  // resizer
  var sceneResizer = new SceneResizer(crystalRenderer, motifRenderer, unitCellRenderer, displayFactor, dollEditor, hudCube);
  $( document ).ready(function() {
    sceneResizer.resize( 'crystal');
  });
  window.addEventListener('resize', function () {
    sceneResizer.resize( crystalScreenEvents.state);
  }, false);

  // leap motion
  var leapM = new LeapMotionHandler( motifEditor, lattice, orbitCrystal, soundMachine, dollEditor, keyboard);

  // rendering modes
  var renderingModes = new RenderingMode(crystalScene, unitCellScene, motifScene);
  var tabActionsManager = new TabActions(lattice, motifEditor, crystalRenderer, unitCellRenderer,crystalScreenEvents, motifRenderer, dollEditor, hudCube, hudArrows, CubeEvent, sceneResizer, gearTour);

  // lattice events binding
  menu.onLatticeChange(function(message, latticeName) {
    lattice.load(latticeName);
  });
  menu.onLatticeParameterChange(function(message, latticeParameters) { 
    lattice.setParameters(latticeParameters); 
    motifEditor.updateFixedDimensions(latticeParameters);
  });
  menu.onLatticeParameterChangeForHud(function(message, latticeParameters) {  
    hudArrows.updateLengths(latticeParameters);
    hudArrows.updateAngles(latticeParameters);  
    hudCube.updateAngles(latticeParameters);
    crystalScene.updateAbcAxes(latticeParameters, crystalRenderer.getMainCamera());
  });
  // grade
  menu.onGradeParameterChange(function(message, gradeParameters) {
    lattice.setGrade(gradeParameters);
  });
  menu.onGradeChoices(function(message, gradeChoices) {
    lattice.setGradeChoices(gradeChoices);
  });

  // miller
  menu.onDirectionalSubmit(function(message, millerParameters) {  
    lattice.millerParameters = millerParameters ;
    lattice.submitDirectional(millerParameters);
  });
  menu.onPlaneSubmit(function(message, millerParameters) {
    lattice.millerParameters = millerParameters ;
    lattice.submitPlane(millerParameters);
  });
  menu.directionSelection(function(message, which) {
    lattice.selectDirection(which);
  });
  menu.directionParameterChange(function(message, arg) {  
    lattice.directionParameterChange(arg);
  });
  menu.planeParameterChange(function(message, arg) { 
    lattice.planeParameterChange(arg);
  });
  menu.planeSelection(function(message, which) {
    lattice.selectPlane(which);
  });
  menu.onPlaneVisibility(function(message, arg) {
    lattice.planeVisibility(arg);
  });
  menu.onDirectionVisibility(function(message, arg) {
    lattice.directionVisibility(arg);
  });
  lattice.onPlaneStateChange(function(message, state) {
    lattice._planeState(state);
  });
  lattice.onDirectionStateChange(function(message, state) {
    lattice.directionState(state);
  });  
  menu.setAnaglyph(function(message, arg) {
    crystalRenderer.setAnaglyph(arg);
    motifRenderer.setAnaglyph(arg);
    unitCellRenderer.setAnaglyph(arg);
  }); 
  menu.onSoundsSet(function(message, arg) { 
    soundMachine.switcher(arg.sounds); 
  });
  menu.onRadiusToggle(function(message, arg) { 
    lattice.toggleRadius(arg); 
  });
  menu.onAtomPosModeChange(function(message, arg) {   
    motifEditor.atomPosMode(arg); 
  });
  menu.onLightsSet(function(message, arg) { 
     
    if(arg.lights){
      crystalScene.AmbLight.color.setHex( 0x4D4D4C ); 
      crystalScene.light.intensity = 1 ;
      crystalScene.light.castShadow = true;  

      unitCellScene.AmbLight.color.setHex( 0x4D4D4C ); 
      unitCellScene.light.intensity = 1 ;
      unitCellScene.light.castShadow = true;  
    }
    else{
      crystalScene.AmbLight.color.setHex( 0xffffff ); 
      crystalScene.light.intensity = 0 ;
      crystalScene.light.castShadow = false;  

      unitCellScene.AmbLight.color.setHex( 0xffffff ); 
      unitCellScene.light.intensity = 0.0;
      unitCellScene.light.castShadow = false;   
    }  
  });
  menu.onLeapMotionSet(function(message, arg) {  
    leapM.toggle(arg.leap);
  });
  menu.onFogParameterChange(function(message, arg) { 
    if(crystalScene.fogActive === true){ 
      if(!_.isUndefined(arg.fogColor)){
        crystalScene.object3d.fog.color.setHex( "0x"+arg.fogColor );  
      }
      else if(!_.isUndefined(arg.fogDensity)){
        crystalScene.object3d.fog.density = parseInt(arg.fogDensity)/3000 ;
      }
    }
  });
  menu.onFogChange(function(message, arg) { 
    crystalScene.fogActive = arg.fog ;
    if(arg.fog === true){  
      crystalScene.object3d.fog.density = parseInt($('#fogDensity').val())/2000;
      crystalScene.object3d.fog.color.setHex( "0x"+($('#fogColor').val()) );  
    }
    else{ 
      crystalScene.object3d.fog.density = 0 ;
    } 
  });
  menu.onRendererColorChange(function(message, arg) { 

    if(!_.isUndefined(arg.crystalScreenColor)){ 
      crystalRenderer.backgroundColor = ('#'+arg.crystalScreenColor);
    }
    else if(!_.isUndefined(arg.cellScreenColor)){
      unitCellRenderer.backgroundColor = ('#'+arg.cellScreenColor);
    } 
    else if(!_.isUndefined(arg.motifXScreenColor)){ 
      motifRenderer.viewportColors[0] = ('#'+arg.motifXScreenColor);
    } 
    else if(!_.isUndefined(arg.motifYScreenColor)){  
      motifRenderer.viewportColors[1] = ('#'+arg.motifYScreenColor);
    } 
    else if(!_.isUndefined(arg.motifZScreenColor)){  
      motifRenderer.viewportColors[2] = ('#'+arg.motifZScreenColor);
    } 
  });
  
  // motif editor events binding
  $("#list li").click(function(e) {
    tabActionsManager.tabClick($(this).attr('id'));
  }); 
  menu.atomSelection(function(message , arg) {
    motifEditor.selectElem(arg); 
    var parameters = motifEditor.getDimensions() ;
    lattice.setMotif(motifEditor.getMotif(), parameters)  ;
  }); 
  motifEditor.onEditorStateChange(function(message, state) {
    motifEditor.editorState_(state);
  });
  motifEditor.onViewStateChange(function(message, state) {
    motifEditor.viewState_(state);
  });
  menu.onAtomSubmit(function(message, atomParam) {
 
    if(atomParam.button === 'saveChanges'){
      var parameters = motifEditor.getDimensions() ;
      lattice.setMotif(motifEditor.getMotif(), parameters)  ;
      
      var params = {
        alpha : parameters.alpha,
        beta : parameters.beta,
        gamma : parameters.gamma, 
        scaleX : parameters.x,
        scaleY : parameters.y,
        scaleZ : parameters.z,
      }
      hudArrows.updateLengths(params);
      hudArrows.updateAngles(params); 
      hudArrows.setVisibility();
      hudCube.updateAngles(params);
      crystalScene.updateAbcAxes(params, crystalRenderer.getMainCamera());
      motifEditor.submitAtom(atomParam); 
    }
    else if(atomParam.button === 'deleteAtom'){
      motifEditor.submitAtom(atomParam);
      var parameters = motifEditor.getDimensions() ;
      lattice.setMotif(motifEditor.getMotif(), parameters)  ;
      
      var params = {
        alpha : parameters.alpha,
        beta : parameters.beta,
        gamma : parameters.gamma, 
        scaleX : parameters.x,
        scaleY : parameters.y,
        scaleZ : parameters.z,
      }
      hudArrows.updateLengths(params);
      hudArrows.updateAngles(params); 
      hudArrows.setVisibility();
      hudCube.updateAngles(params);
      crystalScene.updateAbcAxes(params, crystalRenderer.getMainCamera());
    }
    
  });
  menu.savedAtomSelection(function(message, which) { 
    motifEditor.selectAtom(which);
  });
  menu.onTangentR(function(message, arg) { 
    motifEditor.changeTangentR(arg);
  });
  menu.onAtomParameterChange(function(message, param) { 
    motifEditor.setAtomsParameter(param);
  });
  menu.onAtomPositionChange(function(message, param) {  
    motifEditor.setAtomsPosition(param);
  }); 
  menu.onManuallyCellVolumeChange(function(message, param) { 
    motifEditor.setManuallyCellVolume(param);
  }); 
  menu.onAtomTangencyChange(function(message, param) { 
    motifEditor.setAtomsTangency(param);
  });
  menu.onAtomVisibility(function(message, param) { 
    motifEditor.atomVisibility(param); 
    lattice.atomVisibility(param); 
  });
  menu.setDimsManually(function(message, param) { 
    motifEditor.setDimsManually(param);
  });
  menu.setAnglesManually(function(message, param) { 
    motifEditor.setAnglesManually(param);
  });
  menu.onFixedLengthChange(function(message, param) {  
    motifEditor.padlockMode(param); 
  }); 
  menu.padlockSet(function(message, param) {  
    motifEditor.padlockMode(param); 
  });  
{'fraction_non_alphanumeric': 0.1337276699461998, 'fraction_numerical': 0.00677704128644889, 'mean_word_length': 4.149066421793695, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '714505', 'n_tokens_mistral': 11431, 'n_tokens_neox': 10872, 'n_words': 1633}