<commit_before>"use strict";
/**
 * @module service.filter.tools
 */

var assert = require("node-opcua-assert");

var SimpleAttributeOperand = require("../_generated_/_auto_generated_SimpleAttributeOperand").SimpleAttributeOperand;
var EventFilter = require("../_generated_/_auto_generated_EventFilter").EventFilter;
var StatusCodes = require("node-opcua-status-code").StatusCodes;
var DataType = require("node-opcua-variant").DataType;

var makeNodeId = require("node-opcua-nodeid").makeNodeId;
var _ = require("underscore");
var ObjectTypeIds = require("node-opcua-constants").ObjectTypeIds;
var AttributeIds = require("node-opcua-data-model").AttributeIds;
var stringToQualifiedName = require("node-opcua-data-model").stringToQualifiedName;

var Variant = require("node-opcua-variant").Variant;
var NodeId = require("node-opcua-nodeid").NodeId;
var resolveNodeId = require("node-opcua-nodeid").resolveNodeId;
var sameNodeId = require("node-opcua-nodeid").sameNodeId;
var debugLog = require("node-opcua-debug").make_debugLog(__filename);
var doDebug = require("node-opcua-debug").checkDebugFlag(__filename);

/**
 * helper to construct event filters:
 * construct a simple event filter
 * @method constructEventFilter
 *
 * @param   arrayOfNames   {Array<string>}
 * @param   conditionTypes {Array<NodeId>}
 * @return  {EventFilter}
 *
 * @example
 *
 *     constructEventFilter(["SourceName","Message","ReceiveTime"]);
 *
 *     constructEventFilter(["SourceName",{namespaceIndex:2 , "MyData"}]);
 *     constructEventFilter(["SourceName","2:MyData" ]);
 *
 *     constructEventFilter(["SourceName" ,["EnabledState","EffectiveDisplayName"] ]);
 *     constructEventFilter(["SourceName" ,"EnabledState.EffectiveDisplayName" ]);
 *
 */
function constructEventFilter(arrayOfNames,conditionTypes) {

    if (!_.isArray(arrayOfNames)) {
        return constructEventFilter([arrayOfNames],conditionTypes);
    }
    if (conditionTypes && !_.isArray(conditionTypes)) {
        return constructEventFilter(arrayOfNames,[conditionTypes]);
    }

    // replace "string" element in the form A.B.C into [ "A","B","C"]
    arrayOfNames = arrayOfNames.map(function (path) {
        if (typeof path !== "string") {
            return path;
        }
        return path.split(".");
    });
    arrayOfNames = arrayOfNames.map(function (path) {
        if (_.isArray(path)) {
            path = path.map(stringToQualifiedName);
        }
        return path;
    });
    // replace "string" elements in arrayOfName with QualifiedName in namespace 0
    arrayOfNames = arrayOfNames.map(function (s) {

        return (typeof s === "string") ? stringToQualifiedName(s) : s;
    });

    // construct browse paths array
    var browsePaths = arrayOfNames.map(function (s) {
        return _.isArray(s) ? s : [s];
    });

    // Part 4 page 127:
    // In some cases the same BrowsePath will apply to multiple EventTypes. If the Client specifies the BaseEventType
    // in the SimpleAttributeOperand then the Server shall evaluate the BrowsePath without considering the Type.

    // [..]
    // The SimpleAttributeOperand structure allows the Client to specify any Attribute, however, the Server is only
    // required to support the Value Attribute for Variable Nodes and the NodeId Attribute for Object Nodes.
    // That said, profiles defined in Part 7 may make support for additional Attributes mandatory.
    var selectClauses = browsePaths.map(function (browsePath) {
        return new SimpleAttributeOperand({
            typeId: makeNodeId(ObjectTypeIds.BaseEventType), // i=2041
            browsePath: browsePath,
            attributeId: AttributeIds.Value,
            indexRange: null //  NumericRange
        });
    });

    if (conditionTypes) {
        var extraSelectClauses = conditionTypes.map(function(nodeId) {
            return new SimpleAttributeOperand({
                typeId: nodeId, // conditionType for instance
                browsePath: null,
                attributeId: AttributeIds.NodeId,
                indexRange: null //  NumericRange
            });
        });
        selectClauses =[].concat(selectClauses,extraSelectClauses)
    }

    var filter = new EventFilter({

        selectClauses: selectClauses,

        whereClause: { //ContentFilter
            elements: [ // ContentFilterElement
                //{
                //    filterOperator: FilterOperator.IsNull,
                //    filterOperands: [ //
                //        new ElementOperand({
                //            index: 123
                //        }),
                //        new AttributeOperand({
                //            nodeId: "i=10",
                //            alias: "someText",
                //            browsePath: { //RelativePath
                //
                //            },
                //            attributeId: AttributeIds.Value
                //        })
                //    ]
                //}
            ]
        }
    });

    return filter;

}
exports.constructEventFilter = constructEventFilter;

/**
 * @class SimpleAttributeOperand
 * @method toPath
 * @return {String}
 *
 * @example:
 *
 *
 */

SimpleAttributeOperand.prototype.toPath = function() {
    var self = this;
    return self.browsePath.map(function (a) {
        return a.name;
    }).join("/");
};

*
/**
 * @class SimpleAttributeOperand
 * @method toShortString
 * @return {String}
 *
 * @example:
 *
 *
 */

SimpleAttributeOperand.prototype.toShortString = function(addressSpace) {

    var self = this;
    var str ="";
    if (addressSpace) {
        var n = addressSpace.findNode( self.typeId);
        str += n.BrowseName.toString()
    }
    str +=  "[" + self.typeId.toString() +"]"+self.toPath();
    return str;
};

function assert_valid_event_data(eventData) {
    assert(_.isFunction(eventData.resolveSelectClause));
    assert(_.isFunction(eventData.readValue));
}

/**
 *
 * @method extractEventField
 * extract a eventField from a event node, matching the given selectClause
 * @param eventData
 * @param selectClause
 */
function extractEventField(eventData, selectClause) {

    assert_valid_event_data(eventData);
    assert(selectClause instanceof SimpleAttributeOperand);

    selectClause.browsePath = selectClause.browsePath || [];

    if (selectClause.browsePath.length === 0 && selectClause.attributeId === AttributeIds.NodeId) {

        // "ns=0;i=2782" => ConditionType
        // "ns=0;i=2041" => BaseEventType
        if (selectClause.typeId.toString() !== "ns=0;i=2782") {
            // not ConditionType
            console.warn("this case is not handled yet : selectClause.typeId = " + selectClause.typeId.toString());
            const eventSource = eventData.$eventDataSource;
            return new Variant({dataType: DataType.NodeId, value: eventSource.nodeId});
        }
        const conditionTypeNodeId = resolveNodeId("ConditionType");
        assert(sameNodeId(selectClause.typeId,conditionTypeNodeId));

        const eventSource  = eventData.$eventDataSource;
        const eventSourceTypeDefinition = eventSource.typeDefinitionObj;
        if (!eventSourceTypeDefinition) {
            // eventSource is a EventType class
            return new Variant();
        }
        const addressSpace = eventSource.addressSpace;
        const conditionType = addressSpace.findObjectType(conditionTypeNodeId);

        if (!eventSourceTypeDefinition.isSupertypeOf(conditionType)) {
            return new Variant();
        }
        //xx assert(eventSource instanceof UAConditionBase);
        // Yeh : our EventType is a Condition Type !
        return new Variant({dataType: DataType.NodeId, value: eventSource.nodeId});
    }

    var handle = eventData.resolveSelectClause(selectClause);

    if (handle !== null) {
        var value = eventData.readValue(handle,selectClause);
        assert(value instanceof Variant);
        return value;

    } else {

        ///xx console.log(" Cannot find selectClause ",selectClause.toString());
        // Part 4 - 7.17.3
        // A null value is returned in the corresponding event field in the Publish response if the selected
        // field is not part of the Event or an error was returned in the selectClauseResults of the EventFilterResult.
        // return new Variant({dataType: DataType.StatusCode, value: browsePathResult.statusCode});
        return new Variant();
    }
    //xx var innerNode =
}

/**
 * @method extractEventFields
 * extract a array of eventFields from a event node, matching the selectClauses
 * @param selectClauses
 * @param eventData : a pseudo Node that provides a browse Method and a readValue(nodeId)
 */
function extractEventFields(selectClauses,eventData) {

    assert_valid_event_data(eventData);
    assert(_.isArray(selectClauses));
    assert(selectClauses.length===0 || selectClauses[0] instanceof SimpleAttributeOperand);
    return selectClauses.map(extractEventField.bind(null, eventData));
}

exports.extractEventFields = extractEventFields;

<commit_msg>fix typo<commit_after>"use strict";
/**
 * @module service.filter.tools
 */

var assert = require("node-opcua-assert");

var SimpleAttributeOperand = require("../_generated_/_auto_generated_SimpleAttributeOperand").SimpleAttributeOperand;
var EventFilter = require("../_generated_/_auto_generated_EventFilter").EventFilter;
var StatusCodes = require("node-opcua-status-code").StatusCodes;
var DataType = require("node-opcua-variant").DataType;

var makeNodeId = require("node-opcua-nodeid").makeNodeId;
var _ = require("underscore");
var ObjectTypeIds = require("node-opcua-constants").ObjectTypeIds;
var AttributeIds = require("node-opcua-data-model").AttributeIds;
var stringToQualifiedName = require("node-opcua-data-model").stringToQualifiedName;

