<commit_before>var Util = require("../../../util");

function handleNumber(r, length) {
    var value = ""
    // hex
    if (/^\-?0x|H$/.test(r)) {
        value = parseInt(r.replace("-", ""), 16);
        if (r[0] === "-") {
            value = -value;
        }
        return Util.bin(value, length);
    }

    // Int
    if (/[0-9]+/.test(r)) {
        value = parseInt(r);
        return Util.bin(value, length);
    }

    return Util.bin(0, length);
}

function compile(line, parsed) {

    function bR(r, length) {
        length = length || 5;

        // %r0+x
        if (/^\%r[0-9]\+[a-z]+$/.test(r)) {
            return Util.pad(Util.addBin(
                bR(r.replace(/\+[a-z]+$/g, "")), bR("[" + r.match(/\+([a-z]+)/)[0] + "]")
            ), length);
        }

        // %r0+4
        if (/^\%r[0-9]\+[0-9]+$/.test(r)) {
            debugger
            return Util.pad(
                Util.addBin(bR(r.replace(/\+[0-9]+$/g, "")), bR(r.match(/\+([0-9]+)/)[0])
            ), length);
        }

        // %r0
        if (Util.isRegister(r)) {
            return Util.pad(parseInt(r.match(/\%r([0-9]+)/)[1]).toString(2), length);
        }

        // [x]
        if (Util.isLocAdd(r)) {
            var add = r.match(/^\[([a-z,_]+)\]$/)[1]
              , loc = parsed.addresses[add]
              ;

            if (!loc) {
                throw new Error("Invalid memory location: " + add);
            }
            return Util.pad(loc.address.toString(2), length);
        }

        return handleNumber(r);
    }

    function getRd(line, raw) {
        if (raw === true) {
            return line.iArgs.slice(-1)[0];
        }
        return bR(getRd(line, true));
    }

    function getRs1(line, raw) {
        if (raw === true) {
            return line.iArgs[0];
        }
        var r = getRs1(line, true);
        return bR(r);
    }

    function getRs2(line, raw) {
        if (raw === true) {
            return line.iArgs[1];
        }
        if (line.iArgs.length <= 2) {
            return "00000";
        }
        var r = getRs2(line, true);
        return bR(r);
    }

    var instruction = "";

    if (line.instruction) {
        switch (line.type) {
            case "memory":
                instruction += "11";
                break;
            case "arithmetic":
                instruction += "10";
                break;
            case "sethi":
                instruction += "00";
                break;
            case "branch":
                instruction += "00";
                break;
            case "control":
                instruction += "01";
                break;
        }

        switch (line.instruction) {

            // Memory
            case "ld":
                if (line.iArgs.length >= 2) {
                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "000000";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRs1(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRs1(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: " + line.c);
                }
                break;
            case "st":
                if (line.iArgs.length >= 2) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    if (Util.isLocAdd(getRd(line, true))) {
                        rd = getRs1(line);
                        rs1 = Util.pad("", 5);
                    }

                    // rd
                    instruction += rd;

                    // op
                    instruction += ("000100");

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: " + line.c);
                }
                break;

            // Arithmetic
            case "addcc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    // if (Util.isLocAdd(getRd(line, true))) {
                    //     rd = Util.pad("", 5);
                    // }

                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += ("010000");

                    // rs1
                    instruction += rs1;

                    // Add two registers
                    if (Util.isRegister(getRs2(line, true))) {
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        // Add a register and a constant
                        instruction += "1";
                        instruction += handleNumber(getRs2(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: addcc requires 3 arguments");
                }
                break;
            case "andcc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "010001";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: andcc requires 3 arguments");
                }
                break;
            case "orcc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "010010";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: orcc requires 3 arguments");
                }
                break;
            case "orncc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "010110";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: orncc requires 3 arguments");
                }
                break;
            // Control
            case "call":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for call instruction."); }
                if (!parsed.addresses[line.iArgs[0]]) {
                    throw new Error("Subrutine " +line.iArgs[0] + " doesn't exist");
                }
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 30);
                break;
            case "jmpl":
                if (/^jmpl \%r[0-9]+\+[0-9]+\,\ ?\%r[0-9]+$/.test(line.c)) {
                    instruction += (("00000" + eval(line.iArgs[1].replace("%r", "")).toString(2)).slice(-5));
                    instruction += ("111000");
                    instruction += (("00000" + parseInt(line.iArgs[0].replace(/\%r|\+[0-9]+/g, "")).toString(2)).slice(-5));
                    instruction += ("1");
                    // simm13
                    instruction += (("0000000000000" + parseInt(line.iArgs[0].match(/\+([0-9]+)/)).toString(2)).slice(-13));
                }
                break;
            case "be":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for be instruction."); }
                instruction += "0";
                instruction += "0001";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
            case "bcs":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bcs instruction."); }
                instruction += "0";
                instruction += "0101";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
            case "bneg":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bneg instruction."); }
                instruction += "0";
                instruction += "0110";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
            case "bvs":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bneg instruction."); }
                instruction += "0";
                instruction += "0111";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
            case "ba":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bneg instruction."); }
                instruction += "0";
                instruction += "1000";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
        }
    }

    if (line.label && !line.instruction) {
        instruction = handleNumber(line.c, 32);
    }

    return instruction;
}

module.exports = compile;
<commit_msg>Removed debugger<commit_after>var Util = require("../../../util");

function handleNumber(r, length) {
    var value = ""
    // hex
    if (/^\-?0x|H$/.test(r)) {
        value = parseInt(r.replace("-", ""), 16);
        if (r[0] === "-") {
            value = -value;
        }
        return Util.bin(value, length);
    }

    // Int
    if (/[0-9]+/.test(r)) {
        value = parseInt(r);
        return Util.bin(value, length);
    }

    return Util.bin(0, length);
}

function compile(line, parsed) {

    function bR(r, length) {
        length = length || 5;

        // %r0+x
        if (/^\%r[0-9]\+[a-z]+$/.test(r)) {
            return Util.pad(Util.addBin(
                bR(r.replace(/\+[a-z]+$/g, "")), bR("[" + r.match(/\+([a-z]+)/)[0] + "]")
            ), length);
        }

        // %r0+4
        if (/^\%r[0-9]\+[0-9]+$/.test(r)) {
            return Util.pad(
                Util.addBin(bR(r.replace(/\+[0-9]+$/g, "")), bR(r.match(/\+([0-9]+)/)[0])
            ), length);
        }

        // %r0
        if (Util.isRegister(r)) {
            return Util.pad(parseInt(r.match(/\%r([0-9]+)/)[1]).toString(2), length);
        }

        // [x]
        if (Util.isLocAdd(r)) {
            var add = r.match(/^\[([a-z,_]+)\]$/)[1]
              , loc = parsed.addresses[add]
              ;

            if (!loc) {
                throw new Error("Invalid memory location: " + add);
            }
            return Util.pad(loc.address.toString(2), length);
        }

        return handleNumber(r);
    }

    function getRd(line, raw) {
        if (raw === true) {
            return line.iArgs.slice(-1)[0];
        }
        return bR(getRd(line, true));
    }

    function getRs1(line, raw) {
        if (raw === true) {
            return line.iArgs[0];
        }
        var r = getRs1(line, true);
        return bR(r);
    }

    function getRs2(line, raw) {
        if (raw === true) {
            return line.iArgs[1];
        }
        if (line.iArgs.length <= 2) {
            return "00000";
        }
        var r = getRs2(line, true);
        return bR(r);
    }

    var instruction = "";

    if (line.instruction) {
        switch (line.type) {
            case "memory":
                instruction += "11";
                break;
            case "arithmetic":
                instruction += "10";
                break;
            case "sethi":
                instruction += "00";
                break;
            case "branch":
                instruction += "00";
                break;
            case "control":
                instruction += "01";
                break;
        }

        switch (line.instruction) {

            // Memory
            case "ld":
                if (line.iArgs.length >= 2) {
                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "000000";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRs1(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRs1(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: " + line.c);
                }
                break;
            case "st":
                if (line.iArgs.length >= 2) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    if (Util.isLocAdd(getRd(line, true))) {
                        rd = getRs1(line);
                        rs1 = Util.pad("", 5);
                    }

                    // rd
                    instruction += rd;

                    // op
                    instruction += ("000100");

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: " + line.c);
                }
                break;

            // Arithmetic
            case "addcc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    // if (Util.isLocAdd(getRd(line, true))) {
                    //     rd = Util.pad("", 5);
                    // }

                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += ("010000");

                    // rs1
                    instruction += rs1;

                    // Add two registers
                    if (Util.isRegister(getRs2(line, true))) {
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        // Add a register and a constant
                        instruction += "1";
                        instruction += handleNumber(getRs2(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: addcc requires 3 arguments");
                }
                break;
            case "andcc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "010001";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: andcc requires 3 arguments");
                }
                break;
            case "orcc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "010010";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: orcc requires 3 arguments");
                }
                break;
            case "orncc":
                if (line.iArgs.length === 3) {

                    var rd = getRd(line);
                    var rs1 = getRs1(line);
                    var rs2 = getRs2(line);

                    // rd
                    instruction += rd;

                    // op
                    instruction += "010110";

                    // rs1
                    instruction += rs1;

                    if (!Util.isLocAdd(getRd(line, true))) {
                        // i
                        instruction += "0";
                        instruction += "00000000";
                        instruction += rs2;
                    } else {
                        instruction += "1";
                        instruction += bR(getRd(line, true), 13);
                    }
                } else {
                    throw new Error("Invalid syntax: orncc requires 3 arguments");
                }
                break;
            // Control
            case "call":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for call instruction."); }
                if (!parsed.addresses[line.iArgs[0]]) {
                    throw new Error("Subrutine " +line.iArgs[0] + " doesn't exist");
                }
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 30);
                break;
            case "jmpl":
                if (/^jmpl \%r[0-9]+\+[0-9]+\,\ ?\%r[0-9]+$/.test(line.c)) {
                    instruction += (("00000" + eval(line.iArgs[1].replace("%r", "")).toString(2)).slice(-5));
                    instruction += ("111000");
                    instruction += (("00000" + parseInt(line.iArgs[0].replace(/\%r|\+[0-9]+/g, "")).toString(2)).slice(-5));
                    instruction += ("1");
                    // simm13
                    instruction += (("0000000000000" + parseInt(line.iArgs[0].match(/\+([0-9]+)/)).toString(2)).slice(-13));
                }
                break;
            case "be":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for be instruction."); }
                instruction += "0";
                instruction += "0001";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
            case "bcs":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bcs instruction."); }
                instruction += "0";
                instruction += "0101";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
            case "bneg":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bneg instruction."); }
                instruction += "0";
                instruction += "0110";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
            case "bvs":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bneg instruction."); }
                instruction += "0";
                instruction += "0111";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
            case "ba":
                if (line.iArgs.length > 1) { throw new Error("Too many argumnets for bneg instruction."); }
                instruction += "0";
                instruction += "1000";
                instruction += "010";
                instruction += Util.pad(parsed.addresses[line.iArgs[0]].address.toString(2), 22);
                break;
        }
    }

    if (line.label && !line.instruction) {
        instruction = handleNumber(line.c, 32);
    }

    return instruction;
}

