<commit_before>var Ipc = require('ipc');
var Async = require('async');
var Url = require('fire-url');

Ipc.on('scene:ipc-messages', function ( ipcList ) {
    for ( var i = 0; i < ipcList.length; ++i ) {
        Ipc.emit.apply( Ipc, ipcList[i] );
    }
});

Ipc.on('scene:new-scene', function () {
    window.sceneView.newScene();
});

Ipc.on('scene:save-scene-from-page', function ( url ) {
    var sceneAsset = new cc.SceneAsset();
    sceneAsset.scene = cc.director.getScene();

    // NOTE: we stash scene because we want to save and reload the connected browser
    Editor.stashScene(function () {
        // reload connected browser
        Editor.sendToCore('app:reload-on-device');

        //
        Editor.sendToCore( 'scene:save-scene', url, Editor.serialize(sceneAsset) );
    });
});

Ipc.on('scene:open-scene-by-uuid', function ( uuid ) {
    window.sceneView.loadScene(uuid);
});

Ipc.on('scene:play-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:play-on-device' );
    });
});

Ipc.on('scene:reload-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:reload-on-device' );
    });
});

Ipc.on('scene:drop', function ( uuids, type, x, y ) {
    Editor.Selection.clear('node');
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    node.setPosition(window.sceneView.pixelToScene( cc.v2(x,y) ));
                    node.parent = cc.director.getScene();
                }

                next ( null, nodeID );
            },

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-nodes-by-uuids', function ( uuids, parentID ) {
    var parentNode;
    if ( parentID ) {
        parentNode = cc.engine.getInstanceById(parentID);
    }
    if ( !parentNode ) {
        parentNode = cc.director.getScene();
    }

    Editor.Selection.clear('node');

    //
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    if ( parentNode ) {
                        node.parent = parentNode;
                    }
                    var center_x = cc.game.canvas.width / 2;
                    var center_y = cc.game.canvas.height / 2;
                    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );
                }

                next ( null, nodeID );
            }

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-node-by-classid', function ( name, classID, referenceID, position ) {
    var parent;

    if ( referenceID ) {
        parent = cc.engine.getInstanceById(referenceID);
        if ( position === 'sibling' ) {
            parent = parent.parent;
        }
    }
    if ( !parent ) {
        parent = cc.director.getScene();
    }

    var node = new cc.ENode(name);
    node.parent = parent;

    var center_x = cc.game.canvas.width / 2;
    var center_y = cc.game.canvas.height / 2;
    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );

    cc.engine.repaintInEditMode();
    Editor.Selection.select('node', node.uuid, true, true );

    if (classID) {
        // add component
        var Component = cc.js._getClassById(classID);
        if (Component) {
            node.addComponent(Component);
        }
        else {
            Editor.error('Unknown node to create:', classID);
        }
    }
});

Ipc.on('scene:query-hierarchy', function ( queryID ) {
    if (!cc.engine.isInitialized) {
        return Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, '', [] );
    }
    var nodes = Editor.getHierarchyDump();
    var sceneUuid = cc.director.getScene().uuid;
    Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, sceneUuid, nodes );
});

Ipc.on('scene:query-node', function ( queryID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);
    var dump = Editor.getNodeDump(node);
    dump = JSON.stringify(dump);    // 改成发送字符串，以免字典的顺序发生改变
    Editor.sendToWindows( 'scene:reply-query-node', queryID, dump );
});

Ipc.on('scene:query-node-info', function ( sessionID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);

    Editor.sendToWindows( 'scene:query-node-info:reply', sessionID, {
        name: node ? node.name : '',
        type: cc.js.getClassName(node),
        missed: node ? false : true,
    });
});

Ipc.on('scene:node-new-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        try {
            var id = info.type;
            var ctor;
            if (cc.js._isTempClassId(id)) {
                ctor = cc.js._getClassById(id);
            }
            else {
                ctor = cc.js.getClassByName(id);
            }
            if ( ctor ) {
                var obj;
                try {
                    obj = new ctor();
                }
                catch (e) {
                    Editor.error('Can not create new info.type directly.\nInner message: ' + e.stack);
                    return;
                }
                Editor.setDeepPropertyByPath(nodeOrComp, info.path, obj, info.type);
                cc.engine.repaintInEditMode();
            }
        }
        catch (e) {
            Editor.warn('Failed to new property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:node-set-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        // 兼容旧版 Inspector
        if (info.mixinType) {
            nodeOrComp = nodeOrComp.getComponent(info.mixinType);
            if (!cc.isValid(nodeOrComp)) {
                return;
            }
        }
        //
        try {
            Editor.setPropertyByPath(nodeOrComp, info.path, info.value, info.type);
            cc.engine.repaintInEditMode();
        }
        catch (e) {
            Editor.warn('Failed to set property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:component-add', function ( id, uuid ) {
    if (uuid && Editor.isUuid(uuid)) {
        // check script
        var className = Editor.compressUuid(uuid);
        var Comp = cc.js._getClassById(className);
        if (!Comp) {
            return Editor.error('Can not find cc.Component in the script "%s".', uuid);
        }
        //
        var node = cc.engine.getInstanceById(id);
        if (node) {
            node.addComponent(Comp);
        }
        else {
            Editor.error('Can not find node to add component: %s', id);
        }
    }
    else {
        Editor.error('invalid script to add component');
    }
});

Ipc.on('scene:component-remove', function ( id, className ) {
    var node = cc.engine.getInstanceById(id);
    if (node) {
        node.getComponent(className).destroy();
    }
});

function getSiblingIndex (node) {
    return node._parent._children.indexOf(node);
}

Ipc.on('scene:move-nodes', function ( ids, parentID, nextSiblingId ) {
    var parent;

    if (parentID)
        parent = cc.engine.getInstanceById(parentID);
    else
        parent = cc.director.getScene();

    var next = nextSiblingId ? cc.engine.getInstanceById(nextSiblingId) : null;
    var nextIndex = next ? getSiblingIndex(next) : -1;

    for (var i = 0; i < ids.length; i++) {
        var id = ids[i];
        var node = cc.engine.getInstanceById(id);
        if (node && (!parent || !parent.isChildOf(node))) {
            if (node.parent !== parent) {
                // keep world transform not changed
                var worldPos = node.worldPosition;
                var worldRotation = node.worldRotation;
                var lossyScale = node.worldScale;

                node.parent = parent;

                // restore world transform
                node.worldPosition = worldPos;
                node.worldRotation = worldRotation;
                if (parent) {
                    node.scale = lossyScale.divSelf(parent.worldScale);
                }
                else {
                    node.scale = lossyScale;
                }

                if (next) {
                    node.setSiblingIndex(nextIndex);
                    ++nextIndex;
                }
            }
            else if (next) {
                var lastIndex = getSiblingIndex(node);
                var newIndex = nextIndex;
                if (newIndex > lastIndex) {
                    --newIndex;
                }
                if (newIndex !== lastIndex) {
                    node.setSiblingIndex(newIndex);
                    if (lastIndex > newIndex) {
                        ++nextIndex;
                    }
                    else {
                        --nextIndex;
                    }
                }
            }
            else {
                // move to bottom
                node.setSiblingIndex(-1);
            }
        }
    }
});

Ipc.on('scene:delete-nodes', function ( ids ) {
    window.sceneView.delete(ids);
});

Ipc.on('scene:duplicate-nodes', function ( ids ) {
    var nodes = [];
    for ( var i = 0; i < ids.length; ++i ) {
         var node = cc.engine.getInstanceById(ids[i]);
        if (node) {
            nodes.push(node);
        }
    }

    // get top-level wrappers
    var results = Editor.Utils.arrayCmpFilter ( nodes, function ( a, b ) {
        if (a === b) {
            return 0;
        }

        if (b.isChildOf(a)) {
            return 1;
        }

        if (a.isChildOf(b)) {
            return -1;
        }

        return 0;
    });

    // duplicate results
    var clones = [];
    results.forEach(function ( node ) {
        var clone = cc.instantiate(node);
        clone.parent = node.parent;

        clones.push(clone.uuid);
    });

    // select the last one
    Editor.Selection.select('node', clones);
});

Ipc.on('scene:stash-and-reload', function () {
    Editor.stashScene(function () {
        Ipc.sendToHost('scene:ask-for-reload');
    });
});

Ipc.on('scene:soft-reload', function (compiled) {
    Editor.softReload(compiled);
});

Ipc.on('selection:activated', function ( type, id ) {
    if ( type !== 'node' || !id ) {
        return;
    }

    window.sceneView.activate(id);
});

Ipc.on('selection:deactivated', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }

    window.sceneView.deactivate(id);
});

Ipc.on('selection:selected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.select(ids);
});

Ipc.on('selection:unselected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.unselect(ids);
});

Ipc.on('selection:hoverin', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverin(id);
});

Ipc.on('selection:hoverout', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverout(id);
});

Ipc.on('scene:init-scene-view', function ( settings ) {
    window.sceneView.$.gizmosView.transformTool = settings.transformTool;
    window.sceneView.$.gizmosView.coordinate = settings.coordinate;
    window.sceneView.$.gizmosView.pivot = settings.pivot;
    window.sceneView.$.gizmosView.designSize = [settings.designWidth, settings.designHeight];
});

Ipc.on('scene:transform-tool-changed', function ( value ) {
    window.sceneView.$.gizmosView.transformTool = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:coordinate-changed', function ( value ) {
    window.sceneView.$.gizmosView.coordinate = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:pivot-changed', function ( value ) {
    window.sceneView.$.gizmosView.pivot = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:design-size-changed', function ( w, h ) {
    window.sceneView.$.gizmosView.designSize = [w, h];
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:create-prefab', function ( id, baseUrl ) {
    var node = cc.engine.getInstanceById(id);
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    var json = Editor.serialize(prefab);
    var url = Url.join(baseUrl, node.name + '.prefab');

    Editor.sendRequestToCore('scene:create-prefab', url, json, function (err, uuid) {
        if (!err) {
            Editor.PrefabUtils.savePrefabUuid(node, uuid);
        }
    });
});

Ipc.on('scene:apply-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    var uuid = node._prefab.asset._uuid;
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    Editor.PrefabUtils.savePrefabUuid(node, uuid);
    var json = Editor.serialize(prefab);

    Editor.sendToCore('scene:apply-prefab', uuid, json);
});

Ipc.on('scene:revert-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    Editor.PrefabUtils.revertPrefab(node);
});

