<commit_before>const ENUMS = require('../lib/enums.js');

function WindowCoveringAccessory(name, uuid, profile, node, platform) {
    this.name = name;
    this.uuid = uuid;
    this.platform = platform
    this.log = platform.log;
    this.nodeId = node.id;
    this.profile = profile;
    this.attributes = {};

    for (let i=0; i<node.attributes.length; i++) {
        switch (node.attributes[i].type) {
            case ENUMS.CAAttributeType.CAAttributeTypePosition:
                this.attributes.position = node.attributes[i];
                break;
            case ENUMS.CAAttributeType.CAAttributeTypeUpDown:
                this.attributes.upDown = node.attributes[i];
                break;
        }
    }
}

WindowCoveringAccessory.prototype.updateValue = function (attribute) {
    switch (attribute.type) {
        case ENUMS.CAAttributeType.CAAttributeTypePosition:
            this.attributes.position = attribute;
            this.service.getCharacteristic(Characteristic.CurrentPosition)
                .updateValue(attribute.current_value, null, 'ws');
            this.service.getCharactersitic(Charactersitic.TargetPosition)
                .updateValue(attribute.target_value, null, 'ws');
            break;
        case ENUMS.CAAttributeType.CAAttributeTypeUpDown:
            this.attributes.upDown = attribute;
            this.service.getCharacteristic(Characteristic.PositionState)
                .updateValue([2,2,2,1,0][this.attributes.upDown.current_value], null, 'ws');
            break;
    }

    if (that.platform.debug) that.log(that.name + ': ' + attributeType + ': ' + newValue);
}

WindowCoveringAccessory.prototype.setTargetPosition = function (value, callback, context) {
    if (context && context == 'ws') {
        callback(null, value);
        return;
    }

    if (this.platform.debug) this.log('Setting ' + this.name + ' to ' + value);
    this.platform.homee.send(
        'PUT:/nodes/' + this.nodeId + '/attributes/' + this.attributes.position.id + '?target_value=' + value
    );

    callback(null, value);
}

WindowCoveringAccessory.prototype.setPositionState = function (value, callback, context) {
    if (context && context == 'ws') {
        callback(null, value);
        return;
    }

    newValue = [1,0,2][value];

    if (this.platform.debug) this.log('Setting ' + this.name + ' to ' + newValue);
    this.platform.homee.send(
        'PUT:/nodes/' + this.nodeId + '/attributes/' + this.attributes.upDown.id + '?target_value=' + newValue
    );

    callback(null, value);
}

WindowCoveringAccessory.prototype.getServices = function () {
    let informationService = new Service.AccessoryInformation();

    informationService
        .setCharacteristic(Characteristic.Manufacturer, "Homee")
        .setCharacteristic(Characteristic.Model, "WindowCovering")
        .setCharacteristic(Characteristic.SerialNumber, "");

    this.service = new Service.WindowCovering(this.name);

    this.service.getCharacteristic(Characteristic.CurrentPosition)
        .updateValue(this.attributes.position.current_value);

    this.service.getCharacteristic(Characteristic.TargetPosition)
        .updateValue(this.attributes.position.target_value)
        .on('set', this.setTargetPosition.bind(this));

    this.service.getCharacteristic(Characteristic.PositionState)
        .updateValue([2,2,2,1,0][this.attributes.upDown.current_value])
        .on('set', this.setPositionState.bind(this));

    return [informationService, this.service];
};

module.exports = function(oService, oCharacteristic) {
    Service = oService;
    Characteristic = oCharacteristic;

    return WindowCoveringAccessory;
};
<commit_msg>fixed typos<commit_after>const ENUMS = require('../lib/enums.js');

function WindowCoveringAccessory(name, uuid, profile, node, platform) {
    this.name = name;
    this.uuid = uuid;
    this.platform = platform
    this.log = platform.log;
    this.nodeId = node.id;
    this.profile = profile;
    this.attributes = {};

    for (let i=0; i<node.attributes.length; i++) {
        switch (node.attributes[i].type) {
            case ENUMS.CAAttributeType.CAAttributeTypePosition:
                this.attributes.position = node.attributes[i];
                break;
            case ENUMS.CAAttributeType.CAAttributeTypeUpDown:
                this.attributes.upDown = node.attributes[i];
                break;
        }
    }
}

WindowCoveringAccessory.prototype.updateValue = function (attribute) {
    switch (attribute.type) {
        case ENUMS.CAAttributeType.CAAttributeTypePosition:
            this.attributes.position = attribute;
            this.service.getCharacteristic(Characteristic.CurrentPosition)
                .updateValue(attribute.current_value, null, 'ws');
            this.service.getCharacteristic(Characteristic.TargetPosition)
                .updateValue(attribute.target_value, null, 'ws');
            break;
        case ENUMS.CAAttributeType.CAAttributeTypeUpDown:
            this.attributes.upDown = attribute;
            this.service.getCharacteristic(Characteristic.PositionState)
                .updateValue([2,2,2,1,0][this.attributes.upDown.current_value], null, 'ws');
            break;
    }

    if (this.platform.debug) this.log(this.name + ': ' + attributeType + ': ' + newValue);
}

WindowCoveringAccessory.prototype.setTargetPosition = function (value, callback, context) {
    if (context && context == 'ws') {
        callback(null, value);
        return;
    }

    if (this.platform.debug) this.log('Setting ' + this.name + ' to ' + value);
    this.platform.homee.send(
        'PUT:/nodes/' + this.nodeId + '/attributes/' + this.attributes.position.id + '?target_value=' + value
    );

    callback(null, value);
}

WindowCoveringAccessory.prototype.setPositionState = function (value, callback, context) {
    if (context && context == 'ws') {
        callback(null, value);
        return;
    }

    newValue = [1,0,2][value];

    if (this.platform.debug) this.log('Setting ' + this.name + ' to ' + newValue);
    this.platform.homee.send(
        'PUT:/nodes/' + this.nodeId + '/attributes/' + this.attributes.upDown.id + '?target_value=' + newValue
    );

    callback(null, value);
}

WindowCoveringAccessory.prototype.getServices = function () {
    let informationService = new Service.AccessoryInformation();

    informationService
        .setCharacteristic(Characteristic.Manufacturer, "Homee")
        .setCharacteristic(Characteristic.Model, "WindowCovering")
        .setCharacteristic(Characteristic.SerialNumber, "");

    this.service = new Service.WindowCovering(this.name);

    this.service.getCharacteristic(Characteristic.CurrentPosition)
        .updateValue(this.attributes.position.current_value);

    this.service.getCharacteristic(Characteristic.TargetPosition)
        .updateValue(this.attributes.position.target_value)
        .on('set', this.setTargetPosition.bind(this));

    this.service.getCharacteristic(Characteristic.PositionState)
        .updateValue([2,2,2,1,0][this.attributes.upDown.current_value])
        .on('set', this.setPositionState.bind(this));

    return [informationService, this.service];
};

module.exports = function(oService, oCharacteristic) {
    Service = oService;
    Characteristic = oCharacteristic;

    return WindowCoveringAccessory;
};
<|endoftext|>


<commit_before>// Top-level container object for this js file.
var NER = {};

// "nodes" is a table of entity names, mapping to an array position generated
// uniquely by the "counter" variable.  Once the table is complete, the nodes
// table can be recast into an array.
NER.nodes = {};
NER.links = {};
NER.counter = 0;

// This count will signal when the last ajax request has completed, and graph
// assembly can continue.
NER.num_files = 0;
NER.files_processed = 0;

function assembleGraph(){
    // Create a graph object.
    var g = {};

    // Copy the links over into an array within the graph object.
    g.links = [];
    $.each(NER.links, function(k, v){
        g.links.push(v);
    });

    // Do the same for the nodes, but do two additional things:
    //
    // 1. When extracting an object from the NER.nodes table, remove the "index"
    //    property, as it will no longer be needed after final placement of the
    //    node.
    //
    // 2. Place the node object into the place in the array indexed by that
    //    "index" property.  This ensures that the references in the link list
    //    are to the proper nodes.
    //
    // Start by creating an empty array of length equal to the number of total
    // entities.
    g.nodes = Array(Object.keys(NER.nodes).length);

    // Now plop each entity into its proper place.
    $.each(NER.nodes, function(k, v){
        var i = v.index;
        delete v.index;
        g.nodes[i] = v;
    });

    return g;
}

function renderGraph(g){
    //console.log(JSON.stringify(g));

    var width = 1000,
        height = 1000;

    var color = d3.scale.category20();

    var force = d3.layout.force()
        .charge(-120)
        .linkDistance(30)
        .size([width, height]);

    var svg = d3.select("#graph").append("svg")
        .attr("width", width)
        .attr("height", height);
    var stroke_width = 3;
    svg.append("rect")
        .attr("x", 0.5*stroke_width)
        .attr("y", 0.5*stroke_width)
        .attr("rx", 10)
        .attr("ry", 10)
        .attr("width", width - stroke_width)
        .attr("height", height - stroke_width)
        .style("fill-opacity", 0.1)
        .style("stroke", "black")
        .style("stroke-width", stroke_width);

    force
        .nodes(g.nodes)
        .links(g.links)
        .start();

    var link = svg.selectAll("line.link")
        .data(g.links)
      .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) { return Math.sqrt(d.count); });

    var node = svg.selectAll("circle.node")
        .data(g.nodes)
      .enter().append("circle")
        .attr("class", "node")
        .attr("r", function(d) { return 5*Math.sqrt(d.count); })
        .style("fill", function(d) { return color(d.type); })
        .call(force.drag);

    node.append("title")
        .text(function(d) { return d.name; });

    force.on("tick", function(){
        link.attr("x1", function(d) { return d.source.x; })
            .attr("y1", function(d) { return d.source.y; })
            .attr("x2", function(d) { return d.target.x; })
            .attr("y2", function(d) { return d.target.y; });

        node.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });

    });
}