module.exports = compile;
<|endoftext|>


<commit_before>/*
 * Kuzzle, a backend software, self-hostable and ready to use
 * to power modern apps
 *
 * Copyright 2017 Kuzzle
 * mailto: support AT kuzzle.io
 * website: http://kuzzle.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const
  _ = require('lodash'),
  jwt = require('jsonwebtoken'),
  ms = require('ms'),
  Bluebird = require('bluebird'),
  Token = require('../security/token'),
  Repository = require('./repository'),
  { InternalError: KuzzleInternalError, UnauthorizedError } = require('kuzzle-common-objects').errors;

/**
 * @class TokenRepository
 * @extends Repository
 * @param {Kuzzle} kuzzle
 * @param {object} [opts]
 */
class TokenRepository extends Repository {
  constructor (kuzzle, opts = {}) {
    super(kuzzle);
    this.kuzzle = kuzzle;
    this.collection = 'token';
    this.ObjectConstructor = Token;
    if (opts.ttl !== undefined) {
      this.ttl = opts.ttl;
    }
  }

  init() {
    super.init({
      databaseEngine: null,
      // do not rely on the default value and explicitly
      // use Redis for this repository
      cacheEngine: this.kuzzle.services.list.internalCache
    });
  }

  /**
   * @param {Token} requestToken
   * @returns {Promise<Object>}
   */
  expire(requestToken) {
    return super.expireFromCache(requestToken)
      .then(() => super.delete(super.getCacheKey(requestToken.userId + '#' + requestToken._id)))
      .then(() => this.kuzzle.tokenManager.expire(requestToken));
  }

  /**
   * @param {User} user
   * @param {Request} request
   * @param {object} opts
   * @returns {*}
   */
  generateToken(user, request, opts) {
    const
      token = new Token(),
      options = opts || {};
    let
      expiresIn,
      encodedToken,
      error;

    if (!user || user._id === null) {
      error = new KuzzleInternalError('Unknown User : cannot generate token');
      return Bluebird.reject(error);
    }

    if (!request.context.connectionId) {
      error = new KuzzleInternalError('Unknown context : cannot generate token');
      return Bluebird.reject(error);
    }

    if (!options.algorithm) {
      options.algorithm = this.kuzzle.config.security.jwt.algorithm;
    }
    if (!options.expiresIn) {
      options.expiresIn = this.kuzzle.config.security.jwt.expiresIn;
    }

    expiresIn = parseTimespan(options.expiresIn);

    try {
      encodedToken = jwt.sign({_id: user._id}, this.kuzzle.config.security.jwt.secret, options);
    }
    catch (err) {
      error = new KuzzleInternalError('Error while generating token');
      error.details = err.message;
      error.stack = err.stack;
      return Bluebird.reject(error);
    }

    _.assignIn(token, {
      _id: encodedToken,
      userId: user._id,
      ttl: expiresIn,
      expiresAt: Date.now() + expiresIn
    });

    return this.persistToCache(token, {ttl: expiresIn / 1000})
      .then(() => {
        this.kuzzle.tokenManager.add(token, request.context);

        return this.persistToCache({
          _id: user._id + '#' + token._id,
          expiresAt: token.expiresAt
        }, expiresIn / 1000);
      })
      .then(() => token)
      .catch(err => {
        error = new KuzzleInternalError('Unable to generate token for unknown user');
        error.details = err.message;
        error.stack = err.stack;
        return Bluebird.reject(error);
      });
  }

  verifyToken(token) {
    let error;

    if (token === null) {
      return Bluebird.resolve(this.anonymous());
    }

    try {
      jwt.verify(token, this.kuzzle.config.security.jwt.secret);
    }
    catch (err) {
      if (err instanceof jwt.TokenExpiredError) {
        error = new UnauthorizedError('Token expired', 401);
        error.details = {
          subCode: error.subCodes.TokenExpired,
          expiredAt: err.expiredAt
        };
      }
      else if (err instanceof jwt.JsonWebTokenError) {
        error = new UnauthorizedError('Json Web Token Error', 401);
        error.details = {
          subCode: error.subCodes.JsonWebTokenError,
          description: err.message
        };
      }
      else {
        error = new KuzzleInternalError('Error verifying token');
        error.details = err;
      }

      return Bluebird.reject(error);
    }

    return this.load(token)
      .then(userToken => {
        if (userToken === null) {
          return Bluebird.reject(new UnauthorizedError('Invalid token', 401));
        }

        return userToken;
      })
      .catch(err => {
        if (err instanceof UnauthorizedError) {
          return Bluebird.reject(err);
        }

        error = new KuzzleInternalError('Unknown user');
        error.details = err;

        return Bluebird.reject(error);
      });
  }

  hydrate (userToken, data) {
    if (!_.isObject(data)) {
      return Bluebird.resolve(userToken);
    }

    _.assignIn(userToken, data);

    if (!userToken.userId || userToken.userId === undefined || userToken.userId === null) {
      return Bluebird.resolve(this.anonymous());
    }

    return Bluebird.resolve(userToken);
  }

  anonymous () {
    const token = new Token();

    token._id = null;
    token.userId = '-1';

    return token;
  }

  serializeToDatabase (token) {
    return this.serializeToCache (token);
  }

  /**
   * Deletes tokens affiliated to the provided user identifier
   *
   * @param {string} userId
   * @return {Promise}
   */
  deleteByUserId(userId) {
    const userKey = super.getCacheKey(userId + '#*');

    return this.cacheEngine.searchKeys(userKey)
      .then(keys => {
        /*
         Given the fact that user ids have no restriction,
         and that Redis pattern matching is lacking the
         kind of features we need to safeguard against
         matching unwanted keys,
         we need to prevent to accidentally remove tokens
         from other users.
         For instance, given these two users:
           foo
           foo#bar

         If we remove foo, "foo#bar"'s JWT will match the
         pattern "foo#*".

         This test is possible because '#' is not a valid
         JWT character
         */
        const jwts = keys
          .map(key => key.indexOf('#', userKey.length - 1) === -1 ? key.slice(userKey.length - 1) : null)
          .filter(key => key !== null);

        const promises = jwts.map(token => this.load(token).then(cacheToken => this.expire(cacheToken)));

        return Bluebird.all(promises);
      });
  }
}

module.exports = TokenRepository;

function parseTimespan(time) {
  if (typeof time === 'string') {
    const milliseconds = ms(time);

    if (typeof milliseconds === 'undefined') {
      return -1;
    }

    return milliseconds;
  }

  if (typeof time === 'number') {
    return time;
  }

  return -1;
}
<commit_msg>handle null tokens<commit_after>/*
 * Kuzzle, a backend software, self-hostable and ready to use
 * to power modern apps
 *
 * Copyright 2017 Kuzzle
 * mailto: support AT kuzzle.io
 * website: http://kuzzle.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

const
  _ = require('lodash'),
  jwt = require('jsonwebtoken'),
  ms = require('ms'),
  Bluebird = require('bluebird'),
  Token = require('../security/token'),
  Repository = require('./repository'),
  { InternalError: KuzzleInternalError, UnauthorizedError } = require('kuzzle-common-objects').errors;

/**
 * @class TokenRepository
 * @extends Repository
 * @param {Kuzzle} kuzzle
 * @param {object} [opts]
 */
