<commit_before>
/*!
 * Connect - utils
 * Copyright(c) 2010 Sencha Inc.
 * Copyright(c) 2011 TJ Holowaychuk
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var http = require('http')
  , crypto = require('crypto')
  , parse = require('url').parse
  , Path = require('path')
  , fs = require('fs');

/**
 * Extract the mime type from the given request's
 * _Content-Type_ header.
 *
 * @param  {IncomingMessage} req
 * @return {String}
 * @api private
 */

exports.mime = function(req) {
  var str = req.headers['content-type'] || '';
  return str.split(';')[0];
};

/**
 * Generate an `Error` from the given status `code`.
 *
 * @param {Number} code
 * @return {Error}
 * @api private
 */

exports.error = function(code){
  var err = new Error(http.STATUS_CODES[code]);
  err.status = code;
  return err;
};

/**
 * Return md5 hash of the given string and optional encoding,
 * defaulting to hex.
 *
 *     utils.md5('wahoo');
 *     // => "e493298061761236c96b02ea6aa8a2ad"
 *
 * @param {String} str
 * @param {String} encoding
 * @return {String}
 * @api public
 */

exports.md5 = function(str, encoding){
  return crypto
    .createHash('md5')
    .update(str)
    .digest(encoding || 'hex');
};

/**
 * Merge object b with object a.
 *
 *     var a = { foo: 'bar' }
 *       , b = { bar: 'baz' };
 *
 *     utils.merge(a, b);
 *     // => { foo: 'bar', bar: 'baz' }
 *
 * @param {Object} a
 * @param {Object} b
 * @return {Object}
 * @api private
 */

exports.merge = function(a, b){
  if (a && b) {
    for (var key in b) {
      a[key] = b[key];
    }
  }
  return a;
};

/**
 * Escape the given string of `html`.
 *
 * @param {String} html
 * @return {String}
 * @api private
 */