<commit_msg>add ipc messages (fireball-x/fireball#476)<commit_after>var Ipc = require('ipc');
var Async = require('async');
var Url = require('fire-url');

Ipc.on('scene:ipc-messages', function ( ipcList ) {
    for ( var i = 0; i < ipcList.length; ++i ) {
        Ipc.emit.apply( Ipc, ipcList[i] );
    }
});

Ipc.on('scene:new-scene', function () {
    window.sceneView.newScene();
});

Ipc.on('scene:save-scene-from-page', function ( url ) {
    var sceneAsset = new cc.SceneAsset();
    sceneAsset.scene = cc.director.getScene();

    // NOTE: we stash scene because we want to save and reload the connected browser
    Editor.stashScene(function () {
        // reload connected browser
        Editor.sendToCore('app:reload-on-device');

        //
        Editor.sendToCore( 'scene:save-scene', url, Editor.serialize(sceneAsset) );
    });
});

Ipc.on('scene:open-scene-by-uuid', function ( uuid ) {
    window.sceneView.loadScene(uuid);
});

Ipc.on('scene:play-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:play-on-device' );
    });
});

Ipc.on('scene:reload-on-device', function () {
    Editor.stashScene( function () {
        Editor.sendToCore( 'app:reload-on-device' );
    });
});

Ipc.on('scene:drop', function ( uuids, type, x, y ) {
    Editor.Selection.clear('node');
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    node.setPosition(window.sceneView.pixelToScene( cc.v2(x,y) ));
                    node.parent = cc.director.getScene();
                }

                next ( null, nodeID );
            },

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-nodes-by-uuids', function ( uuids, parentID ) {
    var parentNode;
    if ( parentID ) {
        parentNode = cc.engine.getInstanceById(parentID);
    }
    if ( !parentNode ) {
        parentNode = cc.director.getScene();
    }

    Editor.Selection.clear('node');

    //
    Async.each( uuids, function ( uuid, done ) {
        Async.waterfall([
            function ( next ) {
                Editor.createNode(uuid, next);
            },

            function ( node, next ) {
                var nodeID;
                if ( node ) {
                    nodeID = node.uuid;

                    if ( parentNode ) {
                        node.parent = parentNode;
                    }
                    var center_x = cc.game.canvas.width / 2;
                    var center_y = cc.game.canvas.height / 2;
                    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );
                }

                next ( null, nodeID );
            }

        ], function ( err, nodeID ) {
            if ( err ) {
                Editor.failed( 'Failed to drop asset %s, message: %s', uuid, err.stack || err.errorMessage );
                return;
            }

            if ( nodeID ) {
                Editor.Selection.select('node', nodeID, false, true );
            }
            cc.engine.repaintInEditMode();
            done();
        });
    });
});

Ipc.on('scene:create-node-by-classid', function ( name, classID, referenceID, position ) {
    var parent;

    if ( referenceID ) {
        parent = cc.engine.getInstanceById(referenceID);
        if ( position === 'sibling' ) {
            parent = parent.parent;
        }
    }
    if ( !parent ) {
        parent = cc.director.getScene();
    }

    var node = new cc.ENode(name);
    node.parent = parent;

    var center_x = cc.game.canvas.width / 2;
    var center_y = cc.game.canvas.height / 2;
    node.scenePosition = window.sceneView.pixelToScene( cc.v2(center_x, center_y) );

    cc.engine.repaintInEditMode();
    Editor.Selection.select('node', node.uuid, true, true );

    if (classID) {
        // add component
        var Component = cc.js._getClassById(classID);
        if (Component) {
            node.addComponent(Component);
        }
        else {
            Editor.error('Unknown node to create:', classID);
        }
    }
});

Ipc.on('scene:query-hierarchy', function ( queryID ) {
    if (!cc.engine.isInitialized) {
        return Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, '', [] );
    }
    var nodes = Editor.getHierarchyDump();
    var sceneUuid = cc.director.getScene().uuid;
    Editor.sendToWindows( 'scene:reply-query-hierarchy', queryID, sceneUuid, nodes );
});

Ipc.on('scene:query-node', function ( queryID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);
    var dump = Editor.getNodeDump(node);
    dump = JSON.stringify(dump);    // 改成发送字符串，以免字典的顺序发生改变
    Editor.sendToWindows( 'scene:reply-query-node', queryID, dump );
});

Ipc.on('scene:query-animation-node', function (queryID, nodeID, childName) {
    var node = cc.engine.getInstanceById(nodeID);
    var dump = Editor.getAnimationNodeDump(node, childName);
    Editor.sendToWindows( 'scene:reply-animation-node', queryID, dump );
});

Ipc.on('scene:query-node-info', function ( sessionID, nodeID ) {
    var node = cc.engine.getInstanceById(nodeID);

    Editor.sendToWindows( 'scene:query-node-info:reply', sessionID, {
        name: node ? node.name : '',
        type: cc.js.getClassName(node),
        missed: node ? false : true,
    });
});

Ipc.on('scene:node-new-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        try {
            var id = info.type;
            var ctor;
            if (cc.js._isTempClassId(id)) {
                ctor = cc.js._getClassById(id);
            }
            else {
                ctor = cc.js.getClassByName(id);
            }
            if ( ctor ) {
                var obj;
                try {
                    obj = new ctor();
                }
                catch (e) {
                    Editor.error('Can not create new info.type directly.\nInner message: ' + e.stack);
                    return;
                }
                Editor.setDeepPropertyByPath(nodeOrComp, info.path, obj, info.type);
                cc.engine.repaintInEditMode();
            }
        }
        catch (e) {
            Editor.warn('Failed to new property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:node-set-property', function ( info ) {
    var nodeOrComp = cc.engine.getInstanceById(info.id);
    if (nodeOrComp) {
        // 兼容旧版 Inspector
        if (info.mixinType) {
            nodeOrComp = nodeOrComp.getComponent(info.mixinType);
            if (!cc.isValid(nodeOrComp)) {
                return;
            }
        }
        //
        try {
            Editor.setPropertyByPath(nodeOrComp, info.path, info.value, info.type);
            cc.engine.repaintInEditMode();
        }
        catch (e) {
            Editor.warn('Failed to set property %s of %s to %s, ' + e.message,
                info.path, nodeOrComp.name, info.value);
        }
    }
});

Ipc.on('scene:component-add', function ( id, uuid ) {
    if (uuid && Editor.isUuid(uuid)) {
        // check script
        var className = Editor.compressUuid(uuid);
        var Comp = cc.js._getClassById(className);
        if (!Comp) {
            return Editor.error('Can not find cc.Component in the script "%s".', uuid);
        }
        //
        var node = cc.engine.getInstanceById(id);
        if (node) {
            node.addComponent(Comp);
        }
        else {
            Editor.error('Can not find node to add component: %s', id);
        }
    }
    else {
        Editor.error('invalid script to add component');
    }
});

Ipc.on('scene:component-remove', function ( id, className ) {
    var node = cc.engine.getInstanceById(id);
    if (node) {
        node.getComponent(className).destroy();
    }
});

function getSiblingIndex (node) {
    return node._parent._children.indexOf(node);
}

Ipc.on('scene:move-nodes', function ( ids, parentID, nextSiblingId ) {
    var parent;

    if (parentID)
        parent = cc.engine.getInstanceById(parentID);
    else
        parent = cc.director.getScene();

    var next = nextSiblingId ? cc.engine.getInstanceById(nextSiblingId) : null;
    var nextIndex = next ? getSiblingIndex(next) : -1;

    for (var i = 0; i < ids.length; i++) {
        var id = ids[i];
        var node = cc.engine.getInstanceById(id);
        if (node && (!parent || !parent.isChildOf(node))) {
            if (node.parent !== parent) {
                // keep world transform not changed
                var worldPos = node.worldPosition;
                var worldRotation = node.worldRotation;
                var lossyScale = node.worldScale;

                node.parent = parent;

                // restore world transform
                node.worldPosition = worldPos;
                node.worldRotation = worldRotation;
                if (parent) {
                    node.scale = lossyScale.divSelf(parent.worldScale);
                }
                else {
                    node.scale = lossyScale;
                }

                if (next) {
                    node.setSiblingIndex(nextIndex);
                    ++nextIndex;
                }
            }
            else if (next) {
                var lastIndex = getSiblingIndex(node);
                var newIndex = nextIndex;
                if (newIndex > lastIndex) {
                    --newIndex;
                }
                if (newIndex !== lastIndex) {
                    node.setSiblingIndex(newIndex);
                    if (lastIndex > newIndex) {
                        ++nextIndex;
                    }
                    else {
                        --nextIndex;
                    }
                }
            }
            else {
                // move to bottom
                node.setSiblingIndex(-1);
            }
        }
    }
});

Ipc.on('scene:delete-nodes', function ( ids ) {
    window.sceneView.delete(ids);
});

Ipc.on('scene:duplicate-nodes', function ( ids ) {
    var nodes = [];
    for ( var i = 0; i < ids.length; ++i ) {
         var node = cc.engine.getInstanceById(ids[i]);
        if (node) {
            nodes.push(node);
        }
    }

    // get top-level wrappers
    var results = Editor.Utils.arrayCmpFilter ( nodes, function ( a, b ) {
        if (a === b) {
            return 0;
        }

        if (b.isChildOf(a)) {
            return 1;
        }

        if (a.isChildOf(b)) {
            return -1;
        }

        return 0;
    });

    // duplicate results
    var clones = [];
    results.forEach(function ( node ) {
        var clone = cc.instantiate(node);
        clone.parent = node.parent;

        clones.push(clone.uuid);
    });

    // select the last one
    Editor.Selection.select('node', clones);
});

Ipc.on('scene:stash-and-reload', function () {
    Editor.stashScene(function () {
        Ipc.sendToHost('scene:ask-for-reload');
    });
});

Ipc.on('scene:soft-reload', function (compiled) {
    Editor.softReload(compiled);
});

Ipc.on('selection:activated', function ( type, id ) {
    if ( type !== 'node' || !id ) {
        return;
    }

    var node = cc.engine.getInstanceById(id);
    if (node) {
        var animationNode = node;
        var isAnimationNode = false;

        while (animationNode && !(animationNode instanceof cc.EScene)) {
            isAnimationNode = animationNode.getComponent(cc.AnimationComponent);
            if (isAnimationNode) {
                var dump = Editor.getAnimationNodeDump(animationNode);
                Editor.sendToWindows('scene:animation-node-activated', dump);
                break;
            }

            animationNode = animationNode.parent;
        }
    }

    window.sceneView.activate(id);
});

Ipc.on('selection:deactivated', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }

    window.sceneView.deactivate(id);
});

Ipc.on('selection:selected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.select(ids);
});

Ipc.on('selection:unselected', function ( type, ids ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.unselect(ids);
});

Ipc.on('selection:hoverin', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverin(id);
});

Ipc.on('selection:hoverout', function ( type, id ) {
    if ( type !== 'node' ) {
        return;
    }
    window.sceneView.hoverout(id);
});