class TokenRepository extends Repository {
  constructor (kuzzle, opts = {}) {
    super(kuzzle);
    this.kuzzle = kuzzle;
    this.collection = 'token';
    this.ObjectConstructor = Token;
    if (opts.ttl !== undefined) {
      this.ttl = opts.ttl;
    }
  }

  init() {
    super.init({
      databaseEngine: null,
      // do not rely on the default value and explicitly
      // use Redis for this repository
      cacheEngine: this.kuzzle.services.list.internalCache
    });
  }

  /**
   * @param {Token} requestToken
   * @returns {Promise<Object>}
   */
  expire(requestToken) {
    return super.expireFromCache(requestToken)
      .then(() => super.delete(super.getCacheKey(requestToken.userId + '#' + requestToken._id)))
      .then(() => this.kuzzle.tokenManager.expire(requestToken));
  }

  /**
   * @param {User} user
   * @param {Request} request
   * @param {object} opts
   * @returns {*}
   */
  generateToken(user, request, opts) {
    const
      token = new Token(),
      options = opts || {};
    let
      expiresIn,
      encodedToken,
      error;

    if (!user || user._id === null) {
      error = new KuzzleInternalError('Unknown User : cannot generate token');
      return Bluebird.reject(error);
    }

    if (!request.context.connectionId) {
      error = new KuzzleInternalError('Unknown context : cannot generate token');
      return Bluebird.reject(error);
    }

    if (!options.algorithm) {
      options.algorithm = this.kuzzle.config.security.jwt.algorithm;
    }
    if (!options.expiresIn) {
      options.expiresIn = this.kuzzle.config.security.jwt.expiresIn;
    }

    expiresIn = parseTimespan(options.expiresIn);

    try {
      encodedToken = jwt.sign({_id: user._id}, this.kuzzle.config.security.jwt.secret, options);
    }
    catch (err) {
      error = new KuzzleInternalError('Error while generating token');
      error.details = err.message;
      error.stack = err.stack;
      return Bluebird.reject(error);
    }

    _.assignIn(token, {
      _id: encodedToken,
      userId: user._id,
      ttl: expiresIn,
      expiresAt: Date.now() + expiresIn
    });

    return this.persistToCache(token, {ttl: expiresIn / 1000})
      .then(() => {
        this.kuzzle.tokenManager.add(token, request.context);

        return this.persistToCache({
          _id: user._id + '#' + token._id,
          expiresAt: token.expiresAt
        }, expiresIn / 1000);
      })
      .then(() => token)
      .catch(err => {
        error = new KuzzleInternalError('Unable to generate token for unknown user');
        error.details = err.message;
        error.stack = err.stack;
        return Bluebird.reject(error);
      });
  }

  verifyToken(token) {
    let error;

    if (token === null) {
      return Bluebird.resolve(this.anonymous());
    }

    try {
      jwt.verify(token, this.kuzzle.config.security.jwt.secret);
    }
    catch (err) {
      if (err instanceof jwt.TokenExpiredError) {
        error = new UnauthorizedError('Token expired', 401);
        error.details = {
          subCode: error.subCodes.TokenExpired,
          expiredAt: err.expiredAt
        };
      }
      else if (err instanceof jwt.JsonWebTokenError) {
        error = new UnauthorizedError('Json Web Token Error', 401);
        error.details = {
          subCode: error.subCodes.JsonWebTokenError,
          description: err.message
        };
      }
      else {
        error = new KuzzleInternalError('Error verifying token');
        error.details = err;
      }

      return Bluebird.reject(error);
    }

    return this.load(token)
      .then(userToken => {
        if (userToken === null) {
          return Bluebird.reject(new UnauthorizedError('Invalid token', 401));
        }

        return userToken;
      })
      .catch(err => {
        if (err instanceof UnauthorizedError) {
          return Bluebird.reject(err);
        }

        error = new KuzzleInternalError('Unknown user');
        error.details = err;

        return Bluebird.reject(error);
      });
  }

  hydrate (userToken, data) {
    if (!_.isObject(data)) {
      return Bluebird.resolve(userToken);
    }

    _.assignIn(userToken, data);

    if (!userToken.userId || userToken.userId === undefined || userToken.userId === null) {
      return Bluebird.resolve(this.anonymous());
    }

    return Bluebird.resolve(userToken);
  }

  anonymous () {
    const token = new Token();

    token._id = null;
    token.userId = '-1';

    return token;
  }

  serializeToDatabase (token) {
    return this.serializeToCache (token);
  }

  /**
   * Deletes tokens affiliated to the provided user identifier
   *
   * @param {string} userId
   * @return {Promise}
   */
  deleteByUserId(userId) {
    const userKey = super.getCacheKey(userId + '#*');

    return this.cacheEngine.searchKeys(userKey)
      .then(keys => {
        /*
         Given the fact that user ids have no restriction,
         and that Redis pattern matching is lacking the
         kind of features we need to safeguard against
         matching unwanted keys,
         we need to prevent to accidentally remove tokens
         from other users.
         For instance, given these two users:
           foo
           foo#bar

         If we remove foo, "foo#bar"'s JWT will match the
         pattern "foo#*".

         This test is possible because '#' is not a valid
         JWT character
         */
        const jwts = keys
          .map(key => key.indexOf('#', userKey.length - 1) === -1 ? key.slice(userKey.length - 1) : null)
          .filter(key => key !== null);

        const promises = jwts.map(token => this.load(token).then(cacheToken => {
          if (cacheToken !== null) {
            return this.expire(cacheToken);
          }

          return null;
        }));

        return Bluebird.all(promises);
      });
  }
}

module.exports = TokenRepository;

function parseTimespan(time) {
  if (typeof time === 'string') {
    const milliseconds = ms(time);

    if (typeof milliseconds === 'undefined') {
      return -1;
    }

    return milliseconds;
  }

  if (typeof time === 'number') {
    return time;
  }

  return -1;
}
<|endoftext|>


<commit_before>import { returnTime, updateCurrentPhraseScroll } from 'js/utils';

/**
 * KeyboardController
 * @export
 * @class KeyboardController
 */
export default class KeyboardController {
  /**
   * Creates an instance of KeyboardController.
   *
   * @param {any} $scope
   * @param {any} $global
   * @param {any} $timeout
   * @param {TTSManager} TTSManager
   *
   * @memberOf RecentController
   */
  constructor($scope, $global, $timeout, EventManager, TTSManager) {
    this.$scope = $scope;
    this.$scope.global = $global;
    this.$timeout = $timeout;
    this.tts = TTSManager;
    this.event = EventManager;
    this.fastTypeTimer = null;
    this.suggestions = false;
    // Initilize variables for controller.

    // Call controllerInit
    this.controllerInit();
  }

  /**
   * Create or facilitate new functions for $scope or $global service.
   */
  controllerInit() {
    this.phraseIndex = 0;
    this.suggestionList = [];
  }

  /**
   * Shows the keyboard
   */
  showKeyboard() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      typeInput.focus();
      document.body.scrollTop = document.documentElement.scrollTop = 0;
    }
    this.showKeyboardFocused();
  }

  /**
   * Removes readonly from typeInput
   * Triggered when type input is
   * Walkaround for ios autocorrect
   */
  showKeyboardFocused() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      typeInput.removeAttribute('readonly');
      this.$timeout(() => {
        document.body.style.height = parseInt(window.innerHeight) + 'px';
        document.body.scrollTop = document.documentElement.scrollTop = 0;
        console.log("virtual keyboard opened!");
      }, 300);
    }
  }

  /**
   * Hides the keyboard
   */
  hideKeyboard() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      document.body.style.height = "100%";
    }
  }

  /**
   * Submits (handles) the current typeInput string content.
   */
  submitCurrentInput() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput.value) {
      let inputWord = {};
      inputWord.title = typeInput.value.toLowerCase();
      inputWord.slug = typeInput.value.toLowerCase().replace(" ", "-");
      let checkExist = this.checkWordInDB(inputWord.slug);
      inputWord.slugExist = !checkExist;

      if (inputWord.title.contains(" ") && !checkExist) {
        this.recognizeWord(inputWord.title);
      } else {
        inputWord.phraseIndex = this.phraseIndex++;
        this.$scope.global.currentPhrase.push(inputWord);
      }
      updateCurrentPhraseScroll();
      this.tts.speak(inputWord.title);
      let gs = this.$scope.global.gridSize;
      this.event.appWord(inputWord.title, gs[0], gs[1]);
      typeInput.value = "";
    }
  }

  /**
   * Handles the submission of the input via "enter" from the device
   */
  enterSubmit($event) {
    if ($event.keyCode === 13) {
      this.submitCurrentInput();
      this.suggestionList = [];
    } else {
      let typeInput = document.getElementById("typeInput");
      if (typeInput) {
        // If there is a timeout, clear it.
        if (this.fastTypeTimer) {
          this.$timeout.cancel(this.fastTypeTimer);
        }
        this.fastTypeTimer = this.$timeout(() => {
          if (typeInput.value.length > 1) {
            this.suggestWordsByInput(typeInput.value);
          } else {
            this.suggestionList = [];
            this.suggestions = false;
          }
        }, 300);
      }
    }
  }

  /**
   * Handles, creates the data to set suggestions by,
   * current keyboard input.
   */
  suggestWordsByInput(searchLetter) {
    this.suggestions = true;
    searchLetter = searchLetter.toLocaleLowerCase();
    searchLetter = searchLetter.replace(" ", "-");
    this.suggestionList = this.$scope.global.mainSlugArray.filter((word) => {
      return word.substring(0, searchLetter.length) == searchLetter;
    });
    if (this.suggestionList.length > 0) {
      this.suggestionList.sort(this.sortByLength);
    }
  }

  /**
   * Handles actions when a suggestion symbol is clicked
   */
  clickSuggestion(wordSlug) {
    let wordObj2Push = {};
    wordObj2Push.title = wordSlug.replace("-", " ");
    wordObj2Push.slug = wordSlug;
    wordObj2Push.phraseIndex = this.phraseIndex++;
    this.$scope.global.currentPhrase.push(wordObj2Push);

    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      document.getElementById("typeInput").value = "";
    }
    this.suggestionList = [];
    this.suggestions = false;
  }

  /**
   * Recognizes the string given by the current word package.
   */
  recognizeWord(word) {
    // this function can be better algorithmicly!
    let splittedUnrecognizedWord = word.split(" ");
    splittedUnrecognizedWord.forEach((wordPiece) => {
      if (wordPiece) {
        let wordObj2Push = {};
        wordObj2Push.title = wordPiece;
        wordObj2Push.slug = wordPiece;
        wordObj2Push.slugExist = !this.checkWordInDB(wordObj2Push.slug);
        wordObj2Push.phraseIndex = this.phraseIndex++;
        this.$scope.global.currentPhrase.push(wordObj2Push);
      }
    });
  }

  checkWordInDB(word) {
    return this.$scope.global.mainSlugArray.contains(word);
  }

  sortByLength(a, b) {
    if (a.length > b.length) {
      return 1;
    }
    if (a.length < b.length) {
      return -1;
    }
    return 0;
  }

}

