<commit_before>'use strict';

console.log('!! rsd');

//polyfills
const global = require('suman-browser-polyfills/modules/global');
const process = require('suman-browser-polyfills/modules/process');

//core
const path = require('path');
const fs = require('fs');
const assert = require('assert');
const util = require('util');

//npm
const colors = require('colors/safe');

//project
const _suman = global.__suman = (global.__suman || {});
const su = require('suman-utils');
const constants = require('../../config/suman-constants');

///////////////////////////////////////////////////////////////////

let loaded;

///////////////////////////////////////////////////////////////////

module.exports = function (sumanConfig, projectRoot) {

  if (loaded) {
    return loaded;
  }

  console.log(' => sumanOpts', util.inspect(_suman.sumanOpts));

  if (_suman.sumanOpts.init) {
    return loaded = {};
  }

  let sumanHelpersDir, shd;
  if (shd = _suman.sumanOpts.suman_helpers_dir) {
    sumanHelpersDir = (path.isAbsolute(shd) ? shd : path.resolve(projectRoot + '/' + shd));
  }
  else {
    sumanHelpersDir = path.resolve(projectRoot + '/' + (sumanConfig.sumanHelpersDir || 'suman'));
  }

  let sumanHelpersDirLocated = false;

  try {
    fs.statSync(sumanHelpersDir);
    sumanHelpersDirLocated = true;
  }
  catch (err) {
    try {
      shd = path.resolve('./' + su.removePath(sumanHelpersDir, projectRoot));
      console.error('\n\n', colors.magenta('=> Suman could *not* locate your <suman-helpers-dir>; ' +
          'perhaps you need to update your suman.conf.js file, please see: ***'), '\n',
        colors.cyan('sumanjs.github.io/conf.html'), '\n',
        ' => We expected to find your <suman-helpers-dir> here =>', '\n',
        colors.bgBlack.cyan(shd), '\n',
        '...We will create a temporary suman helpers directory to keep things moving.');

      if (_suman.sumanOpts.verbose || process.env.SUMAN_DEBUG === 'yes') {
        console.log(colors.red(err.stack || err));
      }

      if (_suman.sumanOpts.strict) {
        console.log(' => Exiting because you have used the --strict option and we could not locate the <suman-helpers-dir>\n' +
          'given your configuration and command line options.');
        process.exit(constants.EXIT_CODES.COULD_NOT_LOCATE_SUMAN_HELPERS_DIR);
      }
      else {
        sumanHelpersDir = path.resolve(projectRoot + '/suman-' + Date.now());
        fs.mkdirSync(sumanHelpersDir);
        console.log(' ...Temporary <suman-helpers-dir> directory written here =>');
        console.log(colors.magenta(sumanHelpersDir));
        fs.writeFileSync(sumanHelpersDir + '/.readme-immediately', 'This (temporary) directory was created because you have yet to ' +
          'create a suman helpers directory,\nor it was deleted. Suman expected to find your <suman-helpers-dir> here: ' +
          '"' + sumanConfig.sumanHelpersDir + '". But suman did not find a directory at that path.\n' +
          'When running "suman --init", a directory called "suman" is created at the ' +
          'root of your project.\nYou can move this directory as desired, as long as you update suman.conf.js accordingly.\n' +
          'Please see these instructions on how to remedy the situation:\n' +
          '=> http://sumanjs.github.io/init.html');
      }
    }
    catch (err) {
      console.error(err.stack);
    }
  }

  // const logDir = path.resolve(_suman.sumanHelperDirRoot + '/logs');
  const logDir = path.resolve(sumanHelpersDir + '/logs');
  const integPrePath = path.resolve(sumanHelpersDir + '/suman.once.pre.js');
  const integPostPath = path.resolve(sumanHelpersDir + '/suman.once.post.js');
  const transpileLogPath = process.env.SUMAN_TRANSPILE_LOG_PATH =
    path.resolve(sumanHelpersDir + '/logs/transpile.log');

  //TODO possibly reconcile these with cmd line options
  const testSrcDirDefined = !!sumanConfig.testSrcDir; //TODO: check for valid string
  const testTargetDirDefined = !!sumanConfig.testTargetDir;

  const testDir = process.env.TEST_DIR = _suman.testDir = path.resolve(projectRoot + '/' + (sumanConfig.testDir || 'test'));
  const testSrcDir = process.env.TEST_SRC_DIR = _suman.testSrcDir = path.resolve(projectRoot + '/' + (sumanConfig.testSrcDir || 'test'));
  const testTargetDir = process.env.TEST_TARGET_DIR = _suman.testTargetDir =
    testTargetDirDefined ? path.resolve(projectRoot + '/' + (sumanConfig.testTargetDir)) :
      path.resolve(testSrcDir + '/../' + 'test-target');

  const errStrmPath = path.resolve(sumanHelpersDir + '/logs/test-debug.log');
  const strmStdoutPath = path.resolve(sumanHelpersDir + '/logs/test-output.log');

  return loaded = Object.freeze({
    sumanHelpersDir: _suman.sumanHelperDirRoot = process.env.SUMAN_HELPERS_DIR_ROOT = sumanHelpersDir,
    sumanLogDir: _suman.sumanLogDir = logDir,
    integPrePath: _suman.integPrePath = integPrePath,
    integPostPath: _suman.integPostPath = integPostPath,
    sumanHelpersDirLocated: sumanHelpersDirLocated,
    testDebugLogPath: errStrmPath,
    testLogPath: strmStdoutPath
  });

};
<commit_msg>p:dev<commit_after>'use strict';

console.log('!! rsd');

//polyfills
const global = require('suman-browser-polyfills/modules/global');
const process = require('suman-browser-polyfills/modules/process');

//core
const path = require('path');
const fs = require('fs');
const assert = require('assert');
const util = require('util');

//npm
const colors = require('colors/safe');

//project
const _suman = global.__suman = (global.__suman || {});
const su = require('suman-utils');
const constants = require('../../config/suman-constants');

///////////////////////////////////////////////////////////////////

let loaded;

///////////////////////////////////////////////////////////////////

module.exports = function (sumanConfig, projectRoot, sumanOpts) {

  if (loaded) {
    return loaded;
  }

  console.log(' => sumanOpts', util.inspect(sumanOpts));

  if (sumanOpts.init) {
    return loaded = {};
  }

  let sumanHelpersDir, shd;
  if (shd = _suman.sumanOpts.suman_helpers_dir) {
    sumanHelpersDir = (path.isAbsolute(shd) ? shd : path.resolve(projectRoot + '/' + shd));
  }
  else {
    sumanHelpersDir = path.resolve(projectRoot + '/' + (sumanConfig.sumanHelpersDir || 'suman'));
  }

  let sumanHelpersDirLocated = false;

  try {
    fs.statSync(sumanHelpersDir);
    sumanHelpersDirLocated = true;
  }
  catch (err) {
    try {
      shd = path.resolve('./' + su.removePath(sumanHelpersDir, projectRoot));
      console.error('\n\n', colors.magenta('=> Suman could *not* locate your <suman-helpers-dir>; ' +
          'perhaps you need to update your suman.conf.js file, please see: ***'), '\n',
        colors.cyan('sumanjs.github.io/conf.html'), '\n',
        ' => We expected to find your <suman-helpers-dir> here =>', '\n',
        colors.bgBlack.cyan(shd), '\n',
        '...We will create a temporary suman helpers directory to keep things moving.');

      if (sumanOpts.verbose || process.env.SUMAN_DEBUG === 'yes') {
        console.log(colors.red(err.stack || err));
      }

      if (sumanOpts.strict) {
        console.log(' => Exiting because you have used the --strict option and we could not locate the <suman-helpers-dir>\n' +
          'given your configuration and command line options.');
        process.exit(constants.EXIT_CODES.COULD_NOT_LOCATE_SUMAN_HELPERS_DIR);
      }
      else {
        sumanHelpersDir = path.resolve(projectRoot + '/suman-' + Date.now());
        fs.mkdirSync(sumanHelpersDir);
        console.log(' ...Temporary <suman-helpers-dir> directory written here =>');
        console.log(colors.magenta(sumanHelpersDir));
        fs.writeFileSync(sumanHelpersDir + '/.readme-immediately', 'This (temporary) directory was created because you have yet to ' +
          'create a suman helpers directory,\nor it was deleted. Suman expected to find your <suman-helpers-dir> here: ' +
          '"' + sumanConfig.sumanHelpersDir + '". But suman did not find a directory at that path.\n' +
          'When running "suman --init", a directory called "suman" is created at the ' +
          'root of your project.\nYou can move this directory as desired, as long as you update suman.conf.js accordingly.\n' +
          'Please see these instructions on how to remedy the situation:\n' +
          '=> http://sumanjs.github.io/init.html');
      }
    }
    catch (err) {
      console.error(err.stack);
    }
  }

  // const logDir = path.resolve(_suman.sumanHelperDirRoot + '/logs');
  const logDir = path.resolve(sumanHelpersDir + '/logs');
  const integPrePath = path.resolve(sumanHelpersDir + '/suman.once.pre.js');
  const integPostPath = path.resolve(sumanHelpersDir + '/suman.once.post.js');
  const transpileLogPath = process.env.SUMAN_TRANSPILE_LOG_PATH =
    path.resolve(sumanHelpersDir + '/logs/transpile.log');

  //TODO possibly reconcile these with cmd line options
  const testSrcDirDefined = !!sumanConfig.testSrcDir; //TODO: check for valid string
  const testTargetDirDefined = !!sumanConfig.testTargetDir;

  const testDir = process.env.TEST_DIR = _suman.testDir = path.resolve(projectRoot + '/' + (sumanConfig.testDir || 'test'));
  const testSrcDir = process.env.TEST_SRC_DIR = _suman.testSrcDir = path.resolve(projectRoot + '/' + (sumanConfig.testSrcDir || 'test'));
  const testTargetDir = process.env.TEST_TARGET_DIR = _suman.testTargetDir =
    testTargetDirDefined ? path.resolve(projectRoot + '/' + (sumanConfig.testTargetDir)) :
      path.resolve(testSrcDir + '/../' + 'test-target');

  const errStrmPath = path.resolve(sumanHelpersDir + '/logs/test-debug.log');
  const strmStdoutPath = path.resolve(sumanHelpersDir + '/logs/test-output.log');

  return loaded = Object.freeze({
    sumanHelpersDir: _suman.sumanHelperDirRoot = process.env.SUMAN_HELPERS_DIR_ROOT = sumanHelpersDir,
    sumanLogDir: _suman.sumanLogDir = logDir,
    integPrePath: _suman.integPrePath = integPrePath,
    integPostPath: _suman.integPostPath = integPostPath,
    sumanHelpersDirLocated: sumanHelpersDirLocated,
    testDebugLogPath: errStrmPath,
    testLogPath: strmStdoutPath
  });

};
<|endoftext|>


<commit_before>/* global $ */
/* global Effect */

