<commit_before>// 系统模块
var fs = require('fs');

// HTTP 模块与 DOM 解析, 这是爬虫的核心模块
// HTTP 请求
var request = require('superagent'); // 备选模块 request, 也支持 cookie
// node爬虫之gbk网页中文乱码解决方案
// http://www.cnblogs.com/zichi/p/5157887.html
var charset = require('superagent-charset');
charset(request);
// ENOENT thrown when trying to create a file with an invalid filename
// https://github.com/nodejs/node/issues/8987
var sanitize = require('sanitize-filename');

// encodeURIComponent with charset
// https://github.com/alsotang/urlencode

// 辅组类模块
// 解析命令行参数
var commander = require('commander');
// 命令行输入
var inquirer = require('inquirer');
// 命令行输出的颜色
var chalk = require('chalk');
// 如果有比较复杂的输入选择项, 则使用 commander + inquirer 来处理
commander.version('0.1.0')
         .description('我是一个命令行工具')
         .option('-a, --aa [参数1]', '参数1')
         .option('-b, --bb [参数2]', '参数2')
         .parse(process.argv);
console.log('commander', commander.aa, commander.bb);
// 如果没有传入参数, 则直接提示帮助信息后退出
// if (!process.argv.slice(2).length) {
//     commander.help();
// }

// 提示声
var beep = require('beepbeep'); // 如果要更复杂的播放声音 https://github.com/Marak/play.js

// cron 定时任务
var schedule = require('node-schedule');

var crawlerUtil = require('./crawler-util.js');

/**
 * 在请求发出去之前, 做一些通用的默认设置
 * 例如设置统一的超时时间, 统一的 User-Agent 头
 */
function buildAgent(agent) {
    agent.set('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.1708.400 QQBrowser/9.5.9635.400');

    return agent;
}

// HTTP GET
function testGet() {
    var agent = request.get('http://www.best73.com/Corp.html');
    buildAgent(agent);

    return agent.query({
                    q: 1,
                    q2: '哈哈'
                })
                .charset('gb2312')
                .then(crawlerUtil.showMeTheDollar)
                .then(function($) {
                    var title = '';
                    $('head title').each(function() {
                        var $this = $(this);
                        title = $this.text();
                    });

                    return title;
                });
}
// HTTP POST application/x-www-form-urlencoded
function testPostFormUrlEncoded() {
    var agent = request.post('http://www.best73.com/Corp.html');
    buildAgent(agent);

    return agent.type('form')
                .send({
                    q: 1,
                    q2: '哈哈'
                })
                .then(function() {
                    return 'testPostFormUrlEncoded';
                });
}
// HTTP POST application/json
function testPostJson() {
    var agent = request.post('http://www.best73.com/Corp.html');
    buildAgent(agent);

    return agent.send({
                    q: 1,
                    q2: '哈哈'
                })
                .then(function() {
                    return 'testPostJson';
                });
}
// 测试通过 Promise 来控制延时任务
function testPromise() {
    return new Promise(function(resolve, reject) {
        testGet().then(function(title) {
            // console.log(title);
            setTimeout(function() {
                resolve(title);
            }, crawlerUtil.randomInt(2000, 3000));
        });
    });
}
// 测试序列任务
function testSequenceRequest() {
    var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    return array.reduce(function(promise, value) {
        return promise.then(function() {
            return testPostJson().then(function(t) {
                console.log(value, t);
                return t;
            });
        });
    }, Promise.resolve());
}
// 测试共享 Cookie
function testAgentCookie() {
    var agent = request.agent();
    agent.get('http://www.baidu.com') // 第一个页面
         .then(function() {           // 第二个页面, cookie 会一直跟随着
             return agent.get('http://www.baidu.com');
         });
}
// 测试写入文件
function testWriteFile() {
    var dataFileName = '测试中文特殊:/\符号aaa.txt';
    dataFileName = sanitize(dataFileName);
    fs.writeFileSync(dataFileName, dataFileName);
    // fs.appendFileSync();
}
// 测试 Inquirer
function testInquirer() {
    var promps = [];
    promps.push({
        type: 'input',
        name: 'foo',
        message: '请输入',
        validate: function(input) {
            if(!input) {
                return '输入不能为空';
            }
            return true;
        }
    });
    promps.push({
        type: 'list',
        name: 'bar',
        message: '你想用要什么呢',
        choices: [{
            name: 'Text1',
            value: 't1'
        }, {
            name: 'Text2',
            value: 't2'
        }]
    });
    inquirer.prompt(promps).then(function(answers) {
        console.log(answers);
        console.log(chalk.red('我可以做一个命令行工具了...'));
    });
}
function testNotifySound() {
    beep(5, 1000);
}
function testCron() {
    var j = schedule.scheduleJob('*/5 * * * * *', function(){
        console.log('每 5 秒执行一次...');
    });
}

// testNotifySound();
// testCron();
// testWriteFile();
// testInquirer();
// testAgentCookie();
// testGet().then(function(r) {console.log('testGet', r)});
// testPostFormUrlEncoded().then(function(r) {console.log(r)});
// testPostJson().then(function(r) {console.log(r)});
// testPromise().then(function(r) {console.log('testPromise', r);});
// testSequenceRequest().then(function() {console.log('over');});<commit_msg>使用 httpbin 来测试爬虫<commit_after>// 系统模块
var fs = require('fs');

// HTTP 模块与 DOM 解析, 这是爬虫的核心模块
// HTTP 请求
var request = require('superagent'); // 备选模块 request, 也支持 cookie
// node爬虫之gbk网页中文乱码解决方案
// http://www.cnblogs.com/zichi/p/5157887.html
var charset = require('superagent-charset');
charset(request);
// ENOENT thrown when trying to create a file with an invalid filename
// https://github.com/nodejs/node/issues/8987
var sanitize = require('sanitize-filename');

// encodeURIComponent with charset
// https://github.com/alsotang/urlencode

// 辅组类模块
// 解析命令行参数
var commander = require('commander');
// 命令行输入
var inquirer = require('inquirer');
// 命令行输出的颜色
var chalk = require('chalk');
// 如果有比较复杂的输入选择项, 则使用 commander + inquirer 来处理
commander.version('0.1.0')
         .description('我是一个命令行工具')
         .option('-a, --aa [参数1]', '参数1')
         .option('-b, --bb [参数2]', '参数2')
         .parse(process.argv);
console.log('commander', commander.aa, commander.bb);
// 如果没有传入参数, 则直接提示帮助信息后退出
// if (!process.argv.slice(2).length) {
//     commander.help();
// }

// 提示声
var beep = require('beepbeep'); // 如果要更复杂的播放声音 https://github.com/Marak/play.js

// cron 定时任务
var schedule = require('node-schedule');

var crawlerUtil = require('./crawler-util.js');

/**
 * 在请求发出去之前, 做一些通用的默认设置
 * 例如设置统一的超时时间, 统一的 User-Agent 头
 */
function buildAgent(agent) {
    agent.set('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.1708.400 QQBrowser/9.5.9635.400');

    return agent;
}

// HTTP GET
function testGet() {
    var agent = request.get('http://httpbin.org/get');
    buildAgent(agent);

    return agent.query({
                    q: 1,
                    q2: '哈哈'
                })
                .then(function(result) {
                    return result.body;
                });
}
function testGetGb2312Html() {
    var agent = request.get('http://www.best73.com/Corp.html');
    buildAgent(agent);

    return agent.query({
                    q: 1,
                    q2: '哈哈'
                })
                .charset('gb2312')
                .then(crawlerUtil.showMeTheDollar)
                .then(function($) {
                    var title = '';
                    $('head title').each(function() {
                        var $this = $(this);
                        title = $this.text();
                    });

                    return title;
                });
}
// HTTP POST Content-Type: application/x-www-form-urlencoded
function testPostFormUrlEncoded() {
    var agent = request.post('http://httpbin.org/post');
    buildAgent(agent);

    return agent.type('form')
                .send({
                    q: 1,
                    q2: '哈哈'
                })
                .then(function(result) {
                    return result.body;
                });
}
// HTTP POST Content-Type: application/json
function testPostJson() {
    var agent = request.post('http://httpbin.org/post');
    buildAgent(agent);

    return agent.send({
                    q: 1,
                    q2: '哈哈'
                })
                .then(function(result) {
                    return result.body;
                });
}
// 测试通过 Promise 来控制延时任务
function testPromise() {
    return new Promise(function(resolve, reject) {
        testGet().then(function(json) {
            // console.log(json);
            setTimeout(function() {
                resolve(json);
            }, crawlerUtil.randomInt(2000, 3000));
        });
    });
}
// 测试序列任务
function testSequenceRequest() {
    var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

    return array.reduce(function(promise, value) {
        return promise.then(function() {
            return testPostJson().then(function(t) {
                console.log(value, t);
                return t;
            });
        });
    }, Promise.resolve());
}
// 测试共享 Cookie
function testAgentCookie() {
    var agent = request.agent();
    agent.get('http://httpbin.org/cookies/set') // 第一个页面
         .query({
             name: 'crawler'
         })
         .then(function(result) {               // 第二个页面, cookie 会一直跟随着
             console.log(1, result.body.cookies);

             return agent.get('http://httpbin.org/cookies').then(function(result) {
                 console.log(2, result.body.cookies);
                 return result.body;
             });
         });
}
// 测试写入文件
function testWriteFile() {
    var dataFileName = '测试中文特殊:/\符号aaa.txt';
    dataFileName = sanitize(dataFileName);
    fs.writeFileSync(dataFileName, dataFileName);
    // fs.appendFileSync();
}
// 测试 Inquirer
function testInquirer() {
    var promps = [];
    promps.push({
        type: 'input',
        name: 'foo',
        message: '请输入',
        validate: function(input) {
            if(!input) {
                return '输入不能为空';
            }
            return true;
        }
    });
    promps.push({
        type: 'list',
        name: 'bar',
        message: '你想用要什么呢',
        choices: [{
            name: 'Text1',
            value: 't1'
        }, {
            name: 'Text2',
            value: 't2'
        }]
    });
    inquirer.prompt(promps).then(function(answers) {
        console.log(answers);
        console.log(chalk.red('我可以做一个命令行工具了...'));
    });
}
function testNotifySound() {
    beep(5, 1000);
}
function testCron() {
    var j = schedule.scheduleJob('*/5 * * * * *', function(){
        console.log('每 5 秒执行一次...');
    });
}