// Service Dependency Injection
KeyboardController.$inject = ['$scope', '$global', '$timeout', 'EventManager', 'TTSManager'];
<commit_msg>function comments<commit_after>import { returnTime, updateCurrentPhraseScroll } from 'js/utils';

/**
 * KeyboardController
 * @export
 * @class KeyboardController
 */
export default class KeyboardController {
  /**
   * Creates an instance of KeyboardController.
   *
   * @param {any} $scope
   * @param {any} $global
   * @param {any} $timeout
   * @param {TTSManager} TTSManager
   *
   * @memberOf RecentController
   */
  constructor($scope, $global, $timeout, EventManager, TTSManager) {
    this.$scope = $scope;
    this.$scope.global = $global;
    this.$timeout = $timeout;
    this.tts = TTSManager;
    this.event = EventManager;
    this.fastTypeTimer = null;
    this.suggestions = false;
    // Initilize variables for controller.

    // Call controllerInit
    this.controllerInit();
  }

  /**
   * Create or facilitate new functions for $scope or $global service.
   */
  controllerInit() {
    this.phraseIndex = 0;
    this.suggestionList = [];
  }

  /**
   * Shows the keyboard
   */
  showKeyboard() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      typeInput.focus();
      document.body.scrollTop = document.documentElement.scrollTop = 0;
    }
    this.showKeyboardFocused();
  }

  /**
   * Removes readonly from typeInput
   * Triggered when type input is
   * Walkaround for ios autocorrect
   */
  showKeyboardFocused() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      typeInput.removeAttribute('readonly');
      this.$timeout(() => {
        document.body.style.height = parseInt(window.innerHeight) + 'px';
        document.body.scrollTop = document.documentElement.scrollTop = 0;
        console.log("virtual keyboard opened!");
      }, 300);
    }
  }

  /**
   * Hides the keyboard
   */
  hideKeyboard() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      document.body.style.height = "100%";
    }
  }

  /**
   * Submits (handles) the current typeInput string content.
   */
  submitCurrentInput() {
    let typeInput = document.getElementById("typeInput");
    if (typeInput.value) {
      let inputWord = {};
      inputWord.title = typeInput.value.toLowerCase();
      inputWord.slug = typeInput.value.toLowerCase().replace(" ", "-");
      let checkExist = this.checkWordInDB(inputWord.slug);
      inputWord.slugExist = !checkExist;

      if (inputWord.title.contains(" ") && !checkExist) {
        this.recognizeWord(inputWord.title);
      } else {
        inputWord.phraseIndex = this.phraseIndex++;
        this.$scope.global.currentPhrase.push(inputWord);
      }
      updateCurrentPhraseScroll();
      this.tts.speak(inputWord.title);
      let gs = this.$scope.global.gridSize;
      this.event.appWord(inputWord.title, gs[0], gs[1]);
      typeInput.value = "";
    }
  }

  /**
   * Handles the submission of the input via "enter" from the device
   */
  enterSubmit($event) {
    if ($event.keyCode === 13) {
      this.submitCurrentInput();
      this.suggestionList = [];
    } else {
      let typeInput = document.getElementById("typeInput");
      if (typeInput) {
        // If there is a timeout, clear it.
        if (this.fastTypeTimer) {
          this.$timeout.cancel(this.fastTypeTimer);
        }
        this.fastTypeTimer = this.$timeout(() => {
          if (typeInput.value.length > 1) {
            this.suggestWordsByInput(typeInput.value);
          } else {
            this.suggestionList = [];
            this.suggestions = false;
          }
        }, 300);
      }
    }
  }

  /**
   * Handles, creates the data to set suggestions by,
   * current keyboard input.
   */
  suggestWordsByInput(searchLetter) {
    this.suggestions = true;
    searchLetter = searchLetter.toLocaleLowerCase();
    searchLetter = searchLetter.replace(" ", "-");
    this.suggestionList = this.$scope.global.mainSlugArray.filter((word) => {
      return word.substring(0, searchLetter.length) == searchLetter;
    });
    if (this.suggestionList.length > 0) {
      this.suggestionList.sort(this.sortByLength);
    }
  }

  /**
   * Handles actions when a suggestion symbol is clicked
   */
  clickSuggestion(wordSlug) {
    let wordObj2Push = {};
    wordObj2Push.title = wordSlug.replace("-", " ");
    wordObj2Push.slug = wordSlug;
    wordObj2Push.phraseIndex = this.phraseIndex++;
    this.$scope.global.currentPhrase.push(wordObj2Push);

    let typeInput = document.getElementById("typeInput");
    if (typeInput) {
      document.getElementById("typeInput").value = "";
    }
    this.suggestionList = [];
    this.suggestions = false;
  }

  /**
   * Recognizes the string given by the current word package before pushing.
   * Then pushes the pieces indivicually.
   */
  recognizeWord(word) {
    // this function can be better algorithmicly!
    let splittedUnrecognizedWord = word.split(" ");
    splittedUnrecognizedWord.forEach((wordPiece) => {
      if (wordPiece) {
        let wordObj2Push = {};
        wordObj2Push.title = wordPiece;
        wordObj2Push.slug = wordPiece;
        wordObj2Push.slugExist = !this.checkWordInDB(wordObj2Push.slug);
        wordObj2Push.phraseIndex = this.phraseIndex++;
        this.$scope.global.currentPhrase.push(wordObj2Push);
      }
    });
  }

  /**
   * Checks if the given word in the mainSlugArray
   */
  checkWordInDB(word) {
    return this.$scope.global.mainSlugArray.contains(word);
  }

  /**
   * Comparission function for .sort() prototype.
   */
  sortByLength(a, b) {
    if (a.length > b.length) {
      return 1;
    }
    if (a.length < b.length) {
      return -1;
    }
    return 0;
  }

}

// Service Dependency Injection
KeyboardController.$inject = ['$scope', '$global', '$timeout', 'EventManager', 'TTSManager'];
<|endoftext|>


<commit_before>Config.proxyURL = document.location.protocol + '//' + document.location.host + '/proxy';

Config.wikiRepoUrl = document.location.protocol + '//' + document.location.host +
	(document.URL.include('swa/research') ?
		'/repository/webwerkstatt/swa/research' :
		'/repository/webwerkstatt');

Config.debugExtras = false;

Config.showFabrikWeatherWidgetExample = false;

Config.askBeforeQuit = true;

Config.modulesOnWorldLoad = Config.modulesOnWorldLoad.concat(["lively.Graffle", "lively.Undo", "lively.ide.AutoCompletion", "lively.ide.SyntaxHighlighting", 'lively.Scripting'])
Config.showNetworkExamples = true

if (!Config.isNewMorphic) {
	Config.modulesOnWorldLoad.push('lively.deprecated.Helper')
}

Config.testInRealWorld = true

Config.confirmNavigation = false;

Config.resizeScreenToWorldBounds = true;

Config.disableScriptCaching = true;

Config.silentFailOnWrapperClassNotFound = true;

Config.defaultDisplayTheme = 'hpi' // 'primitive', 'turquoise', 'hpi', 'lively'