var Variant = require("node-opcua-variant").Variant;
var NodeId = require("node-opcua-nodeid").NodeId;
var resolveNodeId = require("node-opcua-nodeid").resolveNodeId;
var sameNodeId = require("node-opcua-nodeid").sameNodeId;
var debugLog = require("node-opcua-debug").make_debugLog(__filename);
var doDebug = require("node-opcua-debug").checkDebugFlag(__filename);

/**
 * helper to construct event filters:
 * construct a simple event filter
 * @method constructEventFilter
 *
 * @param   arrayOfNames   {Array<string>}
 * @param   conditionTypes {Array<NodeId>}
 * @return  {EventFilter}
 *
 * @example
 *
 *     constructEventFilter(["SourceName","Message","ReceiveTime"]);
 *
 *     constructEventFilter(["SourceName",{namespaceIndex:2 , "MyData"}]);
 *     constructEventFilter(["SourceName","2:MyData" ]);
 *
 *     constructEventFilter(["SourceName" ,["EnabledState","EffectiveDisplayName"] ]);
 *     constructEventFilter(["SourceName" ,"EnabledState.EffectiveDisplayName" ]);
 *
 */
function constructEventFilter(arrayOfNames,conditionTypes) {

    if (!_.isArray(arrayOfNames)) {
        return constructEventFilter([arrayOfNames],conditionTypes);
    }
    if (conditionTypes && !_.isArray(conditionTypes)) {
        return constructEventFilter(arrayOfNames,[conditionTypes]);
    }

    // replace "string" element in the form A.B.C into [ "A","B","C"]
    arrayOfNames = arrayOfNames.map(function (path) {
        if (typeof path !== "string") {
            return path;
        }
        return path.split(".");
    });
    arrayOfNames = arrayOfNames.map(function (path) {
        if (_.isArray(path)) {
            path = path.map(stringToQualifiedName);
        }
        return path;
    });
    // replace "string" elements in arrayOfName with QualifiedName in namespace 0
    arrayOfNames = arrayOfNames.map(function (s) {

        return (typeof s === "string") ? stringToQualifiedName(s) : s;
    });

    // construct browse paths array
    var browsePaths = arrayOfNames.map(function (s) {
        return _.isArray(s) ? s : [s];
    });

    // Part 4 page 127:
    // In some cases the same BrowsePath will apply to multiple EventTypes. If the Client specifies the BaseEventType
    // in the SimpleAttributeOperand then the Server shall evaluate the BrowsePath without considering the Type.

    // [..]
    // The SimpleAttributeOperand structure allows the Client to specify any Attribute, however, the Server is only
    // required to support the Value Attribute for Variable Nodes and the NodeId Attribute for Object Nodes.
    // That said, profiles defined in Part 7 may make support for additional Attributes mandatory.
    var selectClauses = browsePaths.map(function (browsePath) {
        return new SimpleAttributeOperand({
            typeId: makeNodeId(ObjectTypeIds.BaseEventType), // i=2041
            browsePath: browsePath,
            attributeId: AttributeIds.Value,
            indexRange: null //  NumericRange
        });
    });

    if (conditionTypes) {
        var extraSelectClauses = conditionTypes.map(function(nodeId) {
            return new SimpleAttributeOperand({
                typeId: nodeId, // conditionType for instance
                browsePath: null,
                attributeId: AttributeIds.NodeId,
                indexRange: null //  NumericRange
            });
        });
        selectClauses =[].concat(selectClauses,extraSelectClauses)
    }

    var filter = new EventFilter({

        selectClauses: selectClauses,

        whereClause: { //ContentFilter
            elements: [ // ContentFilterElement
                //{
                //    filterOperator: FilterOperator.IsNull,
                //    filterOperands: [ //
                //        new ElementOperand({
                //            index: 123
                //        }),
                //        new AttributeOperand({
                //            nodeId: "i=10",
                //            alias: "someText",
                //            browsePath: { //RelativePath
                //
                //            },
                //            attributeId: AttributeIds.Value
                //        })
                //    ]
                //}
            ]
        }
    });

    return filter;

}
exports.constructEventFilter = constructEventFilter;

/**
 * @class SimpleAttributeOperand
 * @method toPath
 * @return {String}
 *
 * @example:
 *
 *
 */

SimpleAttributeOperand.prototype.toPath = function() {
    var self = this;
    return self.browsePath.map(function (a) {
        return a.name;
    }).join("/");
};

/**
 * @class SimpleAttributeOperand
 * @method toShortString
 * @return {String}
 *
 * @example:
 *
 *
 */

SimpleAttributeOperand.prototype.toShortString = function(addressSpace) {

    var self = this;
    var str ="";
    if (addressSpace) {
        var n = addressSpace.findNode( self.typeId);
        str += n.BrowseName.toString()
    }
    str +=  "[" + self.typeId.toString() +"]"+self.toPath();
    return str;
};

function assert_valid_event_data(eventData) {
    assert(_.isFunction(eventData.resolveSelectClause));
    assert(_.isFunction(eventData.readValue));
}

/**
 *
 * @method extractEventField
 * extract a eventField from a event node, matching the given selectClause
 * @param eventData
 * @param selectClause
 */
function extractEventField(eventData, selectClause) {

    assert_valid_event_data(eventData);
    assert(selectClause instanceof SimpleAttributeOperand);

    selectClause.browsePath = selectClause.browsePath || [];

    if (selectClause.browsePath.length === 0 && selectClause.attributeId === AttributeIds.NodeId) {

        // "ns=0;i=2782" => ConditionType
        // "ns=0;i=2041" => BaseEventType
        if (selectClause.typeId.toString() !== "ns=0;i=2782") {
            // not ConditionType
            console.warn("this case is not handled yet : selectClause.typeId = " + selectClause.typeId.toString());
            const eventSource = eventData.$eventDataSource;
            return new Variant({dataType: DataType.NodeId, value: eventSource.nodeId});
        }
        const conditionTypeNodeId = resolveNodeId("ConditionType");
        assert(sameNodeId(selectClause.typeId,conditionTypeNodeId));

        const eventSource  = eventData.$eventDataSource;
        const eventSourceTypeDefinition = eventSource.typeDefinitionObj;
        if (!eventSourceTypeDefinition) {
            // eventSource is a EventType class
            return new Variant();
        }
        const addressSpace = eventSource.addressSpace;
        const conditionType = addressSpace.findObjectType(conditionTypeNodeId);

        if (!eventSourceTypeDefinition.isSupertypeOf(conditionType)) {
            return new Variant();
        }
        //xx assert(eventSource instanceof UAConditionBase);
        // Yeh : our EventType is a Condition Type !
        return new Variant({dataType: DataType.NodeId, value: eventSource.nodeId});
    }

    var handle = eventData.resolveSelectClause(selectClause);

    if (handle !== null) {
        var value = eventData.readValue(handle,selectClause);
        assert(value instanceof Variant);
        return value;

    } else {

        ///xx console.log(" Cannot find selectClause ",selectClause.toString());
        // Part 4 - 7.17.3
        // A null value is returned in the corresponding event field in the Publish response if the selected
        // field is not part of the Event or an error was returned in the selectClauseResults of the EventFilterResult.
        // return new Variant({dataType: DataType.StatusCode, value: browsePathResult.statusCode});
        return new Variant();
    }
    //xx var innerNode =
}

/**
 * @method extractEventFields
 * extract a array of eventFields from a event node, matching the selectClauses
 * @param selectClauses
 * @param eventData : a pseudo Node that provides a browse Method and a readValue(nodeId)
 */
function extractEventFields(selectClauses,eventData) {

    assert_valid_event_data(eventData);
    assert(_.isArray(selectClauses));
    assert(selectClauses.length===0 || selectClauses[0] instanceof SimpleAttributeOperand);
    return selectClauses.map(extractEventField.bind(null, eventData));
}

exports.extractEventFields = extractEventFields;

<|endoftext|>


<commit_before>#! /usr/bin/env node

var program = require("commander");
var colors = require("colors");
var fs = require("fs");

var ImpConfig = require("../lib/impConfig.js");
var config = new ImpConfig();

//program
//  .option("-t, --tag [tag]", "adds a tag to the revision");

program.parse(process.argv);

config.init(["apiKey", "modelId", "agentFile", "deviceFile",], function(err, success) {
  var model = {
    device_code: null,
    agent_code: null
  };

  // Make sure the code files exist
  if (!fs.existsSync(config.get("agentFile"))) {
    console.log("ERROR: Could not find agent code file: " + config.get("deviceFile"));
    return;
  }
  if (!fs.existsSync(config.get("deviceFile"))) {
    console.log("ERROR: Could not find device code file: " + config.get("deviceFile"));
    return;
  }

  model.agent_code = fs.readFileSync(config.get("agentFile"), "utf8");
  model.device_code = fs.readFileSync(config.get("deviceFile"), "utf8");

  // Add the tag (if one was specified)
  // if ("tag" in program) model["marker"] = program.tag;

  imp = config.createImpWithConfig();
  imp.createModelRevision(config.get("modelId"), model, function(err, data) {
    if (err) {
      if (err.code != "CompileFailed") {
        console.log(colors.red("ERROR: " + err.message_short));
        return;
      }

      if (err.details.agent_errors) {
        for(var i = 0; i < err.details.agent_errors.length; i ++) {
          var thisErr = err.details.agent_errors[i];
          console.log(colors.red("ERROR: " + thisErr.error));
          console.log("   at: " + config.get("agentFile") +":" + thisErr.row + " (col "+thisErr.column+")");
        }
      }

      if (err.details.device_errors) {
        for(var i = 0; i < err.details.device_errors.length; i ++) {
          var thisErr = err.details.device_errors[i];
          console.log(colors.red("ERROR: " + thisErr.error));
          console.log("   at: " + config.get("deviceFile") +":" + thisErr.row + " (col "+thisErr.column+")");
        }
      }

      return;
    }

    imp.restartModel(config.get("modelId"), function(err, restartData) {
      if (err) {
        console.log("Warning: Could not restart model");
      }

      console.log("Successfully created revision " + data.revision.version);
    });
  });

});
<commit_msg>Tidy code<commit_after>#! /usr/bin/env node