; (function () {
  var context;

  var googlive = {
    init: function () {
      var self = this;

      self.files = 'techno';

      self.source = {};
      self.gain = {};
      self.fx = {};
      self.audioNode = {};

      $('[type=' + self.files + ']').addClass('typeactive');
      self.eventinit();
      self.audiocontext();

      self.audioNode.analyser = context.createAnalyser();
      self.audioNode.delay = context.createDelay();
      self.audioNode.biquadFilter = context.createBiquadFilter();

      self.audioNode.biquadFilter.frequency.value = 4400;
      self.audioNode.biquadFilter.Q.value = 1;

      self.audioNode.biquadFilter.connect(self.audioNode.delay);
      self.audioNode.delay.connect(self.audioNode.analyser);
      self.audioNode.analyser.connect(context.destination);

      self.fullscreen();

    },
    fullscreen: function (flag) {
      var self = this;
      if (flag) {
        $('#graph').attr('width', $(window).width() + "px");
        $('#graph').attr('height', $(window).height() + "px");
        self.Effect = new Effect(document.getElementById("graph"), self.audioNode.analyser);
      } else {
        $('#graph').attr('width', ($(window).width() - 320 * 2) + "px");
        $('#graph').attr('height', "500px");
        self.Effect = new Effect(document.getElementById("graph"), self.audioNode.analyser);
      }
    },
    animate: function (flag) {

      if (flag) {
        $(".header").show();
        $(".conleft").show();
        $(".conright").show();

        $(".middle").css({'position': 'static'});
        $(".middle").css({
          'width':'auto',
          'height':500
        });
      } else {
        $(".header").hide();
        $(".conleft").hide();
        $(".conright").hide();

        $(".middle").css({'position': 'fixed','height':'100px','width':'100px','top':'50%','left':'50%'});
        $(".middle").animate({
          'top':0,
          'left':0,
          'z-index': 100,
          'width':$(window).width(),
          'height':$(window).height()
        },600);
      }
    },
    eventinit: function () {
      var self = this;
      self.jrange('.voiceall', 0, 100, 130, function (e) {
        var $target = $(this.inputNode);
        var type = $target.attr("vtype");

        self.changevoice(type, e);
      });
      self.jrange('#ctrl-frequency', 0, 20000, 240, function (val) {
        self.audioNode.biquadFilter.frequency.value = val;
      });
      self.jrange('#ctrl-q', 1, 10, 240, function (val) {
        self.audioNode.biquadFilter.Q.value = val;
      });
      // self.jrange('#ctrl-gain', 1, 10, 252, function (val) {
      //   self.audioNode.biquadFilter.gain.value = val;
      // });
      self.changestype = self.calls(self.changestype);
      self.mute = self.calls(self.mute);
      self.mousemove = self.calls(self.mousemove);
      self.keydown = self.calls(self.keydown);
      self.addsource = self.calls(self.addsource);
      self.events();
      self.initDelay();
      self.initMidi();
    },
    initMidi: function () {
      var self = this;
      var wmaw = new WebMIDIAPIWrapper( true );
      window.addEventListener('midiin-event:foo-input', function(event) {
        var out=[];
        for(var i=0; i<event.detail.data.length; i++) {
          out.push("0x"+("00"+event.detail.data[i].toString(16)).substr(-2));
        }
        var result=wmaw.parseMIDIMessage(out);
        var tmp = {};
        if(typeof result.type!="undefined") {
          tmp.type = result.type;
        }
        if(typeof result.subType!="undefined") {
          tmp.subType = result.subType;
        }
        if(typeof result.event.channel!="undefined") {
          tmp.channel = result.event.channel;
        }
        if(typeof result.event.ctrlName!="undefined") {
          tmp.ctrlName = result.event.ctrlName;
        }
        if(typeof result.event.ctrlNo!="undefined") {
          tmp.ctrlNo = +result.event.ctrlNo;
        }
        if(typeof result.event.ctrlStatus!="undefined") {
          tmp.ctrlStatus = result.event.ctrlStatus;
        }
        if(typeof result.event.programNumber!="undefined") {
          tmp.programNumber = result.event.programNumber;
        }
        if(typeof result.event.valueType!="undefined") {
          tmp.valueType = result.event.valueType;
        }
        if(typeof result.event.noteNumber!="undefined") {
          tmp.noteNumber = result.event.noteNumber;
        }
        if(typeof result.event.velocity!="undefined") {
          tmp.velocity = result.event.velocity;
        }
        if(typeof result.event.value!="undefined") {
          tmp.value = +result.event.value;
        }
        if(typeof result.event.amount!="undefined") {
          tmp.amount = result.event.amount;
        }

        self.handleMidi(tmp);
      });
    },
    handleMidi: function (data) {
      var code = data.ctrlNo;

      // style
      if(code >= 41 && code <= 45) {
        $('[data-code="' + code + '"]').click();
      }

      // delay
      if(code === 23) {
        $('#effects-delay-input').val((100 * data.value)/128).trigger('change');
      }

      // style 音量
      if(code === 6) {
        $('#totalvoice').jRange('setValue', (100 * data.value) / 128);
      }
      // 总音量
      if(code === 7) {
        $('#voiceall').jRange('setValue', (100 * data.value) / 128);
      }

      // sample
      if(code >= 64 && code <= 69) {
        $('[data-code="' + code + '"]').click();
      }
      if(code >= 0 && code <= 5) {
        if(code === 5) code = 6;
        $('#source' + code).jRange('setValue', (100 * data.value) / 128);
      }
      console.log('code', code);
    },
    events: function () {
      $('.menu .type').on('click', this.changestype);
      $('.conleft .source').on('click', this.addsource);
      $(window).on('keydown', this.keydown);
      $('#biquadFilters').on('click', 'a', this.switchFilterTypes.bind(this));
    },
    keydown: function (e) {
      if (e.keyCode === 65) {
        this.Effect.clearrect();
        this.fullscreen(true);
        this.animate();
      }
      if (e.keyCode === 27) {
        this.Effect.clearrect();
        this.fullscreen();
        this.animate(true);
      }
    },
    mousemove: function () {
      clearTimeout(this.fullScreentime);
      if (this.fullflag) {
        this.Effect.clearrect();
        this.animate(true);
        this.fullscreen();
        this.fullflag = false;
      }
      this.settimeout();
    },
    switchFilterTypes: function (e) {
      var self = this;
      var $t = $(e.target);
      $t.addClass('active').siblings('.active').removeClass('active');
      self.audioNode.biquadFilter.type = $t.text().toLocaleLowerCase();
    },
    initDelay: function () {
        var self = this;
        $("#effects-delay-input").knob({
            change : function (value) {
                if(!self.audioNode.delay) return;
                self.audioNode.delay.delayTime.value = value;
            }
        });
    },
    addsource: function (e) {
      var $target = $(e.target),
        num = $target.attr('num'),
        self = this;

      if (self.source[num]) {
        return false;
      }
      $target.addClass('sourceaction');

      self.loadsample(context, 'src/files/' + self.files + '/' + self.files + num + '.wav', function(b) {
        var obj = self.play(b);

        self.source[num] = obj.source;
        self.gain[num] = obj.gain;

        self.gain[num].gain.value = $('#source' + num).val() / 100;
        for (var k in this.source) {
          this.source[k].setTargetAtTime(0, 0, 0.001);
        }
        self.source[num].start(0);
        for (var k in this.source) {
          this.source[k].setTargetAtTime(1, 0, 0.001);
        }
      });
    },
    changestype: function(e) {
      var $target = $(e.target),
        files = $target.attr('type');

      $('.menu .type').removeClass('typeactive');
      $target.addClass('typeactive');
      this.files = files;
      for (var k in this.source) {
        this.source[k].stop(0);
      }
      $('.conleft .source').removeClass('sourceaction');
      this.source = {};
    },
    play: function (buffer) {
      var self = this;
      var gain = context.createGain();
      var source = context.createBufferSource();
      source.buffer = buffer;
      source.connect(gain);
      gain.connect(self.audioNode.biquadFilter);

      source.loop = true;

      return {
        source: source,
        gain: gain
      };
    },
    audiocontext: function () {
      try {
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        context = new AudioContext();
      } catch (e) {
        alert('Web Audio API is not supported in this browser');
      }
    },
    loadsample: function (ctx, url, callback) {
      var self = this;
      var req = new XMLHttpRequest();
      req.open("GET", url, true);
      req.responseType = "arraybuffer";
      req.onload = function () {
        if (req.response) {
          ctx.decodeAudioData(req.response, function (b) {
            callback && callback(b);
          }, function () { });
        }
      }
      req.send();
    },
    jrange: function (selector, from, to, width, callback) {
      var self = this;
      $(selector).jRange({
        from: from,
        to: to,
        showLabels: false,
        showScale: false,
        width: width,
        onstatechange: callback
      });
    },
    changevoice: function (type, val) {
      var self = this;
      Object.keys(self.gain).forEach(function (v) {
        console.log(v, self.gain[v]);
      })
      switch (type) {
        case 'voiceall':
          for (var k in self.gain) {
            self.gain[k].gain.value = val * 0.01;
          }
          break;
        case 'totalvoice':
          for (var k in self.gain) {
            self.gain[k].gain.value = val * 0.01;
          }
          break;
        default:
          if (self.gain[type]) {
            self.gain[type].gain.value = val * 0.01;
          }
          break;
      }
    },
    calls: function (fn) {
      var self = this;
      var f = function (e) {
        fn.call(self, e);
      };
      return f;
    }
  };
  googlive.init();
})();<commit_msg>optimize<commit_after>/* global $ */
/* global Effect */