// This function can be called with a filename to *generate* an AJAX-success
// callback function to process the contents of some file.  The parameter passed
// into the generator is so that the callback has access to the name of the file
// being processed.
function processFileContents(filename, file_hash){
    return function(data){
        console.log("success for " + filename);
        $("#" + filename.replace(".","-")).removeClass("inprogress").addClass("done").get(0).innerHTML = filename + " processed";

        // If the "store" parameter is set to true, store the data in the
        // database (caching it for future retrieval).
        if(file_hash !== undefined){
            // Fire an AJAX call that will install the computed data in the DB.
            $.ajax({
                type: 'POST',
                url: '/service/mongo/xdata/ner-cache',
                data: {
                    file_hash: file_hash,
                    data: data
                },
            });
        }

        // Create an entry for the document itself.
        NER.nodes[filename] = {
            name: filename,
            type: "DOCUMENT",
            count: 1,
            index: NER.counter++
        };
        var doc_index = NER.counter - 1;

        // Extract the JSON object from the AJAX response.
        var entities = $.parseJSON(data);

        // Process the entities.
        $.each(entities, function(i, e){
            // Place the entity into the global entity list
            // if not already there.
            //
            // Also update the count of this entity.
            var key = '["' + e[0] + '","' + e[1] + '"]';
            if(!NER.nodes.hasOwnProperty(key)){
                NER.nodes[key] = {
                    name: e[1],
                    type: e[0],
                    count: 1,
                    index: NER.counter++
                }
            }
            else{
                NER.nodes[key].count++;
            }
            var entity_index = NER.nodes[key].index;

            // Enter a link into the link list, or just increase the count if
            // the link exists already.
            var link = "(" + entity_index + "," + doc_index + ")";
            if(!NER.links.hasOwnProperty(link)){
                NER.links[link] = {
                    source: entity_index,
                    target: doc_index,
                    count: 1
                };
            }
            else{
                NER.links[link].count++;
            }
        });

        //console.log(NER.nodes);

        // Increment the number of successfully processed
        // files; if the number reaches the number of total
        // files to process, launch the final step of
        // assembling the graph.
        ++NER.files_processed;
        console.log(NER.files_processed + " of " + NER.num_files + " processed");

        if(NER.files_processed == NER.num_files){
            console.log("calling assembleGraph()");
            var graph = assembleGraph();
            renderGraph(graph);
        }
    }
}

function handleFileSelect(evt){
    // Grab the list of files selected by the user.
    var files = evt.target.files;

    // Compute how many of these files will actually be processed for named
    // entities (see comment below for explanation of how the files are vetted).
    NER.num_files = 0;
    $.each(files, function(k, v){
        if(v.type == '(n/a)' || v.type.slice(0,5) == 'text/'){
            NER.num_files++;
        }
    });
    console.log(NER.num_files + " files to process");

    // Now run through the files, using a callback to load the content from the
    // proper ones and pass it to an ajax call to perform named-entity
    // recognition.
    var output = [];
    for(var i=0; i<files.length; i++){
        var f = files[i];

        // Decide whether to process a selected file or not - accept everything
        // with a mime-type of text/*, as well as those with unspecified type
        // (assume the user knows what they are doing in such a case).
        var using = null;
        if(f.type == '(n/a)'){
            status = "accepted";
            msg = "ok, assuming text";
            using = true;
        }
        else if(f.type.slice(0,5) == 'text/'){
            status = "accepted";
            msg = "ok";
            using = true;
        }
        else{
            status = "rejected";
            msg = "rejected";
            using = false;
        }
        output.push('
', escape(f.name), ' (', f.type || 'n/a', ') - ', f.size, ' bytes ', f.type == 'text/plain' ? '(ok)' : '(rejected)');

        if(using){
            var reader = new FileReader();
            reader.onload = (function(file){
                return function(e){
                    var filename = escape(file.name);
                    console.log(filename);

                    // Grab the text of the file.
                    var text = e.target.result;

                    // Create a "progress" bullet point describing the current
                    // AJAX state of this file.
                    var elem = document.createElement("li");
                    elem.innerHTML = "processing " + filename;
                    elem.setAttribute("id", filename.replace(".","-"));
                    elem.setAttribute("class", "processing inprogress");
                    $("#blobs").get(0).appendChild(elem);

                    var file_hash = CryptoJS.MD5(text).toString();
                    console.log("Checking hash for " + filename + "...");

                    // Check to see if the file contents were already processed,
                    // by querying the database for the results.  If they are
                    // found, retrieve them directly; if not, fire the AJAX call
                    // below to compute the results (but db cache the result
                    // when it finishes!).
                    $.ajax({
                        type: 'POST',
                        url: '/service/mongo/xdata/ner-cache',
                        data: {
                            file_hash: file_hash
                        },
                        success: function(data){
                            // Check the response - if it is blank, launch the
                            // second AJAX call to directly compute the NER set,
                            // and store it in the database.
                            if(data == '[]'){
                                console.log("hash for " + filename + " not found in DB, recomputing");
                                $.ajax({
                                    type: 'POST',
                                    url: '/service/NER',
                                    data: {
                                        text: text
                                    },
                                    dataType: 'text',
                                    success: processFileContents(filename, file_hash),
                                    error: function(){
                                        console.log("error for " + filename);
                                        $("#" + filename.replace(".","-")).removeClass("inprogress").addClass("failed").get(0).innerHTML = filename + " processed";
                                    }
                                });
                            }
                            else{
                                console.log("hash for " + filename + " found in DB!");
                                // The data returned from the DB is in MongoDB
                                // format.  Read it into a JSON object, then
                                // extract the payload.
                                var jsdata = $.parseJSON(data);

                                // TODO(choudhury): error checking.  Make sure
                                // that "jsdata" has only a single element, etc.

                                // The call to processFileContents() generates a
                                // function (in which the file_hash parameter is
                                // OMITTED); the second invocation calls that
                                // function to actually process the data.
                                processFileContents(filename)(jsdata[0].data);
                            }
                        }
                    });
                }
            })(f);

            reader.readAsText(f);
        }
    }
    document.getElementById('file-info').innerHTML = '
' + output.join('') + '
';
}

window.onload = function(){
    document.getElementById('docs').addEventListener('change', handleFileSelect, false);
}
<commit_msg>ran jshint over code<commit_after>// Top-level container object for this js file.
var NER = {};

// "nodes" is a table of entity names, mapping to an array position generated
// uniquely by the "counter" variable.  Once the table is complete, the nodes
// table can be recast into an array.
NER.nodes = {};
NER.links = {};
NER.counter = 0;

// This count will signal when the last ajax request has completed, and graph
// assembly can continue.
NER.num_files = 0;
NER.files_processed = 0;

function assembleGraph(){
    // Create a graph object.
    var g = {};

    // Copy the links over into an array within the graph object.
    g.links = [];
    $.each(NER.links, function(k, v){
        g.links.push(v);
    });

    // Do the same for the nodes, but do two additional things:
    //
    // 1. When extracting an object from the NER.nodes table, remove the "index"
    //    property, as it will no longer be needed after final placement of the
    //    node.
    //
    // 2. Place the node object into the place in the array indexed by that
    //    "index" property.  This ensures that the references in the link list
    //    are to the proper nodes.
    //
    // Start by creating an empty array of length equal to the number of total
    // entities.
    g.nodes = Array(Object.keys(NER.nodes).length);

    // Now plop each entity into its proper place.
    $.each(NER.nodes, function(k, v){
        var i = v.index;
        delete v.index;
        g.nodes[i] = v;
    });

    return g;
}

function renderGraph(g){
    //console.log(JSON.stringify(g));

    var width = 1000,
        height = 1000;

    var color = d3.scale.category20();

    var force = d3.layout.force()
        .charge(-120)
        .linkDistance(30)
        .size([width, height]);

    var svg = d3.select("#graph").append("svg")
        .attr("width", width)
        .attr("height", height);
    var stroke_width = 3;
    svg.append("rect")
        .attr("x", 0.5*stroke_width)
        .attr("y", 0.5*stroke_width)
        .attr("rx", 10)
        .attr("ry", 10)
        .attr("width", width - stroke_width)
        .attr("height", height - stroke_width)
        .style("fill-opacity", 0.1)
        .style("stroke", "black")
        .style("stroke-width", stroke_width);

    force
        .nodes(g.nodes)
        .links(g.links)
        .start();

    var link = svg.selectAll("line.link")
        .data(g.links)
      .enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) { return Math.sqrt(d.count); });

    var node = svg.selectAll("circle.node")
        .data(g.nodes)
      .enter().append("circle")
        .attr("class", "node")
        .attr("r", function(d) { return 5*Math.sqrt(d.count); })
        .style("fill", function(d) { return color(d.type); })
        .call(force.drag);

    node.append("title")
        .text(function(d) { return d.name; });

    force.on("tick", function(){
        link.attr("x1", function(d) { return d.source.x; })
            .attr("y1", function(d) { return d.source.y; })
            .attr("x2", function(d) { return d.target.x; })
            .attr("y2", function(d) { return d.target.y; });

        node.attr("cx", function(d) { return d.x; })
            .attr("cy", function(d) { return d.y; });

    });
}

