<commit_before>var restify = require('restify');
var async = require('async');
var process = require('process');
var PLATFORM = process.platform;
var log = require('./log').logger('updater');
var config = require('./config');
var util = require('./util');
var socketio = require('socket.io')
var events = require('events');
var util = require('util');
var hooks = require('./hooks');
var network = require('./network');
var fs = require('fs');
var GenericNetworkManager = require('./network/manager').NetworkManager;

//var argv = require('minimist')(process.argv);

var Updater = function() {
    this.version = null;
    this.status = {
        'state' : 'idle'
    }
    this.networkManager = network.Generic;
    // Handle Inheritance
    events.EventEmitter.call(this);
};
util.inherits(Updater, events.EventEmitter);

Updater.prototype.setState = function(state) {
    this.status.state = state;
    this.emit('status',this.status);
}

Updater.prototype.stop = function(callback) {
    callback(null);
};

Updater.prototype.updateEngine = function(version, callback) {
    if(this.status.state != 'idle') {
        callback(new Error("Cannot update the engine when in the " + updater.status.state + " state."));
    } else {
        hooks.updateEngine(version, callback);
    }
}

Updater.prototype.installEngine = function(version, callback) {
    if(this.status.state != 'idle') {
        callback(new Error("Cannot install the engine when in the " + updater.status.state + " state."));
    } else {
        hooks.installEngine(version, callback);
    }
}

Updater.prototype.getVersions = function(callback) {
    hooks.getVersions(callback);
}

function UpdaterConfigFirstTime(callback) {
    log.info('Configuring for the first time...');
    switch(config.platform) {
        case 'linux':
            fs.stat('/usr/bin/configure_edison', function(err, stat) {
                if(!err) {
                    log.info('Intel Edison platform detected.');
                    config.updater.set('platform', 'edison');
                }
                callback();
            });
        break;

        case 'darwin':
            log.info('OSX Detected.');
            callback();
        break;
        default:
            callback();
        break;
    }
};
Updater.prototype.start = function(callback) {

    async.series([
       function setup_application(callback) {
            log.info('Checking updater data directory tree...');
            config.createDataDirectories(callback);
        },
        function configure(callback) {
            log.info("Loading configuration...");
            config.configureUpdater(callback);
        },

        function first_time_configure(callback) {
            if(!config.updater.userConfigLoaded) {
                UpdaterConfigFirstTime(callback);
            } else {
                callback();
            }
        },

        function setup_network(callback) {
            try {
                this.networkManager = network.createNetworkManager();
            } catch(e) {
                log.warn(e);
                this.networkManager = new GenericNetworkManager();
                return callback(null);
            }
            log.info("Setting up the network...");
            try {
                this.networkManager.init();
                log.info("Network manager started.")
            } catch(e) {
                log.error(e);
                log.error('Problem starting network manager:' + e);
            }
            callback(null);
        }.bind(this),

        function start_server(callback) {
            log.info("Setting up the webserver...");
            var server = restify.createServer({name:"FabMo Updater"});
            this.server = server;

            // Allow JSON over Cross-origin resource sharing
            log.info("Configuring cross-origin requests...");
            server.use(
                function crossOrigin(req,res,next){
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "X-Requested-With");
                    return next();
                }
            );

            server.on('uncaughtException', function(req, res, route, err) {
                log.uncaught(err);
                answer = {
                    status:"error",
                    message:err
                };
                res.json(answer)
            });

            // Configure local directory for uploading files
            log.info("Cofiguring upload directory...");
            server.use(restify.bodyParser({'uploadDir':config.updater.get('upload_dir') || '/tmp'}));
            server.pre(restify.pre.sanitizePath());

            log.info("Enabling gzip for transport...");
            server.use(restify.gzipResponse());

            // Import the routes module and apply the routes to the server
            log.info("Loading routes...");
            server.io = socketio.listen(server.server);
            var routes = require('./routes')(server);

            // Kick off the server listening for connections
            server.listen(9877, "0.0.0.0", function() {
                log.info(server.name+ ' listening at '+ server.url);
                callback(null, server);
            });

        }.bind(this),

	function test(callback) {
	callback();
	}.bind(this)
	],

        function(err, results) {
            if(err) {
                log.error(err);
                typeof callback === 'function' && callback(err);
            } else {
                typeof callback === 'function' && callback(null, this);
            }
        }.bind(this)
    );
};

module.exports = new Updater();
<commit_msg>Create unique SSID on first launch<commit_after>var restify = require('restify');
var async = require('async');
var process = require('process');
var PLATFORM = process.platform;
var log = require('./log').logger('updater');
var config = require('./config');
var util = require('./util');
var socketio = require('socket.io')
var events = require('events');
var util = require('util');
var hooks = require('./hooks');
var network = require('./network');
var fs = require('fs');
var GenericNetworkManager = require('./network/manager').NetworkManager;
var doshell = require('./util').doshell;

//var argv = require('minimist')(process.argv);

var Updater = function() {
    this.version = null;
    this.status = {
        'state' : 'idle'
    }
    this.networkManager = network.Generic;
    // Handle Inheritance
    events.EventEmitter.call(this);
};
util.inherits(Updater, events.EventEmitter);

Updater.prototype.setState = function(state) {
    this.status.state = state;
    this.emit('status',this.status);
}

Updater.prototype.stop = function(callback) {
    callback(null);
};

Updater.prototype.updateEngine = function(version, callback) {
    if(this.status.state != 'idle') {
        callback(new Error("Cannot update the engine when in the " + updater.status.state + " state."));
    } else {
        hooks.updateEngine(version, callback);
    }
}

Updater.prototype.installEngine = function(version, callback) {
    if(this.status.state != 'idle') {
        callback(new Error("Cannot install the engine when in the " + updater.status.state + " state."));
    } else {
        hooks.installEngine(version, callback);
    }
}

Updater.prototype.getVersions = function(callback) {
    hooks.getVersions(callback);
}

function UpdaterConfigFirstTime(callback) {
    log.info('Configuring for the first time...');
    switch(config.platform) {
        case 'linux':
            fs.stat('/usr/bin/configure_edison', function(err, stat) {
                if(!err) {
                    log.info('Intel Edison platform detected.');
                    config.updater.set('platform', 'edison');
                }
		doshell('cat /sys/class/net/wlan0/address', function(address) {
			var hostname = 'FabMo-' + address.trim().replace(/:/g,"");
			log.info("Setting factory hostname: " + hostname);
			config.updater.set('name', hostname);
			callback();
		});
            });
        break;

        case 'darwin':
            log.info('OSX Detected.');
            callback();
        break;
        default:
            callback();
        break;
    }
};
Updater.prototype.start = function(callback) {

    async.series([
       function setup_application(callback) {
            log.info('Checking updater data directory tree...');
            config.createDataDirectories(callback);
        },
        function configure(callback) {
            log.info("Loading configuration...");
            config.configureUpdater(callback);
        },

        function first_time_configure(callback) {
            if(!config.updater.userConfigLoaded) {
                UpdaterConfigFirstTime(callback);
            } else {
                callback();
            }
        },

        function setup_network(callback) {
            try {
                this.networkManager = network.createNetworkManager();
            } catch(e) {
                log.warn(e);
                this.networkManager = new GenericNetworkManager();
                return callback(null);
            }
            log.info("Setting up the network...");
            try {
                this.networkManager.init();
                log.info("Network manager started.")
            } catch(e) {
                log.error(e);
                log.error('Problem starting network manager:' + e);
            }
            callback(null);
        }.bind(this),

        function start_server(callback) {
            log.info("Setting up the webserver...");
            var server = restify.createServer({name:"FabMo Updater"});
            this.server = server;

            // Allow JSON over Cross-origin resource sharing
            log.info("Configuring cross-origin requests...");
            server.use(
                function crossOrigin(req,res,next){
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "X-Requested-With");
                    return next();
                }
            );

            server.on('uncaughtException', function(req, res, route, err) {
                log.uncaught(err);
                answer = {
                    status:"error",
                    message:err
                };
                res.json(answer)
            });

            // Configure local directory for uploading files
            log.info("Cofiguring upload directory...");
            server.use(restify.bodyParser({'uploadDir':config.updater.get('upload_dir') || '/tmp'}));
            server.pre(restify.pre.sanitizePath());

            log.info("Enabling gzip for transport...");
            server.use(restify.gzipResponse());

            // Import the routes module and apply the routes to the server
            log.info("Loading routes...");
            server.io = socketio.listen(server.server);
            var routes = require('./routes')(server);

            // Kick off the server listening for connections
            server.listen(9877, "0.0.0.0", function() {
                log.info(server.name+ ' listening at '+ server.url);
                callback(null, server);
            });

        }.bind(this),

	function test(callback) {
	callback();
	}.bind(this)
	],

        function(err, results) {
            if(err) {
                log.error(err);
                typeof callback === 'function' && callback(err);
            } else {
                typeof callback === 'function' && callback(null, this);
            }
        }.bind(this)
    );
};

module.exports = new Updater();
<|endoftext|>


<commit_before>/*globals fdom:true */
/*jslint indent:2,sloppy:true */

fdom.apis.set("core", {
  'createChannel': {type: "method", value: [], ret: {
    channel: "proxy",
    identifier: "string"
  }},
  'bindChannel': {type: "method", value: ["string"], ret: "proxy"},
  'getId': {type: "method", value: [], ret: ["array", "string"]}
});

fdom.apis.set("core.view", {
  'open': {type: "method", value: ["string", {
    'file': "string",
    'code': "string"
  }]},
  'show': {type: "method", value: []},
  'close': {type: "method", value: []},
  'postMessage': {type: "method", value: ["object"]},

  'message': {type: "event", value: "object"},
  'onClose': {type: "event", value: []}
});

fdom.apis.set("core.storage", {
  'keys': {type: "method", value: [], ret: ["array", "string"]},
  'get': {type: "method", value: ["string"], ret: "string"},
  'set': {type: "method", value: ["string", "string"], ret: "string"},
  'remove': {type: "method", value: ["string"], ret: "string"},
  'clear': {type: "method", value: []}
});