; (function () {
  var context;

  var googlive = {
    init: function () {
      var self = this;

      self.files = 'techno';

      self.source = {};
      self.gain = {};
      self.fx = {};
      self.audioNode = {};

      $('[type=' + self.files + ']').addClass('typeactive');
      self.eventinit();
      self.audiocontext();

      self.audioNode.analyser = context.createAnalyser();
      self.audioNode.delay = context.createDelay();
      self.audioNode.biquadFilter = context.createBiquadFilter();

      self.audioNode.biquadFilter.frequency.value = 4400;
      self.audioNode.biquadFilter.Q.value = 1;

      self.audioNode.biquadFilter.connect(self.audioNode.delay);
      self.audioNode.delay.connect(self.audioNode.analyser);
      self.audioNode.analyser.connect(context.destination);

      self.fullscreen();

    },
    fullscreen: function (flag) {
      var self = this;
      if (flag) {
        $('#graph').attr('width', $(window).width() + "px");
        $('#graph').attr('height', $(window).height() + "px");
        self.Effect = new Effect(document.getElementById("graph"), self.audioNode.analyser);
      } else {
        $('#graph').attr('width', ($(window).width() - 320 * 2) + "px");
        $('#graph').attr('height', "500px");
        self.Effect = new Effect(document.getElementById("graph"), self.audioNode.analyser);
      }
    },
    animate: function (flag) {

      if (flag) {
        $(".header").show();
        $(".conleft").show();
        $(".conright").show();

        $(".middle").css({'position': 'static'});
        $(".middle").css({
          'width':'auto',
          'height':500
        });
      } else {
        $(".header").hide();
        $(".conleft").hide();
        $(".conright").hide();

        $(".middle").css({'position': 'fixed','height':'100px','width':'100px','top':'50%','left':'50%'});
        $(".middle").animate({
          'top':0,
          'left':0,
          'z-index': 100,
          'width':$(window).width(),
          'height':$(window).height()
        },600);
      }
    },
    eventinit: function () {
      var self = this;
      self.jrange('.voiceall', 0, 100, 130, function (e) {
        var $target = $(this.inputNode);
        var type = $target.attr("vtype");

        self.changevoice(type, e);
      });
      self.jrange('#ctrl-frequency', 0, 20000, 240, function (val) {
        self.audioNode.biquadFilter.frequency.value = val;
      });
      self.jrange('#ctrl-q', 1, 10, 240, function (val) {
        self.audioNode.biquadFilter.Q.value = val;
      });
      // self.jrange('#ctrl-gain', 1, 10, 252, function (val) {
      //   self.audioNode.biquadFilter.gain.value = val;
      // });
      self.changestype = self.calls(self.changestype);
      self.mute = self.calls(self.mute);
      self.mousemove = self.calls(self.mousemove);
      self.keydown = self.calls(self.keydown);
      self.addsource = self.calls(self.addsource);
      self.events();
      self.initDelay();
      self.initMidi();
    },
    initMidi: function () {
      var self = this;
      var wmaw = new WebMIDIAPIWrapper( true );
      window.addEventListener('midiin-event:foo-input', function(event) {
        var out=[];
        for(var i=0; i<event.detail.data.length; i++) {
          out.push("0x"+("00"+event.detail.data[i].toString(16)).substr(-2));
        }
        var result=wmaw.parseMIDIMessage(out);
        var tmp = {};
        if(typeof result.type!="undefined") {
          tmp.type = result.type;
        }
        if(typeof result.subType!="undefined") {
          tmp.subType = result.subType;
        }
        if(typeof result.event.channel!="undefined") {
          tmp.channel = result.event.channel;
        }
        if(typeof result.event.ctrlName!="undefined") {
          tmp.ctrlName = result.event.ctrlName;
        }
        if(typeof result.event.ctrlNo!="undefined") {
          tmp.ctrlNo = +result.event.ctrlNo;
        }
        if(typeof result.event.ctrlStatus!="undefined") {
          tmp.ctrlStatus = result.event.ctrlStatus;
        }
        if(typeof result.event.programNumber!="undefined") {
          tmp.programNumber = result.event.programNumber;
        }
        if(typeof result.event.valueType!="undefined") {
          tmp.valueType = result.event.valueType;
        }
        if(typeof result.event.noteNumber!="undefined") {
          tmp.noteNumber = result.event.noteNumber;
        }
        if(typeof result.event.velocity!="undefined") {
          tmp.velocity = result.event.velocity;
        }
        if(typeof result.event.value!="undefined") {
          tmp.value = +result.event.value;
        }
        if(typeof result.event.amount!="undefined") {
          tmp.amount = result.event.amount;
        }

        self.handleMidi(tmp);
      });
    },
    handleMidi: function (data) {
      var code = data.ctrlNo;
      var val = data.value && (100 * data.value)/128;

      // style
      if(code >= 41 && code <= 45) {
        $('[data-code="' + code + '"]').click();
      }

      // delay
      if(code === 23) {
        $('#effects-delay-input').val(val).trigger('change');
      }

      // style 音量
      if(code === 6) {
        $('#totalvoice').jRange('setValue', val);
      }
      // 总音量
      if(code === 7) {
        $('#voiceall').jRange('setValue', val);
      }

      // sample
      if(code >= 64 && code <= 69) {
        $('[data-code="' + code + '"]').click();
      }
      if(code >= 0 && code <= 5) {
        if(code === 5) code = 6;
        $('#source' + code).jRange('setValue', val);
      }
      console.log('code', code);
    },
    events: function () {
      $('.menu .type').on('click', this.changestype);
      $('.conleft .source').on('click', this.addsource);
      $(window).on('keydown', this.keydown);
      $('#biquadFilters').on('click', 'a', this.switchFilterTypes.bind(this));
    },
    keydown: function (e) {
      if (e.keyCode === 65) {
        this.Effect.clearrect();
        this.fullscreen(true);
        this.animate();
      }
      if (e.keyCode === 27) {
        this.Effect.clearrect();
        this.fullscreen();
        this.animate(true);
      }
    },
    mousemove: function () {
      clearTimeout(this.fullScreentime);
      if (this.fullflag) {
        this.Effect.clearrect();
        this.animate(true);
        this.fullscreen();
        this.fullflag = false;
      }
      this.settimeout();
    },
    switchFilterTypes: function (e) {
      var self = this;
      var $t = $(e.target);
      $t.addClass('active').siblings('.active').removeClass('active');
      self.audioNode.biquadFilter.type = $t.text().toLocaleLowerCase();
    },
    initDelay: function () {
        var self = this;
        $("#effects-delay-input").knob({
            change : function (value) {
                if(!self.audioNode.delay) return;
                self.audioNode.delay.delayTime.value = value;
            }
        });
    },
    addsource: function (e) {
      var $target = $(e.target),
        num = $target.attr('num'),
        self = this;

      if (self.source[num]) {
        return false;
      }
      $target.addClass('sourceaction');

      self.loadsample(context, 'src/files/' + self.files + '/' + self.files + num + '.wav', function(b) {
        var obj = self.play(b);

        self.source[num] = obj.source;
        self.gain[num] = obj.gain;

        self.gain[num].gain.value = $('#source' + num).val() / 100;
        for (var k in this.source) {
          this.source[k].setTargetAtTime(0, 0, 0.001);
        }
        self.source[num].start(0);
        for (var k in this.source) {
          this.source[k].setTargetAtTime(1, 0, 0.001);
        }
      });
    },
    changestype: function(e) {
      var $target = $(e.target),
        files = $target.attr('type');

      $('.menu .type').removeClass('typeactive');
      $target.addClass('typeactive');
      this.files = files;
      for (var k in this.source) {
        this.source[k].stop(0);
      }
      $('.conleft .source').removeClass('sourceaction');
      this.source = {};
    },
    play: function (buffer) {
      var self = this;
      var gain = context.createGain();
      var source = context.createBufferSource();
      source.buffer = buffer;
      source.connect(gain);
      gain.connect(self.audioNode.biquadFilter);

      source.loop = true;

      return {
        source: source,
        gain: gain
      };
    },
    audiocontext: function () {
      try {
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        context = new AudioContext();
      } catch (e) {
        alert('Web Audio API is not supported in this browser');
      }
    },
    loadsample: function (ctx, url, callback) {
      var self = this;
      var req = new XMLHttpRequest();
      req.open("GET", url, true);
      req.responseType = "arraybuffer";
      req.onload = function () {
        if (req.response) {
          ctx.decodeAudioData(req.response, function (b) {
            callback && callback(b);
          }, function () { });
        }
      }
      req.send();
    },
    jrange: function (selector, from, to, width, callback) {
      var self = this;
      $(selector).jRange({
        from: from,
        to: to,
        showLabels: false,
        showScale: false,
        width: width,
        onstatechange: callback
      });
    },
    changevoice: function (type, val) {
      var self = this;
      Object.keys(self.gain).forEach(function (v) {
        console.log(v, self.gain[v]);
      })
      switch (type) {
        case 'voiceall':
          for (var k in self.gain) {
            self.gain[k].gain.value = val * 0.01;
          }
          break;
        case 'totalvoice':
          for (var k in self.gain) {
            self.gain[k].gain.value = val * 0.01;
          }
          break;
        default:
          if (self.gain[type]) {
            self.gain[type].gain.value = val * 0.01;
          }
          break;
      }
    },
    calls: function (fn) {
      var self = this;
      var f = function (e) {
        fn.call(self, e);
      };
      return f;
    }
  };
  googlive.init();
})();<|endoftext|>


<commit_before>var chai = require('chai')
var expect = chai.expect

const Hubspot = require('..')
const hubspot = new Hubspot({ apiKey: 'demo' })

describe('companies', function () {
  describe('get', function () {
    it('should return all companies', function () {
      return hubspot.companies.get().then(data => {
        expect(data).to.be.an('object')
        expect(data.companies).to.be.a('array')
      })
    })

    it('should return a limited number of companies', function () {
      return hubspot.companies.get({ limit: 5 }).then(data => {
        expect(data).to.be.an('object')
        expect(data.companies).to.be.a('array')
        expect(data.companies.length).to.eq(5)
        expect(data['has-more']).to.eq(true)
      })
    })

    it('should return the requested properties', function () {
      return hubspot.companies.get({ limit: 5, properties: ['name', 'country', 'city'] }).then(data => {
        expect(data.companies).to.be.a('array')
        expect(data.companies[0].properties.name.value).to.be.a('string')
      })
    })
  })

  describe('getById', function () {
    let companyId

    before(function () {
      return hubspot.companies.get().then(data => {
        companyId = data.companies[0].companyId
      })
    })

    it('should return a company', function () {
      return hubspot.companies.getById(companyId).then(data => {
        expect(data).to.be.an('object')
      })
    })
  })

  describe('getRecentlyCreated', function () {
    it('should return recently created companies', function () {
      return hubspot.companies.getRecentlyCreated().then(data => {
        expect(data).to.be.an('object')
        expect(data.results).to.be.a('array')
      })
    })
  })

  describe('getRecentlyModified', function () {
    it('should return recently modified companies', function () {
      return hubspot.companies.getRecentlyModified().then(data => {
        expect(data).to.be.an('object')
        expect(data.results).to.be.a('array')
      })
    })
  })

  describe('getByDomain', function () {
    it('should returns a list of all companies that have a matching domain to the specified domain in the request URL', function () {
      this.timeout(10000)
      return hubspot.companies.getByDomain('example.com').then(data => {
        // console.log(data)
        expect(data).to.be.an('array')
        expect(data[0].properties.domain.value).to.equal('example.com')
      })
    })
  })

  describe('create', function () {
    it('should create a company in a given portal', function () {
      const payload = { 'properties': [{'name': 'name', 'value': 'A company name'}, {'name': 'description', 'value': 'A company description'}] }
      return hubspot.companies.create(payload).then(data => {
        expect(data).to.be.an('object')
        // console.log(data)
        expect(data.properties.name.value).to.equal('A company name')
      })
    })
  })

  // describe('addContactToCompany', function () {
  //   it('should add contact to a specific company', function () {
  //     return hubspot.companies.addContactToCompany({ companyId: 322620707, contactVid: 123123 }).then(data => {
  //       expect(data).to.be.an('undefined')
  //     })
  //   })
  // })
})
<commit_msg>test(companies): add test for getContactIds<commit_after>var chai = require('chai')
var expect = chai.expect