exports.escape = function(html){
  return String(html)
    .replace(/&(?!\w+;)/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"');
};

/**
 * Return a unique identifier with the given `len`.
 *
 *     utils.uid(10);
 *     // => "FDaS435D2z"
 *
 * @param {Number} len
 * @return {String}
 * @api private
 */

exports.uid = function(len) {
  return crypto.randomBytes(Math.ceil(len * 3 / 4))
    .toString('base64')
    .slice(0, len);
};

/**
 * Sign the given `val` with `secret`.
 *
 * @param {String} val
 * @param {String} secret
 * @return {String}
 * @api private
 */

exports.sign = function(val, secret){
  return val + '.' + crypto
    .createHmac('sha256', secret)
    .update(val)
    .digest('base64')
    .replace(/=+$/, '');
};

/**
 * Unsign and decode the given `val` with `secret`,
 * returning `false` if the signature is invalid.
 *
 * @param {String} val
 * @param {String} secret
 * @return {String|Boolean}
 * @api private
 */

exports.unsign = function(val, secret){
  var str = val.slice(0,val.lastIndexOf('.'));
  return exports.sign(str, secret) == val
    ? str
    : false;
};

/**
 * Parse signed cookies, returning an object
 * containing the decoded key/value pairs,
 * while removing the signed key from `obj`.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

exports.parseSignedCookies = function(obj, secret){
  var ret = {};
  Object.keys(obj).forEach(function(key){
    var val = obj[key];
    if (0 == val.indexOf('s:')) {
      ret[key] = exports.unsign(val.slice(2), secret);
      delete obj[key];
    }
  });
  return ret;
};

/**
 * Parse a signed cookie string, return the decoded value
 *
 * @param {String} str signed cookie string
 * @param {String} secret
 * @return {String} decoded value
 * @api private
 */

exports.parseSignedCookie = function(str, secret){
  return 0 == str.indexOf('s:')
    ? exports.unsign(str.slice(2), secret)
    : str;
};

/**
 * Parse JSON cookies.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

exports.parseJSONCookies = function(obj){
  Object.keys(obj).forEach(function(key){
    var val = obj[key];
    var res = exports.parseJSONCookie(val);
    if (res) obj[key] = res;
  });
  return obj;
};

/**
 * Parse JSON cookie string
 *
 * @param {String} str
 * @return {Object} Parsed object or null if not json cookie
 * @api private
 */

exports.parseJSONCookie = function(str) {
  if (0 == str.indexOf('j:')) {
    try {
      return JSON.parse(str.slice(2));
    } catch (err) {
      // no op
    }
  }
}

/**
 * Pause `data` and `end` events on the given `obj`.
 * Middleware performing async tasks _should_ utilize
 * this utility (or similar), to re-emit data once
 * the async operation has completed, otherwise these
 * events may be lost.
 *
 *      var pause = utils.pause(req);
 *      fs.readFile(path, function(){
 *         next();
 *         pause.resume();
 *      });
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

exports.pause = function(obj){
  var onData
    , onEnd
    , events = [];

  // buffer data
  obj.on('data', onData = function(data, encoding){
    events.push(['data', data, encoding]);
  });

  // buffer end
  obj.on('end', onEnd = function(data, encoding){
    events.push(['end', data, encoding]);
  });

  return {
    end: function(){
      obj.removeListener('data', onData);
      obj.removeListener('end', onEnd);
    },
    resume: function(){
      this.end();
      for (var i = 0, len = events.length; i < len; ++i) {
        obj.emit.apply(obj, events[i]);
      }
    }
  };
};

/**
 * Strip `Content-*` headers from `res`.
 *
 * @param {ServerResponse} res
 * @api private
 */

exports.removeContentHeaders = function(res){
  Object.keys(res._headers).forEach(function(field){
    if (0 == field.indexOf('content')) {
      res.removeHeader(field);
    }
  });
};

/**
 * Check if `req` is a conditional GET request.
 *
 * @param {IncomingMessage} req
 * @return {Boolean}
 * @api private
 */

exports.conditionalGET = function(req) {
  return req.headers['if-modified-since']
    || req.headers['if-none-match'];
};

/**
 * Respond with 401 "Unauthorized".
 *
 * @param {ServerResponse} res
 * @param {String} realm
 * @api private
 */

exports.unauthorized = function(res, realm) {
  res.statusCode = 401;
  res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');
  res.end('Unauthorized');
};

/**
 * Respond with 304 "Not Modified".
 *
 * @param {ServerResponse} res
 * @param {Object} headers
 * @api private
 */

exports.notModified = function(res) {
  exports.removeContentHeaders(res);
  res.statusCode = 304;
  res.end();
};

/**
 * Return an ETag in the form of `"<size>-<mtime>"`
 * from the given `stat`.
 *
 * @param {Object} stat
 * @return {String}
 * @api private
 */

exports.etag = function(stat) {
  return '"' + stat.size + '-' + Number(stat.mtime) + '"';
};

/**
 * Parse the given Cache-Control `str`.
 *
 * @param {String} str
 * @return {Object}
 * @api private
 */

exports.parseCacheControl = function(str){
  var directives = str.split(',')
    , obj = {};

  for(var i = 0, len = directives.length; i < len; i++) {
    var parts = directives[i].split('=')
      , key = parts.shift().trim()
      , val = parseInt(parts.shift(), 10);

    obj[key] = isNaN(val) ? true : val;
  }

  return obj;
};

/**
 * Parse the `req` url with memoization.
 *
 * @param {ServerRequest} req
 * @return {Object}
 * @api public
 */

exports.parseUrl = function(req){
  var parsed = req._parsedUrl;
  if (parsed && parsed.href == req.url) {
    return parsed;
  } else {
    return req._parsedUrl = parse(req.url);
  }
};

/**
 * Parse byte `size` string.
 *
 * @param {String} size
 * @return {Number}
 * @api private
 */

exports.parseBytes = require('bytes');
<commit_msg>utils are not public<commit_after>
/*!
 * Connect - utils
 * Copyright(c) 2010 Sencha Inc.
 * Copyright(c) 2011 TJ Holowaychuk
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var http = require('http')
  , crypto = require('crypto')
  , parse = require('url').parse
  , Path = require('path')
  , fs = require('fs');

/**
 * Extract the mime type from the given request's
 * _Content-Type_ header.
 *
 * @param  {IncomingMessage} req
 * @return {String}
 * @api private
 */

exports.mime = function(req) {
  var str = req.headers['content-type'] || '';
  return str.split(';')[0];
};

/**
 * Generate an `Error` from the given status `code`.
 *
 * @param {Number} code
 * @return {Error}
 * @api private
 */

exports.error = function(code){
  var err = new Error(http.STATUS_CODES[code]);
  err.status = code;
  return err;
};

/**
 * Return md5 hash of the given string and optional encoding,
 * defaulting to hex.
 *
 *     utils.md5('wahoo');
 *     // => "e493298061761236c96b02ea6aa8a2ad"
 *
 * @param {String} str
 * @param {String} encoding
 * @return {String}
 * @api private
 */

exports.md5 = function(str, encoding){
  return crypto
    .createHash('md5')
    .update(str)
    .digest(encoding || 'hex');
};

/**
 * Merge object b with object a.
 *
 *     var a = { foo: 'bar' }
 *       , b = { bar: 'baz' };
 *
 *     utils.merge(a, b);
 *     // => { foo: 'bar', bar: 'baz' }
 *
 * @param {Object} a
 * @param {Object} b
 * @return {Object}
 * @api private
 */

exports.merge = function(a, b){
  if (a && b) {
    for (var key in b) {
      a[key] = b[key];
    }
  }
  return a;
};

/**
 * Escape the given string of `html`.
 *
 * @param {String} html
 * @return {String}
 * @api private
 */

exports.escape = function(html){
  return String(html)
    .replace(/&(?!\w+;)/g, '&')
    .replace(/</g, '<')
    .replace(/>/g, '>')
    .replace(/"/g, '"');
};

/**
 * Return a unique identifier with the given `len`.
 *
 *     utils.uid(10);
 *     // => "FDaS435D2z"
 *
 * @param {Number} len
 * @return {String}
 * @api private
 */

exports.uid = function(len) {
  return crypto.randomBytes(Math.ceil(len * 3 / 4))
    .toString('base64')
    .slice(0, len);
};

/**
 * Sign the given `val` with `secret`.
 *
 * @param {String} val
 * @param {String} secret
 * @return {String}
 * @api private
 */

exports.sign = function(val, secret){
  return val + '.' + crypto
    .createHmac('sha256', secret)
    .update(val)
    .digest('base64')
    .replace(/=+$/, '');
};

/**
 * Unsign and decode the given `val` with `secret`,
 * returning `false` if the signature is invalid.
 *
 * @param {String} val
 * @param {String} secret
 * @return {String|Boolean}
 * @api private
 */

exports.unsign = function(val, secret){
  var str = val.slice(0,val.lastIndexOf('.'));
  return exports.sign(str, secret) == val
    ? str
    : false;
};

/**
 * Parse signed cookies, returning an object
 * containing the decoded key/value pairs,
 * while removing the signed key from `obj`.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

exports.parseSignedCookies = function(obj, secret){
  var ret = {};
  Object.keys(obj).forEach(function(key){
    var val = obj[key];
    if (0 == val.indexOf('s:')) {
      ret[key] = exports.unsign(val.slice(2), secret);
      delete obj[key];
    }
  });
  return ret;
};

/**
 * Parse a signed cookie string, return the decoded value
 *
 * @param {String} str signed cookie string
 * @param {String} secret
 * @return {String} decoded value
 * @api private
 */

exports.parseSignedCookie = function(str, secret){
  return 0 == str.indexOf('s:')
    ? exports.unsign(str.slice(2), secret)
    : str;
};

/**
 * Parse JSON cookies.
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

exports.parseJSONCookies = function(obj){
  Object.keys(obj).forEach(function(key){
    var val = obj[key];
    var res = exports.parseJSONCookie(val);
    if (res) obj[key] = res;
  });
  return obj;
};

/**
 * Parse JSON cookie string
 *
 * @param {String} str
 * @return {Object} Parsed object or null if not json cookie
 * @api private
 */

exports.parseJSONCookie = function(str) {
  if (0 == str.indexOf('j:')) {
    try {
      return JSON.parse(str.slice(2));
    } catch (err) {
      // no op
    }
  }
}

/**
 * Pause `data` and `end` events on the given `obj`.
 * Middleware performing async tasks _should_ utilize
 * this utility (or similar), to re-emit data once
 * the async operation has completed, otherwise these
 * events may be lost.
 *
 *      var pause = utils.pause(req);
 *      fs.readFile(path, function(){
 *         next();
 *         pause.resume();
 *      });
 *
 * @param {Object} obj
 * @return {Object}
 * @api private
 */

exports.pause = function(obj){
  var onData
    , onEnd
    , events = [];

  // buffer data
  obj.on('data', onData = function(data, encoding){
    events.push(['data', data, encoding]);
  });

  // buffer end
  obj.on('end', onEnd = function(data, encoding){
    events.push(['end', data, encoding]);
  });

  return {
    end: function(){
      obj.removeListener('data', onData);
      obj.removeListener('end', onEnd);
    },
    resume: function(){
      this.end();
      for (var i = 0, len = events.length; i < len; ++i) {
        obj.emit.apply(obj, events[i]);
      }
    }
  };
};

/**
 * Strip `Content-*` headers from `res`.
 *
 * @param {ServerResponse} res
 * @api private
 */

exports.removeContentHeaders = function(res){
  Object.keys(res._headers).forEach(function(field){
    if (0 == field.indexOf('content')) {
      res.removeHeader(field);
    }
  });
};

/**
 * Check if `req` is a conditional GET request.
 *
 * @param {IncomingMessage} req
 * @return {Boolean}
 * @api private
 */

exports.conditionalGET = function(req) {
  return req.headers['if-modified-since']
    || req.headers['if-none-match'];
};

/**
 * Respond with 401 "Unauthorized".
 *
 * @param {ServerResponse} res
 * @param {String} realm
 * @api private
 */

exports.unauthorized = function(res, realm) {
  res.statusCode = 401;
  res.setHeader('WWW-Authenticate', 'Basic realm="' + realm + '"');
  res.end('Unauthorized');
};

/**
 * Respond with 304 "Not Modified".
 *
 * @param {ServerResponse} res
 * @param {Object} headers
 * @api private
 */

exports.notModified = function(res) {
  exports.removeContentHeaders(res);
  res.statusCode = 304;
  res.end();
};

/**
 * Return an ETag in the form of `"<size>-<mtime>"`
 * from the given `stat`.
 *
 * @param {Object} stat
 * @return {String}
 * @api private
 */

exports.etag = function(stat) {
  return '"' + stat.size + '-' + Number(stat.mtime) + '"';
};

/**
 * Parse the given Cache-Control `str`.
 *
 * @param {String} str
 * @return {Object}
 * @api private
 */

exports.parseCacheControl = function(str){
  var directives = str.split(',')
    , obj = {};

  for(var i = 0, len = directives.length; i < len; i++) {
    var parts = directives[i].split('=')
      , key = parts.shift().trim()
      , val = parseInt(parts.shift(), 10);

    obj[key] = isNaN(val) ? true : val;
  }

  return obj;
};

/**
 * Parse the `req` url with memoization.
 *
 * @param {ServerRequest} req
 * @return {Object}
 * @api private
 */

exports.parseUrl = function(req){
  var parsed = req._parsedUrl;
  if (parsed && parsed.href == req.url) {
    return parsed;
  } else {
    return req._parsedUrl = parse(req.url);
  }
};

/**
 * Parse byte `size` string.
 *
 * @param {String} size
 * @return {Number}
 * @api private
 */

exports.parseBytes = require('bytes');
<|endoftext|>


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

const Ajv = require('ajv');
const strictDeepEquals = require('deep-equal');
const fs = require("fs");
const _ = require("lodash");
const path = require("path");
const shell = require("shelljs");
const deepEquals = require("./deepEquals");
const Main = require("../output/Main");
const Samples = require("../output/Samples");
const assert = require("assert");
const { inParallel } = require("./multicore");
const os = require("os");
const exit = require('exit');

//////////////////////////////////////
// Constants
/////////////////////////////////////

function debug(x) {
    if (!process.env.DEBUG) return;
    console.log(x);
    return x;
}

const IS_CI = process.env.CI === "true";
const BRANCH = process.env.TRAVIS_BRANCH;
const IS_BLESSED = ["master"].indexOf(BRANCH) !== -1;
const IS_PUSH = process.env.TRAVIS_EVENT_TYPE === "push";
const IS_PR = process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== "false";

const CPUs = IS_CI
    ? 2 /* Travis has only 2 but reports 8 */
    : process.env.CPUs || os.cpus().length;

const QUICKTYPE_CLI = path.resolve("./cli/quicktype.js");

const NODE_BIN = path.resolve("./node_modules/.bin");
process.env.PATH += `:${NODE_BIN}`;

//////////////////////////////////////
// Fixtures
/////////////////////////////////////

const FIXTURES = [
    {
        name: "csharp",
        base: "test/csharp",
        setup: "dotnet restore",
        diffViaSchema: false,
        output: "QuickType.cs",
        test: testCSharp
    },
    {
        name: "golang",
        base: "test/golang",
        diffViaSchema: true,
        output: "quicktype.go",
        test: testGo
    },
    {
        name: "json-schema",
        base: "test/golang",
        diffViaSchema: false,
        output: "schema.json",
        test: testJsonSchema
    },
    {
        name: "elm",
        base: "test/elm",
        setup: IS_CI ? "./setup-ci.sh" : "elm-make --yes",
        diffViaSchema: false,
        output: "QuickType.elm",
        test: testElm
    }
].filter(({name}) => !process.env.FIXTURE || name === process.env.FIXTURE);

//////////////////////////////////////
// Go tests
/////////////////////////////////////

const knownUnicodeFails = ["identifiers.json"];
const unicodeWillFail = (sample) => knownUnicodeFails.indexOf(path.basename(sample)) !== -1;

function testGo(sample) {
    if (unicodeWillFail(sample)) {
        console.error(`Skipping golang ${sample} – known to fail`);
        return;
    }

    compareJsonFileToJson({
        expectedFile: sample,
        jsonCommand: `go run main.go quicktype.go < "${sample}"`,
        strict: false
    });
}

//////////////////////////////////////
// C# tests
/////////////////////////////////////

function testCSharp(sample) {
    compareJsonFileToJson({
        expectedFile: sample,
        jsonCommand: `dotnet run "${sample}"`,
        strict: false
    });
}

//////////////////////////////////////
// Elm tests
/////////////////////////////////////

function testElm(sample) {
    if (unicodeWillFail(sample)) {
        console.error(`Skipping elm ${sample} – known to fail`);
        return;
    }

    let limit_cpus = IS_CI ? "$TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2" : "";
    exec(`${limit_cpus} elm-make Main.elm QuickType.elm --output elm.js`)

    exec(`node ./runner.js "${sample}"`)
}

//////////////////////////////////////
// JSON Schema tests
/////////////////////////////////////

function testJsonSchema(sample) {
    let input = JSON.parse(fs.readFileSync(sample));
    let schema = JSON.parse(fs.readFileSync("schema.json"));

    let ajv = new Ajv();
    let valid = ajv.validate(schema, input);
    if (!valid) {
        failWith({
            sample,
            error: "Generated schema does not validate input JSON.",
        });
    }

    // Generate Go from the schema
    exec(`quicktype --srcLang json-schema -o quicktype.go --src schema.json`);

    // Possibly check the output of the Go program against the sample
    if (unicodeWillFail(sample)) {
        console.error("Known to fail - not checking output.");
    } else {
        // Parse the sample with Go generated from its schema, and compare to the sample
        compareJsonFileToJson({
            expectedFile: sample,
            jsonCommand: `go run main.go quicktype.go < "${sample}"`,
            strict: false
        });
    }

    // Generate a schema from the schema, making sure the schemas are the same
    compareJsonFileToJson({
        expectedFile: "schema.json",
        jsonCommand: `quicktype --srcLang json-schema --src schema.json --lang json`,
        strict: true
    });
}

//////////////////////////////////////
// Test driver
/////////////////////////////////////

function failWith(obj) {
    obj.cwd = process.cwd();
    console.error(JSON.stringify(obj, null, "  "));
    throw obj;
}

function exec(s, opts, cb) {
    // We special-case quicktype execution
    s = s.replace(/^quicktype /, `node ${QUICKTYPE_CLI} `);

    debug(s);

    let result = shell.exec(s, opts, cb);
    if (result.code !== 0) {
        console.error(result.stdout);
        console.error(result.stderr);
        failWith({
            command: s,
            code: result.code
        });
    }
    return result;
}

function compareJsonFileToJson({expectedFile, jsonFile, jsonCommand, strict}) {
    debug({expectedFile, jsonFile, jsonCommand, strict});

    let jsonString = jsonFile
        ? fs.readFileSync(jsonFile)
        : exec(jsonCommand, {silent: true}).stdout;

    let givenJSON = JSON.parse(jsonString);
    let expectedJSON = JSON.parse(fs.readFileSync(expectedFile));

    let jsonAreEqual = strict
        ? strictDeepEquals(givenJSON, expectedJSON)
        : deepEquals(expectedJSON, givenJSON, []);

    if (!jsonAreEqual) {
        console.error("Error: Output is not equivalent to input.");
        failWith({
            expectedFile,
            jsonCommand,
            jsonFile
        });
    }
}

function inDir(dir, work) {
    let origin = process.cwd();

    debug(`cd ${dir}`)
    process.chdir(dir);

    work();
    process.chdir(origin);
}

function runFixtureWithSample(fixture, sample) {
    let tmp = path.resolve(os.tmpdir(), require("crypto").randomBytes(8).toString('hex'));
    let sampleAbs = path.resolve(sample);

    let stats = fs.statSync(sampleAbs);
    if (stats.size > 32 * 1024 * 1024) {
        console.error(`* Skipping ${sampleAbs} because it's too large`);
        return;
    }

    shell.cp("-R", fixture.base, tmp);

    inDir(tmp, () => {
        // Generate code from the sample
        exec(`quicktype --src ${sampleAbs} --srcLang json -o ${fixture.output}`);

        fixture.test(sampleAbs);

        if (fixture.diffViaSchema) {
            debug("* Diffing with code generated via JSON Schema");
            // Make a schema
            exec(`quicktype --src ${sampleAbs} --srcLang json -o schema.json`);
            // Quicktype from the schema and compare to expected code
            shell.mv(fixture.output, `${fixture.output}.expected`);
            exec(`quicktype --src schema.json --srcLang json-schema -o ${fixture.output}`);

            // Compare fixture.output to fixture.output.expected
            try {
                exec(`diff -Naur ${fixture.output}.expected ${fixture.output}`);
            } catch ({ command }) {
                // FIXME: Set this to fail once we have it working.  See issue #59.
                console.error(`Command failed, but we're allowing it: ${command}`);
            }
        }
    });

    shell.rm("-rf", tmp);
}

function testAll(samples) {
    // Get an array of all { sample, fixtureName } objects we'll run
    let tests =  _
        .chain(FIXTURES)
        .flatMap((fixture) => samples.map((sample) => {
            return { sample, fixtureName: fixture.name };
        }))
        .shuffle()
        .value();

    inParallel({
        queue: tests,
        workers: CPUs,
        setup: () => {
            FIXTURES.forEach(({ name, base, setup }) => {
                if (!setup) return;
                console.error(`* Setting up ${name} fixture`);
                inDir(base, () => exec(setup, { silent: true }));
            });
        },
        work: ({ sample, fixtureName }, i) => {
            console.error(`* [${i+1}/${tests.length}] ${fixtureName} ${sample}`);

            let fixture = _.find(FIXTURES, { name: fixtureName });
            try {
                runFixtureWithSample(fixture, sample);
            } catch (e) {
                exit(1);
            }
        }
    });
}

function testsInDir(dir) {
    return shell.ls(`${dir}/*.json`);
}

function main(sources) {
    if (sources.length == 0) {
        sources = testsInDir("test/inputs/json");
    }

    if (IS_CI && !IS_PR && !IS_BLESSED) {
        // Run just a few random samples on low-priority CI branches
        sources = _.chain(sources).shuffle().take(3).value();
    }

    if (sources.length == 1 && fs.lstatSync(sources[0]).isDirectory()) {
        sources = testsInDir(sources[0]);
    }

    testAll(sources);
}

// skip 2 `node` args
main(process.argv.slice(2));
<commit_msg>Cleanup before tests when running locally<commit_after>#!/usr/bin/env node

const Ajv = require('ajv');
const strictDeepEquals = require('deep-equal');
const fs = require("fs");
const _ = require("lodash");
const path = require("path");
const shell = require("shelljs");
const deepEquals = require("./deepEquals");
const Main = require("../output/Main");
const Samples = require("../output/Samples");
const assert = require("assert");
const { inParallel } = require("./multicore");
const os = require("os");
const exit = require('exit');

//////////////////////////////////////
// Constants
/////////////////////////////////////

function debug(x) {
    if (!process.env.DEBUG) return;
    console.log(x);
    return x;
}

const IS_CI = process.env.CI === "true";
const BRANCH = process.env.TRAVIS_BRANCH;
const IS_BLESSED = ["master"].indexOf(BRANCH) !== -1;
const IS_PUSH = process.env.TRAVIS_EVENT_TYPE === "push";
const IS_PR = process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== "false";

const CPUs = IS_CI
    ? 2 /* Travis has only 2 but reports 8 */
    : process.env.CPUs || os.cpus().length;

const QUICKTYPE_CLI = path.resolve("./cli/quicktype.js");

const NODE_BIN = path.resolve("./node_modules/.bin");
process.env.PATH += `:${NODE_BIN}`;

//////////////////////////////////////
// Fixtures
/////////////////////////////////////

const FIXTURES = [
    {
        name: "csharp",
        base: "test/csharp",
        setup: "dotnet restore",
        diffViaSchema: false,
        output: "QuickType.cs",
        test: testCSharp
    },
    {
        name: "golang",
        base: "test/golang",
        diffViaSchema: true,
        output: "quicktype.go",
        test: testGo
    },
    {
        name: "json-schema",
        base: "test/golang",
        diffViaSchema: false,
        output: "schema.json",
        test: testJsonSchema
    },
    {
        name: "elm",
        base: "test/elm",
        setup: IS_CI ? "./setup-ci.sh" : "rm -rf elm-stuff && elm-make --yes",
        diffViaSchema: false,
        output: "QuickType.elm",
        test: testElm
    }
].filter(({name}) => !process.env.FIXTURE || name === process.env.FIXTURE);

//////////////////////////////////////
// Go tests
/////////////////////////////////////

const knownUnicodeFails = ["identifiers.json"];
const unicodeWillFail = (sample) => knownUnicodeFails.indexOf(path.basename(sample)) !== -1;

function testGo(sample) {
    if (unicodeWillFail(sample)) {
        console.error(`Skipping golang ${sample} – known to fail`);
        return;
    }

    compareJsonFileToJson({
        expectedFile: sample,
        jsonCommand: `go run main.go quicktype.go < "${sample}"`,
        strict: false
    });
}

//////////////////////////////////////
// C# tests
/////////////////////////////////////

function testCSharp(sample) {
    compareJsonFileToJson({
        expectedFile: sample,
        jsonCommand: `dotnet run "${sample}"`,
        strict: false
    });
}

//////////////////////////////////////
// Elm tests
/////////////////////////////////////

function testElm(sample) {
    if (unicodeWillFail(sample)) {
        console.error(`Skipping elm ${sample} – known to fail`);
        return;
    }

    let limit_cpus = IS_CI ? "$TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2" : "";
    exec(`${limit_cpus} elm-make Main.elm QuickType.elm --output elm.js`)

    exec(`node ./runner.js "${sample}"`)
}

//////////////////////////////////////
// JSON Schema tests
/////////////////////////////////////

function testJsonSchema(sample) {
    let input = JSON.parse(fs.readFileSync(sample));
    let schema = JSON.parse(fs.readFileSync("schema.json"));

    let ajv = new Ajv();
    let valid = ajv.validate(schema, input);
    if (!valid) {
        failWith({
            sample,
            error: "Generated schema does not validate input JSON.",
        });
    }

    // Generate Go from the schema
    exec(`quicktype --srcLang json-schema -o quicktype.go --src schema.json`);

    // Possibly check the output of the Go program against the sample
    if (unicodeWillFail(sample)) {
        console.error("Known to fail - not checking output.");
    } else {
        // Parse the sample with Go generated from its schema, and compare to the sample
        compareJsonFileToJson({
            expectedFile: sample,
            jsonCommand: `go run main.go quicktype.go < "${sample}"`,
            strict: false
        });
    }

    // Generate a schema from the schema, making sure the schemas are the same
    compareJsonFileToJson({
        expectedFile: "schema.json",
        jsonCommand: `quicktype --srcLang json-schema --src schema.json --lang json`,
        strict: true
    });
}

//////////////////////////////////////
// Test driver
/////////////////////////////////////

function failWith(obj) {
    obj.cwd = process.cwd();
    console.error(JSON.stringify(obj, null, "  "));
    throw obj;
}

function exec(s, opts, cb) {
    // We special-case quicktype execution
    s = s.replace(/^quicktype /, `node ${QUICKTYPE_CLI} `);

    debug(s);

    let result = shell.exec(s, opts, cb);
    if (result.code !== 0) {
        console.error(result.stdout);
        console.error(result.stderr);
        failWith({
            command: s,
            code: result.code
        });
    }
    return result;
}

function compareJsonFileToJson({expectedFile, jsonFile, jsonCommand, strict}) {
    debug({expectedFile, jsonFile, jsonCommand, strict});

    let jsonString = jsonFile
        ? fs.readFileSync(jsonFile)
        : exec(jsonCommand, {silent: true}).stdout;

    let givenJSON = JSON.parse(jsonString);
    let expectedJSON = JSON.parse(fs.readFileSync(expectedFile));

    let jsonAreEqual = strict
        ? strictDeepEquals(givenJSON, expectedJSON)
        : deepEquals(expectedJSON, givenJSON, []);

    if (!jsonAreEqual) {
        console.error("Error: Output is not equivalent to input.");
        failWith({
            expectedFile,
            jsonCommand,
            jsonFile
        });
    }
}

function inDir(dir, work) {
    let origin = process.cwd();

    debug(`cd ${dir}`)
    process.chdir(dir);

    work();
    process.chdir(origin);
}

function runFixtureWithSample(fixture, sample) {
    let tmp = path.resolve(os.tmpdir(), require("crypto").randomBytes(8).toString('hex'));
    let sampleAbs = path.resolve(sample);

    let stats = fs.statSync(sampleAbs);
    if (stats.size > 32 * 1024 * 1024) {
        console.error(`* Skipping ${sampleAbs} because it's too large`);
        return;
    }

    shell.cp("-R", fixture.base, tmp);

    inDir(tmp, () => {
        // Generate code from the sample
        exec(`quicktype --src ${sampleAbs} --srcLang json -o ${fixture.output}`);

        fixture.test(sampleAbs);

        if (fixture.diffViaSchema) {
            debug("* Diffing with code generated via JSON Schema");
            // Make a schema
            exec(`quicktype --src ${sampleAbs} --srcLang json -o schema.json`);
            // Quicktype from the schema and compare to expected code
            shell.mv(fixture.output, `${fixture.output}.expected`);
            exec(`quicktype --src schema.json --srcLang json-schema -o ${fixture.output}`);

            // Compare fixture.output to fixture.output.expected
            try {
                exec(`diff -Naur ${fixture.output}.expected ${fixture.output}`);
            } catch ({ command }) {
                // FIXME: Set this to fail once we have it working.  See issue #59.
                console.error(`Command failed, but we're allowing it: ${command}`);
            }
        }
    });

    shell.rm("-rf", tmp);
}

function testAll(samples) {
    // Get an array of all { sample, fixtureName } objects we'll run
    let tests =  _
        .chain(FIXTURES)
        .flatMap((fixture) => samples.map((sample) => {
            return { sample, fixtureName: fixture.name };
        }))
        .shuffle()
        .value();

    inParallel({
        queue: tests,
        workers: CPUs,
        setup: () => {
            FIXTURES.forEach(({ name, base, setup }) => {
                if (!setup) return;
                console.error(`* Setting up ${name} fixture`);
                inDir(base, () => exec(setup, { silent: true }));
            });
        },
        work: ({ sample, fixtureName }, i) => {
            console.error(`* [${i+1}/${tests.length}] ${fixtureName} ${sample}`);

            let fixture = _.find(FIXTURES, { name: fixtureName });
            try {
                runFixtureWithSample(fixture, sample);
            } catch (e) {
                exit(1);
            }
        }
    });
}

function testsInDir(dir) {
    return shell.ls(`${dir}/*.json`);
}

function main(sources) {
    if (sources.length == 0) {
        sources = testsInDir("test/inputs/json");
    }

    if (IS_CI && !IS_PR && !IS_BLESSED) {
        // Run just a few random samples on low-priority CI branches
        sources = _.chain(sources).shuffle().take(3).value();
    }

    if (sources.length == 1 && fs.lstatSync(sources[0]).isDirectory()) {
        sources = testsInDir(sources[0]);
    }

    testAll(sources);
}

// skip 2 `node` args
main(process.argv.slice(2));
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const path = require('path');

let controllerDir;
let appName;

/**
 * returns application name
 *
 * The name of the application can be different and this function finds it out.
 *
 * @returns {string}
 */
 function getAppName() {
    const parts = __dirname.replace(/\\/g, '/').split('/');
    return parts[parts.length - 2].split('.')[0];
}

/**
 * looks for js-controller home folder
 *
 * @param {boolean} isInstall
 * @returns {string}
 */
function getControllerDir(isInstall) {
    // Find the js-controller location
    const possibilities = [
        'iobroker.js-controller',
        'ioBroker.js-controller',
    ];
    /** @type {string} */
    let controllerPath;
    for (const pkg of possibilities) {
        try {
            const possiblePath = require.resolve(pkg);
            if (fs.existsSync(possiblePath)) {
                controllerPath = possiblePath;
                break;
            }
        } catch (e) { /* not found */ }
    }
    if (controllerPath == null) {
        if (!isInstall) {
            console.log('Cannot find js-controller');
            process.exit(10);
        } else {
            process.exit();
        }
    }
    // we found the controller
    return path.dirname(controllerPath);
}

/**
 * reads controller base settings
 *
 * @alias getConfig
 * @returns {object}
 */
 function getConfig() {
    let configPath;
    if (fs.existsSync(
        configPath = path.join(controllerDir, 'conf', appName + '.json')
    )) {
        return JSON.parse(fs.readFileSync(configPath, 'utf8'));
    } else if (fs.existsSync(
        configPath = path.join(controllerDir, 'conf', + appName.toLowerCase() + '.json')
    )) {
        return JSON.parse(fs.readFileSync(configPath, 'utf8'));
    } else {
        throw new Error('Cannot find ' + controllerDir + '/conf/' + appName + '.json');
    }
}
appName       = getAppName();
controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.indexOf('--install') !== -1);
const adapter = require(path.join(controllerDir, 'lib/adapter.js'));

exports.controllerDir = controllerDir;
exports.getConfig =     getConfig;
exports.Adapter =       adapter;
exports.appName =       appName;
<commit_msg>remove utils.js<commit_after><|endoftext|>


<commit_before>// Enemies our player must avoid

// Això és una classe en OOP
// Després l'utilitzarem per crear tantes variables d'enemic com vulguem :D
var Enemy = function(x, y) {
    // var Enemy = function(x, y, speed) --> així calculem nivells? idea!
    // Variables applied to each of our instances go here, we've provided one for you to get started

    // Inicialitzem l'enemic a una x i una y que li passarem com a paràmetres per la funció
    // Setting the Enemy initial location
    this.x = x;
    this.y = y;

    // If you assign a speed to each bug in your Enemy definition when you define this.x and
    // this.y you can set a different speed for each bug at the moment it is defined:
    // this.speed = Math.floor(Math.random() * 450 + 1); --> Susan

    // Math.random(); // A random number between 0 and 1.
    // Math.floor(Math.random() * X + 1); // Returns a random number between 1 and X

     // Fem que la velocitat sigui diferent per cada un de forma aleatòria, seguint el consell de la Susan, yay
     // Setting the Enemy speed
     //450 és molt ràpid... però ara hi ha alguns que es queden clavats?
    this.speed = Math.floor(Math.random() * 350 + 1);
    console.log(Math.floor(Math.random() * 350 +1));

    // però i si volem posar-hi nivells? i fer que cada nivell sigui més xungo?
    // aleshores no hauriem de posar la velocitat random, no??

    // Aquí fiquem la imatge de l'enemic, utilitzant el "sprite" --> què és?
    // Loading the image by setting this.sprite to the appropriate image
    this.sprite = 'images/enemy-bug.png';
}

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks --> està creat al engine
// Això és una subclasse del Enemy
Enemy.prototype.update = function(dt) {
    // You should multiply any movement by the dt parameter which will ensure the game runs at the same speed for all computers.

    // Afegim la posició multiplicant la dt per la velocitat. Què és this.speed?
    // Updates the Enemy location
    // In the Enemy update function, you can move the enemy along a little bit --> Susan
    this.x += this.speed * dt;
    // And if you want them to move a little faster you can add something to the calculation:
    // this.x += (this.speed + 100) * dt; --> Susan

    // Handles collision with the Player

    // si se'n va de la pantalla, torna a començar?
    if (this.x > 505) {
       // fem que torni a començar a les quimbambes a l'esquerra
       // fem que la velocitat tb sigui random :D
        this.x = Math.random() * -600;
        this.speed = Math.floor(Math.random() * 350 + 1);
        console.log(Math.random() * -600);
    }
}

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
}