// testNotifySound();
// testCron();
// testWriteFile();
// testInquirer();
// testAgentCookie();
// testGet().then(function(r) {console.log('testGet', r)});
// testGetGb2312Html().then(function(r) {console.log('testGetGb2312Html', r)});
// testPostFormUrlEncoded().then(function(r) {console.log('testPostFormUrlEncoded', r)});
// testPostJson().then(function(r) {console.log('testPostJson', r)});
// testPromise().then(function(r) {console.log('testPromise', r);});
// testSequenceRequest().then(function() {console.log('over');});<|endoftext|>


<commit_before>JSIL.Audio = {};

JSIL.Audio.InstancePrototype = {
  play: function () {
    this._isPlaying = true;
    this._isPaused = false;

    if (this.$play)
      this.$play();
  },
  pause: function () {
    this._isPlaying = false;
    this._isPaused = true;

    if (this.$pause)
      this.$pause();
  },
  resume: function () {
    this._isPlaying = true;
    this._isPaused = false;

    if (this.$resume)
      this.$resume();
  },
  stop: function () {
    this._isPlaying = false;
    this._isPaused = false;

    if (this.$stop)
      this.$stop();
  },
  dispose: function () {
    // TODO: Return to free instance pool

    if (this.$dispose)
      this.$dispose();
    else
      this.stop();
  },
  get_volume: function () {
    return this._volume;
  },
  set_volume: function (value) {
    this._volume = value;

    if (this.$set_volume)
      this.$set_volume(this._volume * this._volumeMultiplier);
  },
  get_volumeMultiplier: function () {
    return this._volumeMultiplier;
  },
  set_volumeMultiplier: function (value) {
    this._volumeMultiplier = value;

    if (this.$set_volume)
      this.$set_volume(this._volume * this._volumeMultiplier);
  },
  get_loop: function () {
    return this._loop;
  },
  set_loop: function (value) {
    this._loop = value;

    if (this.$set_loop)
      this.$set_loop(value);
  },
  get_isPlaying: function () {
    if (this.$get_isPlaying)
      return this.$get_isPlaying();
    else
      return this._isPlaying;
  },
  get_isPaused: function () {
    if (this.$get_isPaused)
      return this.$get_isPaused();
    else
      return this._isPaused;
  }
};