// This function can be called with a filename to *generate* an AJAX-success
// callback function to process the contents of some file.  The parameter passed
// into the generator is so that the callback has access to the name of the file
// being processed.
function processFileContents(filename, file_hash){
    return function(data){
        console.log("success for " + filename);
        $("#" + filename.replace(".","-")).removeClass("inprogress").addClass("done").get(0).innerHTML = filename + " processed";

        // If the "store" parameter is set to true, store the data in the
        // database (caching it for future retrieval).
        if(file_hash !== undefined){
            // Fire an AJAX call that will install the computed data in the DB.
            $.ajax({
                type: 'POST',
                url: '/service/mongo/xdata/ner-cache',
                data: {
                    file_hash: file_hash,
                    data: data
                }
            });
        }

        // Create an entry for the document itself.
        NER.nodes[filename] = {
            name: filename,
            type: "DOCUMENT",
            count: 1,
            index: NER.counter++
        };
        var doc_index = NER.counter - 1;

        // Extract the JSON object from the AJAX response.
        var entities = $.parseJSON(data);

        // Process the entities.
        $.each(entities, function(i, e){
            // Place the entity into the global entity list
            // if not already there.
            //
            // Also update the count of this entity.
            var key = '["' + e[0] + '","' + e[1] + '"]';
            if(!NER.nodes.hasOwnProperty(key)){
                NER.nodes[key] = {
                    name: e[1],
                    type: e[0],
                    count: 1,
                    index: NER.counter++
                };
            }
            else{
                NER.nodes[key].count++;
            }
            var entity_index = NER.nodes[key].index;

            // Enter a link into the link list, or just increase the count if
            // the link exists already.
            var link = "(" + entity_index + "," + doc_index + ")";
            if(!NER.links.hasOwnProperty(link)){
                NER.links[link] = {
                    source: entity_index,
                    target: doc_index,
                    count: 1
                };
            }
            else{
                NER.links[link].count++;
            }
        });

        //console.log(NER.nodes);

        // Increment the number of successfully processed
        // files; if the number reaches the number of total
        // files to process, launch the final step of
        // assembling the graph.
        ++NER.files_processed;
        console.log(NER.files_processed + " of " + NER.num_files + " processed");

        if(NER.files_processed == NER.num_files){
            console.log("calling assembleGraph()");
            var graph = assembleGraph();
            renderGraph(graph);
        }
    };
}