// Now write your own player class
// This class requires an update(), render() and a handleInput() method.
// Això és una classe, i per tant va amb majúscules. Igual que el Enemy
// Implement the Player class
// The Player function, which initiates the Player by
var Player = function() {
    // 0,0 és a dalt a l'esquerra de tot
    // Setting the Player initial location
    // aquest és el punt mig a sota de la pantalla (sempre el punt és a dalt a la esquerra!)
    this.x = 202;
    this.y = 415;
    // Loading the image by setting this.sprite
    this.sprite = 'images/char-boy.png';
}

// Update per actualitzar la posició de la personeta
// Update method for the Player
Player.prototype.update = function() {
    this.x = this.x;
    this.y = this.y;
}

// Render per dibuixar la personeta
// Render method for the Player
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
}

// Això és el control de les fletxes del teclat.
// Li passem coma paràmetre la tecla, i segons la tecla que sigui farem que es mogui d'una forma o d'una altre!
// handleInput method, which should receive user input, allowedKeys (the key which was pressed)
// and move the player according to that input. In particular:
Player.prototype.handleInput = function(allowedKeys) {

    // la imatge fa 101 x 171
    // però en vertical està partida en 2 (cada imatge són 2 quadrats)

    // per tant, --> i <-- han de fer 101 cap a la dreta o cap a l'esquerra
    // cap amunt i avall han de fer 85

    // 101 i 85 són per si volem que salti de bloc en bloc, però per fer una transició smooth....?

    switch(allowedKeys) {
        // left key should move the player to the left
        // recall that the player cannot move off screen (so you will need to check for that and handle appropriately)
         case 'left':

            // cap a l'esquerra
            // però si no posem res més, desapareix!
            if (this.x > 0) {
                this.x -= 101;
                break;
            }

        case 'up':

            // cap a dalt. 83 perquè és el tamany amb què calculem el canvas al engine, per superposar les imatges
            if (this.y > 0) {
                this.y -= 83;
                break;
            }

        case 'right':

            // cap a la dreta
            // per què 404?
            if (this.x < 404) {
                this.x += 101;
                break;
            }

        case 'down':

            // cap a baix
            if (this.y < 400) {
                this.y += 83;
                break;
            }

    }

    // if the player reaches the water, the game should be reset by moving the player back to
    // the initial location (you can write a separate reset Player method to handle that)
    if (this.y < 83) {  //això és aigua
        player.reset();
    }

}