Object.defineProperty(JSIL.Audio.InstancePrototype, "volume", {
  get: JSIL.Audio.InstancePrototype.get_volume,
  set: JSIL.Audio.InstancePrototype.set_volume,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "volumeMultiplier", {
  get: JSIL.Audio.InstancePrototype.get_volume,
  set: JSIL.Audio.InstancePrototype.set_volume,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "loop", {
  get: JSIL.Audio.InstancePrototype.get_loop,
  set: JSIL.Audio.InstancePrototype.set_loop,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "isPlaying", {
  get: JSIL.Audio.InstancePrototype.get_isPlaying,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "isPaused", {
  get: JSIL.Audio.InstancePrototype.get_isPaused,
  configurable: true,
  enumerable: true
});

JSIL.Audio.HTML5Instance = function (audioInfo, node, loop) {
  this._isPlaying = false;
  this._isPaused = false;
  this.node = node;
  this.node.loop = loop;
  this._volume = 1.0;
  this._volumeMultiplier = 1.0;

  this.$bindEvents();
};
JSIL.Audio.HTML5Instance.prototype = Object.create(JSIL.Audio.InstancePrototype);

JSIL.Audio.HTML5Instance.prototype.$bindEvents = function () {
  this.$onEndedListener = JSIL.Browser.RegisterOneShotEventListener(this.node, "ended", true, this.on_ended.bind(this));
};

JSIL.Audio.HTML5Instance.prototype.$unbindEvents = function () {
  if (this.$onEndedListener)
    this.$onEndedListener.unregister();

  this.$onEndedListener = null;
};

JSIL.Audio.HTML5Instance.prototype.$play = function () {
  this.node.play();
}

JSIL.Audio.HTML5Instance.prototype.$pause = function () {
  this.node.pause();
}

JSIL.Audio.HTML5Instance.prototype.$resume = function () {
  this.node.play();
}

JSIL.Audio.HTML5Instance.prototype.$stop = function () {
  this.node.pause();
}

JSIL.Audio.HTML5Instance.prototype.$set_volume = function (value) {
  return this.node.volume = value;
}

JSIL.Audio.HTML5Instance.prototype.$set_loop = function (value) {
  return this.node.loop = value;
}

JSIL.Audio.HTML5Instance.prototype.on_ended = function () {
  this._isPlaying = false;
  this.dispose();
};

JSIL.Audio.HTML5Instance.prototype.$dispose = function () {
  this.node.pause();

  // Manually unregister the event listener because apparently it's 1996 and
  //  browser GCs still can't actually collect cycles
  this.$unbindEvents();

  // HACK: This forces Gecko-based browsers to free the resources previously
  //  used for audio playback.
  try {
    this.node.removeAttribute("src");
    this.node.load();
  } catch (exc) {
  }
};

JSIL.Audio.WebKitInstance = function (audioInfo, buffer, loop) {
  this.gainNode = audioInfo.audioContext.createGainNode();
  this.gainNode.connect(audioInfo.audioContext.destination);

  this.$createBufferSource = function () {
    this.bufferSource = audioInfo.audioContext.createBufferSource();
    this.bufferSource.buffer = buffer;
    this.bufferSource.loop = loop;
    this.bufferSource.connect(this.gainNode);
  };

  this.context = audioInfo.audioContext;
  this.started = 0;
  this.pausedAtOffset = null;

  this._volume = 1.0;
  this._volumeMultiplier = 1.0;
};
JSIL.Audio.WebKitInstance.prototype = Object.create(JSIL.Audio.InstancePrototype);

JSIL.Audio.WebKitInstance.prototype.$play = function () {
  this.$createBufferSource();
  this.started = this.context.currentTime;
  this.pausedAtOffset = null;
  this.bufferSource.start(0);
}

JSIL.Audio.WebKitInstance.prototype.$pause = function () {
  this.pausedAtOffset = this.context.currentTime - this.started;
  this.$stop();
}

JSIL.Audio.WebKitInstance.prototype.$resume = function () {
  // Apparently it's 1993 and audio APIs must precisely emulate analog
  //  hardware characteristics instead of doing useful things
  // http://stackoverflow.com/a/14715786
  this.$createBufferSource();
  this.started = this.context.currentTime - this.pausedAtOffset;
  this.bufferSource.start(0, this.pausedAtOffset);
  this.pausedAtOffset = null;
}

JSIL.Audio.WebKitInstance.prototype.$stop = function () {
  this.started = 0;
  this.bufferSource.stop(0);
};

JSIL.Audio.WebKitInstance.prototype.$set_volume = function (value) {
  this.gainNode.gain.value = value;
}

JSIL.Audio.WebKitInstance.prototype.$set_loop = function (value) {
  this.bufferSource.loop = value;
}

JSIL.Audio.WebKitInstance.prototype.$get_isPlaying = function () {
  if (!this._isPlaying)
    return false;

  var elapsed = this.context.currentTime - this.started;
  return (elapsed <= this.bufferSource.buffer.duration);
}

JSIL.Audio.NullInstance = function (audioInfo, loop) {
};
JSIL.Audio.NullInstance.prototype = Object.create(JSIL.Audio.InstancePrototype);

function finishLoadingSound (filename, createInstance) {
  $jsilbrowserstate.allAssetNames.push(filename);
  var asset = new CallbackSoundAsset(getAssetName(filename, true), createInstance);
  allAssets[getAssetName(filename)] = asset;
};

function loadNullSound (audioInfo, filename, data, onError, onDoneLoading) {
  var finisher = finishLoadingSound.bind(
    null, filename, function createNullSoundInstance (loop) {
      return new JSIL.Audio.NullInstance(audioInfo, loop);
    }
  );

  onDoneLoading(finisher);
};

function loadWebkitSound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning("Error while loading '" + filename + "': " + text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var uri = audioInfo.selectUri(filename, data);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  loadBinaryFileAsync(uri, function decodeWebkitSound (result, error) {
    if ((result !== null) && (!error)) {
      var decodeCompleteCallback = function (buffer) {
        var finisher = finishLoadingSound.bind(
          null, filename, function createWebKitSoundInstance (loop) {
            return new JSIL.Audio.WebKitInstance(audioInfo, buffer, loop);
          }
        );

        onDoneLoading(finisher);
      };

      var decodeFailedCallback = function () {
        handleError("Unknown audio decoding error");
      };

      // Decode should really happen in the finisher stage, but that stage isn't parallel.
      try {
        audioInfo.audioContext.decodeAudioData(result.buffer, decodeCompleteCallback, decodeFailedCallback);
      } catch (exc) {
        handleError(exc);
      }
    } else {
      handleError(error);
    }
  });
};

function loadStreamingSound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning(text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var uri = audioInfo.selectUri(filename, data);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  var createInstance = function createStreamingSoundInstance (loop) {
    var e = audioInfo.makeAudioInstance();
    e.setAttribute("preload", "auto");
    e.setAttribute("autobuffer", "true");
    e.src = uri;

    if (e.load)
      e.load();

    return new JSIL.Audio.HTML5Instance(audioInfo, e, loop);
  };

  var finisher = finishLoadingSound.bind(
    null, filename, createInstance
  );

  onDoneLoading(finisher);
};

function loadBufferedHTML5Sound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning(text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var mimeType = [null];
  var uri = audioInfo.selectUri(filename, data, mimeType);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  loadBinaryFileAsync(uri, function finishBufferingSound (result, error) {
    if ((result !== null) && (!error)) {
      try {
        var objectUrl = JSIL.GetObjectURLForBytes(result, mimeType[0]);
      } catch (exc) {
        return handleError(exc);
      }

      var createInstance = function createBufferedSoundInstance (loop) {
        var e = audioInfo.makeAudioInstance();
        e.setAttribute("preload", "auto");
        e.setAttribute("autobuffer", "true");
        e.src = objectUrl;

        if (e.load)
          e.load();

        return new JSIL.Audio.HTML5Instance(audioInfo, e, loop);
      };

      var finisher = finishLoadingSound.bind(
        null, filename, createInstance
      );

      onDoneLoading(finisher);
    } else {
      return handleError(error);
    }
  });
}

function loadHTML5Sound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning(text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var uri = audioInfo.selectUri(filename, data);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  var createInstance = function createStreamingSoundInstance (loop) {
    var e = audioInfo.makeAudioInstance();
    e.setAttribute("preload", "auto");
    e.setAttribute("autobuffer", "true");
    e.src = uri;

    if (e.load)
      e.load();

    return new JSIL.Audio.HTML5Instance(audioInfo, e, loop);
  };

  var finisher = finishLoadingSound.bind(
    null, filename, createInstance
  );

  onDoneLoading(finisher);
}

function loadSoundGeneric (audioInfo, filename, data, onError, onDoneLoading) {
  if (audioInfo.disableSound) {
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  } else if (data.stream) {
    return loadStreamingSound(audioInfo, filename, data, onError, onDoneLoading);
  } else if (audioInfo.hasAudioContext) {
    return loadWebkitSound(audioInfo, filename, data, onError, onDoneLoading);
  } else if (audioInfo.hasObjectURL && (audioInfo.hasBlobBuilder || audioInfo.hasBlobCtor)) {
    return loadBufferedHTML5Sound(audioInfo, filename, data, onError, onDoneLoading);
  } else {
    return loadHTML5Sound(audioInfo, filename, data, onError, onDoneLoading);
  }
};

function initSoundLoader () {
  var audioContextCtor = window.webkitAudioContext || window.mozAudioContext || window.AudioContext;

  var audioInfo = Object.create($blobBuilderInfo);

  audioInfo.hasAudioContext = typeof (audioContextCtor) === "function";
  audioInfo.audioContext = null;
  audioInfo.testAudioInstance = null;
  audioInfo.disableSound = jsilConfig.disableSound;

  try {
    audioInfo.testAudioInstance = document.createElement("audio");
    if (typeof (audioInfo.testAudioInstance.play) === "function") {
      audioInfo.makeAudioInstance = function () {
        return document.createElement("audio");
      };
    } else {
      audioInfo.disableSound = true;
    }
  } catch (exc) {
    audioInfo.disableSound = true;
  }

  audioInfo.getMimeType = function (extension, mimeType) {
    if (mimeType)
      return mimeType;

    switch (extension) {
      case ".mp3":
        return "audio/mpeg";
      case ".ogg":
        return "audio/ogg; codecs=vorbis"
      case ".wav":
        return "audio/wav"
    }

    return null;
  }

  audioInfo.canPlayType = function (mimeType) {
    var canPlay = "";

    if (this.testAudioInstance.canPlayType) {
      canPlay = this.testAudioInstance.canPlayType(mimeType);
    } else {
      // Goddamn Safari :|
      canPlay = (mimeType == "audio/mpeg") ? "maybe" : "";
    }

    return (canPlay !== "");
  };

  audioInfo.selectUri = function (filename, data, outMimeType) {
    for (var i = 0; i < data.formats.length; i++) {
      var format = data.formats[i];
      var extension, mimeType = null;

      if (typeof (format) === "string") {
        extension = format;
      } else {
        extension = format.extension;
        mimeType = format.mimetype;
      }

      mimeType = this.getMimeType(extension, mimeType);

      if (this.canPlayType(mimeType)) {
        if (outMimeType)
          outMimeType[0] = mimeType;

        return jsilConfig.contentRoot + filename + extension;
      }
    }

    return null;
  };

  if (audioInfo.hasAudioContext) {
    audioInfo.audioContext = new audioContextCtor();
    // Firefox exposes the AudioContext ctor without actually implementing the API
    audioInfo.hasAudioContext =
      audioInfo.audioContext.decodeAudioData &&
      audioInfo.audioContext.createBufferSource &&
      audioInfo.audioContext.createGainNode &&
      audioInfo.audioContext.destination;
  }

  assetLoaders["Sound"] = loadSoundGeneric.bind(null, audioInfo);

  if (audioInfo.disableSound) {
    JSIL.Host.logWriteLine("WARNING: Your browser has insufficient support for playing audio. Sound is disabled.");
  }
};<commit_msg>Clamp range of HTML5 audio volume values<commit_after>JSIL.Audio = {};

JSIL.Audio.InstancePrototype = {
  play: function () {
    this._isPlaying = true;
    this._isPaused = false;

    if (this.$play)
      this.$play();
  },
  pause: function () {
    this._isPlaying = false;
    this._isPaused = true;

    if (this.$pause)
      this.$pause();
  },
  resume: function () {
    this._isPlaying = true;
    this._isPaused = false;

    if (this.$resume)
      this.$resume();
  },
  stop: function () {
    this._isPlaying = false;
    this._isPaused = false;

    if (this.$stop)
      this.$stop();
  },
  dispose: function () {
    // TODO: Return to free instance pool

    if (this.$dispose)
      this.$dispose();
    else
      this.stop();
  },
  get_volume: function () {
    return this._volume;
  },
  set_volume: function (value) {
    this._volume = value;

    if (this.$set_volume)
      this.$set_volume(this._volume * this._volumeMultiplier);
  },
  get_volumeMultiplier: function () {
    return this._volumeMultiplier;
  },
  set_volumeMultiplier: function (value) {
    this._volumeMultiplier = value;

    if (this.$set_volume)
      this.$set_volume(this._volume * this._volumeMultiplier);
  },
  get_loop: function () {
    return this._loop;
  },
  set_loop: function (value) {
    this._loop = value;

    if (this.$set_loop)
      this.$set_loop(value);
  },
  get_isPlaying: function () {
    if (this.$get_isPlaying)
      return this.$get_isPlaying();
    else
      return this._isPlaying;
  },
  get_isPaused: function () {
    if (this.$get_isPaused)
      return this.$get_isPaused();
    else
      return this._isPaused;
  }
};

Object.defineProperty(JSIL.Audio.InstancePrototype, "volume", {
  get: JSIL.Audio.InstancePrototype.get_volume,
  set: JSIL.Audio.InstancePrototype.set_volume,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "volumeMultiplier", {
  get: JSIL.Audio.InstancePrototype.get_volume,
  set: JSIL.Audio.InstancePrototype.set_volume,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "loop", {
  get: JSIL.Audio.InstancePrototype.get_loop,
  set: JSIL.Audio.InstancePrototype.set_loop,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "isPlaying", {
  get: JSIL.Audio.InstancePrototype.get_isPlaying,
  configurable: true,
  enumerable: true
});

Object.defineProperty(JSIL.Audio.InstancePrototype, "isPaused", {
  get: JSIL.Audio.InstancePrototype.get_isPaused,
  configurable: true,
  enumerable: true
});

JSIL.Audio.HTML5Instance = function (audioInfo, node, loop) {
  this._isPlaying = false;
  this._isPaused = false;
  this.node = node;
  this.node.loop = loop;
  this._volume = 1.0;
  this._volumeMultiplier = 1.0;

  this.$bindEvents();
};
JSIL.Audio.HTML5Instance.prototype = Object.create(JSIL.Audio.InstancePrototype);

JSIL.Audio.HTML5Instance.prototype.$bindEvents = function () {
  this.$onEndedListener = JSIL.Browser.RegisterOneShotEventListener(this.node, "ended", true, this.on_ended.bind(this));
};

JSIL.Audio.HTML5Instance.prototype.$unbindEvents = function () {
  if (this.$onEndedListener)
    this.$onEndedListener.unregister();

  this.$onEndedListener = null;
};

JSIL.Audio.HTML5Instance.prototype.$play = function () {
  this.node.play();
}

JSIL.Audio.HTML5Instance.prototype.$pause = function () {
  this.node.pause();
}

JSIL.Audio.HTML5Instance.prototype.$resume = function () {
  this.node.play();
}

JSIL.Audio.HTML5Instance.prototype.$stop = function () {
  this.node.pause();
}

JSIL.Audio.HTML5Instance.prototype.$set_volume = function (value) {
  if (value < 0)
    value = 0;
  else if (value > 1)
    value = 1;

  return this.node.volume = value;
}

JSIL.Audio.HTML5Instance.prototype.$set_loop = function (value) {
  return this.node.loop = value;
}

JSIL.Audio.HTML5Instance.prototype.on_ended = function () {
  this._isPlaying = false;
  this.dispose();
};

JSIL.Audio.HTML5Instance.prototype.$dispose = function () {
  this.node.pause();

  // Manually unregister the event listener because apparently it's 1996 and
  //  browser GCs still can't actually collect cycles
  this.$unbindEvents();

  // HACK: This forces Gecko-based browsers to free the resources previously
  //  used for audio playback.
  try {
    this.node.removeAttribute("src");
    this.node.load();
  } catch (exc) {
  }
};

JSIL.Audio.WebKitInstance = function (audioInfo, buffer, loop) {
  this.gainNode = audioInfo.audioContext.createGainNode();
  this.gainNode.connect(audioInfo.audioContext.destination);

  this.$createBufferSource = function () {
    this.bufferSource = audioInfo.audioContext.createBufferSource();
    this.bufferSource.buffer = buffer;
    this.bufferSource.loop = loop;
    this.bufferSource.connect(this.gainNode);
  };

  this.context = audioInfo.audioContext;
  this.started = 0;
  this.pausedAtOffset = null;

  this._volume = 1.0;
  this._volumeMultiplier = 1.0;
};
JSIL.Audio.WebKitInstance.prototype = Object.create(JSIL.Audio.InstancePrototype);

JSIL.Audio.WebKitInstance.prototype.$play = function () {
  this.$createBufferSource();
  this.started = this.context.currentTime;
  this.pausedAtOffset = null;
  this.bufferSource.start(0);
}

JSIL.Audio.WebKitInstance.prototype.$pause = function () {
  this.pausedAtOffset = this.context.currentTime - this.started;
  this.$stop();
}

JSIL.Audio.WebKitInstance.prototype.$resume = function () {
  // Apparently it's 1993 and audio APIs must precisely emulate analog
  //  hardware characteristics instead of doing useful things
  // http://stackoverflow.com/a/14715786
  this.$createBufferSource();
  this.started = this.context.currentTime - this.pausedAtOffset;
  this.bufferSource.start(0, this.pausedAtOffset);
  this.pausedAtOffset = null;
}

JSIL.Audio.WebKitInstance.prototype.$stop = function () {
  this.started = 0;
  this.bufferSource.stop(0);
};

JSIL.Audio.WebKitInstance.prototype.$set_volume = function (value) {
  this.gainNode.gain.value = value;
}

JSIL.Audio.WebKitInstance.prototype.$set_loop = function (value) {
  this.bufferSource.loop = value;
}

JSIL.Audio.WebKitInstance.prototype.$get_isPlaying = function () {
  if (!this._isPlaying)
    return false;

  var elapsed = this.context.currentTime - this.started;
  return (elapsed <= this.bufferSource.buffer.duration);
}

JSIL.Audio.NullInstance = function (audioInfo, loop) {
};
JSIL.Audio.NullInstance.prototype = Object.create(JSIL.Audio.InstancePrototype);

function finishLoadingSound (filename, createInstance) {
  $jsilbrowserstate.allAssetNames.push(filename);
  var asset = new CallbackSoundAsset(getAssetName(filename, true), createInstance);
  allAssets[getAssetName(filename)] = asset;
};

function loadNullSound (audioInfo, filename, data, onError, onDoneLoading) {
  var finisher = finishLoadingSound.bind(
    null, filename, function createNullSoundInstance (loop) {
      return new JSIL.Audio.NullInstance(audioInfo, loop);
    }
  );

  onDoneLoading(finisher);
};

function loadWebkitSound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning("Error while loading '" + filename + "': " + text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var uri = audioInfo.selectUri(filename, data);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  loadBinaryFileAsync(uri, function decodeWebkitSound (result, error) {
    if ((result !== null) && (!error)) {
      var decodeCompleteCallback = function (buffer) {
        var finisher = finishLoadingSound.bind(
          null, filename, function createWebKitSoundInstance (loop) {
            return new JSIL.Audio.WebKitInstance(audioInfo, buffer, loop);
          }
        );

        onDoneLoading(finisher);
      };

      var decodeFailedCallback = function () {
        handleError("Unknown audio decoding error");
      };

      // Decode should really happen in the finisher stage, but that stage isn't parallel.
      try {
        audioInfo.audioContext.decodeAudioData(result.buffer, decodeCompleteCallback, decodeFailedCallback);
      } catch (exc) {
        handleError(exc);
      }
    } else {
      handleError(error);
    }
  });
};

function loadStreamingSound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning(text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var uri = audioInfo.selectUri(filename, data);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  var createInstance = function createStreamingSoundInstance (loop) {
    var e = audioInfo.makeAudioInstance();
    e.setAttribute("preload", "auto");
    e.setAttribute("autobuffer", "true");
    e.src = uri;

    if (e.load)
      e.load();

    return new JSIL.Audio.HTML5Instance(audioInfo, e, loop);
  };

  var finisher = finishLoadingSound.bind(
    null, filename, createInstance
  );

  onDoneLoading(finisher);
};

function loadBufferedHTML5Sound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning(text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var mimeType = [null];
  var uri = audioInfo.selectUri(filename, data, mimeType);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  loadBinaryFileAsync(uri, function finishBufferingSound (result, error) {
    if ((result !== null) && (!error)) {
      try {
        var objectUrl = JSIL.GetObjectURLForBytes(result, mimeType[0]);
      } catch (exc) {
        return handleError(exc);
      }

      var createInstance = function createBufferedSoundInstance (loop) {
        var e = audioInfo.makeAudioInstance();
        e.setAttribute("preload", "auto");
        e.setAttribute("autobuffer", "true");
        e.src = objectUrl;

        if (e.load)
          e.load();

        return new JSIL.Audio.HTML5Instance(audioInfo, e, loop);
      };

      var finisher = finishLoadingSound.bind(
        null, filename, createInstance
      );

      onDoneLoading(finisher);
    } else {
      return handleError(error);
    }
  });
}

function loadHTML5Sound (audioInfo, filename, data, onError, onDoneLoading) {
  var handleError = function (text) {
    JSIL.Host.warning(text);
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  };

  var uri = audioInfo.selectUri(filename, data);
  if (uri == null)
    return handleError("No supported formats for '" + filename + "'.");

  var createInstance = function createStreamingSoundInstance (loop) {
    var e = audioInfo.makeAudioInstance();
    e.setAttribute("preload", "auto");
    e.setAttribute("autobuffer", "true");
    e.src = uri;

    if (e.load)
      e.load();

    return new JSIL.Audio.HTML5Instance(audioInfo, e, loop);
  };

  var finisher = finishLoadingSound.bind(
    null, filename, createInstance
  );

  onDoneLoading(finisher);
}

function loadSoundGeneric (audioInfo, filename, data, onError, onDoneLoading) {
  if (audioInfo.disableSound) {
    return loadNullSound(audioInfo, filename, data, onError, onDoneLoading);
  } else if (data.stream) {
    return loadStreamingSound(audioInfo, filename, data, onError, onDoneLoading);
  } else if (audioInfo.hasAudioContext) {
    return loadWebkitSound(audioInfo, filename, data, onError, onDoneLoading);
  } else if (audioInfo.hasObjectURL && (audioInfo.hasBlobBuilder || audioInfo.hasBlobCtor)) {
    return loadBufferedHTML5Sound(audioInfo, filename, data, onError, onDoneLoading);
  } else {
    return loadHTML5Sound(audioInfo, filename, data, onError, onDoneLoading);
  }
};

function initSoundLoader () {
  var audioContextCtor = window.webkitAudioContext || window.mozAudioContext || window.AudioContext;

  var audioInfo = Object.create($blobBuilderInfo);

  audioInfo.hasAudioContext = typeof (audioContextCtor) === "function";
  audioInfo.audioContext = null;
  audioInfo.testAudioInstance = null;
  audioInfo.disableSound = jsilConfig.disableSound;

  try {
    audioInfo.testAudioInstance = document.createElement("audio");
    if (typeof (audioInfo.testAudioInstance.play) === "function") {
      audioInfo.makeAudioInstance = function () {
        return document.createElement("audio");
      };
    } else {
      audioInfo.disableSound = true;
    }
  } catch (exc) {
    audioInfo.disableSound = true;
  }

  audioInfo.getMimeType = function (extension, mimeType) {
    if (mimeType)
      return mimeType;

    switch (extension) {
      case ".mp3":
        return "audio/mpeg";
      case ".ogg":
        return "audio/ogg; codecs=vorbis"
      case ".wav":
        return "audio/wav"
    }

    return null;
  }

  audioInfo.canPlayType = function (mimeType) {
    var canPlay = "";

    if (this.testAudioInstance.canPlayType) {
      canPlay = this.testAudioInstance.canPlayType(mimeType);
    } else {
      // Goddamn Safari :|
      canPlay = (mimeType == "audio/mpeg") ? "maybe" : "";
    }

    return (canPlay !== "");
  };

  audioInfo.selectUri = function (filename, data, outMimeType) {
    for (var i = 0; i < data.formats.length; i++) {
      var format = data.formats[i];
      var extension, mimeType = null;

      if (typeof (format) === "string") {
        extension = format;
      } else {
        extension = format.extension;
        mimeType = format.mimetype;
      }

      mimeType = this.getMimeType(extension, mimeType);

      if (this.canPlayType(mimeType)) {
        if (outMimeType)
          outMimeType[0] = mimeType;

        return jsilConfig.contentRoot + filename + extension;
      }
    }

    return null;
  };

  if (audioInfo.hasAudioContext) {
    audioInfo.audioContext = new audioContextCtor();
    // Firefox exposes the AudioContext ctor without actually implementing the API
    audioInfo.hasAudioContext =
      audioInfo.audioContext.decodeAudioData &&
      audioInfo.audioContext.createBufferSource &&
      audioInfo.audioContext.createGainNode &&
      audioInfo.audioContext.destination;
  }

  assetLoaders["Sound"] = loadSoundGeneric.bind(null, audioInfo);

  if (audioInfo.disableSound) {
    JSIL.Host.logWriteLine("WARNING: Your browser has insufficient support for playing audio. Sound is disabled.");
  }
};<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule React
 */
 'use strict';
 module.exports = require('react/lib/React');
<commit_msg>Fix Relay tests, fix React.js whitespace<commit_after>/**
 * Copyright (c) 2016-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @providesModule React
 */

'use strict';

module.exports = require('react/lib/React');
<|endoftext|>


<commit_before>/*
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Mick Hakobyan
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

// core implementation
(function (global, undefined) {
    "use strict";

    // export
    if (global.module) {
        // Node.js
        global.module.exports = Promise;
    } else {
        // <script />
        (global.chnobean = global.chnobean || {}).Promise = Promise;
    }

    /**
    * @constructor
    * @param {function(function, function)} resolver
    */
    function Promise(resolver) {
        if (resolver) {
            try {
                resolver(this._doResolve.bind(this), this._doReject.bind(this));
            } catch(e) {
                this._doReject(e);
            }
        }
    }

    /**
    * @param {function=} onResolve is executed when this promise is fulfilled
    * @param {function=} onReject is executed when this promise is rejected
    */
    Promise.prototype.then = function Promise_then(onResolve, onReject) {
        var promise = new Promise();
        promise._onResolve = onResolve;
        promise._onReject = onReject;
        this._when(promise);
        return promise;
    };

    /**
    * @param {function} onReject
    *
    * Sugar for promise.then(undefined, onReject)
    */
    Promise.prototype.catch = function Promise_catch(onReject) {
        return this.then(undefined, onReject);
    };

    /**
    * @param {*=} result
    *
    * Creates a promise resolved for result.
    */
    Promise.resolve = function Promise_resolve(result) {
        var promise = new Promise();
        promise._resolved = true;
        promise._result = result;
        return promise;
    };

    /**
    * @param {*=} error
    *
    * Creates a promise rejected with error.
    */
    Promise.reject = function Promise_reject(error) {
        var promise = new Promise();
        promise._resolved = false;
        promise._error = error;
        return promise;
    };

    // --------------------------------------------------------------------------------
    // -- private implementation
    // --------------------------------------------------------------------------------

    /**
    * Used instead of "instanceof" for performance reasons.
    */
    Promise.prototype._isPromise = true;

    /**
    * Resolve this promise and process deferals
    */
    Promise.prototype._doResolve = function Promise_doResolve(result) {
        if (this._resolved === undefined) {
            this._resolved = true;
            this._result = result;
            this._settleDefered();
        }
    };

    /**
    * Reject this promise and process deferals
    */
    Promise.prototype._doReject = function Promise_doReject(error) {
        if (this._resolved === undefined) {
            this._resolved = false;
            this._error = error;
            this._settleDefered();
        }
    };

    /**
    * If this one is resolved, settle given promise or defer it's settlement
    */
    Promise.prototype._when = function Promise_when(promise) {
        if (this._resolved !== undefined) {
            // we are resolved, settle the given promise
            promise._settle(this);
        } else {
            // defer the settlement
            this._deferred = this._deferred || [];
            this._deferred.push(promise);
        }
    };

    /**
    * Settle promised whos settlement was defered
    */
    Promise.prototype._settleDefered = function Promise_settleDefered() {
        // assert(this._resolved !== undefined)
        var deferred = this._deferred,
            deferredLength,
            i;
        if (deferred) {
            this._deferred = undefined;
            deferredLength = deferred.length;
            for(i = 0; i < deferredLength; i++) {
                deferred[i]._settle(this);
            }
        }
    };

    /**
    * Settle this promise (called by the one before, when it's resolved)
    */
    Promise.prototype._settle = function Promise_settle(settledBy) {
        // assert(settledBy._resolved !== undefined)
        var resolved = settledBy._resolved,
            result = settledBy._result,
            error = settledBy._error,
            onResolve,
            onReject,
            newResult;

        if (result && result._isPromise) {
            // previous promise resolved to a promise, forward this to that promise
            result._when(this);
        } else {
            // settle this promise given result or error
            // cache and kill the onResolve and onReject we got from .then(onResolve, onReject)
            onResolve = this._onResolve;
            onReject = this._onReject;
            this._onResolve = undefined;
            this._onReject = undefined;
            if (resolved) {
                // resolve
                if (onResolve) {
                    try {
                        newResult = onResolve.call(this, result);
                        this._doResolve(newResult);
                    } catch(e) {
                        this._doReject(e);
                    }
                } else {
                    this._doResolve(result);
                }
            } else {
                // reject
                if (onReject) {
                    try {
                        newResult = onReject.call(this, error);
                        this._doResolve(newResult);
                    } catch(e) {
                        this._doReject(e);
                    }
                } else {
                    this._doReject(error);
                }

            }
        }
    };

})(this);<commit_msg>Refactored to have less "private" functions on prototype<commit_after>/*
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Mick Hakobyan
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

// core implementation
(function (global, undefined) {
    "use strict";

    // export
    if (global.module) {
        // Node.js
        global.module.exports = Promise;
    } else {
        // <script />
        (global.chnobean = global.chnobean || {}).Promise = Promise;
    }

    /**
    * @constructor
    * @param {function(function, function)} resolver
    */
    function Promise(resolver) {
        if (resolver) {
            try {
                resolver(
                    Promise_fulfill.bind(undefined, this),
                    Promise_reject.bind(undefined, this)
                );
            } catch(e) {
                Promise_reject(this, e);
            }
        }
    }

    /**
    * @param {function=} onFulfilled is executed when this promise is fulfilled
    * @param {function=} onRejected is executed when this promise is rejected
    */
    Promise.prototype.then = function Promise_then(onFulfilled, onRejected) {
        var promise = new Promise();
        promise._onFulfilled = onFulfilled;
        promise._onRejected = onRejected;
        Promise_when(this, promise);
        return promise;
    };

    /**
    * @param {function} onRejected
    *
    * Sugar for promise.then(undefined, onRejected)
    */
    Promise.prototype.catch = function Promise_catch(onRejected) {
        return this.then(undefined, onRejected);
    };

    /**
    * @param {*=} result
    *
    * Creates a promise resolved for result.
    */
    Promise.resolve = function Promise_resolve(result) {
        var promise = new Promise();
        promise._fulfilled = true;
        promise._result = result;
        return promise;
    };

    /**
    * @param {*=} error
    *
    * Creates a promise rejected with error.
    */
    Promise.reject = function Promise_reject(error) {
        var promise = new Promise();
        promise._fulfilled = false;
        promise._error = error;
        return promise;
    };

    // --------------------------------------------------------------------------------
    // -- private implementation
    // --------------------------------------------------------------------------------

    /**
    * Used instead of "instanceof" for performance reasons.
    */
    Promise.prototype._isPromise = true;

    /**
    * Fulfills the promise and resolve deferals
    */
    function Promise_fulfill(promise, result) {
        if (promise._fulfilled === undefined) {
            promise._fulfilled = true;
            promise._result = result;
            Promise_resolveDeferred(promise);
        }
    };

    /**
    * Reject the promise and resolve deferals
    */
    function Promise_reject(promise, error) {
        if (promise._fulfilled === undefined) {
            promise._fulfilled = false;
            promise._error = error;
            Promise_resolveDeferred(promise);
        }
    };

    /**
    * Once promise is resolved, resolve nextPromise
    */
    function Promise_when(promise, nextPromise) {
        if (promise._fulfilled !== undefined) {
            // we are resolved, resolve the given promise
            Promise_resolve(nextPromise, promise);
        } else {
            // defer the resolution
            promise._deferred = promise._deferred || [];
            promise._deferred.push(nextPromise);
        }
    };

    /**
    * Resolves deffered promises
    */
    function Promise_resolveDeferred(promise) {
        // assert(promise._fulfilled !== undefined)
        var deferred = promise._deferred,
            deferredLength,
            i;
        if (deferred) {
            promise._deferred = undefined;
            deferredLength = deferred.length;
            for(i = 0; i < deferredLength; i++) {
                Promise_resolve(deferred[i], promise);
            }
        }
    };

    /**
    * Resolves promise (called by the one before, when it's resolved)
    */
    function Promise_resolve(promise, resolvedBy) {
        // assert(resolvedBy._fulfilled !== undefined)
        var resolved = resolvedBy._fulfilled,
            result = resolvedBy._result,
            error = resolvedBy._error,
            onFulfilled,
            onRejected,
            newResult;

        if (result && result._isPromise) {
            // previous promise resolved to a promise, forward the promose
            Promise_when(result, promise);
        } else {
            // resolve promise given result or error
            // cache and kill the onFulfilled and onRejected we got from .then(onFulfilled, onRejected)
            onFulfilled = promise._onFulfilled;
            onRejected = promise._onRejected;
            promise._onFulfilled = undefined;
            promise._onRejected = undefined;
            if (resolved) {
                // resolve
                if (onFulfilled) {
                    try {
                        newResult = onFulfilled.call(promise, result);
                        Promise_fulfill(promise, newResult);
                    } catch(e) {
                        Promise_reject(promise, e);
                    }
                } else {
                    Promise_fulfill(promise, result);
                }
            } else {
                // reject
                if (onRejected) {
                    try {
                        newResult = onRejected.call(promise, error);
                        Promise_fulfill(promise, newResult);
                    } catch(e) {
                        Promise_reject(promise, e);
                    }
                } else {
                    Promise_reject(promise, error);
                }

            }
        }
    };

})(this);<|endoftext|>


<commit_before>(function(coinswap) {

coinswap.TransactionsView = Backbone.View.extend({
  template: _.template($('#template-transactions').html()),
  rowTemplate: _.template($('#template-transactions-row').html()),
  className: 'container transactions',

  initialize: function() {
    _.bindAll(this, 'addTransaction');
    var t = this;
    this.render();
    this.collection.each(function(coin) {
      var transactions = coin.get('transactions');
      t.listenTo(transactions, 'add', t.addTransaction);
      transactions.each(t.addTransaction);
    });
  },

  render: function() {
    this.$el.html(this.template({}));
  },

  addTransaction: function(tx) {
    tx.window = window;
    var row = $('<tr>').html(this.rowTemplate(tx.attributes));
    this.$el.find('tbody').prepend(row);
  }
});

})(coinswap);
<commit_msg>Fixed ordering of transactions across different currencies<commit_after>(function(coinswap) {

coinswap.TransactionsView = Backbone.View.extend({
  template: _.template($('#template-transactions').html()),
  rowTemplate: _.template($('#template-transactions-row').html()),
  className: 'container transactions',

  initialize: function() {
    _.bindAll(this, 'addTransaction');
    var t = this;
    this.render();

    var combined = new coinswap.TransactionCollection;
    this.collection.each(function(coin) {
      var transactions = coin.get('transactions');
      t.listenTo(transactions, 'add', t.addTransaction);
      transactions.each(function(tx){ combined.add(tx); });
    });
    combined.each(this.addTransaction);
  },

  render: function() {
    this.$el.html(this.template({}));
  },

  addTransaction: function(tx) {
    tx.window = window;
    var row = $('<tr>').html(this.rowTemplate(tx.attributes));
    this.$el.find('tbody').prepend(row);
  }
});

})(coinswap);
<|endoftext|>


<commit_before>define( [

  "dojo/_base/declare"
, "dojo/topic"

, "dijit/form/Button"
, "dijit/Dialog"

], function(

  declare
, topic

, Button
, Dialog

){

  return declare( [ Dialog ], {

    startup: function(){
      this.inherited(arguments);
      this.show();
    },

    postCreate: function(){

      this.inherited(arguments);
      var self = this;

      if( this.hideOn ){
        // Honour the hideOn attribute
        topic.subscribe( this.hideOn, function(){
          self.hide();
        });
      };
    },

    // Hiding this widget will destroy it. This widget is good for disposable dialogs
    hide: function(){

      var self = this;
      var p = self.inherited(arguments);

      // Attach a new callback triggered when the animation is over:
      // the callback will destroy the widget
      if( p ) {
        var newPromise = p.then( function(){
          self.destroyRecursive();
        });
        return newPromise;
      } else {
        return p;
      }

    },

  });

});

<commit_msg>Improved tempDialog, now responds to forceResise event<commit_after>define( [

  "dojo/_base/declare"
, "dojo/topic"
, "dojo/on"

, "dijit/Destroyable"
, "dijit/form/Button"
, "dijit/Dialog"

], function(

  declare
, topic
, on

, Destroyable
, Button
, Dialog

){

  return declare( [ Dialog, Destroyable ], {

    startup: function(){
      this.inherited(arguments);
      this.show();
    },

    postCreate: function(){

      this.inherited(arguments);
      var self = this;

      // Honour the force-resize event
      this.own(
        on( self.domNode, 'force-resize', function( e ){
          self.resize();
        })
      );

      if( this.hideOn ){
        // Honour the hideOn attribute
        topic.subscribe( this.hideOn, function(){
          self.hide();
        });
      };
    },

    // Hiding this widget will destroy it. This widget is good for disposable dialogs
    hide: function(){

      var self = this;
      var p = self.inherited(arguments);

      // Attach a new callback triggered when the animation is over:
      // the callback will destroy the widget
      if( p ) {
        var newPromise = p.then( function(){
          self.destroyRecursive();
        });
        return newPromise;
      } else {
        return p;
      }

    },

  });

});

<|endoftext|>


<commit_before>Ext.define('Datanium.view.charts.ChartToolbar', {
	extend : 'Ext.toolbar.Toolbar',
	xtype : 'basic-buttons',
	alias : 'widget.chart-toolbar',
	shadowOffset : 10,
	minHeight : 38,
	padding : '0 5',
	initComponent : function() {
		this.callParent();
	},
	items : [ {
		xtype : 'splitbutton',
		iconCls : 'fa fa-bar-chart-o',
		cls : 'chartTypeBtn',
		scale : 'medium',
		tooltip : 'Column Chart',
		tooltipType : 'title',
		text : 'Column Chart',
		menu : [ {
			iconCls : 'fa fa-star-o',
			text : 'Column Chart',
			handler : function() {
				this.parentMenu.ownerButton.setText('Column Chart');
				Datanium.util.CommonUtils.markSelection(this);
				if (Datanium.GlobalData.chartMode != 'columnchart') {
					Datanium.GlobalData.chartMode = 'columnchart';
					Datanium.util.CommonUtils.generateChart();
				}
			}
		}, {
			text : 'Stack Chart',
			handler : function() {
				this.parentMenu.ownerButton.setText('Stack Chart');
				Datanium.util.CommonUtils.markSelection(this);
				if (Datanium.GlobalData.chartMode != 'stackchart') {
					Datanium.GlobalData.chartMode = 'stackchart';
					Datanium.util.CommonUtils.generateChart();
				}
			}
		}, {
			text : 'Line Chart',
			handler : function() {
				this.parentMenu.ownerButton.setText('Line Chart');
				Datanium.util.CommonUtils.markSelection(this);
				if (Datanium.GlobalData.chartMode != 'linechart') {
					Datanium.GlobalData.chartMode = 'linechart';
					Datanium.util.CommonUtils.generateChart();
				}
			}
		} ]
	}, {
		xtype : 'tbseparator',
		height : 14,
		margins : '0 0 0 1'
	}, {
		id : 'dimSwitch',
		xtype : 'splitbutton',
		iconCls : 'fa fa-cube',
		cls : 'chartTypeBtn',
		scale : 'medium',
		tooltip : 'Column Chart',
		tooltipType : 'title',
		text : 'Primary Dimension',
		menu : []
	}, {
		xtype : 'tbseparator',
		height : 14,
		margins : '0 0 0 1'
	}, {
		iconCls : 'fa fa-arrows fa',
		cls : 'chartTypeBtn',
		scale : 'medium',
		tooltip : 'Auto Scale',
		tooltipType : 'title',
		text : 'Auto Scale',
		action : 'auto-scale',
		enableToggle : true,
		pressed : false
	} ]
});<commit_msg>chart toolbar improvement<commit_after>Ext.define('Datanium.view.charts.ChartToolbar', {
	extend : 'Ext.toolbar.Toolbar',
	xtype : 'basic-buttons',
	alias : 'widget.chart-toolbar',
	shadowOffset : 10,
	minHeight : 38,
	padding : '0 5',
	initComponent : function() {
		this.callParent();
	},
	items : [ {
		xtype : 'splitbutton',
		iconCls : 'fa fa-bar-chart-o',
		cls : 'chartTypeBtn',
		scale : 'medium',
		tooltip : 'Column Chart',
		tooltipType : 'title',
		text : 'Column Chart',
		handler : function() {
			this.showMenu();
		},
		menu : [ {
			iconCls : 'fa fa-star-o',
			text : 'Column Chart',
			handler : function() {
				this.parentMenu.ownerButton.setText('Column Chart');
				Datanium.util.CommonUtils.markSelection(this);
				if (Datanium.GlobalData.chartMode != 'columnchart') {
					Datanium.GlobalData.chartMode = 'columnchart';
					Datanium.util.CommonUtils.generateChart();
				}
			}
		}, {
			text : 'Stack Chart',
			handler : function() {
				this.parentMenu.ownerButton.setText('Stack Chart');
				Datanium.util.CommonUtils.markSelection(this);
				if (Datanium.GlobalData.chartMode != 'stackchart') {
					Datanium.GlobalData.chartMode = 'stackchart';
					Datanium.util.CommonUtils.generateChart();
				}
			}
		}, {
			text : 'Line Chart',
			handler : function() {
				this.parentMenu.ownerButton.setText('Line Chart');
				Datanium.util.CommonUtils.markSelection(this);
				if (Datanium.GlobalData.chartMode != 'linechart') {
					Datanium.GlobalData.chartMode = 'linechart';
					Datanium.util.CommonUtils.generateChart();
				}
			}
		} ]
	}, {
		xtype : 'tbseparator',
		height : 14,
		margins : '0 0 0 1'
	}, {
		id : 'dimSwitch',
		xtype : 'splitbutton',
		iconCls : 'fa fa-cube',
		cls : 'chartTypeBtn',
		scale : 'medium',
		tooltip : 'Column Chart',
		tooltipType : 'title',
		text : 'Primary Dimension',
		handler : function() {
			this.showMenu();
		},
		menu : []
	}, {
		xtype : 'tbseparator',
		height : 14,
		margins : '0 0 0 1'
	}, {
		iconCls : 'fa fa-arrows fa',
		cls : 'chartTypeBtn',
		scale : 'medium',
		tooltip : 'Auto Scale',
		tooltipType : 'title',
		text : 'Auto Scale',
		action : 'auto-scale',
		enableToggle : true,
		pressed : false
	} ]
});<|endoftext|>


<commit_before>console.log(html`<b>${process.argv[2]} says</b>: "${process.argv[3]}"`);
<commit_msg>Add last exercise of 'count-to-6'<commit_after>console.log(html`<b>${process.argv[2]} says</b>: "${process.argv[3]}"`);

function html (strs, ...args) {
  let p1 = strs[0],
      p2 = args[0],
      p3 = strs[1],
      p4 = args[1],
      p5 = strs[2];

  return `${p1}${entities(p2)}${p3}${entities(p4)}${p5}`;
}

function entities(str) {
  return str.replace(/&/g, '&')
            .replace(/>/g, '>')
            .replace(/</g, '&lt')
            .replace(/"/g, '"')
            .replace(/'/g, ''');
}
<|endoftext|>


<commit_before>

var allTestFiles = [];
var TEST_REGEXP = /\/spec\//i;

// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function (file) {
    if (TEST_REGEXP.test(file)) {
        // console.log(file);
        // Normalize paths to RequireJS module names.
        // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
        // then do not normalize the paths
        var normalizedTestModule = file.replace('/js/src/js/', '/js/');
        allTestFiles.push(normalizedTestModule);
    }
});

require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base/js/src',
    paths: {
        // spec: '../tests/spec',
        router: 'router/router',

        initialState: '../tests/lib/initialState',

        app: 'core/app-config',
        jquery: '../lib/jquery-latest',
        jqueryUI: '../lib/jquery-ui',
        'jaddons': '../lib/jquery-addons',
        underscore: '../lib/lodash.min',
        backbone: '../lib/backbone-min-my',
        'backbone-epoxy': '../lib/backbone-epoxy',
        util: 'core/util',
        'baron': '../lib/baron',
        'TestRoute': 'router/TestRoute',
        'landingPage': 'landing/LandingPage',
        cookie: '../lib/jquery.cookie',
        nicescroll: '../lib/jquery.nicescroll',
        bootstrap: '../lib/bootstrap.min',
        bootswitch: '../lib/bootstrap-switch.min',
        elementQuery: '../lib/EQCSS',
        base64: '../lib/base64',
        nprogress: '../lib/nprogress',
        localization: 'localizations/default',
        moment: '../lib/moment.2.10.2',
        message: 'message/message-panel',
        templates: '../../compiled/templates/templates',
        mainview: 'main-view',
        favorites: 'favorites/favorites',
        register: 'register/register',
        filters: 'filter/filters',
        components: 'core/components',
        lazyload: '../lib/jquery.lazyload.min',
        daterangepicker: '../lib/daterangepicker',
        'readmore-js': '../lib/readmore',
        select2: '../lib/select2.custom',
        launch: 'launch/launch-navigation',
        launchgrid: 'launch/launch-grid',
        launchCrumbs: 'launch/launch-crumbs',
        defectEditor: 'defect/defect-editor',
        log: 'log/logs',
        member: 'member/member',
        memberService: 'member/service',
        launchEditor: 'launch/launch-editor',
        stickyHeader: 'core/sticky-header',
        'launchCrumbs': 'launch/launch-crumbs',
        log: 'log/logs',
        'DemoDataSettingsView': 'project/DemoDataSettingsView',

        dataUrlResolver: 'core/data-url-resolver',
        project: 'project/project',
        'projectinfo': 'project/projectinfo',
        validators: 'core/validators',
        validate: '../lib/jquery.validate',

        filtersPanel: 'filter/filters-panel',
        filtersResolver: 'filter/filters-resolver',
        filtersService: 'filter/filters-service',
        profile: 'login/user_profile',
        ace: '../lib/ace/ace.custom',
        aceDark: '../lib/ace/theme-dark',
        'mode-properties': '../lib/ace/mode-properties',

        "colorpicker": "../lib/colorpicker/bootstrap-colorpicker",
        "colorpickerConfig": "../lib/colorpicker/bootstrap-colorpicker-cfg-custom",

        'lunr': '../lib/lunr',

        callService: 'core/call-service',
        coreService: 'core/core-service',
        storageService: 'core/storage-service',
        widgetWizard: 'wizard/widget',
        widgets: 'widget/widgets',
        dashboard: 'dashboard/dashboard-view',
        'fullscreen': '../lib/jquery.fullscreen',
        'isLoading': '../lib/jquery.isLoading',
        'equalHeightRows': '../lib/grids',
        'popup': '../lib/jquery.magnific-popup',
        'highlight': '../lib/highlight.pack',
        'gridstack': '../lib/gridstack/gridstack.custom',
        helpers: 'core/helpers',

        d3: '../lib/d3/d3.v3.min',
        nvd3: '../lib/nvd3/nv.d3.custom',
        d3Tip: '../lib/d3/d3.tip.custom',
        elasticColumns: '../lib/elastic-columns.min',
        'slick': '../lib/slick',
        'landingMain': 'landing/main',
        'landingUI': 'landing/ui',
        'landingDocs': 'landing/documentation',

        admin: 'admin/admin',
        projects: 'admin/projects',
        users: 'admin/users',
        settings: 'admin/settings',
        adminService: 'admin/service',

        'textile': '../lib/textile',
        'markitup': '../lib/jquery.markitup.custom',
        'markitupset': '../lib/jquery.markitup.textile',
        'stickyHeader': 'core/sticky-header',
        'cacheService': 'core/cache-service',
        'scrollable': 'core/scrollable-view',
        "text" : "../lib/text",

        fakeData: '../tests/mocks/data',
        adminFakeData: '../tests/mocks/adminData',
        jasminejQuery: '../tests/lib/jasmine-jquery.2.0.5'
    },
    shim: {
        'jquery': {
            exports: '$'
        },
        'jasminejQuery': {exports: 'jasminejQuery', deps : ["jquery"] },
        'jqueryUI': ['jquery'],
        'bootstrap': ['jquery'],
        'equalHeightRows':  ['jquery'],
        'bootswitch': ['jquery', 'bootstrap'],
        'base64': {exports: 'Base64'},
        'cookie': ['jquery'],
        'isLoading': ['jquery'],
        'lazyload': ['jquery'],
        'fullscreen': ['jquery'],
        'nicescroll': ['jquery'],
        'select2': ['jquery'],
        'daterangepicker': ['jquery'],
        'gridstack': ['jquery', 'jqueryUI', 'underscore'],
        'validate': {deps: ["jquery"]},
        'elasticColumns': ['jquery'],
        'nvd3': {deps: ['d3'], exports: 'nv'},
        'widgets': ['d3', 'nvd3', 'elementQuery'],
        'markitup': ['jquery'],
        'markitupset': ['markitup']
    },

    // dynamically load all test files
    // deps: allTestFiles,
    deps: [
        '../tests/spec/login/login',

        '../tests/spec/dashboards/add-dashboard',
        '../tests/spec/dashboards/edit-dashboard',
        '../tests/spec/dashboards/dashboards-menu',
        '../tests/spec/dashboards/dashboards',

        '../tests/spec/widgets/widgets',

        '../tests/spec/post_bug_to_jira/post_bug_to_bts',
        '../tests/spec/post_bug_to_jira/load_bug_to_bts',

        '../tests/spec/project/projectinfo',

        //'../tests/spec/favorites/favorites',

        '../tests/spec/components/paging',

        '../tests/spec/test_item_editor/testItemEditor',

        '../tests/spec/launches/historyGrid',

        '../tests/spec/user_profile/user_profile',

        '../tests/spec/wizard/widget-wizard',

        '../tests/spec/project/project',

        '../tests/spec/admin/admin',

        '../tests/spec/member/member_assigned',
        '../tests/spec/member/assign_member',
        '../tests/spec/member/invite_member',

        //
        // '../tests/spec/filter/filters-panel',
    ],

    // we have to kickoff jasmine, as it is asynchronous
    callback: window.__karma__.start
});
<commit_msg>fix unit tests<commit_after>