function handleFileSelect(evt){
    // Grab the list of files selected by the user.
    var files = evt.target.files;

    // Compute how many of these files will actually be processed for named
    // entities (see comment below for explanation of how the files are vetted).
    NER.num_files = 0;
    $.each(files, function(k, v){
        if(v.type == '(n/a)' || v.type.slice(0,5) == 'text/'){
            NER.num_files++;
        }
    });
    console.log(NER.num_files + " files to process");

    // Now run through the files, using a callback to load the content from the
    // proper ones and pass it to an ajax call to perform named-entity
    // recognition.
    var output = [];
    for(var i=0; i<files.length; i++){
        var f = files[i];

        // Decide whether to process a selected file or not - accept everything
        // with a mime-type of text/*, as well as those with unspecified type
        // (assume the user knows what they are doing in such a case).
        var using = null;
        if(f.type == '(n/a)'){
            status = "accepted";
            msg = "ok, assuming text";
            using = true;
        }
        else if(f.type.slice(0,5) == 'text/'){
            status = "accepted";
            msg = "ok";
            using = true;
        }
        else{
            status = "rejected";
            msg = "rejected";
            using = false;
        }
        output.push('
', escape(f.name), ' (', f.type || 'n/a', ') - ', f.size, ' bytes ', f.type == 'text/plain' ? '(ok)' : '(rejected)');

        if(using){
            var reader = new FileReader();
            reader.onload = (function(file){
                return function(e){
                    var filename = escape(file.name);
                    console.log(filename);

                    // Grab the text of the file.
                    var text = e.target.result;

                    // Create a "progress" bullet point describing the current
                    // AJAX state of this file.
                    var elem = document.createElement("li");
                    elem.innerHTML = "processing " + filename;
                    elem.setAttribute("id", filename.replace(".","-"));
                    elem.setAttribute("class", "processing inprogress");
                    $("#blobs").get(0).appendChild(elem);

                    var file_hash = CryptoJS.MD5(text).toString();
                    console.log("Checking hash for " + filename + "...");

                    // Check to see if the file contents were already processed,
                    // by querying the database for the results.  If they are
                    // found, retrieve them directly; if not, fire the AJAX call
                    // below to compute the results (but db cache the result
                    // when it finishes!).
                    $.ajax({
                        type: 'POST',
                        url: '/service/mongo/xdata/ner-cache',
                        data: {
                            file_hash: file_hash
                        },
                        success: function(data){
                            // Check the response - if it is blank, launch the
                            // second AJAX call to directly compute the NER set,
                            // and store it in the database.
                            if(data == '[]'){
                                console.log("hash for " + filename + " not found in DB, recomputing");
                                $.ajax({
                                    type: 'POST',
                                    url: '/service/NER',
                                    data: {
                                        text: text
                                    },
                                    dataType: 'text',
                                    success: processFileContents(filename, file_hash),
                                    error: function(){
                                        console.log("error for " + filename);
                                        $("#" + filename.replace(".","-")).removeClass("inprogress").addClass("failed").get(0).innerHTML = filename + " processed";
                                    }
                                });
                            }
                            else{
                                console.log("hash for " + filename + " found in DB!");
                                // The data returned from the DB is in MongoDB
                                // format.  Read it into a JSON object, then
                                // extract the payload.
                                var jsdata = $.parseJSON(data);

                                // TODO(choudhury): error checking.  Make sure
                                // that "jsdata" has only a single element, etc.

                                // The call to processFileContents() generates a
                                // function (in which the file_hash parameter is
                                // OMITTED); the second invocation calls that
                                // function to actually process the data.
                                processFileContents(filename)(jsdata[0].data);
                            }
                        }
                    });
                };
            })(f);

            reader.readAsText(f);
        }
    }
    document.getElementById('file-info').innerHTML = '
' + output.join('') + '
';
}

window.onload = function(){
    document.getElementById('docs').addEventListener('change', handleFileSelect, false);
};
<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../templates/components/em-markdown-editor';

export default Ember.Component.extend({
    content: "",
    layout: layout,

    lang: {
        preview: "Preview",
        editor: "Editor",
        fullscreen: "Click to toggle fullscreen"
    },

    onInit: Ember.on('didInsertElement', function() {
        this.updateLayout();
    }),

    onTyping: Ember.observer('content', function() {
        this.updateLayout();
    }),

    updateLayout: function() {
        var lines = this.get("content").split('\n');
        var height = lines.length * 15;
        var previewHeight = this.$('.em-markdown-preview').css('height');

        if (previewHeight > height) {
            height = previewHeight;
        }

        this.$('textarea, .em-markdown-output').css('height', height);

    },

    doubleClick: function() {
        this.$().children().toggleClass("fullscreen");
    },

    drop: function(ev) {
        ev.preventDefault();
        this.sendAction("onUpload", ev);
        Ember.debug("you dropped something");
    },

    dragEnter: function() {
        this.$('.em-markdown-editor').addClass("drop-file-enter");
    },

    dragLeave: function() {
        this.$('.em-markdown-editor').removeClass("drop-file-enter");
    },

    dragOver: function() {
        this.$('.em-markdown-editor').addClass("drop-file-enter");
    },

    actions: {
        toggleFullscreen: function() {
            this.doubleClick();
        }
    }
});
<commit_msg>rename onUpload to upload<commit_after>import Ember from 'ember';
import layout from '../templates/components/em-markdown-editor';

export default Ember.Component.extend({
    content: "",
    layout: layout,

    lang: {
        preview: "Preview",
        editor: "Editor",
        fullscreen: "Click to toggle fullscreen"
    },

    onInit: Ember.on('didInsertElement', function() {
        this.updateLayout();
    }),

    onTyping: Ember.observer('content', function() {
        this.updateLayout();
    }),

    updateLayout: function() {
        var lines = this.get("content").split('\n');
        var height = lines.length * 15;
        var previewHeight = this.$('.em-markdown-preview').css('height');

        if (previewHeight > height) {
            height = previewHeight;
        }

        this.$('textarea, .em-markdown-output').css('height', height);

    },

    doubleClick: function() {
        this.$().children().toggleClass("fullscreen");
    },

    drop: function(ev) {
        ev.preventDefault();
        this.sendAction("upload", ev);
        Ember.debug("you dropped something");
    },

    dragEnter: function() {
        this.$('.em-markdown-editor').addClass("drop-file-enter");
    },

    dragLeave: function() {
        this.$('.em-markdown-editor').removeClass("drop-file-enter");
    },

    dragOver: function() {
        this.$('.em-markdown-editor').addClass("drop-file-enter");
    },

    actions: {
        toggleFullscreen: function() {
            this.doubleClick();
        }
    }
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import HasBlockMixin from '../mixins/hasblock-mixin';
import { promiseArray } from 'ember-paper/utils/promise-proxies';

function isString(item) {
  return typeof item === 'string' || item instanceof String;
}

/**
 * @name paper-autocomplete
 *
 * @description
 *     Provides material design autocomplete.
 *
 *
 * ## Dependencies
 * - paper-autocomplete-item
 * - paper-autocomplete-list
 * - paper-input
 * - paper-button
 * - input
 */
export default Ember.Component.extend(HasBlockMixin, {
  util: Ember.inject.service(),
  constants: Ember.inject.service(),

  tagName: 'md-autocomplete',
  classNameBindings: ['notFloating:md-default-theme'],
  attributeBindings: ['floating:md-floating-label', 'showDisabled:disabled'],

  // Internal
  hidden: true,
  selectedIndex: 0,
  messages: [],
  noBlur: false,
  hasFocus: false,
  searchText: '',
  // wrap in a computed property so that cache
  // isn't shared among autocomplete instances
  itemCache: Ember.computed(function() {
    return {};
  }),

  // Public
  disabled: null,
  required: null,
  lookupKey: null,
  placeholder: '',
  delay: 0,
  minLength: 1,
  allowNonExisting: false,
  noCache: false,
  notFoundMessage: 'No matches found for \'%@\'.',

  init() {
    this._super(...arguments);

    if (this.get('model')) {
      this.set('searchText', this.lookupLabelOfItem(this.get('model')));
      this.searchTextDidChange();
    }
  },

  notFloating: Ember.computed.not('floating'),
  notHidden: Ember.computed.not('hidden'),

  autocompleteWrapperId: Ember.computed('elementId', function() {
    return 'autocomplete-wrapper-' + this.get('elementId');
  }),

  sections: {
    itemTemplate: {isItemTemplate: true},
    notFoundTemplate: {isNotFoundTemplate: true}
  },

  notFoundMsg: Ember.computed('searchText', 'notFoundMessage', function() {
    return Ember.String.fmt(this.get('notFoundMessage'), [this.get('searchText')]);
  }),

  /**
   * Needed because of false = disabled='false'.
   */
  showDisabled: Ember.computed('disabled', function() {
    if (this.get('disabled')) {
      return true;
    }
  }),

  showLoadingBar: Ember.computed('loading', 'allowNonExisting', 'debouncingState', function() {
    return !this.get('loading') && !this.get('allowNonExisting') && !this.get('debouncingState');
  }),

  enableClearButton: Ember.computed('searchText', 'disabled', function() {
    return this.get('searchText') && !this.get('disabled');
  }),

  /**
   * Source filtering logic
   */

  searchTextDidChange: Ember.observer('searchText', function() {
    var searchText = this.get('searchText');
    if (searchText !== this.get('previousSearchText')) {
      if (!this.get('allowNonExisting')) {
        this.set('model', null);
      } else {
        this.set('model', searchText);
      }

      this.sendAction('update-filter', searchText);

      this.set('debouncingState', true);
      Ember.run.debounce(this, this.setDebouncedSearchText, this.get('delay'));
      this.set('previousSearchText', searchText);
    }
  }),

  modelDidChange: Ember.observer('model', function() {
    var model = this.get("model");
    var value = this.lookupLabelOfItem(model);
    // First set previousSearchText then searchText ( do not trigger observer only update value! ).
    this.set('previousSearchText', value);
    this.set('searchText', value);
    this.set('hidden', true);
  }),

  setDebouncedSearchText() {
    var searchText = this.get('searchText');
    if (this.get('isMinLengthMet')) {
      this.sendAction('debounced-update-filter', searchText);
      if (!this.cacheGet(searchText)) {
        this.sendAction('cache-miss', searchText);
      } else {
        this.sendAction('cache-hit', searchText);
      }
      this.set('debouncedSearchText', searchText);

      // If the autocomplete is being triggered by a human / not on initial render.
      if (this.get('hasFocus') || this.get('noBlur')) {
        this.set('hidden', false);
      }
    } else {
      this.set('hidden', true);
    }
    this.set('debouncingState', false);
  },

  loading: Ember.computed.bool('sourcePromiseArray.isPending').readOnly(),

  //coalesces all promises into PromiseArrays or Arrays
  sourcePromiseArray: Ember.computed('source', function() {
    var source = this.get('source');
    if (source && source.then) {
      //coalesce into promise array
      return promiseArray(source);
    } else if (Ember.isArray(source)) {
      //return array
      return Ember.A(source);
    } else {
      //Unknown source type
      Ember.assert('The provided \'source\' for paper-autocomplete must be an Array or a Promise.', !Ember.isPresent(source));
      return Ember.A();
    }
  }).readOnly(),

  suggestions: Ember.computed('debouncedSearchText', 'sourcePromiseArray.[]', function() {
    var source = this.get('sourcePromiseArray');
    var lookupKey = this.get('lookupKey');
    var searchText = (this.get('debouncedSearchText') || '').toLowerCase();
    var cachedItems = this.cacheGet(searchText);
    var suggestions;

    if (cachedItems) {
      //We have cached results
      suggestions = cachedItems;
    } else {
      //no cache

      var data = this.filterArray(source, searchText, lookupKey);
      if (source.then && source.get('isFulfilled')) {
        //cache when we have a PromiseArray
        this.cacheSet(searchText, data);
      }
      suggestions = Ember.A(data);
    }
    // If we have no item suggestions, and allowNonExisting is enabled
    // We need to close the paper-autocomplete-list so all mouse events get activated again.
    if (suggestions.length === 0 && this.get('allowNonExisting')){
      this.set('hidden', true);
    }
    return suggestions;
  }).readOnly(),

  filterArray(array, searchText, lookupKey) {
    return array.filter(function(item) {
      Ember.assert('You have not defined \'lookupKey\' on paper-autocomplete, when source contained ' +
        'items that are not of type String. To fix this error provide a ' +
        'lookupKey=\'key to lookup from source item\'.', isString(item) || Ember.isPresent(lookupKey));

      Ember.assert('You specified \'' + lookupKey + '\' as a lookupKey on paper-autocomplete, ' +
        'but at least one of its values is not of type String. To fix this error make sure that every \'' + lookupKey +
        '\' value is a string.', isString(item) || (Ember.isPresent(lookupKey) && isString(Ember.get(item, lookupKey))) );

      var search = isString(item) ? item.toLowerCase() : Ember.get(item, lookupKey).toLowerCase();
      return search.indexOf(searchText) === 0;
    });
  },

  //TODO move cache to service? Components are not singletons.
  cacheGet(text) {
    return !this.get('noCache') && this.get('itemCache')[text];
  },

  cacheSet(text, data) {
    this.get('itemCache')[text] = data;
  },

  shouldHide: Ember.computed.not('isMinLengthMet'),

  isMinLengthMet: Ember.computed('searchText', 'minLength', function() {
   return this.get('searchText').length >= this.get('minLength');
  }),

  /**
   * Returns the default index based on whether or not autoselect is enabled.
   * @returns {number}
   */
  defaultIndex: Ember.computed('autoselect', function() {
    return this.get('autoselect') ? 0 : -1;
  }),

  lookupLabelOfItem(model) {
    return this.get('lookupKey') ? Ember.get(model, this.get('lookupKey')) : model;
  },

  actions: {
    clear() {
      this.set('searchText', '');
      this.set('selectedIndex', -1);
      this.set('model', null);
      this.set('hidden', this.get('shouldHide'));
    },

    pickModel(model) {
      this.set('model', model);
      var value = this.lookupLabelOfItem(model);
      // First set previousSearchText then searchText ( do not trigger observer only update value! ).
      this.set('previousSearchText', value);
      this.set('searchText', value);
      this.set('hidden', true);
    },

    inputFocusOut() {
      this.set('hasFocus', false);
      if (this.get('noBlur') === false) {
        this.set('hidden', true);
      }
    },

    inputFocusIn() {
      this.set('hasFocus', true);
      this.set('hidden', this.get('shouldHide'));
    },

    inputKeyDown(value, event) {
      switch (event.keyCode) {
        case this.get('constants').KEYCODE.DOWN_ARROW:
          if (this.get('loading')) {
            return;
          }
          this.set('selectedIndex', Math.min(this.get('selectedIndex') + 1, this.get('suggestions').length - 1));
          break;
        case this.get('constants').KEYCODE.UP_ARROW:
          if (this.get('loading')) {
            return;
          }
          this.set('selectedIndex', this.get('selectedIndex') < 0 ? this.get('suggestions').length - 1 : Math.max(0, this.get('selectedIndex') - 1));
          break;
        case this.get('constants').KEYCODE.TAB:
        case this.get('constants').KEYCODE.ENTER:
          if (this.get('hidden') || this.get('loading') || this.get('selectedIndex') < 0 || this.get('suggestions').length < 1) {
            return;
          }
          this.send('pickModel', this.get('suggestions').objectAt(this.get('selectedIndex')));
          break;
        case this.get('constants').KEYCODE.ESCAPE:
          this.set('searchText', '');
          this.set('selectedIndex', this.get('defaultIndex'));
          this.set('model', null);
          this.set('hidden', this.get('shouldHide'));
          break;
        default:
          break;
      }
    },

    listMouseEnter() {
      this.set('noBlur', true);
    },

    listMouseLeave() {
      this.set('noBlur', false);
      if (this.get('hasFocus') === false) {
        this.set('hidden', true);
      }
    },

    listMouseUp() {
      this.$().find('input').focus();
    }
  }

});
<commit_msg>Update paper-autocomplete.js<commit_after>import Ember from 'ember';
import HasBlockMixin from '../mixins/hasblock-mixin';
import { promiseArray } from 'ember-paper/utils/promise-proxies';

function isString(item) {
  return typeof item === 'string' || item instanceof String;
}

/**
 * @name paper-autocomplete
 *
 * @description
 *     Provides material design autocomplete.
 *
 *
 * ## Dependencies
 * - paper-autocomplete-item
 * - paper-autocomplete-list
 * - paper-input
 * - paper-button
 * - input
 */
export default Ember.Component.extend(HasBlockMixin, {
  util: Ember.inject.service(),
  constants: Ember.inject.service(),

  tagName: 'md-autocomplete',
  classNameBindings: ['notFloating:md-default-theme'],
  attributeBindings: ['floating:md-floating-label', 'showDisabled:disabled'],

  // Internal
  hidden: true,
  selectedIndex: 0,
  messages: [],
  noBlur: false,
  hasFocus: false,
  searchText: '',
  // wrap in a computed property so that cache
  // isn't shared among autocomplete instances
  itemCache: Ember.computed(function() {
    return {};
  }),

  // Public
  disabled: null,
  required: null,
  lookupKey: null,
  placeholder: '',
  delay: 0,
  minLength: 1,
  allowNonExisting: false,
  noCache: false,
  notFoundMessage: 'No matches found for \'%@\'.',

  init() {
    this._super(...arguments);

    if (this.get('model')) {
      this.set('searchText', this.lookupLabelOfItem(this.get('model')));
      this.searchTextDidChange();
    }
  },

  notFloating: Ember.computed.not('floating'),
  notHidden: Ember.computed.not('hidden'),

  autocompleteWrapperId: Ember.computed('elementId', function() {
    return 'autocomplete-wrapper-' + this.get('elementId');
  }),

  sections: {
    itemTemplate: {isItemTemplate: true},
    notFoundTemplate: {isNotFoundTemplate: true}
  },

  notFoundMsg: Ember.computed('searchText', 'notFoundMessage', function() {
    return Ember.String.fmt(this.get('notFoundMessage'), [this.get('searchText')]);
  }),

  /**
   * Needed because of false = disabled='false'.
   */
  showDisabled: Ember.computed('disabled', function() {
    if (this.get('disabled')) {
      return true;
    }
  }),

  showLoadingBar: Ember.computed('loading', 'allowNonExisting', 'debouncingState', function() {
    return !this.get('loading') && !this.get('allowNonExisting') && !this.get('debouncingState');
  }),

  enableClearButton: Ember.computed('searchText', 'disabled', function() {
    return this.get('searchText') && !this.get('disabled');
  }),

  /**
   * Source filtering logic
   */

  searchTextDidChange: Ember.observer('searchText', function() {
    var searchText = this.get('searchText');
    if (searchText !== this.get('previousSearchText')) {
      if (!this.get('allowNonExisting')) {
        this.set('model', null);
      } else {
        this.set('model', searchText);
      }

      this.sendAction('update-filter', searchText);

      this.set('debouncingState', true);
      Ember.run.debounce(this, this.setDebouncedSearchText, this.get('delay'));
      this.set('previousSearchText', searchText);
    }
  }),

  modelDidChange: Ember.observer('model', function() {
    var model = this.get('model');
    var value = this.lookupLabelOfItem(model);
    // First set previousSearchText then searchText ( do not trigger observer only update value! ).
    this.set('previousSearchText', value);
    this.set('searchText', value);
    this.set('hidden', true);
  }),

  setDebouncedSearchText() {
    var searchText = this.get('searchText');
    if (this.get('isMinLengthMet')) {
      this.sendAction('debounced-update-filter', searchText);
      if (!this.cacheGet(searchText)) {
        this.sendAction('cache-miss', searchText);
      } else {
        this.sendAction('cache-hit', searchText);
      }
      this.set('debouncedSearchText', searchText);

      // If the autocomplete is being triggered by a human / not on initial render.
      if (this.get('hasFocus') || this.get('noBlur')) {
        this.set('hidden', false);
      }
    } else {
      this.set('hidden', true);
    }
    this.set('debouncingState', false);
  },

  loading: Ember.computed.bool('sourcePromiseArray.isPending').readOnly(),

  //coalesces all promises into PromiseArrays or Arrays
  sourcePromiseArray: Ember.computed('source', function() {
    var source = this.get('source');
    if (source && source.then) {
      //coalesce into promise array
      return promiseArray(source);
    } else if (Ember.isArray(source)) {
      //return array
      return Ember.A(source);
    } else {
      //Unknown source type
      Ember.assert('The provided \'source\' for paper-autocomplete must be an Array or a Promise.', !Ember.isPresent(source));
      return Ember.A();
    }
  }).readOnly(),

  suggestions: Ember.computed('debouncedSearchText', 'sourcePromiseArray.[]', function() {
    var source = this.get('sourcePromiseArray');
    var lookupKey = this.get('lookupKey');
    var searchText = (this.get('debouncedSearchText') || '').toLowerCase();
    var cachedItems = this.cacheGet(searchText);
    var suggestions;

    if (cachedItems) {
      //We have cached results
      suggestions = cachedItems;
    } else {
      //no cache

      var data = this.filterArray(source, searchText, lookupKey);
      if (source.then && source.get('isFulfilled')) {
        //cache when we have a PromiseArray
        this.cacheSet(searchText, data);
      }
      suggestions = Ember.A(data);
    }
    // If we have no item suggestions, and allowNonExisting is enabled
    // We need to close the paper-autocomplete-list so all mouse events get activated again.
    if (suggestions.length === 0 && this.get('allowNonExisting')){
      this.set('hidden', true);
    }
    return suggestions;
  }).readOnly(),

  filterArray(array, searchText, lookupKey) {
    return array.filter(function(item) {
      Ember.assert('You have not defined \'lookupKey\' on paper-autocomplete, when source contained ' +
        'items that are not of type String. To fix this error provide a ' +
        'lookupKey=\'key to lookup from source item\'.', isString(item) || Ember.isPresent(lookupKey));

      Ember.assert('You specified \'' + lookupKey + '\' as a lookupKey on paper-autocomplete, ' +
        'but at least one of its values is not of type String. To fix this error make sure that every \'' + lookupKey +
        '\' value is a string.', isString(item) || (Ember.isPresent(lookupKey) && isString(Ember.get(item, lookupKey))) );

      var search = isString(item) ? item.toLowerCase() : Ember.get(item, lookupKey).toLowerCase();
      return search.indexOf(searchText) === 0;
    });
  },

  //TODO move cache to service? Components are not singletons.
  cacheGet(text) {
    return !this.get('noCache') && this.get('itemCache')[text];
  },

  cacheSet(text, data) {
    this.get('itemCache')[text] = data;
  },

  shouldHide: Ember.computed.not('isMinLengthMet'),

  isMinLengthMet: Ember.computed('searchText', 'minLength', function() {
   return this.get('searchText').length >= this.get('minLength');
  }),

  /**
   * Returns the default index based on whether or not autoselect is enabled.
   * @returns {number}
   */
  defaultIndex: Ember.computed('autoselect', function() {
    return this.get('autoselect') ? 0 : -1;
  }),

  lookupLabelOfItem(model) {
    return this.get('lookupKey') ? Ember.get(model, this.get('lookupKey')) : model;
  },

  actions: {
    clear() {
      this.set('searchText', '');
      this.set('selectedIndex', -1);
      this.set('model', null);
      this.set('hidden', this.get('shouldHide'));
    },

    pickModel(model) {
      this.set('model', model);
      var value = this.lookupLabelOfItem(model);
      // First set previousSearchText then searchText ( do not trigger observer only update value! ).
      this.set('previousSearchText', value);
      this.set('searchText', value);
      this.set('hidden', true);
    },

    inputFocusOut() {
      this.set('hasFocus', false);
      if (this.get('noBlur') === false) {
        this.set('hidden', true);
      }
    },

    inputFocusIn() {
      this.set('hasFocus', true);
      this.set('hidden', this.get('shouldHide'));
    },

    inputKeyDown(value, event) {
      switch (event.keyCode) {
        case this.get('constants').KEYCODE.DOWN_ARROW:
          if (this.get('loading')) {
            return;
          }
          this.set('selectedIndex', Math.min(this.get('selectedIndex') + 1, this.get('suggestions').length - 1));
          break;
        case this.get('constants').KEYCODE.UP_ARROW:
          if (this.get('loading')) {
            return;
          }
          this.set('selectedIndex', this.get('selectedIndex') < 0 ? this.get('suggestions').length - 1 : Math.max(0, this.get('selectedIndex') - 1));
          break;
        case this.get('constants').KEYCODE.TAB:
        case this.get('constants').KEYCODE.ENTER:
          if (this.get('hidden') || this.get('loading') || this.get('selectedIndex') < 0 || this.get('suggestions').length < 1) {
            return;
          }
          this.send('pickModel', this.get('suggestions').objectAt(this.get('selectedIndex')));
          break;
        case this.get('constants').KEYCODE.ESCAPE:
          this.set('searchText', '');
          this.set('selectedIndex', this.get('defaultIndex'));
          this.set('model', null);
          this.set('hidden', this.get('shouldHide'));
          break;
        default:
          break;
      }
    },

    listMouseEnter() {
      this.set('noBlur', true);
    },

    listMouseLeave() {
      this.set('noBlur', false);
      if (this.get('hasFocus') === false) {
        this.set('hidden', true);
      }
    },

    listMouseUp() {
      this.$().find('input').focus();
    }
  }

});
<|endoftext|>


<commit_before>/*---------------------------------------------------------
 * OpenERP base library
 *---------------------------------------------------------*/

openerp.base.view_tree = function(openerp) {

openerp.base.views.add('tree', 'openerp.base.TreeView');
/**
 * Genuine tree view (the one displayed as a tree, not the list)
 */
openerp.base.TreeView = openerp.base.View.extend({
    /**
     * Indicates that this view is not searchable, and thus that no search
     * view should be displayed (if there is one active).
     */
    searchable : false,

    init: function(parent, element_id, dataset, view_id, options) {
        this._super(parent, element_id);
        this.dataset = dataset;
        this.model = dataset.model;
        this.view_id = view_id;

        this.records = {};

        this.options = _.extend({}, this.defaults, options || {});
    },

    start: function () {
        this._super();
        return this.rpc("/base/treeview/load", {
            model: this.model,
            view_id: this.view_id,
            toolbar: this.view_manager ? !!this.view_manager.sidebar : false
        }, this.on_loaded);
    },
    /**
     * Returns the list of fields needed to correctly read objects.
     *
     * Gathers the names of all fields in fields_view_get, and adds the
     * field_parent (children_field in the tree view) if it's not already one
     * of the fields to fetch
     *
     * @returns {Array} an array of fields which can be provided to DataSet.read_slice and others
     */
    fields_list: function () {
        var fields = _.keys(this.fields);
        if (!_(fields).contains(this.children_field)) {
            fields.push(this.children_field);
        }
        return fields;
    },
    on_loaded: function (fields_view) {
        var self = this;
        var has_toolbar = !!fields_view.arch.attrs.toolbar;
        // field name in OpenERP is kinda stupid: this is the name of the field
        // holding the ids to the children of the current node, why call it
        // field_parent?
        this.children_field = fields_view['field_parent'];
        this.fields_view = fields_view;
        _(this.fields_view.arch.children).each(function (field) {
            if (field.attrs.modifiers) {
                field.attrs.modifiers = JSON.parse(field.attrs.modifiers);
            }
        });
        this.fields = fields_view.fields;
        this.hook_row_click();
        this.$element.html(QWeb.render('TreeView', {
            'title': this.fields_view.arch.attrs.string,
            'fields_view': this.fields_view.arch.children,
            'fields': this.fields,
            'toolbar': has_toolbar
        }));

        this.dataset.read_slice(this.fields_list(), 0, false, function (records) {
            if (!has_toolbar) {
                // WARNING: will do a second read on the same ids, but only on
                //          first load so not very important
                self.getdata(null, _(records).pluck('id'));
                return;
            }

            var $select = self.$element.find('select')
                .change(function () {
                    var $option = $(this).find(':selected');
                    self.getdata($option.val(), $option.data('children'));
                });
            _(records).each(function (record) {
                self.records[record.id] = record;
                $('<option>')
                        .val(record.id)
                        .text(record.name)
                        .data('children', record[self.children_field])
                    .appendTo($select);
            });

            $select.change();
        });
    },
    /**
     * Sets up opening a row
     */
    hook_row_click: function () {
        var self = this;
        this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
            e.stopImmediatePropagation();
            self.activate($(this).closest('tr').data('id'));
        });

        this.$element.delegate('.treeview-tr', 'click', function () {
            var is_loaded = 0,
                $this = $(this),
                record_id = $this.data('id'),
                record = self.records[record_id],
                children_ids = record[self.children_field];

            _(children_ids).each(function(childid) {
                if (self.$element.find('#treerow_' + childid).length) {
                    if (self.$element.find('#treerow_' + childid).is(':hidden')) {
                        is_loaded = -1;
                    } else {
                        is_loaded++;
                    }
                }
            });
            if (is_loaded === 0) {
                if (!$this.parent().hasClass('oe-open')) {
                    self.getdata(record_id, children_ids);
                }
            } else {
                self.showcontent(record_id, is_loaded < 0);
            }
        });
    },
    // get child data of selected value
    getdata: function (id, children_ids) {
        var self = this;

        self.dataset.read_ids(children_ids, this.fields_list(), function (records) {
            _(records).each(function (record) {
                self.records[record.id] = record;
            });

            var $curr_node = self.$element.find('#treerow_' + id);
            var children_rows = QWeb.render('TreeView.rows', {
                'records': records,
                'children_field': self.children_field,
                'fields_view': self.fields_view.arch.children,
                'fields': self.fields,
                'level': $curr_node.data('level') || 0,
                'render': openerp.base.format_value
            });

            if ($curr_node.length) {
                $curr_node.addClass('oe-open');
                $curr_node.after(children_rows);
            } else {
                self.$element.find('tbody').html(children_rows);
            }
        });
    },

    // Get details in listview
    activate: function(id) {
        var self = this;
        this.rpc('/base/treeview/action', {
            id: id,
            model: this.dataset.model,
            context: new openerp.base.CompoundContext(
                this.dataset.get_context(), {
                    active_model: this.dataset.model,
                    active_id: id,
                    active_ids: [id]})
        }, function (actions) {
            if (!actions.length) { return; }
            var action = actions[0][2];
            action.flags.new_window = true;
            self.session.action_manager.do_action(action);
        });
    },

    // show & hide the contents
    showcontent: function (record_id, show) {
        this.$element.find('#treerow_' + record_id)
                .toggleClass('oe-open', show);

        _(this.records[record_id][this.children_field]).each(function (child_id) {
            var $child_row = this.$element.find('#treerow_' + child_id);
            if ($child_row.hasClass('oe-open')) {
                this.showcontent(child_id, false);
            }
            $child_row.toggle(show);
        }, this);
    },

    do_show: function () {
        this.$element.show();
    },

    do_hide: function () {
        this.$element.hide();
        this.hidden = true;
    }
});
};
<commit_msg>[FIX] don't blow up when there are no records in the theeview<commit_after>/*---------------------------------------------------------
 * OpenERP base library
 *---------------------------------------------------------*/

openerp.base.view_tree = function(openerp) {

openerp.base.views.add('tree', 'openerp.base.TreeView');
/**
 * Genuine tree view (the one displayed as a tree, not the list)
 */
openerp.base.TreeView = openerp.base.View.extend({
    /**
     * Indicates that this view is not searchable, and thus that no search
     * view should be displayed (if there is one active).
     */
    searchable : false,

    init: function(parent, element_id, dataset, view_id, options) {
        this._super(parent, element_id);
        this.dataset = dataset;
        this.model = dataset.model;
        this.view_id = view_id;

        this.records = {};

        this.options = _.extend({}, this.defaults, options || {});
    },

    start: function () {
        this._super();
        return this.rpc("/base/treeview/load", {
            model: this.model,
            view_id: this.view_id,
            toolbar: this.view_manager ? !!this.view_manager.sidebar : false
        }, this.on_loaded);
    },
    /**
     * Returns the list of fields needed to correctly read objects.
     *
     * Gathers the names of all fields in fields_view_get, and adds the
     * field_parent (children_field in the tree view) if it's not already one
     * of the fields to fetch
     *
     * @returns {Array} an array of fields which can be provided to DataSet.read_slice and others
     */
    fields_list: function () {
        var fields = _.keys(this.fields);
        if (!_(fields).contains(this.children_field)) {
            fields.push(this.children_field);
        }
        return fields;
    },
    on_loaded: function (fields_view) {
        var self = this;
        var has_toolbar = !!fields_view.arch.attrs.toolbar;
        // field name in OpenERP is kinda stupid: this is the name of the field
        // holding the ids to the children of the current node, why call it
        // field_parent?
        this.children_field = fields_view['field_parent'];
        this.fields_view = fields_view;
        _(this.fields_view.arch.children).each(function (field) {
            if (field.attrs.modifiers) {
                field.attrs.modifiers = JSON.parse(field.attrs.modifiers);
            }
        });
        this.fields = fields_view.fields;
        this.hook_row_click();
        this.$element.html(QWeb.render('TreeView', {
            'title': this.fields_view.arch.attrs.string,
            'fields_view': this.fields_view.arch.children,
            'fields': this.fields,
            'toolbar': has_toolbar
        }));

        this.dataset.read_slice(this.fields_list(), 0, false, function (records) {
            if (!has_toolbar) {
                // WARNING: will do a second read on the same ids, but only on
                //          first load so not very important
                self.getdata(null, _(records).pluck('id'));
                return;
            }

            var $select = self.$element.find('select')
                .change(function () {
                    var $option = $(this).find(':selected');
                    self.getdata($option.val(), $option.data('children'));
                });
            _(records).each(function (record) {
                self.records[record.id] = record;
                $('<option>')
                        .val(record.id)
                        .text(record.name)
                        .data('children', record[self.children_field])
                    .appendTo($select);
            });

            if (!_.isEmpty(records)) {
                $select.change();
            }
        });
    },
    /**
     * Sets up opening a row
     */
    hook_row_click: function () {
        var self = this;
        this.$element.delegate('.treeview-td span, .treeview-tr span', 'click', function (e) {
            e.stopImmediatePropagation();
            self.activate($(this).closest('tr').data('id'));
        });

        this.$element.delegate('.treeview-tr', 'click', function () {
            var is_loaded = 0,
                $this = $(this),
                record_id = $this.data('id'),
                record = self.records[record_id],
                children_ids = record[self.children_field];

            _(children_ids).each(function(childid) {
                if (self.$element.find('#treerow_' + childid).length) {
                    if (self.$element.find('#treerow_' + childid).is(':hidden')) {
                        is_loaded = -1;
                    } else {
                        is_loaded++;
                    }
                }
            });
            if (is_loaded === 0) {
                if (!$this.parent().hasClass('oe-open')) {
                    self.getdata(record_id, children_ids);
                }
            } else {
                self.showcontent(record_id, is_loaded < 0);
            }
        });
    },
    // get child data of selected value
    getdata: function (id, children_ids) {
        var self = this;

        self.dataset.read_ids(children_ids, this.fields_list(), function (records) {
            _(records).each(function (record) {
                self.records[record.id] = record;
            });

            var $curr_node = self.$element.find('#treerow_' + id);
            var children_rows = QWeb.render('TreeView.rows', {
                'records': records,
                'children_field': self.children_field,
                'fields_view': self.fields_view.arch.children,
                'fields': self.fields,
                'level': $curr_node.data('level') || 0,
                'render': openerp.base.format_value
            });

            if ($curr_node.length) {
                $curr_node.addClass('oe-open');
                $curr_node.after(children_rows);
            } else {
                self.$element.find('tbody').html(children_rows);
            }
        });
    },

    // Get details in listview
    activate: function(id) {
        var self = this;
        this.rpc('/base/treeview/action', {
            id: id,
            model: this.dataset.model,
            context: new openerp.base.CompoundContext(
                this.dataset.get_context(), {
                    active_model: this.dataset.model,
                    active_id: id,
                    active_ids: [id]})
        }, function (actions) {
            if (!actions.length) { return; }
            var action = actions[0][2];
            action.flags.new_window = true;
            self.session.action_manager.do_action(action);
        });
    },

    // show & hide the contents
    showcontent: function (record_id, show) {
        this.$element.find('#treerow_' + record_id)
                .toggleClass('oe-open', show);

        _(this.records[record_id][this.children_field]).each(function (child_id) {
            var $child_row = this.$element.find('#treerow_' + child_id);
            if ($child_row.hasClass('oe-open')) {
                this.showcontent(child_id, false);
            }
            $child_row.toggle(show);
        }, this);
    },

    do_show: function () {
        this.$element.show();
    },

    do_hide: function () {
        this.$element.hide();
        this.hidden = true;
    }
});
};
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var webpack = require('webpack');

module.exports = function(config) {
  config.set({
    frameworks: ['mocha', 'chai'],
    files: [
      'node_modules/babel-polyfill/dist/polyfill.js',
      'test/*test.js',
      'test/**/*test.js'
    ],

    preprocessors: {
      '*test.js': ['babel', 'webpack', 'sourcemap'],
      '**/*test.js': ['babel', 'webpack', 'sourcemap']
    },

    client: {
      captureConsole: true
    },

    browsers: ['ChromeHeadless', 'FirefoxHeadless'],

    // see https://github.com/karma-runner/karma-firefox-launcher/issues/76
    customLaunchers: {
      FirefoxHeadless: {
        base: 'Firefox',
        flags: [ '-headless' ],
      },
    },

    webpack: {
      devtool: 'inline-source-map',
      module: {
        rules: [{
          test: /\.js$/,
          exclude: /node_modules/,
          use: 'babel-loader'
        }, {
          test: /\.mustache$/,
          use: 'mustache-loader'
        }]
      },
      resolve: {
        modules: ['node_modules']
      },
      plugins: [
        new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery"
        })
      ]
    },

    webpackServer: {
      noInfo: true
    },

    plugins: [
      require('karma-babel-preprocessor'),
      require('karma-webpack'),
      require('karma-mocha'),
      require('karma-chai'),
      require('karma-chrome-launcher'),
      require('karma-firefox-launcher'),
      require('karma-sourcemap-loader')
    ]
  });
};
<commit_msg>Removes ChromeHeadless from zipkin-ui test setup<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var webpack = require('webpack');

