<commit_before>

/**
 * WPCOM module
 */

var WPCOM = require('../');
var Site = require('../lib/site');
var util = require('./util');
var assert = require('assert');
var fs = require('fs');

/**
 * Testing data
 */

var test = require('./data');

/**
 * Create a `Site` instance
 */

describe('WPCOM#Site', function(){

  // Create a new_post before to start the tests
  var new_post;
  before(function(done){
    util.addPost(function(err, post) {
      if (err) return done(err);

      new_post = post;
      done();
    });
  });

  describe('sync', function(){

    it('should be create a site object instance', function(){
      var site = util.public_site();

      assert.ok(site instanceof Site);
      assert.equal(test.site.public.url, site._id);
    });

  });

  describe('async', function(){

    describe('site.get()', function(){
      it('should require site data', function(done){
        var site = util.public_site();

        site.get(function(err, info){
          if (err) throw err;

          assert.equal('number', typeof info.ID);
          assert.equal('string', typeof info.name);

          done();
        });
      });
    });

    describe('site.postsList()', function(){

      it('should request posts list', function(done){
        var site = util.public_site();

        site.postsList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);

          // `posts list` object data testing
          assert.equal('number', typeof list.found);

          assert.equal('object', typeof list.posts);
          assert.ok(list.posts instanceof Array);

          done();
        });
      });

      it('should request only one post', function(done){

        var site = util.public_site();

        site.postsList({ number: 1 }, function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.posts);
          assert.ok(list.posts instanceof Array);
          assert.ok(list.posts.length <= 1);

          done();
        });

      });

    });

    describe('site.mediaList()', function(){

      it('should request media library list', function(done){
        var site = util.private_site();

        site.mediaList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.media);
          assert.ok(list.media instanceof Array);

          done();

        });

      });

    });

    describe('site.usersList()', function(){

      it('should request users list', function(done){
        var site = util.private_site();

        site.usersList(function(err, list){
          if (err) throw err;

          assert.equal('number', typeof list.found);
          assert.ok(list.users instanceof Array);
          done();
        });

      });

    });

    describe('site.commentsList()', function(){

      it('should request comments list', function(done){
        var site = util.private_site();

        site.commentsList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.comments);
          assert.ok(list.comments instanceof Array);

          done();

        });

      });

    });

    describe('site.followsList()', function(){

      it('should request follows list', function(done){
        var site = util.private_site();

        site.followsList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.users);
          assert.ok(list.users instanceof Array);

          done();

        });

      });

    });

    describe('site.addPost()', function(){

      it('should create a new blog post', function(done){
        var site = util.private_site();

        var post = site.addPost(test.new_post_data, function(err, data){
          if (err) throw err;

          assert.equal('object', typeof data);
          assert.equal(test.site.private.id, data.site_ID);

          done();
        });

      });

    });

    describe('site.deletePost()', function(){

      it('should delete a blog post', function(done){

        var site = util.private_site();

        var post = site.deletePost(new_post.ID, function(err, data){

          if (err) throw err;

          assert.equal('object', typeof data);
          assert.equal(test.site.private.id, data.site_ID);
          assert.equal(new_post.ID, data.ID);

          done();

        });

      });

    });

    describe('site.addMediaFiles([fs])', function(){

      it('should create a new media from a file', function(done){
        var site = util.private_site();

        // pass streams
        var files = [];
        //test.new_media_data.files
        for (var i = 0; i < test.new_media_data.files.length; i++) {
          files.push(fs.createReadStream(test.new_media_data.files[i]));
        }

        var media = site.addMediaFiles(files, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.media instanceof Array);
          assert.equal(test.new_media_data.files.length, data.media.length);
          done();
        });

      });

    });

    describe('site.addMediaUrls([\'url1\', \'url2\'])', function(){

      it('should create a new site media', function(done){
        var site = util.private_site();

        var media = site.addMediaUrls(test.new_media_data.media_urls, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.media instanceof Array);
          assert.equal(test.new_media_data.media_urls.length, data.media.length);
          done();
        });

      });

    });

  });

});
<commit_msg>test: add site.categoriesList() test<commit_after>

/**
 * WPCOM module
 */

var WPCOM = require('../');
var Site = require('../lib/site');
var util = require('./util');
var assert = require('assert');
var fs = require('fs');

/**
 * Testing data
 */

var test = require('./data');

/**
 * Create a `Site` instance
 */

describe('WPCOM#Site', function(){

  // Create a new_post before to start the tests
  var new_post;
  before(function(done){
    util.addPost(function(err, post) {
      if (err) return done(err);

      new_post = post;
      done();
    });
  });

  describe('sync', function(){

    it('should be create a site object instance', function(){
      var site = util.public_site();

      assert.ok(site instanceof Site);
      assert.equal(test.site.public.url, site._id);
    });

  });

  describe('async', function(){

    describe('site.get()', function(){
      it('should require site data', function(done){
        var site = util.public_site();

        site.get(function(err, info){
          if (err) throw err;

          assert.equal('number', typeof info.ID);
          assert.equal('string', typeof info.name);

          done();
        });
      });
    });

    describe('site.postsList()', function(){

      it('should request posts list', function(done){
        var site = util.public_site();

        site.postsList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);

          // `posts list` object data testing
          assert.equal('number', typeof list.found);

          assert.equal('object', typeof list.posts);
          assert.ok(list.posts instanceof Array);

          done();
        });
      });

      it('should request only one post', function(done){

        var site = util.public_site();

        site.postsList({ number: 1 }, function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.posts);
          assert.ok(list.posts instanceof Array);
          assert.ok(list.posts.length <= 1);

          done();
        });

      });

    });

    describe('site.mediaList()', function(){

      it('should request media library list', function(done){
        var site = util.private_site();

        site.mediaList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.media);
          assert.ok(list.media instanceof Array);

          done();

        });

      });

    });

    describe('site.usersList()', function(){

      it('should request users list', function(done){
        var site = util.private_site();

        site.usersList(function(err, list){
          if (err) throw err;

          assert.equal('number', typeof list.found);
          assert.ok(list.users instanceof Array);
          done();
        });

      });

    });

    describe('site.commentsList()', function(){

      it('should request comments list', function(done){
        var site = util.private_site();

        site.commentsList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.comments);
          assert.ok(list.comments instanceof Array);

          done();

        });

      });

    });

    describe('site.followsList()', function(){

      it('should request follows list', function(done){
        var site = util.private_site();

        site.followsList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.users);
          assert.ok(list.users instanceof Array);

          done();

        });

      });

    });

    describe('site.categoriesList()', function(){

      it('should request categories list', function(done){
        var site = util.private_site();

        site.categoriesList(function(err, list){
          if (err) throw err;

          // list object data testing
          assert.equal('object', typeof list);
          assert.equal('number', typeof list.found);
          assert.equal('object', typeof list.categories);
          assert.ok(list.categories instanceof Array);

          done();

        });

      });

    });

    describe('site.addPost()', function(){

      it('should create a new blog post', function(done){
        var site = util.private_site();

        var post = site.addPost(test.new_post_data, function(err, data){
          if (err) throw err;

          assert.equal('object', typeof data);
          assert.equal(test.site.private.id, data.site_ID);

          done();
        });

      });

    });

    describe('site.deletePost()', function(){

      it('should delete a blog post', function(done){

        var site = util.private_site();

        var post = site.deletePost(new_post.ID, function(err, data){

          if (err) throw err;

          assert.equal('object', typeof data);
          assert.equal(test.site.private.id, data.site_ID);
          assert.equal(new_post.ID, data.ID);

          done();

        });

      });

    });

    describe('site.addMediaFiles([fs])', function(){

      it('should create a new media from a file', function(done){
        var site = util.private_site();

        // pass streams
        var files = [];
        //test.new_media_data.files
        for (var i = 0; i < test.new_media_data.files.length; i++) {
          files.push(fs.createReadStream(test.new_media_data.files[i]));
        }

        var media = site.addMediaFiles(files, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.media instanceof Array);
          assert.equal(test.new_media_data.files.length, data.media.length);
          done();
        });

      });

    });

    describe('site.addMediaUrls([\'url1\', \'url2\'])', function(){

      it('should create a new site media', function(done){
        var site = util.private_site();

        var media = site.addMediaUrls(test.new_media_data.media_urls, function(err, data){
          if (err) throw err;

          assert.ok(data);
          assert.ok(data.media instanceof Array);
          assert.equal(test.new_media_data.media_urls.length, data.media.length);
          done();
        });

      });

    });

  });

});
<|endoftext|>


<commit_before>/*
 * Copyright 2014-2016 Simon Edwards <simon@simonzone.com>
 *
 * This source code is licensed under the MIT license which is detailed in the LICENSE.txt file.
 */
require('shelljs/global');
const fs = require('fs');
const path = require('path');
const packager = require('electron-packager');

const log = console.log.bind(console);
const BUILD_TMP = 'build_tmp';

