diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js
index 43c18da72d..862c4e72e6 100644
--- a/examples/controllers/handControllerGrab.js
+++ b/examples/controllers/handControllerGrab.js
@@ -44,8 +44,8 @@ var PICK_WITH_HAND_RAY = true;
 
 var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
 var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
-var DISTANCE_HOLDING_UNITY_MASS = 1200;  //  The mass at which the distance holding action timeframe is unmodified
-var DISTANCE_HOLDING_UNITY_DISTANCE = 6;  //  The distance at which the distance holding action timeframe is unmodified
+var DISTANCE_HOLDING_UNITY_MASS = 1200; //  The mass at which the distance holding action timeframe is unmodified
+var DISTANCE_HOLDING_UNITY_DISTANCE = 6; //  The distance at which the distance holding action timeframe is unmodified
 var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did
 var MOVE_WITH_HEAD = true; // experimental head-control of distantly held objects
 var FAR_TO_NEAR_GRAB_PADDING_FACTOR = 1.2;
@@ -126,6 +126,7 @@ var GRABBABLE_PROPERTIES = [
 
 var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
 var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js
+var GRAB_CONSTRAINTS_USER_DATA_KEY = "grabConstraintsKey"
 
 var DEFAULT_GRABBABLE_DATA = {
     disableReleaseVelocity: false
@@ -345,7 +346,7 @@ function MyController(hand) {
         this.grabSphereOff();
         if (WANT_DEBUG || WANT_DEBUG_STATE) {
             print("STATE (" + this.hand + "): " + stateToName(this.state) + " --> " +
-                  stateToName(newState) + ", hand: " + this.hand);
+                stateToName(newState) + ", hand: " + this.hand);
         }
         this.state = newState;
     };
@@ -424,11 +425,15 @@ function MyController(hand) {
     }
 
     this.grabSphereOn = function() {
-        var color = {red: 0, green: 255, blue: 0};
+        var color = {
+            red: 0,
+            green: 255,
+            blue: 0
+        };
         if (this.grabSphere === null) {
             var sphereProperties = {
                 position: this.getHandPosition(),
-                size: GRAB_RADIUS*2,
+                size: GRAB_RADIUS * 2,
                 color: color,
                 alpha: 0.1,
                 solid: true,
@@ -438,7 +443,7 @@ function MyController(hand) {
         } else {
             Overlays.editOverlay(this.grabSphere, {
                 position: this.getHandPosition(),
-                size: GRAB_RADIUS*2,
+                size: GRAB_RADIUS * 2,
                 color: color,
                 alpha: 0.1,
                 solid: true,
@@ -491,12 +496,10 @@ function MyController(hand) {
         }
 
         var searchSphereLocation = Vec3.sum(distantPickRay.origin,
-                                            Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
-        this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance,
-                            (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
+            Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
+        this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
         if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) {
-            this.overlayLineOn(handPosition, searchSphereLocation,
-                               (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
+            this.overlayLineOn(handPosition, searchSphereLocation, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
         }
     }
 
@@ -823,8 +826,8 @@ function MyController(hand) {
         var distantPickRay = {
             origin: PICK_WITH_HAND_RAY ? handPosition : Camera.position,
             direction: PICK_WITH_HAND_RAY ? Quat.getUp(this.getHandRotation()) : Vec3.mix(Quat.getUp(this.getHandRotation()),
-                                                                                          Quat.getFront(Camera.orientation),
-                                                                                          HAND_HEAD_MIX_RATIO),
+                Quat.getFront(Camera.orientation),
+                HAND_HEAD_MIX_RATIO),
             length: PICK_MAX_DISTANCE
         };
 
@@ -999,6 +1002,8 @@ function MyController(hand) {
                         intersectionPointToCenterDistance *
                         FAR_TO_NEAR_GRAB_PADDING_FACTOR);
                 }
+
+
                 this.setState(this.state == STATE_SEARCHING ? STATE_DISTANCE_HOLDING : STATE_EQUIP);
                 this.searchSphereOff();
                 return;
@@ -1145,9 +1150,9 @@ function MyController(hand) {
 
         // double delta controller rotation
         var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation,
-                                                  controllerRotation,
-                                                  DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
-                                       Quat.inverse(this.previousControllerRotation));
+                controllerRotation,
+                DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
+            Quat.inverse(this.previousControllerRotation));
 
         // update the currentObject position and rotation.
         this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, handMoved);
@@ -1275,7 +1280,9 @@ function MyController(hand) {
     };
 
     this.hasPresetOffsets = function() {
-        var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}});
+        var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {
+            joints: {}
+        });
         if ("joints" in wearableData) {
             var allowedJoints = wearableData.joints;
             var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
@@ -1287,7 +1294,9 @@ function MyController(hand) {
     }
 
     this.getPresetPosition = function() {
-        var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}});
+        var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {
+            joints: {}
+        });
         var allowedJoints = wearableData.joints;
         var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
         if (handJointName in allowedJoints) {
@@ -1296,7 +1305,9 @@ function MyController(hand) {
     }
 
     this.getPresetRotation = function() {
-        var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}});
+        var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {
+            joints: {}
+        });
         var allowedJoints = wearableData.joints;
         var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
         if (handJointName in allowedJoints) {
@@ -1304,7 +1315,23 @@ function MyController(hand) {
         }
     }
 