// hem de fer que s'esperi un segon a l'aigua, i després resetegi
Player.prototype.reset = function() {
    this.x = 202;
    this.y = 415;
}

// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
// Place the player object in a variable called player

// Creem tots els enemics que volem tenir en pantalla i li passem les posicions inicials (si posem posicions negatives, fem que surtin a diferents temps)
// create several new Enemies objects and placing them in an array called allEnemies
var enemy_1 = new Enemy(-200, 63);
var enemy_2 = new Enemy(-350, 145);
var enemy_3 = new Enemy(-96, 228);
var enemy_4 = new Enemy(-96, 63);
var enemy_5 = new Enemy(-150, 145);
var enemy_6 = new Enemy(-450, 228);  //
var allEnemies = [enemy_1, enemy_2, enemy_3, enemy_4, enemy_5, enemy_6];  // Array

// Creem el nostre jugador
// create a new Player object
var player = new Player();

// Hem de crear la funció per veure si hi ha col·lisió i aleshores resetejar-ho!

// This listens for key presses and sends the keys to your Player.handleInput() method
document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };

    player.handleInput(allowedKeys[e.keyCode]);
});

/* Adding functionality:
Player selection: allow the user to select the image for the player.
Score: you can implement a score for the game. It can increase each time the player reaches the water, and it can reset to 0 when collision occurs
Collectables: you can add gems to the game, allowing the player to collect them to make the game more interesting. */

/* Collission forum
https://discussions.udacity.com/t/trying-to-identify-collisions-but-how-do-i-compare-enemy-x-with-player-x/29930
https://discussions.udacity.com/t/sure-i-would-love-some-collisioncheck-help/29801
https://discussions.udacity.com/t/player-bug-collision-problem/15068
https://discussions.udacity.com/t/problems-with-checkcollisions-function/30228 */

/* Links del forum útils pels nous canvis:
https://discussions.udacity.com/t/bug-drawn-behind-gem-on-canvas/23201
https://discussions.udacity.com/t/adding-sprites-to-canvas-background/28880
https://discussions.udacity.com/t/project-3-add-scores/20978
https://discussions.udacity.com/t/creating-multiple-enemy-instances/29406
https://discussions.udacity.com/t/finite-state-machine-to-model-game-states/21955
https://discussions.udacity.com/t/start-end-the-game/21441
*/

/* Links d'altres llocs útils:
https://docs.google.com/document/d/1v01aScPjSWCCWQLIpFqvg3-vXLH2e8_SZQKC8jNO0Dc/pub
http://jlongster.com/Making-Sprite-based-Games-with-Canvas
https://docs.google.com/document/d/1sYjy4Swrppc6OreRy6zWQFKNnJhu1pJ9uikZPSD0HMc/pub
http://opengameart.org/
http://www.freesound.org/
http://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
http://www.html5gamedevelopment.com/html5-game-tutorials/2013-06-5-part-html5-game-tutorial-galaxian-shooter
http://eloquentjavascript.net/04_data.html
*/<commit_msg>velocitats i variables<commit_after>// Enemies our player must avoid

// Això és una classe en OOP
// Després l'utilitzarem per crear tantes variables d'enemic com vulguem :D
var Enemy = function(x, y) {
    // var Enemy = function(x, y, speed) --> així calculem nivells? idea!
    // Variables applied to each of our instances go here, we've provided one for you to get started

    // Inicialitzem l'enemic a una x i una y que li passarem com a paràmetres per la funció
    // Setting the Enemy initial location
    this.x = x;
    this.y = y;

    // If you assign a speed to each bug in your Enemy definition when you define this.x and
    // this.y you can set a different speed for each bug at the moment it is defined:
    // this.speed = Math.floor(Math.random() * 450 + 1); --> Susan

    // Math.random(); // A random number between 0 and 1.
    // Math.floor(Math.random() * X + 1); // Returns a random number between 1 and X

     // Fem que la velocitat sigui diferent per cada un de forma aleatòria, seguint el consell de la Susan, yay
     // Setting the Enemy speed
     //450 és molt ràpid... però ara hi ha alguns que es queden clavats?
    this.speed = Math.floor(Math.random() * 350 + 1);
    console.log(Math.floor(Math.random() * 350 +1));

    // però i si volem posar-hi nivells? i fer que cada nivell sigui més xungo?
    // aleshores no hauriem de posar la velocitat random, no??

    // Loading the image by setting this.sprite to the appropriate image
    this.sprite = 'images/enemy-bug.png';
}

// Update the enemy's position, required method for game
// Parameter: dt, a time delta between ticks --> està creat al engine
// Això és una subclasse del Enemy
Enemy.prototype.update = function(dt) {
    // You should multiply any movement by the dt parameter which will ensure the game runs at the same speed for all computers.

    // Afegim la posició multiplicant la dt per la velocitat. Què és this.speed?
    // Updates the Enemy location
    // In the Enemy update function, you can move the enemy along a little bit --> Susan
    this.x += this.speed * dt;
    // And if you want them to move a little faster you can add something to the calculation:
    // this.x += (this.speed + 100) * dt; --> Susan

    // Handles collision with the Player

    // si se'n va de la pantalla, torna a començar?
    if (this.x > 505) {
       // fem que torni a començar a les quimbambes a l'esquerra
       // fem que la velocitat tb sigui random :D --> comprovar què estem fent amb la velocitat...
        this.x = Math.random() * -600;
        this.speed = Math.floor(Math.random() * 350 + 1);
        console.log(Math.random() * -600);
    }
}

// Draw the enemy on the screen, required method for game
Enemy.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
}

// Now write your own player class
// This class requires an update(), render() and a handleInput() method.
// Això és una classe, i per tant va amb majúscules. Igual que el Enemy
// Implement the Player class
// The Player function, which initiates the Player by
var Player = function() {
    // 0,0 és a dalt a l'esquerra de tot
    // Setting the Player initial location
    // aquest és el punt mig a sota de la pantalla (sempre el punt és a dalt a la esquerra!)
    this.x = 202;
    this.y = 415;
    // Loading the image by setting this.sprite
    this.sprite = 'images/char-boy.png';
}

// Update per actualitzar la posició de la personeta
// Update method for the Player
Player.prototype.update = function() {
    this.x = this.x;
    this.y = this.y;
}

// Render per dibuixar la personeta
// Render method for the Player
Player.prototype.render = function() {
    ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
}

// Això és el control de les fletxes del teclat.
// Li passem coma paràmetre la tecla, i segons la tecla que sigui farem que es mogui d'una forma o d'una altre
// handleInput method, which should receive user input, allowedKeys (the key which was pressed)
// and move the player according to that input. In particular:
Player.prototype.handleInput = function(allowedKeys) {

    // la imatge fa 101 x 171
    // però en vertical està partida en 2 (cada imatge són 2 quadrats)

    // per tant, --> i <-- han de fer 101 cap a la dreta o cap a l'esquerra
    // cap amunt i avall han de fer 85

    // 101 i 85 són per si volem que salti de bloc en bloc, però per fer una transició smooth....?

    switch(allowedKeys) {
        // left key should move the player to the left
        // recall that the player cannot move off screen (so you will need to check for that and handle appropriately)
         case 'left':

            // cap a l'esquerra
            // però si no posem res més, desapareix!
            if (this.x > 0) {
                this.x -= 101;
                break;
            }

        case 'up':

            // cap a dalt. 83 perquè és el tamany amb què calculem el canvas al engine, per superposar les imatges
            if (this.y > 0) {
                this.y -= 83;
                break;
            }

        case 'right':

            // cap a la dreta
            // per què 404?
            if (this.x < 404) {
                this.x += 101;
                break;
            }

        case 'down':

            // cap a baix
            if (this.y < 400) {
                this.y += 83;
                break;
            }

    }

    // if the player reaches the water, the game should be reset by moving the player back to
    // the initial location (you can write a separate reset Player method to handle that)
    if (this.y < 83) {  //això és aigua
        player.reset();
    }

}

// hem de fer que s'esperi un segon a l'aigua, i després resetegi
Player.prototype.reset = function() {
    this.x = 202;
    this.y = 415;
}

// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
// Place the player object in a variable called player

// Creem tots els enemics que volem tenir en pantalla i li passem les posicions inicials (si posem posicions negatives, fem que surtin a diferents temps)
// create several new Enemies objects and placing them in an array called allEnemies

var allEnemies = [];