Ipc.on('scene:init-scene-view', function ( settings ) {
    window.sceneView.$.gizmosView.transformTool = settings.transformTool;
    window.sceneView.$.gizmosView.coordinate = settings.coordinate;
    window.sceneView.$.gizmosView.pivot = settings.pivot;
    window.sceneView.$.gizmosView.designSize = [settings.designWidth, settings.designHeight];
});

Ipc.on('scene:transform-tool-changed', function ( value ) {
    window.sceneView.$.gizmosView.transformTool = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:coordinate-changed', function ( value ) {
    window.sceneView.$.gizmosView.coordinate = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:pivot-changed', function ( value ) {
    window.sceneView.$.gizmosView.pivot = value;
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:design-size-changed', function ( w, h ) {
    window.sceneView.$.gizmosView.designSize = [w, h];
    cc.engine.repaintInEditMode();
});

Ipc.on('scene:create-prefab', function ( id, baseUrl ) {
    var node = cc.engine.getInstanceById(id);
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    var json = Editor.serialize(prefab);
    var url = Url.join(baseUrl, node.name + '.prefab');

    Editor.sendRequestToCore('scene:create-prefab', url, json, function (err, uuid) {
        if (!err) {
            Editor.PrefabUtils.savePrefabUuid(node, uuid);
        }
    });
});

Ipc.on('scene:apply-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    var uuid = node._prefab.asset._uuid;
    var prefab = Editor.PrefabUtils.createPrefabFrom(node);
    Editor.PrefabUtils.savePrefabUuid(node, uuid);
    var json = Editor.serialize(prefab);

    Editor.sendToCore('scene:apply-prefab', uuid, json);
});

Ipc.on('scene:revert-prefab', function ( id ) {
    var node = cc.engine.getInstanceById(id);
    if (!node || !node._prefab) {
        return;
    }

    node = node._prefab.root;
    Editor.PrefabUtils.revertPrefab(node);
});

<|endoftext|>


<commit_before>angular.module('shopper.home', [
    'ui.router'
])
.config(function config($stateProvider ) {
    $stateProvider.state('home', {
        url: '/home',
        views: {
            'main': {
                controller: 'HomeCtrl',
                templateUrl: 'home/home.tpl.html'
            }
        }
    });
})
.controller('HomeCtrl', function($scope, $rootScope, $timeout, $translate, $window, HomeService) {
    $scope.$on('bodyClicked', function(scope, event) {
        var productSearchQueryKey = 'productSearchQuery';
        if ([
                productSearchQueryKey,
                'add-custom-product'
            ].indexOf(event.target.id !== -1))
            return;
        $scope[productSearchQueryKey] = '';
    });

    $scope.$on('updateAllProducts', function(scope, data) {
        $scope.allProducts = data;
    });

    $scope.$on('updateLists', function(scope, data) {
        $scope.lists = data;
    });

    $scope.$on('goToFirstList', function(scope) {
        if ($scope.currentListIndex > 0) {
            $scope.currentListIndex--;
        }
    });

    $scope.$on('hideListDetail', function(scope) {
        $scope.showMe = true;
    });

    $scope.$watch('currentListIndex', function(newValue) {
        if ($scope.lists[newValue]) {
            localStorage.lastListId = $scope.lists[newValue].id;
        }
    });

    $scope.refresh = function(initialLoad) {
        var allProductsSorted = [];
        var allProductsClean = JSON.parse(angular.toJson($scope.allProducts));
        for (var i = 0; i < allProductsClean.length; i++) {
            var arrayOfSortedKeyValues = [];
            var keys = Object.keys(allProductsClean[i]).sort();
            for (var j = 0; j < keys.length; j++) {
                arrayOfSortedKeyValues.push(allProductsClean[i][keys[j]]);
            }
            allProductsSorted.push(arrayOfSortedKeyValues);
        }
        var allProductsSortedJsonString = JSON.stringify(allProductsSorted);
        HomeService.getAllProducts(SparkMD5.hash(allProductsSortedJsonString));

        var listsClean = JSON.parse(angular.toJson($scope.lists));
        var listsStringified = JSON.stringify(listsClean);
        HomeService.getListsWithProductsOfUser(SparkMD5.hash(listsStringified)).then(function() {
            if (initialLoad) {
                $timeout(function() {
                    if (localStorage.lastListId) {
                        for (var i = 0; i < $scope.lists.length; i++) {
                            if ($scope.lists[i].id.toString() === localStorage.lastListId) {
                                $scope.currentListIndex = i;
                                break;
                            }
                        }
                    }
                });
            }
        });

        $timeout(function() {
            $scope.refresh();
        }, 1500);
    };

    $scope.addCustomProductToList = function(name) {
        if (name.trim() === '')
            return;

        HomeService.addCustomProductToList($scope.capitalizeString(name), $scope.lists[$scope.currentListIndex]).success(function(data) {
            $scope.refresh();
        });

        $scope.productSearchQuery = '';
    };

    $scope.isProductInList = function(product) {
        if (getCurrentList() === undefined) {
            return false;
        }

        for (var i = 0; i < getCurrentList().products.length; i++) {
            if (product.id === getCurrentList().products[i].id) {
                return true;
            }
        }
        return false;
    };

    $scope.addProductToList = function(product) {
        if ($scope.isProductInList(product))
            return;

        HomeService.addProductToList(product, getCurrentList()).then(function() {
            $scope.refresh();
        });

        $scope.productSearchQuery = '';
    };

    $scope.changeActiveStateOfProductFromList = function(product, active) {
        HomeService.changeActiveStateOfProductFromList(product, getCurrentList(), active);
        getCurrentList().products[getCurrentList().products.indexOf(product)].disabled = true;
    };

    $scope.addList = function() {
        $translate('WHAT_SHOULD_WE_CALL_IT').then(function(translation) {
            var name = prompt(translation);
            if (! name)
                return;
            HomeService.addList(name).success(function(data) {
                HomeService.getListsWithProductsOfUser().success(function() {
                    $timeout(function() {
                        $scope.currentListIndex = $scope.lists.length - 1;
                    });
                });
            });
        });

    };

    $scope.editList = function(index) {
        $scope.showMe = false;
        $rootScope.$broadcast('showListDetail', $scope.lists[index]);
    };

    $scope.editComment = function (product, list) {
        $translate('CHANGE_COMMENT').then(function(translation) {
            $timeout(function() {
                var oldComment = (typeof product.comment === 'string') ? product.comment : '';
                var newComment = $window.prompt(translation, oldComment);
                if (newComment === null || newComment === oldComment)
                    return;
                product.disabled = true;
                HomeService.changeComment(product, list, newComment).then(function () {
                    $scope.refresh();
                });
            }, 0);
        });
    };

    $scope.moveListOnePosition = function(direction) {
        var currentListIndex = $scope.currentListIndex;
        var otherListIndex = $scope.currentListIndex + direction;

        if (otherListIndex < 0 || otherListIndex > $scope.lists.length - 1) {
            return;
        }

        $timeout(function() {
            $scope.currentListIndex = otherListIndex;
        });
        var otherList = $scope.lists[otherListIndex];
        $scope.lists[otherListIndex] = $scope.lists[currentListIndex];
        $scope.lists[currentListIndex] = otherList;

        HomeService.moveListOnePosition($scope.lists[otherListIndex].id, direction);
    };

    $scope.capitalizeString = function(str) {
        if (typeof str === 'string') {
            return str.charAt(0).toUpperCase() + str.slice(1);
        }
        return '';
    };

    function getCurrentList() {
        return $scope.lists[$scope.currentListIndex];
    }

    $scope.showMe = true;
    $scope.lists = [];
    $scope.allProducts = [];
    $scope.currentListIndex = 0;
    $scope.refresh(true);
})
.service('HomeService', function($http, $rootScope, Api, Session) {
    this.getAllProducts = function(hash) {
        var params = Api.getParams();
        params.cmd = 'get_all_products';
        params.user_id = Session.user.id;
        params.hash = hash;

        $http.get(Api.url, { params: params }).success(function(data) {
            if (data !== 'null')
                $rootScope.$broadcast('updateAllProducts', data);
        });
    };

    this.getListsWithProductsOfUser = function(hash) {
        var params = Api.getParams();
        params.cmd = 'get_lists_with_products_of_user';
        params.user_id = Session.user.id;
        params.hash = hash;

        return $http.get(Api.url, { params: params }).success(function(data) {
            if (data !== 'null')
                $rootScope.$broadcast('updateLists', data);
        });
    };

    this.addProductToList = function(product, list) {
        var params = Api.getParams();
        params.cmd = 'add_product_to_list';
        params.product_id = product.id;
        params.list_id = list.id;
        params.comment = product.comment;
        return $http.get(Api.url, { params: params });
    };

    this.addCustomProductToList = function(name, list) {
        var params = Api.getParams();
        params.cmd = 'add_custom_product_to_list';
        params.name = name;
        params.list_id = list.id;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };

    this.changeActiveStateOfProductFromList = function (product, list, active) {
        var params = Api.getParams();
        params.cmd = 'change_active_state_of_product_from_list';
        params.product_id = product.id;
        params.list_id = list.id;
        params.active = active;
        return $http.get(Api.url, { params: params });
    };

    this.addList = function(name) {
        var params = Api.getParams();
        params.cmd = 'add_list';
        params.name = name;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };

    this.moveListOnePosition = function(list_id, direction) {
        var params = Api.getParams();
        params.cmd = 'move_list_one_position';
        params.list_id = list_id;
        params.direction = direction;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };

    this.changeComment = function (product, list, comment) {
        var params = Api.getParams();
        params.cmd = 'change_comment';
        params.product_id = product.id;
        params.list_id = list.id;
        params.comment = comment;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };
})
.filter('productsFilter', function () {
    function fetchComment(query, pattern) {
        if (query.indexOf(' ' + pattern) !== -1)
            pattern = ' ' + pattern;
        return query.replace(pattern, '');
    }

    return function(items, query) {
        if (query === undefined || query === '')
            return items;

        var i, j, filteredItems = [];
        query = query.toLowerCase();

        for (i = 0; i < items.length; i++) {
            var itemName = items[i].name.toLowerCase();

            if (query.indexOf(itemName) !== -1) {
                items[i].comment = fetchComment(query, itemName);
                filteredItems.push(items[i]);
                continue;
            }

            var queryTokens = query.split(' ');
            for (j = 1; j <= queryTokens.length; j++) {
                var pattern = queryTokens.slice(-j).join(' ');
                if (itemName.startsWith(pattern)) {
                    items[i].comment = fetchComment(query, pattern);
                    filteredItems.push(items[i]);
                    break;
                }
            }
        }

        return filteredItems;
    };
})
;
<commit_msg>Bugfix: Products where always shown as addable, because there were not checks whether the product in the list was active or not<commit_after>angular.module('shopper.home', [
    'ui.router'
])
.config(function config($stateProvider ) {
    $stateProvider.state('home', {
        url: '/home',
        views: {
            'main': {
                controller: 'HomeCtrl',
                templateUrl: 'home/home.tpl.html'
            }
        }
    });
})
.controller('HomeCtrl', function($scope, $rootScope, $timeout, $translate, $window, HomeService) {
    $scope.$on('bodyClicked', function(scope, event) {
        var productSearchQueryKey = 'productSearchQuery';
        if ([
                productSearchQueryKey,
                'add-custom-product'
            ].indexOf(event.target.id !== -1))
            return;
        $scope[productSearchQueryKey] = '';
    });

    $scope.$on('updateAllProducts', function(scope, data) {
        $scope.allProducts = data;
    });

    $scope.$on('updateLists', function(scope, data) {
        $scope.lists = data;
    });

    $scope.$on('goToFirstList', function(scope) {
        if ($scope.currentListIndex > 0) {
            $scope.currentListIndex--;
        }
    });

    $scope.$on('hideListDetail', function(scope) {
        $scope.showMe = true;
    });

    $scope.$watch('currentListIndex', function(newValue) {
        if ($scope.lists[newValue]) {
            localStorage.lastListId = $scope.lists[newValue].id;
        }
    });

    $scope.refresh = function(initialLoad) {
        var allProductsSorted = [];
        var allProductsClean = JSON.parse(angular.toJson($scope.allProducts));
        for (var i = 0; i < allProductsClean.length; i++) {
            var arrayOfSortedKeyValues = [];
            var keys = Object.keys(allProductsClean[i]).sort();
            for (var j = 0; j < keys.length; j++) {
                arrayOfSortedKeyValues.push(allProductsClean[i][keys[j]]);
            }
            allProductsSorted.push(arrayOfSortedKeyValues);
        }
        var allProductsSortedJsonString = JSON.stringify(allProductsSorted);
        HomeService.getAllProducts(SparkMD5.hash(allProductsSortedJsonString));

        var listsClean = JSON.parse(angular.toJson($scope.lists));
        var listsStringified = JSON.stringify(listsClean);
        HomeService.getListsWithProductsOfUser(SparkMD5.hash(listsStringified)).then(function() {
            if (initialLoad) {
                $timeout(function() {
                    if (localStorage.lastListId) {
                        for (var i = 0; i < $scope.lists.length; i++) {
                            if ($scope.lists[i].id.toString() === localStorage.lastListId) {
                                $scope.currentListIndex = i;
                                break;
                            }
                        }
                    }
                });
            }
        });

        $timeout(function() {
            $scope.refresh();
        }, 1500);
    };

    $scope.addCustomProductToList = function(name) {
        if (name.trim() === '')
            return;

        HomeService.addCustomProductToList($scope.capitalizeString(name), $scope.lists[$scope.currentListIndex]).success(function(data) {
            $scope.refresh();
        });

        $scope.productSearchQuery = '';
    };

    $scope.isProductInList = function(product) {
        if (getCurrentList() === undefined) {
            return false;
        }

        for (var i = 0; i < getCurrentList().products.length; i++) {
            if (product.id === getCurrentList().products[i].id && getCurrentList().products[i].active) {
                return true;
            }
        }
        return false;
    };

    $scope.addProductToList = function(product) {
        if ($scope.isProductInList(product))
            return;

        HomeService.addProductToList(product, getCurrentList()).then(function() {
            $scope.refresh();
        });

        $scope.productSearchQuery = '';
    };

    $scope.changeActiveStateOfProductFromList = function(product, active) {
        HomeService.changeActiveStateOfProductFromList(product, getCurrentList(), active);
        getCurrentList().products[getCurrentList().products.indexOf(product)].disabled = true;
    };

    $scope.addList = function() {
        $translate('WHAT_SHOULD_WE_CALL_IT').then(function(translation) {
            var name = prompt(translation);
            if (! name)
                return;
            HomeService.addList(name).success(function(data) {
                HomeService.getListsWithProductsOfUser().success(function() {
                    $timeout(function() {
                        $scope.currentListIndex = $scope.lists.length - 1;
                    });
                });
            });
        });

    };

    $scope.editList = function(index) {
        $scope.showMe = false;
        $rootScope.$broadcast('showListDetail', $scope.lists[index]);
    };

    $scope.editComment = function (product, list) {
        $translate('CHANGE_COMMENT').then(function(translation) {
            $timeout(function() {
                var oldComment = (typeof product.comment === 'string') ? product.comment : '';
                var newComment = $window.prompt(translation, oldComment);
                if (newComment === null || newComment === oldComment)
                    return;
                product.disabled = true;
                HomeService.changeComment(product, list, newComment).then(function () {
                    $scope.refresh();
                });
            }, 0);
        });
    };

    $scope.moveListOnePosition = function(direction) {
        var currentListIndex = $scope.currentListIndex;
        var otherListIndex = $scope.currentListIndex + direction;

        if (otherListIndex < 0 || otherListIndex > $scope.lists.length - 1) {
            return;
        }

        $timeout(function() {
            $scope.currentListIndex = otherListIndex;
        });
        var otherList = $scope.lists[otherListIndex];
        $scope.lists[otherListIndex] = $scope.lists[currentListIndex];
        $scope.lists[currentListIndex] = otherList;

        HomeService.moveListOnePosition($scope.lists[otherListIndex].id, direction);
    };

    $scope.capitalizeString = function(str) {
        if (typeof str === 'string') {
            return str.charAt(0).toUpperCase() + str.slice(1);
        }
        return '';
    };

    function getCurrentList() {
        return $scope.lists[$scope.currentListIndex];
    }

    $scope.showMe = true;
    $scope.lists = [];
    $scope.allProducts = [];
    $scope.currentListIndex = 0;
    $scope.refresh(true);
})
.service('HomeService', function($http, $rootScope, Api, Session) {
    this.getAllProducts = function(hash) {
        var params = Api.getParams();
        params.cmd = 'get_all_products';
        params.user_id = Session.user.id;
        params.hash = hash;

        $http.get(Api.url, { params: params }).success(function(data) {
            if (data !== 'null')
                $rootScope.$broadcast('updateAllProducts', data);
        });
    };

    this.getListsWithProductsOfUser = function(hash) {
        var params = Api.getParams();
        params.cmd = 'get_lists_with_products_of_user';
        params.user_id = Session.user.id;
        params.hash = hash;

        return $http.get(Api.url, { params: params }).success(function(data) {
            if (data !== 'null')
                $rootScope.$broadcast('updateLists', data);
        });
    };

    this.addProductToList = function(product, list) {
        var params = Api.getParams();
        params.cmd = 'add_product_to_list';
        params.product_id = product.id;
        params.list_id = list.id;
        params.comment = product.comment;
        return $http.get(Api.url, { params: params });
    };

    this.addCustomProductToList = function(name, list) {
        var params = Api.getParams();
        params.cmd = 'add_custom_product_to_list';
        params.name = name;
        params.list_id = list.id;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };

    this.changeActiveStateOfProductFromList = function (product, list, active) {
        var params = Api.getParams();
        params.cmd = 'change_active_state_of_product_from_list';
        params.product_id = product.id;
        params.list_id = list.id;
        params.active = active;
        return $http.get(Api.url, { params: params });
    };

    this.addList = function(name) {
        var params = Api.getParams();
        params.cmd = 'add_list';
        params.name = name;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };

    this.moveListOnePosition = function(list_id, direction) {
        var params = Api.getParams();
        params.cmd = 'move_list_one_position';
        params.list_id = list_id;
        params.direction = direction;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };

    this.changeComment = function (product, list, comment) {
        var params = Api.getParams();
        params.cmd = 'change_comment';
        params.product_id = product.id;
        params.list_id = list.id;
        params.comment = comment;
        params.user_id = Session.user.id;
        return $http.get(Api.url, { params: params });
    };
})
.filter('productsFilter', function () {
    function fetchComment(query, pattern) {
        if (query.indexOf(' ' + pattern) !== -1)
            pattern = ' ' + pattern;
        return query.replace(pattern, '');
    }

    return function(items, query) {
        if (query === undefined || query === '')
            return items;

        var i, j, filteredItems = [];
        query = query.toLowerCase();

        for (i = 0; i < items.length; i++) {
            var itemName = items[i].name.toLowerCase();

            if (query.indexOf(itemName) !== -1) {
                items[i].comment = fetchComment(query, itemName);
                filteredItems.push(items[i]);
                continue;
            }

            var queryTokens = query.split(' ');
            for (j = 1; j <= queryTokens.length; j++) {
                var pattern = queryTokens.slice(-j).join(' ');
                if (itemName.startsWith(pattern)) {
                    items[i].comment = fetchComment(query, pattern);
                    filteredItems.push(items[i]);
                    break;
                }
            }
        }

        return filteredItems;
    };
})
;
<|endoftext|>