var program = require("commander");
var colors = require("colors");
var fs = require("fs");

var ImpConfig = require("../lib/impConfig.js");
var config = new ImpConfig();

program.parse(process.argv);

config.init(["apiKey", "modelId", "agentFile", "deviceFile",], function(err, success) {
  var model = {
    device_code: null,
    agent_code: null
  };

  // Make sure the code files exist
  if (!fs.existsSync(config.get("agentFile"))) {
    console.log("ERROR: Could not find agent code file: " + config.get("deviceFile"));
    return;
  }
  if (!fs.existsSync(config.get("deviceFile"))) {
    console.log("ERROR: Could not find device code file: " + config.get("deviceFile"));
    return;
  }

  model.agent_code = fs.readFileSync(config.get("agentFile"), "utf8");
  model.device_code = fs.readFileSync(config.get("deviceFile"), "utf8");

  imp = config.createImpWithConfig();
  imp.createModelRevision(config.get("modelId"), model, function(err, data) {
    if (err) {
      if (err.code != "CompileFailed") {
        console.log(colors.red("ERROR: " + err.message_short));
        return;
      }

      if (err.details.agent_errors) {
        // List out agent code compilation errors (returned by server)
        for(var i = 0; i < err.details.agent_errors.length; i++) {
          var thisErr = err.details.agent_errors[i];
          console.log(colors.red("ERROR: " + thisErr.error));
          console.log("   at: " + config.get("agentFile") + ":" + thisErr.row + " (col " + thisErr.column + ")");
        }
      }

      if (err.details.device_errors) {
        // List out agent code compilation errors (returned by server)
        for(var i = 0; i < err.details.device_errors.length; i++) {
          var thisErr = err.details.device_errors[i];
          console.log(colors.red("ERROR: " + thisErr.error));
          console.log("   at: " + config.get("deviceFile") + ":" + thisErr.row + " (col " + thisErr.column + ")");
        }
      }

      return;
    }

    imp.restartModel(config.get("modelId"), function(err, restartData) {
      if (err) {
        console.log("Warning: Could not restart model");
      }

      console.log("Successfully created revision " + data.revision.version);
    });
  });
});
<|endoftext|>


<commit_before>/**
 * Copyright JS Foundation and other contributors, http://js.foundation
 *
 * Licensed 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.
 **/