fdom.apis.set("core.socket", {
  'create': {type: "method", value: ["string", "object"], ret: "number"},
  'connect': {
    type: "method",
    value: ["number", "string", "number"],
    ret: "number"
  },
  'onData': {type: "event", value: {"socketId": "number", "data": "buffer"}},
  'write': {type: "method", value: ["number", "buffer"], ret: "number"},
  'disconnect': {type: "method", value: ["number"]},
  'destroy': {type: "method", value: ["number"]},
  'listen': {
    type: "method",
    value: ["number", "string", "number"],
    ret: "number"
  },
  'onConnection': {type: "event", value: {
    'serverSocketId': "number",
    'clientSocketId': "number"
  }},
  'onDisconnect': {type: "event", value: {
    "socketId": "number",
    "error": "string"
  }},
  'getInfo': {type: "method", value: ["number"], ret: {
    "type": "string",
    "connected": "boolean",
    "peerAddress": "string",
    "peerPort": "number",
    "localAddress": "string",
    "localPort": "number"
  }}
});

// A UDP socket.
// Generally, to use you just need to call bind() at which point onData
// events will start to flow. Note that bind() should only be called
// once per instance.
fdom.apis.set('core.udpsocket', {
  // Creates a socket, binds it to an interface and port and listens for
  // messages, dispatching each message as on onData event.
  // Returns an integer, with zero meaning success and any other value
  // being implementation-dependant.
  'bind': {
    type: 'method',
    value: [
      // Interface (address) on which to bind.
      'string',
      // Port on which to bind.
      'number'
    ],
    ret: 'number'
  },

  // Retrieves the state of the socket.
  // Returns an object with the following properties:
  //  - localAddress: the socket's local address, if bound
  //  - localPort: the socket's local port, if bound
  'getInfo': {type: 'method', value: [], ret: {
    'localAddress': 'string',
    'localPort': 'number'
  }},

  // Sends data to a server.
  // The socket must be bound.
  // Returns an integer indicating the number of bytes written, with no
  // guarantee that the remote side received the data.
  'sendTo': {
    type: 'method',
    value: [
      // Data to send.
      'buffer',
      // Destination address.
      'string',
      // Destination port.
      'number'
    ],
    ret: 'number'
  },

  // Releases all resources associated with this socket.
  // No-op if the socket is not bound.
  'destroy': {type: 'method', value: []},

  // Called once for each message received on this socket, once it's
  // been successfully bound.
  'onData': {
    type: 'event',
    value: {
      // Zero means success, any other value is implementation-dependent.
      'resultCode': 'number',
      // Address from which data was received.
      'address': 'string',
      // Port from which data was received.
      'port': 'number',
      // Data received.
      'data': 'buffer'
    }
  }
});

fdom.apis.set("core.runtime", {
  'createApp': {type: "method", value: ["string", "proxy"]},
  'resolve': {type: "method", value: ["string", "string"]},
  'needFile': {type: 'event', value: ["string", "string"]}
});

fdom.apis.set('core.echo', {
  'setup': {type: "method", value: ["string"]},
  'send': {type: "method", value: ["string"]},
  'message': {type: "event", value: "string"}
});

fdom.apis.set('core.peerconnection', {
  // Setup the link to the peer and options for this peer connection.
  'setup': {
    type: "method",
    value: [
      // The freedom.js channel identifier used to setup a signalling chanel.
      "string",
      // The peerName, used debugging and console messages.
      "string",
      // The list of STUN servers to use.
      // The format of a single entry is stun:HOST:PORT, where HOST
      // and PORT are a stun server hostname and port, respectively.
      ["array", "string"]
    ]
  },

  // Send a message to the peer.
  'send': {type: "method", value: [{
    // Data channel id. If provided, will be used as the channel label.
    // The behavior is undefined if the channel label doesn't exist.
    "channelLabel": "string",
    // One of the bellow should be defined; this is the data to send.
    "text": "string",
    "binary": "blob",
    "buffer": "buffer"
  }]},

  // Called when we get a message from the peer.
  'onReceived': {type: "event", value: {
    // The label/id of the data channel.
    "channelLabel": "string",
    // One the below will be specified.
    "text": "string",
    "binary": "blob",
    "buffer": "buffer"
  }},

  // Open the data channel with this label.
  'openDataChannel': {type: "method", value: ["string"]},
  // Close the data channel with this label.
  'closeDataChannel': {type: "method", value: ["string"]},

  // A channel with this id has been opened.
  'onOpenDataChannel': {type: "event", value: {"channelId": "string"}},
  // The channale with this id has been closed.
  'onCloseDataChannel': {type: "event", value: {"channelId": "string"}},

  // Returns the number of bytes that have queued using "send", but not
  // yet sent out. Currently just exposes:
  // http://www.w3.org/TR/webrtc/#widl-RTCDataChannel-bufferedAmount
  "getBufferedAmount": {type: "method", value: ["string"]},

  // Close the peer connection.
  'close': {type: "method", value: []},
  // The peer connection has been closed.
  'onClose': {type: "event", value: {}}
});

<commit_msg>socket create return<commit_after>/*globals fdom:true */
/*jslint indent:2,sloppy:true */

fdom.apis.set("core", {
  'createChannel': {type: "method", value: [], ret: {
    channel: "proxy",
    identifier: "string"
  }},
  'bindChannel': {type: "method", value: ["string"], ret: "proxy"},
  'getId': {type: "method", value: [], ret: ["array", "string"]}
});

fdom.apis.set("core.view", {
  'open': {type: "method", value: ["string", {
    'file': "string",
    'code': "string"
  }]},
  'show': {type: "method", value: []},
  'close': {type: "method", value: []},
  'postMessage': {type: "method", value: ["object"]},

  'message': {type: "event", value: "object"},
  'onClose': {type: "event", value: []}
});

fdom.apis.set("core.storage", {
  'keys': {type: "method", value: [], ret: ["array", "string"]},
  'get': {type: "method", value: ["string"], ret: "string"},
  'set': {type: "method", value: ["string", "string"], ret: "string"},
  'remove': {type: "method", value: ["string"], ret: "string"},
  'clear': {type: "method", value: []}
});

fdom.apis.set("core.socket", {
  'create': {type: "method", value: ["string", "object"], ret: {
    socketId: "number"
  }},
  'connect': {
    type: "method",
    value: ["number", "string", "number"],
    ret: "number"
  },
  'onData': {type: "event", value: {"socketId": "number", "data": "buffer"}},
  'write': {type: "method", value: ["number", "buffer"], ret: "number"},
  'disconnect': {type: "method", value: ["number"]},
  'destroy': {type: "method", value: ["number"]},
  'listen': {
    type: "method",
    value: ["number", "string", "number"],
    ret: "number"
  },
  'onConnection': {type: "event", value: {
    'serverSocketId': "number",
    'clientSocketId': "number"
  }},
  'onDisconnect': {type: "event", value: {
    "socketId": "number",
    "error": "string"
  }},
  'getInfo': {type: "method", value: ["number"], ret: {
    "type": "string",
    "connected": "boolean",
    "peerAddress": "string",
    "peerPort": "number",
    "localAddress": "string",
    "localPort": "number"
  }}
});

// A UDP socket.
// Generally, to use you just need to call bind() at which point onData
// events will start to flow. Note that bind() should only be called
// once per instance.
fdom.apis.set('core.udpsocket', {
  // Creates a socket, binds it to an interface and port and listens for
  // messages, dispatching each message as on onData event.
  // Returns an integer, with zero meaning success and any other value
  // being implementation-dependant.
  'bind': {
    type: 'method',
    value: [
      // Interface (address) on which to bind.
      'string',
      // Port on which to bind.
      'number'
    ],
    ret: 'number'
  },

  // Retrieves the state of the socket.
  // Returns an object with the following properties:
  //  - localAddress: the socket's local address, if bound
  //  - localPort: the socket's local port, if bound
  'getInfo': {type: 'method', value: [], ret: {
    'localAddress': 'string',
    'localPort': 'number'
  }},

  // Sends data to a server.
  // The socket must be bound.
  // Returns an integer indicating the number of bytes written, with no
  // guarantee that the remote side received the data.
  'sendTo': {
    type: 'method',
    value: [
      // Data to send.
      'buffer',
      // Destination address.
      'string',
      // Destination port.
      'number'
    ],
    ret: 'number'
  },

  // Releases all resources associated with this socket.
  // No-op if the socket is not bound.
  'destroy': {type: 'method', value: []},

  // Called once for each message received on this socket, once it's
  // been successfully bound.
  'onData': {
    type: 'event',
    value: {
      // Zero means success, any other value is implementation-dependent.
      'resultCode': 'number',
      // Address from which data was received.
      'address': 'string',
      // Port from which data was received.
      'port': 'number',
      // Data received.
      'data': 'buffer'
    }
  }
});

fdom.apis.set("core.runtime", {
  'createApp': {type: "method", value: ["string", "proxy"]},
  'resolve': {type: "method", value: ["string", "string"]},
  'needFile': {type: 'event', value: ["string", "string"]}
});

fdom.apis.set('core.echo', {
  'setup': {type: "method", value: ["string"]},
  'send': {type: "method", value: ["string"]},
  'message': {type: "event", value: "string"}
});

fdom.apis.set('core.peerconnection', {
  // Setup the link to the peer and options for this peer connection.
  'setup': {
    type: "method",
    value: [
      // The freedom.js channel identifier used to setup a signalling chanel.
      "string",
      // The peerName, used debugging and console messages.
      "string",
      // The list of STUN servers to use.
      // The format of a single entry is stun:HOST:PORT, where HOST
      // and PORT are a stun server hostname and port, respectively.
      ["array", "string"]
    ]
  },

  // Send a message to the peer.
  'send': {type: "method", value: [{
    // Data channel id. If provided, will be used as the channel label.
    // The behavior is undefined if the channel label doesn't exist.
    "channelLabel": "string",
    // One of the bellow should be defined; this is the data to send.
    "text": "string",
    "binary": "blob",
    "buffer": "buffer"
  }]},

  // Called when we get a message from the peer.
  'onReceived': {type: "event", value: {
    // The label/id of the data channel.
    "channelLabel": "string",
    // One the below will be specified.
    "text": "string",
    "binary": "blob",
    "buffer": "buffer"
  }},

  // Open the data channel with this label.
  'openDataChannel': {type: "method", value: ["string"]},
  // Close the data channel with this label.
  'closeDataChannel': {type: "method", value: ["string"]},

  // A channel with this id has been opened.
  'onOpenDataChannel': {type: "event", value: {"channelId": "string"}},
  // The channale with this id has been closed.
  'onCloseDataChannel': {type: "event", value: {"channelId": "string"}},

  // Returns the number of bytes that have queued using "send", but not
  // yet sent out. Currently just exposes:
  // http://www.w3.org/TR/webrtc/#widl-RTCDataChannel-bufferedAmount
  "getBufferedAmount": {type: "method", value: ["string"]},

  // Close the peer connection.
  'close': {type: "method", value: []},
  // The peer connection has been closed.
  'onClose': {type: "event", value: {}}
});