function main() {
  "use strict";

  if ( ! test('-f', './package.json')) {
    echo("This script was called from the wrong directory.");
    return;
  }

  const srcRootDir = pwd();
  if (test('-d', BUILD_TMP)) {
    rm('-rf', BUILD_TMP);
  }
  mkdir(BUILD_TMP);

  const packageJson = fs.readFileSync('package.json');
  const packageData = JSON.parse(packageJson);

  const gitUrl = packageData.repository.url.replace("git://github.com/", "git@github.com:");

  echo("Fetching a clean copy of the source code from " + gitUrl);
  cd(BUILD_TMP);
  const buildTmpPath = pwd();

  exec("git clone --depth 1 " + gitUrl);

  echo("Setting up the run time dependencies in " + BUILD_TMP);

  cd("extraterm");
  echo("Downloading dependencies.");
  exec("npm install");

  echo("Building");
  exec("npm run build");

  echo("Removing development dependencies");
  exec("npm prune --production");

  // Create the commands zip
  echo("Creating commands.zip");
  const commandsDir = packageData.name + "-commands-" + packageData.version;
  cp("-r", "src/commands", path.join(buildTmpPath, commandsDir));
  const codeDir = pwd();
  cd(buildTmpPath);
  exec(`zip -r ${commandsDir}.zip ${commandsDir}`);
  cd(codeDir);

  const electronVersion = packageData.devDependencies['electron-prebuilt'];

  const ignoreRegExp = [
    /^\/build_scripts\//,
    /^\/test\//,
    /^\/build_tmp\//,
    /^\/typedocs\//,
    /^\/[^/]+\.ts/,
    /^\/[^/]+\.js\.map/
  ];

  const ignoreFunc = function ignoreFunc(filePath) {
    return ignoreRegExp.some( (exp) => exp.test(filePath));
  };

  function makePackage(arch, platform) {
    log("");
    return new Promise(function(resolve, reject) {

      // Clean up the output dirs and files first.
      const versionedOutputDir = packageData.name + "-" + packageData.version + "-" + platform + "-" + arch;
      if (test('-d', versionedOutputDir)) {
        rm('-rf', versionedOutputDir);
      }

      const outputZip = path.join(buildTmpPath, versionedOutputDir + ".zip");

      packager({
        arch: arch,
        dir: ".",
        platform: platform,
        version: electronVersion,
        ignore: ignoreFunc,
        overwrite: true,
        out: BUILD_TMP
      }, function done(err, appPath) {
        if (err !== null) {
          log(err);
          reject();
        } else {
          // Rename the output dir to a one with a version number in it.
          mv(appPath[0], path.join(BUILD_TMP, versionedOutputDir));

          // Zip it up.
          log("Zipping up the package");

          const thisCD = pwd();
          cd(BUILD_TMP);
          exec(`zip -r ${outputZip} ${versionedOutputDir}`);
          cd(thisCD);

          log("App bundle written to " + versionedOutputDir);
          resolve();
        }
      });
    });
  }

  function replaceDirs(targetDir, replacementsDir) {
    const prevDir = pwd();
    cd(srcRootDir);
    const replacements = ls(replacementsDir);
    replacements.forEach( (rDir) => {
      const targetSubDir = path.join(targetDir, rDir);
      if (test('-d', targetSubDir)) {
        rm('-r', targetSubDir);
        cp('-r', path.join(replacementsDir, rDir), targetSubDir);
      }
    });
    cd(prevDir);
  }

  makePackage('x64', 'win32')
    .then( () => {
      replaceDirs(path.join(BUILD_TMP, 'extraterm/node_modules'), 'src/build_scripts/node_modules-linux-x64');
      return makePackage('x64', 'linux'); })

    .then( () => {
      replaceDirs(path.join(BUILD_TMP, 'extraterm/node_modules'), 'src/build_scripts/node_modules-linux-ia32');
      return makePackage('ia32', 'linux'); })

    .then( () => {
      replaceDirs(path.join(BUILD_TMP, 'extraterm/node_modules'), 'src/build_scripts/node_modules-darwin-x86');
      return makePackage('x64', 'darwin'); })

    .then( () => { log("Done"); } );
}
main();
<commit_msg>Fixes for the releases zips. Omit a bunch of unneeded files. Include our README.md and license file in the zip root dir.<commit_after>/*
 * Copyright 2014-2016 Simon Edwards <simon@simonzone.com>
 *
 * This source code is licensed under the MIT license which is detailed in the LICENSE.txt file.
 */
require('shelljs/global');
const fs = require('fs');
const path = require('path');
const packager = require('electron-packager');

const log = console.log.bind(console);
const BUILD_TMP = 'build_tmp';

function main() {
  "use strict";

  if ( ! test('-f', './package.json')) {
    echo("This script was called from the wrong directory.");
    return;
  }

  const srcRootDir = pwd();
  if (test('-d', BUILD_TMP)) {
    rm('-rf', BUILD_TMP);
  }
  mkdir(BUILD_TMP);

  const packageJson = fs.readFileSync('package.json');
  const packageData = JSON.parse(packageJson);

  const gitUrl = packageData.repository.url.replace("git://github.com/", "git@github.com:");

  echo("Fetching a clean copy of the source code from " + gitUrl);
  cd(BUILD_TMP);
  const buildTmpPath = pwd();

  exec("git clone --depth 1 " + gitUrl);

  echo("Setting up the run time dependencies in " + BUILD_TMP);

  cd("extraterm");
  echo("Downloading dependencies.");
  exec("npm install");

  echo("Building");
  exec("npm run build");

  echo("Removing development dependencies");
  exec("npm prune --production");

  // Create the commands zip
  echo("Creating commands.zip");
  const commandsDir = packageData.name + "-commands-" + packageData.version;
  cp("-r", "src/commands", path.join(buildTmpPath, commandsDir));
  const codeDir = pwd();
  cd(buildTmpPath);
  exec(`zip -r ${commandsDir}.zip ${commandsDir}`);
  cd(codeDir);

  const electronVersion = packageData.devDependencies['electron-prebuilt'];

  const ignoreRegExp = [
    /^\/src\/build_scripts\//,
    /^\/test\//,
    /^\/build_tmp\//,
    /^\/src\/typedocs\//,
    /\.ts$/,
    /\.js\.map$/,
    /^\/\.git\//
  ];

  const ignoreFunc = function ignoreFunc(filePath) {
    const result = ignoreRegExp.some( (exp) => exp.test(filePath));
    return result;
  };

  function makePackage(arch, platform) {
    log("");
    return new Promise(function(resolve, reject) {

      // Clean up the output dirs and files first.
      const versionedOutputDir = packageData.name + "-" + packageData.version + "-" + platform + "-" + arch;
      if (test('-d', versionedOutputDir)) {
        rm('-rf', versionedOutputDir);
      }

      const outputZip = path.join(buildTmpPath, versionedOutputDir + ".zip");

      packager({
        arch: arch,
        dir: ".",
        platform: platform,
        version: electronVersion,
        ignore: ignoreFunc,
        overwrite: true,
        out: buildTmpPath
      }, function done(err, appPath) {
        if (err !== null) {
          log(err);
          reject();
        } else {
          // Rename the output dir to a one with a version number in it.
          mv(appPath[0], path.join(buildTmpPath, versionedOutputDir));

          // Zip it up.
          log("Zipping up the package");

          const thisCD = pwd();
          cd(buildTmpPath);
          mv(path.join(versionedOutputDir, "LICENSE"), path.join(versionedOutputDir, "LICENSE_electron.txt"));
          cp("extraterm/README.md", versionedOutputDir);
          cp("extraterm/LICENSE.txt", versionedOutputDir);

          exec(`zip -r ${outputZip} ${versionedOutputDir}`);
          cd(thisCD);

          log("App bundle written to " + versionedOutputDir);
          resolve();
        }
      });
    });
  }

  function replaceDirs(targetDir, replacementsDir) {
    const prevDir = pwd();
    cd(srcRootDir);
    const replacements = ls(replacementsDir);
    replacements.forEach( (rDir) => {
      const targetSubDir = path.join(targetDir, rDir);
      if (test('-d', targetSubDir)) {
        rm('-r', targetSubDir);
        cp('-r', path.join(replacementsDir, rDir), targetSubDir);
      }
    });
    cd(prevDir);
  }

  makePackage('x64', 'win32')
    .then( () => {
      replaceDirs(path.join(buildTmpPath, 'extraterm/node_modules'), 'src/build_scripts/node_modules-linux-x64');
      return makePackage('x64', 'linux'); })

    .then( () => {
      replaceDirs(path.join(buildTmpPath, 'extraterm/node_modules'), 'src/build_scripts/node_modules-linux-ia32');
      return makePackage('ia32', 'linux'); })

    .then( () => {
      replaceDirs(path.join(buildTmpPath, 'extraterm/node_modules'), 'src/build_scripts/node_modules-darwin-x86');
      return makePackage('x64', 'darwin'); })

    .then( () => { log("Done"); } );
}
main();
<|endoftext|>