RED.user = (function() {

    function login(opts,done) {
        if (typeof opts == 'function') {
            done = opts;
            opts = {};
        }

        var dialog = $('
'+
                       '

'+
                       '
'+
                       '<form id="node-dialog-login-fields" class="form-horizontal" style="margin-bottom: 0px;"></form>'+
                       '
'+
                       '
');

        dialog.dialog({
            autoOpen: false,
            classes: {
                "ui-dialog": "red-ui-editor-dialog",
                "ui-dialog-titlebar-close": "hide",
                "ui-widget-overlay": "red-ui-editor-dialog"
            },
            modal: true,
            closeOnEscape: !!opts.cancelable,
            width: 600,
            resizable: false,
            draggable: false
        });

        $("#node-dialog-login-fields").empty();
        $.ajax({
            dataType: "json",
            url: "auth/login",
            success: function(data) {
                var i=0;

                if (data.type == "credentials") {

                    for (;i<data.prompts.length;i++) {
                        var field = data.prompts[i];
                        var row = $("
",{class:"form-row"});
                        $(''+RED._(field.label)+':
').appendTo(row);
                        var input = $('<input style="width: 100%" id="node-dialog-login-'+field.id+'" type="'+field.type+'" tabIndex="'+(i+1)+'"/>').appendTo(row);

                        if (i<data.prompts.length-1) {
                            input.keypress(
                                (function() {
                                    var r = row;
                                    return function(event) {
                                        if (event.keyCode == 13) {
                                            r.next("div").find("input").trigger("focus");
                                            event.preventDefault();
                                        }
                                    }
                                })()
                            );
                        }
                        row.appendTo("#node-dialog-login-fields");
                    }
                    $('
'+RED._("user.loginFailed")+''+
                        (opts.cancelable?''+RED._("common.label.cancel")+'':'')+
                        '<input type="submit" id="node-dialog-login-submit" class="red-ui-button" style="width: auto;" tabIndex="'+(i+2)+'" value="'+RED._("user.login")+'">
').appendTo("#node-dialog-login-fields");

                    $("#node-dialog-login-submit").button();
                    $("#node-dialog-login-fields").on("submit", function(event) {
                        $("#node-dialog-login-submit").button("option","disabled",true);
                        $("#node-dialog-login-failed").hide();
                        $(".login-spinner").show();

                        var body = {
                            client_id: "node-red-editor",
                            grant_type: "password",
                            scope:""
                        }
                        for (var i=0;i<data.prompts.length;i++) {
                            var field = data.prompts[i];
                            body[field.id] = $("#node-dialog-login-"+field.id).val();
                        }
                        $.ajax({
                            url:"auth/token",
                            type: "POST",
                            data: body
                        }).done(function(data,textStatus,xhr) {
                            RED.settings.set("auth-tokens",data);
                            $("#node-dialog-login").dialog('destroy').remove();
                            if (opts.updateMenu) {
                                updateUserMenu();
                            }
                            done();
                        }).fail(function(jqXHR,textStatus,errorThrown) {
                            RED.settings.remove("auth-tokens");
                            $("#node-dialog-login-failed").show();
                        }).always(function() {
                            $("#node-dialog-login-submit").button("option","disabled",false);
                            $(".login-spinner").hide();
                        });
                        event.preventDefault();
                    });

                } else if (data.type == "strategy") {
                    i = 0;
                    for (;i<data.prompts.length;i++) {
                        var field = data.prompts[i];
                        var row = $("
",{class:"form-row",style:"text-align: center"}).appendTo("#node-dialog-login-fields");

                        var loginButton = $('',{style: "padding: 10px"}).appendTo(row).on("click", function() {
                            document.location = field.url;
                        });
                        if (field.image) {
                            $("",{src:field.image}).appendTo(loginButton);
                        } else if (field.label) {
                            var label = $('').text(field.label);
                            if (field.icon) {
                                $('',{class: "fa fa-2x "+field.icon, style:"vertical-align: middle"}).appendTo(loginButton);
                                label.css({
                                    "verticalAlign":"middle",
                                    "marginLeft":"8px"
                                });

                            }
                            label.appendTo(loginButton);
                        }
                        loginButton.button();
                    }

                }
                if (opts.cancelable) {
                    $("#node-dialog-login-cancel").button().on("click", function( event ) {
                        $("#node-dialog-login").dialog('destroy').remove();
                    });
                }

                var loginImageSrc = data.image || "red/images/node-red-256.png";

                $("#node-dialog-login-image").load(function() {
                    dialog.dialog("open");
                }).attr("src",loginImageSrc);

            }
        });
    }

    function logout() {
        var tokens = RED.settings.get("auth-tokens");
        var token = tokens?tokens.access_token:"";
        $.ajax({
            url: "auth/revoke",
            type: "POST",
            data: {token:token}
        }).done(function(data,textStatus,xhr) {
            RED.settings.remove("auth-tokens");
            if (data && data.redirect) {
                document.location.href = data.redirect;
            } else {
                document.location.reload(true);
            }
        }).fail(function(jqXHR,textStatus,errorThrown) {
            if (jqXHR.status === 401) {
                document.location.reload(true);
            } else {
                console.log(textStatus);
            }
        })
    }

    function updateUserMenu() {
        $("#red-ui-header-button-user-submenu li").remove();
        if (RED.settings.user.anonymous) {
            RED.menu.addItem("red-ui-header-button-user",{
                id:"usermenu-item-login",
                label:RED._("menu.label.login"),
                onselect: function() {
                    RED.user.login({cancelable:true},function() {
                        RED.settings.load(function() {
                            RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success");
                            updateUserMenu();
                            RED.events.emit("login",RED.settings.user.username);
                        });
                    });
                }
            });
        } else {
            RED.menu.addItem("red-ui-header-button-user",{
                id:"usermenu-item-username",
                label:""+RED.settings.user.username+""
            });
            RED.menu.addItem("red-ui-header-button-user",{
                id:"usermenu-item-logout",
                label:RED._("menu.label.logout"),
                onselect: function() {
                    RED.user.logout();
                }
            });
        }

    }

    function init() {
        if (RED.settings.user) {
            if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) {

                var userMenu = $('

')
                    .prependTo(".red-ui-header-toolbar");
                if (RED.settings.user.image) {
                    $('').css({
                        backgroundImage: "url("+RED.settings.user.image+")",
                    }).appendTo(userMenu.find("a"));
                } else {
                    $('').appendTo(userMenu.find("a"));
                }

                RED.menu.init({id:"red-ui-header-button-user",
                    options: []
                });
                updateUserMenu();
            }
        }

    }

    var readRE = /^((.+)\.)?read$/
    var writeRE = /^((.+)\.)?write$/

    function hasPermission(permission) {
        if (permission === "") {
            return true;
        }
        if (!RED.settings.user) {
            return true;
        }
        return checkPermission(RED.settings.user.permissions||"",permission);
    }
    function checkPermission(userScope,permission) {
        if (permission === "") {
            return true;
        }
        var i;

        if (Array.isArray(permission)) {
            // Multiple permissions requested - check each one
            for (i=0;i<permission.length;i++) {
                if (!checkPermission(userScope,permission[i])) {
                    return false;
                }
            }
            // All permissions check out
            return true;
        }

        if (Array.isArray(userScope)) {
            if (userScope.length === 0) {
                return false;
            }
            for (i=0;i<userScope.length;i++) {
                if (checkPermission(userScope[i],permission)) {
                    return true;
                }
            }
            return false;
        }

        if (userScope === "*" || userScope === permission) {
            return true;
        }

        if (userScope === "read" || userScope === "*.read") {
            return readRE.test(permission);
        } else if (userScope === "write" || userScope === "*.write") {
            return writeRE.test(permission);
        }
        return false;
    }

    return {
        init: init,
        login: login,
        logout: logout,
        hasPermission: hasPermission
    }

})();
<commit_msg>add class red-ui-button to cancel button<commit_after>/**
 * Copyright JS Foundation and other contributors, http://js.foundation
 *
 * Licensed 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.
 **/
RED.user = (function() {

    function login(opts,done) {
        if (typeof opts == 'function') {
            done = opts;
            opts = {};
        }

        var dialog = $('
'+
                       '

'+
                       '
'+
                       '<form id="node-dialog-login-fields" class="form-horizontal" style="margin-bottom: 0px;"></form>'+
                       '
'+
                       '
');

        dialog.dialog({
            autoOpen: false,
            classes: {
                "ui-dialog": "red-ui-editor-dialog",
                "ui-dialog-titlebar-close": "hide",
                "ui-widget-overlay": "red-ui-editor-dialog"
            },
            modal: true,
            closeOnEscape: !!opts.cancelable,
            width: 600,
            resizable: false,
            draggable: false
        });

        $("#node-dialog-login-fields").empty();
        $.ajax({
            dataType: "json",
            url: "auth/login",
            success: function(data) {
                var i=0;

                if (data.type == "credentials") {

                    for (;i<data.prompts.length;i++) {
                        var field = data.prompts[i];
                        var row = $("
",{class:"form-row"});
                        $(''+RED._(field.label)+':
').appendTo(row);
                        var input = $('<input style="width: 100%" id="node-dialog-login-'+field.id+'" type="'+field.type+'" tabIndex="'+(i+1)+'"/>').appendTo(row);

                        if (i<data.prompts.length-1) {
                            input.keypress(
                                (function() {
                                    var r = row;
                                    return function(event) {
                                        if (event.keyCode == 13) {
                                            r.next("div").find("input").trigger("focus");
                                            event.preventDefault();
                                        }
                                    }
                                })()
                            );
                        }
                        row.appendTo("#node-dialog-login-fields");
                    }
                    $('
'+RED._("user.loginFailed")+''+
                        (opts.cancelable?''+RED._("common.label.cancel")+'':'')+
                        '<input type="submit" id="node-dialog-login-submit" class="red-ui-button" style="width: auto;" tabIndex="'+(i+2)+'" value="'+RED._("user.login")+'">
').appendTo("#node-dialog-login-fields");

                    $("#node-dialog-login-submit").button();
                    $("#node-dialog-login-fields").on("submit", function(event) {
                        $("#node-dialog-login-submit").button("option","disabled",true);
                        $("#node-dialog-login-failed").hide();
                        $(".login-spinner").show();

                        var body = {
                            client_id: "node-red-editor",
                            grant_type: "password",
                            scope:""
                        }
                        for (var i=0;i<data.prompts.length;i++) {
                            var field = data.prompts[i];
                            body[field.id] = $("#node-dialog-login-"+field.id).val();
                        }
                        $.ajax({
                            url:"auth/token",
                            type: "POST",
                            data: body
                        }).done(function(data,textStatus,xhr) {
                            RED.settings.set("auth-tokens",data);
                            $("#node-dialog-login").dialog('destroy').remove();
                            if (opts.updateMenu) {
                                updateUserMenu();
                            }
                            done();
                        }).fail(function(jqXHR,textStatus,errorThrown) {
                            RED.settings.remove("auth-tokens");
                            $("#node-dialog-login-failed").show();
                        }).always(function() {
                            $("#node-dialog-login-submit").button("option","disabled",false);
                            $(".login-spinner").hide();
                        });
                        event.preventDefault();
                    });

                } else if (data.type == "strategy") {
                    i = 0;
                    for (;i<data.prompts.length;i++) {
                        var field = data.prompts[i];
                        var row = $("
",{class:"form-row",style:"text-align: center"}).appendTo("#node-dialog-login-fields");

                        var loginButton = $('',{style: "padding: 10px"}).appendTo(row).on("click", function() {
                            document.location = field.url;
                        });
                        if (field.image) {
                            $("",{src:field.image}).appendTo(loginButton);
                        } else if (field.label) {
                            var label = $('').text(field.label);
                            if (field.icon) {
                                $('',{class: "fa fa-2x "+field.icon, style:"vertical-align: middle"}).appendTo(loginButton);
                                label.css({
                                    "verticalAlign":"middle",
                                    "marginLeft":"8px"
                                });

                            }
                            label.appendTo(loginButton);
                        }
                        loginButton.button();
                    }

                }
                if (opts.cancelable) {
                    $("#node-dialog-login-cancel").button().on("click", function( event ) {
                        $("#node-dialog-login").dialog('destroy').remove();
                    });
                }

                var loginImageSrc = data.image || "red/images/node-red-256.png";

                $("#node-dialog-login-image").load(function() {
                    dialog.dialog("open");
                }).attr("src",loginImageSrc);

            }
        });
    }

    function logout() {
        var tokens = RED.settings.get("auth-tokens");
        var token = tokens?tokens.access_token:"";
        $.ajax({
            url: "auth/revoke",
            type: "POST",
            data: {token:token}
        }).done(function(data,textStatus,xhr) {
            RED.settings.remove("auth-tokens");
            if (data && data.redirect) {
                document.location.href = data.redirect;
            } else {
                document.location.reload(true);
            }
        }).fail(function(jqXHR,textStatus,errorThrown) {
            if (jqXHR.status === 401) {
                document.location.reload(true);
            } else {
                console.log(textStatus);
            }
        })
    }

    function updateUserMenu() {
        $("#red-ui-header-button-user-submenu li").remove();
        if (RED.settings.user.anonymous) {
            RED.menu.addItem("red-ui-header-button-user",{
                id:"usermenu-item-login",
                label:RED._("menu.label.login"),
                onselect: function() {
                    RED.user.login({cancelable:true},function() {
                        RED.settings.load(function() {
                            RED.notify(RED._("user.loggedInAs",{name:RED.settings.user.username}),"success");
                            updateUserMenu();
                            RED.events.emit("login",RED.settings.user.username);
                        });
                    });
                }
            });
        } else {
            RED.menu.addItem("red-ui-header-button-user",{
                id:"usermenu-item-username",
                label:""+RED.settings.user.username+""
            });
            RED.menu.addItem("red-ui-header-button-user",{
                id:"usermenu-item-logout",
                label:RED._("menu.label.logout"),
                onselect: function() {
                    RED.user.logout();
                }
            });
        }

    }

    function init() {
        if (RED.settings.user) {
            if (!RED.settings.editorTheme || !RED.settings.editorTheme.hasOwnProperty("userMenu")) {

                var userMenu = $('

')
                    .prependTo(".red-ui-header-toolbar");
                if (RED.settings.user.image) {
                    $('').css({
                        backgroundImage: "url("+RED.settings.user.image+")",
                    }).appendTo(userMenu.find("a"));
                } else {
                    $('').appendTo(userMenu.find("a"));
                }

                RED.menu.init({id:"red-ui-header-button-user",
                    options: []
                });
                updateUserMenu();
            }
        }

    }

    var readRE = /^((.+)\.)?read$/
    var writeRE = /^((.+)\.)?write$/

    function hasPermission(permission) {
        if (permission === "") {
            return true;
        }
        if (!RED.settings.user) {
            return true;
        }
        return checkPermission(RED.settings.user.permissions||"",permission);
    }
    function checkPermission(userScope,permission) {
        if (permission === "") {
            return true;
        }
        var i;

        if (Array.isArray(permission)) {
            // Multiple permissions requested - check each one
            for (i=0;i<permission.length;i++) {
                if (!checkPermission(userScope,permission[i])) {
                    return false;
                }
            }
            // All permissions check out
            return true;
        }

        if (Array.isArray(userScope)) {
            if (userScope.length === 0) {
                return false;
            }
            for (i=0;i<userScope.length;i++) {
                if (checkPermission(userScope[i],permission)) {
                    return true;
                }
            }
            return false;
        }

        if (userScope === "*" || userScope === permission) {
            return true;
        }

        if (userScope === "read" || userScope === "*.read") {
            return readRE.test(permission);
        } else if (userScope === "write" || userScope === "*.write") {
            return writeRE.test(permission);
        }
        return false;
    }

    return {
        init: init,
        login: login,
        logout: logout,
        hasPermission: hasPermission
    }

})();
<|endoftext|>


<commit_before>import {setResourceMeta} from '../../../src';

describe('setResourceMeta', function() {
  beforeEach(() => {
    this.meta = {
      1: {
        isSelected: false,
        otherData: {
          hungry: true,
          food: 'pizza'
        }
      },
      2: {thirsty: true},
      3: {what: false}
    };
  });

  describe('mergeMeta: false', () => {
    it('should only keep metadata that is passed in', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, 2, 5],
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
    });

    it('should only keep metadata that is passed in when `resources` is an object', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: {
          1: {id: 1},
          2: {id: 2},
          5: {id: 5}
        },
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
    });

    it('should ignore badly formed resources, object form (gh-118)', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, {name: 'pasta'}],
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {thirsty: true},
        3: {what: false}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
    });

    it('should ignore badly formed resources, non-object form (gh-118)', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, {id: {}}],
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {thirsty: true},
        3: {what: false}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
    });
  });

  describe('mergeMeta: true', () => {
    it('should keep other list items and merge in the new results', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, 2, 5],
        mergeMeta: true
      });

      expect(result).to.deep.equal({
        1: {
          isSelected: true,
          otherData: {
            hungry: true,
            food: 'pizza'
          }
        },
        2: {thirsty: true, isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
      // Unrelated items pass through unchanged
      expect(result[3]).to.equal(this.meta[3]);
    });

    it('should keep other list items and merge in the new results when `resources` is an object', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: {
          1: {id: 1},
          2: {id: 2},
          5: {id: 5}
        },
        mergeMeta: true
      });

      expect(result).to.deep.equal({
        1: {
          isSelected: true,
          otherData: {
            hungry: true,
            food: 'pizza'
          }
        },
        2: {thirsty: true, isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
      // Unrelated items pass through unchanged
      expect(result[3]).to.equal(this.meta[3]);
    });
  });
});
<commit_msg>add tests for acceptable falsy-positive ID checks<commit_after>import {setResourceMeta} from '../../../src';

describe('setResourceMeta', function() {
  beforeEach(() => {
    this.meta = {
      1: {
        isSelected: false,
        otherData: {
          hungry: true,
          food: 'pizza'
        }
      },
      2: {thirsty: true},
      3: {what: false}
    };
  });

  describe('mergeMeta: false', () => {
    it('should only keep metadata that is passed in', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, 2, 5],
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
    });

    it('should only keep metadata that is passed in when `resources` is an object', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: {
          1: {id: 1},
          2: {id: 2},
          5: {id: 5}
        },
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
    });

    it('should ignore badly formed resources, object form (gh-118)', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, {name: 'pasta'}],
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {thirsty: true},
        3: {what: false}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
    });

    it('should ignore badly formed resources, non-object form (gh-118)', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, {id: {}}],
        mergeMeta: false
      });

      expect(result).to.deep.equal({
        1: {isSelected: true},
        2: {thirsty: true},
        3: {what: false}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
    });
  });

  describe('mergeMeta: true', () => {
    it('should keep other list items and merge in the new results', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: [1, 2, 5],
        mergeMeta: true
      });

      expect(result).to.deep.equal({
        1: {
          isSelected: true,
          otherData: {
            hungry: true,
            food: 'pizza'
          }
        },
        2: {thirsty: true, isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
      // Unrelated items pass through unchanged
      expect(result[3]).to.equal(this.meta[3]);
    });

    it('should keep other list items and merge in the new results when `resources` is an object', () => {
      const result = setResourceMeta({
        meta: this.meta,
        newMeta: {isSelected: true},
        resources: {
          1: {id: 1},
          2: {id: 2},
          5: {id: 5}
        },
        mergeMeta: true
      });

      expect(result).to.deep.equal({
        1: {
          isSelected: true,
          otherData: {
            hungry: true,
            food: 'pizza'
          }
        },
        2: {thirsty: true, isSelected: true},
        3: {what: false},
        5: {isSelected: true}
      });

      // The original `meta` is shallow cloned
      expect(result).to.not.equal(this.meta);
      // The existing item is not modified
      expect(result[1]).to.not.equal(this.meta[1]);
      expect(result[2]).to.not.equal(this.meta[2]);
      // Unrelated items pass through unchanged
      expect(result[3]).to.equal(this.meta[3]);
    });
  });

  describe('update resource meta', () => {
    it('should perform updates for any valid resource ids (gh-298)', () => {
      const result = setResourceMeta({
        meta: {},
        newMeta: {updated: true},
        resources: [0, '', {id: false}, 1, 2, 3, '1234'],
      });

      expect(result).to.have.property('0');
      expect(result[0]).to.eql({updated: true});
      expect(result).to.not.have.property('false');
    });
  });
});
<|endoftext|>