<|endoftext|>


<commit_before>function trim(input){
  return input.replace(/^\s+|\s+$/g, "");
}

function hasProp(obj, key) {
  return obj && obj.hasOwnProperty(key);
}

function is(type, obj) {
  let clas = Object.prototype.toString.call(obj);

  if (type === "array") {
    return clas === "[object Array]";

  } else if (type === "oejct"){
    clas = typeof obj;
    return clas === "function" || clas === "oejct" && !!obj && !is("array", obj);

  } else if (type === "collection"){
    return is("array", obj) || is("object", obj);

  } else {
    clas = clas.slice(8, -1).toLowerCase();
    if (type === "numeric") {
      return (clas === "number" || clas === "string") && (obj - parseFloat(obj) + 1) >= 0;
    } else {
      return obj !== undefined && obj != null && clas === type;
    }
  }
}

function empty(obj) {
  if (is("array", obj)) {
    return obj.length === 0;
  } else if(is("object", obj)) {
    for (let name in obj) {
      return false;
    }
    return true;
  } else if(is("numeric", obj)) {
    return parseFloat(obj) === 0;
  }

  return !obj;
}

function clone(obj){
  var _isArray = is("array", obj),
      _isObject = is("object", obj);

  if (!_isArray && !_isObject) return undefined;

  var result = _isArray ? [] : {}, key, val;

  for (key in obj) {
    if (!hasProp(obj, key)) continue;
    val = obj[key];
    if(is("collection", val)) val = clone(val);
    result[key] = val;
  }

  return result;
}

function each(obj, iterate, context){
  if (obj == null) return obj;

  context = context || obj;

  if (is("object", obj)) {
    for (let key in obj) {
      if (!hasProp(obj, key)) continue;
      if (iterate.call(context, obj[key], key) === false) break;
    }

  } else if (is("array", obj)) {
    let i, length = obj.length;
    for (i = 0; i < length; i++) {
      if (iterate.call(context, obj[i], i) === false) break;
    }
  }

  return obj;
}

function tokenize(str, separator = ",", left = "(", right = ")") {
  if( empty(str) ){
    return [];
  }

  let depth = 0;
  let offset = 0;
  let buffer = "";
  let results = [];
  let length = str.length;
  let open = false;

  while (offset <= length) {
    let tmpOffset = -1;
    let offsets = [
      str.indexOf(separator, offset),
      str.indexOf(left, offset),
      str.indexOf(right, offset)
    ];
    for (let i = 0; i < 3; i++) {
      if (offsets[i] !== -1 && (offsets[i] < tmpOffset || tmpOffset === -1)) {
        tmpOffset = offsets[i];
      }
    }
    if (tmpOffset !== -1) {
      buffer += str.substr(offset, (tmpOffset - offset));
      let char = str.substr(tmpOffset, 1);
      if (!depth && char === separator) {
        results.push(buffer);
        buffer = "";
      } else {
        buffer += char;
      }
      if (left !== right) {
        if (char === left) {
          depth++;
        }
        if (char === right) {
          depth--;
        }
      } else {
        if (char === left) {
          if (!open) {
            depth++;
            open = true;
          } else {
            depth--;
          }
        }
      }
      offset = ++tmpOffset;
    } else {
      results.push(buffer + str.substr(offset));
      offset = length + 1;
    }
  }

  if (empty(results) && !empty(buffer)) {
    results.push(buffer);
  }

  if (!empty(results)) {
    return results.map(val => trim(val));
  }

  return [];
}

function splitConditions(token) {
  let conditions = false;
  let position = token.indexOf("[");
  if (position > -1) {
    conditions = token.substr(position);
    token = token.substr(0, position);
  }
  return [token, conditions];
}

function matchToken(key, token) {
  switch (token) {
    case "{n}":
      return is("numeric", key);
    case "{s}":
      return is("string", key);
    case "{*}":
      return true;
    default:
      return is("numeric", token) ? (key == token) : key === token;
  }
}

function matches(data, selector) {
  const identifier = "(?:\\\\.|[\\w-_\.]|[^\\x00-\\xa0])+";
  const attributes = new RegExp(`\\s*(${identifier})(?:\\s*([><!]?[=]|[><])\\s*(\\/.*?\\/|${identifier})|)\\s*\]`, "g");
  let cond;

  while (cond = attributes.exec(selector)) {
    const attr = cond[1];
    const op = cond[2] || null;
    const val = cond[3] || null;
    const hasProperty = hasProp(data, attr);

    if (empty(op) && empty(val) && !hasProperty) {
      return false;
    }

    if (!(hasProperty || data[attr] != null)) {
      return false;
    }

    let prop = hasProperty ? prop = data[attr] : undefined;
    let isBoolean = is("boolean", prop) || (prop === "true" || prop === "false");

    if (isBoolean && is("numeric", val)) {
      prop = prop ? "1": "0";
    } else if(isBoolean) {
      prop = prop ? "true" : "false";
    }

    if (op === "=" && val && val[0] === "/") {
      if (!prop.match(new RegExp(val.substr(1, val.length - 2)))) {
        return false;
      }
    } else if ((op === "=" && prop != val) ||
      (op === "!=" && prop == val) ||
      (op === ">" && prop <= val) ||
      (op === "<" && prop >= val) ||
      (op === ">=" && prop < val) ||
      (op === "<=" && prop > val)
    ) {
      return false;
    }
  }

  return true;
}

export function get(data, path, defaultValue = null) {
  let parts, val;

  if (!is("collection", data)) {
    return defaultValue;
  }

  if (empty(data) || path == null || path === "" ) {
    return defaultValue;
  }

  if (is("string", path) || is("numeric", path)) {
    parts = (path + "").split(".");
  } else {
    if (!is("array", path)) {
      return defaultValue;
    }
    parts = path;
  }

  val = is("collection", data) ? clone(data) : data;
  each(parts, (v) => {
    if (is("collection", val) && hasProp(val, v)) {
      val = val[v];
    } else {
      val = defaultValue;
      return false;
    }
  });

  return val;
}