for (var i = 0; i < 6; i++) {
    if (i % 3 === 0) {  // row 1
        var enemyRandom = new Enemy(-(Math.floor(Math.random() * 400 + 100)), 63);
    } else if (i % 3 === 1) {  // row 2
        var enemyRandom = new Enemy(-(Math.floor(Math.random() * 400 + 100)), 146);
    } else {  // row 3
        var enemyRandom = new Enemy(-(Math.floor(Math.random() * 400 + 100)), 229);
    }
    allEnemies[i] = enemyRandom;
}

// Creem el nostre jugador
// create a new Player object
var player = new Player();

// Hem de crear la funció per veure si hi ha col·lisió i aleshores resetejar-ho!

// This listens for key presses and sends the keys to your Player.handleInput() method
document.addEventListener('keyup', function(e) {
    var allowedKeys = {
        37: 'left',
        38: 'up',
        39: 'right',
        40: 'down'
    };

    player.handleInput(allowedKeys[e.keyCode]);
});

/* Adding functionality:
Player selection: allow the user to select the image for the player.
Score: you can implement a score for the game. It can increase each time the player reaches the water, and it can reset to 0 when collision occurs
Collectables: you can add gems to the game, allowing the player to collect them to make the game more interesting. */

/* Collission forum
https://discussions.udacity.com/t/trying-to-identify-collisions-but-how-do-i-compare-enemy-x-with-player-x/29930
https://discussions.udacity.com/t/sure-i-would-love-some-collisioncheck-help/29801
https://discussions.udacity.com/t/player-bug-collision-problem/15068
https://discussions.udacity.com/t/problems-with-checkcollisions-function/30228 */

/* Links del forum útils pels nous canvis:
https://discussions.udacity.com/t/bug-drawn-behind-gem-on-canvas/23201
https://discussions.udacity.com/t/adding-sprites-to-canvas-background/28880
https://discussions.udacity.com/t/project-3-add-scores/20978
https://discussions.udacity.com/t/creating-multiple-enemy-instances/29406
https://discussions.udacity.com/t/finite-state-machine-to-model-game-states/21955
https://discussions.udacity.com/t/start-end-the-game/21441
*/

/* Links d'altres llocs útils:
https://docs.google.com/document/d/1v01aScPjSWCCWQLIpFqvg3-vXLH2e8_SZQKC8jNO0Dc/pub
http://jlongster.com/Making-Sprite-based-Games-with-Canvas
https://docs.google.com/document/d/1sYjy4Swrppc6OreRy6zWQFKNnJhu1pJ9uikZPSD0HMc/pub
http://opengameart.org/
http://www.freesound.org/
http://gamedevelopment.tutsplus.com/tutorials/finite-state-machines-theory-and-implementation--gamedev-11867
http://www.williammalone.com/articles/create-html5-canvas-javascript-sprite-animation/
http://www.html5gamedevelopment.com/html5-game-tutorials/2013-06-5-part-html5-game-tutorial-galaxian-shooter
http://eloquentjavascript.net/04_data.html
*/<|endoftext|>


<commit_before>if (!window['$']) var $ = function a(){}
(function a(){
    $.get('https://api.github.com/repos/KaMeHb-UA/LeNode/releases/latest', function(data, status){
        if (status != 'success') a(); else {
            $('a[rel="download"]').attr('href', data.assets[0].browser_download_url);
            $('#latest-version').html(data.tag_name);
            $('*[rel="release-description"]').html(data.name);
        }
    }, 'json');
})();
document.addEventListener('DOMContentLoaded', function(){
    'use strict';
    var actions = {
        log : function(){
            console.log.apply(null, arguments);
            console.log(this);
        },
        hide : function(){
            this.css('display', 'none')
        },
        detach : function(){
            this.detach(arguments ? arguments[0] : undefined)
        },
        remove : function(){
            this.remove(arguments ? arguments[0] : undefined)
        }
    };
    $('*[__click]').each(function(i,e){
        var e = $(e);
        e.click(function(){
            try{
                actions[e.attr('__click')].apply(e, (function(a){
                    if (a){
                        try{
                            return JSON.parse(a);
                        } catch(e){
                            return [a];
                        }
                    } else return [];
                })(e.attr('__click_data')));
            } catch(e){
                console.warn('Cannot find action ' + e.attr('__click'));
            }
        });
    });
});
<commit_msg>Fixed async script executing<commit_after>(function waitForJQuery(){
    if(!window.jQuery) setTimeout(waitForJQuery, 10); else document.dispatchEvent(new Event('jQuery loaded', {}));
})();
document.addEventListener('jQuery loaded', function(){
    'use strict';
    (function a(){
        $.get('https://api.github.com/repos/KaMeHb-UA/LeNode/releases/latest', function(data, status){
            if (status != 'success') a(); else {
                $('a[rel="download"]').attr('href', data.assets[0].browser_download_url);
                $('#latest-version').html(data.tag_name);
                $('*[rel="release-description"]').html(data.name);
            }
        }, 'json');
    })();
    (function(){
        var actions = {
            log : function(){
                console.log.apply(null, arguments);
                console.log(this);
            },
            hide : function(){
                this.css('display', 'none')
            },
            detach : function(){
                this.detach(arguments ? arguments[0] : undefined)
            },
            remove : function(){
                this.remove(arguments ? arguments[0] : undefined)
            }
        };
        $('*[__click]').each(function(i,e){
            var e = $(e);
            e.click(function(){
                try{
                    actions[e.attr('__click')].apply(e, (function(a){
                        if (a){
                            try{
                                return JSON.parse(a);
                            } catch(e){
                                return [a];
                            }
                        } else return [];
                    })(e.attr('__click_data')));
                } catch(err){
                    console.warn('Cannot find action ' + e.attr('__click'));
                }
            });
        });
    })();
});
<|endoftext|>


<commit_before>function getEmoji(msg, emojiname) {
  let guildEmoji = msg.guild.emojis.array();
  for (let i = 0; i < guildEmoji.length; i++) {
    if (guildEmoji[i].name == emojiname) {
      return guildEmoji[i].toString;
    }
  }
  return "";
}

function getAllEmoji(guild) {
  let ret = {};
  let gem = guild.emojis.array();
  for (let i = 0; i < gem.length; i++) {
    ret[gem[i].name] = gem[i];
  }
  return ret;
}

function hascmd(msg, cmd) {
  console.log(msg.substring(0, "!" + cmd + " ".length).toLowerCase());
  console.log("!" + cmd + " ");
  return msg.substring(0, "!" + cmd + " ".length).toLowerCase() === "!" + cmd + " ";
}

module.exports = {
  getEmoji,
  getAllEmoji,
  hascmd
}<commit_msg>fixing it with the actual correct changes<commit_after>function getEmoji(msg, emojiname) {
  let guildEmoji = msg.guild.emojis.array();
  for (let i = 0; i < guildEmoji.length; i++) {
    if (guildEmoji[i].name == emojiname) {
      return guildEmoji[i].toString;
    }
  }
  return "";
}

function getAllEmoji(guild) {
  let ret = {};
  let gem = guild.emojis.array();
  for (let i = 0; i < gem.length; i++) {
    ret[gem[i].name] = gem[i];
  }
  return ret;
}

function hascmd(msg, cmd) {
  return msg.substring(0, ("!" + cmd + " ").length).toLowerCase() === "!" + cmd + " ";
}

module.exports = {
  getEmoji,
  getAllEmoji,
  hascmd
}<|endoftext|>


<commit_before>angular.module('app.newsmute', ['ionic', 'ionic.service.core', 'app.controllers', 'app.factory', 'app.feedurls', 'app.iso3116CountryCodes', 'app.services', 'ngCordova'])

    .run(function ($ionicPlatform, $rootScope, $ionicLoading, $timeout) {
        $ionicPlatform.ready(function () {

            //Show loading
            $rootScope.$on('loading:show', function () {
                $ionicLoading.show(
                    {
                        template: '
Control your news!
<ion-spinner icon="lines"></ion-spinner>

Touch to read or Swipe Right to ignore
Loading, please wait'
                    }
                )
            });
            //Hide loading
            $rootScope.$on('loading:hide', function () {
                $ionicLoading.hide()
            });

            //Show loading
            $rootScope.$on('error:show', function (event, error) {
                var errorString = error.toString().substring(0, 10);

                $ionicLoading.show(
                    {
                        template: '
An error occured
<ion-spinner icon="lines"></ion-spinner>
' + errorString
                    }
                );

                $timeout(function () {
                    $ionicLoading.hide();
                }, 3000);

            });

            //Show loading
            $rootScope.$on('info:show', function (event, args) {
                $ionicLoading.show(
                    {
                        template: '
' + args.message + '
   '
                    }
                );

                $timeout(function () {
                    $ionicLoading.hide();
                }, 3000);
            });

        });
    })

    .config(function ($httpProvider, $ionicConfigProvider) {
        $ionicConfigProvider.platform.android.views.maxCache(5);
    })

    .config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider

            .state('login', {
                url: "/login",
                templateUrl: "templates/login.html",
                controller: 'LoginCtrl'
            })

            .state('app', {
                url: "/app",
                abstract: true,
                templateUrl: "templates/menu.html",
                controller: 'AppCtrl'
            })

            .state('app.news', {
                url: "/news",
                views: {
                    'menuContent': {
                        templateUrl: "templates/news.html",
                        controller: 'NewsCtrl'
                    }
                }
            })

            .state('app.directory', {
                url: "/directory",
                views: {
                    'menuContent': {
                        templateUrl: "templates/directory.html",
                        controller: 'DirectoryCtrl'
                    }
                }
            });

        $urlRouterProvider.otherwise('/login');
    })
;
<commit_msg>Loader tweak<commit_after>angular.module('app.newsmute', ['ionic', 'ionic.service.core', 'app.controllers', 'app.factory', 'app.feedurls', 'app.iso3116CountryCodes', 'app.services', 'ngCordova'])

    .run(function ($ionicPlatform, $rootScope, $ionicLoading, $timeout) {
        $ionicPlatform.ready(function () {

            //Show loading
            $rootScope.$on('loading:show', function () {
                $ionicLoading.show(
                    {
                        template: '
Control your news!
Touch to read or Swipe Right to ignore
<ion-spinner icon="lines"></ion-spinner>
Loading, please wait'
                    }
                )
            });
            //Hide loading
            $rootScope.$on('loading:hide', function () {
                $ionicLoading.hide()
            });

            //Show loading
            $rootScope.$on('error:show', function (event, error) {
                var errorString = error.toString().substring(0, 10);

                $ionicLoading.show(
                    {
                        template: '
An error occured
<ion-spinner icon="lines"></ion-spinner>
' + errorString
                    }
                );

                $timeout(function () {
                    $ionicLoading.hide();
                }, 3000);

            });

            //Show loading
            $rootScope.$on('info:show', function (event, args) {
                $ionicLoading.show(
                    {
                        template: '
' + args.message + '
   '
                    }
                );

                $timeout(function () {
                    $ionicLoading.hide();
                }, 3000);
            });

        });
    })

    .config(function ($httpProvider, $ionicConfigProvider) {
        $ionicConfigProvider.platform.android.views.maxCache(5);
    })

    .config(function ($stateProvider, $urlRouterProvider) {
        $stateProvider

            .state('login', {
                url: "/login",
                templateUrl: "templates/login.html",
                controller: 'LoginCtrl'
            })

            .state('app', {
                url: "/app",
                abstract: true,
                templateUrl: "templates/menu.html",
                controller: 'AppCtrl'
            })

            .state('app.news', {
                url: "/news",
                views: {
                    'menuContent': {
                        templateUrl: "templates/news.html",
                        controller: 'NewsCtrl'
                    }
                }
            })

            .state('app.directory', {
                url: "/directory",
                views: {
                    'menuContent': {
                        templateUrl: "templates/directory.html",
                        controller: 'DirectoryCtrl'
                    }
                }
            });

        $urlRouterProvider.otherwise('/login');
    })
;
<|endoftext|>


<commit_before>var cp = require('child_process'),
    os = require('os'),
    fs = require('fs'),
    shellwords = require('shellwords'),
    semver = require('semver'),
    clone = require('clone');