<commit_before>Meteor.methods(
    {
        'getknowledgeList': function (data) {
            var result = HTTP.call('POST', mmtServerURL + "mmt-web/f/mm/mmtKnowledge/queryMmtKnowledge",
                {
                    data: data,
                    params: GetUser()
                });
            if (result.data.total === 0) {
                result.data = _.extend(result.data, { rows: [] });
            }
            return result.data;
        },

        'getallcategory': function (data) {
            var result = HTTP.call('GET', mmtServerURL + "mmt-web/f/mm/mmtCategory/getAllMmtCategory");
            return result.data;
        },

        'getcategorybyuserid': function (data) {
            //var postdata={
            //       id: data
            //  };
            var result = HTTP.call('GET', mmtServerURL + "mmt-web/f/mm/mmtCategory/queryMyMmtCategory");
            //    {
            //     data: postdata
            //   });
            //  console.log(result.data);
            return result.data;
        },

        'getknowledgedetailbyid': function (data) {
            var result = HTTP.call('GET', mmtServerURL + 'mmt-web/f/mm/mmtKnowledge/getMmtKnowledge?id=' + data.id);
            return result;
        },
        'addToFavorite': function (data) {
            var result = HTTP.call('POST', mmtServerURL + "mmt-web/f/mm/mmtCategory/addToFavorite",
                {
                    data: data,
                    params: GetUser()
                });
            return result;
        },

        'removeFromFavorite': function (data) {
            var result = HTTP.call('POST', mmtServerURL + "mmt-web/f/mm/mmtCategory/removeFromFavorite",
                {
                    data: data,
                    params: GetUser()
                });
            return result;
        }
    }
)
<commit_msg>mycategory添加userid<commit_after>Meteor.methods(
    {
        'getknowledgeList': function (data) {
            var result = HTTP.call('POST', mmtServerURL + "mmt-web/f/mm/mmtKnowledge/queryMmtKnowledge",
                {
                    data: data,
                    params: GetUser()
                });
            if (result.data.total === 0) {
                result.data = _.extend(result.data, { rows: [] });
            }
            return result.data;
        },

        'getallcategory': function (data) {
            var result = HTTP.call('GET', mmtServerURL + "mmt-web/f/mm/mmtCategory/getAllMmtCategory");
            return result.data;
        },

        'getcategorybyuserid': function (data) {
            var result = HTTP.call('GET', mmtServerURL + "mmt-web/f/mm/mmtCategory/queryMyMmtCategory", {
                params: GetUser()
            });
            return result.data;
        },

        'getknowledgedetailbyid': function (data) {
            var result = HTTP.call('GET', mmtServerURL + 'mmt-web/f/mm/mmtKnowledge/getMmtKnowledge?id=' + data.id);
            return result;
        },
        'addToFavorite': function (data) {
            var result = HTTP.call('POST', mmtServerURL + "mmt-web/f/mm/mmtCategory/addToFavorite",
                {
                    data: data,
                    params: GetUser()
                });
            return result;
        },

        'removeFromFavorite': function (data) {
            var result = HTTP.call('POST', mmtServerURL + "mmt-web/f/mm/mmtCategory/removeFromFavorite",
                {
                    data: data,
                    params: GetUser()
                });
            return result;
        }
    }
)
<|endoftext|>