var allTestFiles = [];
var TEST_REGEXP = /\/spec\//i;

// Get a list of all the test files to include
Object.keys(window.__karma__.files).forEach(function (file) {
    if (TEST_REGEXP.test(file)) {
        // console.log(file);
        // Normalize paths to RequireJS module names.
        // If you require sub-dependencies of test files to be loaded as-is (requiring file extension)
        // then do not normalize the paths
        var normalizedTestModule = file.replace('/js/src/js/', '/js/');
        allTestFiles.push(normalizedTestModule);
    }
});

require.config({
    // Karma serves files under /base, which is the basePath from your config file
    baseUrl: '/base/js/src',
    paths: {
        // spec: '../tests/spec',
        router: 'router/router',

        initialState: '../tests/lib/initialState',

        app: 'core/app-config',
        jquery: '../lib/jquery-latest',
        jqueryUI: '../lib/jquery-ui',
        'jaddons': '../lib/jquery-addons',
        underscore: '../lib/lodash.min',
        backbone: '../lib/backbone-min-my',
        'backbone-epoxy': '../lib/backbone-epoxy',
        util: 'core/util',
        'baron': '../lib/baron',
        'TestRoute': 'router/TestRoute',
        'landingPage': 'landing/LandingPage',
        cookie: '../lib/jquery.cookie',
        nicescroll: '../lib/jquery.nicescroll',
        bootstrap: '../lib/bootstrap.min',
        bootswitch: '../lib/bootstrap-switch.min',
        elementQuery: '../lib/EQCSS',
        base64: '../lib/base64',
        nprogress: '../lib/nprogress',
        localization: 'localizations/default',
        moment: '../lib/moment.2.10.2',
        message: 'message/message-panel',
        templates: '../../compiled/templates/templates',
        mainview: 'main-view',
        favorites: 'favorites/favorites',
        register: 'register/register',
        filters: 'filter/filters',
        components: 'core/components',
        lazyload: '../lib/jquery.lazyload.min',
        daterangepicker: '../lib/daterangepicker',
        'readmore-js': '../lib/readmore',
        select2: '../lib/select2.custom',
        launch: 'launch/launch-navigation',
        launchgrid: 'launch/launch-grid',
        launchCrumbs: 'launch/launch-crumbs',
        defectEditor: 'defect/defect-editor',
        log: 'log/logs',
        member: 'member/member',
        memberService: 'member/service',
        launchEditor: 'launch/launch-editor',
        stickyHeader: 'core/sticky-header',
        'launchCrumbs': 'launch/launch-crumbs',
        log: 'log/logs',
        'DemoDataSettingsView': 'project/DemoDataSettingsView',

        dataUrlResolver: 'core/data-url-resolver',
        project: 'project/project',
        'projectinfo': 'project/projectinfo',
        validators: 'core/validators',
        validate: '../lib/jquery.validate',

        filtersPanel: 'filter/filters-panel',
        filtersResolver: 'filter/filters-resolver',
        filtersService: 'filter/filters-service',
        profile: 'login/user_profile',
        ace: '../lib/ace/ace.custom',
        aceDark: '../lib/ace/theme-dark',
        'mode-properties': '../lib/ace/mode-properties',

        "colorpicker": "../lib/colorpicker/bootstrap-colorpicker",
        "colorpickerConfig": "../lib/colorpicker/bootstrap-colorpicker-cfg-custom",

        'lunr': '../lib/lunr',

        callService: 'core/call-service',
        coreService: 'core/core-service',
        storageService: 'core/storage-service',
        widgetWizard: 'wizard/widget',
        widgets: 'widget/widgets',
        dashboard: 'dashboard/dashboard-view',
        'fullscreen': '../lib/jquery.fullscreen',
        'isLoading': '../lib/jquery.isLoading',
        'equalHeightRows': '../lib/grids',
        'popup': '../lib/jquery.magnific-popup',
        'highlight': '../lib/highlight.pack',
        'gridstack': '../lib/gridstack/gridstack.custom',
        helpers: 'core/helpers',

        d3: '../lib/d3/d3.v3.min',
        nvd3: '../lib/nvd3/nv.d3.custom',
        d3Tip: '../lib/d3/d3.tip.custom',
        elasticColumns: '../lib/elastic-columns.min',
        'slick': '../lib/slick',
        'landingMain': 'landing/main',
        'landingUI': 'landing/ui',
        'landingDocs': 'landing/documentation',

        admin: 'admin/admin',
        projects: 'admin/projects',
        users: 'admin/users',
        settings: 'admin/settings',
        adminService: 'admin/service',

        'textile': '../lib/textile',
        'markitup': '../lib/jquery.markitup.custom',
        'markitupset': '../lib/jquery.markitup.textile',
        'stickyHeader': 'core/sticky-header',
        'cacheService': 'core/cache-service',
        'scrollable': 'core/scrollable-view',
        "text" : "../lib/text",

        fakeData: '../tests/mocks/data',
        adminFakeData: '../tests/mocks/adminData',
        jasminejQuery: '../tests/lib/jasmine-jquery.2.0.5'
    },
    shim: {
        'jquery': {
            exports: '$'
        },
        'jasminejQuery': {exports: 'jasminejQuery', deps : ["jquery"] },
        'jqueryUI': ['jquery'],
        'bootstrap': ['jquery'],
        'equalHeightRows':  ['jquery'],
        'bootswitch': ['jquery', 'bootstrap'],
        'base64': {exports: 'Base64'},
        'cookie': ['jquery'],
        'isLoading': ['jquery'],
        'lazyload': ['jquery'],
        'fullscreen': ['jquery'],
        'nicescroll': ['jquery'],
        'select2': ['jquery'],
        'daterangepicker': ['jquery'],
        'gridstack': ['jquery', 'jqueryUI', 'underscore'],
        'validate': {deps: ["jquery"]},
        'elasticColumns': ['jquery'],
        'nvd3': {deps: ['d3'], exports: 'nv'},
        'widgets': ['d3', 'nvd3', 'elementQuery'],
        'markitup': ['jquery'],
        'markitupset': ['markitup']
    },

    // dynamically load all test files
    // deps: allTestFiles,
    deps: [
        '../tests/spec/login/login',

        '../tests/spec/dashboards/add-dashboard',
        '../tests/spec/dashboards/edit-dashboard',
        '../tests/spec/dashboards/dashboards-menu',
        '../tests/spec/dashboards/dashboards',

        '../tests/spec/widgets/widgets',

        '../tests/spec/post_bug_to_jira/post_bug_to_bts',
        '../tests/spec/post_bug_to_jira/load_bug_to_bts',

        '../tests/spec/project/projectinfo',

        //'../tests/spec/favorites/favorites',

        '../tests/spec/components/paging',

        '../tests/spec/test_item_editor/testItemEditor',

        '../tests/spec/launches/historyGrid',

        '../tests/spec/user_profile/user_profile',

        '../tests/spec/wizard/widget-wizard',

        '../tests/spec/project/project',

        //'../tests/spec/admin/admin',

        '../tests/spec/member/member_assigned',
        '../tests/spec/member/assign_member',
        '../tests/spec/member/invite_member',

        //
        // '../tests/spec/filter/filters-panel',
    ],

    // we have to kickoff jasmine, as it is asynchronous
    callback: window.__karma__.start
});
<|endoftext|>