Config.disableNoConsoleWarning = true;

Config.ignoreAdvice = false;

Config.loadUserConfig = true;
Config.ChromeSVGRenderingHotfix = true;
<commit_msg>Revert "Reverting "jens config (cherry picked from commit 00fd34abb17d7a70b4eff2784748beeff24611ab)""<commit_after>Config.proxyURL = document.location.protocol + '//' + document.location.host + '/proxy';

Config.wikiRepoUrl = document.location.protocol + '//' + document.location.host +
	(document.URL.include('swa/research') ?
		'/repository/webwerkstatt/swa/research' :
		'/repository/webwerkstatt');

Config.debugExtras = false;

Config.showFabrikWeatherWidgetExample = false;

Config.askBeforeQuit = true;

Config.modulesOnWorldLoad = Config.modulesOnWorldLoad.concat(["lively.Graffle", "lively.Undo", "lively.ide.AutoCompletion", "lively.ide.SyntaxHighlighting", 'lively.Scripting'])
Config.showNetworkExamples = true

if (!Config.isNewMorphic) {
	Config.modulesOnWorldLoad.push('lively.deprecated.Helper')
}

Config.testInRealWorld = true

Config.confirmNavigation = false;

Config.resizeScreenToWorldBounds = true;

Config.disableScriptCaching = true;

Config.silentFailOnWrapperClassNotFound = true;

Config.defaultDisplayTheme = 'hpi' // 'primitive', 'turquoise', 'hpi', 'lively'

Config.disableNoConsoleWarning = true;

Config.ignoreAdvice = false;

Config.loadUserConfig = true;
Config.ChromeSVGRenderingHotfix = true;

Config.modulePaths.push('apps')

<|endoftext|>


<commit_before>const cp = require('child_process');
const fs = require('fs');
const path = require('path');

const args = require('minimist')(process.argv.slice(2), {
  boolean: ['default'],
  string: ['jUnitDir']
});

const BASE = path.resolve(__dirname, '../..');
const DISABLED_TESTS = require('./node-disabled-tests.json');
const NODE_DIR = path.resolve(BASE, 'third_party', 'electron_node');
const JUNIT_DIR = args.jUnitDir ? path.resolve(args.jUnitDir) : null;
const TAP_FILE_NAME = 'test.tap';

const utils = require('./lib/utils');

if (!process.mainModule) {
  throw new Error('Must call the node spec runner directly');
}

const defaultOptions = [
  'tools/test.py',
  '-p',
  'tap',
  '--logfile',
  TAP_FILE_NAME,
  '--mode=debug',
  'default',
  `--skip-tests=${DISABLED_TESTS.join(',')}`,
  '--shell',
  utils.getAbsoluteElectronExec(),
  '-J'
];

const getCustomOptions = () => {
  let customOptions = ['tools/test.py'];

  // Add all custom arguments.
  const extra = process.argv.slice(2);
  if (extra) {
    customOptions = customOptions.concat(extra);
  }

  // We need this unilaterally or Node.js will try
  // to run from out/Release/node.
  customOptions = customOptions.concat([
    '--shell',
    utils.getAbsoluteElectronExec()
  ]);

  return customOptions;
};

async function main () {
  const options = args.default ? defaultOptions : getCustomOptions();

  const testChild = cp.spawn('python', options, {
    env: {
      ...process.env,
      ELECTRON_RUN_AS_NODE: 'true',
      ELECTRON_EAGER_ASAR_HOOK_FOR_TESTING: 'true'
    },
    cwd: NODE_DIR,
    stdio: 'inherit'
  });
  testChild.on('exit', (testCode) => {
    if (JUNIT_DIR) {
      fs.mkdirSync(JUNIT_DIR);
      const converterStream = require('tap-xunit')();
      fs.createReadStream(
        path.resolve(NODE_DIR, TAP_FILE_NAME)
      ).pipe(converterStream).pipe(
        fs.createWriteStream(path.resolve(JUNIT_DIR, 'nodejs.xml'))
      ).on('close', () => {
        process.exit(testCode);
      });
    }
  });
}