const Hubspot = require('..')
const hubspot = new Hubspot({ apiKey: 'demo' })

describe('companies', function () {
  describe('get', function () {
    it('should return all companies', function () {
      return hubspot.companies.get().then(data => {
        expect(data).to.be.an('object')
        expect(data.companies).to.be.a('array')
      })
    })

    it('should return a limited number of companies', function () {
      return hubspot.companies.get({ limit: 5 }).then(data => {
        expect(data).to.be.an('object')
        expect(data.companies).to.be.a('array')
        expect(data.companies.length).to.eq(5)
        expect(data['has-more']).to.eq(true)
      })
    })

    it('should return the requested properties', function () {
      return hubspot.companies.get({ limit: 5, properties: ['name', 'country', 'city'] }).then(data => {
        expect(data.companies).to.be.a('array')
        expect(data.companies[0].properties.name.value).to.be.a('string')
      })
    })
  })

  describe('getById', function () {
    let companyId

    before(function () {
      return hubspot.companies.get().then(data => {
        companyId = data.companies[0].companyId
      })
    })

    it('should return a company', function () {
      return hubspot.companies.getById(companyId).then(data => {
        expect(data).to.be.an('object')
      })
    })
  })

  describe('getRecentlyCreated', function () {
    it('should return recently created companies', function () {
      return hubspot.companies.getRecentlyCreated().then(data => {
        expect(data).to.be.an('object')
        expect(data.results).to.be.a('array')
      })
    })
  })

  describe('getRecentlyModified', function () {
    it('should return recently modified companies', function () {
      return hubspot.companies.getRecentlyModified().then(data => {
        expect(data).to.be.an('object')
        expect(data.results).to.be.a('array')
      })
    })
  })

  describe('getByDomain', function () {
    it('should returns a list of all companies that have a matching domain to the specified domain in the request URL', function () {
      this.timeout(10000)
      return hubspot.companies.getByDomain('example.com').then(data => {
        // console.log(data)
        expect(data).to.be.an('array')
        expect(data[0].properties.domain.value).to.equal('example.com')
      })
    })
  })

  describe('create', function () {
    it('should create a company in a given portal', function () {
      const payload = { 'properties': [{'name': 'name', 'value': 'A company name'}, {'name': 'description', 'value': 'A company description'}] }
      return hubspot.companies.create(payload).then(data => {
        expect(data).to.be.an('object')
        // console.log(data)
        expect(data.properties.name.value).to.equal('A company name')
      })
    })
  })

  describe('getContactIds', function () {
    let companyId

    before(function () {
      return hubspot.companies.get().then(data => {
        companyId = data.companies[0].companyId
      })
    })

    it('should return a list of contact vids', function () {
      const payload = { count: 10 }
      return hubspot.companies.getContactIds(companyId, payload).then(data => {
        expect(data).to.be.an('object')
        expect(data).to.have.property('vids')
        expect(data).to.have.property('vidOffset')
        expect(data).to.have.property('hasMore')
        expect(data.vids).to.be.an('array')
      })
    })
  })

  // describe('addContactToCompany', function () {
  //   it('should add contact to a specific company', function () {
  //     return hubspot.companies.addContactToCompany({ companyId: 322620707, contactVid: 123123 }).then(data => {
  //       expect(data).to.be.an('undefined')
  //     })
  //   })
  // })
})
<|endoftext|>


<commit_before>module.exports = function(sails) {

	/**
	 * Module dependencies.
	 */

	var util = require('util'),
		cookie				= require('express/node_modules/cookie'),
		getSDKMetadata				= require('./getSDKMetadata'),
		parseSignedCookie	= require('express/node_modules/connect').utils.parseSignedCookie,
		ConnectSession		= require('express/node_modules/connect').middleware.session.Session;

	/**
	 * Fired after a socket is connected
	 */

	return function socketAttemptingToConnect (handshake, accept) {

		// If a cookie override was provided in the query string, use it.
		// (e.g. ?cookie=sails.sid=a4g8dsgajsdgadsgasd)
		if (handshake.query.cookie) {
			handshake.headers.cookie = handshake.query.cookie;
		}

		var sdk = getSDKMetadata(handshake);
		sails.log.verbose(util.format('%s client (v%s) is trying to connect a socket...', sdk.platform, sdk.version));

		var TROUBLESHOOTING =
		'Perhaps you have an old browser tab open?  In that case, you can ignore this warning.'+'\n'+
		'Otherwise, are you are trying to access your Sails.js ' + '\n'+
		'server from a socket.io javascript client hosted on a 3rd party domain?  ' + '\n'+
		' *-> You can override the cookie for a user entirely by setting ?cookie=... in the querystring of '+ '\n'+
		'your socket.io connection url on the client.'+ '\n'+
		' *-> You can send a JSONP request first from the javascript client on the other domain '+ '\n'+
		'to the Sails.js server to get the cookie first, then connect the socket.'+ '\n'+
		' *-> For complete customizability, to override the built-in session assignment logic in Sails '+ '\n'+
		'for socket.io requests, you can override socket.io\'s `authorization` logic with your own function '+ '\n'+
		'in `config/sockets.js`. ' + '\n'+
		'Or disable authorization for incoming socket connection requests entirely by setting `authorization: false`.'+'\n';

		// Parse and decrypt cookie and save it in the handshake
		if (!handshake.headers.cookie) {
			return socketConnectionError(accept,
				'Cannot load session for an incoming socket.io connection...  ' + '\n'+
				'No cookie was sent!\n'+
				TROUBLESHOOTING,
				'Cannot load session. No cookie transmitted.'
			);
		}

		// Decrypt cookie into session id using session secret
		// Maintain sessionID in socket handshake so that the session
		// can be queried before processing each incoming message from this
		// socket in the future.
		try {
			handshake.cookie = cookie.parse(handshake.headers.cookie);
			handshake.sessionID = parseSignedCookie(handshake.cookie[sails.config.session.key], sails.config.session.secret);
		}
		catch (e) {
			return socketConnectionError(accept,
				'Unable to parse the cookie that was transmitted for an incoming socket.io connect request:\n' +
				util.inspect(e) + '\n' + TROUBLESHOOTING,
				'Cannot load session. Cookie could not be parsed.'
			);
		}

		// Look up this socket's session id in the Connect session store
		// and see if we already have a record of 'em.
		sails.session.get(handshake.sessionID, function(err, session) {

			// An error occurred, so refuse the connection
			if(err) {
				return socketConnectionError(accept,
					'Error loading session during socket connection! \n' + err,
					'Error loading session.');
			}

			// Cookie is present (there is a session id), but it doesn't
			// correspond to a known session in the session store.
			// So generate a new, blank session.
			else if (!session) {
				handshake.session = new ConnectSession(handshake, {
					cookie: {
						// Prevent access from client-side javascript
						httpOnly: true
					}
				});
				sails.log.verbose("Generated new session for socket....", handshake);

				// TO_TEST:
				// do we need to set handshake.sessionID with the id of the new session?

				// TO_TEST:
				// do we need to revoke/replace the cookie as well?
				// how can we do that w/ socket.io?
				// can we access the response headers in the http UPGRADE response?
				// or should we just clear the cookie from the handshake and call it good?

				accept(null, true);
			}

			// Parsed cookie matches a known session- onward!
			else {

				// Create a session object, passing our just-acquired session handshake
				handshake.session = new ConnectSession(handshake, session);
				sails.log.verbose("Connected socket to existing session....");
				accept(null, true);
			}
		});
	};

	/**
	 * Fired when an internal server error occurs while authorizing the socket
	 */

	function socketConnectionError (accept, devMsg, prodMsg) {
		var msg;
		if (sails.config.environment === 'development') {
			msg = devMsg;
		}
		else msg = prodMsg;
		return accept(msg, false);
	}

};
<commit_msg>Add example to todo<commit_after>module.exports = function(sails) {

	/**
	 * Module dependencies.
	 */

	var util = require('util'),
		cookie				= require('express/node_modules/cookie'),
		getSDKMetadata				= require('./getSDKMetadata'),
		parseSignedCookie	= require('express/node_modules/connect').utils.parseSignedCookie,
		ConnectSession		= require('express/node_modules/connect').middleware.session.Session;

	/**
	 * Fired after a socket is connected
	 */

	return function socketAttemptingToConnect (handshake, accept) {

		// If a cookie override was provided in the query string, use it.
		// (e.g. ?cookie=sails.sid=a4g8dsgajsdgadsgasd)
		if (handshake.query.cookie) {
			handshake.headers.cookie = handshake.query.cookie;
		}

		var sdk = getSDKMetadata(handshake);
		sails.log.verbose(util.format('%s client (v%s) is trying to connect a socket...', sdk.platform, sdk.version));

		var TROUBLESHOOTING =
		'Perhaps you have an old browser tab open?  In that case, you can ignore this warning.'+'\n'+
		'Otherwise, are you are trying to access your Sails.js ' + '\n'+
		'server from a socket.io javascript client hosted on a 3rd party domain?  ' + '\n'+
		' *-> You can override the cookie for a user entirely by setting ?cookie=... in the querystring of '+ '\n'+
		'your socket.io connection url on the client.'+ '\n'+
		' *-> You can send a JSONP request first from the javascript client on the other domain '+ '\n'+
		'to the Sails.js server to get the cookie first, then connect the socket.'+ '\n'+
		' *-> For complete customizability, to override the built-in session assignment logic in Sails '+ '\n'+
		'for socket.io requests, you can override socket.io\'s `authorization` logic with your own function '+ '\n'+
		'in `config/sockets.js`. ' + '\n'+
		'Or disable authorization for incoming socket connection requests entirely by setting `authorization: false`.'+'\n';

		// Parse and decrypt cookie and save it in the handshake
		if (!handshake.headers.cookie) {
			return socketConnectionError(accept,
				'Cannot load session for an incoming socket.io connection...  ' + '\n'+
				'No cookie was sent!\n'+
				TROUBLESHOOTING,
				'Cannot load session. No cookie transmitted.'
			);
		}

		// Decrypt cookie into session id using session secret
		// Maintain sessionID in socket handshake so that the session
		// can be queried before processing each incoming message from this
		// socket in the future.
		try {
			handshake.cookie = cookie.parse(handshake.headers.cookie);
			handshake.sessionID = parseSignedCookie(handshake.cookie[sails.config.session.key], sails.config.session.secret);
		}
		catch (e) {
			return socketConnectionError(accept,
				'Unable to parse the cookie that was transmitted for an incoming socket.io connect request:\n' +
				util.inspect(e) + '\n' + TROUBLESHOOTING,
				'Cannot load session. Cookie could not be parsed.'
			);
		}

		// Look up this socket's session id in the Connect session store
		// and see if we already have a record of 'em.
		sails.session.get(handshake.sessionID, function(err, session) {

			// An error occurred, so refuse the connection
			if(err) {
				return socketConnectionError(accept,
					'Error loading session during socket connection! \n' + err,
					'Error loading session.');
			}

			// Cookie is present (there is a session id), but it doesn't
			// correspond to a known session in the session store.
			// So generate a new, blank session.
			else if (!session) {
				handshake.session = new ConnectSession(handshake, {
					cookie: {
						// Prevent access from client-side javascript
						httpOnly: true
					}
				});
				sails.log.verbose("Generated new session for socket....", handshake);

				// TO_TEST:
				// do we need to set handshake.sessionID with the id of the new session?

				// TO_TEST:
				// do we need to revoke/replace the cookie as well?
				// how can we do that w/ socket.io?
				// can we access the response headers in the http UPGRADE response?
				// or should we just clear the cookie from the handshake and call it good?
				// e.g
				// var date = new Date();
		    // date.setTime(date.getTime()+(days*24*60*60*1000));
		    // var expires = "; expires="+date.toGMTString();
		    // handshake.headers.cookie = name+"="+value+expires+"; path=/";

				accept(null, true);
			}

			// Parsed cookie matches a known session- onward!
			else {

				// Create a session object, passing our just-acquired session handshake
				handshake.session = new ConnectSession(handshake, session);
				sails.log.verbose("Connected socket to existing session....");
				accept(null, true);
			}
		});
	};

	/**
	 * Fired when an internal server error occurs while authorizing the socket
	 */

	function socketConnectionError (accept, devMsg, prodMsg) {
		var msg;
		if (sails.config.environment === 'development') {
			msg = devMsg;
		}
		else msg = prodMsg;
		return accept(msg, false);
	}

};
<|endoftext|>