module.exports = function(config) {
  config.set({
    frameworks: ['mocha', 'chai'],
    files: [
      'node_modules/babel-polyfill/dist/polyfill.js',
      'test/*test.js',
      'test/**/*test.js'
    ],

    preprocessors: {
      '*test.js': ['babel', 'webpack', 'sourcemap'],
      '**/*test.js': ['babel', 'webpack', 'sourcemap']
    },

    client: {
      captureConsole: true
    },

    browsers: ['FirefoxHeadless'],

    // see https://github.com/karma-runner/karma-firefox-launcher/issues/76
    customLaunchers: {
      FirefoxHeadless: {
        base: 'Firefox',
        flags: [ '-headless' ],
      },
    },

    webpack: {
      devtool: 'inline-source-map',
      module: {
        rules: [{
          test: /\.js$/,
          exclude: /node_modules/,
          use: 'babel-loader'
        }, {
          test: /\.mustache$/,
          use: 'mustache-loader'
        }]
      },
      resolve: {
        modules: ['node_modules']
      },
      plugins: [
        new webpack.ProvidePlugin({
          $: "jquery",
          jQuery: "jquery"
        })
      ]
    },

    webpackServer: {
      noInfo: true
    },

    plugins: [
      require('karma-babel-preprocessor'),
      require('karma-webpack'),
      require('karma-mocha'),
      require('karma-chai'),
      require('karma-chrome-launcher'),
      require('karma-firefox-launcher'),
      require('karma-sourcemap-loader')
    ]
  });
};
<|endoftext|>