main().catch((err) => {
  console.error('An unhandled error occurred in the node spec runner', err);
  process.exit(1);
});
<commit_msg>test: run node specs with py3 (#34154)<commit_after>const cp = require('child_process');
const fs = require('fs');
const path = require('path');

const args = require('minimist')(process.argv.slice(2), {
  boolean: ['default'],
  string: ['jUnitDir']
});

const BASE = path.resolve(__dirname, '../..');
const DISABLED_TESTS = require('./node-disabled-tests.json');
const NODE_DIR = path.resolve(BASE, 'third_party', 'electron_node');
const JUNIT_DIR = args.jUnitDir ? path.resolve(args.jUnitDir) : null;
const TAP_FILE_NAME = 'test.tap';

const utils = require('./lib/utils');

if (!process.mainModule) {
  throw new Error('Must call the node spec runner directly');
}

const defaultOptions = [
  'tools/test.py',
  '-p',
  'tap',
  '--logfile',
  TAP_FILE_NAME,
  '--mode=debug',
  'default',
  `--skip-tests=${DISABLED_TESTS.join(',')}`,
  '--shell',
  utils.getAbsoluteElectronExec(),
  '-J'
];

const getCustomOptions = () => {
  let customOptions = ['tools/test.py'];

  // Add all custom arguments.
  const extra = process.argv.slice(2);
  if (extra) {
    customOptions = customOptions.concat(extra);
  }

  // We need this unilaterally or Node.js will try
  // to run from out/Release/node.
  customOptions = customOptions.concat([
    '--shell',
    utils.getAbsoluteElectronExec()
  ]);

  return customOptions;
};

async function main () {
  const options = args.default ? defaultOptions : getCustomOptions();

  const testChild = cp.spawn('python3', options, {
    env: {
      ...process.env,
      ELECTRON_RUN_AS_NODE: 'true',
      ELECTRON_EAGER_ASAR_HOOK_FOR_TESTING: 'true'
    },
    cwd: NODE_DIR,
    stdio: 'inherit'
  });
  testChild.on('exit', (testCode) => {
    if (JUNIT_DIR) {
      fs.mkdirSync(JUNIT_DIR);
      const converterStream = require('tap-xunit')();
      fs.createReadStream(
        path.resolve(NODE_DIR, TAP_FILE_NAME)
      ).pipe(converterStream).pipe(
        fs.createWriteStream(path.resolve(JUNIT_DIR, 'nodejs.xml'))
      ).on('close', () => {
        process.exit(testCode);
      });
    }
  });
}

main().catch((err) => {
  console.error('An unhandled error occurred in the node spec runner', err);
  process.exit(1);
});
<|endoftext|>


<commit_before>(function (exports) {
  'use strict';
  /*jshint node:true */

  var request, fs, hub, scrape, writer, Writer, ROOT_URL, types, logger, uuid, knownEntities, Sync;

  ROOT_URL = process.env.ROOT_URL;
  request = require('request');
  hub = require('node-pubsub');
  fs = require('fs');

  console.log('Beginning scrape of', ROOT_URL);

  // Generate a UUID
  uuid = function uuid(a){
    //Function from https://gist.github.com/982883 (@jed)
    return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,uuid);
  };

  // Semaphore from https://gist.github.com/1296828
  Sync = function Sync(syncCount, callback, preventInstantCallbackExecution) {
      this.syncCount = syncCount;
      this.callback = callback;
      if(preventInstantCallbackExecution === false && this.syncCount === 0) {
        this.executeCallback();
      }
    };
    Sync.prototype.decrement = function() {
      --this.syncCount;
      if(this.syncCount === 0) {
        this.executeCallback();
      }
    };
    Sync.prototype.increment = function() {
      ++this.syncCount;
    };
    Sync.prototype.executeCallback = function() {
      if (typeof this.callback === "function") this.callback();
    };

  // Writer Singleton
  Writer = (function (){
    var instantiated, init;

    init = function () {

      var writer = {}, fileName;

      fileName = "/tcgascrape"+Date.now()+".nt";

      writer.stream = fs.createWriteStream(process.cwd()+fileName);

      writer.listen = function (msg) {
        var triples = msg.triples;
        triples = triples.split(" . ").join(" .\n");
        writer.stream.write(triples);
      };

      writer.close = function () {
        writer.stream.end();
      };

      return writer;

    };

    return {
      getInstance : function () {
        if (!instantiated) instantiated = init();
        return instantiated;
      }
    };
  })();

  types = {
    9 : "disease-study",
    10 : "center-type",
    11 : "center-domain",
    12 : "platform",
    13 : "data-type",
    14 : "archive",
    archive : "archive",
    15 : "file",
    file : "file"
  };

  knownEntities = {};

  scrape = function (options) {
    var opts, target, parent, callback, start, callCallback;

    opts = options || {};
    target = opts.target || ROOT_URL;
    parent = opts.parent || {};

    callCallback = function () {
      if (callback && typeof callback === 'function') callback();
    };
    callback = opts.callback;

    request(target, function (error, response, body) {

      if (error || response.statusCode !== 200) {
        console.log("Failed to get", target);
        if (callback && typeof callback === 'function') callback();
        else return;
      }

      else {

        var pre, rows, children = [], tcga, literal;

        tcga = function (name) { return "<http://purl.org/tcga/core#"+name+">"; };
        literal = function (value) { return '"'+value+'"'; };
        pre = body.match(/<pre>([\s\S]*)<\/pre>/)[1];
        rows = pre.match(/<a[^?P]*?<\/a>[\s\S]+?\d{2}-\w{3}-\d{4}/g);

        if (rows) rows.forEach(function (row) {

          var name, id, url, type, tripleString, lastModified, subject, scrapeChildren = true;

          name = row.match(/>(.*)</)[1];
          id = uuid();
          url = target + row.match(/href="(.*)"/)[1];
          type = types[target.split('/').length];
          lastModified = (new Date(row.match(/\d{2}-\w{3}-\d{4}/)[0])).toISOString().slice(0,10);
          tripleString = "";

          if (process.env.TESTING && target.split("/").length >= 10) {
            scrapeChildren = false;
          }

          // Things with extensions are files (e.g. reallylong_name.tiff)
          // TODO Use MIME types to determine files.
          if (name.match(/^.*\.[^\/]+$/)) {
            type = types.file;
            scrapeChildren = false;
          }

          // TODO when should this NOT be done (e.g. files)
          if (type !== types.file) name = name.slice(0,-1); // Remove the trailing "/"

          // If a file ends in .tar.gz or .tar.gz.md5, type it as an archive
          if (type === types.file && name.match(/\.tar\.gz($|\.md5$)/)) {
            type = types.archive;
          }

          if (type !== types.file && type !== types.archive) {
            if (!knownEntities[name]) knownEntities[name] = id;
            else id = knownEntities[name];
          }

          subject = tcga(id);
          tripleString = [
            subject, "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>",  tcga(type), ".",
            subject, "<http://www.w3.org/2000/01/rdf-schema#label>", literal(name), ".",
            subject, tcga("url"), literal(url), "."
          ];

          if (type === types.file) {
            var ancestor;
            Object.keys(parent).forEach(function (ancestor) {
              tripleString.push(subject, tcga(ancestor), parent[ancestor], ".");
            });
          }

          hub.publish('/triples', [{
            triples : tripleString.join(" ") + "\n",
            type : type,
            name : name
          }]);

          if (scrapeChildren){
            parent[type] = subject;
            children.push({target:url, parent:JSON.parse(JSON.stringify(parent))});
          }

        });

        //hub.publish('/triples', [ { triples : children } ]);

        if (children.length > 0) {
          var counter = new Sync(children.length, callback);
          var nextChild = function nextChild(children){
            var child = children.pop();
            if (child){
              child.callback = function(){
                counter.decrement();
                nextChild(children);
              };
              scrape(child);
            }
          };
          nextChild(children);
        }
        else callCallback();

      }

    });
  };

  //logger = hub.subscribe('/triples', function ( msg ) {
  //  console.log(msg.triples);
  //});

  writer = Writer.getInstance();

  hub.subscribe('/triples', writer.listen);

  scrape({
    target : ROOT_URL,
    callback : function () { writer.close(); console.log("Scrape finished"); }
  });

})( exports );
<commit_msg>Made regex's more resilient.<commit_after>(function (exports) {
  'use strict';
  /*jshint node:true */

  var request, fs, hub, scrape, writer, Writer, ROOT_URL, types, logger, uuid, knownEntities, Sync;

  ROOT_URL = process.env.ROOT_URL;
  request = require('request');
  hub = require('node-pubsub');
  fs = require('fs');

  console.log('Beginning scrape of', ROOT_URL);

  // Generate a UUID
  uuid = function uuid(a){
    //Function from https://gist.github.com/982883 (@jed)
    return a?(a^Math.random()*16>>a/4).toString(16):([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,uuid);
  };

  // Semaphore from https://gist.github.com/1296828
  Sync = function Sync(syncCount, callback, preventInstantCallbackExecution) {
      this.syncCount = syncCount;
      this.callback = callback;
      if(preventInstantCallbackExecution === false && this.syncCount === 0) {
        this.executeCallback();
      }
    };
    Sync.prototype.decrement = function() {
      --this.syncCount;
      if(this.syncCount === 0) {
        this.executeCallback();
      }
    };
    Sync.prototype.increment = function() {
      ++this.syncCount;
    };
    Sync.prototype.executeCallback = function() {
      if (typeof this.callback === "function") this.callback();
    };

  // Writer Singleton
  Writer = (function (){
    var instantiated, init;

    init = function () {

      var writer = {}, fileName;

      fileName = "/tcgascrape"+Date.now()+".nt";

      writer.stream = fs.createWriteStream(process.cwd()+fileName);

      writer.listen = function (msg) {
        var triples = msg.triples;
        triples = triples.split(" . ").join(" .\n");
        writer.stream.write(triples);
      };

      writer.close = function () {
        writer.stream.end();
      };

      return writer;

    };

    return {
      getInstance : function () {
        if (!instantiated) instantiated = init();
        return instantiated;
      }
    };
  })();

  types = {
    9 : "disease-study",
    10 : "center-type",
    11 : "center-domain",
    12 : "platform",
    13 : "data-type",
    14 : "archive",
    archive : "archive",
    15 : "file",
    file : "file"
  };

  knownEntities = {};

  scrape = function (options) {
    var opts, target, parent, callback, start, callCallback;

    opts = options || {};
    target = opts.target || ROOT_URL;
    parent = opts.parent || {};

    callCallback = function () {
      if (callback && typeof callback === 'function') callback();
    };
    callback = opts.callback;

    request(target, function (error, response, body) {

      if (error || response.statusCode !== 200) {
        console.log("Failed to get", target);
        if (callback && typeof callback === 'function') callback();
        else return;
      }

      else {

        var pre, rows, children = [], tcga, literal;

        tcga = function (name) { return "<http://purl.org/tcga/core#"+name+">"; };
        literal = function (value) { return '"'+value+'"'; };
        pre = body.match(/<pre>([\s\S]*)<\/pre>/);
        if (!pre) return callCallback(); else pre = pre[1];
        rows = pre.match(/<a[^?P]*?<\/a>[\s\S]+?\d{2}-\w{3}-\d{4}/g);

        if (rows) rows.forEach(function (row) {

          var name, id, url, type, tripleString, lastModified, subject, scrapeChildren = true, level;

          name = row.match(/>([\s\S]*)</);
          if (!name) console.log(row); else name = name[1];
          id = uuid();
          url = target + row.match(/href="(.*)"/)[1];
          level = target.split('/').length;
          type = types[level];
          lastModified = (new Date(row.match(/\d{2}-\w{3}-\d{4}/)[0])).toISOString().slice(0,10);
          tripleString = "";

          if ((process.env.TESTING && level >= 10) || level >= 15) {
            scrapeChildren = false;
          }

          // Things with extensions are files (e.g. reallylong_name.tiff)
          // TODO Use MIME types to determine files.
          if (name.match(/^.*\.[^\/]+$/)) {
            type = types.file;
            scrapeChildren = false;
          }

          // TODO when should this NOT be done (e.g. files)
          if (type !== types.file) name = name.slice(0,-1); // Remove the trailing "/"

          // If a file ends in .tar.gz or .tar.gz.md5, type it as an archive
          if (type === types.file && name.match(/\.tar\.gz($|\.md5$)/)) {
            type = types.archive;
          }

          if (type !== types.file && type !== types.archive) {
            if (!knownEntities[name]) knownEntities[name] = id;
            else id = knownEntities[name];
          }

          subject = tcga(id);
          tripleString = [
            subject, "<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>",  tcga(type), ".",
            subject, "<http://www.w3.org/2000/01/rdf-schema#label>", literal(name), ".",
            subject, tcga("url"), literal(url), "."
          ];

          if (type === types.file) {
            var ancestor;
            Object.keys(parent).forEach(function (ancestor) {
              tripleString.push(subject, tcga(ancestor), parent[ancestor], ".");
            });
          }

          hub.publish('/triples', [{
            triples : tripleString.join(" ") + "\n",
            type : type,
            name : name
          }]);

          if (scrapeChildren){
            parent[type] = subject;
            children.push({target:url, parent:JSON.parse(JSON.stringify(parent))});
          }

        });

        //hub.publish('/triples', [ { triples : children } ]);

        if (children.length > 0) {
          var counter = new Sync(children.length, callback);
          var nextChild = function nextChild(children){
            var child = children.pop();
            if (child){
              child.callback = function(){
                counter.decrement();
                nextChild(children);
              };
              scrape(child);
            }
          };
          nextChild(children);
        }
        else callCallback();

      }

    });
  };

  //logger = hub.subscribe('/triples', function ( msg ) {
  //  console.log(msg.triples);
  //});

  writer = Writer.getInstance();

  hub.subscribe('/triples', writer.listen);

  scrape({
    target : ROOT_URL,
    callback : function () { writer.close(); console.log("Scrape finished"); }
  });

})( exports );
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