<commit_before>/*
 Tracks calls to action.

 Usage:

 Include the tracking.js file by adding the below tracking code right before the
 closing body element (i.e. </body> element).

 Replace [CAMPAIGNCHAIN INSTALLATION] with the URL of the root of your CampaignChain
 installation, e.g. http://www.example.com/bundles/campaignchaincore/js/campaignchain/campaignchain_tracking.js.

 Next, replace [CAMPAIGNCHAIN CHANNEL TRACKING ID] with the ID generated by CampaignChain for your
 channel.

 <script type="text/javascript" src="[CAMPAIGNCHAIN INSTALLATION]/bundles/campaignchaincore/js/campaignchain/campaignchain_tracking.js"></script>
 <script type="text/javascript">
    var campaignchainChannel = '[CAMPAIGNCHAIN CHANNEL TRACKING ID]';
 </script>
 */

/*
 Includes JQuery if not yet available.
 */
if(typeof jQuery == 'undefined'){
    document.write('<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></'+'script>');
}

/*
Include JQuery Cookies library.
 */
document.write('<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></'+'script>');

/*
 *  Initiate the tracking functionality.
 */
jQuery(document).ready(function() {
    var campaignchain = new CampaignChain();

    // If Tracking ID is not in cookie, then this is a first-time visit and
    // we want to report that.
    if(campaignchain.newVisit() == true){
        /*
            We pass this page as the target. The tracking API will then
            detect that the source equals the target and will understand
            that the CTA is the actual source.
         */
        campaignchain.sendUrlReport(window.location.href);
    }

    // Disable clicks if dev-stay mode and Tracking ID exists in URL.
    if(campaignchain.mode == 'dev-stay' &&
        campaignchain.getTrackingId()){
        jQuery('a').on('click', function(event) {
            event.preventDefault();
        });
    }

    // Has a link been clicked?
    jQuery('a').click(function(){
        campaignchain.sendUrlReport(jQuery(this).attr("href"));
        return false;
    })
    // TODO: Has a form been submitted?
});

/**
 *  Define the CampaignChain class.
 *
 * @constructor
 */
function CampaignChain(){
    /**
     * The name of the CTA Tracking ID, e.g. 'campaignchain-id'.
     *
     * @type {string}
     */
    this.idName = 'campaignchain-id';

    /**
     * Value of the Tracking ID.
     *
     * @type {string|bool}
     */
    this.idValue = null;

    /**
     * The Channel Tracking ID.
     *
     * @type {string}
     */
    this.channel = window.campaignchainChannel;

    /**
     * The URL of the source (i.e. the current) page.
     *
     * @type {string}
     */
    this.source = window.location.href;

    /**
     * Development or production mode.
     *
     * Possible values:
     * - 'prod': Production mode
     * - 'dev': Development mode
     * - 'dev-stay': Click will not be executed and you will stay on the Web page.
     *
     * @type {string} prod|dev|dev-stay
     */
    this.mode = 'dev';
}

/**
 * Sends a CTA report to CampaignChain.
 *
 * @param target
 */
CampaignChain.prototype.sendUrlReport = function(target)
{
    this.target = target;

    // Check if the CampaignChain Tracking ID exists.
    if(this.getTrackingId()){
        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            console.log('Tracking ID does exist.');
        }

        // Use Symfony dev environment if dev mode for API URL.
        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            var ajaxUrlMode = 'app_dev.php/';
        } else {
            var ajaxUrlMode = '';
        }
        // Compose the API URL.
        var ajaxUrl = jQuery('script[src$="campaignchain_tracking.js"]').
            attr('src').replace(
                'bundles/campaignchaincore/js/campaignchain/campaignchain_tracking.js',
                ajaxUrlMode + 'api/v1/report/cta/new/' + this.channel);

        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            console.log('API URL: ' + ajaxUrl);
        }

        // Pass the tracking data to the CampaignChain API.
        jQuery.ajax({
            url: ajaxUrl,
            data: { id_name: this.idName, id_value: this.idValue, source: this.source, target: this.target },
            dataType: 'jsonp',
            cache: false,
            context: this,

            success: function(data, status) {
                console.log(data);
                /*
                 If an external target URL, then append the Tracking ID if it is not
                 already appended.
                 */
                this.continueTracking(data.target_affiliation);

                if(this.mode != 'dev-stay'){
                    if(this.newVisit() == false){
                        window.location.href = this.target;
                    }
                } else {
                    if(this.newVisit() == false){
                        console.log('AJAX success: ' + status);
                        console.log('Would redirect to: ' + this.target);
                    } else {
                        console.log('First visit, so we stay here.');
                    }
                }
            },
            error: function (xhr, ajaxOptions, thrownError) {
                if(this.mode == 'dev-stay'){
                    console.log(
                        'AJAX error: URL: ' + ajaxUrl + ', status: ' + xhr.status +
                        ', message: ' +thrownError
                    );
                }
            }
        });
    } else {
        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            console.log('No Tracking ID exists.');
        }
    }
}

/**
 * Checks whether Tracking ID exists as parameter in URL of this page.
 *
 * @returns {boolean}
 */
CampaignChain.prototype.getTrackingId = function()
{
    var logMsg = 'CTA Tracking ID with name "' + this.idName + '"';

    // If not in URL, check if it's in a Cookie.
    if(this.source.toLowerCase().indexOf(this.idName) < 0){
        logMsg =  logMsg + 'is NOT in URL';

        this.idValue = this.getCookie();

        if(this.idValue){
            logMsg = logMsg + ', but is in Cookie.';
        } else {
            logMsg = logMsg + ' and is NOT in Cookie.';
        }
    } else {
        this.idValue = decodeURIComponent((new RegExp('[?|&]' + this.idName + '=' + '([^&;]+?)(&|#|;|$)').exec(this.source)||[,""])[1].replace(/\+/g, '%20'))||null;
        logMsg = logMsg + ' is in URL.';
    }

    if(this.mode == 'dev' || this.mode == 'dev-stay'){
        console.log(logMsg);
        console.log('Tracking ID value: ' + this.idValue);
    }

    return this.idValue;
}

/**
 * Appends the Tracking ID to the target URL.
 *
 * @returns {CampaignChain.target}
 */
CampaignChain.prototype.continueTracking = function(affiliation)
{
    // If Tracking ID is already in URL, then return as is.
    if(this.target.toLowerCase().indexOf(this.idName) >= 0){
        return true;
    }

    /*
        No Tracking ID yet, so proceed depending on the target's affiliation:

        1. 'current': If target is within the current channel, then store the Tracking ID
           in a cookie.

        2. 'connected': If target is outside the current channel, but within another
           Channel registered with CampaignChain, then append the Tracking ID to the URL.

        3. 'unknown': If target is outside the current channel and not within a Channel
           connected with CampaignChain, then keep the target URL as is.
     */
    switch (affiliation){
        case 'current':
            jQuery.cookie(this.idName, this.idValue);

            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('Stored in cookie: Tracking ID with affiliation "' + affiliation + '", name "' + this.idName + '" and value "' + this.idValue + '".' );
            }

            break
        case 'connected':
            if (this.target.indexOf(this.idName + "=") >= 0)
            {
                var prefix = this.target.substring(0, this.target.indexOf(this.idName));
                var suffix = this.target.substring(this.target.indexOf(this.idName));
                suffix = suffix.substring(suffix.indexOf("=") + 1);
                suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : "";
                this.target = prefix + this.idName + "=" + this.idValue + suffix;
            }
            else
            {
                if (this.target.indexOf("?") < 0)
                    this.target += "?" + this.idName + "=" + this.idValue;
                else
                    this.target += "&" + this.idName + "=" + this.idValue;
            }

            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('Appended to URL: Tracking ID with affiliation "' + affiliation + '", name "' + this.idName + '" and value "' + this.idValue + '".' );
            }

            break;
        case 'unknown':
            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('Untouched target URL "' + this.target + '" due to affiliation "' + affiliation + '".' );
            }

            break;
    }
}

/**
 * Returns the Tracking ID value from the Cookie.
 *
 * @returns {string}
 */
CampaignChain.prototype.getCookie = function() {
    return jQuery.cookie(this.idName);
}

/**
 * Is this a new visit to this page from the Activity with the CTA?
 *
 * @returns {boolean}
 */
CampaignChain.prototype.newVisit = function()
{
    // Is the Tracking ID in the URL?
    if(this.source.toLowerCase().indexOf(this.idName) >= 0){
        // Is the visitor from a page outside of this pages domain?
        if(document.referrer.indexOf(location.protocol + "//" + location.host) !== 0){
            // Delete existing cookie.
            jQuery.removeCookie(this.idName);
            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('New visit.');
                console.log('Cookie deleted.');
            }
            return true;
        }
    }

    if(this.mode == 'dev' || this.mode == 'dev-stay'){
        console.log('Not a new visit.');
        console.log('Referrer: ' + document.referrer);
    }

    return false;
}<commit_msg>CE-245 Visualize CTA tracking<commit_after>/*
 Tracks calls to action.

 Usage:

 Include the tracking.js file by adding the below tracking code right before the
 closing body element (i.e. </body> element).

 Replace [CAMPAIGNCHAIN INSTALLATION] with the URL of the root of your CampaignChain
 installation, e.g. http://www.example.com/bundles/campaignchaincore/js/campaignchain/campaignchain_tracking.js.

 Next, replace [CAMPAIGNCHAIN CHANNEL TRACKING ID] with the ID generated by CampaignChain for your
 channel.

 <script type="text/javascript" src="[CAMPAIGNCHAIN INSTALLATION]/bundles/campaignchaincore/js/campaignchain/campaignchain_tracking.js"></script>
 <script type="text/javascript">
    var campaignchainChannel = '[CAMPAIGNCHAIN CHANNEL TRACKING ID]';
 </script>
 */