<commit_before>define(['$',
        'expect'],
function($,
        expect){

    var a = $.Id('a'),
        b = $.Id('b'),
        c = $.Id('c'),
        Object = $.Id('Object'),
        defineProperty = $.Member(Object, $.Id('defineProperty'));

    return {
        'module': "For In Statement",
        'tests': [
            ["Zero Iteration For",
            function(){
                expect.run(
                    $.Program(
                        $.ForIn(a, $.Object(),
                            $.Expression($.Number(1)))))

                    .testResult()
                        .type('undefined', undefined);

                expect.run(
                    $.Program(
                        $.ForIn($.Var($.Declarator($.Id('a'))), $.Object(),
                            $.Expression($.Number(1)))))

                    .testResult()
                        .type('undefined', undefined)

                    .test($.Expression(a))
                        .type('undefined', undefined);
            }],
            ["Zero Iteration Yielded Value",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Number(10)),
                        $.ForIn(a, $.Object(),
                            $.Expression($.Number(1)))))
                    .testResult()
                        .type('number', 10);
            }],

            ["Simple Object Iteration",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                                {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                                {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)}))),
                        $.ForIn(a, c,
                            $.Expression($.AddAssign(b, $.ComputedMember(c, a))))))

                    .testResult()
                        .type('number', '3')

                    .test($.Expression(a))
                        .type('string', 'y')
            }],
            ["Member Lhs",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(a, $.Object())),
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                            {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                            {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)}))),
                        $.ForIn($.Member(a, $.Id('i')), c,
                            $.Expression($.AddAssign(b, $.ComputedMember(c, $.Member(a, $.Id('i'))))))))

                    .testResult()
                        .type('number', '3')

                    .test($.Expression($.Member(a, $.Id('i'))))
                        .type('string', 'y')
            }],
            ["Lhs revaluated every iteration",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign($.Id('i'), $.Number(0))),
                        $.Expression($.Assign(a, $.Object())),
                        $.Expression($.Assign(c, $.Object(
                            {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                            {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)}))),
                        $.ForIn($.ComputedMember(a, $.PostIncrement($.Id('i'))), c,
                            $.Block())))

                    .test($.Expression($.Member(a, $.Id('0'))))
                        .type('string', 'x')

                    .test($.Expression($.Member(a, $.Id('1'))))
                        .type('string', 'y')
            }],

            ["Does not iterate over non enumerables",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign($.Id('i'), $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                            {'key': $.String('x'), 'kind': 'init', 'value': $.Number(1)}))),
                        $.Expression($.Call(defineProperty, [
                                c,
                                $.String('y'),
                                $.Object({
                                    'kind': 'init',
                                    'key': $.String('value'),
                                    'value': $.Number(2)
                                }, {
                                    'kind': 'init',
                                    'key': $.String('enumerable'),
                                    'value': $.Boolean(false)
                                })])),
                        $.ForIn(a, c,
                            $.Expression($.PostIncrement($.Id('i'))))))

                    .test($.Expression($.Id('i')))
                        .type('number', 1)

                    .test($.Expression(a))
                        .type('string', 'x')
            }],
            ["Does not iterate over inherited",
            function(){
                expect.run(
                    $.Program(
                        $.FunctionDeclaration(b, [],
                            $.Block(
                                $.Expression($.Assign($.Member($.This(), $.Id('x')), $.Number(1))))),
                        $.Expression($.Assign($.Member($.Member(b, $.Id('prototype')), $.Id('y')), $.Number(2))),

                        $.Expression($.Assign($.Id('i'), $.Number(0))),
                        $.ForIn(a, $.New(b, []),
                            $.Expression($.PostIncrement($.Id('i'))))))

                    .test($.Expression($.Id('i')))
                        .type('number', 1)

                    .test($.Expression(a))
                        .type('string', 'x')
            }],

            ["Continue",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                                {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                                {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)},
                                {'key':$.String('ya'), 'kind': 'init', 'value': $.Number(10)},
                                {'key':$.String('z'), 'kind': 'init', 'value': $.Number(3)}))),
                        $.ForIn(a, c,
                            $.Block(
                                $.If($.Equals($.ComputedMember(a, $.Number(0)), $.String('y')),
                                    $.Expression($.AddAssign(b, $.ComputedMember(c, a))),
                                    $.Continue())))))

                    .testResult()
                        .type('number', '12')

                    .test($.Expression(a))
                        .type('string', 'z')

                    .test($.Expression(b))
                        .type('number', '12')
            }],
        ]
    };
});
<commit_msg>Added simple test for break forin<commit_after>define(['$',
        'expect'],
function($,
        expect){

    var a = $.Id('a'),
        b = $.Id('b'),
        c = $.Id('c'),
        Object = $.Id('Object'),
        defineProperty = $.Member(Object, $.Id('defineProperty'));

    return {
        'module': "For In Statement",
        'tests': [
            ["Zero Iteration For",
            function(){
                expect.run(
                    $.Program(
                        $.ForIn(a, $.Object(),
                            $.Expression($.Number(1)))))

                    .testResult()
                        .type('undefined', undefined);

                expect.run(
                    $.Program(
                        $.ForIn($.Var($.Declarator($.Id('a'))), $.Object(),
                            $.Expression($.Number(1)))))

                    .testResult()
                        .type('undefined', undefined)

                    .test($.Expression(a))
                        .type('undefined', undefined);
            }],
            ["Zero Iteration Yielded Value",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Number(10)),
                        $.ForIn(a, $.Object(),
                            $.Expression($.Number(1)))))
                    .testResult()
                        .type('number', 10);
            }],

            ["Simple Object Iteration",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                                {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                                {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)}))),
                        $.ForIn(a, c,
                            $.Expression($.AddAssign(b, $.ComputedMember(c, a))))))

                    .testResult()
                        .type('number', '3')

                    .test($.Expression(a))
                        .type('string', 'y')
            }],
            ["Member Lhs",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(a, $.Object())),
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                            {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                            {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)}))),
                        $.ForIn($.Member(a, $.Id('i')), c,
                            $.Expression($.AddAssign(b, $.ComputedMember(c, $.Member(a, $.Id('i'))))))))

                    .testResult()
                        .type('number', '3')

                    .test($.Expression($.Member(a, $.Id('i'))))
                        .type('string', 'y')
            }],
            ["Lhs revaluated every iteration",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign($.Id('i'), $.Number(0))),
                        $.Expression($.Assign(a, $.Object())),
                        $.Expression($.Assign(c, $.Object(
                            {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                            {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)}))),
                        $.ForIn($.ComputedMember(a, $.PostIncrement($.Id('i'))), c,
                            $.Block())))

                    .test($.Expression($.Member(a, $.Id('0'))))
                        .type('string', 'x')

                    .test($.Expression($.Member(a, $.Id('1'))))
                        .type('string', 'y')
            }],

            ["Does not iterate over non enumerables",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign($.Id('i'), $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                            {'key': $.String('x'), 'kind': 'init', 'value': $.Number(1)}))),
                        $.Expression($.Call(defineProperty, [
                                c,
                                $.String('y'),
                                $.Object({
                                    'kind': 'init',
                                    'key': $.String('value'),
                                    'value': $.Number(2)
                                }, {
                                    'kind': 'init',
                                    'key': $.String('enumerable'),
                                    'value': $.Boolean(false)
                                })])),
                        $.ForIn(a, c,
                            $.Expression($.PostIncrement($.Id('i'))))))

                    .test($.Expression($.Id('i')))
                        .type('number', 1)

                    .test($.Expression(a))
                        .type('string', 'x')
            }],
            ["Does not iterate over inherited",
            function(){
                expect.run(
                    $.Program(
                        $.FunctionDeclaration(b, [],
                            $.Block(
                                $.Expression($.Assign($.Member($.This(), $.Id('x')), $.Number(1))))),
                        $.Expression($.Assign($.Member($.Member(b, $.Id('prototype')), $.Id('y')), $.Number(2))),

                        $.Expression($.Assign($.Id('i'), $.Number(0))),
                        $.ForIn(a, $.New(b, []),
                            $.Expression($.PostIncrement($.Id('i'))))))

                    .test($.Expression($.Id('i')))
                        .type('number', 1)

                    .test($.Expression(a))
                        .type('string', 'x')
            }],

            ["Continue",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                                {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                                {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)},
                                {'key':$.String('ya'), 'kind': 'init', 'value': $.Number(10)},
                                {'key':$.String('z'), 'kind': 'init', 'value': $.Number(3)}))),
                        $.ForIn(a, c,
                            $.Block(
                                $.If($.Equals($.ComputedMember(a, $.Number(0)), $.String('y')),
                                    $.Expression($.AddAssign(b, $.ComputedMember(c, a))),
                                    $.Continue())))))

                    .testResult()
                        .type('number', '12')

                    .test($.Expression(a))
                        .type('string', 'z')

                    .test($.Expression(b))
                        .type('number', '12')
            }],

            ["Break",
            function(){
                expect.run(
                    $.Program(
                        $.Expression($.Assign(b, $.Number(0))),
                        $.Expression($.Assign(c, $.Object(
                                {'key':$.String('x'), 'kind': 'init', 'value': $.Number(1)},
                                {'key':$.String('y'), 'kind': 'init', 'value': $.Number(2)},
                                {'key':$.String('ya'), 'kind': 'init', 'value': $.Number(10)},
                                {'key':$.String('z'), 'kind': 'init', 'value': $.Number(5)}))),
                        $.ForIn(a, c,
                            $.Block(
                                $.If($.Equals(a, $.String('ya')),
                                    $.Break(),
                                    $.Expression($.AddAssign(b, $.ComputedMember(c, a))))))))

                    .testResult()
                        .type('number', '3')

                    .test($.Expression(a))
                        .type('string', 'ya')

                    .test($.Expression(b))
                        .type('number', '3')
            }],
        ]
    };
});
<|endoftext|>


<commit_before>/**
 * window.c.ProjectSuccessfulOnboard component
 * render first interaction of successful project onboarding
 * used when project is successful and wants to confirm bank data and request transfer
 *
 * Example:
 * m.component(c.ProjectSuccessfulOnboard, {project: project})
 **/