var InspectorFrontendAPI = {
    _pendingCommands: [],

    setAttachedWindow: function(side)
    {
    },

    setDockSide: function(side)
    {
        if (WebInspector.dockController)
            WebInspector.dockController.setDockSide(side);
    },

    showConsole: function()
    {
        WebInspector.showPanel("console");
    },

    showMainResourceForFrame: function(frameId)
    {
        // FIXME: Implement this to show the source code for the main resource of a given frame.
    },

    showResources: function()
    {
        WebInspector.showPanel("resources");
    },

    setDockingUnavailable: function(unavailable)
    {
        WebInspector.setDockingUnavailable(unavailable);
    },

    enterInspectElementMode: function()
    {
        WebInspector.showPanel("elements");

        if (WebInspector.inspectElementModeController)
            WebInspector.inspectElementModeController.toggleSearch();
    },

    fileSystemsLoaded: function(fileSystems)
    {
        WebInspector.isolatedFileSystemDispatcher.fileSystemsLoaded(fileSystems);
    },

    fileSystemRemoved: function(fileSystemPath)
    {
        WebInspector.isolatedFileSystemDispatcher.fileSystemRemoved(fileSystemPath);
    },

    fileSystemAdded: function(errorMessage, fileSystem)
    {
        WebInspector.isolatedFileSystemDispatcher.fileSystemAdded(errorMessage, fileSystem);
    },

    indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.indexingTotalWorkCalculated(requestId, totalWork);
    },

    indexingWorked: function(requestId, fileSystemPath, worked)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.indexingWorked(requestId, worked);
    },

    indexingDone: function(requestId, fileSystemPath)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.indexingDone(requestId);
    },

    searchCompleted: function(requestId, fileSystemPath, files)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.searchCompleted(requestId, files);
    },

    savedURL: function(url)
    {
        WebInspector.fileManager.savedURL(url);
    },

    appendedToURL: function(url)
    {
        WebInspector.fileManager.appendedToURL(url);
    },

    setToolbarColors: function(backgroundColor, color)
    {
        WebInspector.setToolbarColors(backgroundColor, color);
    },

    evaluateForTest: function(callId, script)
    {
        WebInspector.evaluateForTestInFrontend(callId, script);
    },

    dispatch: function(signature)
    {
        if (InspectorFrontendAPI._isLoaded) {
            var methodName = signature.shift();
            return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
        }
        InspectorFrontendAPI._pendingCommands.push(signature);
    },

    dispatchQueryParameters: function()
    {
        if ("dispatch" in WebInspector.queryParamsObject)
            InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"])));
    },

    /**
     * @param {string} url
     */
    loadTimelineFromURL: function(url)
    {
        /** @type {WebInspector.TimelinePanel} */ (WebInspector.showPanel("timeline")).loadFromURL(url);
    },

    loadCompleted: function()
    {
        InspectorFrontendAPI._isLoaded = true;
        for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
            InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
        InspectorFrontendAPI._pendingCommands = [];
        if (window.opener)
            window.opener.postMessage(["loadCompleted"], "*");
    },

    contextMenuItemSelected: function(id)
    {
        WebInspector.contextMenuItemSelected(id);
    },

    contextMenuCleared: function()
    {
        WebInspector.contextMenuCleared();
    },

    dispatchMessageAsync: function(messageObject)
    {
        WebInspector.dispatch(messageObject);
    },

    dispatchMessage: function(messageObject)
    {
        InspectorBackend.dispatch(messageObject);
    }
}

if (window.opener && window.dispatchStandaloneTestRunnerMessages) {
    function onMessageFromOpener(event)
    {
        if (event.source === window.opener)
            InspectorFrontendAPI.dispatch(event.data);
    }
    window.addEventListener("message", onMessageFromOpener, true);
}
<commit_msg>Add a inspectUISourceCode method to the InspectorFrontendAPI<commit_after>/*
 * Copyright (C) 2011 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

var InspectorFrontendAPI = {
    _pendingCommands: [],

    setAttachedWindow: function(side)
    {
    },

    setDockSide: function(side)
    {
        if (WebInspector.dockController)
            WebInspector.dockController.setDockSide(side);
    },

    showConsole: function()
    {
        WebInspector.showPanel("console");
    },

    showMainResourceForFrame: function(frameId)
    {
        // FIXME: Implement this to show the source code for the main resource of a given frame.
    },

    showResources: function()
    {
        WebInspector.showPanel("resources");
    },

    setDockingUnavailable: function(unavailable)
    {
        WebInspector.setDockingUnavailable(unavailable);
    },

    enterInspectElementMode: function()
    {
        WebInspector.showPanel("elements");

        if (WebInspector.inspectElementModeController)
            WebInspector.inspectElementModeController.toggleSearch();
    },

    /**
     * Focus on a particular line in the specified resource.
     * @param {string} url The url to the resource.
     * @param {number} lineNumber The line number to focus on.
     * @param {number} columnNumber The column number to focus on.
     */
    revealSourceLine: function(url, lineNumber, columnNumber)
    {
        var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
        if (uiSourceCode) {
            WebInspector.showPanel("scripts").showUISourceCode(uiSourceCode, lineNumber, columnNumber);
            return;
        }

        /**
         * @param {WebInspector.Event} event
         */
        function listener(event)
        {
            var uiSourceCode = /** @type {WebInspector.UISourceCode} */ (event.data);
            if (uiSourceCode.url === url) {
                WebInspector.showPanel("scripts").showUISourceCode(uiSourceCode, lineNumber, columnNumber);
                WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, listener);
            }
        }

        WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, listener);
    },

    fileSystemsLoaded: function(fileSystems)
    {
        WebInspector.isolatedFileSystemDispatcher.fileSystemsLoaded(fileSystems);
    },

    fileSystemRemoved: function(fileSystemPath)
    {
        WebInspector.isolatedFileSystemDispatcher.fileSystemRemoved(fileSystemPath);
    },

    fileSystemAdded: function(errorMessage, fileSystem)
    {
        WebInspector.isolatedFileSystemDispatcher.fileSystemAdded(errorMessage, fileSystem);
    },

    indexingTotalWorkCalculated: function(requestId, fileSystemPath, totalWork)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.indexingTotalWorkCalculated(requestId, totalWork);
    },

    indexingWorked: function(requestId, fileSystemPath, worked)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.indexingWorked(requestId, worked);
    },

    indexingDone: function(requestId, fileSystemPath)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.indexingDone(requestId);
    },

    searchCompleted: function(requestId, fileSystemPath, files)
    {
        var projectDelegate = WebInspector.fileSystemWorkspaceProvider.delegate(fileSystemPath);
        projectDelegate.searchCompleted(requestId, files);
    },

    savedURL: function(url)
    {
        WebInspector.fileManager.savedURL(url);
    },

    appendedToURL: function(url)
    {
        WebInspector.fileManager.appendedToURL(url);
    },

    setToolbarColors: function(backgroundColor, color)
    {
        WebInspector.setToolbarColors(backgroundColor, color);
    },

    evaluateForTest: function(callId, script)
    {
        WebInspector.evaluateForTestInFrontend(callId, script);
    },

    dispatch: function(signature)
    {
        if (InspectorFrontendAPI._isLoaded) {
            var methodName = signature.shift();
            return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
        }
        InspectorFrontendAPI._pendingCommands.push(signature);
    },

    dispatchQueryParameters: function()
    {
        if ("dispatch" in WebInspector.queryParamsObject)
            InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"])));
    },

    /**
     * @param {string} url
     */
    loadTimelineFromURL: function(url)
    {
        /** @type {WebInspector.TimelinePanel} */ (WebInspector.showPanel("timeline")).loadFromURL(url);
    },

    loadCompleted: function()
    {
        InspectorFrontendAPI._isLoaded = true;
        for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
            InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
        InspectorFrontendAPI._pendingCommands = [];
        if (window.opener)
            window.opener.postMessage(["loadCompleted"], "*");
    },

    contextMenuItemSelected: function(id)
    {
        WebInspector.contextMenuItemSelected(id);
    },

    contextMenuCleared: function()
    {
        WebInspector.contextMenuCleared();
    },

    dispatchMessageAsync: function(messageObject)
    {
        WebInspector.dispatch(messageObject);
    },

    dispatchMessage: function(messageObject)
    {
        InspectorBackend.dispatch(messageObject);
    }
}

if (window.opener && window.dispatchStandaloneTestRunnerMessages) {
    function onMessageFromOpener(event)
    {
        if (event.source === window.opener)
            InspectorFrontendAPI.dispatch(event.data);
    }
    window.addEventListener("message", onMessageFromOpener, true);
}
<|endoftext|>


<commit_before>import styled, { css } from 'styled-components';

import { focusStyle, inputStyle } from '../utils';

const placeholderColor = css`
  color: ${props => props.theme.global.placeholder.color};
`;

const sizeStyle = (props) => {
  const data = props.theme.text[props.size];
  return css`
    font-size: ${data.size};
    line-height: ${data.height};
  `;
};

const plainStyle = css`
  border: none;
  width: 100%;
`;

const StyledTextInput = styled.input`
  ${inputStyle}

  ${props => props.size && sizeStyle(props)}
  ${props => props.plain && plainStyle}

  &::-webkit-input-placeholder {
    ${placeholderColor}
  }

  &::-moz-placeholder {
    ${placeholderColor}
  }

  &:-ms-input-placeholder {
    ${placeholderColor}
  }

  &::-moz-focus-inner {
    border: none;
    outline: none;
  }

  &:focus {
    ${props => !props.plain && focusStyle}
  }
`;