/*
 Includes JQuery if not yet available.
 */
if(typeof jQuery == 'undefined'){
    document.write('<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></'+'script>');
}

/*
Include JQuery Cookies library.
 */
document.write('<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></'+'script>');

/*
 *  Initiate the tracking functionality.
 */
jQuery(document).ready(function() {
    var campaignchain = new CampaignChain();

    // If Tracking ID is not in cookie, then this is a first-time visit and
    // we want to report that.
    if(campaignchain.newVisit() == true){
        /*
            We pass this page as the target. The tracking API will then
            detect that the source equals the target and will understand
            that the CTA is the actual source.
         */
        campaignchain.sendUrlReport(window.location.href);
    }

    // Disable clicks if dev-stay mode and Tracking ID exists in URL.
    if(campaignchain.mode == 'dev-stay' &&
        campaignchain.getTrackingId()){
        jQuery('a').on('click', function(event) {
            event.preventDefault();
        });
    }

    // Has a link been clicked?
    jQuery('a').click(function(){
        campaignchain.sendUrlReport(jQuery(this).attr("href"));
        return false;
    })
    // TODO: Has a form been submitted?
});

/**
 *  Define the CampaignChain class.
 *
 * @constructor
 */
function CampaignChain(){
    /**
     * The name of the CTA Tracking ID, e.g. 'campaignchain-id'.
     *
     * @type {string}
     */
    this.idName = 'campaignchain-id';

    /**
     * Value of the Tracking ID.
     *
     * @type {string|bool}
     */
    this.idValue = null;

    /**
     * The Channel Tracking ID.
     *
     * @type {string}
     */
    this.channel = window.campaignchainChannel;

    /**
     * The URL of the source (i.e. the current) page.
     *
     * @type {string}
     */
    this.source = window.location.href;

    /**
     * Development or production mode.
     *
     * Possible values:
     * - 'prod': Production mode
     * - 'dev': Development mode
     * - 'dev-stay': Click will not be executed and you will stay on the Web page.
     *
     * @type {string} prod|dev|dev-stay
     */
    this.mode = 'prod';
}

/**
 * Sends a CTA report to CampaignChain.
 *
 * @param target
 */
CampaignChain.prototype.sendUrlReport = function(target)
{
    this.target = target;

    // Check if the CampaignChain Tracking ID exists.
    if(this.getTrackingId()){
        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            console.log('Tracking ID does exist.');
        }

        // Use Symfony dev environment if dev mode for API URL.
        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            var ajaxUrlMode = 'app_dev.php/';
        } else {
            var ajaxUrlMode = '';
        }
        // Compose the API URL.
        var ajaxUrl = jQuery('script[src$="campaignchain_tracking.js"]').
            attr('src').replace(
                'bundles/campaignchaincore/js/campaignchain/campaignchain_tracking.js',
                ajaxUrlMode + 'api/v1/report/cta/new/' + this.channel);

        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            console.log('API URL: ' + ajaxUrl);
        }

        // Pass the tracking data to the CampaignChain API.
        jQuery.ajax({
            url: ajaxUrl,
            data: { id_name: this.idName, id_value: this.idValue, source: this.source, target: this.target },
            dataType: 'jsonp',
            cache: false,
            context: this,

            success: function(data, status) {
                console.log(data);
                /*
                 If an external target URL, then append the Tracking ID if it is not
                 already appended.
                 */
                this.continueTracking(data.target_affiliation);

                if(this.mode != 'dev-stay'){
                    if(this.newVisit() == false){
                        window.location.href = this.target;
                    }
                } else {
                    if(this.newVisit() == false){
                        console.log('AJAX success: ' + status);
                        console.log('Would redirect to: ' + this.target);
                    } else {
                        console.log('First visit, so we stay here.');
                    }
                }
            },
            error: function (xhr, ajaxOptions, thrownError) {
                if(this.mode == 'dev-stay'){
                    console.log(
                        'AJAX error: URL: ' + ajaxUrl + ', status: ' + xhr.status +
                        ', message: ' +thrownError
                    );
                }
            }
        });
    } else {
        if(this.mode == 'dev' || this.mode == 'dev-stay'){
            console.log('No Tracking ID exists.');
        }
    }
}

/**
 * Checks whether Tracking ID exists as parameter in URL of this page.
 *
 * @returns {boolean}
 */
CampaignChain.prototype.getTrackingId = function()
{
    var logMsg = 'CTA Tracking ID with name "' + this.idName + '"';

    // If not in URL, check if it's in a Cookie.
    if(this.source.toLowerCase().indexOf(this.idName) < 0){
        logMsg =  logMsg + 'is NOT in URL';

        this.idValue = this.getCookie();

        if(this.idValue){
            logMsg = logMsg + ', but is in Cookie.';
        } else {
            logMsg = logMsg + ' and is NOT in Cookie.';
        }
    } else {
        this.idValue = decodeURIComponent((new RegExp('[?|&]' + this.idName + '=' + '([^&;]+?)(&|#|;|$)').exec(this.source)||[,""])[1].replace(/\+/g, '%20'))||null;
        logMsg = logMsg + ' is in URL.';
    }

    if(this.mode == 'dev' || this.mode == 'dev-stay'){
        console.log(logMsg);
        console.log('Tracking ID value: ' + this.idValue);
    }

    return this.idValue;
}

/**
 * Appends the Tracking ID to the target URL.
 *
 * @returns {CampaignChain.target}
 */
CampaignChain.prototype.continueTracking = function(affiliation)
{
    // If Tracking ID is already in URL, then return as is.
    if(this.target.toLowerCase().indexOf(this.idName) >= 0){
        return true;
    }

    /*
        No Tracking ID yet, so proceed depending on the target's affiliation:

        1. 'current': If target is within the current channel, then store the Tracking ID
           in a cookie.

        2. 'connected': If target is outside the current channel, but within another
           Channel registered with CampaignChain, then append the Tracking ID to the URL.

        3. 'unknown': If target is outside the current channel and not within a Channel
           connected with CampaignChain, then keep the target URL as is.
     */
    switch (affiliation){
        case 'current':
            jQuery.cookie(this.idName, this.idValue);

            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('Stored in cookie: Tracking ID with affiliation "' + affiliation + '", name "' + this.idName + '" and value "' + this.idValue + '".' );
            }

            break
        case 'connected':
            if (this.target.indexOf(this.idName + "=") >= 0)
            {
                var prefix = this.target.substring(0, this.target.indexOf(this.idName));
                var suffix = this.target.substring(this.target.indexOf(this.idName));
                suffix = suffix.substring(suffix.indexOf("=") + 1);
                suffix = (suffix.indexOf("&") >= 0) ? suffix.substring(suffix.indexOf("&")) : "";
                this.target = prefix + this.idName + "=" + this.idValue + suffix;
            }
            else
            {
                if (this.target.indexOf("?") < 0)
                    this.target += "?" + this.idName + "=" + this.idValue;
                else
                    this.target += "&" + this.idName + "=" + this.idValue;
            }

            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('Appended to URL: Tracking ID with affiliation "' + affiliation + '", name "' + this.idName + '" and value "' + this.idValue + '".' );
            }

            break;
        case 'unknown':
            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('Untouched target URL "' + this.target + '" due to affiliation "' + affiliation + '".' );
            }

            break;
    }
}

/**
 * Returns the Tracking ID value from the Cookie.
 *
 * @returns {string}
 */
CampaignChain.prototype.getCookie = function() {
    return jQuery.cookie(this.idName);
}

/**
 * Is this a new visit to this page from the Activity with the CTA?
 *
 * @returns {boolean}
 */
CampaignChain.prototype.newVisit = function()
{
    // Is the Tracking ID in the URL?
    if(this.source.toLowerCase().indexOf(this.idName) >= 0){
        // Is the visitor from a page outside of this pages domain?
        if(document.referrer.indexOf(location.protocol + "//" + location.host) !== 0){
            // Delete existing cookie.
            jQuery.removeCookie(this.idName);
            if(this.mode == 'dev' || this.mode == 'dev-stay'){
                console.log('New visit.');
                console.log('Cookie deleted.');
            }
            return true;
        }
    }

    if(this.mode == 'dev' || this.mode == 'dev-stay'){
        console.log('Not a new visit.');
        console.log('Referrer: ' + document.referrer);
    }

    return false;
}<|endoftext|>


<commit_before>'use strict';
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');

describe('generator-angular-modsmith:component', () => {
  beforeAll(() => {
    return helpers.run(path.join(__dirname, '../generators/component'))
      .withPrompts({someAnswer: true});
  });

  it('creates files', () => {
    assert.file([
      'dummyfile.txt'
    ]);
  });
});
<commit_msg>subgen: component: Add unit test cases<commit_after>'use strict';
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-test');

const proxyquire = require('proxyquire').noCallThru();
const simpleGitMock = require('./simple-git-mock');

const moduleBeingTested = '../generators/component';

//
// Use 'simple-git' mock
//
proxyquire(moduleBeingTested, {'simple-git': simpleGitMock});

describe('generator-angular-modsmith:component', () => {
  before(() => {
    return helpers.run(path.join(__dirname, '../generators/component'))
      .withLocalConfig({
        pkg: {
          name: {
            orig: 'test-mod',
            slug: 'test-mod',
            camel: 'testMod'
          },
          desc: 'Test Module',
          version: '0.0.1',
          repo: '',
          license: 'Apache-2.0',
          keywords: [
            'key', 'word'
          ]
        },
        author: {
          name: 'Some One',
          email: 'some@one.two',
          url: ''
        }
      })
      .withPrompts({
        argName: 'fox-trot',
        argExtTpl: true,
        argStyle: true,
        argTransclude: true
      })
      .toPromise();
  });

  it('Creates component file', () => {
    assert.file([
      'src/components/foxTrot/foxTrot.component.js'
    ]);
  });

  it('Creates external template', () => {
    assert.file([
      'src/components/foxTrot/foxTrot.html'
    ]);
  });

  it('Creates stylus file', () => {
    assert.file([
      'src/components/foxTrot/foxTrot.styl'
    ]);
  });

  it('Creates spec file', () => {
    assert.file([
      'src/components/foxTrot/foxTrot.component.spec.js'
    ]);
  });
});