+    this.getGrabConstraints = function() {
+        var defaultConstraints = {
+            positionLocked: false,
+            rotationLocked: false,
+            positionMod: false,
+            rotationMod: {
+                pitch: false,
+                yaw: false,
+                roll: false
+            }
+        }
+        var constraints = getEntityCustomData(GRAB_CONSTRAINTS_USER_DATA_KEY, this.grabbedEntity, defaultConstraints);
+        return constraints;
+    }
+
     this.nearGrabbing = function() {
+        print('NEAR GRAB')
         var now = Date.now();
 
         if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
@@ -1370,6 +1397,7 @@ function MyController(hand) {
                 reparentProps["localRotation"] = this.offsetRotation;
             }
             Entities.editEntity(this.grabbedEntity, reparentProps);
+
             Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
                 action: 'equip',
                 grabbedEntity: this.grabbedEntity
@@ -1392,6 +1420,7 @@ function MyController(hand) {
     };
 
     this.continueNearGrabbing = function() {
+        print('CONTINUE NEAR GRAB')
         if (this.state == STATE_CONTINUE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
             this.setState(STATE_RELEASE);
             this.callEntityMethodOnGrabbed("releaseGrab");
@@ -1427,7 +1456,7 @@ function MyController(hand) {
             Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) {
             // for whatever reason, the held/equipped entity has been pulled away.  ungrab or unequip.
             print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand." +
-                  props.parentID + " " + vec3toStr(props.position));
+                props.parentID + " " + vec3toStr(props.position));
             this.setState(STATE_RELEASE);
             this.callEntityMethodOnGrabbed(this.state == STATE_NEAR_GRABBING ? "releaseGrab" : "releaseEquip");
             return;
@@ -1457,7 +1486,19 @@ function MyController(hand) {
             this.callEntityMethodOnGrabbed("continueNearGrab");
         }
 
+
+        var constraints = this.getGrabConstraints();
+        if (constraints.positionLocked === true) {
+            print('IT HAS ITS POSITION LOCKED!!')
+        }
+        if (constraints.rotationMod !== false) {
+            print('IT HAS A ROTATION MOD!!!')
+        }
+
+
+        // so it never seems to hit this currently
         if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) {
+
             // if less than a 5 seconds left, refresh the actions ttl
             var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
                 hand: this.hand === RIGHT_HAND ? "right" : "left",
@@ -1493,6 +1534,9 @@ function MyController(hand) {
         }
         this.callEntityMethodOnGrabbed("startNearTrigger");
         this.setState(STATE_CONTINUE_NEAR_TRIGGER);
+        print('START NEAR TRIGGER')
+
+
     };
 
     this.farTrigger = function() {
@@ -1511,6 +1555,71 @@ function MyController(hand) {
             this.callEntityMethodOnGrabbed("stopNearTrigger");
             return;
         }
+
+
+        var constraints = this.getGrabConstraints();
+        if (constraints.rotationMod !== false) {
+            //implement the rotation modifier
+            var grabbedProps = Entities.getEntityProperties(this.grabbedEntity);
+
+            var handPosition = this.getHandPosition();
+
+            var modTypes = [];
+
+            if (constraints.rotationMod.pitch !== false) {
+                modTypes.push('pitch')
+            }
+            if (constraints.rotationMod.yaw !== false) {
+                modTypes.push('yaw')
+            }
+            if (constraints.rotationMod.roll !== false) {
+                modTypes.push('roll')
+            }
+
+
+            finalRotation = {
+                x: 0,
+                y: 0,
+                z: 0
+            }
+            modTypes.forEach(function(modType) {
+
+                var value = handPosition[constraints.rotationMod[modType].startingAxis];
+                var min1 = constraints.rotationMod[modType].startingPoint;
+
+                var finalAngle = scale(value, min1, constraints.rotationMod[modType].distanceToMax, constraints.rotationMod[modType].min, constraints.rotationMod[modType].max)
+                    // print('VARS: ')
+                    // print('CONSTRAINTS:: ' + JSON.stringify(constraints))
+                    // print('value: ' + value)
+                    // print('min1:' + min1)
+                    // print('max1:' + constraints.rotationMod[modType].distanceToMax)
+                    // print('min2: ' + constraints.rotationMod[modType].min)
+                    // print('max2: ' + constraints.rotationMod[modType].max)
+                    // print('FINAL ANGLE::' + finalAngle)
+
+
+                if (finalAngle < constraints.rotationMod[modType].min) {
+                    finalAngle = constraints.rotationMod[modType].min;
+                }
+
+                if (finalAngle > constraints.rotationMod[modType].max) {
+                    finalAngle = constraints.rotationMod[modType].max;
+                }
+
+                if (modType === 'pitch') {
+                    finalRotation.x = finalAngle
+                }
+                if (modType === 'yaw') {
+                    finalRotation.y = finalAngle
+                }
+                if (modType === 'roll') {
+                    finalRotation.z = finalAngle
+                }
+            });
+
+            Entities.callEntityMethod(this.grabbedEntity, constraints.callback, [JSON.stringify(finalRotation)]);
+
+        }
         this.callEntityMethodOnGrabbed("continueNearTrigger");
     };
 
@@ -1624,6 +1733,7 @@ function MyController(hand) {
                 // sometimes we want things to stay right where they are when we let go.
                 var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, {});
                 var releaseVelocityData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA);