export const StyledTextInputContainer = styled.div`
  ${props => props.plain && 'width: 100%'}
`;

const selectedStyle = css`
  background-color: ${
    props => props.theme.global.selected.backgroundColor
  };
  color: ${props => props.theme.global.selected.textColor};
`;

export const StyledSuggestion = styled.div`
  ${props => props.selected && selectedStyle}
`;

export const StyledSuggestions = styled.ol`
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  margin: 0;
  padding: 0;
  list-style-type: none;
`;

export default StyledTextInput.extend`
  ${props => props.theme.textInput && props.theme.textInput.extend}
`;
<commit_msg>Added webkit appereance none to fix input in safari.<commit_after>import styled, { css } from 'styled-components';

import { focusStyle, inputStyle } from '../utils';

const placeholderColor = css`
  color: ${props => props.theme.global.placeholder.color};
`;

const sizeStyle = (props) => {
  const data = props.theme.text[props.size];
  return css`
    font-size: ${data.size};
    line-height: ${data.height};
  `;
};

const plainStyle = css`
  border: none;
  width: 100%;
  -webkit-appearance: none;
`;

const StyledTextInput = styled.input`
  ${inputStyle}

  ${props => props.size && sizeStyle(props)}
  ${props => props.plain && plainStyle}

  &::-webkit-input-placeholder {
    ${placeholderColor}
  }

  &::-moz-placeholder {
    ${placeholderColor}
  }

  &:-ms-input-placeholder {
    ${placeholderColor}
  }

  &::-moz-focus-inner {
    border: none;
    outline: none;
  }

  &:focus {
    ${props => !props.plain && focusStyle}
  }
`;

export const StyledTextInputContainer = styled.div`
  ${props => props.plain && 'width: 100%'}
`;

const selectedStyle = css`
  background-color: ${
    props => props.theme.global.selected.backgroundColor
  };
  color: ${props => props.theme.global.selected.textColor};
`;

export const StyledSuggestion = styled.div`
  ${props => props.selected && selectedStyle}
`;

export const StyledSuggestions = styled.ol`
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  margin: 0;
  padding: 0;
  list-style-type: none;
`;

export default StyledTextInput.extend`
  ${props => props.theme.textInput && props.theme.textInput.extend}
`;
<|endoftext|>


<commit_before>const got = require('got');

const db = require('../db.js');

const time = require('../utils/time.js');

const elron = require('../providers/elron.js');
const tlt = require('../providers/tlt.js');
const mnt = require('../providers/mnt.js');

// Get trips for stop.
async function getTrips(req, res) {

	const { stop_id: id } = req.query;
	const now = time.getSeconds();
	let trips = [];

	// Verify stop, get type and region.
	const stop = (await db.query('SELECT type, region FROM stops WHERE id = ?', [ id ]))[0];
	if (!stop) throw new Error(`Stop with id '${id}' not found`);

	// Elron

	if (stop.type === 'train') return res.send(await elron.getTrips(id));

	// TLT + MNT

	if (stop.region === 'tallinn') trips = await tlt.getTrips(id);
	trips = trips.concat(await mnt.getTrips(id, trips.length)).sort((a, b) => a.time - b.time);

	res.send(trips);

}

module.exports = (fastify, opts, next) => {

	fastify.get('/trips', {
		schema: {
			querystring: {
				type: 'object',
				required: [ 'stop_id' ],
				properties: {
					stop_id: { type: 'string' }
				}
			}
		}
	}, getTrips);

	next();

};
<commit_msg>Fix trip ordering for TLT data<commit_after>const got = require('got');

const db = require('../db.js');

const time = require('../utils/time.js');

const elron = require('../providers/elron.js');
const tlt = require('../providers/tlt.js');
const mnt = require('../providers/mnt.js');

// Get trips for stop.
async function getTrips(req, res) {

	const { stop_id: id } = req.query;
	const now = time.getSeconds();
	let trips = [];

	// Verify stop, get type and region.
	const stop = (await db.query('SELECT type, region FROM stops WHERE id = ?', [ id ]))[0];
	if (!stop) throw new Error(`Stop with id '${id}' not found`);

	// Elron

	if (stop.type === 'train') return res.send(await elron.getTrips(id));

	// TLT + MNT

	if (stop.region === 'tallinn') trips = await tlt.getTrips(id);
	trips = trips.concat(await mnt.getTrips(id, trips.length)).sort((a, b) => a.countdown - b.countdown);

	res.send(trips);

}

module.exports = (fastify, opts, next) => {

	fastify.get('/trips', {
		schema: {
			querystring: {
				type: 'object',
				required: [ 'stop_id' ],
				properties: {
					stop_id: { type: 'string' }
				}
			}
		}
	}, getTrips);

	next();

};
<|endoftext|>


<commit_before>_.load(function () {
  // The module name
  var moduleName = null;

  // The optional permissions for this module
  var modulePermissions = [];

  // The description of the optional permissions
  var modulePermissionsDescription = null;

  // Are the permissions for this module enabled?
  var isPermissionsEnabled = false;

  // Lookup the state of the history permission
  var lookupPermissions = function () {
    chrome.permissions.contains({permissions: modulePermissions}, function (isEnabled) {
      isPermissionsEnabled = isEnabled;

      document.querySelector('.permissions-state-inverse').innerHTML = (isEnabled ? 'Disable' : 'Enable');
      document.querySelector('.permissions-description').innerHTML = modulePermissionsDescription;
    });
  };

  // Toggle the history permission
  var togglePermission = function(e) {
    if (isPermissionsEnabled) {
      chrome.permissions.remove({ permissions: ['history'] }, function(isRemoved) {
        if (isRemoved) {
          // The permissions have been removed.
          console.log("The permissions have been removed.");
        } else {
          // The permissions have not been removed (e.g., you tried to remove required permissions).
          console.log("The permissions have not been removed (e.g., you tried to remove required permissions).");
        }

        lookupPermissions();
      });
    } else {
      chrome.permissions.request({ permissions: modulePermissions }, function (isGranted) {
        if (isGranted) {
          // The permissions have been granted
          console.log('The permissions have been granted');
        } else {
          // The permissions have not been granted
          console.log('The permissions have not been granted');
        }

        lookupPermissions();
      });
    }
  };

  // Bind the events to the toggle button
  document.querySelector('#toggle-permissions').addEventListener('click', togglePermission);

  // Get the optional permissions details for this module
  _.request('/lib/defaults.json', 'get', function (results) {
    var permissions = JSON.parse(results).permissions;

    // What module are we requesting optional permissions for?
    moduleName = window.location.hash.replace(/^#/, '');

    if (permissions[moduleName] !== undefined) {
      modulePermissions = permissions[moduleName].permissions;
      modulePermissionsDescription = permissions[moduleName].description;

      lookupPermissions();
    } else {
      throw "Could not find optional permissions for \"" + moduleName + "\" module";
    }
  });
});
<commit_msg>slightly refactor permissions.js<commit_after>_.load(function () {
  var moduleName = null;                   // The module name
  var modulePermissions = null;            // The optional permissions for this module
  var modulePermissionsDescription = null; // The description of the optional permissions
  var isPermissionsEnabled = false;        // Are the permissions for this module enabled?

  // Lookup the state of the current permission
  var checkPermissionState = function () {
    chrome.permissions.contains({ permissions: modulePermissions }, function (isEnabled) {
      isPermissionsEnabled = isEnabled;

      document.querySelector('.permissions-state-inverse').innerHTML = (isEnabled ? 'Disable' : 'Enable');
      document.querySelector('.permissions-description').innerHTML = modulePermissionsDescription;
    });
  };

  // Toggle the current permission
  var togglePermission = function(e) {
    if (isPermissionsEnabled) {
      chrome.permissions.remove({ permissions: modulePermissions }, function(isRemoved) {
        if (isRemoved) {
          // The permissions have been removed.
          console.log("The permissions have been removed.");
        } else {
          // The permissions have not been removed (e.g., you tried to remove required permissions).
          console.log("The permissions have not been removed (e.g., you tried to remove required permissions).");
        }
      });
    } else {
      chrome.permissions.request({ permissions: modulePermissions }, function (isGranted) {
        if (isGranted) {
          // The permissions have been granted
          console.log('The permissions have been granted');
        } else {
          // The permissions have not been granted
          console.log('The permissions have not been granted');
        }
      });
    }

    checkPermissionState();
  };

  // Bind the events to the toggle button
  document.querySelector('#toggle-permissions').addEventListener('click', togglePermission);

  // Get the optional permissions details for this module
  _.request('/lib/defaults.json', 'get', function (results) {
    var permissions = JSON.parse(results).permissions;

    // What module are we requesting optional permissions for?
    moduleName = window.location.hash.replace(/^#/, '');

    if (permissions[moduleName] !== undefined) {
      modulePermissions = permissions[moduleName].permissions;
      modulePermissionsDescription = permissions[moduleName].description;

      checkPermissionState();
    } else {
      throw "Could not find optional permissions for \"" + moduleName + "\" module";
    }
  });
});
<|endoftext|>