var escapeQuotes = function (str) {
  if (typeof str === 'string') {
    return str.replace(/(["$`\\])/g, '\\$1');
  } else {
    return str;
  }
};

var inArray = function (arr, val) {
  for(var i = 0; i < arr.length; i++) {
    if (arr[i] === val) {
      return true;
    }
  }
  return false;
};

var notifySendFlags = {
  "u":            "urgency",
  "urgency":      "urgency",
  "t":            "expire-time",
  "e":            "expire-time",
  "expire":       "expire-time",
  "expire-time":  "expire-time",
  "i":            "icon",
  "icon":         "icon",
  "c":            "category",
  "category":     "category",
  "h":            "hint",
  "hint":         "hint"
};

module.exports.command = function (notifier, options, cb) {
  var notifier = shellwords.escape(notifier);
  return cp.exec(notifier + ' ' + options.join(' '), function (error, stdout, stderr) {
    if (error) return cb(error);
    cb(stderr, stdout);
  });
};

module.exports.fileCommand = function (notifier, options, cb) {
  return cp.execFile(notifier, options, function (error, stdout, stderr) {
    if (error) return cb(error, stdout);
    cb(stderr, stdout);
  });
};

module.exports.immediateFileCommand = function (notifier, options, cb) {
  notifierExists(notifier, function (exists) {
    if (!exists) return cb(new Error('Notifier (' + notifier + ') not found on system.'));
    cp.execFile(notifier, options);
    cb();
  });
};

function notifierExists (notifier, cb) {
  return fs.stat(notifier, function (err, stat) {
    if (err) return cb(false);
    cb(stat.isFile());
  });
}

var mapAppIcon = function (options) {
  if (options.appIcon) {
    options.icon = options.appIcon;
    delete options.appIcon;
  }

  return options;
};

var mapText = function (options) {
  if (options.text) {
    options.message = options.text;
    delete options.text;
  }

  return options;
};

var mapIconShorthand = function (options) {
  if (options.i) {
    options.icon = options.i;
    delete options.i;
  }

  return options;
};

module.exports.mapToNotifySend = function (options) {
  options = mapAppIcon(options);
  options = mapText(options);

  for (var key in options) {
    if (key === "message" || key === "title") continue;
    if (options.hasOwnProperty(key) && (notifySendFlags[key] != key)) {
      options[notifySendFlags[key]] = options[key];
      delete options[key];
    }
  }

  return options;
};

module.exports.mapToGrowl = function (options) {
  options = mapAppIcon(options);
  options = mapIconShorthand(options);

  if (options.text) {
    options.message = options.text;
    delete options.text;
  }

  if (options.icon && !Buffer.isBuffer(options.icon)) {
    options.icon = fs.readFileSync(options.icon);
  }

  return options;
};

module.exports.mapToMac = function (options) {
  options = mapIconShorthand(options);
  options = mapText(options);

  if (options.icon) {
    options.appIcon = options.icon;
    delete options.icon;
  }

  if (options.sound === true) {
    options.sound = 'Bottle';
  }

  return options;
};

module.exports.actionJackerDecorator = function (emitter, options, fn, mapper) {
  options = clone(options);
  fn = fn || function (err, data) {};
  return function (err, data) {
    fn.apply(emitter, [err, data]);
    if (err || !mapper || !data) return;

    var key = mapper(data);
    if (!key) return;
    emitter.emit(key, emitter, options);
  };
};

module.exports.constructArgumentList = function (options, extra) {
  var args = [];
  extra = extra || {};

  // Massive ugly setup. Default args
  var initial = extra.initial || [];
  var keyExtra = extra.keyExtra || "";
  var allowedArguments = extra.allowedArguments || [];
  var noEscape = extra.noEscape !== void 0;
  var checkForAllowed = extra.allowedArguments !== void 0;
  var wrapper = extra.wrapper === void 0 ? '"' : extra.wrapper;

  var escapeFn = noEscape ? function (i) { return i; } : escapeQuotes;

  initial.forEach(function (val) {
    args.push(wrapper + escapeFn(val) + wrapper);
  });
  for(var key in options) {
    if (options.hasOwnProperty(key) && (!checkForAllowed || inArray(allowedArguments, key))) {
      args.push('-' + keyExtra + key, wrapper + escapeFn(options[key]) + wrapper);
    }
  }
  return args;
};

module.exports.mapToWin8 = function (options){

  options = mapAppIcon(options);
  options = mapText(options);

  if(options.icon){
    options.p = options.icon;
    delete options.icon;
  }

  if(options.message){
    options.m = options.message;
    delete options.message;
  }

  if (options.title) {
    options.t = options.title;
    delete options.title;
  }

  if (options.quiet || options.silent) {
    options.q = options.quiet || options.silent;
    delete options.quiet;
    delete options.silent;
  }

  if (options.q !== false) {
    options.q = true;
  } else {
    delete options.q;
  }

  if (options.sound) {
    delete options.q;
    delete options.sound;
  }

  if (options.wait) {
    options.w = options.wait;
    delete options.wait;
  }

  return options;
};

module.exports.mapToNotifu = function (options) {
  options = mapAppIcon(options);
  options = mapText(options);

  if(options.icon){
    options.i = options.icon;
    delete options.icon;
  }

  if(options.message){
    options.m = options.message;
    delete options.message;
  }

  if (options.title) {
    options.p = options.title;
    delete options.title;
  }

  if (options.time) {
    options.d = options.time;
    delete options.time;
  }

  if (options.t) {
    options.d = options.t;
    delete options.t;
  }

  return options;
};

module.exports.isMac = function() {
  return os.type() === 'Darwin';
};

module.exports.isMountainLion = function() {
  return os.type() === 'Darwin' && semver.satisfies(garanteeSemverFormat(os.release()), '>=12.0.0');
};

module.exports.isWin8 = function() {
  return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '>=6.2.9200');
};

module.exports.isLessThanWin8 = function() {
  return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '<6.2.9200');
};

function garanteeSemverFormat (version) {
  if (version.split('.').length === 2) {
    version += '.0';
  }
  return version;
}
<commit_msg>Adds possibility of removing sound from Notification Center<commit_after>var cp = require('child_process'),
    os = require('os'),
    fs = require('fs'),
    shellwords = require('shellwords'),
    semver = require('semver'),
    clone = require('clone');

var escapeQuotes = function (str) {
  if (typeof str === 'string') {
    return str.replace(/(["$`\\])/g, '\\$1');
  } else {
    return str;
  }
};

var inArray = function (arr, val) {
  for(var i = 0; i < arr.length; i++) {
    if (arr[i] === val) {
      return true;
    }
  }
  return false;
};

var notifySendFlags = {
  "u":            "urgency",
  "urgency":      "urgency",
  "t":            "expire-time",
  "e":            "expire-time",
  "expire":       "expire-time",
  "expire-time":  "expire-time",
  "i":            "icon",
  "icon":         "icon",
  "c":            "category",
  "category":     "category",
  "h":            "hint",
  "hint":         "hint"
};

module.exports.command = function (notifier, options, cb) {
  var notifier = shellwords.escape(notifier);
  return cp.exec(notifier + ' ' + options.join(' '), function (error, stdout, stderr) {
    if (error) return cb(error);
    cb(stderr, stdout);
  });
};

module.exports.fileCommand = function (notifier, options, cb) {
  return cp.execFile(notifier, options, function (error, stdout, stderr) {
    if (error) return cb(error, stdout);
    cb(stderr, stdout);
  });
};

module.exports.immediateFileCommand = function (notifier, options, cb) {
  notifierExists(notifier, function (exists) {
    if (!exists) return cb(new Error('Notifier (' + notifier + ') not found on system.'));
    cp.execFile(notifier, options);
    cb();
  });
};

function notifierExists (notifier, cb) {
  return fs.stat(notifier, function (err, stat) {
    if (err) return cb(false);
    cb(stat.isFile());
  });
}

var mapAppIcon = function (options) {
  if (options.appIcon) {
    options.icon = options.appIcon;
    delete options.appIcon;
  }

  return options;
};

var mapText = function (options) {
  if (options.text) {
    options.message = options.text;
    delete options.text;
  }

  return options;
};

var mapIconShorthand = function (options) {
  if (options.i) {
    options.icon = options.i;
    delete options.i;
  }

  return options;
};

module.exports.mapToNotifySend = function (options) {
  options = mapAppIcon(options);
  options = mapText(options);

  for (var key in options) {
    if (key === "message" || key === "title") continue;
    if (options.hasOwnProperty(key) && (notifySendFlags[key] != key)) {
      options[notifySendFlags[key]] = options[key];
      delete options[key];
    }
  }

  return options;
};

module.exports.mapToGrowl = function (options) {
  options = mapAppIcon(options);
  options = mapIconShorthand(options);

  if (options.text) {
    options.message = options.text;
    delete options.text;
  }

  if (options.icon && !Buffer.isBuffer(options.icon)) {
    options.icon = fs.readFileSync(options.icon);
  }

  return options;
};

module.exports.mapToMac = function (options) {
  options = mapIconShorthand(options);
  options = mapText(options);

  if (options.icon) {
    options.appIcon = options.icon;
    delete options.icon;
  }

  if (options.sound === true) {
    options.sound = 'Bottle';
  }

  if (options.sound === false) {
    delete options.sound;
  }

  return options;
};

module.exports.actionJackerDecorator = function (emitter, options, fn, mapper) {
  options = clone(options);
  fn = fn || function (err, data) {};
  return function (err, data) {
    fn.apply(emitter, [err, data]);
    if (err || !mapper || !data) return;

    var key = mapper(data);
    if (!key) return;
    emitter.emit(key, emitter, options);
  };
};

module.exports.constructArgumentList = function (options, extra) {
  var args = [];
  extra = extra || {};

  // Massive ugly setup. Default args
  var initial = extra.initial || [];
  var keyExtra = extra.keyExtra || "";
  var allowedArguments = extra.allowedArguments || [];
  var noEscape = extra.noEscape !== void 0;
  var checkForAllowed = extra.allowedArguments !== void 0;
  var wrapper = extra.wrapper === void 0 ? '"' : extra.wrapper;

  var escapeFn = noEscape ? function (i) { return i; } : escapeQuotes;

  initial.forEach(function (val) {
    args.push(wrapper + escapeFn(val) + wrapper);
  });
  for(var key in options) {
    if (options.hasOwnProperty(key) && (!checkForAllowed || inArray(allowedArguments, key))) {
      args.push('-' + keyExtra + key, wrapper + escapeFn(options[key]) + wrapper);
    }
  }
  return args;
};

module.exports.mapToWin8 = function (options){

  options = mapAppIcon(options);
  options = mapText(options);

  if(options.icon){
    options.p = options.icon;
    delete options.icon;
  }

  if(options.message){
    options.m = options.message;
    delete options.message;
  }

  if (options.title) {
    options.t = options.title;
    delete options.title;
  }

  if (options.quiet || options.silent) {
    options.q = options.quiet || options.silent;
    delete options.quiet;
    delete options.silent;
  }

  if (options.q !== false) {
    options.q = true;
  } else {
    delete options.q;
  }

  if (options.sound) {
    delete options.q;
    delete options.sound;
  }

  if (options.wait) {
    options.w = options.wait;
    delete options.wait;
  }

  return options;
};

module.exports.mapToNotifu = function (options) {
  options = mapAppIcon(options);
  options = mapText(options);

  if(options.icon){
    options.i = options.icon;
    delete options.icon;
  }

  if(options.message){
    options.m = options.message;
    delete options.message;
  }

  if (options.title) {
    options.p = options.title;
    delete options.title;
  }

  if (options.time) {
    options.d = options.time;
    delete options.time;
  }

  if (options.t) {
    options.d = options.t;
    delete options.t;
  }

  return options;
};

module.exports.isMac = function() {
  return os.type() === 'Darwin';
};

module.exports.isMountainLion = function() {
  return os.type() === 'Darwin' && semver.satisfies(garanteeSemverFormat(os.release()), '>=12.0.0');
};

module.exports.isWin8 = function() {
  return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '>=6.2.9200');
};

module.exports.isLessThanWin8 = function() {
  return os.type() === 'Windows_NT' && semver.satisfies(garanteeSemverFormat(os.release()), '<6.2.9200');
};

function garanteeSemverFormat (version) {
  if (version.split('.').length === 2) {
    version += '.0';
  }
  return version;
}
<|endoftext|>


<commit_before>var angularjsx = require("../index.js");
var assert = require("assert");

describe("angularjsx", function () {
    it("should not touch empty object", function () {
        assert.equal(angularjsx.convert("var x = {}"), "var x = {}");
    });
    it("should not touch object with properties", function () {
        assert.equal(angularjsx.convert("var x = {a: 1}"), "var x = {a: 1}");
    });
    it("should convert simple JSX template", function () {
        assert.equal(angularjsx.convert("var x = {template:

}"), "var x = {template: \"

\"}");
    });
    it("should convert multi-line JSX template", function () {
        assert.equal(angularjsx.convert("var x = {template:
\n
}"), "var x = {template: \"
\\n
\"}");
    });
    it("should convert JSX with quotes", function () {
        assert.equal(angularjsx.convert("var x = {template:

}"), "var x = {template: \"

\"}");
    });
    it("should ignore non-JSX templates", function () {
        //TODO: \r\n on Windows only? Test on Linux.
        assert.equal(angularjsx.convert("var x = {template: {\n}}"), "var x = {template: {\r\n}}");
    });
});<commit_msg>Failing test for template with dots<commit_after>var angularjsx = require("../index.js");
var assert = require("assert");

describe("angularjsx", function () {
    it("should not touch empty object", function () {
        assert.equal(angularjsx.convert("var x = {}"), "var x = {}");
    });
    it("should not touch object with properties", function () {
        assert.equal(angularjsx.convert("var x = {a: 1}"), "var x = {a: 1}");
    });
    it("should convert simple JSX template", function () {
        assert.equal(angularjsx.convert("var x = {template:

}"), "var x = {template: \"

\"}");
    });
    it("should convert multi-line JSX template", function () {
        assert.equal(angularjsx.convert("var x = {template:
\n
}"), "var x = {template: \"
\\n
\"}");
    });
    it("should convert JSX with quotes", function () {
        assert.equal(angularjsx.convert("var x = {template:

}"), "var x = {template: \"

\"}");
    });
    it("should ignore non-JSX templates", function () {
        //TODO: \r\n on Windows only? Test on Linux.
        assert.equal(angularjsx.convert("var x = {template: {\n}}"), "var x = {template: {\r\n}}");
    });
    it("should handle dots in span", function () {
        assert.equal(angularjsx.convert("var x = {template: {{a.b}}}"), "var x = {template: \"{{a.b}}\"}");
    });
});<|endoftext|>


<commit_before>var urlBase = "";
if (window != null && window.os_map_base !== undefined) {
	urlBase = window.os_map_base;
}

var versions = {
	leaflet: 'v0.7.7',
	leaflet_bing: '1.6.0',
	proj4: '2.3.14',
	leaflet_cluster: '232e93ccbe5b70241913f47a4d1a8ceec8c88c30',
	leaflet_mouseposition: 'b628c7be754c134c63117b3feb75e720a1d20673',
	leaflet_screenposition: 'cc990a672930886aaef55b1a66e651bdaaf27353',
	leaflet_subgroup: 'e675f5736513ec6f9a8ab391965808b192990e9e',
	leaflet_matrixlayers: '0f164741adceb211abac6c913882290ddd417d9c',
	leaflet_locate: '0.52.0',
	jquery: '3.0.0',
	Squire: '0.2.1',
	sinon: '1.17.5'
};

var paths = {
	leaflet: 'http://cdn.leafletjs.com/leaflet/' + versions.leaflet + '/leaflet',
	leaflet_bing: 'http://cdnjs.cloudflare.com/ajax/libs/leaflet-plugins/' + versions.leaflet_bing + '/layer/tile/Bing',
	proj4: 'http://cdnjs.cloudflare.com/ajax/libs/proj4js/' + versions.proj4 + '/proj4',
	leaflet_cluster: 'https://cdn.rawgit.com/Leaflet/Leaflet.markercluster/' + versions.leaflet_cluster + '/dist/leaflet.markercluster-src',
	leaflet_mouseposition: 'https://cdn.rawgit.com/tstibbs/Leaflet.MousePosition/' + versions.leaflet_mouseposition + '/src/L.Control.MousePosition',
	leaflet_screenposition: 'https://cdn.rawgit.com/tstibbs/Leaflet.MapCenterCoord/' + versions.leaflet_screenposition + '/src/L.Control.MapCenterCoord',
	leaflet_subgroup: 'https://cdn.rawgit.com/ghybs/Leaflet.FeatureGroup.SubGroup/' + versions.leaflet_subgroup + '/leaflet.featuregroup.subgroup-src',
	leaflet_matrixlayers: 'https://cdn.rawgit.com/tstibbs/Leaflet.MatrixLayersControl/' + versions.leaflet_matrixlayers + '/src/matrixControl',
	leaflet_locate: 'https://cdn.jsdelivr.net/leaflet.locatecontrol/' + versions.leaflet_locate + '/L.Control.Locate.min',
	jquery: 'https://code.jquery.com/jquery-' + versions.jquery
}

var testingPaths = {
	Squire: 'https://unpkg.com/squirejs@' + versions.Squire + '/src/Squire',
	sinon: 'https://unpkg.com/sinon@' + versions.sinon + '/pkg/sinon'
}

if (window.location.search.indexOf("dev=true") !== -1) {
	paths.leaflet = paths.leaflet + '-src';
	paths.leaflet_matrixlayers = '../../Leaflet.MatrixLayersControl/src/matrixControl';
}

requirejs.config({
    baseUrl: urlBase + "js",
    paths: paths,
    shim: {
        leaflet: {
            exports: 'L'
        },
        leaflet_bing: {
            deps: ['leaflet'],
            exports: 'L.BingLayer'
        },
        leaflet_mouseposition: {
            deps: ['leaflet'],
            exports: 'L.Control.MousePosition'
        },
        leaflet_screenposition: {
            deps: ['leaflet'],
            exports: 'L.Control.MapCenterCoord'
        },
        leaflet_cluster: {
            deps: ['leaflet'],
            exports: 'L.markerClusterGroup'
        },
        leaflet_subgroup: {
            deps: ['leaflet'],
            exports: 'L.featureGroup.subGroup'
        },
        leaflet_matrixlayers: {
            deps: ['leaflet'],
            exports: 'L.Control.MatrixLayers'
        },
        leaflet_locate: {
            deps: ['leaflet'],
            exports: 'L.control.locate'
        },
        proj4js: {
            exports: 'module.exports'
        }
    }
});
<commit_msg>Removing shims for modules that are already AMD-compatible<commit_after>var urlBase = "";
if (window != null && window.os_map_base !== undefined) {
	urlBase = window.os_map_base;
}

var versions = {
	leaflet: 'v0.7.7',
	leaflet_bing: '1.6.0',
	proj4: '2.3.14',
	leaflet_cluster: '232e93ccbe5b70241913f47a4d1a8ceec8c88c30',
	leaflet_mouseposition: 'b628c7be754c134c63117b3feb75e720a1d20673',
	leaflet_screenposition: 'cc990a672930886aaef55b1a66e651bdaaf27353',
	leaflet_subgroup: 'e675f5736513ec6f9a8ab391965808b192990e9e',
	leaflet_matrixlayers: '8638fae333195849977fc0dd7f94de7d23e804cf',
	leaflet_locate: '0.52.0',
	jquery: '3.0.0',
	Squire: '0.2.1',
	sinon: '1.17.5'
};

var paths = {
	leaflet: 'http://cdn.leafletjs.com/leaflet/' + versions.leaflet + '/leaflet',
	leaflet_bing: 'http://cdnjs.cloudflare.com/ajax/libs/leaflet-plugins/' + versions.leaflet_bing + '/layer/tile/Bing',
	proj4: 'http://cdnjs.cloudflare.com/ajax/libs/proj4js/' + versions.proj4 + '/proj4',
	leaflet_cluster: 'https://cdn.rawgit.com/Leaflet/Leaflet.markercluster/' + versions.leaflet_cluster + '/dist/leaflet.markercluster-src',
	leaflet_mouseposition: 'https://cdn.rawgit.com/tstibbs/Leaflet.MousePosition/' + versions.leaflet_mouseposition + '/src/L.Control.MousePosition',
	leaflet_screenposition: 'https://cdn.rawgit.com/tstibbs/Leaflet.MapCenterCoord/' + versions.leaflet_screenposition + '/src/L.Control.MapCenterCoord',
	leaflet_subgroup: 'https://cdn.rawgit.com/ghybs/Leaflet.FeatureGroup.SubGroup/' + versions.leaflet_subgroup + '/leaflet.featuregroup.subgroup-src',
	leaflet_matrixlayers: 'https://cdn.rawgit.com/tstibbs/Leaflet.MatrixLayersControl/' + versions.leaflet_matrixlayers + '/src/matrixControl',
	leaflet_locate: 'https://cdn.jsdelivr.net/leaflet.locatecontrol/' + versions.leaflet_locate + '/L.Control.Locate.min',
	jquery: 'https://code.jquery.com/jquery-' + versions.jquery
}

var testingPaths = {
	Squire: 'https://unpkg.com/squirejs@' + versions.Squire + '/src/Squire',
	sinon: 'https://unpkg.com/sinon@' + versions.sinon + '/pkg/sinon'
}

if (window.location.search.indexOf("dev=true") !== -1) {
	paths.leaflet = paths.leaflet + '-src';
	paths.leaflet_matrixlayers = '../../Leaflet.MatrixLayersControl/src/matrixControl';
}

requirejs.config({
    baseUrl: urlBase + "js",
    paths: paths,
    shim: {
        leaflet_bing: {
            deps: ['leaflet'],
            exports: 'L.BingLayer'
        },
        leaflet_mouseposition: {
            deps: ['leaflet'],
            exports: 'L.Control.MousePosition'
        },
        leaflet_screenposition: {
            deps: ['leaflet'],
            exports: 'L.Control.MapCenterCoord'
        },
        leaflet_cluster: {
            deps: ['leaflet'],
            exports: 'L.markerClusterGroup'
        },
        leaflet_locate: {
            deps: ['leaflet'],
            exports: 'L.control.locate'
        },
        proj4js: {
            exports: 'module.exports'
        }
    }
});
<|endoftext|>


<commit_before>// Woodlot utility library

var DEFAULT_JSON_SPACING = '\t';

// Function to get log format based on Woodlot config setup
function getLogFormat(options) {
	if(options.format && options.format.type) {
		return options.format.type.toUpperCase();
	}
	return 'JSON';
};

// Function to get JSON format spacing value
function getFormatSpacing(options) {
	var format = getLogFormat(options);

	// Get format spacing only for JSON type
	if(format === 'JSON') {
		if(options.format && options.format.spacing) {
			var spacing = parseInt(options.format.spacing, 10);
			if(isNaN(spacing)) {
				return options.format.spacing;
			}
			return spacing;
		}
		return  DEFAULT_JSON_SPACING;
	}
	return null;
};

// Function that stringifies a log based on its format
function stringifyLog(log, format, spacing) {
	spacing = spacing || DEFAULT_JSON_SPACING;

	switch(format.toLowerCase()) {
		case 'combined':
		case 'common':

			return log;

		case 'json':
		default:

			return JSON.stringify(log, null, spacing);
	}
};

module.exports = {
	getLogFormat: getLogFormat,
	getFormatSpacing: getFormatSpacing,
	stringifyLog: stringifyLog
};<commit_msg>Format spacing option check - bug fix<commit_after>// Woodlot utility library

var DEFAULT_JSON_SPACING = '\t';

// Function to get log format based on Woodlot config setup
function getLogFormat(options) {
	if(options.format && options.format.type) {
		return options.format.type.toUpperCase();
	}
	return 'JSON';
};

// Function to get JSON format spacing value
function getFormatSpacing(options) {
	var format = getLogFormat(options);

	// Get format spacing only for JSON type
	if(format === 'JSON') {
		if(options.format && ('spacing' in options.format)) {
			var spacing = parseInt(options.format.spacing, 10);

			if(isNaN(spacing)) {
				return options.format.spacing;
			}

			return spacing;
		}
		return  DEFAULT_JSON_SPACING;
	}
	return null;
};

// Function that stringifies a log based on its format
function stringifyLog(log, format, spacing) {
	spacing = spacing || DEFAULT_JSON_SPACING;

	switch(format.toLowerCase()) {
		case 'combined':
		case 'common':

			return log;

		case 'json':
		default:

			return JSON.stringify(log, null, spacing);
	}
};

module.exports = {
	getLogFormat: getLogFormat,
	getFormatSpacing: getFormatSpacing,
	stringifyLog: stringifyLog
};<|endoftext|>


<commit_before>OV.GetTriangleArea = function (v0, v1, v2)
{
    const a = OV.CoordDistance3D (v0, v1);
    const b = OV.CoordDistance3D (v1, v2);
    const c = OV.CoordDistance3D (v0, v2);
    const s = (a + b + c) / 2.0;
    const areaSquare = s * (s - a) * (s - b) * (s - c);
    if (areaSquare < 0.0) {
        return 0.0;
    }
    return Math.sqrt (areaSquare);
};

OV.GetTriangleSignedVolume = function (v0, v1, v2)
{
    return OV.DotVector3D (v0, OV.CrossVector3D (v1, v2)) / 6.0;
};

OV.CalculateModelVolume = function (model)
{
    if (!OV.IsModelSolid (model)) {
        return null;
    }
    let volume = 0.0;
    OV.EnumerateModelTriangles (model, function (v0, v1, v2) {
        volume += OV.GetTriangleSignedVolume (v0, v1, v2);
    });
    return volume;
};

OV.CalculateModelSurfaceArea = function (model)
{
    let surface = 0.0;
    OV.EnumerateModelTriangles (model, function (v0, v1, v2) {
        surface += OV.GetTriangleArea (v0, v1, v2);
    });
    return surface;
};
<commit_msg>Minor modification.<commit_after>OV.GetTriangleArea = function (v0, v1, v2)
{
    const a = OV.CoordDistance3D (v0, v1);
    const b = OV.CoordDistance3D (v1, v2);
    const c = OV.CoordDistance3D (v0, v2);
    const s = (a + b + c) / 2.0;
    const areaSquare = s * (s - a) * (s - b) * (s - c);
    if (areaSquare < 0.0) {
        return 0.0;
    }
    return Math.sqrt (areaSquare);
};

OV.GetTetrahedronSignedVolume = function (v0, v1, v2)
{
    return OV.DotVector3D (v0, OV.CrossVector3D (v1, v2)) / 6.0;
};

OV.CalculateModelVolume = function (model)
{
    if (!OV.IsModelSolid (model)) {
        return null;
    }
    let volume = 0.0;
    OV.EnumerateModelTriangles (model, function (v0, v1, v2) {
        volume += OV.GetTetrahedronSignedVolume (v0, v1, v2);
    });
    return volume;
};

OV.CalculateModelSurfaceArea = function (model)
{
    let surface = 0.0;
    OV.EnumerateModelTriangles (model, function (v0, v1, v2) {
        surface += OV.GetTriangleArea (v0, v1, v2);
    });
    return surface;
};
<|endoftext|>


<commit_before>'use strict';

var BinBuild = require('../');
var Decompress = require('decompress');
var fs = require('fs');
var nock = require('nock');
var path = require('path');
var fixture = path.join.bind(null, __dirname, 'fixtures');
var rm = require('rimraf');
var test = require('ava');

test('expose a constructor', function (t) {
	t.plan(1);
	t.assert(typeof BinBuild === 'function');
});

test('set source file', function (t) {
	t.plan(1);

	var build = new BinBuild()
		.src('src.tar.gz');

	t.assert(build._src === 'src.tar.gz');
});

test('add commands to run', function (t) {
	t.plan(2);

	var build = new BinBuild()
		.cmd('make')
		.cmd('make install');

	t.assert(build._cmd[0] === 'make');
	t.assert(build._cmd[1] === 'make install');
});

test('download and build source', function (t) {
	t.plan(2);

	nock('http://foo.com')
		.get('/gifsicle.tar.gz')
		.replyWithFile(200, fixture('test.tar.gz'));

	var tmp = path.join(__dirname, 'tmp');
	var cmd = [
		'./configure --disable-gifview --disable-gifdiff',
		'--prefix="' + tmp + '" --bindir="' + tmp + '"'
	].join(' ');

	var build = new BinBuild()
		.src('http://foo.com/gifsicle.tar.gz')
		.cmd('autoreconf -ivf')
		.cmd(cmd)
		.cmd('make install');

	build.run(function (err) {
		t.assert(!err, err);

		fs.exists(path.join(tmp, 'gifsicle'), function (exists) {
			t.assert(exists);
		});
	});
});

test('build source from existing archive', function (t) {
	t.plan(2);

	var tmp = path.join(__dirname, 'tmp');
	var cmd = [
		'./configure --disable-gifview --disable-gifdiff',
		'--prefix="' + tmp + '" --bindir="' + tmp + '"'
	].join(' ');

	var build = new BinBuild()
		.src(fixture('test.tar.gz'))
		.cmd('autoreconf -ivf')
		.cmd(cmd)
		.cmd('make install');

	build.run(function (err) {
		t.assert(!err, err);

		fs.exists(path.join(tmp, 'gifsicle'), function (exists) {
			t.assert(exists);
		});
	});
});

test('build source from existing folder', function (t) {
	t.plan(4);

	var decompress = new Decompress({
		mode: '777',
		strip: 1
	});

	decompress.src(fixture('test.tar.gz'));
	decompress.dest(fixture('test-directory'));
	decompress.run(function (err) {
		t.assert(!err, err);

		var tmp = path.join(__dirname, 'tmp');
		var cmd = [
			'./configure --disable-gifview --disable-gifdiff',
			'--prefix="' + tmp + '" --bindir="' + tmp + '"'
		].join(' ');

		var build = new BinBuild()
			.src(fixture('test-directory'))
			.cmd('autoreconf -ivf')
			.cmd(cmd)
			.cmd('make install');

		build.run(function (err) {
			t.assert(!err, err);

			fs.exists(path.join(tmp, 'gifsicle'), function (exists) {
				t.assert(exists);

				rm(fixture('test-directory'), function (err) {
					t.assert(!err, err);
				});
			});
		});
	});
});

test('pass the command error to the callback', function (t) {
	t.plan(1);

	nock('http://foo.com')
		.get('/gifsicle.tar.gz')
		.replyWithFile(200, fixture('test.tar.gz'));

	var build = new BinBuild()
		.src('http://foo.com/gifsicle.tar.gz')
		.cmd('autoreconf -ivf')
		.cmd('unknown-command')
		.cmd('./configure')
		.cmd('make install');

	build.run(function (err) {
		t.assert(err);
	});
});
<commit_msg>Small tweaks<commit_after>'use strict';

var BinBuild = require('../');
var Decompress = require('decompress');
var fs = require('fs');
var nock = require('nock');
var path = require('path');
var fixture = path.join.bind(null, __dirname, 'fixtures');
var rm = require('rimraf');
var test = require('ava');

test('expose a constructor', function (t) {
	t.plan(1);
	t.assert(typeof BinBuild === 'function');
});

test('set source file', function (t) {
	t.plan(1);

	var build = new BinBuild()
		.src('src.tar.gz');

	t.assert(build._src === 'src.tar.gz');
});

test('add commands to run', function (t) {
	t.plan(2);

	var build = new BinBuild()
		.cmd('make')
		.cmd('make install');

	t.assert(build._cmd[0] === 'make');
	t.assert(build._cmd[1] === 'make install');
});

test('download and build source', function (t) {
	t.plan(2);

	nock('http://foo.com')
		.get('/gifsicle.tar.gz')
		.replyWithFile(200, fixture('test.tar.gz'));

	var tmp = path.join(__dirname, 'tmp');
	var cmd = [
		'./configure --disable-gifview --disable-gifdiff',
		'--prefix="' + tmp + '" --bindir="' + tmp + '"'
	].join(' ');

	var build = new BinBuild()
		.src('http://foo.com/gifsicle.tar.gz')
		.cmd('autoreconf -ivf')
		.cmd(cmd)
		.cmd('make install');

	build.run(function (err) {
		t.assert(!err, err);
		fs.exists(path.join(tmp, 'gifsicle'), t.assert.bind(t));
	});
});

test('build source from existing archive', function (t) {
	t.plan(2);

	var tmp = path.join(__dirname, 'tmp');
	var cmd = [
		'./configure --disable-gifview --disable-gifdiff',
		'--prefix="' + tmp + '" --bindir="' + tmp + '"'
	].join(' ');

	var build = new BinBuild()
		.src(fixture('test.tar.gz'))
		.cmd('autoreconf -ivf')
		.cmd(cmd)
		.cmd('make install');

	build.run(function (err) {
		t.assert(!err, err);
		fs.exists(path.join(tmp, 'gifsicle'), t.assert.bind(t));
	});
});

test('build source from existing folder', function (t) {
	t.plan(4);

	var decompress = new Decompress({
		mode: '777',
		strip: 1
	});

	decompress.src(fixture('test.tar.gz'));
	decompress.dest(fixture('test-directory'));
	decompress.run(function (err) {
		t.assert(!err, err);

		var tmp = path.join(__dirname, 'tmp');
		var cmd = [
			'./configure --disable-gifview --disable-gifdiff',
			'--prefix="' + tmp + '" --bindir="' + tmp + '"'
		].join(' ');

		var build = new BinBuild()
			.src(fixture('test-directory'))
			.cmd('autoreconf -ivf')
			.cmd(cmd)
			.cmd('make install');

		build.run(function (err) {
			t.assert(!err, err);

			fs.exists(path.join(tmp, 'gifsicle'), function (exists) {
				t.assert(exists);

				rm(fixture('test-directory'), function (err) {
					t.assert(!err, err);
				});
			});
		});
	});
});

test('pass the command error to the callback', function (t) {
	t.plan(1);

	nock('http://foo.com')
		.get('/gifsicle.tar.gz')
		.replyWithFile(200, fixture('test.tar.gz'));

	var build = new BinBuild()
		.src('http://foo.com/gifsicle.tar.gz')
		.cmd('autoreconf -ivf')
		.cmd('unknown-command')
		.cmd('./configure')
		.cmd('make install');

	build.run(t.assert.bind(t));
});
<|endoftext|>


<commit_before>$(document).foundation()

var Pokedex = {

    template: template = $("#li_template")
            .detach()
            .removeAttr("id"),

    addPokemonToList: function(pokemon) {
        var li = this.template.clone().bind(this);
        var list = $("#pokemon_list");
        li.text(pokemon.pokemon_species.name);
        list.append(li);
    },

    loadPokemon: function(pokemon) {
        $.each(pokemon.pokemon_entries, function(i, pokemon) {
            this.addPokemonToList(pokemon);
        }.bind(this));
    },

    getAllPokemon: function() {
        $.get({
            url: this.url,
        }).done(this.loadPokemon.bind(this));
    },

    init: function(url) {
        this.url = url;
        if(!/^.*\/$/.test(url))
            this.url += "/";

        this.getAllPokemon()
    },
};

Pokedex.init("https://pokeapi.co/api/v2/pokedex/2");
<commit_msg>load images with the pokemon names<commit_after>$(document).foundation()

var Pokedex = {

    template: template = $("#li_template")
            .detach()
            .removeAttr("id"),

    addPokemonToList: function(pokemon) {
        var li = this.template.clone().bind(this);
        var list = $("#pokemon_list");
        var icon = li.find(".pokemon-icon");
        icon.attr("src", "http://pokeapi.co/media/sprites/pokemon/" + pokemon.entry_number + ".png");
        li.text(pokemon.pokemon_species.name);
        li.append(icon);
        list.append(li);
    },

    loadPokemon: function(pokemon) {
        $.each(pokemon.pokemon_entries, function(i, pokemon) {
            this.addPokemonToList(pokemon);
        }.bind(this));
    },

    getAllPokemon: function() {
        $.get({
            url: this.url,
        }).done(this.loadPokemon.bind(this));
    },

    init: function(url) {
        this.url = url;
        if(!/^.*\/$/.test(url))
            this.url += "/";

        this.getAllPokemon()
    },
};

Pokedex.init("https://pokeapi.co/api/v2/pokedex/2");
<|endoftext|>