+                print('RELEASE DATA::' + JSON.stringify(releaseVelocityData))
                 if (releaseVelocityData.disableReleaseVelocity === true ||
                     // this next line allowed both:
                     // (1) far-grab, pull to self, near grab, then throw
@@ -1638,6 +1748,7 @@ function MyController(hand) {
         this.actionID = null;
         this.setState(STATE_OFF);
 
+        print('HAS VELOCITY AT RELEASE?? ' + noVelocity)
         Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
             action: 'release',
             grabbedEntity: this.grabbedEntity,
@@ -1705,6 +1816,7 @@ function MyController(hand) {
                     // when using string values
                     "collidesWith": COLLIDES_WITH_WHILE_GRABBED
                 };
+                print('ACTIVATING ENTITY')
                 Entities.editEntity(entityID, whileHeldProperties);
             } else if (data["refCount"] > 1) {
                 if (data["heartBeat"] === undefined ||
@@ -1722,9 +1834,12 @@ function MyController(hand) {
                 // people are holding something and one of them will be able (if the other releases at the right time) to
                 // bootstrap themselves with the held object.  This happens because the meaning of "otherAvatar" in
                 // the collision mask hinges on who the physics simulation owner is.
-                Entities.editEntity(entityID, {"collidesWith": COLLIDES_WITH_WHILE_MULTI_GRABBED});
+                Entities.editEntity(entityID, {
+                    "collidesWith": COLLIDES_WITH_WHILE_MULTI_GRABBED
+                });
             }
         }
+        print('ACTIVATED ENTITY!!!')
         setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
         return data;
     };
@@ -1736,7 +1851,9 @@ function MyController(hand) {
         var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex);
         children.forEach(function(childID) {
             print("disconnecting stray child of hand: (" + _this.hand + ") " + childID);
-            Entities.editEntity(childID, {parentID: NULL_UUID});
+            Entities.editEntity(childID, {
+                parentID: NULL_UUID
+            });
         });
     }
 