<commit_before>/*
	Idea from http://www.boingboing.net/2010/05/26/keyboard-shortcuts.html

	Thanks to
		http://www.howtocreate.co.uk/tutorials/javascript/eventinfo
	and
		http://www.webfetti.com/MySpace/Glitter/Animals.jhtml
*/
var Konami = {
	/* Set this to whatever path (relative or absolute) where your images are stored. */
	imagePath: 'http://github.com/jmhobbs/Konami-Unicorn-Blitz/raw/master/',
	/* You need to have all of your images in the same format, numbered starting at 1 */
	imageCount: 4,
	imageFormat: '.gif',
	/* How many unicorns do you want to spam them with? */
	unicornCount: 50,
	/* What do you want the text on top to be? */
	words: 'UNICORNS',
	/* if you want to auto hide the unicorns after some time (in milliseconds) */
	hideAfter: 30000,

	code: [ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65 ],

	index: 0,

	idPrefix: 'konami_',
	active: false,
	elements: [],

	init: function () {
		document.onkeyup = Konami.keyUp;
	},

	keyUp: function ( e ) {
		if( !e ) {
			if( window.event ) {
				e = window.event;
			}
			else {
				return;
			}
		}

		if( typeof( e.keyCode ) == 'number'  ) {
			e = e.keyCode;
		}
		else if( typeof( e.which ) == 'number' ) {
			e = e.which;
		}
		else if( typeof( e.charCode ) == 'number'  ) {
			e = e.charCode;
		}
		else {
			return;
		}

		if( e == Konami.code[Konami.index] ) {
			++Konami.index;
			if( Konami.index == Konami.code.length ) {
				if ( Konami.active ) {
					Konami.remove();
				} else {
					Konami.unicorns();
				}
				Konami.index = 0;
			}
		}
		else {
			Konami.index = 0;
		}
	},

	unicorns: function () {
		Konami.active = true;
		document.body.style.overflow = 'hidden';
		var _height = window.innerHeight;
		var _width = window.innerWidth;
		for( i = 0; i < Konami.unicornCount; ++i ) {
			var imageId = Konami.idPrefix + '_image_' + i;
			var unicorn = document.createElement( 'img' );
			unicorn.setAttribute( 'src', Konami.imagePath + ( ( i % Konami.imageCount ) + 1 ) + Konami.imageFormat );
			var _top = Math.floor( Math.random() * _height ) - 100;
			var _left = Math.floor( Math.random() * _width  ) - 100;
			unicorn.setAttribute( 'style', 'position: fixed; z-index: 9998; top: ' + _top + 'px; left: ' + _left + 'px;' );
			unicorn.setAttribute('id', imageId);
			unicorn.setAttribute('class', 'konami_code');
			/* store our element id's so that we can remove them from the DOM */
			Konami.elements.push(imageId);
			document.body.appendChild( unicorn );
		}
		var words = document.createElement( 'div' );
		var wordsId = Konami.idPrefix + '_words';
		Konami.elements.push(wordsId);
		words.setAttribute('id', wordsId);
		words.setAttribute('class', 'konami_code');
		words.innerHTML = Konami.words;
		var _t_top = ( Math.floor( _top / 2 ) - 100 );
		var _t_top = ( _t_top < 0 ) ? 0 : _t_top;
		words.setAttribute( 'style', 'font-size: 100px; text-shadow: #FFF 0 0 20px; font-weight: bold; position: fixed; top: ' + _t_top + 'px; width: 100%; text-align: center; z-index: 9999;' );
		document.body.appendChild( words );

		if(Konami.hideAfter > 0) {
			setTimeout(function() { Konami.remove() }, Konami.hideAfter);
		}
	},

	remove: function() {
		Konami.active = false;
		document.body.style.overflow = 'auto';
		while ( Konami.elements.length ) {
			var elementId = Konami.elements.pop();
			document.body.removeChild(document.getElementById(elementId));
		}
	}
};

Konami.init();
<commit_msg>added clearTimeout call in remove, so that remove isn't called twice (once by user typing in code a second time and once by the hideAfter timeout)<commit_after>/*
	Idea from http://www.boingboing.net/2010/05/26/keyboard-shortcuts.html

	Thanks to
		http://www.howtocreate.co.uk/tutorials/javascript/eventinfo
	and
		http://www.webfetti.com/MySpace/Glitter/Animals.jhtml
*/
var Konami = {
	/* Set this to whatever path (relative or absolute) where your images are stored. */
	imagePath: 'http://github.com/jmhobbs/Konami-Unicorn-Blitz/raw/master/',
	/* You need to have all of your images in the same format, numbered starting at 1 */
	imageCount: 4,
	imageFormat: '.gif',
	/* How many unicorns do you want to spam them with? */
	unicornCount: 50,
	/* What do you want the text on top to be? */
	words: 'UNICORNS',
	/* if you want to auto hide the unicorns after some time (in milliseconds) */
	hideAfter: 30000,
	hideTimeoutId: null,

	code: [ 38, 38, 40, 40, 37, 39, 37, 39, 66, 65 ],

	index: 0,

	idPrefix: 'konami_',
	active: false,
	elements: [],

	init: function () {
		document.onkeyup = Konami.keyUp;
	},

	keyUp: function ( e ) {
		if( !e ) {
			if( window.event ) {
				e = window.event;
			}
			else {
				return;
			}
		}

		if( typeof( e.keyCode ) == 'number'  ) {
			e = e.keyCode;
		}
		else if( typeof( e.which ) == 'number' ) {
			e = e.which;
		}
		else if( typeof( e.charCode ) == 'number'  ) {
			e = e.charCode;
		}
		else {
			return;
		}

		if( e == Konami.code[Konami.index] ) {
			++Konami.index;
			if( Konami.index == Konami.code.length ) {
				if ( Konami.active ) {
					Konami.remove();
				} else {
					Konami.unicorns();
				}
				Konami.index = 0;
			}
		}
		else {
			Konami.index = 0;
		}
	},

	unicorns: function () {
		Konami.active = true;
		document.body.style.overflow = 'hidden';
		var _height = window.innerHeight;
		var _width = window.innerWidth;
		for( i = 0; i < Konami.unicornCount; ++i ) {
			var imageId = Konami.idPrefix + '_image_' + i;
			var unicorn = document.createElement( 'img' );
			unicorn.setAttribute( 'src', Konami.imagePath + ( ( i % Konami.imageCount ) + 1 ) + Konami.imageFormat );
			var _top = Math.floor( Math.random() * _height ) - 100;
			var _left = Math.floor( Math.random() * _width  ) - 100;
			unicorn.setAttribute( 'style', 'position: fixed; z-index: 9998; top: ' + _top + 'px; left: ' + _left + 'px;' );
			unicorn.setAttribute('id', imageId);
			unicorn.setAttribute('class', 'konami_code');
			/* store our element id's so that we can remove them from the DOM */
			Konami.elements.push(imageId);
			document.body.appendChild( unicorn );
		}
		var words = document.createElement( 'div' );
		var wordsId = Konami.idPrefix + '_words';
		Konami.elements.push(wordsId);
		words.setAttribute('id', wordsId);
		words.setAttribute('class', 'konami_code');
		words.innerHTML = Konami.words;
		var _t_top = ( Math.floor( _top / 2 ) - 100 );
		var _t_top = ( _t_top < 0 ) ? 0 : _t_top;
		words.setAttribute( 'style', 'font-size: 100px; text-shadow: #FFF 0 0 20px; font-weight: bold; position: fixed; top: ' + _t_top + 'px; width: 100%; text-align: center; z-index: 9999;' );
		document.body.appendChild( words );

		if(Konami.hideAfter > 0) {
			Konami.hideAfterTimeoutId = setTimeout(function() { Konami.remove() }, Konami.hideAfter);
		}
	},

	remove: function() {
		if(Konami.hideAfterTimeoutId != null) {
			clearTimeout(Konami.hideAfterTimeoutId);
			Konami.hideAfterTimeoutId = null;
		}
		Konami.active = false;
		document.body.style.overflow = 'auto';
		while ( Konami.elements.length ) {
			var elementId = Konami.elements.pop();
			document.body.removeChild(document.getElementById(elementId));
		}
	}
};

Konami.init();
<|endoftext|>


<commit_before>/* global define, require, console, document, window, setTimeout: false */
'use strict';