window.c.ProjectSuccessfulOnboard = ((m, c, models, h, _) => {
    return {
        controller: (args) => {
            let projectIdVM = m.postgrest.filtersVM({project_id: 'eq'}),
                projectAccounts = m.prop([]),
                projectTransfers = m.prop([]),
                currentStage = m.prop('ProjectSuccessfulOnboardStart'),
                loader = m.postgrest.loaderWithToken;

            projectIdVM.project_id(args.project.id);

            const lProjectAccount = loader(models.projectAccount.getRowOptions(projectIdVM.parameters()));
            lProjectAccount.load().then(projectAccounts);

            const lProjectTransfer = loader(models.projectTransfer.getRowOptions(projectIdVM.parameters()));
            lProjectTransfer.load().then(projectTransfers);

            const setStage = (stage) => {
                return () => {
                    console.log(stage);

                    const stages = {
                        'start': 'ProjectSuccessfulOnboardStart',
                        'confirm_account': 'ProjectSuccessfulOnboardConfirmAccount'
                    };

                    currentStage(stages[stage||'start']);
                    return currentStage();
                };
            };

            const loadCurrentStage = () => {
                if (!lProjectAccount() && !lProjectTransfer()) {
                    const pa = _.first(projectAccounts);

                    if (_.isNull(pa.error_reason) && _.isNull(pa.transfer_state)) {
                        return setStage('start')();
                    }
                }

                return void(0);
            };

            loadCurrentStage();

            return {
                projectAccounts: projectAccounts,
                projectTransfers: projectTransfers,
                lProjectAccount: lProjectAccount,
                lProjectTransfer: lProjectTransfer,
                setStage: setStage,
                currentStage: currentStage
            };
        },

        view: (ctrl, args) => {
            const projectAccount = _.first(ctrl.projectAccounts()),
                  projectTransfer = _.first(ctrl.projectTransfers()),
                  lpa = ctrl.lProjectAccount,
                  lpt = ctrl.lProjectTransfer;

            return m('.w-section.section', [
                (!lpa() && !lpt() ?
                 m.component(c[ctrl.currentStage()], {
                     projectTransfer: projectTransfer,
                     projectAccount: projectAccount,
                     setStage: ctrl.setStage
                 }) : '')

            ]);
        }
    };
}(window.m, window.c, window.c.models, window.c.h, window._));
<commit_msg>mapping new onboard components<commit_after>/**
 * window.c.ProjectSuccessfulOnboard component
 * render first interaction of successful project onboarding
 * used when project is successful and wants to confirm bank data and request transfer
 *
 * Example:
 * m.component(c.ProjectSuccessfulOnboard, {project: project})
 **/

window.c.ProjectSuccessfulOnboard = ((m, c, models, h, _) => {
    return {
        controller: (args) => {
            let projectIdVM = m.postgrest.filtersVM({project_id: 'eq'}),
                projectAccounts = m.prop([]),
                projectTransfers = m.prop([]),
                onboardStages = {
                    'start': 'ProjectSuccessfulOnboardStart',
                    'confirm_account': 'ProjectSuccessfulOnboardConfirmAccount',
                    'error_account': 'ProjectSuccessfulOnboardErrorAccount',
                    'pending_transfer': 'ProjectSuccessfulOnboardPendingTransfer',
                    'finished': 'ProjectSuccessfulOnboardFinished'
                },
                currentStage = m.prop(onboardStages['start']),
                loader = m.postgrest.loaderWithToken;

            projectIdVM.project_id(args.project.id);

            const lProjectAccount = loader(models.projectAccount.getRowOptions(projectIdVM.parameters()));
            lProjectAccount.load().then(projectAccounts);

            const lProjectTransfer = loader(models.projectTransfer.getRowOptions(projectIdVM.parameters()));
            lProjectTransfer.load().then(projectTransfers);

            const setStage = (stage) => {
                return () => {
                    currentStage(onboardStages[stage]);

                    return currentStage();
                };},

                  loadCurrentStage = () => {
                      if (!lProjectAccount() && !lProjectTransfer()) {
                          const pa = _.first(projectAccounts);

                          if (_.isNull(pa.error_reason) && _.isNull(pa.transfer_state)) {
                              return setStage('start')();
                          }
                      }

                      return void(0);
                  },

                  addErrorReason = (errorProp) => {
                      return () => {
                          console.log(errorProp());
                          setStage('error_account')();
                          return void(0);
                      };
                  },

                  acceptAccount = () => {
                      setStage('pending_transfer')();
                      return void(0);
                  };

            loadCurrentStage();

            return {
                projectAccounts: projectAccounts,
                projectTransfers: projectTransfers,
                lProjectAccount: lProjectAccount,
                lProjectTransfer: lProjectTransfer,
                setStage: setStage,
                currentStage: currentStage,
                addErrorReason: addErrorReason,
                acceptAccount: acceptAccount
            };
        },

        view: (ctrl, args) => {
            const projectAccount = _.first(ctrl.projectAccounts()),
                  projectTransfer = _.first(ctrl.projectTransfers()),
                  lpa = ctrl.lProjectAccount,
                  lpt = ctrl.lProjectTransfer;

            return m('.w-section.section', [
                (!lpa() && !lpt() ?
                 m.component(c[ctrl.currentStage()], {
                     projectTransfer: projectTransfer,
                     projectAccount: projectAccount,
                     setStage: ctrl.setStage,
                     addErrorReason: ctrl.addErrorReason,
                     acceptAccount: ctrl.acceptAccount
                 }) : '')

            ]);
        }
    };
}(window.m, window.c, window.c.models, window.c.h, window._));
<|endoftext|>