@@ -1764,11 +1881,23 @@ function MyController(hand) {
                     data["dynamic"] &&
                     data["parentID"] == NULL_UUID &&
                     !data["collisionless"]) {
-                    deactiveProps["velocity"] = {x: 0.0, y: 0.1, z: 0.0};
+                    deactiveProps["velocity"] = {
+                        x: 0.0,
+                        y: 0.1,
+                        z: 0.0
+                    };
                 }
                 if (noVelocity) {
-                    deactiveProps["velocity"] = {x: 0.0, y: 0.0, z: 0.0};
-                    deactiveProps["angularVelocity"] = {x: 0.0, y: 0.0, z: 0.0};
+                    deactiveProps["velocity"] = {
+                        x: 0.0,
+                        y: 0.0,
+                        z: 0.0
+                    };
+                    deactiveProps["angularVelocity"] = {
+                        x: 0.0,
+                        y: 0.0,
+                        z: 0.0
+                    };
                 }
 
                 Entities.editEntity(entityID, deactiveProps);
@@ -1778,13 +1907,31 @@ function MyController(hand) {
                 var deactiveProps = {
                     parentID: this.previousParentID,
                     parentJointIndex: this.previousParentJointIndex,
-                    velocity: {x: 0.0, y: 0.0, z: 0.0},
-                    angularVelocity: {x: 0.0, y: 0.0, z: 0.0}
+                    velocity: {
+                        x: 0.0,
+                        y: 0.0,
+                        z: 0.0
+                    },
+                    angularVelocity: {
+                        x: 0.0,
+                        y: 0.0,
+                        z: 0.0
+                    }
                 };
                 Entities.editEntity(entityID, deactiveProps);
             } else if (noVelocity) {
-                Entities.editEntity(entityID, {velocity: {x: 0.0, y: 0.0, z: 0.0},
-                                               angularVelocity: {x: 0.0, y: 0.0, z: 0.0}});
+                Entities.editEntity(entityID, {
+                    velocity: {
+                        x: 0.0,
+                        y: 0.0,
+                        z: 0.0
+                    },
+                    angularVelocity: {
+                        x: 0.0,
+                        y: 0.0,
+                        z: 0.0
+                    }
+                });
             }
         } else {
             data = null;
@@ -1916,3 +2063,8 @@ function cleanup() {
 }
 Script.scriptEnding.connect(cleanup);
 Script.update.connect(update);
+
+
+function scale(value, min1, max1, min2, max2) {
+    return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
+}
\ No newline at end of file
diff --git a/unpublishedScripts/DomainContent/Home/musicBox/createMusicBox.js b/unpublishedScripts/DomainContent/Home/musicBox/createMusicBox.js
new file mode 100644
index 0000000000..43abe429bb
--- /dev/null
+++ b/unpublishedScripts/DomainContent/Home/musicBox/createMusicBox.js
@@ -0,0 +1,144 @@
+var SHOULD_CLEANUP = true;
+
+var WHITE = {
+    red: 255,
+    green: 255,
+    blue: 255
+};
+
+var RED = {
+    red: 255,
+    green: 0,
+    blue: 0
+};
+
+var GREEN = {
+    red: 0,
+    green: 255,
+    blue: 0
+};
+
+var BLUE = {
+    red: 0,
+    green: 0,
+    blue: 255
+};
+
+var center = Vec3.sum(Vec3.sum(MyAvatar.position, {
+    x: 0,
+    y: 0.5,
+    z: 0
+}), Vec3.multiply(1, Quat.getFront(Camera.getOrientation())));
+
+var BASE_DIMENSIONS = {
+    x: 0.5,
+    y: 0.5,
+    z: 0.5
+};
+
+var BASE_POSITION = center;
+
+var LID_DIMENSIONS = {
+    x: BASE_DIMENSIONS.x,
+    y: BASE_DIMENSIONS.y / 8,
+    z: BASE_DIMENSIONS.z
+};
+
+var LID_OFFSET = {
+    x: 0,
+    y: BASE_DIMENSIONS.y / 2 + (LID_DIMENSIONS.y / 2),
+    z: 0.25
+};
+
+var LID_REGISTRATION_POINT = {
+    x: 0.5,
+    y: 0.5,
+    z: 1
+}
+
+var LID_SCRIPT_URL = Script.resolvePath('lid.js?'+Math.random());
+
+var base, lid;
+
+
+function createBase() {
+    var baseProperties = {
+        name: 'hifi-home-music-box-base',
+        type: 'Box',
+        color: WHITE,
+        position: BASE_POSITION,
+        dimensions: BASE_DIMENSIONS
+    }
+
+    base = Entities.addEntity(baseProperties);
+};
+
+
+function createLid() {
+
+    var lidPosition = Vec3.sum(BASE_POSITION, LID_OFFSET);
+    print('LID DIMENSIONS:' + JSON.stringify(lidPosition))
+    var lidProperties = {
+        name: 'hifi-home-music-box-lid',
+        type: 'Box',
+        color: BLUE,
+        dimensions: LID_DIMENSIONS,
+        position: lidPosition,
+        registrationPoint: LID_REGISTRATION_POINT,
+        dynamic: false,
+        script:LID_SCRIPT_URL,
+        collidesWith: 'myAvatar,otherAvatar',
+        userData: JSON.stringify({
+            grabConstraintsKey: {
+                callback:'rotateLid',
+                positionLocked: true,
+                rotationLocked: false,
+                positionMod: false,
+                rotationMod: {
+                    pitch: {
+                        min: 0,
+                        max: 75,
+                        startingAxis:'y',
+                        startingPoint:lidPosition.y,
+                        distanceToMax:lidPosition.y+0.35,
+                    },
+                    yaw: false,
+                    roll: false
+                }
+            },
+            grabbableKey: {
+                wantsTrigger: true,
+                disableReleaseVelocity: true,
+                disableMoveWithHead: true,
+                disableFarGrab:true,
+                disableEquip:true
+            }
+        })
+    }
+
+    lid = Entities.addEntity(lidProperties);
+
+};
+
+var theta = 0;
+var min = 0;
+var max = 60;
+var direction = "up";
+
+function animateLid() {
+    theata += 1
+}
+
+
+
+if (SHOULD_CLEANUP === true) {
+    Script.scriptEnding.connect(cleanup);
+}
+
+function cleanup() {
+    Entities.deleteEntity(base);
+    Entities.deleteEntity(lid);
+}
+
+createBase();
+createLid();
\ No newline at end of file
diff --git a/unpublishedScripts/DomainContent/Home/musicBox/lid.js b/unpublishedScripts/DomainContent/Home/musicBox/lid.js
new file mode 100644
index 0000000000..41c59a24be
--- /dev/null
+++ b/unpublishedScripts/DomainContent/Home/musicBox/lid.js
@@ -0,0 +1,132 @@
+(function() {
+
+    var _this;
+
+    function Lid() {
+        _this = this;
+        return this;
+    }
+
+    var MUSIC_URL = 'https://hifi-content.s3.amazonaws.com/DomainContent/Home/Sounds/aquarium_small.L.wav';
+    var SHUT_SOUND_URL = 'http://hifi-content.s3.amazonaws.com/DomainContent/Home/Sounds/book_fall.L.wav';
+    var OPEN_SOUND_URL = 'http://public.highfidelity.io/sounds/Switches%20and%20sliders/lamp_switch_2.wav'
+
+    Lid.prototype = {
+        preload: function(entityID) {
+            print('PRELOAD LID')
+            _this.entityID = entityID;
+            _this.music = SoundCache.getSound(MUSIC_URL);
+            _this.shutSound = SoundCache.getSound(SHUT_SOUND_URL);
+            _this.openSound = SoundCache.getSound(OPEN_SOUND_URL);
+            _this.musicIsPlaying = false;
+            _this.shut = true;
+            _this.shutSoundInjector = {
+                isPlaying: false
+            };
+            _this.musicInjector = null;
+            _this.openSoundInjector = {
+                isPlaying: false
+            }
+
+
+        },
+        continueNearTrigger: function() {
+            var properties = Entities.getEntityProperties(this.entityID);
+
+        },
+        playMusic: function() {
+            if (this.musicIsPlaying !== true) {
+
+                var properties = Entities.getEntityProperties(this.entityID);
+
+                var audioOptions = {
+                    position: properties.position,
+                    volume: 0.75,
+                    loop: true
+                }
+                this.musicInjector = Audio.playSound(this.music, audioOptions);
+                this.musicIsPlaying = true;
+            }
+        },
+
+        stopMusic: function() {
+            this.musicInjector.stop();
+            this.musicIsPlaying = false;
+        },
+
+        playOpenSound: function() {
+            if (this.openSoundInjector.isPlaying !== true) {
+
+                var properties = Entities.getEntityProperties(this.entityID);
+
+                var audioOptions = {
+                    position: properties.position,
+                    volume: 1,
+                    loop: false
+                }
+                this.openSoundInjector = Audio.playSound(this.openSound, audioOptions);
+            }
+        },
+        playShutSound: function() {
+            if (this.shutSoundInjector.isPlaying !== true) {
+
+                var properties = Entities.getEntityProperties(this.entityID);
+
+                var audioOptions = {
+                    position: properties.position,
+                    volume: 1,
+                    loop: false
+                }
+                this.shutSoundInjector = Audio.playSound(this.shutSound, audioOptions);
+            }
+        },
+        rotateLid: function(myID, paramsArray) {
+
+            var finalRotation;
+            paramsArray.forEach(function(param) {
+                var p;
+                // print('param is:' + param)
+                try {
+                    p = JSON.parse(param);
+                    finalRotation = p;
+
+                } catch (err) {
+                    // print('not a json param')
+                    return;
+                    p = param;
+                }
+
+            });
+
+            if (finalRotation.x > 20 && this.musicIsPlaying === false) {
+                this.playMusic();
+                print('play music!!')
+            }
+            if (finalRotation.x <= 20 && this.musicIsPlaying === true) {
+                print('stop music!!')
+                this.stopMusic();
+            }
+            if (finalRotation.x > 0 && this.shut === true) {
+                print('play open sound!!')
+                this.shut = false;
+                this.playOpenSound();
+            } else if (finalRotation.x <= 0 && this.shut === false) {
+                print('play shut sound!!')
+                this.shut = true;
+                this.playShutSound();
+            }
+            Entities.editEntity(this.entityID, {
+                rotation: Quat.fromPitchYawRollDegrees(finalRotation.x, finalRotation.y, finalRotation.z)
+            })
+
+        },
+
+        unload: function() {
+            this.musicInjector.stop();
+
+        },
+    }
+
+
+    return new Lid();
+})
\ No newline at end of file