define('camunda-tasklist-ui', [
  'camunda-commons-ui',
  'camunda-bpm-sdk-js',
  'angular-data-depend',

  'scripts/config/date',
  'scripts/config/routes',
  'scripts/config/locales',
  'scripts/config/tooltip',
  'scripts/config/uris',

  'scripts/controller/cam-tasklist-app-ctrl',
  'scripts/controller/cam-tasklist-view-ctrl',
  'scripts/services/cam-tasklist-assign-notification',
  'scripts/services/cam-tasklist-configuration',

  'scripts/user/index',
  'scripts/variable/index',
  'scripts/tasklist/index',
  'scripts/task/index',
  'scripts/process/index',
  'scripts/navigation/index',
  'scripts/form/index',
  'scripts/filter/index',
  'scripts/api/index',

  'text!scripts/index.html'
], function() {
  /**
   * @namespace cam
   */

  /**
   * @module cam.tasklist
   */

  var pluginPackages = window.PLUGIN_PACKAGES || [];
  var pluginDependencies = window.PLUGIN_DEPENDENCIES || [];

  require.config({
    // baseUrl: './',
    packages: pluginPackages
  });

  var tasklistApp;

  var deps = [
    'camunda-commons-ui'
  ].concat(pluginDependencies.map(function(plugin) {
    return plugin.requirePackageName;
  }));

  // converts AMD paths to angular module names
  // "./filter" will be "cam.tasklist.filter"
  // function rj2ngNames(names) {
  //   var name, translated = [];
  //   for (var n = 0; n < names.length; n++) {
  //     if(names[n].indexOf("!") !== -1) continue;
  //     name = (require(names[n]) || {}).name;
  //     if (name) translated.push(name);
  //   }
  //   return translated;
  // }

  function bootstrapApp() {
    var angular = require('angular');
    var $ = angular.element;

    $(document).ready(function() {
      angular.bootstrap(document, [
        'cam.tasklist',
        'cam.embedded.forms',
        'cam.tasklist.custom'
      ]);

      setTimeout(function() {
        var $aufocused = $('[autofocus]');
        if ($aufocused.length) {
          $aufocused[0].focus();
        }
      }, 300);
    });
  }

  function loaded() {
    var angular = require('angular');
    var $ = angular.element;

    function parseUriConfig() {
      var $baseTag = angular.element('base');
      var config = {};
      var names = ['href', 'app-root', 'admin-api', 'engine-api'];
      for(var i = 0; i < names.length; i++) {
        config[names[i]] = $baseTag.attr(names[i]);
      }
      return config;
    }

    var ngDeps = [
      'cam.commons',
      'pascalprecht.translate',
      'ngRoute',
      'dataDepend',
      require('scripts/user/index').name,
      require('scripts/variable/index').name,
      require('scripts/tasklist/index').name,
      require('scripts/task/index').name,
      require('scripts/process/index').name,
      require('scripts/navigation/index').name,
      require('scripts/form/index').name,
      require('scripts/filter/index').name,
      require('scripts/api/index').name,
      // 'cam.tasklist.user',
      // 'cam.tasklist.variables',
      // 'cam.tasklist.tasklist',
      // 'cam.tasklist.task',
      // 'cam.tasklist.process',
      // 'cam.tasklist.form',
      // 'cam.tasklist.filter',
      // 'cam.tasklist.client'
    ].concat(pluginDependencies.map(function(el){
      return el.ngModuleName;
    }));

    var uriConfig = parseUriConfig();

    tasklistApp = angular.module('cam.tasklist', ngDeps);

    tasklistApp.factory('assignNotification', require('scripts/services/cam-tasklist-assign-notification'));
    tasklistApp.provider('configuration', require('scripts/services/cam-tasklist-configuration'));

    require('scripts/config/locales')(tasklistApp, uriConfig['app-root']);
    require('scripts/config/uris')(tasklistApp, uriConfig);

    tasklistApp.config(require('scripts/config/routes'));
    tasklistApp.config(require('scripts/config/date'));
    tasklistApp.config(require('scripts/config/tooltip'));

    tasklistApp.controller('camTasklistAppCtrl', require('scripts/controller/cam-tasklist-app-ctrl'));
    tasklistApp.controller('camTasklistViewCtrl', require('scripts/controller/cam-tasklist-view-ctrl'));

    // The `cam.tasklist` AngularJS module is now available but not yet bootstraped,
    // it is the right moment to load plugins
    if (typeof window.camTasklistConf !== 'undefined' && window.camTasklistConf.customScripts) {
      var custom = window.camTasklistConf.customScripts || {};

      // copy the relevant RequireJS configuration in a empty object
      // see: http://requirejs.org/docs/api.html#config
      var conf = {};
      [
        'baseUrl',
        'paths',
        'bundles',
        'shim',
        'map',
        'config',
        'packages',
        // 'nodeIdCompat',
        'waitSeconds',
        'context',
        // 'deps', // not relevant in this case
        'callback',
        'enforceDefine',
        'xhtml',
        'urlArgs',
        'scriptType'
        // 'skipDataMain' // not relevant either
      ].forEach(function (prop) {
        if (custom[prop]) {
          conf[prop] = custom[prop];
        }
      });

      // configure RequireJS
      require.config(conf);

      // load the dependencies and bootstrap the AngularJS application
      require(custom.deps || [], function() {

        // create a AngularJS module (with possible AngularJS module dependencies)
        // on which the custom scripts can register their
        // directives, controllers, services and all when loaded
        angular.module('cam.tasklist.custom', custom.ngDeps);

        bootstrapApp.apply(this, arguments);
      });
    }
    else {
      // for consistency, also create a empty module
      angular.module('cam.tasklist.custom', []);
      bootstrapApp();
    }
  }

  // and load the dependencies
  require(deps, loaded);
});
<commit_msg>fix(app-boostrap): boostrap angular app after all plugin callbacks<commit_after>/* global define, require, console, document, window, setTimeout: false */
'use strict';

define('camunda-tasklist-ui', [
  'camunda-commons-ui',
  'camunda-bpm-sdk-js',
  'angular-data-depend',

  'scripts/config/date',
  'scripts/config/routes',
  'scripts/config/locales',
  'scripts/config/tooltip',
  'scripts/config/uris',

  'scripts/controller/cam-tasklist-app-ctrl',
  'scripts/controller/cam-tasklist-view-ctrl',
  'scripts/services/cam-tasklist-assign-notification',
  'scripts/services/cam-tasklist-configuration',

  'scripts/user/index',
  'scripts/variable/index',
  'scripts/tasklist/index',
  'scripts/task/index',
  'scripts/process/index',
  'scripts/navigation/index',
  'scripts/form/index',
  'scripts/filter/index',
  'scripts/api/index',

  'text!scripts/index.html'
], function() {
  /**
   * @namespace cam
   */

  /**
   * @module cam.tasklist
   */

  var pluginPackages = window.PLUGIN_PACKAGES || [];
  var pluginDependencies = window.PLUGIN_DEPENDENCIES || [];

  require.config({
    // baseUrl: './',
    packages: pluginPackages
  });

  var tasklistApp;

  var deps = [
    'camunda-commons-ui'
  ].concat(pluginDependencies.map(function(plugin) {
    return plugin.requirePackageName;
  }));

  // converts AMD paths to angular module names
  // "./filter" will be "cam.tasklist.filter"
  // function rj2ngNames(names) {
  //   var name, translated = [];
  //   for (var n = 0; n < names.length; n++) {
  //     if(names[n].indexOf("!") !== -1) continue;
  //     name = (require(names[n]) || {}).name;
  //     if (name) translated.push(name);
  //   }
  //   return translated;
  // }

  function bootstrapApp() {
    var angular = require('angular');
    var $ = angular.element;

    $(document).ready(function() {
      angular.bootstrap(document, [
        'cam.tasklist',
        'cam.embedded.forms',
        'cam.tasklist.custom'
      ]);

      setTimeout(function() {
        var $aufocused = $('[autofocus]');
        if ($aufocused.length) {
          $aufocused[0].focus();
        }
      }, 300);
    });
  }

  function loaded() {
    var angular = require('angular');
    var $ = angular.element;

    function parseUriConfig() {
      var $baseTag = angular.element('base');
      var config = {};
      var names = ['href', 'app-root', 'admin-api', 'engine-api'];
      for(var i = 0; i < names.length; i++) {
        config[names[i]] = $baseTag.attr(names[i]);
      }
      return config;
    }

    var ngDeps = [
      'cam.commons',
      'pascalprecht.translate',
      'ngRoute',
      'dataDepend',
      require('scripts/user/index').name,
      require('scripts/variable/index').name,
      require('scripts/tasklist/index').name,
      require('scripts/task/index').name,
      require('scripts/process/index').name,
      require('scripts/navigation/index').name,
      require('scripts/form/index').name,
      require('scripts/filter/index').name,
      require('scripts/api/index').name,
      // 'cam.tasklist.user',
      // 'cam.tasklist.variables',
      // 'cam.tasklist.tasklist',
      // 'cam.tasklist.task',
      // 'cam.tasklist.process',
      // 'cam.tasklist.form',
      // 'cam.tasklist.filter',
      // 'cam.tasklist.client'
    ].concat(pluginDependencies.map(function(el){
      return el.ngModuleName;
    }));

    var uriConfig = parseUriConfig();

    tasklistApp = angular.module('cam.tasklist', ngDeps);

    tasklistApp.factory('assignNotification', require('scripts/services/cam-tasklist-assign-notification'));
    tasklistApp.provider('configuration', require('scripts/services/cam-tasklist-configuration'));

    require('scripts/config/locales')(tasklistApp, uriConfig['app-root']);
    require('scripts/config/uris')(tasklistApp, uriConfig);

    tasklistApp.config(require('scripts/config/routes'));
    tasklistApp.config(require('scripts/config/date'));
    tasklistApp.config(require('scripts/config/tooltip'));

    tasklistApp.controller('camTasklistAppCtrl', require('scripts/controller/cam-tasklist-app-ctrl'));
    tasklistApp.controller('camTasklistViewCtrl', require('scripts/controller/cam-tasklist-view-ctrl'));

    // The `cam.tasklist` AngularJS module is now available but not yet bootstraped,
    // it is the right moment to load plugins
    if (typeof window.camTasklistConf !== 'undefined' && window.camTasklistConf.customScripts) {
      var custom = window.camTasklistConf.customScripts || {};

      // copy the relevant RequireJS configuration in a empty object
      // see: http://requirejs.org/docs/api.html#config
      var conf = {};
      [
        'baseUrl',
        'paths',
        'bundles',
        'shim',
        'map',
        'config',
        'packages',
        // 'nodeIdCompat',
        'waitSeconds',
        'context',
        // 'deps', // not relevant in this case
        'callback',
        'enforceDefine',
        'xhtml',
        'urlArgs',
        'scriptType'
        // 'skipDataMain' // not relevant either
      ].forEach(function (prop) {
        if (custom[prop]) {
          conf[prop] = custom[prop];
        }
      });

      // configure RequireJS
      require.config(conf);

      // load the dependencies and bootstrap the AngularJS application
      require(custom.deps || [], function() {

        // create a AngularJS module (with possible AngularJS module dependencies)
        // on which the custom scripts can register their
        // directives, controllers, services and all when loaded
        angular.module('cam.tasklist.custom', custom.ngDeps);

        bootstrapApp.apply(this, arguments);
      });
    }
    else {
      // for consistency, also create a empty module
      angular.module('cam.tasklist.custom', []);

      // make sure that we are at the end of the require-js callback queue.
      // Why? => the plugins will also execute require(..) which will place new
      // entries into the queue.  if we bootstrap the angular app
      // synchronously, the plugins' require callbacks will not have been
      // executed yet and the angular modules provided by those plugins will
      // not have been defined yet. Placing a new require call here will put
      // the bootstrapping of the angular app at the end of the queue
      require([], function() {
        bootstrapApp();
      });
    }
  }

  // and load the dependencies
  require(deps, loaded);
});
<|endoftext|>