<commit_before>var $ = require('jquery');

module.exports = {
  tableRowItems: function (first, second, cls) {
    return $('
')
      .addClass(cls)
      .append($('
').append(first))
      .append($('
').append(second));
  },

  tableRow: function (description, data) {
    return this.tableRowItems(
      $('').text(description),
      $('<input readonly="readonly"/>').val(data));
  },

  textRow: function (description, data, cls) {
    return this.tableRowItems(
      $('').text(description),
      $('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
      cls);
  },

  preRow: function (description, data) {
    return this.tableRowItems(
      $('').text(description),
      $('
').text(data)
    );
  },

  formatAssemblyText: function (asm, prefix, source) {
    var self = this;
    if (typeof asm === typeof '' || asm === null || asm === undefined) {
      return prefix + asm + '\n';
    }
    var text = prefix + '.code\n';
    $.each(asm['.code'], function (i, item) {
      var v = item.value === undefined ? '' : item.value;
      var src = '';
      if (item.begin !== undefined && item.end !== undefined) {
        src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
      }
      if (src.length > 30) {
        src = src.slice(0, 30) + '...';
      }
      if (item.name !== 'tag') {
        text += '  ';
      }
      text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
    });
    text += prefix + '.data\n';
    if (asm['.data']) {
      $.each(asm['.data'], function (i, item) {
        text += '  ' + prefix + '' + i + ':\n';
        text += self.formatAssemblyText(item, prefix + '    ', source);
      });
    }
    return text;
  },

  gethDeploy: function (contractName, jsonInterface, bytecode) {
    var code = '';
    var funABI = this.getConstructorInterface(JSON.parse(jsonInterface));

    funABI.inputs.forEach(function (inp) {
      code += 'var ' + inp.name + ' = /* var of type ' + inp.type + ' here */ ;\n';
    });

    code += 'var ' + contractName + 'Contract = web3.eth.contract(' + jsonInterface.replace('\n', '') + ');' +
      '\nvar ' + contractName + ' = ' + contractName + 'Contract.new(';

    funABI.inputs.forEach(function (inp) {
      code += '\n   ' + inp.name + ',';
    });

    code += '\n   {' +
      '\n     from: web3.eth.accounts[0], ' +
      "\n     data: '" + bytecode + "', " +
      '\n     gas: 4700000' +
      '\n   }, function (e, contract){' +
      '\n    console.log(e, contract);' +
      "\n    if (typeof contract.address !== 'undefined') {" +
      "\n         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" +
      '\n    }' +
      '\n })';

    return code;
  },

  getConstructorInterface: function (abi) {
    var funABI = { 'name': '', 'inputs': [], 'type': 'constructor', 'outputs': [] };
    for (var i = 0; i < abi.length; i++) {
      if (abi[i].type === 'constructor') {
        funABI.inputs = abi[i].inputs || [];
        break;
      }
    }
    return funABI;
  },

  formatGasEstimates: function (data) {
    // FIXME: the whole gasEstimates object should be nil instead
    if (data.creation === undefined && data.external === undefined && data.internal === undefined) {
      return;
    }

    var gasToText = function (g) {
      return g === null ? 'unknown' : g;
    };

    var text = '';
    var fun;
    if ('creation' in data) {
      text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
    }

    if ('external' in data) {
      text += 'External:\n';
      for (fun in data.external) {
        text += '  ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
      }
    }

    if ('internal' in data) {
      text += 'Internal:\n';
      for (fun in data.internal) {
        text += '  ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
      }
    }
    return text;
  },

  detailsOpen: {},
  getDetails: function (contract, source, contractName) {
    var button = $('<button>Toggle Details</button>');
    var details = $('
')
      .append(this.tableRow('Solidity Interface', contract.solidity_interface));

    var funHashes = '';
    for (var fun in contract.functionHashes) {
      funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
    }
    details.append(this.preRow('Functions', funHashes));

    var gasEstimates = this.formatGasEstimates(contract.gasEstimates);
    if (gasEstimates) {
      details.append(this.preRow('Gas Estimates', gasEstimates));
    }

    if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0) {
      details.append(this.tableRow('Runtime Bytecode', contract.runtimeBytecode));
    }

    if (contract.opcodes !== '') {
      details.append(this.tableRow('Opcodes', contract.opcodes));
    }

    if (contract.assembly !== null) {
      details.append(this.preRow('Assembly', this.formatAssemblyText(contract.assembly, '', source)));
    }

    var self = this;
    button.click(function () {
      self.detailsOpen[contractName] = !self.detailsOpen[contractName];
      details.toggle();
    });
    if (this.detailsOpen[contractName]) {
      details.show();
    }
    return $('
').append(button).append(details);
  }
};
<commit_msg>Support missing opcodes field<commit_after>var $ = require('jquery');

module.exports = {
  tableRowItems: function (first, second, cls) {
    return $('
')
      .addClass(cls)
      .append($('
').append(first))
      .append($('
').append(second));
  },

  tableRow: function (description, data) {
    return this.tableRowItems(
      $('').text(description),
      $('<input readonly="readonly"/>').val(data));
  },

  textRow: function (description, data, cls) {
    return this.tableRowItems(
      $('').text(description),
      $('<textarea readonly="readonly" class="gethDeployText"/>').val(data),
      cls);
  },

  preRow: function (description, data) {
    return this.tableRowItems(
      $('').text(description),
      $('
').text(data)
    );
  },

  formatAssemblyText: function (asm, prefix, source) {
    var self = this;
    if (typeof asm === typeof '' || asm === null || asm === undefined) {
      return prefix + asm + '\n';
    }
    var text = prefix + '.code\n';
    $.each(asm['.code'], function (i, item) {
      var v = item.value === undefined ? '' : item.value;
      var src = '';
      if (item.begin !== undefined && item.end !== undefined) {
        src = source.slice(item.begin, item.end).replace('\n', '\\n', 'g');
      }
      if (src.length > 30) {
        src = src.slice(0, 30) + '...';
      }
      if (item.name !== 'tag') {
        text += '  ';
      }
      text += prefix + item.name + ' ' + v + '\t\t\t' + src + '\n';
    });
    text += prefix + '.data\n';
    if (asm['.data']) {
      $.each(asm['.data'], function (i, item) {
        text += '  ' + prefix + '' + i + ':\n';
        text += self.formatAssemblyText(item, prefix + '    ', source);
      });
    }
    return text;
  },

  gethDeploy: function (contractName, jsonInterface, bytecode) {
    var code = '';
    var funABI = this.getConstructorInterface(JSON.parse(jsonInterface));

    funABI.inputs.forEach(function (inp) {
      code += 'var ' + inp.name + ' = /* var of type ' + inp.type + ' here */ ;\n';
    });

    code += 'var ' + contractName + 'Contract = web3.eth.contract(' + jsonInterface.replace('\n', '') + ');' +
      '\nvar ' + contractName + ' = ' + contractName + 'Contract.new(';

    funABI.inputs.forEach(function (inp) {
      code += '\n   ' + inp.name + ',';
    });

    code += '\n   {' +
      '\n     from: web3.eth.accounts[0], ' +
      "\n     data: '" + bytecode + "', " +
      '\n     gas: 4700000' +
      '\n   }, function (e, contract){' +
      '\n    console.log(e, contract);' +
      "\n    if (typeof contract.address !== 'undefined') {" +
      "\n         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);" +
      '\n    }' +
      '\n })';

    return code;
  },

  getConstructorInterface: function (abi) {
    var funABI = { 'name': '', 'inputs': [], 'type': 'constructor', 'outputs': [] };
    for (var i = 0; i < abi.length; i++) {
      if (abi[i].type === 'constructor') {
        funABI.inputs = abi[i].inputs || [];
        break;
      }
    }
    return funABI;
  },

  formatGasEstimates: function (data) {
    // FIXME: the whole gasEstimates object should be nil instead
    if (data.creation === undefined && data.external === undefined && data.internal === undefined) {
      return;
    }

    var gasToText = function (g) {
      return g === null ? 'unknown' : g;
    };

    var text = '';
    var fun;
    if ('creation' in data) {
      text += 'Creation: ' + gasToText(data.creation[0]) + ' + ' + gasToText(data.creation[1]) + '\n';
    }

    if ('external' in data) {
      text += 'External:\n';
      for (fun in data.external) {
        text += '  ' + fun + ': ' + gasToText(data.external[fun]) + '\n';
      }
    }

    if ('internal' in data) {
      text += 'Internal:\n';
      for (fun in data.internal) {
        text += '  ' + fun + ': ' + gasToText(data.internal[fun]) + '\n';
      }
    }
    return text;
  },

  detailsOpen: {},
  getDetails: function (contract, source, contractName) {
    var button = $('<button>Toggle Details</button>');
    var details = $('
')
      .append(this.tableRow('Solidity Interface', contract.solidity_interface));

    var funHashes = '';
    for (var fun in contract.functionHashes) {
      funHashes += contract.functionHashes[fun] + ' ' + fun + '\n';
    }
    details.append(this.preRow('Functions', funHashes));

    var gasEstimates = this.formatGasEstimates(contract.gasEstimates);
    if (gasEstimates) {
      details.append(this.preRow('Gas Estimates', gasEstimates));
    }

    if (contract.runtimeBytecode && contract.runtimeBytecode.length > 0) {
      details.append(this.tableRow('Runtime Bytecode', contract.runtimeBytecode));
    }

    if (contract.opcodes !== undefined && contract.opcodes !== '') {
      details.append(this.tableRow('Opcodes', contract.opcodes));
    }

    if (contract.assembly !== null) {
      details.append(this.preRow('Assembly', this.formatAssemblyText(contract.assembly, '', source)));
    }

    var self = this;
    button.click(function () {
      self.detailsOpen[contractName] = !self.detailsOpen[contractName];
      details.toggle();
    });
    if (this.detailsOpen[contractName]) {
      details.show();
    }
    return $('
').append(button).append(details);
  }
};
<|endoftext|>


<commit_before>var Collider = require('../src/collider').Collider;
var Maths = Collider.Maths;

var mockObj = function(posX, posY, sizeX, sizeY, boundingBox) {
  return {
    pos: { x:posX, y:posY },
    size: { x:sizeX, y:sizeY },
    boundingBox: boundingBox
  };
};

describe('collider', function() {
  describe('maths', function() {
    describe('rectangleCorners', function() {
      it('should get corners of rect', function() {
        var obj = mockObj(5, 5, 10, 10);
        var corners = Maths.rectangleCorners(obj);
        expect(corners[0]).toEqual({ x:5, y:5 });
        expect(corners[1]).toEqual({ x:15, y:5 });
        expect(corners[2]).toEqual({ x:15, y:15 });
        expect(corners[3]).toEqual({ x:5, y:15 });
      });
    });

    describe('isLineIntersectingCircle', function() {
      it('should return false when circle and line intersect', function() {
        var obj = mockObj(5, 5, 10, 10);
        var intersecting = Maths.isLineIntersectingCircle(obj, { x:1, y:1 }, { x:20, y:20 });
        expect(intersecting).toEqual(true);
      });

      it('should return false when circle and line do not intersect', function() {
        var obj = mockObj(5, 5, 10, 10);
        var intersecting = Maths.isLineIntersectingCircle(obj, { x:1, y:1 }, { x:1, y:20 });
        expect(intersecting).toEqual(false);
      });
    });

    describe('circleAndRectangleIntersecting', function() {
      it('should return true when centres align', function() {
        var circle = mockObj(5, 5, 10, 10);
        var rectangle = mockObj(7, 7, 10, 10);
        var intersecting = Maths.circleAndRectangleIntersecting(circle, rectangle);
        expect(intersecting).toEqual(true);
      });

      it('should return true when circle and rect overlap a bit', function() {
        var circle = mockObj(5, 5, 10, 10);
        var rectangle = mockObj(7, 7, 10, 10);
        var intersecting = Maths.circleAndRectangleIntersecting(circle, rectangle);
        expect(intersecting).toEqual(true);
      });

      it('should return false when circle and rect do not intersect', function() {
        var circle = mockObj(5, 5, 10, 10);
        var rectangle = mockObj(16, 16, 10, 10);
        var intersecting = Maths.circleAndRectangleIntersecting(circle, rectangle);
        expect(intersecting).toEqual(false);
      });
    });

    describe('isIntersecting', function() {
      it('should use rect as default bounding box', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10);
        var obj2 = mockObj(15, 15, 10, 10);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      it('should return true for two rects that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10);
        var obj2 = mockObj(15, 15, 10, 10);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      it('should return false for two circles that are not colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10, collider.CIRCLE);
        var obj2 = mockObj(14, 14, 10, 10, collider.CIRCLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(false);
      });

      it('should return true for circ+rect that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10, collider.CIRCLE);
        var obj2 = mockObj(14, 14, 10, 10, collider.RECTANGLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(false);
      });

      it('should return true for point+rect that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
        var obj2 = mockObj(0, 0, 10, 10, collider.RECTANGLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      it('should return true for point+circ that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
        var obj2 = mockObj(0, 0, 10, 10, collider.CIRCLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      it('should throw when either obj has invalid bounding box', function() {
        var collider = new Collider();

        var obj1 = mockObj(5, 5, 1, 1, "la");
        var obj2 = mockObj(0, 0, 10, 10, collider.CIRCLE);
        expect(function() {
          collider.isIntersecting(obj1, obj2);
        }).toThrow();

        var obj1 = mockObj(5, 5, 1, 1, Collider.CIRCLE);
        var obj2 = mockObj(0, 0, 10, 10, "la");
        expect(function() {
          collider.isIntersecting(obj1, obj2);
        }).toThrow();
      });

      describe('object ordering', function() {
        it('should only return true when circle+rect in right order to collide', function() {
          var collider = new Collider();

          var obj1 = mockObj(33, 33, 10, 10, collider.CIRCLE);
          var obj2 = mockObj(5, 5, 30, 30, collider.RECTANGLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(true);

          // same dimensions, swap shape type and get no collision
          var obj1 = mockObj(33, 33, 10, 10, collider.RECTANGLE);
          var obj2 = mockObj(5, 5, 30, 30, collider.CIRCLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(false);
        });

        it('should only return true when point+rect in right order to collide', function() {
          var collider = new Collider();

          var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
          var obj2 = mockObj(0, 0, 10, 10, collider.RECTANGLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(true);

          // same dimensions, swap shape type and get no collision
          var obj1 = mockObj(5, 5, 1, 1, collider.RECTANGLE);
          var obj2 = mockObj(0, 0, 10, 10, collider.POINT);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(false);
        });

        it('should only return true when point+circ in right order to collide', function() {
          var collider = new Collider();

          var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
          var obj2 = mockObj(0, 0, 10, 10, collider.CIRCLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(true);

          // same dimensions, swap shape type and get no collision
          var obj1 = mockObj(5, 5, 1, 1, collider.CIRCLE);
          var obj2 = mockObj(0, 0, 10, 10, collider.POINT);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(false);
        });
      });
    });
  });
});
<commit_msg>rect/rect collision tests check all possibilities.<commit_after>var Collider = require('../src/collider').Collider;
var Maths = Collider.Maths;

var mockObj = function(posX, posY, sizeX, sizeY, boundingBox) {
  return {
    pos: { x:posX, y:posY },
    size: { x:sizeX, y:sizeY },
    boundingBox: boundingBox
  };
};

describe('collider', function() {
  describe('maths', function() {
    describe('rectangleCorners', function() {
      it('should get corners of rect', function() {
        var obj = mockObj(5, 5, 10, 10);
        var corners = Maths.rectangleCorners(obj);
        expect(corners[0]).toEqual({ x:5, y:5 });
        expect(corners[1]).toEqual({ x:15, y:5 });
        expect(corners[2]).toEqual({ x:15, y:15 });
        expect(corners[3]).toEqual({ x:5, y:15 });
      });
    });

    describe('isLineIntersectingCircle', function() {
      it('should return false when circle and line intersect', function() {
        var obj = mockObj(5, 5, 10, 10);
        var intersecting = Maths.isLineIntersectingCircle(obj, { x:1, y:1 }, { x:20, y:20 });
        expect(intersecting).toEqual(true);
      });

      it('should return false when circle and line do not intersect', function() {
        var obj = mockObj(5, 5, 10, 10);
        var intersecting = Maths.isLineIntersectingCircle(obj, { x:1, y:1 }, { x:1, y:20 });
        expect(intersecting).toEqual(false);
      });
    });

    describe('circleAndRectangleIntersecting', function() {
      it('should return true when centres align', function() {
        var circle = mockObj(5, 5, 10, 10);
        var rectangle = mockObj(7, 7, 10, 10);
        var intersecting = Maths.circleAndRectangleIntersecting(circle, rectangle);
        expect(intersecting).toEqual(true);
      });

      it('should return true when circle and rect overlap a bit', function() {
        var circle = mockObj(5, 5, 10, 10);
        var rectangle = mockObj(7, 7, 10, 10);
        var intersecting = Maths.circleAndRectangleIntersecting(circle, rectangle);
        expect(intersecting).toEqual(true);
      });

      it('should return false when circle and rect do not intersect', function() {
        var circle = mockObj(5, 5, 10, 10);
        var rectangle = mockObj(16, 16, 10, 10);
        var intersecting = Maths.circleAndRectangleIntersecting(circle, rectangle);
        expect(intersecting).toEqual(false);
      });
    });

    describe('isIntersecting', function() {
      it('should use rect as default bounding box', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10);
        var obj2 = mockObj(15, 15, 10, 10);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      describe('two rects', function() {
        describe('collisions', function() {
          it('should return true: bottom right corner over top left corner', function() {
            expect(new Collider().isIntersecting(mockObj(10, 10, 2, 4),
                                                 mockObj(12, 14, 4, 2))).toEqual(true);
          });

          it('should return true: bottom left corner over top right corner', function() {
            expect(new Collider().isIntersecting(mockObj(10, 10, 2, 4),
                                                 mockObj(6, 14, 4, 2))).toEqual(true);
          });

          it('should return true: top left corner over bottom right corner', function() {
            expect(new Collider().isIntersecting(mockObj(12, 14, 4, 2),
                                                 mockObj(10, 10, 2, 4))).toEqual(true);
          });

          it('should return true: top right corner over bottom left corner', function() {
            expect(new Collider().isIntersecting(mockObj(6, 14, 4, 2),
                                                 mockObj(10, 10, 2, 4))).toEqual(true);
          });
        });

        describe('non-collisions', function() {
          it('should return true: bottom right corner over top left corner', function() {
            expect(new Collider().isIntersecting(mockObj(10, 10, 2, 4),
                                                 mockObj(13, 14, 4, 2))).toEqual(false);
          });

          it('should return true: bottom left corner over top right corner', function() {
            expect(new Collider().isIntersecting(mockObj(10, 10, 2, 4),
                                                 mockObj(5, 14, 4, 2))).toEqual(false);
          });

          it('should return true: top left corner over bottom right corner', function() {
            expect(new Collider().isIntersecting(mockObj(13, 14, 4, 2),
                                                 mockObj(10, 10, 2, 4))).toEqual(false);
          });

          it('should return true: top right corner over bottom left corner', function() {
            expect(new Collider().isIntersecting(mockObj(5, 14, 4, 2),
                                                 mockObj(10, 10, 2, 4))).toEqual(false);
          });
        });
      });

      it('should return false for two circles that are not colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10, collider.CIRCLE);
        var obj2 = mockObj(14, 14, 10, 10, collider.CIRCLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(false);
      });

      it('should return true for circ+rect that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 10, 10, collider.CIRCLE);
        var obj2 = mockObj(14, 14, 10, 10, collider.RECTANGLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(false);
      });

      it('should return true for point+rect that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
        var obj2 = mockObj(0, 0, 10, 10, collider.RECTANGLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      it('should return true for point+circ that are colliding', function() {
        var collider = new Collider();
        var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
        var obj2 = mockObj(0, 0, 10, 10, collider.CIRCLE);
        var intersecting = collider.isIntersecting(obj1, obj2);
        expect(intersecting).toEqual(true);
      });

      it('should throw when either obj has invalid bounding box', function() {
        var collider = new Collider();

        var obj1 = mockObj(5, 5, 1, 1, "la");
        var obj2 = mockObj(0, 0, 10, 10, collider.CIRCLE);
        expect(function() {
          collider.isIntersecting(obj1, obj2);
        }).toThrow();

        var obj1 = mockObj(5, 5, 1, 1, Collider.CIRCLE);
        var obj2 = mockObj(0, 0, 10, 10, "la");
        expect(function() {
          collider.isIntersecting(obj1, obj2);
        }).toThrow();
      });

      describe('object ordering', function() {
        it('should only return true when circle+rect in right order to collide', function() {
          var collider = new Collider();

          var obj1 = mockObj(33, 33, 10, 10, collider.CIRCLE);
          var obj2 = mockObj(5, 5, 30, 30, collider.RECTANGLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(true);

          // same dimensions, swap shape type and get no collision
          var obj1 = mockObj(33, 33, 10, 10, collider.RECTANGLE);
          var obj2 = mockObj(5, 5, 30, 30, collider.CIRCLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(false);
        });

        it('should only return true when point+rect in right order to collide', function() {
          var collider = new Collider();

          var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
          var obj2 = mockObj(0, 0, 10, 10, collider.RECTANGLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(true);

          // same dimensions, swap shape type and get no collision
          var obj1 = mockObj(5, 5, 1, 1, collider.RECTANGLE);
          var obj2 = mockObj(0, 0, 10, 10, collider.POINT);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(false);
        });

        it('should only return true when point+circ in right order to collide', function() {
          var collider = new Collider();

          var obj1 = mockObj(5, 5, 1, 1, collider.POINT);
          var obj2 = mockObj(0, 0, 10, 10, collider.CIRCLE);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(true);

          // same dimensions, swap shape type and get no collision
          var obj1 = mockObj(5, 5, 1, 1, collider.CIRCLE);
          var obj2 = mockObj(0, 0, 10, 10, collider.POINT);
          expect(collider.isIntersecting(obj1, obj2)).toEqual(false);
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>Fire.Texture = (function () {

    /**
     * Class for texture handling.
     * Use this to create textures on the fly or to modify existing texture assets.
     *
     * @class Texture
     * @extends Asset
     * @constructor
     * @param {Image} [img] - the html image element to render
     */
    var Texture = Fire.extend('Fire.Texture', Fire.Asset, function () {
        var img = arguments[0];
        if (img) {
            this.image = img;
            this.width = img.width;
            this.height = img.height;
        }
    });

    /**
     * @class WrapMode
     * @static
     * @namespace Texture
     */
    Texture.WrapMode = Fire.defineEnum({
        /**
         * @property Repeat
         * @type number
         */
        Repeat: -1,
        /**
         * @property Clamp
         * @type number
         */
        Clamp: -1
    });

    /**
     * @class FilterMode
     * @static
     * @namespace Texture
     */
    Texture.FilterMode = Fire.defineEnum({
        /**
         * @property Point
         * @type number
         */
        Point: -1,
        /**
         * @property Bilinear
         * @type number
         */
        Bilinear: -1,
        /**
         * @property Trilinear
         * @type number
         */
        Trilinear: -1
    });

    /**
     * @class Texture
     */
    /**
     * @property image
     * @type Image
     */
    Texture.prop('image', null, Fire.RawType('image'), Fire.HideInInspector);
    /**
     * @property width
     * @type number
     */
    Texture.prop('width', 0, Fire.Integer_Obsoleted, Fire.ReadOnly);
    /**
     * @property height
     * @type number
     */
    Texture.prop('height', 0, Fire.Integer_Obsoleted, Fire.ReadOnly);
    /**
     * @property wrapMode
     * @type Texture.WrapMode
     */
    Texture.prop('wrapMode', Texture.WrapMode.Clamp, Fire.Enum(Texture.WrapMode), Fire.ReadOnly);
    /**
     * @property filterMode
     * @type Texture.FilterMode
     */
    Texture.prop('filterMode', Texture.FilterMode.Bilinear, Fire.Enum(Texture.FilterMode), Fire.ReadOnly);

    //Texture.prototype.onAfterDeserialize = function () {
    //    this.width = this.image.width;
    //    this.height = this.image.height;
    //};

    /**
     * Returns pixel color at coordinates (x, y).
     *
     * If the pixel coordinates are out of bounds (larger than width/height or small than 0),
     * they will be clamped or repeated based on the texture's wrap mode.
     *
     * @method getPixel
     * @param {number} x
     * @param {nmber} y
     * @return {Fire.Color}
     */
    Texture.prototype.getPixel = function (x, y) {
        if (!canvasCtxToGetPixel) {
            var canvas = document.createElement('canvas');
            canvas.width = 1;
            canvas.height = 1;
            canvasCtxToGetPixel = canvas.getContext('2d');
        }
        if (this.wrapMode === Texture.WrapMode.Clamp) {
            x = Math.clamp(x, 0, this.image.width);
            y = Math.clamp(y, 0, this.image.height);
        }
        else if (this.wrapMode === Texture.WrapMode.Repeat) {
            x = x % this.image.width;
            if (x < 0) {
                x += this.image.width
            }
            y = y % this.image.width;
            if (y < 0) {
                y += this.image.width
            }
        }
        canvasCtxToGetPixel.clearRect(0, 0, 1, 1);
        canvasCtxToGetPixel.drawImage(this.image, x, y, 1, 1, 0, 0, 1, 1);

        var imgBytes = null;
        try {
            imgBytes = canvasCtxToGetPixel.getImageData(0, 0, 1, 1).data;
        }
        catch (e) {
            Fire.error("An error has occurred. This is most likely due to security restrictions on reading canvas pixel data with local or cross-domain images.");
            return Fire.Color.transparent;
        }
        var result = new Fire.Color();
        result.r = imgBytes[0] / 255;
        result.g = imgBytes[1] / 255;
        result.b = imgBytes[2] / 255;
        result.a = imgBytes[3] / 255;
        return result;
    }

    return Texture;
})();

var canvasCtxToGetPixel = null;
<commit_msg>fix texture.js warning<commit_after>Fire.Texture = (function () {

    /**
     * Class for texture handling.
     * Use this to create textures on the fly or to modify existing texture assets.
     *
     * @class Texture
     * @extends Asset
     * @constructor
     * @param {Image} [img] - the html image element to render
     */
    var Texture = Fire.extend('Fire.Texture', Fire.Asset, function () {
        var img = arguments[0];
        if (img) {
            this.image = img;
            this.width = img.width;
            this.height = img.height;
        }
    });

    /**
     * @class WrapMode
     * @static
     * @namespace Texture
     */
    Texture.WrapMode = Fire.defineEnum({
        /**
         * @property Repeat
         * @type number
         */
        Repeat: -1,
        /**
         * @property Clamp
         * @type number
         */
        Clamp: -1
    });

    /**
     * @class FilterMode
     * @static
     * @namespace Texture
     */
    Texture.FilterMode = Fire.defineEnum({
        /**
         * @property Point
         * @type number
         */
        Point: -1,
        /**
         * @property Bilinear
         * @type number
         */
        Bilinear: -1,
        /**
         * @property Trilinear
         * @type number
         */
        Trilinear: -1
    });

    /**
     * @class Texture
     */
    /**
     * @property image
     * @type Image
     */
    Texture.prop('image', null, Fire.RawType('image'), Fire.HideInInspector);
    /**
     * @property width
     * @type number
     */
    Texture.prop('width', 0, Fire.Integer_Obsoleted, Fire.ReadOnly);
    /**
     * @property height
     * @type number
     */
    Texture.prop('height', 0, Fire.Integer_Obsoleted, Fire.ReadOnly);
    /**
     * @property wrapMode
     * @type Texture.WrapMode
     */
    Texture.prop('wrapMode', Texture.WrapMode.Clamp, Fire.Enum(Texture.WrapMode), Fire.ReadOnly);
    /**
     * @property filterMode
     * @type Texture.FilterMode
     */
    Texture.prop('filterMode', Texture.FilterMode.Bilinear, Fire.Enum(Texture.FilterMode), Fire.ReadOnly);

    //Texture.prototype.onAfterDeserialize = function () {
    //    this.width = this.image.width;
    //    this.height = this.image.height;
    //};

    /**
     * Returns pixel color at coordinates (x, y).
     *
     * If the pixel coordinates are out of bounds (larger than width/height or small than 0),
     * they will be clamped or repeated based on the texture's wrap mode.
     *
     * @method getPixel
     * @param {number} x
     * @param {number} y
     * @return {Fire.Color}
     */
    Texture.prototype.getPixel = function (x, y) {
        if (!canvasCtxToGetPixel) {
            var canvas = document.createElement('canvas');
            canvas.width = 1;
            canvas.height = 1;
            canvasCtxToGetPixel = canvas.getContext('2d');
        }
        if (this.wrapMode === Texture.WrapMode.Clamp) {
            x = Math.clamp(x, 0, this.image.width);
            y = Math.clamp(y, 0, this.image.height);
        }
        else if (this.wrapMode === Texture.WrapMode.Repeat) {
            x = x % this.image.width;
            if (x < 0) {
                x += this.image.width;
            }
            y = y % this.image.width;
            if (y < 0) {
                y += this.image.width;
            }
        }
        canvasCtxToGetPixel.clearRect(0, 0, 1, 1);
        canvasCtxToGetPixel.drawImage(this.image, x, y, 1, 1, 0, 0, 1, 1);

        var imgBytes = null;
        try {
            imgBytes = canvasCtxToGetPixel.getImageData(0, 0, 1, 1).data;
        }
        catch (e) {
            Fire.error("An error has occurred. This is most likely due to security restrictions on reading canvas pixel data with local or cross-domain images.");
            return Fire.Color.transparent;
        }
        var result = new Fire.Color();
        result.r = imgBytes[0] / 255;
        result.g = imgBytes[1] / 255;
        result.b = imgBytes[2] / 255;
        result.a = imgBytes[3] / 255;
        return result;
    };

    return Texture;
})();

var canvasCtxToGetPixel = null;
<|endoftext|>


<commit_before>/* CONSTANTS */
const bMin = document.querySelector('.b--min');
const sMin = document.querySelector('.s--min');
const bPlus = document.querySelector('.b--plus');
const sPlus = document.querySelector('.s--plus');
const sSes = document.querySelector('.span--session');
const sBreak = document.querySelector('.span--break');
const h2Type = document.querySelector('.h2--type');
const bReset = document.querySelector('.b--reset');
const pTimer = document.querySelector('.p--timer');
const bTimer = document.querySelector('.b--timer');
const beep = new Audio('assets/beep.mp3');
let myNoti

/* Allow Notification */
if(Notification.permission !== 'granted') {
  Notification.requestPermission().then(perm => {
    if(perm === 'granted')
      console.log('Notifications will show');
  });
}

/* FUNCTION FOR SETTINGS */
const minOrPlus = (op, n)=>{
  if(op === 'min' && n.innerHTML > 0){
    if(n === sSes)
      n.innerHTML -= 5;
    else
      n.innerHTML -= 1;
  }
  else if(op == 'plus' && n.innerHTML < 60){
    if(n === sSes)
      n.innerHTML = +n.innerHTML + 5;
    else
      n.innerHTML = +n.innerHTML + 1;
  }

  if(n === sSes && h2Type.innerHTML === 'Session')
    pTimer.innerHTML = sSes.innerHTML + ':00';
  else if(n === sBreak && h2Type.innerHTML === 'Break')
    pTimer.innerHTML = sBreak.innerHTML + ':00';
};

/* FUNCTIONS FOR COUNTING */
const setSecs = (mins, secs)=>{
  if(secs > 10)
    return mins + ':' + (secs-1);
  else if(secs > 0)
    return mins + ':0' + (secs-1);
  else
    return setMins(mins);
};

const setMins = (mins)=>{
  if(mins > 10)
    return (mins-1) + ':59';
  else if(mins > 0)
    return (mins-1) + ':59';
  else
    return '0:00';
};

/* FUNCTIONS FOR TIMER */
const stop = (intervalID) => {
  clearInterval(intervalID);

  bMin.disabled = sMin.disabled = bPlus.disabled = sPlus.disabled = false;
  bTimer.style.background = 'none';

  bTimer.onclick = () => {run();};
};

const change = () => {
  beep.play();

  //add notification
  if(!myNoti) {
    myNoti= new Notification('Timer Ended', { requireInteraction: true });
    myNoti.onclose = function() {
      myNoti = undefined

      if(h2Type.innerHTML === 'Session') {
        h2Type.innerHTML = 'Break';
        pTimer.innerHTML = sBreak.innerHTML + ':00';
      }
      else {
        h2Type.innerHTML = 'Session';
        pTimer.innerHTML = sSes.innerHTML + ':00';
      }
    }
  }

  bTimer.onclick = () => {
    //remove notification
    if(myNoti) {
      setTimeout(myNoti.close.bind(myNoti), 500);
      myNoti = undefined;
    }

    if(h2Type.innerHTML === 'Session') {
      h2Type.innerHTML = 'Break';
      pTimer.innerHTML = sBreak.innerHTML + ':00';
    }
    else {
      h2Type.innerHTML = 'Session';
      pTimer.innerHTML = sSes.innerHTML + ':00';
    }
  };
};

const run = () => {
  //Stop from clicking too fast
  if(bTimer.style.background === 'yellow')
    return;

  bMin.disabled = sMin.disabled = bPlus.disabled = sPlus.disabled = true;
  bTimer.style.background = 'yellow';

  const intervalID = setInterval(() => {
    //Running and Stopping
    if(pTimer.innerHTML !== '0:00'){
      pTimer.innerHTML =
        setSecs(pTimer.innerHTML.split(':')[0],
                pTimer.innerHTML.split(':')[1]);

      bTimer.onclick = () => { stop(intervalID); };
    }

    //Changing between Session and Break
    else change();
  }, 1000);

  //Reset button
  bReset.onclick = () => {
    stop(intervalID);
    pTimer.innerHTML = sSes.innerHTML + ':00';
    h2Type.innerHTML = 'Session';

    //remove notification
    if(myNoti) {
      setTimeout(myNoti.close.bind(myNoti), 500);
      myNoti = undefined;
    }
  };
};

/* VOLUME */
beep.volume = 1;

/* SETTINGS */
bMin.onclick = () => { minOrPlus('min', sBreak); };
sMin.onclick = () => { minOrPlus('min', sSes); };
bPlus.onclick = () => { minOrPlus('plus', sBreak); };
sPlus.onclick = () => { minOrPlus('plus', sSes); };

/* TIMER */
bTimer.onclick = () => { run(); };
<commit_msg>fix bugs<commit_after>/* CONSTANTS */
const bMin = document.querySelector('.b--min');
const sMin = document.querySelector('.s--min');
const bPlus = document.querySelector('.b--plus');
const sPlus = document.querySelector('.s--plus');
const sSes = document.querySelector('.span--session');
const sBreak = document.querySelector('.span--break');
const h2Type = document.querySelector('.h2--type');
const bReset = document.querySelector('.b--reset');
const pTimer = document.querySelector('.p--timer');
const bTimer = document.querySelector('.b--timer');
const beep = new Audio('assets/beep.mp3');
let myNoti

/* Allow Notification */
if(Notification.permission !== 'granted') {
  Notification.requestPermission().then(perm => {
    if(perm === 'granted')
      console.log('Notifications will show');
  });
}

/* FUNCTION FOR SETTINGS */
const minOrPlus = (op, n)=>{
  if(op === 'min' && n.innerHTML > 0){
    if(n === sSes)
      n.innerHTML -= 5;
    else
      n.innerHTML -= 1;
  }
  else if(op == 'plus' && n.innerHTML < 60){
    if(n === sSes)
      n.innerHTML = +n.innerHTML + 5;
    else
      n.innerHTML = +n.innerHTML + 1;
  }

  if(n === sSes && h2Type.innerHTML === 'Session')
    pTimer.innerHTML = sSes.innerHTML + ':00';
  else if(n === sBreak && h2Type.innerHTML === 'Break')
    pTimer.innerHTML = sBreak.innerHTML + ':00';
};

/* FUNCTIONS FOR COUNTING */
const setSecs = (mins, secs)=>{
  if(secs > 10)
    return mins + ':' + (secs-1);
  else if(secs > 0)
    return mins + ':0' + (secs-1);
  else
    return setMins(mins);
};

const setMins = (mins)=>{
  if(mins > 10)
    return (mins-1) + ':59';
  else if(mins > 0)
    return (mins-1) + ':59';
  else
    return '0:00';
};

/* FUNCTIONS FOR TIMER */
const stop = (intervalID) => {
  clearInterval(intervalID);

  bMin.disabled = sMin.disabled = bPlus.disabled = sPlus.disabled = false;
  bTimer.style.background = 'none';

  bTimer.onclick = () => {run();};
};

const change = () => {
  beep.play();

  //add notification
  if(!myNoti) {
    myNoti= new Notification('Timer Ended', { requireInteraction: true });
    myNoti.onclick = function() {
      setTimeout(myNoti.close.bind(myNoti), 500);
      myNoti = undefined

      if(h2Type.innerHTML === 'Session') {
        h2Type.innerHTML = 'Break';
        pTimer.innerHTML = sBreak.innerHTML + ':00';
      }
      else {
        h2Type.innerHTML = 'Session';
        pTimer.innerHTML = sSes.innerHTML + ':00';
      }
    }
  }

  bTimer.onclick = () => {
    //remove notification
    if(myNoti) {
      setTimeout(myNoti.close.bind(myNoti), 500);
      myNoti = undefined;
    }

    if(h2Type.innerHTML === 'Session') {
      h2Type.innerHTML = 'Break';
      pTimer.innerHTML = sBreak.innerHTML + ':00';
    }
    else {
      h2Type.innerHTML = 'Session';
      pTimer.innerHTML = sSes.innerHTML + ':00';
    }
  };
};

const run = () => {
  //Stop from clicking too fast
  if(bTimer.style.background === 'yellow')
    return;

  bMin.disabled = sMin.disabled = bPlus.disabled = sPlus.disabled = true;
  bTimer.style.background = 'yellow';

  const intervalID = setInterval(() => {
    //Running and Stopping
    if(pTimer.innerHTML !== '0:00'){
      pTimer.innerHTML =
        setSecs(pTimer.innerHTML.split(':')[0],
                pTimer.innerHTML.split(':')[1]);

      bTimer.onclick = () => { stop(intervalID); };
    }

    //Changing between Session and Break
    else change();
  }, 1000);

  //Reset button
  bReset.onclick = () => {
    stop(intervalID);
    pTimer.innerHTML = sSes.innerHTML + ':00';
    h2Type.innerHTML = 'Session';

    //remove notification
    if(myNoti) {
      setTimeout(myNoti.close.bind(myNoti), 500);
      myNoti = undefined;
    }
  };
};

/* VOLUME */
beep.volume = 1;

/* SETTINGS */
bMin.onclick = () => { minOrPlus('min', sBreak); };
sMin.onclick = () => { minOrPlus('min', sSes); };
bPlus.onclick = () => { minOrPlus('plus', sBreak); };
sPlus.onclick = () => { minOrPlus('plus', sSes); };

/* TIMER */
bTimer.onclick = () => { run(); };
<|endoftext|>


<commit_before>//import {$,jQuery} from 'jquery';
// export for others scripts to use
//window.$ = $;
//window.jQuery = jQuery;

import Prism from 'prismjs';
require('prismjs/plugins/line-numbers/prism-line-numbers');
require('prismjs/components/prism-markup-templating');
require('prismjs/components/prism-php');
require('prismjs/components/prism-scss');

import autosize from 'autosize';

import Glide from '@glidejs/glide';

(function ()
{
    'use strict';

    // If JavaScript enabled, add a class to `<html>` tag.

    document.documentElement.className = 'js';

    // Load objects as variables.

    var code = document.querySelectorAll('code[class*="language-"], [class*="language-"] code'),
        fields = document.querySelectorAll('textarea'),
        navmenu = document.getElementById('site-navigation'),
        slider = document.querySelectorAll('.glide');

    // Syntax highlighting, via 'Prism'.
    // Applies syntax highlighting to `code` HTML elements.
    // More info - https://prismjs.com.

    if (code.length) {
        Prism.highlightAll();
    }

    // Auto-growing textareas, via 'Autosize'.
    // Allows dynamic resizing of textarea height, so that it grows as based
    // on visitor input. More info - https://github.com/jackmoore/autosize.

    if (fields.length) {
        autosize(fields);
    }

    // Responsive navigation menu.

    if (navmenu) {
        var navtoggle = document.getElementById('site-navigation-toggle');

        navtoggle.addEventListener('click', function(e)
        {
            e.preventDefault();
            navtoggle.classList.toggle('site-navigation-toggle-active');
            navmenu.classList.toggle('site-navigation-open');
        });
    }

    // Slider, via 'Glide'.
    // More info - https://github.com/glidejs/glide.

    if (slider.length) {
        new Glide('.glide', {
            type: 'carousel'
        }).mount();
    }

})();
<commit_msg>Dark Mode helpers<commit_after>//import {$,jQuery} from 'jquery';
// export for others scripts to use
//window.$ = $;
//window.jQuery = jQuery;

import Prism from 'prismjs';
require('prismjs/plugins/line-numbers/prism-line-numbers');
require('prismjs/components/prism-markup-templating');
require('prismjs/components/prism-php');
require('prismjs/components/prism-scss');

import autosize from 'autosize';

import Glide from '@glidejs/glide';

(function ()
{
    'use strict';

    // If JavaScript enabled, add a class to `<html>` tag.

    document.documentElement.className = 'js';

    // Load objects as variables.

    var code = document.querySelectorAll('code[class*="language-"], [class*="language-"] code'),
        fields = document.querySelectorAll('textarea'),
        navmenu = document.getElementById('site-navigation'),
        slider = document.querySelectorAll('.glide');

    // Syntax highlighting, via 'Prism'.
    // Applies syntax highlighting to `code` HTML elements.
    // More info - https://prismjs.com.

    if (code.length) {
        Prism.highlightAll();
    }

    // Auto-growing textareas, via 'Autosize'.
    // Allows dynamic resizing of textarea height, so that it grows as based
    // on visitor input. More info - https://github.com/jackmoore/autosize.

    if (fields.length) {
        autosize(fields);
    }

    // Responsive navigation menu.

    if (navmenu) {
        var navtoggle = document.getElementById('site-navigation-toggle');

        navtoggle.addEventListener('click', function(e)
        {
            e.preventDefault();
            navtoggle.classList.toggle('site-navigation-toggle-active');
            navmenu.classList.toggle('site-navigation-open');
        });
    }

    // Slider, via 'Glide'.
    // More info - https://github.com/glidejs/glide.

    if (slider.length) {
        new Glide('.glide', {
            type: 'carousel'
        }).mount();
    }

})();

// Specific dark and light images.
// Example:
// <img src="assets/images/feature.png"
//     data-src-light="assets/images/example.png"
//     data-src-dark="assets/images/example-dark.png"
//     srcset="assets/images/example@2x.png 2x"
//     data-srcset-light="assets/images/example@2x.png 2x"
//     data-srcset-dark="assets/images/example-dark@2x.png 2x" />

function makeImagesDark()
{
    'use strict';

    $('img.color-specific').each(function() {
        $(this).attr('src', $(this).attr('data-dark-src'));
        $(this).attr('srcset', $(this).attr('data-dark-srcset'));
    });
}

function makeImagesLight()
{
    'use strict';

    $('img.color-specific').each(function() {
        $(this).attr('src', $(this).attr('data-light-src'));
        $(this).attr('srcset', $(this).attr('data-light-srcset'));
    });
}

// Detect Dark Mode/Light Mode.

function toggleDarkMode(isDark)
{
    'use strict';

    if (isDark.matches) {
        makeImagesDark();
    } else {
        makeImagesLight();
    }
}

var isDark = window.matchMedia('screen and (prefers-color-scheme: dark)');
toggleDarkMode(isDark);
isDark.addListener(toggleDarkMode);

// Switch between Dark Mode/Light Mode manually.

$('#lightswitch').on('click', function()
{
    'use strict';

    if ($('body').hasClass('darkmode')) {
        $('body').removeClass('darkmode');
        makeImagesLight();
        localStorage.removeItem("prefers-color-scheme", "dark");
        return false;
    } else {
        $('body').addClass('darkmode');
        makeImagesDark();
        localStorage.setItem("prefers-color-scheme", "dark");
        return false;
    }
});

if (localStorage.getItem("prefers-color-scheme") === "dark") {
    $('body').addClass('darkmode');
    makeImagesDark();
}
<|endoftext|>