export function extract(data, path) {
  if (!is("collection", data)) {
    return null;
  }

  if (empty(path)) {
    return data;
  }

  if (!/[{\[]/.test(path)) {
    return get(data, path);
  }

  const key = "__set_item__";
  let tokens;
  let context = {[key]: [data]};

  if (path.indexOf("[") < 0) {
    tokens = path.split(".");
  } else {
    tokens = tokenize(path, ".", "[", "]");
  }

  each(tokens, (token) => {
    let next = [];
    let [_token, conditions] = splitConditions(token);

    each(context[key], (item) => {
      each(item, (v, k) => {
        if (matchToken(k, _token)) {
          next.push(v);
        }
      });
    });

    if (conditions) {
      let filter = [];
      each(next, (item) => {
        if (is("collection", item) && matches(item, conditions)) {
          filter.push(item);
        }
      });
      next = filter;
    }
    context = {[key]: next};
  });

  return context[key];
}

export function insert(data, path, value) {}

export function remove(data, path) {}

export function combine(data, keyPath, valuePath = null, groupPath = null) {}

export function format(data, paths, format) {}

export function contains(data, needle) {}

export function check(data, path) {}

export function filter(data, callback) {}

export function flatten(data, separator = ".") {}

export function expand(data, separator = ".") {}

export function merge(data, merge) {}

export function numeric(data) {}

export function dimensions(data) {}

export function maxDimensions(data) {}

export function map(data, path, callback) {}

export function reduce(data, path, callback) {}

export function apply(data, path, callback) {}

export function sort(data, path, dir = "asc") {}

export function diff(data, compare) {}

export function mergeDiff(data, compare) {}

export function normalize(data, assoc) {}

export function nest(data, options) {}

export function nest(data, options) {}<commit_msg>Fix attribute matching null comparison<commit_after>function trim(input){
  return input.replace(/^\s+|\s+$/g, "");
}

function hasProp(obj, key) {
  return obj && obj.hasOwnProperty(key);
}

function is(type, obj) {
  let clas = Object.prototype.toString.call(obj);

  if (type === "array") {
    return clas === "[object Array]";

  } else if (type === "oejct"){
    clas = typeof obj;
    return clas === "function" || clas === "oejct" && !!obj && !is("array", obj);

  } else if (type === "collection"){
    return is("array", obj) || is("object", obj);

  } else {
    clas = clas.slice(8, -1).toLowerCase();
    if (type === "numeric") {
      return (clas === "number" || clas === "string") && (obj - parseFloat(obj) + 1) >= 0;
    } else {
      return obj !== undefined && obj != null && clas === type;
    }
  }
}

function empty(obj) {
  if (is("array", obj)) {
    return obj.length === 0;
  } else if(is("object", obj)) {
    for (let name in obj) {
      return false;
    }
    return true;
  } else if(is("numeric", obj)) {
    return parseFloat(obj) === 0;
  }

  return !obj;
}

function clone(obj){
  var _isArray = is("array", obj),
      _isObject = is("object", obj);

  if (!_isArray && !_isObject) return undefined;

  var result = _isArray ? [] : {}, key, val;

  for (key in obj) {
    if (!hasProp(obj, key)) continue;
    val = obj[key];
    if(is("collection", val)) val = clone(val);
    result[key] = val;
  }

  return result;
}

function each(obj, iterate, context){
  if (obj == null) return obj;

  context = context || obj;

  if (is("object", obj)) {
    for (let key in obj) {
      if (!hasProp(obj, key)) continue;
      if (iterate.call(context, obj[key], key) === false) break;
    }

  } else if (is("array", obj)) {
    let i, length = obj.length;
    for (i = 0; i < length; i++) {
      if (iterate.call(context, obj[i], i) === false) break;
    }
  }

  return obj;
}

function tokenize(str, separator = ",", left = "(", right = ")") {
  if( empty(str) ){
    return [];
  }

  let depth = 0;
  let offset = 0;
  let buffer = "";
  let results = [];
  let length = str.length;
  let open = false;

  while (offset <= length) {
    let tmpOffset = -1;
    let offsets = [
      str.indexOf(separator, offset),
      str.indexOf(left, offset),
      str.indexOf(right, offset)
    ];
    for (let i = 0; i < 3; i++) {
      if (offsets[i] !== -1 && (offsets[i] < tmpOffset || tmpOffset === -1)) {
        tmpOffset = offsets[i];
      }
    }
    if (tmpOffset !== -1) {
      buffer += str.substr(offset, (tmpOffset - offset));
      let char = str.substr(tmpOffset, 1);
      if (!depth && char === separator) {
        results.push(buffer);
        buffer = "";
      } else {
        buffer += char;
      }
      if (left !== right) {
        if (char === left) {
          depth++;
        }
        if (char === right) {
          depth--;
        }
      } else {
        if (char === left) {
          if (!open) {
            depth++;
            open = true;
          } else {
            depth--;
          }
        }
      }
      offset = ++tmpOffset;
    } else {
      results.push(buffer + str.substr(offset));
      offset = length + 1;
    }
  }

  if (empty(results) && !empty(buffer)) {
    results.push(buffer);
  }

  if (!empty(results)) {
    return results.map(val => trim(val));
  }

  return [];
}

function splitConditions(token) {
  let conditions = false;
  let position = token.indexOf("[");
  if (position > -1) {
    conditions = token.substr(position);
    token = token.substr(0, position);
  }
  return [token, conditions];
}

function matchToken(key, token) {
  switch (token) {
    case "{n}":
      return is("numeric", key);
    case "{s}":
      return is("string", key);
    case "{*}":
      return true;
    default:
      return is("numeric", token) ? (key == token) : key === token;
  }
}

function matches(data, selector) {
  const identifier = "(?:\\\\.|[\\w-_\.]|[^\\x00-\\xa0])+";
  const attributes = new RegExp(`\\s*(${identifier})(?:\\s*([><!]?[=]|[><])\\s*(\\/.*?\\/|${identifier})|)\\s*\]`, "g");
  let cond;

  while (cond = attributes.exec(selector)) {
    const attr = cond[1];
    const op = cond[2] || null;
    const val = cond[3] || null;
    const hasProperty = hasProp(data, attr);

    if (empty(op) && empty(val) && !hasProperty) {
      return false;
    }

    if (!(hasProperty || data[attr] != null)) {
      return false;
    }

    let prop = hasProperty ? prop = data[attr] : undefined;
    let isBoolean = is("boolean", prop) || (prop === "true" || prop === "false");

    if (isBoolean && is("numeric", val)) {
      prop = prop ? "1": "0";
    } else if(isBoolean) {
      prop = prop ? "true" : "false";
    }

    if (op === "=" && val && val[0] === "/" && val[val.length - 1] === "/") {
      prop = is("string", prop) || is("numeric", prop) ? prop : "";
      if (!new RegExp(val.substr(1, val.length - 2)).test(prop)) {
        return false;
      }
    } else if ((op === "=" && prop != val) ||
      (op === "!=" && prop == val) ||
      (op === ">" && prop <= val) ||
      (op === "<" && prop >= val) ||
      (op === ">=" && prop < val) ||
      (op === "<=" && prop > val)
    ) {
      return false;
    }
  }

  return true;
}

export function get(data, path, defaultValue = null) {
  let parts, val;

  if (!is("collection", data)) {
    return defaultValue;
  }

  if (empty(data) || path == null || path === "" ) {
    return defaultValue;
  }

  if (is("string", path) || is("numeric", path)) {
    parts = (path + "").split(".");
  } else {
    if (!is("array", path)) {
      return defaultValue;
    }
    parts = path;
  }

  val = is("collection", data) ? clone(data) : data;
  each(parts, (v) => {
    if (is("collection", val) && hasProp(val, v)) {
      val = val[v];
    } else {
      val = defaultValue;
      return false;
    }
  });

  return val;
}

export function extract(data, path) {
  if (!is("collection", data)) {
    return null;
  }

  if (empty(path)) {
    return data;
  }

  if (!/[{\[]/.test(path)) {
    return get(data, path);
  }

  const key = "__set_item__";
  let tokens;
  let context = {[key]: [data]};

  if (path.indexOf("[") < 0) {
    tokens = path.split(".");
  } else {
    tokens = tokenize(path, ".", "[", "]");
  }

  each(tokens, (token) => {
    let next = [];
    let [_token, conditions] = splitConditions(token);

    each(context[key], (item) => {
      each(item, (v, k) => {
        if (matchToken(k, _token)) {
          next.push(v);
        }
      });
    });

    if (conditions) {
      let filter = [];
      each(next, (item) => {
        if (is("collection", item) && matches(item, conditions)) {
          filter.push(item);
        }
      });
      next = filter;
    }
    context = {[key]: next};
  });

  return context[key];
}

export function insert(data, path, value) {}

export function remove(data, path) {}

export function combine(data, keyPath, valuePath = null, groupPath = null) {}

export function format(data, paths, format) {}

export function contains(data, needle) {}

export function check(data, path) {}

export function filter(data, callback) {}

export function flatten(data, separator = ".") {}

export function expand(data, separator = ".") {}

export function merge(data, merge) {}

export function numeric(data) {}

export function dimensions(data) {}

export function maxDimensions(data) {}

export function map(data, path, callback) {}

export function reduce(data, path, callback) {}

export function apply(data, path, callback) {}

export function sort(data, path, dir = "asc") {}

export function diff(data, compare) {}

export function mergeDiff(data, compare) {}

export function normalize(data, assoc) {}

export function nest(data, options) {}

export function nest(data, options) {}<|endoftext|>


<commit_before>import {CRC32, checkCRCHash} from './crc32';
const commentSenderQuery = async(hash, retries = 5) => {
    if (sessionStorage['commentSender_hash_' + hash]) return JSON.parse(sessionStorage['commentSender_hash_' + hash]);
    if (hash.indexOf('D') === 0) return {};
    let mid = await checkCRCHash(hash);
    if (!mid) return {mid};
    try {
        let json = await fetch(`${location.protocol}//api.bilibili.com/cardrich?mid=${mid}`).then((res) => res.json());
        if (hash && (CRC32.bstr('' + mid) >>> 0) === parseInt(hash, 16)) sessionStorage['commentSender_hash_' + hash] = JSON.stringify(json.data.card);
        return json.data.card;
    } catch (e) {
        if (--retries > 0) return await commentSenderQuery(hash, retries);
        else return mid;
    }
};
export default commentSenderQuery;
<commit_msg>commentSenderQuery: fix api<commit_after>import {CRC32, checkCRCHash} from './crc32';
const commentSenderQuery = async(hash, retries = 5) => {
    if (sessionStorage['commentSender_hash_' + hash]) return JSON.parse(sessionStorage['commentSender_hash_' + hash]);
    if (hash.indexOf('D') === 0) return {};
    let mid = await checkCRCHash(hash);
    if (!mid) return {mid};
    try {
        let json = await fetch(`${location.protocol}//api.bilibili.com/x/web-interface/card?mid=${mid}&type=json`).then((res) => res.json());
        if (hash && (CRC32.bstr('' + mid) >>> 0) === parseInt(hash, 16)) sessionStorage['commentSender_hash_' + hash] = JSON.stringify(json.data.card);
        return json.data.card;
    } catch (e) {
        if (--retries > 0) return await commentSenderQuery(hash, retries);
        else return mid;
    }
};
export default commentSenderQuery;
<|endoftext|>


<commit_before>// validate
var validate = FORMx.validate = {
    // natural extension points
    type: {
        number: /^\-?\d*(\.\d+)?$/,
        email: /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
        url: /^http.[^\s]+$/i
    },
    test: {
        required: function(value) {
            return !value;
        },
        pattern: function(value, pattern) {
            return value && !value.match(new RegExp('^'+pattern+'$'));
        },
        'equal-to': function(value, reference, referenceValue) {
            return value !== referenceValue;
        },
        'not-equal': function(value, reference, referenceValue) {
            return value === referenceValue;
        },
        'required-if': function(value, reference, referenceValue) {
            return !!referenceValue && !value;
        },
        'required-unless': function(value, reference, referenceValue) {
            return !referenceValue && !value;
        },
        maxlength: function(value, maxlength) {
            return value.length > parseInt(maxlength, 10);
        },
        minlength: function(value, minlength) {
            return value && value.length < parseInt(minlength, 10);
        },
        min: function(value, min) {
            return validate.parse(value) < validate.parse(min);
        },
        max: function(value, max) {
            return validate.parse(value) > validate.parse(max);
        },
        step: function(value, step) {
            // % operator is inconsistent with floats, convert to ints first
            var decimal = step.indexOf('.'),
                factor = 1;
            if (decimal >= 0) {
                var power = step.length - decimal - 1;
                factor = Math.pow(10, power);
            }
            step = Math.round(parseFloat(step) * factor);
            var remainder = Math.round(value * factor) % step;
            return !isNaN(remainder) && remainder !== 0;
        }
    },
    classes: {
        required: 'valueMissing',
        pattern: 'patternMismatch',
        'equal-to': 'notEqual',
        'not-equal': 'notDifferent',
        'required-if': 'valueMissing',
        'required-unless': 'valueMissing',
        maxlength: 'tooLong',
        minlength: 'tooShort',
        min: 'rangeUnderflow',
        max: 'rangeOverflow',
        step: 'stepMismatch'
    },
    field: '[type=number],[type=email],[type=url],'+//types
           '[required],[pattern],[maxlength],[min],[max],[step],'+// standards
           '[equal-to],[not-equal],[required-if],[required-unless],[minlength]',// extensions
    toggle: function(el, valid) {
        el.classList.toggle('invalid', !valid);
        el.setCustomValidity(valid ? '' : 'This value is not valid.');
    },

    // internal functions
    parse: function(string) {
        return parseFloat(string);
    },
    valueOf: function(name, form) {
        var el = form.query('[name="'+name+'"]');
        return el && el.nameValue;
    },
    check: function(el, event) {
        var no = el.getAttribute('novalidate');
        if (!no) {
            return true;
        }
        if (no === 'true' || no === 'novalidate') {
            return false;
        }
        if (no.indexOf('!') === 0) {
            return no.substring(1).split().indexOf(event) !== -1;
        }
        return no.split(' ').indexOf(event) === -1;
    },
    one: function(el, event, form) {
        if (!validate.check(el, event)) {
            return true;
        }

        var typeRE = validate.type[el.getAttribute('type')],
            value = el.value,
            valid = true;
        form = form || validate.getForm(el);
        if (typeRE) {
            valid = !value || !!value.match(typeRE);
            el.classList.toggle('typeMismatch', !valid);
        }
        for (var name in validate.test) {
            var constraint = el.getAttribute(name) || el.hasAttribute(name);
            if (constraint) {
                var _class = validate.classes[name],
                    referenceValue = validate.valueOf(constraint, form),
                    failed = validate.test[name](value, referenceValue || constraint, referenceValue);
                if (failed) {
                    valid = false;
                }
                el.classList.toggle(_class, failed);
            }
        }
        validate.toggle(el, valid);
        if (valid) {
            el.lastValidValue = value;
        }
        return valid;
    },
    all: function(form, event) {
        if (!validate.check(form, event)) {
            return true;
        }

        var valid = true;
        form.queryAll(validate.field).each(function(field) {
            if (!validate.one(field, event, form)) {
                valid = false;
            }
        });
        form.classList.toggle('invalid', !valid);
        Eventi.fire(form, valid ? 'valid' : 'invalid');
        if (!valid) {
            var el = form.query('.invalid');
            if (el) {
                el.focus();
            }
        }
        return valid;
    },
    getForm: function(el) {
        return Eventi._.closest(el, 'form') || D.body;
    }
};

Eventi.on('^ready', function() {
    D.queryAll('form').each(function(){ validate.all(this, 'ready'); });
    D.queryAll('[required]').each('aria-required', true);
});
Eventi.on('keyup submit validate', function(e, event) {
    if (e.keyCode === 9) {
        return;// don't validate when tabbing
    }
    var el = e.target,
        valid = true;
    event = event && typeof event === "string" ? event : e.type;
    if (el.matches(validate.field)) {
        valid = validate.one(el, event);
    } else if (event === 'submit' || event === 'validate') {
        valid = validate.all(validate.getForm(el), event);
    }
    return valid;
});
Eventi.on('focusout<[restrict]>', function(e) {
    var el = e.target;
    if (el.matches('.invalid')) {
        var is = el.value;
        el.value = el.lastValidValue || el.getAttribute('value') || '';
        Eventi.fire(el, 'restricted', is);
        setTimeout(function(){ el.focus(); }, 0);
        return false;
    }
});
var errors = Object.keys(validate.classes)
                   .map(function(key){ return validate.classes[key]; })
                   .filter(function(error, i, self){ return self.indexOf(error) === i; });
D.head.append('style').textContent =
    '.error { display: none; }\n' +
    errors.map(function(error) {
        return '.invalid.'+error+' ~ .error.'+error;
    }).join(',\n') +
    ' { display: inline-block; }';
// end validate<commit_msg>fix novalidate logic<commit_after>// validate
var validate = FORMx.validate = {
    // natural extension points
    type: {
        number: /^\-?\d*(\.\d+)?$/,
        email: /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
        url: /^http.[^\s]+$/i
    },
    test: {
        required: function(value) {
            return !value;
        },
        pattern: function(value, pattern) {
            return value && !value.match(new RegExp('^'+pattern+'$'));
        },
        'equal-to': function(value, reference, referenceValue) {
            return value !== referenceValue;
        },
        'not-equal': function(value, reference, referenceValue) {
            return value === referenceValue;
        },
        'required-if': function(value, reference, referenceValue) {
            return !!referenceValue && !value;
        },
        'required-unless': function(value, reference, referenceValue) {
            return !referenceValue && !value;
        },
        maxlength: function(value, maxlength) {
            return value.length > parseInt(maxlength, 10);
        },
        minlength: function(value, minlength) {
            return value && value.length < parseInt(minlength, 10);
        },
        min: function(value, min) {
            return validate.parse(value) < validate.parse(min);
        },
        max: function(value, max) {
            return validate.parse(value) > validate.parse(max);
        },
        step: function(value, step) {
            // % operator is inconsistent with floats, convert to ints first
            var decimal = step.indexOf('.'),
                factor = 1;
            if (decimal >= 0) {
                var power = step.length - decimal - 1;
                factor = Math.pow(10, power);
            }
            step = Math.round(parseFloat(step) * factor);
            var remainder = Math.round(value * factor) % step;
            return !isNaN(remainder) && remainder !== 0;
        }
    },
    classes: {
        required: 'valueMissing',
        pattern: 'patternMismatch',
        'equal-to': 'notEqual',
        'not-equal': 'notDifferent',
        'required-if': 'valueMissing',
        'required-unless': 'valueMissing',
        maxlength: 'tooLong',
        minlength: 'tooShort',
        min: 'rangeUnderflow',
        max: 'rangeOverflow',
        step: 'stepMismatch'
    },
    field: '[type=number],[type=email],[type=url],'+//types
           '[required],[pattern],[maxlength],[min],[max],[step],'+// standards
           '[equal-to],[not-equal],[required-if],[required-unless],[minlength]',// extensions
    toggle: function(el, valid) {
        el.classList.toggle('invalid', !valid);
        el.setCustomValidity(valid ? '' : 'This value is not valid.');
    },

    // internal functions
    parse: function(string) {
        return parseFloat(string);
    },
    valueOf: function(name, form) {
        var el = form.query('[name="'+name+'"]');
        return el && el.nameValue;
    },
    check: function(el, event) {
        var no = el.getAttribute('novalidate');
        if (!el.hasAttribute('novalidate') || no === 'false') {
            return true;
        }
        if (no === 'true' || !no) {
            return false;
        }
        if (no.indexOf('!') === 0) {
            return no.substring(1).split().indexOf(event) !== -1;
        }
        return no.split(' ').indexOf(event) === -1;
    },
    one: function(el, event, form) {
        if (!validate.check(el, event)) {
            return true;
        }

        var typeRE = validate.type[el.getAttribute('type')],
            value = el.value,
            valid = true;
        form = form || validate.getForm(el);
        if (typeRE) {
            valid = !value || !!value.match(typeRE);
            el.classList.toggle('typeMismatch', !valid);
        }
        for (var name in validate.test) {
            var constraint = el.getAttribute(name) || el.hasAttribute(name);
            if (constraint) {
                var _class = validate.classes[name],
                    referenceValue = validate.valueOf(constraint, form),
                    failed = validate.test[name](value, referenceValue || constraint, referenceValue);
                if (failed) {
                    valid = false;
                }
                el.classList.toggle(_class, failed);
            }
        }
        validate.toggle(el, valid);
        if (valid) {
            el.lastValidValue = value;
        }
        return valid;
    },
    all: function(form, event) {
        if (!validate.check(form, event)) {
            return true;
        }

        var valid = true;
        form.queryAll(validate.field).each(function(field) {
            if (!validate.one(field, event, form)) {
                valid = false;
            }
        });
        form.classList.toggle('invalid', !valid);
        Eventi.fire(form, valid ? 'valid' : 'invalid');
        if (!valid) {
            var el = form.query('.invalid');
            if (el) {
                el.focus();
            }
        }
        return valid;
    },
    getForm: function(el) {
        return Eventi._.closest(el, 'form') || D.body;
    }
};

Eventi.on('^ready', function() {
    D.queryAll('form').each(function(){ validate.all(this, 'ready'); });
    D.queryAll('[required]').each('aria-required', true);
});
Eventi.on('keyup submit validate', function(e, event) {
    if (e.keyCode === 9) {
        return;// don't validate when tabbing
    }
    var el = e.target,
        valid = true;
    event = event && typeof event === "string" ? event : e.type;
    if (el.matches(validate.field)) {
        valid = validate.one(el, event);
    } else if (event === 'submit' || event === 'validate') {
        valid = validate.all(validate.getForm(el), event);
    }
    return valid;
});
Eventi.on('focusout<[restrict]>', function(e) {
    var el = e.target;
    if (el.matches('.invalid')) {
        var is = el.value;
        el.value = el.lastValidValue || el.getAttribute('value') || '';
        Eventi.fire(el, 'restricted', is);
        setTimeout(function(){ el.focus(); }, 0);
        return false;
    }
});
var errors = Object.keys(validate.classes)
                   .map(function(key){ return validate.classes[key]; })
                   .filter(function(error, i, self){ return self.indexOf(error) === i; });
D.head.append('style').textContent =
    '.error { display: none; }\n' +
    errors.map(function(error) {
        return '.invalid.'+error+' ~ .error.'+error;
    }).join(',\n') +
    ' { display: inline-block; }';
// end validate<|endoftext|>


<commit_before>function errors_trans(trans) {
    var errors = [];

    if(!trans.priority) {
        errors.push("undefined priority");
    }

    if(!trans.qeue) {
        errors.push("undefined queue");
    }
    else if(trans.qeue.constructor != Array) {
        errors.push("invalid queue (should be an Array)");
    }
    else {
        trans.qeue.forEach(function( value, index){
            if(!value || !value.id) {
                errors.push("invalid queue element " + index);
            }
        });
    }

    if(!trans.payload) {
        errors.push("undefined payload");
    }

    return errors;

}

exports.errors_trans = errors_trans;<commit_msg>queue, spelling<commit_after>function errors_trans(trans) {
    var errors = [];

    if(!trans.priority) {
        errors.push("undefined priority");
    }

    if(!trans.queue) {
        errors.push("undefined queue");
    }
    else if(trans.queue.constructor != Array) {
        errors.push("invalid queue (should be an Array)");
    }
    else {
        trans.queue.forEach(function( value, index){
            if(!value || !value.id) {
                errors.push("invalid queue element " + index);
            }
        });
    }

    if(!trans.payload) {
        errors.push("undefined payload");
    }

    return errors;

}

exports.errors_trans = errors_trans;<|endoftext|>


<commit_before>/*
 * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of perseo-fe
 *
 * perseo-fe is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * perseo-fe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with perseo-fe.
 * If not, see http://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */
'use strict';

var rules = require('../models/rules'),
    metrics = require('../models/metrics'),
    constants = require('./constants'),
    config = require('../../config'),
    logger = require('logops'),
    myutils = require('../myutils');

function GetAllRules(req, resp) {
    var limit = req.query.limit ? req.query.limit : 1000;
    var offset = req.query.offset ? req.query.offset : 0;
    var count = req.query.count ? req.query.count : true;
    rules.FindAll(req.service, req.subservice, limit, offset, count, function(err, data) {
        // apply limit and offset over rules array
        resp.set(constants.TOTAL_COUNT_HEADER, data.length);
        data = data.splice(offset, limit);
        myutils.respond(resp, err, data, true);
    });
}
function GetRules(req, resp) {
    var rule = {
        name: req.params.id,
        subservice: req.subservice,
        service: req.service
    };
    logger.info({}, 'getting rule %j', rule);
    rules.Find(rule, function(err, data) {
        myutils.respond(resp, err, data);
    });
}
function PostRules(req, resp) {
    req.body = req.body || {};
    req.body.subservice = req.subservice;
    req.body.service = req.service;
    logger.info({}, 'posting rule %j', req.body);
    metrics.IncMetrics(req.service, req.subservice, metrics.ruleCreation);
    rules.Save(req.body, function(err, data) {
        if (err) {
            metrics.IncMetrics(req.service, req.subservice, metrics.failedRuleCreation);
        } else {
            metrics.IncMetrics(req.service, req.subservice, metrics.okRuleCreation);
        }
        myutils.respond(resp, err, data);
    });
}
function DelRules(req, resp) {
    var rule = {
        name: req.params.id,
        subservice: req.subservice,
        service: req.service
    };
    logger.info({}, 'deleting rule %j', rule);
    metrics.IncMetrics(req.service, req.subservice, metrics.ruleDelete);
    rules.Remove(rule, function(err, data) {
        if (err) {
            metrics.IncMetrics(req.service, req.subservice, metrics.failedRuleDelete);
        } else {
            metrics.IncMetrics(req.service, req.subservice, metrics.okRuleDelete);
        }
        //200, it includes entity
        myutils.respond(resp, err, data);
    });
}

function AddTo(app) {
    app.get(config.endpoint.rulesPath, GetAllRules);
    app.get(config.endpoint.rulesPath + '/:id', GetRules);
    app.post(config.endpoint.rulesPath, PostRules);
    app.delete(config.endpoint.rulesPath + '/:id', DelRules);
}

/**
 * AddTo adds path and handler function to the Express app.
 *
 *  @param {Object}  Express application
 */
module.exports.AddTo = AddTo;
<commit_msg>fix pagination and fiware-total-count header<commit_after>/*
 * Copyright 2015 Telefonica Investigación y Desarrollo, S.A.U
 *
 * This file is part of perseo-fe
 *
 * perseo-fe is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 *
 * perseo-fe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public
 * License along with perseo-fe.
 * If not, see http://www.gnu.org/licenses/.
 *
 * For those usages not covered by the GNU Affero General Public License
 * please contact with::[contacto@tid.es]
 */
'use strict';

var rules = require('../models/rules'),
    metrics = require('../models/metrics'),
    constants = require('../constants'),
    config = require('../../config'),
    logger = require('logops'),
    myutils = require('../myutils');

function GetAllRules(req, resp) {
    var limit = req.query.limit ? req.query.limit : 1000;
    var offset = req.query.offset ? req.query.offset : 0;
    var count = req.query.count ? req.query.count : true;
    rules.FindAll(req.service, req.subservice, limit, offset, count, function(err, data) {
        // apply limit and offset over rules array
        resp.set(constants.TOTAL_COUNT_HEADER, data.length);
        data = data.splice(offset, limit);
        myutils.respond(resp, err, data, true);
    });
}
function GetRules(req, resp) {
    var rule = {
        name: req.params.id,
        subservice: req.subservice,
        service: req.service
    };
    logger.info({}, 'getting rule %j', rule);
    rules.Find(rule, function(err, data) {
        myutils.respond(resp, err, data);
    });
}
function PostRules(req, resp) {
    req.body = req.body || {};
    req.body.subservice = req.subservice;
    req.body.service = req.service;
    logger.info({}, 'posting rule %j', req.body);
    metrics.IncMetrics(req.service, req.subservice, metrics.ruleCreation);
    rules.Save(req.body, function(err, data) {
        if (err) {
            metrics.IncMetrics(req.service, req.subservice, metrics.failedRuleCreation);
        } else {
            metrics.IncMetrics(req.service, req.subservice, metrics.okRuleCreation);
        }
        myutils.respond(resp, err, data);
    });
}
function DelRules(req, resp) {
    var rule = {
        name: req.params.id,
        subservice: req.subservice,
        service: req.service
    };
    logger.info({}, 'deleting rule %j', rule);
    metrics.IncMetrics(req.service, req.subservice, metrics.ruleDelete);
    rules.Remove(rule, function(err, data) {
        if (err) {
            metrics.IncMetrics(req.service, req.subservice, metrics.failedRuleDelete);
        } else {
            metrics.IncMetrics(req.service, req.subservice, metrics.okRuleDelete);
        }
        //200, it includes entity
        myutils.respond(resp, err, data);
    });
}

function AddTo(app) {
    app.get(config.endpoint.rulesPath, GetAllRules);
    app.get(config.endpoint.rulesPath + '/:id', GetRules);
    app.post(config.endpoint.rulesPath, PostRules);
    app.delete(config.endpoint.rulesPath + '/:id', DelRules);
}

/**
 * AddTo adds path and handler function to the Express app.
 *
 *  @param {Object}  Express application
 */
module.exports.AddTo = AddTo;
<|endoftext|>


<commit_before>export const defaultPpls = [{"sn":"1","name":"员工1","loc":"珠海","laId":"","gaId":""},
{"sn":"2","name":"员工2","loc":"广州","laId":"","gaId":""},
{"sn":"3","name":"员工3","loc":"珠海","laId":"","gaId":""},
{"sn":"4","name":"员工4","loc":"珠海","laId":"","gaId":""},
{"sn":"5","name":"员工5","loc":"珠海","laId":"","gaId":""},
{"sn":"6","name":"员工6","loc":"珠海","laId":"","gaId":""},
{"sn":"7","name":"员工7","loc":"珠海","laId":"","gaId":""},
{"sn":"8","name":"员工8","loc":"珠海","laId":"","gaId":""},
{"sn":"9","name":"员工9","loc":"珠海","laId":"","gaId":""},
{"sn":"10","name":"员工10","loc":"珠海","laId":"","gaId":""},
{"sn":"11","name":"员工11","loc":"珠海","laId":"","gaId":""},
{"sn":"12","name":"员工12","loc":"珠海","laId":"","gaId":""},
{"sn":"13","name":"员工13","loc":"珠海","laId":"","gaId":""},
{"sn":"14","name":"员工14","loc":"珠海","laId":"","gaId":""},
{"sn":"15","name":"员工15","loc":"珠海","laId":"","gaId":""},
{"sn":"16","name":"员工16","loc":"珠海","laId":"","gaId":""},
{"sn":"17","name":"员工17","loc":"珠海","laId":"","gaId":""},
{"sn":"18","name":"员工18","loc":"珠海","laId":"","gaId":""},
{"sn":"19","name":"员工19","loc":"珠海","laId":"","gaId":""},
{"sn":"20","name":"员工20","loc":"珠海","laId":"","gaId":""},
{"sn":"21","name":"员工21","loc":"珠海","laId":"","gaId":""},
{"sn":"22","name":"员工22","loc":"珠海","laId":"","gaId":""},
{"sn":"23","name":"员工23","loc":"珠海","laId":"","gaId":""},
{"sn":"24","name":"员工24","loc":"珠海","laId":"","gaId":""},
{"sn":"25","name":"员工25","loc":"珠海","laId":"","gaId":""},
{"sn":"26","name":"员工26","loc":"珠海","laId":"","gaId":""},
{"sn":"27","name":"员工27","loc":"珠海","laId":"","gaId":""},
{"sn":"28","name":"员工28","loc":"珠海","laId":"","gaId":""},
{"sn":"29","name":"员工29","loc":"珠海","laId":"","gaId":""},
{"sn":"30","name":"员工30","loc":"珠海","laId":"","gaId":""}];<commit_msg>refine mock ppl<commit_after>export const defaultPpls = [{"sn":"1","name":"员工1","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"2","name":"员工2","loc":"广州","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"3","name":"员工3","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"4","name":"员工4","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"5","name":"员工5","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"6","name":"员工6","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"7","name":"员工7","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"8","name":"员工8","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"9","name":"员工9","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"10","name":"员工10","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"11","name":"员工11","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"12","name":"员工12","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"13","name":"员工13","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"14","name":"员工14","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"15","name":"员工15","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"16","name":"员工16","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"17","name":"员工17","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"18","name":"员工18","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"19","name":"员工19","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"20","name":"员工20","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"21","name":"员工21","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"22","name":"员工22","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"23","name":"员工23","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"24","name":"员工24","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"25","name":"员工25","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"26","name":"员工26","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"27","name":"员工27","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"28","name":"员工28","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"29","name":"员工29","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"},
{"sn":"30","name":"员工30","loc":"珠海","laId":"","gaId":"","forLa":"true","forGa":"true","done":"",rtx:"yuangong1"}];
<|endoftext|>


<commit_before>var knife = require('../knife'),
    Issue = require('../issue');

module.exports = {
    name: 'spec-char-escape',
    on: ['dom'],
    filter: ['text', 'tag'],
    desc: 'If set, special characters in text and attributes (e.g. `>`) must be escaped.'
};

// Messages for each group in the regex
var messages = [
    undefined,
    'an escape with invalid characters',
    'an unescaped angle bracket',
    'an ill-formed escape sequence'
];
var regex = /(&[^a-zA-Z0-9#;]*;)|([<>])|(&[a-zA-Z0-9#]*[^a-zA-Z0-9#;])/gm;

function addIssues(text, lineCol, issues, partDesc) {
    var lineColFunc = knife.getLineColFunc(text, lineCol),
        match;
    while (match = regex.exec(text)) {
        var i = 1; while (!match[i]) { i++; }
        issues.push(new Issue('E023', lineColFunc(match.index), {
            chars: match[i],
            part: partDesc,
            desc: messages[i]
        }));
    }
}

module.exports.lint = function (element, opts) {
    var issues = [];

    // if it's text - make sure it only has alphanumericals. If it has a &, a ; should follow.
    if (element.type === 'text' && element.data.length > 0) {
        addIssues(element.data, element.openLineCol, issues, 'text');
    }

    var attrs = element.attribs;
    if (attrs) {
        Object.keys(attrs).forEach(function (name) {
            var v = attrs[name];
            addIssues(v.value, v.valueLineCol, issues, 'attribute value');
        });
    }
    return issues;
};
<commit_msg>Fix line/column numbers in spec-char-escape output (fixes #205)<commit_after>var knife = require('../knife'),
    Issue = require('../issue');

module.exports = {
    name: 'spec-char-escape',
    on: ['dom'],
    filter: ['text', 'tag'],
    desc: 'If set, special characters in text and attributes (e.g. `>`) must be escaped.'
};

// Messages for each group in the regex
var messages = [
    undefined,
    'an escape with invalid characters',
    'an unescaped angle bracket',
    'an ill-formed escape sequence'
];
var regex = /(&[^a-zA-Z0-9#;]*;)|([<>])|(&[a-zA-Z0-9#]*[^a-zA-Z0-9#;])/gm;

function addIssues(text, lineCol, issues, partDesc) {
    var lineColFunc = knife.getLineColFunc(text, lineCol),
        match;
    while (match = regex.exec(text)) {
        var i = 1; while (!match[i]) { i++; }
        issues.push(new Issue('E023', lineColFunc(match.index), {
            chars: match[i],
            part: partDesc,
            desc: messages[i]
        }));
    }
}

module.exports.lint = function (element, opts) {
    var issues = [];

    // if it's text - make sure it only has alphanumericals. If it has a &, a ; should follow.
    if (element.type === 'text' && element.data.length > 0) {
        addIssues(element.data, element.lineCol, issues, 'text');
    }

    var attrs = element.attribs;
    if (attrs) {
        Object.keys(attrs).forEach(function (name) {
            var v = attrs[name];
            addIssues(v.value, v.valueLineCol, issues, 'attribute value');
        });
    }
    return issues;
};
<|endoftext|>


<commit_before>function makeKoalaJS() {
    var statics = {};
	var koala = function(e,t){
		if (typeof e == "object"){
			e.kid = koala.raw.length;
			koala.raw.push(e);
			return;
		}
		var args = [];
		var temp;
		/*for (var i = 0; i < arguments.length; i++){
			if (typeof arguments[i] == "string"){
				temp = koala.splitquery(arguments[i]);
				for (var t in temp){
					args.push(temp[t]);
				}
			}
			else{
				args.push(arguments[i]);
			}

		}*/

		args = koala.splitquery(e);

		var workspace = koala.switcher(args[0]);

		for (var i = 1; i < args.length; i++){
			workspace = koala.switcher(args[i],workspace);
		}
		if (t){
			var retval = [];
			for (var i = 0; i < workspace.length; i++){
				retval.push(t(workspace[i]));
			}
			return retval;
		}
		else{
			return workspace;
		}
	}
	var dirty = 0;
	koala.remove = function(o){
		if (typeof o == "object"){
			o = o.kid;
		}
		koala.raw[o].shouldbedeleted = true;
		dirty++;
		delete koala.raw[o];
		/*for (var i in koala.cache){
			delete koala.cache[i].raw[o];
		}*/
		/*koala.raw.splice(o,1);
		for (var i = o; i < koala.raw.length; i++){
			koala.raw[i].kid = i;
		}*/
	}
	koala.merge = function(x,y){
		for (var i in y){
			x[i] = y[i];
		}
	}
	koala.splitquery = function(x){
		var delim = [".","<",">","!"];
		var closest = [];
		var index = 0;
		var retval = [];
		for (var i = 0; i < delim.length; i++){
			closest[i] = x.indexOf(delim[i]);
		}
		var go;
		var c = x.length;
		while(true){
			go = false;
			for (var i = 0; i < closest.length; i++){
				if (closest[i] < index){
					closest[i] = x.indexOf(delim[i],index);
				}
				if ( closest[i] >= 0 && closest[i] < c){
					c = closest[i];
					go = true;
				}
			}
			if (!go){
				break;
			}
			retval.push(x.substring(index-1,c));
			index = c+1;
			c=x.length;
		}
		retval.splice(0,1);
		retval.push(x.substr(index-1));
		return retval;
	}
	koala.switcher = function(t,w){
		if (typeof t == "string"){
			return koala.string(t,w);
		}
	};
	koala.raw = [];

	//koala.cache = {};
	koala.string = function(t,w){
		var search;
		var retval = [];
		search = t.substr(1);
		if (typeof w == "undefined"){
			w = koala.raw;
		}
		switch (t.charAt(0)){
			case ".":
				var eq = search.split("=");

				if (eq.length > 1){
					search = eq[0];
					if (JSON){
						eq = JSON.parse(eq[1]);
					}
					else{
						eq = eval(eq[1]);
					}
					for (var i = 0; i < w.length; i++){
					    if (w[i]) {
					        if (w[i][search] == eq && !w[i].shouldbedeleted) {
					            retval.push(w[i]);
					        }
					    }
					}
				}
				else{
				    for (var i = 0; i < w.length; i++) {
				        if (w[i]) {
				            if (w[i][search] && !w[i].shouldbedeleted) {
				                retval.push(w[i]);
				            }
				        }
					}
				}
				return retval;
				break;

			case "!":
				var eq = search.split("=");

				if (eq.length > 1){
					search = eq[0];
					if (JSON){
						eq = JSON.parse(eq[1]);
					}
					else{
						eq = eval(eq[1]);
					}
					for (var i = 0; i < w.length; i++) {
					    if (w[i]) {
					        if (w[i][search] != eq && !w[i].shouldbedeleted) {
					            retval.push(w[i]);
					        }
					    }
					}
				}
				else{
				    for (var i = 0; i < w.length; i++) {
				        if (w[i]) {
				            if (!w[i][search] && !w[i].shouldbedeleted) {
				                retval.push(w[i]);
				            }
				        }
					}
				}
				return retval;
				break;
			case ">":
			    for (var i = 0; i < w.length; i++) {
			        if (w[i]) {
			            if (w[i][search] && !w[i].shouldbedeleted) {
			                retval.push(w[i][search]());
			            }
			        }
				}
				return retval;
				break;

			case "<":
			    for (var i = 0; i < w.length; i++) {
			        if (w[i]) {
			            if (!w[i].shouldbedeleted) {
			                retval.push(w[i][search]);
			            }
			        }
				}
				return retval;
				break;

		}
	}
	koala.clean = function () {
	    if (dirty >= koala.raw.length/2) {
	        var newraw = [];
	        var index = 0;
	        for (var i in koala.raw) {
	            newraw.push(koala.raw[i]);
	            koala.raw[i].kid = index;
	            index++;

	        }
	        koala.raw = newraw;
	        dirty = 0;
	    }
	}
	return koala;
}<commit_msg>Made variables private<commit_after>function makeKoalaJS() {
    var statics = {};
    var raw = [];
	var koala = function(e,t){
		if (typeof e == "object"){
			e.kid = raw.length;
			raw.push(e);
			return;
		}
		var args = [];
		var temp;
		/*for (var i = 0; i < arguments.length; i++){
			if (typeof arguments[i] == "string"){
				temp = koala.splitquery(arguments[i]);
				for (var t in temp){
					args.push(temp[t]);
				}
			}
			else{
				args.push(arguments[i]);
			}

		}*/

		args = splitquery(e);

		var workspace = switcher(args[0]);

		for (var i = 1; i < args.length; i++){
			workspace = switcher(args[i],workspace);
		}
		if (t){
			var retval = [];
			for (var i = 0; i < workspace.length; i++){
				retval.push(t(workspace[i]));
			}
			return retval;
		}
		else{
			return workspace;
		}
	}
	var dirty = 0;
	koala.remove = function(o){
		if (typeof o == "object"){
			o = o.kid;
		}
		raw[o].shouldbedeleted = true;
		dirty++;
		delete raw[o];
		/*for (var i in koala.cache){
			delete koala.cache[i].raw[o];
		}*/
		/*raw.splice(o,1);
		for (var i = o; i < raw.length; i++){
			raw[i].kid = i;
		}*/
	}
	koala.merge = function(x,y){
		for (var i in y){
			x[i] = y[i];
		}
	}
	function splitquery(x) {
		var delim = [".","<",">","!"];
		var closest = [];
		var index = 0;
		var retval = [];
		for (var i = 0; i < delim.length; i++){
			closest[i] = x.indexOf(delim[i]);
		}
		var go;
		var c = x.length;
		while(true){
			go = false;
			for (var i = 0; i < closest.length; i++){
				if (closest[i] < index){
					closest[i] = x.indexOf(delim[i],index);
				}
				if ( closest[i] >= 0 && closest[i] < c){
					c = closest[i];
					go = true;
				}
			}
			if (!go){
				break;
			}
			retval.push(x.substring(index-1,c));
			index = c+1;
			c=x.length;
		}
		retval.splice(0,1);
		retval.push(x.substr(index-1));
		return retval;
	}
	function switcher(t, w) {
		if (typeof t == "string"){
			return string(t,w);
		}
	};

	//koala.cache = {};
	function string(t, w) {
		var search;
		var retval = [];
		search = t.substr(1);
		if (typeof w == "undefined"){
			w = raw;
		}
		switch (t.charAt(0)){
			case ".":
				var eq = search.split("=");

				if (eq.length > 1){
					search = eq[0];
					if (JSON){
						eq = JSON.parse(eq[1]);
					}
					else{
						eq = eval(eq[1]);
					}
					for (var i = 0; i < w.length; i++){
					    if (w[i]) {
					        if (w[i][search] == eq && !w[i].shouldbedeleted) {
					            retval.push(w[i]);
					        }
					    }
					}
				}
				else{
				    for (var i = 0; i < w.length; i++) {
				        if (w[i]) {
				            if (w[i][search] && !w[i].shouldbedeleted) {
				                retval.push(w[i]);
				            }
				        }
					}
				}
				return retval;
				break;

			case "!":
				var eq = search.split("=");

				if (eq.length > 1){
					search = eq[0];
					if (JSON){
						eq = JSON.parse(eq[1]);
					}
					else{
						eq = eval(eq[1]);
					}
					for (var i = 0; i < w.length; i++) {
					    if (w[i]) {
					        if (w[i][search] != eq && !w[i].shouldbedeleted) {
					            retval.push(w[i]);
					        }
					    }
					}
				}
				else{
				    for (var i = 0; i < w.length; i++) {
				        if (w[i]) {
				            if (!w[i][search] && !w[i].shouldbedeleted) {
				                retval.push(w[i]);
				            }
				        }
					}
				}
				return retval;
				break;
			case ">":
			    for (var i = 0; i < w.length; i++) {
			        if (w[i]) {
			            if (w[i][search] && !w[i].shouldbedeleted) {
			                retval.push(w[i][search]());
			            }
			        }
				}
				return retval;
				break;

			case "<":
			    for (var i = 0; i < w.length; i++) {
			        if (w[i]) {
			            if (!w[i].shouldbedeleted) {
			                retval.push(w[i][search]);
			            }
			        }
				}
				return retval;
				break;

		}
	}
	koala.clean = function () {
	    if (dirty >= raw.length/2) {
	        var newraw = [];
	        var index = 0;
	        for (var i in raw) {
	            newraw.push(raw[i]);
	            raw[i].kid = index;
	            index++;

	        }
	        raw = newraw;
	        dirty = 0;
	    }
	}
	return koala;
}<|endoftext|>


<commit_before>/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/

/**********************************************************\
 *                                                        *
 * hprose/server/WebSocketServer.js                       *
 *                                                        *
 * Hprose WebSocket Server for Node.js.                   *
 *                                                        *
 * LastModified: Jun 19, 2015                             *
 * Author: Ma Bingyao <andot@hprose.com>                  *
 *                                                        *
\**********************************************************/

/*jshint node:true, eqeqeq:true */
'use strict';

var util = require('util');
var ws = require('ws');
var http = require('http');
var https = require('https');
var WebSocketService = global.hprose.WebSocketService;

function WebSocketServer(options, tlsOptions) {
    WebSocketService.call(this);
    var self = this;
    var httpserver = http.createServer(self.handle);
    var host = options.host;
    var port = options.port;
    delete options.host;
    delete options.port;
    options.server = httpserver;
    options.perMessageDeflate = false;
    var server = null;

    function onerror(e) {
        var context = {
            httpserver: httpserver,
            server: self.server,
            userdata:{}
        };
        self.emit('sendError', e, context);
        if (self.onSendError) {
            self.onSendError(e, context);
        }
    }

    httpserver.on('clientError', onerror);

    function start() {
        httpserver.listen(port, host);
        server = new ws.Server(options);
        server.on('connection', self.wsHandle);
        server.on('error', onerror);
    }
    function stop() {
        server.close();
        httpserver.close();
    }
    function listen() {
        server.listen.apply(server, arguments);
        server = new ws.Server(options);
        server.on('connection', self.wsHandle);
        server.on('error', onerror);
    }
    function close(callback) {
        server.close();
        httpserver.close(callback);
    }

    Object.defineProperties(this, {
        httpserver: { get: function () { return httpserver; } },
        server: { get: function () { return server; } },
        start: { value: start },
        stop: { value: stop },
        listen: { value: listen },
        close: { value: close }
    });
}

util.inherits(WebSocketServer, WebSocketService);

global.hprose.WebSocketServer = WebSocketServer;
<commit_msg>Fixed listen method of WebSocketServer<commit_after>/**********************************************************\
|                                                          |
|                          hprose                          |
|                                                          |
| Official WebSite: http://www.hprose.com/                 |
|                   http://www.hprose.org/                 |
|                                                          |
\**********************************************************/

/**********************************************************\
 *                                                        *
 * hprose/server/WebSocketServer.js                       *
 *                                                        *
 * Hprose WebSocket Server for Node.js.                   *
 *                                                        *
 * LastModified: Aug 1, 2015                              *
 * Author: Ma Bingyao <andot@hprose.com>                  *
 *                                                        *
\**********************************************************/

/*jshint node:true, eqeqeq:true */
'use strict';

var util = require('util');
var ws = require('ws');
var http = require('http');
var https = require('https');
var WebSocketService = global.hprose.WebSocketService;

function WebSocketServer(options, tlsOptions) {
    WebSocketService.call(this);
    var self = this;
    var httpserver = http.createServer(self.handle);
    var host = options.host;
    var port = options.port;
    delete options.host;
    delete options.port;
    options.server = httpserver;
    options.perMessageDeflate = false;
    var server = null;

    function onerror(e) {
        var context = {
            httpserver: httpserver,
            server: self.server,
            userdata:{}
        };
        self.emit('sendError', e, context);
        if (self.onSendError) {
            self.onSendError(e, context);
        }
    }

    httpserver.on('clientError', onerror);

    function start() {
        httpserver.listen(port, host);
        server = new ws.Server(options);
        server.on('connection', self.wsHandle);
        server.on('error', onerror);
    }
    function stop() {
        server.close();
        httpserver.close();
    }
    function listen() {
        httpserver.listen.apply(httpserver, arguments);
        server = new ws.Server(options);
        server.on('connection', self.wsHandle);
        server.on('error', onerror);
    }
    function close(callback) {
        server.close();
        httpserver.close(callback);
    }

    Object.defineProperties(this, {
        httpserver: { get: function () { return httpserver; } },
        server: { get: function () { return server; } },
        start: { value: start },
        stop: { value: stop },
        listen: { value: listen },
        close: { value: close }
    });
}

util.inherits(WebSocketServer, WebSocketService);

global.hprose.WebSocketServer = WebSocketServer;
<|endoftext|>


<commit_before>var databaseAccessor = require('./DatabaseAccessor.js');
var dbNames = {
    'userFriends':{key:'RIN',value:'friends'},
}
var databaseFactory = function(dbname, localMap){
    var names = dbNames[dbname];
    var obj = databaseAccessor();
    obj.setDbName(dbname);
    obj.setKeyName(names.key);
    obj.setValueName(names.value);
    return obj;
};
module.exports = databaseFactory;
<commit_msg>Fixed build errors<commit_after>var databaseAccessor = require('./DatabaseAccessor.js');
var dbNames = {
    'userFriends':{key:'RIN',value:'friends'},
};
var databaseFactory = function(dbname, localMap){
    var names = dbNames[dbname];
    var obj = databaseAccessor();
    obj.setDbName(dbname);
    obj.setKeyName(names.key);
    obj.setValueName(names.value);
    return obj;
};
module.exports = databaseFactory;
<|endoftext|>


<commit_before>/** Versions code */

var fs = require('nor-fs');
var path = require('path');

/** Returns the current package version on disk */
function pkg_version_on_disk(file) {
	var data = fs.sync.readFile( file, {'encoding':'utf8'});
	try {
		data = JSON.parse(data);
		return data.version;
	} catch(e) {
		return;
	}
}

// Exports
var versions = module.exports = {};

/** */
versions.getAppName = function() {
	return process.env.npm_package_name;
};

/** Returns current versions */
versions.get = function(file) {
	var result = {};
	result[versions.getAppName() + '@fs'] = pkg_version_on_disk(file);
	result[versions.getAppName() + '@backend'] = process.env.npm_package_version;
	result['node@backend'] = process.env.npm_config_node_version.replace(/^v/, "");
	return result;
};

/* EOF */
<commit_msg>Fixed compatibility for node v0.11.13<commit_after>/** Versions code */

var fs = require('nor-fs');
var path = require('path');

/** Returns the current package version on disk */
function pkg_version_on_disk(file) {
	var data = fs.sync.readFile( file, {'encoding':'utf8'});
	try {
		data = JSON.parse(data);
		return data.version;
	} catch(e) {
		return;
	}
}

// Exports
var versions = module.exports = {};

/** */
versions.getAppName = function() {
	return process.env.npm_package_name;
};

/** Returns current versions */
versions.get = function(file) {
	var result = {};
	result[versions.getAppName() + '@fs'] = pkg_version_on_disk(file);
	result[versions.getAppName() + '@backend'] = process.env.npm_package_version;
	result['node@backend'] = process.versions.node;
	return result;
};

/* EOF */
<|endoftext|>


<commit_before>function ytvidcount() {
    if ("/watch" !== window.location.pathname) return false;
    var anchor = document.createElement("a"),
        channelId = document.querySelector("meta[itemprop=channelId]").getAttribute("content"),
        username = document.querySelector("a.yt-user-photo").href,
        xhr = new XMLHttpRequest;
    anchor.style = "color:#999;display:inline-block;font-size:11px;margin-top:1px;",
    anchor.className = "yt-channel-video-count spf-link",
    anchor.href = username + "/videos", document.querySelector(".yt-user-info").append(e),

    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            var response = JSON.parse(o.responseText);
            anchor.innerHTML = "· " + response.items[0].statistics.videoCount + " videos"
        }
    },
    xhr.open("GET", "https://content.googleapis.com/youtube/v3/channels?id=" + channelId + "&part=statistics&key="+window.apikey, true),
    xhr.send()
}
ytvidcount();

window.addEventListener("spfdone", ytvidcount);<commit_msg>Further documentation<commit_after>//This is the main function - payload, this is the main logic executed.
//All the content_script, background helpers are to help inject this payload like a normal inline JavaScript without chrome security restrictions while still maintaing a roundabout access to chrome.* APIs

//Function name is chosen to avoid any potential further conflict
function ytvidcount() {
    //making sure we are on a /watch* page, in any other case - function is not executed at all (saves quota)
    if ("/watch" !== window.location.pathname) return false;

    //set up variables
    //main anchor element 100 videos
    var anchor = document.createElement("a"),
        //channel id found in meta header to be used in the API call
        channelId = document.querySelector("meta[itemprop=channelId]").getAttribute("content"),
        //canonical username just to make the video list link prettier
        username = document.querySelector("a.yt-user-photo").href,
        //set up for AJAX API request
        xhr = new XMLHttpRequest;

    //styling of the anchor
    anchor.style = "color:#999;display:inline-block;font-size:11px;margin-top:1px;",
    //adding classes also spf-link to make it spf-friendly
    anchor.className = "yt-channel-video-count spf-link",
    //construction of the destination url - "/user/USERNAME/videos"
    anchor.href = username + "/videos", document.querySelector(".yt-user-info").append(e),

    //the ajax call for the number of videos of the particular channel
    xhr.onreadystatechange = function() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            //returned are some channel stats in JSON
            var response = JSON.parse(o.responseText);
            //the number of videos is under response.items[0].statistics.videoCount which set as anchor text alongside a dot and a string 'videos'
            anchor.innerHTML = "· " + response.items[0].statistics.videoCount + " videos"
        }
    },
    //the actual AJAX call being executed with the apikey retrieved from chrome.storage.sync which is saved by options.
    //In production this whole script is in a content_script so the apikey is never actaully written to winow.apikey
    //But to portray the apikey in sourcecode i used some old code that wrote apikey to window.apikey in a content_script and then retrieved it in the injected payload script.
    xhr.open("GET", "https://content.googleapis.com/youtube/v3/channels?id=" + channelId + "&part=statistics&key="+window.apikey, true),
    xhr.send()
}
//First call if we landed on a watch page
ytvidcount();

//YouTube uses SPF (spfjs - github.com/youtube/spfjs) which is their own HTML5 History API library that reloads only the changing parts of a webpage, because of the way our payload works it must be called everytime any change of location happens - a spf reload
window.addEventListener("spfdone", ytvidcount);<|endoftext|>