<commit_before>var player, isoGroup, cursorPos;

var turnState = true;
var moveCT = 0;
var moveWait = 8;
var move = false;
var enemyMoveCT = 0;

var Game = {
    preload: function() {
        game.stage.backgroundColor = 0x777777;

        game.time.advancedTiming = true;

        game.plugins.add(new Phaser.Plugin.Isometric(game));
        game.iso.anchor.setTo(0.5, 0.2);

        game.load.image('tile', './assets/img/tileBorder.png');
        game.load.image('player', './assets/img/alienPink.png');
        game.load.image('enemy', './assets/img/alienBlue.png');
    },

    create: function() {
        isoGroup = game.add.group();
        playerGroup = game.add.group();
        enemyGroup = game.add.group();

        /*player = game.add.isoSprite(-8, -10, 32, 'player', 0, playerGroup);
        player.movement = new this.Movement(player);
        player.anchor.set(0.5, 0);*/
        player = new Entity('player');
        player.add('sprite', new Sprite(-8, -10, 32, 'player', 0, playerGroup));
        player.add('movement', new Movement());

        this.spawnTiles();
        this.spawnEnemies();

        cursorPos = new Phaser.Plugin.Isometric.Point3();

        this.cursors = game.input.keyboard.createCursorKeys();

        game.input.keyboard.addKeyCapture([
            Phaser.Keyboard.LEFT,
            Phaser.Keyboard.RIGHT,
            Phaser.Keyboard.UP,
            Phaser.Keyboard.DOWN,
            Phaser.Keyboard.W,
            Phaser.Keyboard.A,
            Phaser.Keyboard.S,
            Phaser.Keyboard.D,
        ]);

        //game.iso.topologicalSort(isoGroup);
    },

    update: function() {
        game.iso.unproject(game.input.activePointer.position, cursorPos);

        isoGroup.forEach(function(tile) {
            tile.collision.highlight();
        });

        enemyGroup.forEach(function(enemy) {
            enemy.collision.highlight();
            enemy.collision.damage();
        });

        if (turnState) {
            if ((this.cursors.up.isDown || game.input.keyboard.isDown(Phaser.Keyboard.W)) && player.isoY > 0 && !move) {
                player.movement.moveUp();
                move = true;
            }
            else if ((this.cursors.down.isDown || game.input.keyboard.isDown(Phaser.Keyboard.S)) && player.isoY < 256 - 64 && !move) {
                player.movement.moveDown();
                move = true;
            }

            if ((this.cursors.left.isDown || game.input.keyboard.isDown(Phaser.Keyboard.A)) && player.isoX > 0 && !move) {
                player.movement.moveLeft();
                move = true;
            }
            else if ((this.cursors.right.isDown || game.input.keyboard.isDown(Phaser.Keyboard.D)) && player.isoX < 256 - 64 && !move) {
                player.movement.moveRight();
                move = true;
            }

            if (move) {
                move = false;
                turnState = false;
            }

            /*if (moveCT >= moveWait) {
                moveCT = 0;
                move = false;
            }

            if (move) {
                moveCT++;
            }*/
        }
        if (!turnState) {
            if (enemyMoveCT >= moveWait) {
                enemyMoveCT = 0;
                this.moveEnemies();
                turnState = true;
            }
            else {
                enemyMoveCT++;
            }
        }

        enemyGroup.forEach(function(enemy) {
            enemyGroup.forEach(function(enemy2) {
                if (enemy.isoX == enemy2.isoX && enemy.isoY == enemy2.isoY && enemy != enemy2) {
                    switch(enemy.oldType) {
                        case 0:
                            enemy.isoX = enemy.oldPos;
                            break;
                        case 1:
                            enemy.isoY = enemy.oldPos;
                            break;
                    }
                    switch(enemy2.oldType) {
                        case 0:
                            enemy2.isoX = enemy2.oldPos;
                            break;
                        case 1:
                            enemy2.isoY = enemy2.oldPos;
                            break;
                    }
                }
            })
            if (enemy.isoX == player.isoX && enemy.isoY == player.isoY) {
                switch(enemy.oldType) {
                    case 0:
                        enemy.isoX = enemy.oldPos;
                        break;
                    case 1:
                        enemy.isoY = enemy.oldPos;
                        break;
                }
            }
            if (player.isoX == enemy.isoX && player.isoY == enemy.isoY) {
                enemy.destroy();
            }
        });

        game.iso.simpleSort(isoGroup);
        game.iso.simpleSort(enemyGroup);
        game.iso.simpleSort(playerGroup);
    },

    spawnTiles: function() {
        var tile;
        for (var xx = 0; xx < 256; xx += 32) {
            for (var yy = 0; yy < 256; yy += 32) {
                tile = game.add.isoSprite(xx, yy, 0, 'tile', 0, isoGroup);
                tile.collision = new this.Collision(isoGroup, tile.isoZ, tile.isoZ + 4);
                tile.selected = false;
                tile.anchor.set(0.5, 0);
            }
        }
    },

    spawnEnemies: function() {
        var enemy, rand, rand2;
        var max = 7;
        var min = 0;
        for (var i = 0; i < 4; i++) {
            rand = Math.floor(Math.random() * (max - min + 1)) + min;
            rand2 = Math.floor(Math.random() * (max - min + 1)) + min;
            enemy = game.add.isoSprite(32 * rand - 8, 32 * rand2 - 10, 32, 'enemy', 0, enemyGroup);
            enemy.movement = new this.Movement(enemy);
            enemy.collision = new this.Collision(enemyGroup, enemy.isoZ, enemy.isoZ + 4);
            enemy.anchor.set(0.5, 0);
        }
    },

    moveEnemies: function() {
        var randXY, randDir;
        enemyGroup.forEach(function(enemy) {
            randXY = Math.floor(Math.random() * 2);
            randDir = Math.floor(Math.random() * 2);

            switch(randXY) {
                case 0:
                    enemy.oldPos = enemy.isoX;
                    enemy.oldType = 0;
                    switch(randDir) {
                        case 0:
                            if (enemy.isoX < 256 - 64) {
                                enemy.movement.moveRight();
                            }
                            break;
                        case 1:
                            if (enemy.isoX > 0) {
                                enemy.movement.moveLeft();
                            }
                            break;
                    }
                    break;
                case 1:
                    enemy.oldPos = enemy.isoY;
                    enemy.oldType = 1;
                    switch(randDir) {
                        case 0:
                            if (enemy.isoY < 256 - 64) {
                                enemy.movement.moveDown();
                            }
                            break;
                        case 1:
                            if (enemy.isoY > 0) {
                                enemy.movement.moveUp();
                            }
                            break;
                    }
                    break;
            }
        });
    },

    Collision: function(group, zNormal, zHighlight) {
        this.highlight = function() {
            group.forEach(function(entity) {
                var inBounds = entity.isoBounds.containsXY(cursorPos.x, cursorPos.y);
                if (!entity.selected && inBounds) {
                    entity.selected = true;
                    entity.tint = 0x86bfda;
                    game.add.tween(entity).to({isoZ: zHighlight}, 200, Phaser.Easing.Quadratic.InOut, true);
                }
                else if (entity.selected && !inBounds) {
                    entity.selected = false;
                    entity.tint = 0xffffff;
                    game.add.tween(entity).to({isoZ: zNormal}, 200, Phaser.Easing.Quadratic.InOut, true);
                }
            });
        };
        this.damage = function() {
            group.forEach(function(entity) {
                var inBounds = entity.isoBounds.containsXY(cursorPos.x, cursorPos.y);

                if (entity.selected && inBounds && game.input.activePointer.isDown && Math.abs(player.isoX - entity.isoX) <= 32 && Math.abs(player.isoY - entity.isoY) <= 32) {
                        entity.destroy();
                    }
            });
        };
    },

    Movement: function(entity) {
        this.moveUp = function() {
            entity.isoY -= 32;
            entity.scale.x = 1;
        };
        this.moveDown = function() {
            entity.isoY += 32;
            entity.scale.x = -1;
        };
        this.moveLeft = function() {
            entity.isoX -= 32;
            entity.scale.x = -1;
        };
        this.moveRight = function() {
            entity.isoX += 32;
            entity.scale.x = 1;
        };
    }
};<commit_msg>Tried converting to ECS<commit_after>var tileSize = 32;