describe('generator-angular-modsmith:component [2]', () => {
  before(() => {
    return helpers.run(path.join(__dirname, '../generators/component'))
      .withLocalConfig({
        pkg: {
          name: {
            orig: 'test-mod',
            slug: 'test-mod',
            camel: 'testMod'
          },
          desc: 'Test Module',
          version: '0.0.1',
          repo: '',
          license: 'Apache-2.0',
          keywords: [
            'key', 'word'
          ]
        },
        author: {
          name: 'Some One',
          email: 'some@one.two',
          url: ''
        }
      })
      .withPrompts({
        argName: 'golf-psi',
        argExtTpl: false,
        argStyle: false,
        argTransclude: false
      })
      .toPromise();
  });

  it('Creates component file', () => {
    assert.file([
      'src/components/golfPsi/golfPsi.component.js'
    ]);
  });

  it('Creates inline template', () => {
    assert.fileContent(
      'src/components/golfPsi/golfPsi.component.js',
      'template: \'
Component: golfPsi
\''
    );
  });

  it('Doesn\'t create external template', () => {
    assert.noFile([
      'src/components/golfPsi/golfPsi.html'
    ]);
  });

  it('Doesn\'t create stylus file', () => {
    assert.noFile([
      'src/components/golfPsi/golfPsi.styl'
    ]);
  });

  it('Doesn\'t set transclude', () => {
    assert.noFileContent(
      'src/components/golfPsi/golfPsi.component.js',
      'transclude: true'
    );
  });
});
<|endoftext|>


<commit_before>(function(document, location, history) { /* jshint maxdepth:8, boss:true */
    "use strict";

    // do not enable the plugin for old browsers
    if (typeof history.pushState !== "function") return;

    const identity = (s) => s;
    const states = []; // in-memory storage for states
    var lastState = {}, lastFormData;

    function attachNonPreventedListener(eventType, callback) {
        document.addEventListener(eventType, function(e) {
            if (!e.defaultPrevented) {
                callback(e);
            }
        }, false);
    }

    function dispatchAjaxifyEvent(el, type, detail) {
        const e = document.createEvent("CustomEvent");
        e.initCustomEvent("ajaxify:" + type, true, true, detail || null);
        return el.dispatchEvent(e);
    }

    function updateState(state, detail) {
        var target = document.body;

        if (detail.nodeType === 9) {
            state.selector = detail.body.getAttribute("data-selector");
        }

        if (state.selector) {
            // try to find the target
            target = document.querySelector(state.selector);
            if (target) {
                lastState.selector = state.selector;
            } else {
                target = document.body;
            }
        }

        if (detail.nodeType === 9) {
            // prepare target content
            state.body = target.cloneNode(false);
            // move all elements to replacement
            for (var node = detail.body.firstChild; !!node; node = detail.body.firstChild) {
                state.body.appendChild(node);
            }
        }

        if (dispatchAjaxifyEvent(target, "update", state.body)) {
            // by default just swap elements
            target.parentNode.replaceChild(state.body, target);
        }

        lastState.body = target;
        lastState.title = document.title;
        if (states.indexOf(lastState) < 0) {
            // if state does not exist - store it in memory
            states.push(lastState);
        }

        document.title = state.title;
    }

    attachNonPreventedListener("click", (e) => {
        const body = document.body;

        for (var el = e.target; el && el !== body; el = el.parentNode) {
            if (el.nodeName.toLowerCase() === "a") {
                if (!el.target) {
                    const targetUrl = el.href;

                    if (el.getAttribute("aria-disabled") === "true") {
                        e.preventDefault();
                    } else if (targetUrl && targetUrl.indexOf("http") === 0) {
                        const currentUrl = location.href;

                        if (targetUrl === currentUrl || targetUrl.split("#")[0] !== currentUrl.split("#")[0]) {
                            if (dispatchAjaxifyEvent(el, "fetch")) {
                                // override default bahavior for links
                                e.preventDefault();
                            }
                        } else {
                            location.hash = el.hash;
                            // override default bahavior for anchors
                            e.preventDefault();
                        }
                    }
                }

                break;
            }
        }
    });

    attachNonPreventedListener("submit", (e) => {
        const el = e.target;

        if (!el.target) {
            if (el.getAttribute("aria-disabled") === "true") {
                e.preventDefault();
            } else {
                const formEnctype = el.getAttribute("enctype");

                var data;

                if (formEnctype === "multipart/form-data") {
                    data = new FormData(el);
                } else {
                    data = {};

                    for (var i = 0, field; field = el.elements[i]; ++i) {
                        const fieldType = field.type;

                        if (fieldType && field.name && !field.disabled) {
                            const fieldName = field.name;

                            if (fieldType === "select-multiple") {
                                for (var j = 0, option; option = field.options[j]; ++j) {
                                    if (option.selected) {
                                        (data[fieldName] = data[fieldName] || []).push(option.value);
                                    }
                                }
                            } else if ((fieldType !== "checkbox" && fieldType !== "radio") || field.checked) {
                                data[fieldName] = field.value;
                            }
                        }
                    }
                }

                if (!dispatchAjaxifyEvent(el, "serialize", data)) {
                    e.preventDefault();
                } else {
                    if (data instanceof FormData) {
                        lastFormData = data;
                    } else {
                        const encode = formEnctype === "text/plain" ? identity : encodeURIComponent;
                        const reSpace = encode === identity ? / /g : /%20/g;

                        lastFormData = Object.keys(data).map((key) => {
                            const name = encode(key);
                            var value = data[key];

                            if (Array.isArray(value)) {
                                value = value.map(encode).join("&" + name + "=");
                            }

                            return name + "=" + encode(value);
                        }).join("&").replace(reSpace, "+");
                    }

                    if (dispatchAjaxifyEvent(el, "fetch")) {
                        e.preventDefault();
                    }

                    lastFormData = null; // cleanup internal reference
                }
            }
        }
    });

    attachNonPreventedListener("ajaxify:fetch", (e) => {
        const el = e.target;
        const detail = e.detail;

        if (detail && detail.nodeType === 9) {
            const state = {title: detail.title};

            updateState(state, detail);

            lastState = {}; // create a new state object

            if (detail.URL !== location.href) {
                history.pushState(states.length, state.title, detail.URL);
            }
        } else {
            const xhr = new XMLHttpRequest();
            const method = (el.method || "GET").toUpperCase();
            const nodeName = el.nodeName.toLowerCase();
            const nodeType = el.nodeType;

            var url = detail;

            if (nodeName === "a") {
                url = url || el.href;
            } else if (nodeName === "form") {
                url = url || el.action;

                if (method === "GET" && lastFormData) {
                    url += (~url.indexOf("?") ? "&" : "?") + lastFormData;
                    // for get forms append all data to url
                    lastFormData = null;
                }
            }

            ["abort", "error", "load", "timeout"].forEach((type) => {
                xhr["on" + type] = () => {
                    if (nodeType === 1) {
                        el.removeAttribute("aria-disabled");
                    }

                    const res = xhr.response;
                    var url = xhr.responseURL;
                    // polyfill xhr.responseURL value
                    if (!url && res && res.URL) {
                        url = xhr.getResponseHeader("Location");

                        if (url) {
                            url = location.origin + url;
                            // patch XHR object to set responseURL
                            Object.defineProperty(xhr, "responseURL", {get: () => url});
                        }
                    }

                    if (dispatchAjaxifyEvent(el, type, xhr) && type === "load") {
                        const defaultTitle = xhr.status + " " + xhr.statusText;
                        const doc = res || document.implementation.createHTMLDocument(defaultTitle);
                        const state = {title: doc.title || defaultTitle};

                        updateState(state, doc);

                        lastState = {}; // create a new state object

                        if (url !== location.href) {
                            history.pushState(states.length, state.title, url);
                        }
                    }
                };
            });

            xhr.open(method, url, true);
            xhr.responseType = "document";

            if (dispatchAjaxifyEvent(el, "send", xhr)) {
                xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

                if (method !== "GET") {
                    xhr.setRequestHeader("Content-Type", el.getAttribute("enctype") || el.enctype);
                }

                xhr.send(lastFormData);

                if (nodeType === 1) {
                    el.setAttribute("aria-disabled", "true");
                }
            }
        }
    });

    window.addEventListener("popstate", (e) => {
        // numeric value indicates better-ajaxify state
        if (!e.defaultPrevented && e.state >= 0) {
            const state = states[e.state];

            if (state) {
                updateState(state, state.body);

                lastState = state;
            }
        }
    });

    // update initial state address url
    history.replaceState(0, document.title);

}(window.document, window.location, window.history));
<commit_msg>use id attribute instead of data-selector<commit_after>(function(document, location, history) { /* jshint maxdepth:8, boss:true */
    "use strict";

    // do not enable the plugin for old browsers
    if (typeof history.pushState !== "function") return;

    const identity = (s) => s;
    const states = []; // in-memory storage for states
    var lastState = {}, lastFormData;

    function attachNonPreventedListener(eventType, callback) {
        document.addEventListener(eventType, function(e) {
            if (!e.defaultPrevented) {
                callback(e);
            }
        }, false);
    }

    function dispatchAjaxifyEvent(el, type, detail) {
        const e = document.createEvent("CustomEvent");
        e.initCustomEvent("ajaxify:" + type, true, true, detail || null);
        return el.dispatchEvent(e);
    }

    function updateState(state, detail) {
        var target = document.body;
        var id = (state.body || detail.body || {}).id;

        if (id) {
            target = document.getElementById(id) || target;
        }

        if (detail.nodeType === 9) {
            // prepare target content
            state.body = target.cloneNode(false);
            // move all elements to replacement
            for (var node = detail.body.firstChild; !!node; node = detail.body.firstChild) {
                state.body.appendChild(node);
            }
        }

        if (dispatchAjaxifyEvent(target, "update", state.body)) {
            // by default just swap elements
            target.parentNode.replaceChild(state.body, target);
        }

        lastState.body = target;
        lastState.title = document.title;
        if (states.indexOf(lastState) < 0) {
            // if state does not exist - store it in memory
            states.push(lastState);
        }

        document.title = state.title;
    }

    attachNonPreventedListener("click", (e) => {
        const body = document.body;

        for (var el = e.target; el && el !== body; el = el.parentNode) {
            if (el.nodeName.toLowerCase() === "a") {
                if (!el.target) {
                    const targetUrl = el.href;

                    if (el.getAttribute("aria-disabled") === "true") {
                        e.preventDefault();
                    } else if (targetUrl && targetUrl.indexOf("http") === 0) {
                        const currentUrl = location.href;

                        if (targetUrl === currentUrl || targetUrl.split("#")[0] !== currentUrl.split("#")[0]) {
                            if (dispatchAjaxifyEvent(el, "fetch")) {
                                // override default bahavior for links
                                e.preventDefault();
                            }
                        } else {
                            location.hash = el.hash;
                            // override default bahavior for anchors
                            e.preventDefault();
                        }
                    }
                }

                break;
            }
        }
    });

    attachNonPreventedListener("submit", (e) => {
        const el = e.target;

        if (!el.target) {
            if (el.getAttribute("aria-disabled") === "true") {
                e.preventDefault();
            } else {
                const formEnctype = el.getAttribute("enctype");

                var data;

                if (formEnctype === "multipart/form-data") {
                    data = new FormData(el);
                } else {
                    data = {};

                    for (var i = 0, field; field = el.elements[i]; ++i) {
                        const fieldType = field.type;

                        if (fieldType && field.name && !field.disabled) {
                            const fieldName = field.name;

                            if (fieldType === "select-multiple") {
                                for (var j = 0, option; option = field.options[j]; ++j) {
                                    if (option.selected) {
                                        (data[fieldName] = data[fieldName] || []).push(option.value);
                                    }
                                }
                            } else if ((fieldType !== "checkbox" && fieldType !== "radio") || field.checked) {
                                data[fieldName] = field.value;
                            }
                        }
                    }
                }

                if (!dispatchAjaxifyEvent(el, "serialize", data)) {
                    e.preventDefault();
                } else {
                    if (data instanceof FormData) {
                        lastFormData = data;
                    } else {
                        const encode = formEnctype === "text/plain" ? identity : encodeURIComponent;
                        const reSpace = encode === identity ? / /g : /%20/g;

                        lastFormData = Object.keys(data).map((key) => {
                            const name = encode(key);
                            var value = data[key];

                            if (Array.isArray(value)) {
                                value = value.map(encode).join("&" + name + "=");
                            }

                            return name + "=" + encode(value);
                        }).join("&").replace(reSpace, "+");
                    }

                    if (dispatchAjaxifyEvent(el, "fetch")) {
                        e.preventDefault();
                    }

                    lastFormData = null; // cleanup internal reference
                }
            }
        }
    });

    attachNonPreventedListener("ajaxify:fetch", (e) => {
        const el = e.target;
        const detail = e.detail;

        if (detail && detail.nodeType === 9) {
            const state = {title: detail.title};

            updateState(state, detail);

            lastState = {}; // create a new state object

            if (detail.URL !== location.href) {
                history.pushState(states.length, state.title, detail.URL);
            }
        } else {
            const xhr = new XMLHttpRequest();
            const method = (el.method || "GET").toUpperCase();
            const nodeName = el.nodeName.toLowerCase();
            const nodeType = el.nodeType;

            var url = detail;

            if (nodeName === "a") {
                url = url || el.href;
            } else if (nodeName === "form") {
                url = url || el.action;

                if (method === "GET" && lastFormData) {
                    url += (~url.indexOf("?") ? "&" : "?") + lastFormData;
                    // for get forms append all data to url
                    lastFormData = null;
                }
            }

            ["abort", "error", "load", "timeout"].forEach((type) => {
                xhr["on" + type] = () => {
                    if (nodeType === 1) {
                        el.removeAttribute("aria-disabled");
                    }

                    const res = xhr.response;
                    var url = xhr.responseURL;
                    // polyfill xhr.responseURL value
                    if (!url && res && res.URL) {
                        url = xhr.getResponseHeader("Location");

                        if (url) {
                            url = location.origin + url;
                            // patch XHR object to set responseURL
                            Object.defineProperty(xhr, "responseURL", {get: () => url});
                        }
                    }

                    if (dispatchAjaxifyEvent(el, type, xhr) && type === "load") {
                        const defaultTitle = xhr.status + " " + xhr.statusText;
                        const doc = res || document.implementation.createHTMLDocument(defaultTitle);
                        const state = {title: doc.title || defaultTitle};

                        updateState(state, doc);

                        lastState = {}; // create a new state object

                        if (url !== location.href) {
                            history.pushState(states.length, state.title, url);
                        }
                    }
                };
            });

            xhr.open(method, url, true);
            xhr.responseType = "document";

            if (dispatchAjaxifyEvent(el, "send", xhr)) {
                xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

                if (method !== "GET") {
                    xhr.setRequestHeader("Content-Type", el.getAttribute("enctype") || el.enctype);
                }

                xhr.send(lastFormData);

                if (nodeType === 1) {
                    el.setAttribute("aria-disabled", "true");
                }
            }
        }
    });

    window.addEventListener("popstate", (e) => {
        // numeric value indicates better-ajaxify state
        if (!e.defaultPrevented && e.state >= 0) {
            const state = states[e.state];

            if (state) {
                updateState(state, state.body);

                lastState = state;
            }
        }
    });

    // update initial state address url
    history.replaceState(0, document.title);

}(window.document, window.location, window.history));
<|endoftext|>