<commit_before>(function() {

    "use strict";

    /** This behavior provides "fly" mode camera control on the given
     *  camera transformable.
     *  This behavior does have no notion of the interaction device. All it needs
     *  are deltaX and deltaY values, from which it computes the camera pose.
     *
     *  Usage:
     *  o instantiate this class
     *  o call rotate(), move{Forward,Backward}(), step{Left,Right}()
     *
     *  @constructor
     */
    XMOT.FlyControllerBehavior = new XMOT.Class({

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @param {Element|Transformable} targetViewGroup
         *  @param {Object} options
         *
         *  options:
         *  o rotateSpeed
         *  o moveSpeed
         */
        initialize: function(targetViewGroup, options) {

			this.target = XMOT.util.getOrCreateTransformable(targetViewGroup);

            var options = options || {};

            this._rotateSpeed = options.rotateSpeed || 1;
            this._moveSpeed = options.moveSpeed || 1;

            this._initialRotation = new XML3DRotation();
            this._yAxisAngle = 0;
            this._xAxisAngle = 0;
            this._maxXAxisAngle = Math.PI/2 - 0.2;

            this._setInitialRotation(this.target.getOrientation());
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        rotate: function(deltaX, deltaY) {

            var deltaXAxis = -this._rotateSpeed * deltaY * 2.0 * Math.PI;
            var deltaYAxis = -this._rotateSpeed * deltaX * 2.0 * Math.PI;

            this._xAxisAngle += deltaXAxis;
            this._yAxisAngle += deltaYAxis;

            if(this._xAxisAngle >= this._maxXAxisAngle)
                this._xAxisAngle = this._maxXAxisAngle;
            if(this._xAxisAngle <= -this._maxXAxisAngle)
                this._xAxisAngle = -this._maxXAxisAngle;

            var mx = new window.XML3DRotation(new window.XML3DVec3(1, 0, 0), this._xAxisAngle);
            var my = new window.XML3DRotation(new window.XML3DVec3(0, 1, 0), this._yAxisAngle);
            var rot = my.multiply(mx);

            var newRot = rot.multiply(this._initialRotation);

            this.target.setOrientation(newRot);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        moveForward: function() {
            this._moveInCamDirection();
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        moveBackward: function() {
            this._moveInCamDirection(true);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        stepRight: function() {
            this._stepRight();
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        stepLeft: function() {
            this._stepRight(true);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        lookAt: function(point) {

            var initCamDirection = new XML3DVec3(0, 0, -1);

            // calculate new direction
            var position = this.getPosition();
            var direction = point.subtract(position);
            direction = direction.normalize();

            // create rotation from angle b/w initial and new direction
            var dirRot = new XML3DRotation();
            dirRot.setRotation(initCamDirection, direction);

            this._setInitialRotation(dirRot);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        setPosition: function(position) {
            this.target.setPosition(position);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        setOrientation: function(orientation) {
            this._setInitialRotation(orientation);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        getPosition: function() {
            return this.target.getPosition();
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        getOrientation: function() {
            return this.target.getOrientation();
        },

        getMoveSpeed: function() {
            return this._moveSpeed;
        },

        setMoveSpeed: function(speed) {
            this._moveSpeed = speed;
        },

        getRotationSpeed: function() {
            return this._rotateSpeed;
        },

        setRotationSpeed: function(speed) {
            this._rotateSpeed = speed;
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _moveInCamDirection: function(doInvertDirection) {

            var moveDirection = this._getLookDirection();

            if(doInvertDirection) {
                moveDirection = moveDirection.scale(-1);
            }

            this._translateCamera(moveDirection);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _stepRight: function(doInvertDirection) {

            var lookDirection = this._getLookDirection();

            var stepDirection = lookDirection.cross(new XML3DVec3(0,1,0));

            if(doInvertDirection) {
                stepDirection = stepDirection.scale(-1);
            }

            this._translateCamera(stepDirection);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _getLookDirection: function() {

            var curRot = this.target.getOrientation();

            var defaultDirection = new window.XML3DVec3(0, 0, -1);
            var lookDirection = curRot.rotateVec3(defaultDirection).normalize();

            return lookDirection;
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _translateCamera: function(direction) {

            var transl = direction.scale(this._moveSpeed);

            var newPos = this.target.getPosition().add(transl);
            this.target.setPosition(newPos);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _setInitialRotation: function(rot) {

            var euler = this._toEuler(rot);

            this._xAxisAngle = euler.x;
            this._yAxisAngle = euler.y;
            this._initialRotation.set(new XML3DRotation());

            // align the target's orientation to compensate for precision errors
            this.rotate(0, 0);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _toEuler: function(rot) {

            // from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
            //  - disregard for qxy + qzw case, since we never change z
            // and https://truesculpt.googlecode.com/hg-history/38000e9dfece971460473d5788c235fbbe82f31b/Doc/rotation_matrix_to_euler.pdf
            //  - disregard for two-fold solution of y, works up to now

            var q = rot.getQuaternion();

            var qxx = q[0]*q[0];
            var qxz = q[0]*q[2];
            var qxw = q[0]*q[3];
            var qyy = q[1]*q[1];
            var qyz = q[1]*q[2];
            var qyw = q[1]*q[3];
            var qzz = q[2]*q[2];

            var y = Math.atan2(2*(qyw + qxz), 1 - 2*(qyy + qzz));
            var x = Math.atan2(2*(qxw + qyz), 1 - 2*(qxx + qzz));
            if(Math.cos(y) < -0.01)
                x = -x;

            return {x: x, y: y};
        }
    });
}());
<commit_msg>Fixed small bug<commit_after>(function() {

    "use strict";

    /** This behavior provides "fly" mode camera control on the given
     *  camera transformable.
     *  This behavior does have no notion of the interaction device. All it needs
     *  are deltaX and deltaY values, from which it computes the camera pose.
     *
     *  Usage:
     *  o instantiate this class
     *  o call rotate(), move{Forward,Backward}(), step{Left,Right}()
     *
     *  @constructor
     */
    XMOT.FlyControllerBehavior = new XMOT.Class({

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @param {Element|Transformable} targetViewGroup
         *  @param {Object} options
         *
         *  options:
         *  o rotateSpeed
         *  o moveSpeed
         */
        initialize: function(targetViewGroup, options) {

			this.target = XMOT.util.getOrCreateTransformable(targetViewGroup);

            var options = options || {};

            this._rotateSpeed = options.rotateSpeed || 1;
            this._moveSpeed = options.moveSpeed || 1;

            this._initialRotation = new XML3DRotation();
            this._yAxisAngle = 0;
            this._xAxisAngle = 0;
            this._maxXAxisAngle = Math.PI/2 - 0.2;

            this._setInitialRotation(this.target.getOrientation());
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        rotate: function(deltaX, deltaY) {

            var deltaXAxis = -this._rotateSpeed * deltaX * 2.0 * Math.PI;
            var deltaYAxis = -this._rotateSpeed * deltaY * 2.0 * Math.PI;

            this._xAxisAngle += deltaXAxis;
            this._yAxisAngle += deltaYAxis;

            if(this._xAxisAngle >= this._maxXAxisAngle)
                this._xAxisAngle = this._maxXAxisAngle;
            if(this._xAxisAngle <= -this._maxXAxisAngle)
                this._xAxisAngle = -this._maxXAxisAngle;

            var mx = new window.XML3DRotation(new window.XML3DVec3(1, 0, 0), this._xAxisAngle);
            var my = new window.XML3DRotation(new window.XML3DVec3(0, 1, 0), this._yAxisAngle);
            var rot = my.multiply(mx);

            var newRot = rot.multiply(this._initialRotation);

            this.target.setOrientation(newRot);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        moveForward: function() {
            this._moveInCamDirection();
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        moveBackward: function() {
            this._moveInCamDirection(true);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        stepRight: function() {
            this._stepRight();
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        stepLeft: function() {
            this._stepRight(true);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        lookAt: function(point) {

            var initCamDirection = new XML3DVec3(0, 0, -1);

            // calculate new direction
            var position = this.getPosition();
            var direction = point.subtract(position);
            direction = direction.normalize();

            // create rotation from angle b/w initial and new direction
            var dirRot = new XML3DRotation();
            dirRot.setRotation(initCamDirection, direction);

            this._setInitialRotation(dirRot);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        setPosition: function(position) {
            this.target.setPosition(position);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        setOrientation: function(orientation) {
            this._setInitialRotation(orientation);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        getPosition: function() {
            return this.target.getPosition();
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         */
        getOrientation: function() {
            return this.target.getOrientation();
        },

        getMoveSpeed: function() {
            return this._moveSpeed;
        },

        setMoveSpeed: function(speed) {
            this._moveSpeed = speed;
        },

        getRotationSpeed: function() {
            return this._rotateSpeed;
        },

        setRotationSpeed: function(speed) {
            this._rotateSpeed = speed;
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _moveInCamDirection: function(doInvertDirection) {

            var moveDirection = this._getLookDirection();

            if(doInvertDirection) {
                moveDirection = moveDirection.scale(-1);
            }

            this._translateCamera(moveDirection);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _stepRight: function(doInvertDirection) {

            var lookDirection = this._getLookDirection();

            var stepDirection = lookDirection.cross(new XML3DVec3(0,1,0));

            if(doInvertDirection) {
                stepDirection = stepDirection.scale(-1);
            }

            this._translateCamera(stepDirection);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _getLookDirection: function() {

            var curRot = this.target.getOrientation();

            var defaultDirection = new window.XML3DVec3(0, 0, -1);
            var lookDirection = curRot.rotateVec3(defaultDirection).normalize();

            return lookDirection;
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _translateCamera: function(direction) {

            var transl = direction.scale(this._moveSpeed);

            var newPos = this.target.getPosition().add(transl);
            this.target.setPosition(newPos);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _setInitialRotation: function(rot) {

            var euler = this._toEuler(rot);

            this._xAxisAngle = euler.x;
            this._yAxisAngle = euler.y;
            this._initialRotation.set(new XML3DRotation());

            // align the target's orientation to compensate for precision errors
            this.rotate(0, 0);
        },

        /**
         *  @this {XMOT.FlyControllerBehavior}
         *  @private
         */
        _toEuler: function(rot) {

            // from: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
            //  - disregard for qxy + qzw case, since we never change z
            // and https://truesculpt.googlecode.com/hg-history/38000e9dfece971460473d5788c235fbbe82f31b/Doc/rotation_matrix_to_euler.pdf
            //  - disregard for two-fold solution of y, works up to now

            var q = rot.getQuaternion();

            var qxx = q[0]*q[0];
            var qxz = q[0]*q[2];
            var qxw = q[0]*q[3];
            var qyy = q[1]*q[1];
            var qyz = q[1]*q[2];
            var qyw = q[1]*q[3];
            var qzz = q[2]*q[2];

            var y = Math.atan2(2*(qyw + qxz), 1 - 2*(qyy + qzz));
            var x = Math.atan2(2*(qxw + qyz), 1 - 2*(qxx + qzz));
            if(Math.cos(y) < -0.01)
                x = -x;

            return {x: x, y: y};
        }
    });
}());
<|endoftext|>


<commit_before>

module("can/view");

/*test("Ajax transport", function(){
	var order = 0;
	$.ajax({
		url: "//can/view/test/qunit/template.ejs",
		dataType : "view",
		async : false
	}).done(function(view){
		equals(++order,1, "called synchronously");
		equals(view({message: "hi"}).indexOf("
hi
"), 0, "renders stuff!")
	});

	equals(++order,2, "called synchronously");
})*/

if(window.Jaml){
	test("multiple template types work", function(){

		can.each(["micro","ejs","jaml"/*, "tmpl"*/], function(i, ext){
			var div = can.$(document.createElement('div'));

			can.append(div, can.view("//can/view/test/qunit/template."+ext,{"message" :"helloworld"}))

			ok( div[0].getElementsByTagName('h3').length, ext+": h3 written for ")
			ok( /helloworld\s*/.test( div[0].innerHTML ), ext+": hello world present for ")
		})
	});
}

test("plugin in ejs", function(){

	can.append( can.$("#qunit-test-area"), can.view("//can/view/test/qunit/plugin.ejs",{}) )
	ok(/something/.test( can.$("#something span")[0].firstChild.nodeValue ),"something has something");
	can.remove( can.$("#something") );
});

test("async templates, and caching work", function(){
	stop();
	var i = 0;

	can.view.render("//can/view/test/qunit/temp.ejs",{"message" :"helloworld"}, function(text){
		ok(/helloworld\s*/.test(text), "we got a rendered template");
		i++;
		equals(i, 2, "Ajax is not synchronous");
		start();
	});
	i++;
	equals(i, 1, "Ajax is not synchronous")
})
test("caching works", function(){
	// this basically does a large ajax request and makes sure
	// that the second time is always faster
	stop();
	var startT = new Date(),
		first;
	can.view.render("//can/view/test/qunit/large.ejs",{"message" :"helloworld"}, function(text){
		first = new Date();
		ok(text, "we got a rendered template");

		can.view.render("//can/view/test/qunit/large.ejs",{"message" :"helloworld"}, function(text){
			var lap2 = (new Date()) - first,
				lap1 =  first-startT;
			// ok( lap1 > lap2, "faster this time "+(lap1 - lap2) )

			start();
		})

	})
})
test("hookup", function(){

	can.view("//can/view/test/qunit/hookup.ejs",{})

})

test("inline templates other than 'tmpl' like ejs", function(){

        can.append( can.$("#qunit-test-area") ,'');

		var div = document.createElement('div');
		div.appendChild(can.view('test_ejs', {name: 'Henry'}))

        equal( div.getElementsByTagName("span")[0].firstChild.nodeValue , 'Henry');

});

test("object of deferreds", function(){
	var foo = new can.Deferred(),
		bar = new can.Deferred();
	stop();
	can.view.render("//can/view/test/qunit/deferreds.ejs",{
		foo : typeof foo.promise == 'function' ? foo.promise() : foo,
		bar : bar
	}).then(function(result){
		equals(result, "FOO and BAR");
		start();
	});
	setTimeout(function(){
		foo.resolve("FOO");
	},100);
	bar.resolve("BAR");

});

test("deferred", function(){
	var foo = new can.Deferred();
	stop();
	can.view.render("//can/view/test/qunit/deferred.ejs",foo).then(function(result){
		equals(result, "FOO");
		start();
	});
	setTimeout(function(){
		foo.resolve({
			foo: "FOO"
		});
	},100);

});

/*test("bad url", function(){
	can.render("//asfdsaf/sadf.ejs")
});*/

test("hyphen in type", function(){

	can.append( can.$("#qunit-test-area") ,"");

	var div = document.createElement('div');
	div.appendChild(can.view('hyphenEjs', {}))

    ok( /Hyphen/.test(div.innerHTML) , 'has hyphen');

})

<commit_msg>Fix for 'Dojo/can/view: inline templates other than 'tmpl' like ejs' in IE8<commit_after>

module("can/view");

/*test("Ajax transport", function(){
	var order = 0;
	$.ajax({
		url: "//can/view/test/qunit/template.ejs",
		dataType : "view",
		async : false
	}).done(function(view){
		equals(++order,1, "called synchronously");
		equals(view({message: "hi"}).indexOf("
hi
"), 0, "renders stuff!")
	});

	equals(++order,2, "called synchronously");
})*/

if(window.Jaml){
	test("multiple template types work", function(){

		can.each(["micro","ejs","jaml"/*, "tmpl"*/], function(i, ext){
			var div = can.$(document.createElement('div'));

			can.append(div, can.view("//can/view/test/qunit/template."+ext,{"message" :"helloworld"}))

			ok( div[0].getElementsByTagName('h3').length, ext+": h3 written for ")
			ok( /helloworld\s*/.test( div[0].innerHTML ), ext+": hello world present for ")
		})
	});
}

test("plugin in ejs", function(){

	can.append( can.$("#qunit-test-area"), can.view("//can/view/test/qunit/plugin.ejs",{}) )
	ok(/something/.test( can.$("#something span")[0].firstChild.nodeValue ),"something has something");
	can.remove( can.$("#something") );
});

test("async templates, and caching work", function(){
	stop();
	var i = 0;

	can.view.render("//can/view/test/qunit/temp.ejs",{"message" :"helloworld"}, function(text){
		ok(/helloworld\s*/.test(text), "we got a rendered template");
		i++;
		equals(i, 2, "Ajax is not synchronous");
		start();
	});
	i++;
	equals(i, 1, "Ajax is not synchronous")
})
test("caching works", function(){
	// this basically does a large ajax request and makes sure
	// that the second time is always faster
	stop();
	var startT = new Date(),
		first;
	can.view.render("//can/view/test/qunit/large.ejs",{"message" :"helloworld"}, function(text){
		first = new Date();
		ok(text, "we got a rendered template");

		can.view.render("//can/view/test/qunit/large.ejs",{"message" :"helloworld"}, function(text){
			var lap2 = (new Date()) - first,
				lap1 =  first-startT;
			// ok( lap1 > lap2, "faster this time "+(lap1 - lap2) )

			start();
		})

	})
})
test("hookup", function(){

	can.view("//can/view/test/qunit/hookup.ejs",{})

})

test("inline templates other than 'tmpl' like ejs", function(){
	var script = document.createElement('script');
	script.setAttribute('type', 'test/ejs')
	script.setAttribute('id', 'test_ejs')
	script.text = '<%= name %>';
	document.getElementById("qunit-test-area").appendChild(script);

	var div = document.createElement('div');
	div.appendChild(can.view('test_ejs', {name: 'Henry'}))

	equal( div.getElementsByTagName("span")[0].firstChild.nodeValue , 'Henry');
});

test("object of deferreds", function(){
	var foo = new can.Deferred(),
		bar = new can.Deferred();
	stop();
	can.view.render("//can/view/test/qunit/deferreds.ejs",{
		foo : typeof foo.promise == 'function' ? foo.promise() : foo,
		bar : bar
	}).then(function(result){
		equals(result, "FOO and BAR");
		start();
	});
	setTimeout(function(){
		foo.resolve("FOO");
	},100);
	bar.resolve("BAR");

});

test("deferred", function(){
	var foo = new can.Deferred();
	stop();
	can.view.render("//can/view/test/qunit/deferred.ejs",foo).then(function(result){
		equals(result, "FOO");
		start();
	});
	setTimeout(function(){
		foo.resolve({
			foo: "FOO"
		});
	},100);

});

/*test("bad url", function(){
	can.render("//asfdsaf/sadf.ejs")
});*/

test("hyphen in type", function(){

	can.append( can.$("#qunit-test-area") ,"");

	var div = document.createElement('div');
	div.appendChild(can.view('hyphenEjs', {}))

    ok( /Hyphen/.test(div.innerHTML) , 'has hyphen');

})

<|endoftext|>


<commit_before>/*!
 * OS.js - JavaScript Cloud/Web Desktop Platform
 *
 * Copyright (c) 2011-2016, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
(function() {
  'use strict';

  /////////////////////////////////////////////////////////////////////////////
  // COOKIES
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Gets a cookie by key, or all cookies
   *
   * @function getCookie
   * @memberof OSjs.Utils
   *
   * @param {String} [k] What key to get
   * @return {String|Object}  Depending on 'k' parameter
   */
  OSjs.Utils.getCookie = function(k) {
    var map = {};
    document.cookie.split(/;\s+?/g).forEach(function(i) {
      var idx = i.indexOf('=');
      map[i.substr(i, idx)] = i.substr(idx + 1);
    });
    return k ? map[k] : map;
  };

  /////////////////////////////////////////////////////////////////////////////
  // STRING
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Format a string (almost like sprintf)
   *
   * @function format
   * @memberof OSjs.Utils
   * @link http://stackoverflow.com/a/4673436
   *
   * @param   {String}      format        String format
   * @param   {...String}   s             Insert into format
   *
   * @return  {String}                    The formatted string
   */
  OSjs.Utils.format = function(format) {
    var args = Array.prototype.slice.call(arguments, 1);
    var sprintfRegex = /\{(\d+)\}/g;

    function sprintf(match, number) {
      return number in args ? args[number] : match;
    }

    return format.replace(sprintfRegex, sprintf);
  };

  /**
   * Remove whitespaces and newlines from HTML document
   *
   * @function cleanHTML
   * @memberof OSjs.Utils
   *
   * @param   {String}    html          HTML string input
   *
   * @return  {String}
   */
  OSjs.Utils.cleanHTML = function(html) {
    return html.replace(/\n/g, '')
               .replace(/[\t ]+</g, '<')
               .replace(/\>[\t ]+</g, '><')
               .replace(/\>[\t ]+$/g, '>');
  };

  /**
   * Parses url into a dictionary (supports modification)
   *
   * @function parseurl
   * @memberof OSjs.Utils
   *
   * @param     {String}        url       Input URL
   * @param     {Object}        [modify]  Modify URL with these options
   *
   * @return    {Object}                  Object with protocol, host, path
   */
  OSjs.Utils.parseurl = function(url, modify) {
    modify = modify || {};

    if ( !url.match(/^(\w+\:)\/\//) ) {
      url = '//' + url;
    }

    var protocol = url.split(/^(\w+\:)?\/\//);

    var splitted = (function() {
      var tmp = protocol[2].replace(/^\/\//, '').split('/');
      return {
        proto: (modify.protocol || protocol[1] || window.location.protocol || '').replace(/\:$/, ''),
        host: modify.host || tmp.shift(),
        path: modify.path || '/' + tmp.join('/')
      };
    })();

    function _parts() {
      var parts = [splitted.proto, '://'];

      if ( modify.username ) {
        var authstr = String(modify.username) + ':' + String(modify.password);
        parts.push(authstr);
        parts.push('@');
      }

      parts.push(splitted.host);
      parts.push(splitted.path);
      return parts.join('');
    }

    return {
      protocol: splitted.proto,
      host: splitted.host,
      path: splitted.path,
      url: _parts()
    };
  };

  /**
   * Returns the URL without protocol
   *
   * @function getRelativeURL
   * @memberof OSjs.Utils
   *
   * @param   {String}    orig        Path name
   *
   * @return  {String}
   */
  OSjs.Utils.getRelativeURL = function getRelativeURL(orig) {
    return orig.replace(/^([A-z0-9\-_]+)\:\/\//, '');
  };

  /////////////////////////////////////////////////////////////////////////////
  // OBJECT HELPERS
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Wrapper for merging function argument dictionaries
   *
   * @function argumentDefaults
   * @memberof OSjs.Utils
   *
   * @param  {Object}   args      Given function Dictionary
   * @param  {Object}   defaults  Defaults Dictionary
   * @param  {Boolean}  undef     Check with 'undefined'
   * @return {Object}
   */
  OSjs.Utils.argumentDefaults = function(args, defaults, undef) {
    args = args || {};
    Object.keys(defaults).forEach(function(key) {
      if ( typeof defaults[key] === 'boolean' || typeof defaults[key] === 'number' ) {
        if ( typeof args[key] === 'undefined' || args[key] === null ) {
          args[key] = defaults[key];
        }
      } else {
        args[key] = args[key] || defaults[key];
      }
    });
    return args;
  };

  /**
   * Deep-merge to objects
   *
   * @function mergeObject
   * @memberof OSjs.Utils
   *
   * @param   {Object}      obj1      Object to merge to
   * @param   {Object}      obj2      Object to merge with
   *
   * @return  {Object}                The merged object
   */
  OSjs.Utils.mergeObject = function(obj1, obj2, opts) {
    opts = opts || {};

    for ( var p in obj2 ) {
      if ( obj2.hasOwnProperty(p) ) {
        try {
          if (opts.overwrite === false && obj1.hasOwnProperty(p)) {
            continue;
          }

          if ( obj2[p].constructor === Object ) {
            obj1[p] = OSjs.Utils.mergeObject(obj1[p], obj2[p]);
          } else {
            obj1[p] = obj2[p];
          }
        } catch (e) {
          obj1[p] = obj2[p];
        }
      }
    }
    return obj1;
  };

  /**
   * Clone a object
   *
   * @function cloneObject
   * @memberof OSjs.Utils
   *
   * @param   {Object}      o     The object to clone
   *
   * @return  {Object}            An identical object
   */
  OSjs.Utils.cloneObject = function(o) {
    return JSON.parse(JSON.stringify(o, function(key, value) {
      if ( value && typeof value === 'object' && value.tagName ) {
        return undefined;
      }
      return value;
    }));
  };

  /**
   * Fixes JSON for HTTP requests (in case they were returned as string)
   *
   * @function fixJSON
   * @memberof OSjs.Utils
   *
   * @param   {Mixed}     response      The data
   *
   * @return  {Object}                  JSON
   */
  OSjs.Utils.fixJSON = function(response) {
    if ( typeof response === 'string' ) {
      if ( response.match(/^\{|\[/) ) {
        try {
          response = JSON.parse(response);
        } catch ( e  ) {
          console.warn('FAILED TO FORCE JSON MIME TYPE', e);
        }
      }
    }
    return response;
  };

  /**
   * Extends the given object
   *
   * <pre>
   * If you give a `parentObj` and a prototype method exists
   * in that target, the child object method will be wrapped
   * to make sure the super object method is called.
   * </pre>
   *
   * @example
   * Utils.extend({
   *  a: 'foo'
   * }, {
   *  b: 'bar'
   * }); // -> {a: 'foo', b: 'bar'}
   *
   * @function extend
   * @memberof OSjs.Utils
   *
   * @param {Object}    obj          The destination
   * @param {Object}    methods      The source
   */
  OSjs.Utils.extend = function(obj, methods) {
    if ( obj && methods ) {
      Object.keys(methods).forEach(function(k) {
        obj[k] = methods[k];
      });
    }
  };

  /**
   * Extends the given object by prototype chain
   *
   * @example
   * var MyApp = Utils.inherit(OSjs.Core.Application, function(name, args, metadata) {
   *  Application.apply(this, arguments);
   * }, {
   *  init: function() {
   *    // then do your stuff here
   *  }
   * });
   *
   * @function inherit
   * @memberof OSjs.Utils
   * @see OSjs.Utils.extend
   *
   * @param {Object}    to        The class to inherit
   * @param {Object}    from      The child class
   * @param {Object}    [extend]  Extend the class with these methods
   */
  OSjs.Utils.inherit = function(to, from, extend) {
    from.prototype = Object.create(to.prototype);
    from.constructor = to;

    if ( extend ) {
      OSjs.Utils.extend(from.prototype, extend);
    }

    return from;
  };

  /////////////////////////////////////////////////////////////////////////////
  // COLORS
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Convert HEX to RGB
   *
   * @function convertToRGB
   * @memberof OSjs.Utils
   *
   * @param   {String}      hex     The hex string (with #)
   *
   * @return  {Object}              RGB in form of r, g, b
   */
  OSjs.Utils.convertToRGB = function(hex) {
    var rgb = parseInt(hex.replace('#', ''), 16);
    var val = {};
    val.r = (rgb & (255 << 16)) >> 16;
    val.g = (rgb & (255 << 8)) >> 8;
    val.b = (rgb & 255);
    return val;
  };

  /**
   * Convert RGB to HEX
   *
   * @function convertToHEX
   * @memberof OSjs.Utils
   *
   * @param   Object      rgb       (ALTERNATIVE 1) The RGB object in form of r, g, b
   * @param   {Number}    r         (ALTERNATIVE 2) Red value
   * @param   {Number}    g         (ALTERNATIVE 2) Green value
   * @param   {Number}    b         (ALTERNATIVE 2) Blue value
   *
   * @return  {String}                Hex string (with #)
   */
  OSjs.Utils.convertToHEX = function(r, g, b) {
    if ( typeof r === 'object' ) {
      g = r.g;
      b = r.b;
      r = r.r;
    }

    if ( typeof r === 'undefined' || typeof g === 'undefined' || typeof b === 'undefined' ) {
      throw new Error('Invalid RGB supplied to convertToHEX()');
    }

    var hex = [
      parseInt(r, 10).toString( 16 ),
      parseInt(g, 10).toString( 16 ),
      parseInt(b, 10).toString( 16 )
    ];

    Object.keys(hex).forEach(function(i) {
      if ( hex[i].length === 1 ) {
        hex[i] = '0' + hex[i];
      }
    });

    return '#' + hex.join('').toUpperCase();
  };

  /**
   * Ivert HEX color
   *
   * @function invertHEX
   * @memberof OSjs.Utils
   * @link http://stackoverflow.com/a/9601429/1236086
   *
   * @param   {String}      hex     Hex string (With #)
   *
   * @return  {String}              Inverted hex (With #)
   *
   */
  OSjs.Utils.invertHEX = function(hex) {
    var color = parseInt(hex.replace('#', ''), 16);
    color = 0xFFFFFF ^ color;
    color = color.toString(16);
    color = ('000000' + color).slice(-6);
    return '#' + color;
  };

  /////////////////////////////////////////////////////////////////////////////
  // ASYNC
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Run an async queue in series
   *
   * @function asyncs
   * @memberof OSjs.Utils
   *
   * @param   {Array}       queue     The queue
   * @param   {Function}    onentry   Callback on step => fn(entry, index, fnNext)
   * @param   {Function}    ondone    Callback on done => fn()
   */
  OSjs.Utils.asyncs = function(queue, onentry, ondone) {
    onentry = onentry || function(e, i, n) {
      n();
    };

    ondone = ondone || function() {
    };

    var finished = [];

    function next(i) {

      // Ensure that the given index is not run again!
      // This might occur if something is out of time
      if ( finished.indexOf(i) !== -1 ) {
        return;
      }
      finished.push(i);

      if ( i >= queue.length ) {
        ondone();
        return;
      }

      try {
        onentry(queue[i], i, function() {
          next(i + 1);
        });
      } catch ( e ) {
        console.warn('Utils::async()', 'Exception while stepping', e.stack, e);
        next(i + 1);
      }
    }

    next(0);
  };

})();
<commit_msg>Utils: Added asyncp() method<commit_after>/*!
 * OS.js - JavaScript Cloud/Web Desktop Platform
 *
 * Copyright (c) 2011-2016, Anders Evenrud <andersevenrud@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @author  Anders Evenrud <andersevenrud@gmail.com>
 * @licence Simplified BSD License
 */
(function() {
  'use strict';

  /////////////////////////////////////////////////////////////////////////////
  // COOKIES
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Gets a cookie by key, or all cookies
   *
   * @function getCookie
   * @memberof OSjs.Utils
   *
   * @param {String} [k] What key to get
   * @return {String|Object}  Depending on 'k' parameter
   */
  OSjs.Utils.getCookie = function(k) {
    var map = {};
    document.cookie.split(/;\s+?/g).forEach(function(i) {
      var idx = i.indexOf('=');
      map[i.substr(i, idx)] = i.substr(idx + 1);
    });
    return k ? map[k] : map;
  };

  /////////////////////////////////////////////////////////////////////////////
  // STRING
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Format a string (almost like sprintf)
   *
   * @function format
   * @memberof OSjs.Utils
   * @link http://stackoverflow.com/a/4673436
   *
   * @param   {String}      format        String format
   * @param   {...String}   s             Insert into format
   *
   * @return  {String}                    The formatted string
   */
  OSjs.Utils.format = function(format) {
    var args = Array.prototype.slice.call(arguments, 1);
    var sprintfRegex = /\{(\d+)\}/g;

    function sprintf(match, number) {
      return number in args ? args[number] : match;
    }

    return format.replace(sprintfRegex, sprintf);
  };

  /**
   * Remove whitespaces and newlines from HTML document
   *
   * @function cleanHTML
   * @memberof OSjs.Utils
   *
   * @param   {String}    html          HTML string input
   *
   * @return  {String}
   */
  OSjs.Utils.cleanHTML = function(html) {
    return html.replace(/\n/g, '')
               .replace(/[\t ]+</g, '<')
               .replace(/\>[\t ]+</g, '><')
               .replace(/\>[\t ]+$/g, '>');
  };

  /**
   * Parses url into a dictionary (supports modification)
   *
   * @function parseurl
   * @memberof OSjs.Utils
   *
   * @param     {String}        url       Input URL
   * @param     {Object}        [modify]  Modify URL with these options
   *
   * @return    {Object}                  Object with protocol, host, path
   */
  OSjs.Utils.parseurl = function(url, modify) {
    modify = modify || {};

    if ( !url.match(/^(\w+\:)\/\//) ) {
      url = '//' + url;
    }

    var protocol = url.split(/^(\w+\:)?\/\//);

    var splitted = (function() {
      var tmp = protocol[2].replace(/^\/\//, '').split('/');
      return {
        proto: (modify.protocol || protocol[1] || window.location.protocol || '').replace(/\:$/, ''),
        host: modify.host || tmp.shift(),
        path: modify.path || '/' + tmp.join('/')
      };
    })();

    function _parts() {
      var parts = [splitted.proto, '://'];

      if ( modify.username ) {
        var authstr = String(modify.username) + ':' + String(modify.password);
        parts.push(authstr);
        parts.push('@');
      }

      parts.push(splitted.host);
      parts.push(splitted.path);
      return parts.join('');
    }

    return {
      protocol: splitted.proto,
      host: splitted.host,
      path: splitted.path,
      url: _parts()
    };
  };

  /**
   * Returns the URL without protocol
   *
   * @function getRelativeURL
   * @memberof OSjs.Utils
   *
   * @param   {String}    orig        Path name
   *
   * @return  {String}
   */
  OSjs.Utils.getRelativeURL = function getRelativeURL(orig) {
    return orig.replace(/^([A-z0-9\-_]+)\:\/\//, '');
  };

  /////////////////////////////////////////////////////////////////////////////
  // OBJECT HELPERS
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Wrapper for merging function argument dictionaries
   *
   * @function argumentDefaults
   * @memberof OSjs.Utils
   *
   * @param  {Object}   args      Given function Dictionary
   * @param  {Object}   defaults  Defaults Dictionary
   * @param  {Boolean}  undef     Check with 'undefined'
   * @return {Object}
   */
  OSjs.Utils.argumentDefaults = function(args, defaults, undef) {
    args = args || {};
    Object.keys(defaults).forEach(function(key) {
      if ( typeof defaults[key] === 'boolean' || typeof defaults[key] === 'number' ) {
        if ( typeof args[key] === 'undefined' || args[key] === null ) {
          args[key] = defaults[key];
        }
      } else {
        args[key] = args[key] || defaults[key];
      }
    });
    return args;
  };

  /**
   * Deep-merge to objects
   *
   * @function mergeObject
   * @memberof OSjs.Utils
   *
   * @param   {Object}      obj1      Object to merge to
   * @param   {Object}      obj2      Object to merge with
   *
   * @return  {Object}                The merged object
   */
  OSjs.Utils.mergeObject = function(obj1, obj2, opts) {
    opts = opts || {};

    for ( var p in obj2 ) {
      if ( obj2.hasOwnProperty(p) ) {
        try {
          if (opts.overwrite === false && obj1.hasOwnProperty(p)) {
            continue;
          }

          if ( obj2[p].constructor === Object ) {
            obj1[p] = OSjs.Utils.mergeObject(obj1[p], obj2[p]);
          } else {
            obj1[p] = obj2[p];
          }
        } catch (e) {
          obj1[p] = obj2[p];
        }
      }
    }
    return obj1;
  };

  /**
   * Clone a object
   *
   * @function cloneObject
   * @memberof OSjs.Utils
   *
   * @param   {Object}      o     The object to clone
   *
   * @return  {Object}            An identical object
   */
  OSjs.Utils.cloneObject = function(o) {
    return JSON.parse(JSON.stringify(o, function(key, value) {
      if ( value && typeof value === 'object' && value.tagName ) {
        return undefined;
      }
      return value;
    }));
  };

  /**
   * Fixes JSON for HTTP requests (in case they were returned as string)
   *
   * @function fixJSON
   * @memberof OSjs.Utils
   *
   * @param   {Mixed}     response      The data
   *
   * @return  {Object}                  JSON
   */
  OSjs.Utils.fixJSON = function(response) {
    if ( typeof response === 'string' ) {
      if ( response.match(/^\{|\[/) ) {
        try {
          response = JSON.parse(response);
        } catch ( e  ) {
          console.warn('FAILED TO FORCE JSON MIME TYPE', e);
        }
      }
    }
    return response;
  };

  /**
   * Extends the given object
   *
   * <pre>
   * If you give a `parentObj` and a prototype method exists
   * in that target, the child object method will be wrapped
   * to make sure the super object method is called.
   * </pre>
   *
   * @example
   * Utils.extend({
   *  a: 'foo'
   * }, {
   *  b: 'bar'
   * }); // -> {a: 'foo', b: 'bar'}
   *
   * @function extend
   * @memberof OSjs.Utils
   *
   * @param {Object}    obj          The destination
   * @param {Object}    methods      The source
   */
  OSjs.Utils.extend = function(obj, methods) {
    if ( obj && methods ) {
      Object.keys(methods).forEach(function(k) {
        obj[k] = methods[k];
      });
    }
  };

  /**
   * Extends the given object by prototype chain
   *
   * @example
   * var MyApp = Utils.inherit(OSjs.Core.Application, function(name, args, metadata) {
   *  Application.apply(this, arguments);
   * }, {
   *  init: function() {
   *    // then do your stuff here
   *  }
   * });
   *
   * @function inherit
   * @memberof OSjs.Utils
   * @see OSjs.Utils.extend
   *
   * @param {Object}    to        The class to inherit
   * @param {Object}    from      The child class
   * @param {Object}    [extend]  Extend the class with these methods
   */
  OSjs.Utils.inherit = function(to, from, extend) {
    from.prototype = Object.create(to.prototype);
    from.constructor = to;

    if ( extend ) {
      OSjs.Utils.extend(from.prototype, extend);
    }

    return from;
  };

  /////////////////////////////////////////////////////////////////////////////
  // COLORS
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Convert HEX to RGB
   *
   * @function convertToRGB
   * @memberof OSjs.Utils
   *
   * @param   {String}      hex     The hex string (with #)
   *
   * @return  {Object}              RGB in form of r, g, b
   */
  OSjs.Utils.convertToRGB = function(hex) {
    var rgb = parseInt(hex.replace('#', ''), 16);
    var val = {};
    val.r = (rgb & (255 << 16)) >> 16;
    val.g = (rgb & (255 << 8)) >> 8;
    val.b = (rgb & 255);
    return val;
  };

  /**
   * Convert RGB to HEX
   *
   * @function convertToHEX
   * @memberof OSjs.Utils
   *
   * @param   Object      rgb       (ALTERNATIVE 1) The RGB object in form of r, g, b
   * @param   {Number}    r         (ALTERNATIVE 2) Red value
   * @param   {Number}    g         (ALTERNATIVE 2) Green value
   * @param   {Number}    b         (ALTERNATIVE 2) Blue value
   *
   * @return  {String}                Hex string (with #)
   */
  OSjs.Utils.convertToHEX = function(r, g, b) {
    if ( typeof r === 'object' ) {
      g = r.g;
      b = r.b;
      r = r.r;
    }

    if ( typeof r === 'undefined' || typeof g === 'undefined' || typeof b === 'undefined' ) {
      throw new Error('Invalid RGB supplied to convertToHEX()');
    }

    var hex = [
      parseInt(r, 10).toString( 16 ),
      parseInt(g, 10).toString( 16 ),
      parseInt(b, 10).toString( 16 )
    ];

    Object.keys(hex).forEach(function(i) {
      if ( hex[i].length === 1 ) {
        hex[i] = '0' + hex[i];
      }
    });

    return '#' + hex.join('').toUpperCase();
  };

  /**
   * Ivert HEX color
   *
   * @function invertHEX
   * @memberof OSjs.Utils
   * @link http://stackoverflow.com/a/9601429/1236086
   *
   * @param   {String}      hex     Hex string (With #)
   *
   * @return  {String}              Inverted hex (With #)
   *
   */
  OSjs.Utils.invertHEX = function(hex) {
    var color = parseInt(hex.replace('#', ''), 16);
    color = 0xFFFFFF ^ color;
    color = color.toString(16);
    color = ('000000' + color).slice(-6);
    return '#' + color;
  };

  /////////////////////////////////////////////////////////////////////////////
  // ASYNC
  /////////////////////////////////////////////////////////////////////////////

  /**
   * Run an async queue in series
   *
   * @function asyncs
   * @memberof OSjs.Utils
   *
   * @param   {Array}       queue     The queue
   * @param   {Function}    onentry   Callback on step => fn(entry, index, fnNext)
   * @param   {Function}    ondone    Callback on done => fn()
   */
  OSjs.Utils.asyncs = function(queue, onentry, ondone) {
    onentry = onentry || function(e, i, n) {
      return n();
    };
    ondone = ondone || function() {};

    var finished = [];

    (function next(i) {
      // Ensure that the given index is not run again!
      // This might occur if something is out of time
      if ( finished.indexOf(i) !== -1 ) {
        return;
      }
      finished.push(i);

      if ( i >= queue.length ) {
        return ondone();
      }

      try {
        onentry(queue[i], i, function() {
          next(i + 1);
        });
      } catch ( e ) {
        console.warn('Utils::asyncs()', 'Exception while stepping', e.stack, e);
        next(i + 1);
      }
    })(0);
  };

  /**
   * Run an async queue in parallel
   *
   * @function asyncp
   * @memberof OSjs.Utils
   *
   * @param   {Array}       queue         The queue
   * @param   {Object}      [opts]        Options
   * @param   {Number}      [opts.max=3]  Maximum number of running entries
   * @param   {Function}    onentry       Callback on step => fn(entry, index, fnNext)
   * @param   {Function}    ondone        Callback on done => fn()
   */
  OSjs.Utils.asyncp = function(queue, opts, onentry, ondone) {
    opts = opts || {};

    var running = 0;
    var max = opts.max || 3;
    var qleft = Object.keys(queue);

    function spawn(i, cb) {
      function _done() {
        running--;
        cb();
      }

      running++;
      try {
        onentry(queue[i], i, _done);
      } catch ( e ) {
        console.warn('Utils::asyncp()', 'Exception while stepping', e.stack, e);
        _done();
      }
    }

    (function check() {
      if ( !qleft.length ) {
        return ondone();
      }
      var d = Math.min(qleft.length, max - running);
      for ( var i = 0; i < d; i++ ) {
        spawn(qleft.shift(), check);
      }
    })();
  };

})();
<|endoftext|>