var player, isoGroup, cursorPos;
var entities = [];

var turnState = true;
var moveCT = 0;
var moveWait = 8;
var move = false;
var enemyMoveCT = 0;

var Game = {
    preload: function() {
        game.stage.backgroundColor = 0x777777;

        game.time.advancedTiming = true;

        game.plugins.add(new Phaser.Plugin.Isometric(game));
        game.iso.anchor.setTo(0.5, 0.2);

        game.load.image('tile', './assets/img/tileBorder.png');
        game.load.image('player', './assets/img/alienPink.png');
        game.load.image('enemy', './assets/img/alienBlue.png');
    },

    create: function() {
        isoGroup = game.add.group();
        playerGroup = game.add.group();
        enemyGroup = game.add.group();

        /*player = game.add.isoSprite(-8, -10, 32, 'player', 0, playerGroup);
        player.movement = new this.Movement(player);
        player.anchor.set(0.5, 0);*/
        player = new Entity('player');
        player.add(new Sprite(-8, -10, 32, 'player', 0, playerGroup, 0.5, 0), new Movement(tileSize, 1));
        entities.add(player);

        this.spawnTiles();
        this.spawnEnemies();

        cursorPos = new Phaser.Plugin.Isometric.Point3();

        this.cursors = game.input.keyboard.createCursorKeys();

        game.input.keyboard.addKeyCapture([
            Phaser.Keyboard.LEFT,
            Phaser.Keyboard.RIGHT,
            Phaser.Keyboard.UP,
            Phaser.Keyboard.DOWN,
            Phaser.Keyboard.W,
            Phaser.Keyboard.A,
            Phaser.Keyboard.S,
            Phaser.Keyboard.D,
        ]);

        //game.iso.topologicalSort(isoGroup);
    },

    update: function() {
        game.iso.unproject(game.input.activePointer.position, cursorPos);

        /*isoGroup.forEach(function(tile) {
            tile.collision.highlight();
        });*/

        /*enemyGroup.forEach(function(enemy) {
            enemy.collision.highlight();
            enemy.collision.damage();
        });*/

        if (turnState) {
            if ((this.cursors.up.isDown || game.input.keyboard.isDown(Phaser.Keyboard.W)) && player.isoY > 0 && !move) {
                player.movement.moveUp();
                move = true;
            }
            else if ((this.cursors.down.isDown || game.input.keyboard.isDown(Phaser.Keyboard.S)) && player.isoY < 256 - 64 && !move) {
                player.movement.moveDown();
                move = true;
            }

            if ((this.cursors.left.isDown || game.input.keyboard.isDown(Phaser.Keyboard.A)) && player.isoX > 0 && !move) {
                player.movement.moveLeft();
                move = true;
            }
            else if ((this.cursors.right.isDown || game.input.keyboard.isDown(Phaser.Keyboard.D)) && player.isoX < 256 - 64 && !move) {
                player.movement.moveRight();
                move = true;
            }

            if (move) {
                move = false;
                turnState = false;
            }

            /*if (moveCT >= moveWait) {
                moveCT = 0;
                move = false;
            }

            if (move) {
                moveCT++;
            }*/
        }
        if (!turnState) {
            if (enemyMoveCT >= moveWait) {
                enemyMoveCT = 0;
                this.moveEnemies();
                turnState = true;
            }
            else {
                enemyMoveCT++;
            }
        }

        /*enemyGroup.forEach(function(enemy) {
            enemyGroup.forEach(function(enemy2) {
                if (enemy.isoX == enemy2.isoX && enemy.isoY == enemy2.isoY && enemy != enemy2) {
                    switch(enemy.oldType) {
                        case 0:
                            enemy.isoX = enemy.oldPos;
                            break;
                        case 1:
                            enemy.isoY = enemy.oldPos;
                            break;
                    }
                    switch(enemy2.oldType) {
                        case 0:
                            enemy2.isoX = enemy2.oldPos;
                            break;
                        case 1:
                            enemy2.isoY = enemy2.oldPos;
                            break;
                    }
                }
            })
            if (enemy.isoX == player.isoX && enemy.isoY == player.isoY) {
                switch(enemy.oldType) {
                    case 0:
                        enemy.isoX = enemy.oldPos;
                        break;
                    case 1:
                        enemy.isoY = enemy.oldPos;
                        break;
                }
            }
            if (player.isoX == enemy.isoX && player.isoY == enemy.isoY) {
                enemy.destroy();
            }
        });*/

        game.iso.simpleSort(isoGroup);
        game.iso.simpleSort(enemyGroup);
        game.iso.simpleSort(playerGroup);
    },

    spawnTiles: function() {
        var tile;
        for (var xx = 0; xx < 256; xx += tileSize) {
            for (var yy = 0; yy < 256; yy += tileSize) {
                //tile = game.add.isoSprite(xx, yy, 0, 'tile', 0, isoGroup);
                tile = new Entity('tile' + xx + '|' + yy);
                tile.add(new Sprite(xx, yy, 0, 'tile', 0, isoGroup, 0.5, 0));
                entities.add(tile);
                //tile.collision = new this.Collision(isoGroup, tile.isoZ, tile.isoZ + 4);
                //tile.selected = false;
                //tile.anchor.set(0.5, 0);
            }
        }
    },

    spawnEnemies: function() {
        var enemy, rand, rand2;
        var max = 7;
        var min = 0;
        for (var i = 0; i < 4; i++) {
            rand = Math.floor(Math.random() * (max - min + 1)) + min;
            rand2 = Math.floor(Math.random() * (max - min + 1)) + min;
            enemy = new Entity('enemy' + i);
            enemy.add(new Sprite(32 * rand - 8, 32 * rand2 - 10, 32, 'enemy', 0, enemyGroup, 0.5, 0), new Movement(tileSize, 1));
            entities.add(enemy);
            //enemy = game.add.isoSprite(32 * rand - 8, 32 * rand2 - 10, 32, 'enemy', 0, enemyGroup);
            //enemy.movement = new this.Movement(enemy);
            //enemy.collision = new this.Collision(enemyGroup, enemy.isoZ, enemy.isoZ + 4);
            //enemy.anchor.set(0.5, 0);
        }
    },

    moveEnemies: function() {
        var randXY, randDir;
        enemyGroup.forEach(function(enemy) {
            randXY = Math.floor(Math.random() * 2);
            randDir = Math.floor(Math.random() * 2);

            switch(randXY) {
                case 0:
                    enemy.oldPos = enemy.isoX;
                    enemy.oldType = 0;
                    switch(randDir) {
                        case 0:
                            if (enemy.isoX < 256 - 64) {
                                enemy.movement.moveRight();
                            }
                            break;
                        case 1:
                            if (enemy.isoX > 0) {
                                enemy.movement.moveLeft();
                            }
                            break;
                    }
                    break;
                case 1:
                    enemy.oldPos = enemy.isoY;
                    enemy.oldType = 1;
                    switch(randDir) {
                        case 0:
                            if (enemy.isoY < 256 - 64) {
                                enemy.movement.moveDown();
                            }
                            break;
                        case 1:
                            if (enemy.isoY > 0) {
                                enemy.movement.moveUp();
                            }
                            break;
                    }
                    break;
            }
        });
    }//,

    /*Collision: function(group, zNormal, zHighlight) {
        this.highlight = function() {
            group.forEach(function(entity) {
                var inBounds = entity.isoBounds.containsXY(cursorPos.x, cursorPos.y);
                if (!entity.selected && inBounds) {
                    entity.selected = true;
                    entity.tint = 0x86bfda;
                    game.add.tween(entity).to({isoZ: zHighlight}, 200, Phaser.Easing.Quadratic.InOut, true);
                }
                else if (entity.selected && !inBounds) {
                    entity.selected = false;
                    entity.tint = 0xffffff;
                    game.add.tween(entity).to({isoZ: zNormal}, 200, Phaser.Easing.Quadratic.InOut, true);
                }
            });
        };
        this.damage = function() {
            group.forEach(function(entity) {
                var inBounds = entity.isoBounds.containsXY(cursorPos.x, cursorPos.y);

                if (entity.selected && inBounds && game.input.activePointer.isDown && Math.abs(player.isoX - entity.isoX) <= 32 && Math.abs(player.isoY - entity.isoY) <= 32) {
                        entity.destroy();
                    }
            });
        };
    },

    Movement: function(entity) {
        this.moveUp = function() {
            entity.isoY -= 32;
            entity.scale.x = 1;
        };
        this.moveDown = function() {
            entity.isoY += 32;
            entity.scale.x = -1;
        };
        this.moveLeft = function() {
            entity.isoX -= 32;
            entity.scale.x = -1;
        };
        this.moveRight = function() {
            entity.isoX += 32;
            entity.scale.x = 1;
        };
    }*/
};<|endoftext|>