<commit_before>import {theVariable} from "./modules/demomodule";

console.log('theVariable:', theVariable);
<commit_msg>demoapp: Include import from node_modules in browserify_babelbuild_demo.<commit_after>import {theVariable} from "./modules/demomodule";
import {unique} from 'uniq';

console.log('theVariable:', theVariable, unique([1, 1, 2]));
<|endoftext|>


<commit_before>'use strict'
const test = require('tape')
const subsTest = require('./test')

test('condition', function (t) {
  const subs = {
    movies: {
      $any: {
        $condition: {
          val (state) {
            var query = state.getRoot().query.compute()
            if (query && state.title) {
              return (state.title.compute().indexOf(query) > -1)
            }
          },
          $subs: {
            title: {},
            $root: { query: {} }
          },
          $pass: {
            val: 1,
            description: { val: true },
            title: { val: true },
            $root: {
              current: { val: true }
            }
          }
        }
      }
    }
  }

  const state = {
    query: 'interstellar',
    movies: [
      {
        title: 'jump street',
        description: 'its about streets!'
      },
      {
        title: 'interstellar',
        description: 'its about stars!'
      }
    ]
  }

  const s = subsTest(t, state, subs)
  s('initial subscription', [
    { path: 'movies/1', type: 'new' },
    { path: 'movies/1/description', type: 'new' },
    { path: 'movies/1/title', type: 'new' }
  ])

  s('change query to "jump"', [
    { path: 'movies/0', type: 'new' },
    { path: 'movies/0/description', type: 'new' },
    { path: 'movies/0/title', type: 'new' },
    { path: 'movies/1', type: 'remove' }
  ], { query: 'jump' })

  s('change query to "stellar"', [
    { path: 'movies/0', type: 'remove' },
    { path: 'movies/1', type: 'new' },
    { path: 'movies/1/description', type: 'new' },
    { path: 'movies/1/title', type: 'new' }
  ], { query: 'stellar' })

  s('change title from "jump street" to "stellar jumps"', [
    { path: 'movies/0', type: 'new' },
    { path: 'movies/0/description', type: 'new' },
    { path: 'movies/0/title', type: 'new' }
  ], { movies: { 0: { title: 'stellar jumps' } } })

  s('change title from "stellar jumps" to "jump street"', [
    { path: 'movies/0', type: 'remove' }
  ], { movies: { 0: { title: 'jump street' } } })

  s('change query to "blargh"', [
    { path: 'movies/1', type: 'remove' }
  ], { query: 'blargh' })

  s('add movie "the blargh"', [
    { path: 'movies/2', type: 'new' },
    { path: 'movies/2/title', type: 'new' }
  ], { movies: { 2: { title: 'the blargh' } } })

  s(
    'add description for "the blargh"',
    [ { path: 'movies/2/description', type: 'new' } ],
    {
      movies: {
        2: {
          description: 'its about a monster, the blargh!'
        }
      }
    }
  )

  s(
    'change root/current fire for "the blargh"',
    [
      { path: 'current', type: 'new' },
      { path: 'movies/2', type: 'update' }
    ],
    { current: 'hello!' }
  )
  t.end()
})
<commit_msg>added tests for condition/$c<commit_after>'use strict'
const test = require('tape')
const subsTest = require('./test')
const logger = require('./log')

test('condition', function (t) {
  const subs = {
    movies: {
      $any: {
        $condition: {
          val (state) {
            var query = state.getRoot().query.compute()
            if (query && state.title) {
              return (state.title.compute().indexOf(query) > -1)
            }
          },
          $subs: {
            title: {},
            $root: { query: {} }
          },
          $pass: {
            val: 1,
            description: { val: true },
            title: { val: true },
            $root: {
              current: { val: true }
            }
          }
        }
      }
    }
  }

  const state = {
    query: 'interstellar',
    movies: [
      {
        title: 'jump street',
        description: 'its about streets!'
      },
      {
        title: 'interstellar',
        description: 'its about stars!'
      }
    ]
  }

  const s = subsTest(t, state, subs)

  const r = s('initial subscription', [
    { path: 'movies/1', type: 'new' },
    { path: 'movies/1/description', type: 'new' },
    { path: 'movies/1/title', type: 'new' }
  ])

  s('change query to "jump"', [
    { path: 'movies/0', type: 'new' },
    { path: 'movies/0/description', type: 'new' },
    { path: 'movies/0/title', type: 'new' },
    { path: 'movies/1', type: 'remove' }
  ], { query: 'jump' })

  s('change query to "stellar"', [
    { path: 'movies/0', type: 'remove' },
    { path: 'movies/1', type: 'new' },
    { path: 'movies/1/description', type: 'new' },
    { path: 'movies/1/title', type: 'new' }
  ], { query: 'stellar' })

  s('change title from "jump street" to "stellar jumps"', [
    { path: 'movies/0', type: 'new' },
    { path: 'movies/0/description', type: 'new' },
    { path: 'movies/0/title', type: 'new' }
  ], { movies: { 0: { title: 'stellar jumps' } } })

  s('change title from "stellar jumps" to "jump street"', [
    { path: 'movies/0', type: 'remove' }
  ], { movies: { 0: { title: 'jump street' } } })

  s('change query to "blargh"', [
    { path: 'movies/1', type: 'remove' }
  ], { query: 'blargh' })

  s('add movie "the blargh"', [
    { path: 'movies/2', type: 'new' },
    { path: 'movies/2/title', type: 'new' }
  ], { movies: { 2: { title: 'the blargh' } } })

  s(
    'add description for "the blargh"',
    [ { path: 'movies/2/description', type: 'new' } ],
    {
      movies: {
        2: {
          description: 'its about a monster, the blargh!'
        }
      }
    }
  )

  s(
    'change root/current fire for "the blargh"',
    [
      { path: 'current', type: 'new' },
      { path: 'movies/2', type: 'update' }
    ],
    { current: 'hello!' }
  )

  t.same(
    r.tree.movies[2].$c,
    { $condition: 'root', $pass: 'root' },
    'movies/2 has $c/$pass'
  )

  s(
    'change query to "somethig"',
    [ { path: 'movies/2', type: 'remove' } ],
    { query: 'something' }
  )

  t.same(
    r.tree.movies[2].$c,
    { $condition: 'root' },
    'movies/2 does not have $c/$pass'
  )

  t.end()
})
<|endoftext|>