<commit_before>import { NUM_CHANGE } from '../constants/index';

const initialState = {
  coffee: 0,
  water: 0,
  ratio: 0
}

export default function values(state = initialState, action) {
  switch(action.type) {
    case NUM_CHANGE:
      const newNum = {
        onlyOneDecimal: function(current) {
          return current.indexOf('.') > -1 ? false : true;
        },

        deleteLast: function(current) {
          var newInput;

          if (current.length === 1 || !current.length) {
            newInput = 0;
          } else {
            let c = current.substr(0, current.length-1);
            newInput = c;
          }
          return newInput;
        },

        findMax: function(current) {
          const decimal = current.indexOf(".");
          var max;

          switch(decimal) {
            case -1:
              max = 3;
              break;
            case 1:
              max = 4;
              break;
            case 2:
              max = 5;
              break;
            case 3:
              max = 6;
              break;
          }

          return max;
        },

        isNotMax: function(current) {
          return current.length >= this.findMax(current) ? false : true;
        },

        output: function(input, current) {
          var output;

          switch (true) {
            case (!current && input !== "delete" && input !== "." && input !== "0"):
              output = input;
              break;
            case (!current && input === "."):
              output = `0${input}`;
              break;
            case (!current && input === "0"):
              output = current;
              break;
            case (input === "delete"):
              output = this.deleteLast(current);
              break;
            case (input === "." && this.onlyOneDecimal(current)):
              output = current + input;
              break;
            case (input === "." && !(this.onlyOneDecimal(current))):
              console.error('too many decibles');
              output = current;
              break;
            case (input !== "." && input !== "delete"):
              output = this.isNotMax(current) ? `${current}${input}` : current;
              break;
            default:
              console.error('output error to default');
              output = current;
          }

          return output;
        },

        num: this.output(action.input, state[action.block])
      }

      const calculate = {
        findRatio: function(coffee, water) {
          return Math.round((parseFloat(water) / parseFloat(coffee)) * 10) / 10
        },

        findWater: function() {
          return;
        },

        findCoffee: function() {
          return;
        },

        getConstant: function(a, b) {
          return;
        },

        result: function() {
          switch (action.mode) {
            case "findRatio": {
              var coffee, water;

              if (action.block === "coffee") {
                coffee = newNum.num;
                water = state.water;
              } else if ( action.block === "water") {
                coffee = state.coffee;
                water = newNum.num;
              }

              var result = {
                [action.block]: newNum.num,
                ratio: this.findRatio(coffee, water)
              }

              console.log(result);

              return result;
            }

            case "findWater": {
              break;
            }

            case "findCoffee": {
              break;
            }
          }
        }
      }

      const output = calculate.result()
      return {...state, ...output}

    default:
      return state;

  }
}

// switch (action.block) {
//   case "coffee":
//     return {...state, coffee: newNum.output(action.input, state[action.block])}
//   case "water":
//     return {...state, water: newNum.output(action.input, state[action.block])}
//   case "ratio":
//     return {...state, ratio: newNum.output(action.input, state[action.block])}
//   default:
//     return state;
// }
<commit_msg>working calculations with ratio mode<commit_after>import { NUM_CHANGE } from '../constants/index';

const initialState = {
  coffee: 0,
  water: 0,
  ratio: 0
}

export default function values(state = initialState, action) {
  switch(action.type) {
    case NUM_CHANGE:

      const newNum = {
        onlyOneDecimal: function(current) {
          return current.indexOf('.') > -1 ? false : true;
        },

        deleteLast: function(current) {
          var newInput;

          if (current.length === 1 || !current.length) {
            newInput = 0;
          } else {
            let c = current.substr(0, current.length-1);
            newInput = c;
          }
          return newInput;
        },

        findMax: function(current) {
          const decimal = current.indexOf(".");
          var max;

          switch(decimal) {
            case -1:
              max = 3;
              break;
            case 1:
              max = 4;
              break;
            case 2:
              max = 5;
              break;
            case 3:
              max = 6;
              break;
          }

          return max;
        },

        isNotMax: function(current) {
          return current.length >= this.findMax(current) ? false : true;
        },

        output: function(input, current) {
          var output;

          switch (true) {
            case (!current && input !== "delete" && input !== "." && input !== "0"):
              output = input;
              break;
            case (!current && input === "."):
              output = `0${input}`;
              break;
            case (!current && input === "0"):
              output = current;
              break;
            case (input === "delete"):
              output = this.deleteLast(current);
              break;
            case (input === "." && this.onlyOneDecimal(current)):
              output = current + input;
              break;
            case (input === "." && !(this.onlyOneDecimal(current))):
              console.error('too many decibles');
              output = current;
              break;
            case (input !== "." && input !== "delete"):
              output = this.isNotMax(current) ? `${current}${input}` : current;
              break;
            default:
              console.error('output error to default');
              output = current;
          }

          return output;
        },

        getNum: function() {
          return this.output(action.input, state[action.block])
        }
      }

      const calculate = {
        findRatio: function(coffee, water) {
          console.log(Math.round((parseFloat(water) / parseFloat(coffee)) * 10) / 10);
          return Math.round((parseFloat(water) / parseFloat(coffee)) * 10) / 10;
        },

        findWater: function() {
          return;
        },

        findCoffee: function() {
          return;
        },

        getConstant: function(a, b) {
          return;
        },

        result: function() {
          switch (action.mode) {
            case "findRatio": {
              var coffee, water;

              if (action.block === "coffee") {
                coffee = newNum.getNum();
                water = state.water;
              } else if ( action.block === "water") {
                coffee = state.coffee;
                water = newNum.getNum();
              }

              var result = {
                [action.block]: newNum.getNum(),
                ratio: this.findRatio(coffee, water)
              }

              console.log(result);

              return result;
            }

            case "findWater": {
              break;
            }

            case "findCoffee": {
              break;
            }
          }
        }
      }

      const output = calculate.result()
      return {...state, ...output}

    default:
      return state;

  }
}

// switch (action.block) {
//   case "coffee":
//     return {...state, coffee: newNum.output(action.input, state[action.block])}
//   case "water":
//     return {...state, water: newNum.output(action.input, state[action.block])}
//   case "ratio":
//     return {...state, ratio: newNum.output(action.input, state[action.block])}
//   default:
//     return state;
// }
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';
<commit_msg>Copy ruby CLI code into new JS CLI file<commit_after>#!/usr/bin/env node

'use strict';

// require 'import_js'
// require 'slop'
// require 'json'
//
// opts = Slop.parse do |o|
//   o.banner = 'Usage: import-js [<path-to-file>] [options] ...'
//   o.string '-w', '--word', 'A word/variable to import'
//   o.bool '--goto', 'Instead of importing, just print the path to a module'
//   o.array '--selections', 'A list of resolved selections, e.g. Foo:0,Bar:1'
//   o.string '--stdin-file-path',
//            'A path to the file whose content is being passed in as stdin. ' \
//            'This is used as a way to make sure that the right configuration ' \
//            'is applied.'
//   o.bool '--overwrite',
//          'Overwrite the file with the result after importing (the default ' \
//          'behavior is to print to stdout). This only applies if you are ' \
//          'passing in a file (<path-to-file>) as the first positional argument.'
//   o.string '--filename', '(deprecated) Alias for --stdin-file-path'
//   o.bool '--rewrite',
//          'Rewrite all current imports to match Import-JS configuration. ' \
//          'This does not add missing imports or remove unused imports.'
//
//   o.on '-v', '--version', 'Prints the current version' do
//     puts ImportJS::VERSION
//     exit
//   end
//   o.on '-h', '--help', 'Prints help' do
//     puts o
//     exit
//   end
// end
//
// path_to_file = opts.arguments[0] || opts['stdin-file-path'] || opts[:filename]
//
// file_contents = if STDIN.tty?
//                   unless path_to_file
//                     puts 'Error: missing <path-to-file>'
//                     puts opts
//                     exit 1
//                   end
//                   File.read(path_to_file).split("\n")
//                 else
//                   STDIN.read.split("\n")
//                 end
//
// if opts[:selections]
//   # Convert array of string tuples to hash, `word` => `selectedIndex`
//   opts[:selections] = Hash[opts[:selections].map do |str|
//     tuple = str.split(':')
//     [tuple.first, tuple[1].to_i]
//   end]
// end
//
// editor = ImportJS::CommandLineEditor.new(
//   file_contents, opts.to_hash.merge(path_to_file: path_to_file))
// importer = ImportJS::Importer.new(editor)
// if opts.goto?
//   importer.goto
// elsif opts[:word]
//   importer.import
// elsif opts[:rewrite]
//   importer.rewrite_imports
// else
//   importer.fix_imports
// end
//
// if opts.goto?
//   # Print the path to the module to go to
//   puts editor.goto
// elsif opts[:overwrite]
//   File.open(path_to_file, 'w') do |f|
//     f.write editor.current_file_content + "\n"
//   end
// else
//   # Print resulting file to stdout
//   puts editor.current_file_content
// end
//
// # Print messages to stderr
// meta = {
//   messages: editor.messages,
// }
// ask = editor.ask_for_selections
// meta[:ask_for_selections] = ask unless ask.empty?
// STDERR.puts meta.to_json
<|endoftext|>