<commit_before>(function (window) {
    'use strict';

    function AudioManager(soundDescriptors) {
        this.sounds = {};
        this.soundDescriptors = soundDescriptors || {};
        this.mute = false;

        try {
            window.AudioContext = window.AudioContext || window.webkitAudioContext;
            this.audioContext = new window.AudioContext();
        } catch (e) {
            window.alert('API Audio non supportée.');
        }
    }

    AudioManager.prototype.loadSounds = function (soundDescriptors) {

        var promises = soundDescriptors.map(function (soundDescriptor) {
            var sound = this.sounds[soundDescriptor.title];

            if (!sound) {
                this.sounds[soundDescriptor.title] = {
                    title: soundDescriptor.title,
                    url: soundDescriptor.url
                };
                return this.loadSound(this.sounds[soundDescriptor.title]);
            }
            return sound;
        }.bind(this));

        return Promise.all(promises);
    };

    AudioManager.prototype.loadSound = function (sound) {

        return new Promise(function (resolve, reject) {

            if (sound.buffer) {
                resolve(sound);
            } else {
                var request = new XMLHttpRequest();
                request.open('GET', sound.url, true);
                request.responseType = 'arraybuffer';

                request.onload = function () {
                    this.audioContext.decodeAudioData(
                        request.response,
                        function (buffer) {
                            sound.buffer = buffer;
                            resolve(sound);
                        }.bind(this),
                        function (error) {
                            console.error('Fail to decodeAudioData [%s]', sound.url, error);
                            reject(sound);
                        }
                    );
                }.bind(this);

                request.onerror = function (event) {
                    reject(new Error("Erreur XMLHttpRequest", event));
                };

                request.send();
            }

        }.bind(this));
    };

    AudioManager.prototype.load = function () {
        return this.loadSounds(this.soundDescriptors);
    };

    AudioManager.prototype.play = function (sound, loop, loopStart, loopEnd) {
        return new Promise(function (resolve) {
            if (!this.mute) {
                var source = this.audioContext.createBufferSource();
                sound.source = null;
                sound.source = source;

                source.buffer = sound.buffer;
                source.loop = loop;

                if (loop) {
                    source.loopStart = loopStart;
                    source.loopEnd = loopEnd;

                    resolve(source);
                }

                source.onended = function () {
                    if (!loop) {
                        resolve(source);
                    }
                };

                source.connect(this.audioContext.destination);
                source.start(0);
            }
        }.bind(this));
    };

    /*
     * Méthodes de lecture spécifique des sons
     */

    AudioManager.prototype.stageBgm = function () {
        return this.play(this.sounds.stage, true, 0, 0);
    };

    AudioManager.prototype.laser = function () {
        return this.play(this.sounds.laser, false);
    };

    AudioManager.prototype.toogleMute = function () {
        this.mute = !this.mute;
        if (this.mute) {
            this.sounds.stage.source.stop(0);
        } else {
            this.stageBgm();
        }
        return this.mute;
    };

    window.AudioManager = AudioManager;

})(window);
<commit_msg>feat(audio): ajout d'une méthode pour stopper un son<commit_after>(function (window) {
    'use strict';

    function AudioManager(soundDescriptors) {
        this.sounds = {};
        this.soundDescriptors = soundDescriptors || {};
        this.mute = false;

        try {
            window.AudioContext = window.AudioContext || window.webkitAudioContext;
            this.audioContext = new window.AudioContext();
        } catch (e) {
            window.alert('API Audio non supportée.');
        }
    }

    AudioManager.prototype.loadSounds = function (soundDescriptors) {

        var promises = soundDescriptors.map(function (soundDescriptor) {
            var sound = this.sounds[soundDescriptor.title];

            if (!sound) {
                this.sounds[soundDescriptor.title] = {
                    title: soundDescriptor.title,
                    url: soundDescriptor.url
                };
                return this.loadSound(this.sounds[soundDescriptor.title]);
            }
            return sound;
        }.bind(this));

        return Promise.all(promises);
    };

    AudioManager.prototype.loadSound = function (sound) {

        return new Promise(function (resolve, reject) {

            if (sound.buffer) {
                resolve(sound);
            } else {
                var request = new XMLHttpRequest();
                request.open('GET', sound.url, true);
                request.responseType = 'arraybuffer';

                request.onload = function () {
                    this.audioContext.decodeAudioData(
                        request.response,
                        function (buffer) {
                            sound.buffer = buffer;
                            resolve(sound);
                        }.bind(this),
                        function (error) {
                            console.error('Fail to decodeAudioData [%s]', sound.url, error);
                            reject(sound);
                        }
                    );
                }.bind(this);

                request.onerror = function (event) {
                    reject(new Error("Erreur XMLHttpRequest", event));
                };

                request.send();
            }

        }.bind(this));
    };

    AudioManager.prototype.load = function () {
        return this.loadSounds(this.soundDescriptors);
    };

    AudioManager.prototype.play = function (sound, loop, loopStart, loopEnd) {
        return new Promise(function (resolve) {
            if (!this.mute) {
                var source = this.audioContext.createBufferSource();
                sound.source = null;
                sound.source = source;

                source.buffer = sound.buffer;
                source.loop = loop;

                if (loop) {
                    source.loopStart = loopStart;
                    source.loopEnd = loopEnd;

                    resolve(source);
                }

                source.onended = function () {
                    if (!loop) {
                        resolve(source);
                    }
                };

                source.connect(this.audioContext.destination);
                source.start(0);
            }
        }.bind(this));
    };

    AudioManager.prototype.stopSound = function (sound) {
        if (sound.source) {
            sound.source.stop(0);
        }
    };

    /*
     * Méthodes de lecture spécifique des sons
     */

    AudioManager.prototype.stageBgm = function () {
        return this.play(this.sounds.stage, true, 0, 0);
    };

    AudioManager.prototype.laser = function () {
        return this.play(this.sounds.laser, false);
    };

    AudioManager.prototype.toogleMute = function () {
        this.mute = !this.mute;
        if (this.mute) {
            this.stopSound(this.sounds.stage);
        } else {
            this.stageBgm();
        }
        return this.mute;
    };

    window.AudioManager = AudioManager;

})(window);
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

/**
 * The global object.
 * @type {!Object}
 * @const
 */
var global = this;

/** Platform, package, object property, and Event support. */
this.base = (function() {
  /**
   * Base path for modules. Used to form URLs for module 'require' requests.
   */
  var moduleBasePath = '.';
  function setModuleBasePath(path) {
    if (path[path.length - 1] == '/')
      path = path.substring(0, path.length - 1);
    moduleBasePath = path;
  }

  function mLog(text, opt_indentLevel) {
    if (true)
      return;

    var spacing = '';
    var indentLevel = opt_indentLevel || 0;
    for (var i = 0; i < indentLevel; i++)
      spacing += ' ';
    console.log(spacing + text);
  }

  /**
   * Builds an object structure for the provided namespace path,
   * ensuring that names that already exist are not overwritten. For
   * example:
   * 'a.b.c' -> a = {};a.b={};a.b.c={};
   * @param {string} name Name of the object that this file defines.
   * @param {*=} opt_object The object to expose at the end of the path.
   * @param {Object=} opt_objectToExportTo The object to add the path to;
   *     default is {@code global}.
   * @private
   */
  function exportPath(name, opt_object, opt_objectToExportTo) {
    var parts = name.split('.');
    var cur = opt_objectToExportTo || global;

    for (var part; parts.length && (part = parts.shift());) {
      if (!parts.length && opt_object !== undefined) {
        // last part and we have an object; use it
        cur[part] = opt_object;
      } else if (part in cur) {
        cur = cur[part];
      } else {
        cur = cur[part] = {};
      }
    }
    return cur;
  };

  var didLoadModules = false;
  var moduleDependencies = {};
  var moduleStylesheets = {};
  var moduleRawScripts = {};

  function addModuleDependency(moduleName, dependentModuleName) {
    if (!moduleDependencies[moduleName])
      moduleDependencies[moduleName] = [];

    var dependentModules = moduleDependencies[moduleName];
    var found = false;
    for (var i = 0; i < dependentModules.length; i++)
      if (dependentModules[i] == dependentModuleName)
        found = true;
      if (!found)
        dependentModules.push(dependentModuleName);
  }

  function addModuleRawScriptDependency(moduleName, rawScriptName) {
    if (!moduleRawScripts[moduleName])
      moduleRawScripts[moduleName] = [];

    var dependentRawScripts = moduleRawScripts[moduleName];
    var found = false;
    for (var i = 0; i < moduleRawScripts.length; i++)
      if (dependentRawScripts[i] == rawScriptName)
        found = true;
      if (!found)
        dependentRawScripts.push(rawScriptName);
  }

  function addModuleStylesheet(moduleName, stylesheetName) {
    if (!moduleStylesheets[moduleName])
      moduleStylesheets[moduleName] = [];

    var stylesheets = moduleStylesheets[moduleName];
    var found = false;
    for (var i = 0; i < stylesheets.length; i++)
      if (stylesheets[i] == stylesheetName)
        found = true;
      if (!found)
        stylesheets.push(stylesheetName);
  }

  function ensureDepsLoaded() {
    if (window.FLATTENED)
      return;

    if (didLoadModules)
      return;
    didLoadModules = true;

    var req = new XMLHttpRequest();
    var src = '/deps.js';
    req.open('GET', src, false);
    req.send(null);
    if (req.status != 200) {
      var serverSideException = JSON.parse(req.responseText);
      var msg = 'You have a module problem: ' +
          serverSideException.message;
      var baseWarningEl = document.createElement('div');
      baseWarningEl.style.position = 'fixed';
      baseWarningEl.style.border = '3px solid red';
      baseWarningEl.style.color = 'black';
      baseWarningEl.style.padding = '8px';
      baseWarningEl.innerHTML =
          '
Module parsing problem
' +
          '

' +
          '

';
      baseWarningEl.querySelector('#message').textContent =
          serverSideException.message;
      var detailsEl = baseWarningEl.querySelector('#details');
      detailsEl.textContent = serverSideException.details;
      detailsEl.style.maxWidth = '800px';
      detailsEl.style.overflow = 'auto';

      if (!document.body) {
        setTimeout(function() {
          document.body.appendChild(baseWarningEl);
        }, 150);
      } else {
        document.body.appendChild(baseWarningEl);
      }
      throw new Error(msg);
    }

    base.addModuleDependency = addModuleDependency;
    base.addModuleRawScriptDependency = addModuleRawScriptDependency;
    base.addModuleStylesheet = addModuleStylesheet;
    try {
      // By construction, the deps should call addModuleDependency.
      eval(req.responseText);
    } catch (e) {
      throw new Error('When loading deps, got ' +
                      e.stack ? e.stack : e.message);
    }
    delete base.addModuleStylesheet;
    delete base.addModuleRawScriptDependency;
    delete base.addModuleDependency;
  }

  // TODO(dsinclair): Remove this when HTML imports land as the templates
  // will be pulled in by the requireTemplate calls.
  var templatesLoaded_ = false;
  function ensureTemplatesLoaded() {
    if (templatesLoaded_ || window.FLATTENED)
      return;
    templatesLoaded_ = true;

    var req = new XMLHttpRequest();
    req.open('GET', '/templates', false);
    req.send(null);

    var elem = document.createElement('div');
    elem.innerHTML = req.responseText;
    while (elem.hasChildNodes())
      document.head.appendChild(elem.removeChild(elem.firstChild));
  }

  var moduleLoadStatus = {};
  var rawScriptLoadStatus = {};
  function require(modules, opt_indentLevel) {
    var indentLevel = opt_indentLevel || 0;
    var dependentModules = modules;
    if (!(modules instanceof Array))
      dependentModules = [modules];

    ensureDepsLoaded();
    ensureTemplatesLoaded();

    dependentModules.forEach(function(module) {
      requireModule(module, indentLevel);
    });
  }

  var modulesWaiting = [];
  function requireModule(dependentModuleName, indentLevel) {
    if (window.FLATTENED) {
      if (!window.FLATTENED[dependentModuleName]) {
        throw new Error('Somehow, module ' + dependentModuleName +
                        ' didn\'t get stored in the flattened js file! ' +
                        'You may need to rerun ' +
                        'build/generate_about_tracing_contents.py');
      }
      return;
    }

    if (moduleLoadStatus[dependentModuleName] == 'APPENDED')
      return;

    if (moduleLoadStatus[dependentModuleName] == 'RESOLVING')
      return;

    mLog('require(' + dependentModuleName + ')', indentLevel);
    moduleLoadStatus[dependentModuleName] = 'RESOLVING';
    requireDependencies(dependentModuleName, indentLevel);

    loadScript(dependentModuleName.replace(/\./g, '/') + '.js');
    moduleLoadStatus[name] = 'APPENDED';
  }

  function requireDependencies(dependentModuleName, indentLevel) {
    // Load the module's dependent scripts after.
    var dependentModules = moduleDependencies[dependentModuleName] || [];
    require(dependentModules, indentLevel + 1);

    // Load the module stylesheet first.
    var stylesheets = moduleStylesheets[dependentModuleName] || [];
    for (var i = 0; i < stylesheets.length; i++)
      requireStylesheet(stylesheets[i]);

    // Load the module raw scripts next
    var rawScripts = moduleRawScripts[dependentModuleName] || [];
    for (var i = 0; i < rawScripts.length; i++) {
      var rawScriptName = rawScripts[i];
      if (rawScriptLoadStatus[rawScriptName])
        continue;

      loadScript(rawScriptName);
      mLog('load(' + rawScriptName + ')', indentLevel);
      rawScriptLoadStatus[rawScriptName] = 'APPENDED';
    }
  }

  function loadScript(path) {
    var scriptEl = document.createElement('script');
    scriptEl.src = moduleBasePath + '/' + path;
    scriptEl.type = 'text/javascript';
    scriptEl.defer = true;
    scriptEl.async = false;
    base.doc.head.appendChild(scriptEl);
  }

  /**
   * Adds a dependency on a raw javascript file, e.g. a third party
   * library.
   * @param {String} rawScriptName The path to the script file, relative to
   * moduleBasePath.
   */
  function requireRawScript(rawScriptPath) {
    if (window.FLATTENED_RAW_SCRIPTS) {
      if (!window.FLATTENED_RAW_SCRIPTS[rawScriptPath]) {
        throw new Error('Somehow, ' + rawScriptPath +
            ' didn\'t get stored in the flattened js file! ' +
            'You may need to rerun build/generate_about_tracing_contents.py');
      }
      return;
    }

    if (rawScriptLoadStatus[rawScriptPath])
      return;
    throw new Error(rawScriptPath + ' should already have been loaded.' +
        ' Did you forget to run build/generate_about_tracing_contents.py?');
  }

  var stylesheetLoadStatus = {};
  function requireStylesheet(dependentStylesheetName) {
    if (window.FLATTENED)
      return;

    if (stylesheetLoadStatus[dependentStylesheetName])
      return;
    stylesheetLoadStatus[dependentStylesheetName] = true;

    var localPath = dependentStylesheetName.replace(/\./g, '/') + '.css';
    var stylesheetPath = moduleBasePath + '/' + localPath;

    var linkEl = document.createElement('link');
    linkEl.setAttribute('rel', 'stylesheet');
    linkEl.setAttribute('href', stylesheetPath);
    base.doc.head.appendChild(linkEl);
  }

  var templateLoadStatus = {};
  function requireTemplate(template) {
    if (window.FLATTENED)
      return;

    if (templateLoadStatus[template])
      return;
    templateLoadStatus[template] = true;

    var localPath = template.replace(/\./g, '/') + '.html';
    var importPath = moduleBasePath + '/' + localPath;

    var linkEl = document.createElement('link');
    linkEl.setAttribute('rel', 'import');
    linkEl.setAttribute('href', importPath);
    // TODO(dsinclair): Enable when HTML imports are available.
    //base.doc.head.appendChild(linkEl);
  }

  function exportTo(namespace, fn) {
    var obj = exportPath(namespace);
    try {
      var exports = fn();
    } catch (e) {
      console.log('While running exports for ', namespace, ':');
      console.log(e.stack || e);
      return;
    }

    for (var propertyName in exports) {
      // Maybe we should check the prototype chain here? The current usage
      // pattern is always using an object literal so we only care about own
      // properties.
      var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
                                                               propertyName);
      if (propertyDescriptor) {
        Object.defineProperty(obj, propertyName, propertyDescriptor);
        mLog('  +' + propertyName);
      }
    }
  };

  /**
   * Initialization which must be deferred until run-time.
   */
  function initialize() {
    // If 'document' isn't defined, then we must be being pre-compiled,
    // so set a trap so that we're initialized on first access at run-time.
    if (!global.document) {
      var originalBase = base;

      Object.defineProperty(global, 'base', {
        get: function() {
          Object.defineProperty(global, 'base', {value: originalBase});
          originalBase.initialize();
          return originalBase;
        },
        configurable: true
      });

      return;
    }

    base.doc = document;

    base.isMac = /Mac/.test(navigator.platform);
    base.isWindows = /Win/.test(navigator.platform);
    base.isChromeOS = /CrOS/.test(navigator.userAgent);
    base.isLinux = /Linux/.test(navigator.userAgent);
    base.isGTK = /GTK/.test(chrome.toolkit);
    base.isViews = /views/.test(chrome.toolkit);

    setModuleBasePath('/src');
  }

  return {
    set moduleBasePath(path) {
      setModuleBasePath(path);
    },

    get moduleBasePath() {
      return moduleBasePath;
    },

    initialize: initialize,

    require: require,
    requireStylesheet: requireStylesheet,
    requireRawScript: requireRawScript,
    requireTemplate: requireTemplate,
    exportTo: exportTo
  };
})();

base.initialize();
<commit_msg>Fix positioning on base error dialog<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

/**
 * The global object.
 * @type {!Object}
 * @const
 */
var global = this;

/** Platform, package, object property, and Event support. */
this.base = (function() {
  /**
   * Base path for modules. Used to form URLs for module 'require' requests.
   */
  var moduleBasePath = '.';
  function setModuleBasePath(path) {
    if (path[path.length - 1] == '/')
      path = path.substring(0, path.length - 1);
    moduleBasePath = path;
  }

  function mLog(text, opt_indentLevel) {
    if (true)
      return;

    var spacing = '';
    var indentLevel = opt_indentLevel || 0;
    for (var i = 0; i < indentLevel; i++)
      spacing += ' ';
    console.log(spacing + text);
  }

  /**
   * Builds an object structure for the provided namespace path,
   * ensuring that names that already exist are not overwritten. For
   * example:
   * 'a.b.c' -> a = {};a.b={};a.b.c={};
   * @param {string} name Name of the object that this file defines.
   * @param {*=} opt_object The object to expose at the end of the path.
   * @param {Object=} opt_objectToExportTo The object to add the path to;
   *     default is {@code global}.
   * @private
   */
  function exportPath(name, opt_object, opt_objectToExportTo) {
    var parts = name.split('.');
    var cur = opt_objectToExportTo || global;

    for (var part; parts.length && (part = parts.shift());) {
      if (!parts.length && opt_object !== undefined) {
        // last part and we have an object; use it
        cur[part] = opt_object;
      } else if (part in cur) {
        cur = cur[part];
      } else {
        cur = cur[part] = {};
      }
    }
    return cur;
  };

  var didLoadModules = false;
  var moduleDependencies = {};
  var moduleStylesheets = {};
  var moduleRawScripts = {};

  function addModuleDependency(moduleName, dependentModuleName) {
    if (!moduleDependencies[moduleName])
      moduleDependencies[moduleName] = [];

    var dependentModules = moduleDependencies[moduleName];
    var found = false;
    for (var i = 0; i < dependentModules.length; i++)
      if (dependentModules[i] == dependentModuleName)
        found = true;
      if (!found)
        dependentModules.push(dependentModuleName);
  }

  function addModuleRawScriptDependency(moduleName, rawScriptName) {
    if (!moduleRawScripts[moduleName])
      moduleRawScripts[moduleName] = [];

    var dependentRawScripts = moduleRawScripts[moduleName];
    var found = false;
    for (var i = 0; i < moduleRawScripts.length; i++)
      if (dependentRawScripts[i] == rawScriptName)
        found = true;
      if (!found)
        dependentRawScripts.push(rawScriptName);
  }

  function addModuleStylesheet(moduleName, stylesheetName) {
    if (!moduleStylesheets[moduleName])
      moduleStylesheets[moduleName] = [];

    var stylesheets = moduleStylesheets[moduleName];
    var found = false;
    for (var i = 0; i < stylesheets.length; i++)
      if (stylesheets[i] == stylesheetName)
        found = true;
      if (!found)
        stylesheets.push(stylesheetName);
  }

  function ensureDepsLoaded() {
    if (window.FLATTENED)
      return;

    if (didLoadModules)
      return;
    didLoadModules = true;

    var req = new XMLHttpRequest();
    var src = '/deps.js';
    req.open('GET', src, false);
    req.send(null);
    if (req.status != 200) {
      var serverSideException = JSON.parse(req.responseText);
      var msg = 'You have a module problem: ' +
          serverSideException.message;
      var baseWarningEl = document.createElement('div');
      baseWarningEl.style.boxSizing = 'border-box';
      baseWarningEl.style.position = 'fixed';
      baseWarningEl.style.top = 0;
      baseWarningEl.style.left = 0;
      baseWarningEl.style.width = '100%';
      baseWarningEl.style.height = '100%';
      baseWarningEl.style.display = '-webkit-flex';
      baseWarningEl.style.webkitFlexDirection = 'column';
      baseWarningEl.style.border = '3px solid red';
      baseWarningEl.style.color = 'black';
      baseWarningEl.style.padding = '8px';
      baseWarningEl.innerHTML =
          '
Module parsing problem
' +
          '

' +
          '

';
      baseWarningEl.querySelector('#message').textContent =
          serverSideException.message;
      var detailsEl = baseWarningEl.querySelector('#details');
      detailsEl.textContent = serverSideException.details;
      detailsEl.style.webkitFlex = '1 1 auto';
      detailsEl.style.overflow = 'auto';

      if (!document.body) {
        setTimeout(function() {
          document.body.appendChild(baseWarningEl);
        }, 150);
      } else {
        document.body.appendChild(baseWarningEl);
      }
      throw new Error(msg);
    }

    base.addModuleDependency = addModuleDependency;
    base.addModuleRawScriptDependency = addModuleRawScriptDependency;
    base.addModuleStylesheet = addModuleStylesheet;
    try {
      // By construction, the deps should call addModuleDependency.
      eval(req.responseText);
    } catch (e) {
      throw new Error('When loading deps, got ' +
                      e.stack ? e.stack : e.message);
    }
    delete base.addModuleStylesheet;
    delete base.addModuleRawScriptDependency;
    delete base.addModuleDependency;
  }

  // TODO(dsinclair): Remove this when HTML imports land as the templates
  // will be pulled in by the requireTemplate calls.
  var templatesLoaded_ = false;
  function ensureTemplatesLoaded() {
    if (templatesLoaded_ || window.FLATTENED)
      return;
    templatesLoaded_ = true;

    var req = new XMLHttpRequest();
    req.open('GET', '/templates', false);
    req.send(null);

    var elem = document.createElement('div');
    elem.innerHTML = req.responseText;
    while (elem.hasChildNodes())
      document.head.appendChild(elem.removeChild(elem.firstChild));
  }

  var moduleLoadStatus = {};
  var rawScriptLoadStatus = {};
  function require(modules, opt_indentLevel) {
    var indentLevel = opt_indentLevel || 0;
    var dependentModules = modules;
    if (!(modules instanceof Array))
      dependentModules = [modules];

    ensureDepsLoaded();
    ensureTemplatesLoaded();

    dependentModules.forEach(function(module) {
      requireModule(module, indentLevel);
    });
  }

  var modulesWaiting = [];
  function requireModule(dependentModuleName, indentLevel) {
    if (window.FLATTENED) {
      if (!window.FLATTENED[dependentModuleName]) {
        throw new Error('Somehow, module ' + dependentModuleName +
                        ' didn\'t get stored in the flattened js file! ' +
                        'You may need to rerun ' +
                        'build/generate_about_tracing_contents.py');
      }
      return;
    }

    if (moduleLoadStatus[dependentModuleName] == 'APPENDED')
      return;

    if (moduleLoadStatus[dependentModuleName] == 'RESOLVING')
      return;

    mLog('require(' + dependentModuleName + ')', indentLevel);
    moduleLoadStatus[dependentModuleName] = 'RESOLVING';
    requireDependencies(dependentModuleName, indentLevel);

    loadScript(dependentModuleName.replace(/\./g, '/') + '.js');
    moduleLoadStatus[name] = 'APPENDED';
  }

  function requireDependencies(dependentModuleName, indentLevel) {
    // Load the module's dependent scripts after.
    var dependentModules = moduleDependencies[dependentModuleName] || [];
    require(dependentModules, indentLevel + 1);

    // Load the module stylesheet first.
    var stylesheets = moduleStylesheets[dependentModuleName] || [];
    for (var i = 0; i < stylesheets.length; i++)
      requireStylesheet(stylesheets[i]);

    // Load the module raw scripts next
    var rawScripts = moduleRawScripts[dependentModuleName] || [];
    for (var i = 0; i < rawScripts.length; i++) {
      var rawScriptName = rawScripts[i];
      if (rawScriptLoadStatus[rawScriptName])
        continue;

      loadScript(rawScriptName);
      mLog('load(' + rawScriptName + ')', indentLevel);
      rawScriptLoadStatus[rawScriptName] = 'APPENDED';
    }
  }

  function loadScript(path) {
    var scriptEl = document.createElement('script');
    scriptEl.src = moduleBasePath + '/' + path;
    scriptEl.type = 'text/javascript';
    scriptEl.defer = true;
    scriptEl.async = false;
    base.doc.head.appendChild(scriptEl);
  }

  /**
   * Adds a dependency on a raw javascript file, e.g. a third party
   * library.
   * @param {String} rawScriptName The path to the script file, relative to
   * moduleBasePath.
   */
  function requireRawScript(rawScriptPath) {
    if (window.FLATTENED_RAW_SCRIPTS) {
      if (!window.FLATTENED_RAW_SCRIPTS[rawScriptPath]) {
        throw new Error('Somehow, ' + rawScriptPath +
            ' didn\'t get stored in the flattened js file! ' +
            'You may need to rerun build/generate_about_tracing_contents.py');
      }
      return;
    }

    if (rawScriptLoadStatus[rawScriptPath])
      return;
    throw new Error(rawScriptPath + ' should already have been loaded.' +
        ' Did you forget to run build/generate_about_tracing_contents.py?');
  }

  var stylesheetLoadStatus = {};
  function requireStylesheet(dependentStylesheetName) {
    if (window.FLATTENED)
      return;

    if (stylesheetLoadStatus[dependentStylesheetName])
      return;
    stylesheetLoadStatus[dependentStylesheetName] = true;

    var localPath = dependentStylesheetName.replace(/\./g, '/') + '.css';
    var stylesheetPath = moduleBasePath + '/' + localPath;

    var linkEl = document.createElement('link');
    linkEl.setAttribute('rel', 'stylesheet');
    linkEl.setAttribute('href', stylesheetPath);
    base.doc.head.appendChild(linkEl);
  }

  var templateLoadStatus = {};
  function requireTemplate(template) {
    if (window.FLATTENED)
      return;

    if (templateLoadStatus[template])
      return;
    templateLoadStatus[template] = true;

    var localPath = template.replace(/\./g, '/') + '.html';
    var importPath = moduleBasePath + '/' + localPath;

    var linkEl = document.createElement('link');
    linkEl.setAttribute('rel', 'import');
    linkEl.setAttribute('href', importPath);
    // TODO(dsinclair): Enable when HTML imports are available.
    //base.doc.head.appendChild(linkEl);
  }

  function exportTo(namespace, fn) {
    var obj = exportPath(namespace);
    try {
      var exports = fn();
    } catch (e) {
      console.log('While running exports for ', namespace, ':');
      console.log(e.stack || e);
      return;
    }

    for (var propertyName in exports) {
      // Maybe we should check the prototype chain here? The current usage
      // pattern is always using an object literal so we only care about own
      // properties.
      var propertyDescriptor = Object.getOwnPropertyDescriptor(exports,
                                                               propertyName);
      if (propertyDescriptor) {
        Object.defineProperty(obj, propertyName, propertyDescriptor);
        mLog('  +' + propertyName);
      }
    }
  };

  /**
   * Initialization which must be deferred until run-time.
   */
  function initialize() {
    // If 'document' isn't defined, then we must be being pre-compiled,
    // so set a trap so that we're initialized on first access at run-time.
    if (!global.document) {
      var originalBase = base;

      Object.defineProperty(global, 'base', {
        get: function() {
          Object.defineProperty(global, 'base', {value: originalBase});
          originalBase.initialize();
          return originalBase;
        },
        configurable: true
      });

      return;
    }

    base.doc = document;

    base.isMac = /Mac/.test(navigator.platform);
    base.isWindows = /Win/.test(navigator.platform);
    base.isChromeOS = /CrOS/.test(navigator.userAgent);
    base.isLinux = /Linux/.test(navigator.userAgent);
    base.isGTK = /GTK/.test(chrome.toolkit);
    base.isViews = /views/.test(chrome.toolkit);

    setModuleBasePath('/src');
  }

  return {
    set moduleBasePath(path) {
      setModuleBasePath(path);
    },

    get moduleBasePath() {
      return moduleBasePath;
    },

    initialize: initialize,

    require: require,
    requireStylesheet: requireStylesheet,
    requireRawScript: requireRawScript,
    requireTemplate: requireTemplate,
    exportTo: exportTo
  };
})();

base.initialize();
<|endoftext|>


<commit_before>/*#ifndef(UMD)*/
"use strict";
/*global _gpfAssert*/ // Assertion method
/*global _gpfExit*/ // Exit function
/*global _gpfExtend*/ // gpf.extend
/*exported _gpfNodeBuffer2JsArray*/ // Converts a NodeJS buffer into an int array
/*#endif*/

_gpfExtend(gpf, {

    /**
     * Shallow copy an object
     *
     * @param {Object} obj
     * @return {Object}
     */
    clone: function (obj) {
        // http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object/5344074#5344074
        return JSON.parse(JSON.stringify(obj));
    },

    /*
     * Find the first member of dictionary which value equals to value.
     *
     * @param {Object/array} dictionary
     * @param {*} value
     * @return {String/number/undefined} undefined if not found
     */
    test: function (dictionary, value) {
        var idx;
        if (dictionary instanceof Array) {
            idx = dictionary.length;
            while (idx > 0) {
                if (dictionary[--idx] === value) {
                    return idx;
                }
            }
        } else {
            for (idx in dictionary) {
                if (dictionary.hasOwnProperty(idx) && dictionary[idx] === value) {
                    return idx;
                }
            }
        }
        return undefined;
    },

    /*
     * Inserts the value in the array if not already present.
     *
     * @param {Array} array
     * @param {*} value
     * @return {Array}
     * @chainable
     */
    set: function (array, value) {
        _gpfAssert(array instanceof Array, "gpf.set must be used with an Array");
        var idx = array.length;
        while (idx > 0) {
            if (array[--idx] === value) {
                return array; // Already set
            }
        }
        array.push(value);
        return array;
    },

    /*
     * Removes the member of 'dictionary' which value equals 'value'.
     * NOTE: that the object is modified.
     *
     * @param {Object/array} dictionary
     * @param {*} value
     * @return {Object/array} dictionary
     * @chainable
     */
    clear: function (dictionary, value) {
        var idx;
        if (dictionary instanceof Array) {
            idx = dictionary.length;
            while (idx > 0) {
                if (dictionary[--idx] === value) {
                    dictionary.splice(idx, 1);
                    break;
                }
            }
        } else {
            for (idx in dictionary) {
                if (dictionary.hasOwnProperty(idx) && dictionary[idx] === value) {
                    delete dictionary[idx];
                }
            }
        }
        return dictionary;
    },

    /**
     * XOR
     *
     * @param {Boolean} a
     * @param {Boolean} b
     */
    xor: function (a, b) {
        return a && !b || !a && b;
    }

});

/* istanbul ignore next */ // Not testable
/**
 * Exit function
 *
 * @paran {Number} [exitCode=0] exitCode
 */
gpf.exit = function (exitCode) {
    if (undefined === exitCode) {
        exitCode = 0;
    }
    _gpfExit(exitCode);
};

//region NodeJS helpers

/**
 * Converts a NodeJS buffer into a native array containing unsigned
 * bytes
 *
 * @param {Buffer} buffer
 * @return {Number[]}
 */
function _gpfNodeBuffer2JsArray (buffer) {
    var result = [],
        len = buffer.length,
        idx;
    for (idx = 0; idx < len; ++idx) {
        result.push(buffer.readUInt8(idx));
    }
    return result;
}

//endregion

/*#ifndef(UMD)*/

gpf.internals._gpfNodeBuffer2JsArray = _gpfNodeBuffer2JsArray;

/*#endif*/
<commit_msg>Isolate set methods<commit_after>/*#ifndef(UMD)*/
"use strict";
/*global _gpfAssert*/ // Assertion method
/*global _gpfExit*/ // Exit function
/*global _gpfExtend*/ // gpf.extend
/*exported _gpfNodeBuffer2JsArray*/ // Converts a NodeJS buffer into an int array
/*#endif*/

_gpfExtend(gpf, {

    /**
     * Shallow copy an object
     *
     * @param {Object} obj
     * @return {Object}
     */
    clone: function (obj) {
        // http://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-clone-an-object/5344074#5344074
        return JSON.parse(JSON.stringify(obj));
    },

    /**
     * XOR
     *
     * @param {Boolean} a
     * @param {Boolean} b
     */
    xor: function (a, b) {
        return a && !b || !a && b;
    }

});

/* istanbul ignore next */ // Not testable
/**
 * Exit function
 *
 * @paran {Number} [exitCode=0] exitCode
 */
gpf.exit = function (exitCode) {
    if (undefined === exitCode) {
        exitCode = 0;
    }
    _gpfExit(exitCode);
};

//region NodeJS helpers

/**
 * Converts a NodeJS buffer into a native array containing unsigned
 * bytes
 *
 * @param {Buffer} buffer
 * @return {Number[]}
 */
function _gpfNodeBuffer2JsArray (buffer) {
    var result = [],
        len = buffer.length,
        idx;
    for (idx = 0; idx < len; ++idx) {
        result.push(buffer.readUInt8(idx));
    }
    return result;
}

//endregion

/*#ifndef(UMD)*/

gpf.internals._gpfNodeBuffer2JsArray = _gpfNodeBuffer2JsArray;

/*#endif*/
<|endoftext|>


<commit_before>/*
base - the groundwork

base.extend(extended, extender)
  add properties of extender to extended, then return the modified extended

base.urlencode(dataObj)
  serialize dataObj's key/value pairs into form-urlencoding
    any values in dataObj that are arrays will have their items iterated through
    and added to the resulting string

base.urldecode(dataStr)
  deserialize dataStr's data from form-urlencoding
    values in the return obj are all arrays, because the same key may appear
    more than once in urlencoding

base.trim(str)
  most efficient javascript whitespace trim known to man
  courtesy of Steve Leviathan
    (http://blog.stevenlevithan.com/archives/faster-trim-javascript)
*/
/*global tjp*/

function coerce(str) {
  // a safer eval
  var as_num;

  if (str === "undefined") return undefined;
  if (str === "null") return null;
  as_num = Number(str);
  if (String(as_num) === str) return as_num;
  return str;
};

tjp.base = {};

tjp.base.extend = function(extended, extender) {
  for(var name in extender) extended[name] = extender[name];
  return extended;
};

tjp.base.urlencode = function(dataObj) {
  var i, name, values, results = [];
  for (name in dataObj) {
    values = dataObj[name] instanceof Array ? dataObj[name] : [dataObj[name]];
    for (i = 0; i < values.length; i++)
      results.push([
        encodeURIComponent(name),
        encodeURIComponent(values[i])
      ].join("="));
  }
  return results.join("&");
};

tjp.base.urldecode = function(dataStr) {
  var i, name, value, pair, pairs, results = {};
  pairs = dataStr.split("&");
  for (i = 0; i < pairs.length; i++) {
    pair = pairs[i].split("=");
    name = decodeURIComponent(pair[0]);
    value = decodeURIComponent(pair[1]);

    if (!(name in results)) results[name] = [];
    results[name].push(coerce(value));
  }
  return results;
};

tjp.base.trim = function (str) {
  var
    ws = /\s/,
    i = str.length;
  str = str.replace(/^\s\s*/, '');
  while (ws.test(str.charAt(--i)));
  return str.slice(0, i + 1);
};
<commit_msg>bugfix to base.trim<commit_after>/*
base - the groundwork

base.extend(extended, extender)
  add properties of extender to extended, then return the modified extended

base.urlencode(dataObj)
  serialize dataObj's key/value pairs into form-urlencoding
    any values in dataObj that are arrays will have their items iterated through
    and added to the resulting string

base.urldecode(dataStr)
  deserialize dataStr's data from form-urlencoding
    values in the return obj are all arrays, because the same key may appear
    more than once in urlencoding

base.trim(str)
  most efficient javascript whitespace trim known to man
  courtesy of Steve Leviathan
    (http://blog.stevenlevithan.com/archives/faster-trim-javascript)
*/
/*global tjp*/

function coerce(str) {
  // a safer eval
  var as_num;

  if (str === "undefined") return undefined;
  if (str === "null") return null;
  as_num = Number(str);
  if (String(as_num) === str) return as_num;
  return str;
};

tjp.base = {};

tjp.base.extend = function(extended, extender) {
  for(var name in extender) extended[name] = extender[name];
  return extended;
};

tjp.base.urlencode = function(dataObj) {
  var i, name, values, results = [];
  for (name in dataObj) {
    values = dataObj[name] instanceof Array ? dataObj[name] : [dataObj[name]];
    for (i = 0; i < values.length; i++)
      results.push([
        encodeURIComponent(name),
        encodeURIComponent(values[i])
      ].join("="));
  }
  return results.join("&");
};

tjp.base.urldecode = function(dataStr) {
  var i, name, value, pair, pairs, results = {};
  pairs = dataStr.split("&");
  for (i = 0; i < pairs.length; i++) {
    pair = pairs[i].split("=");
    name = decodeURIComponent(pair[0]);
    value = decodeURIComponent(pair[1]);

    if (!(name in results)) results[name] = [];
    results[name].push(coerce(value));
  }
  return results;
};

tjp.base.trim = function (str) {
  var
    i,
    ws = /\s/,
  str = str.replace(/^\s\s*/, '');
  i = str.length;
  while (ws.test(str.charAt(--i)));
  return str.slice(0, i + 1);
};
<|endoftext|>


<commit_before>var configApp = angular.module('configApp', [
    'ngRoute',
    'ngResource',
    'configControllers']);

/***************************************************************************
 * Route Config
 ***************************************************************************/

configApp.config(['$routeProvider',
		  function($routeProvider) {
		      $routeProvider.
			  when('/base', {
			      templateUrl: 'partials/base.html',
			      controller: 'BaseCtrl'
			  }).
			  when('/mqtt_broker', {
			      templateUrl: 'partials/mqtt_broker.html',
			      controller: 'MqttBrokerCtrl'
			  }).
			  when('/subscribes', {
			      templateUrl: 'partials/subscribes.html',
			      controller: 'SubscribesCtrl'
			  }).
			  when('/gpio', {
			      templateUrl: 'partials/gpio.html',
			      controller: 'GpioCtrl'
			  }).
			  when('/arduino', {
			      templateUrl: 'partials/arduino.html',
			      controller: 'ArduinoCtrl'
			  }).
			  otherwise({
			      redirectTo: '/base'
			  });
		  }]);

/***************************************************************************
 * Controllers
 ***************************************************************************/

var configControllers = angular.module('configControllers', []);

// navigation var controller
configControllers.controller('NavCtrl', function($scope, $location) {
    $scope.selected = undefined;
    $scope.menuList = [
	{title: "Base"     , href:"#/base"       },
	{title: "MQTT"     , href:"#/mqtt_broker"},
	{title: "Subscribe", href:"#/subscribes" },
	{title: "GPIO"     , href:"#/gpio"       },
	{title: "Arduino  ", href:"#/arduino"    }
    ];

    $scope.setActionButton = function(path) {
	$scope.menuList.forEach(function(m) {
	    if (m.href === path) {
		$scope.selected = m;
	    }
	})
    }

    $scope.setActionButton("#" + $location.path());
});

// base config
configControllers.controller('BaseCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.base = undefined;

    var Base = $resource('/api/config/base.json', {});
    var base = Base.get(function() {
	$scope.base = base;
	setWatch('base', $scope);
    });

    $scope.save = function() {
	base.$save(function() {
	    $scope.changed = false;
	    setWatch('base', $scope);
	});
    }
});

// mqtt broker config
configControllers.controller('MqttBrokerCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.mqtt = undefined;

    var Mqtt = $resource('/api/config/mqtt_broker.json', {});
    var mqtt = Mqtt.get(function() {
	$scope.mqtt = mqtt;
	setWatch('mqtt', $scope);
    });

    $scope.save = function() {
	mqtt.$save(function(){
	    $scope.changed = false;
	    setWatch('mqtt', $scope);
	});
    }
});

// subscribes config
configControllers.controller('SubscribesCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.subscribes = undefined;
    $scope.isChangedFlag = [];
    $scope.qosList = [0, 1, 2];

    var Subscribe = $resource('/api/config/subscribes.json', {});
    var subscribes = Subscribe.get(function() {
	$scope.subscribes = subscribes;
	subscribes.subscribes.forEach(function(e) {
	    $scope.isChangedFlag.push(false);
	})
	setWatch('subscribes', $scope);
    });

    $scope.addSubscriber = function() {
	subscribes.subscribes.push({topic:"", qos:0});
    }

    $scope.delSubscriber = function(index) {
	var newArray = [];

	for(var i=0; i < subscribes.subscribes.length; i++) {
	    if (i != index) { newArray.push(subscribes.subscribes[i]); }
	}

	subscribes.subscribes = newArray;
    }

    $scope.save = function() {
	subscribes.$save(function() {
	    $scope.changed = false;
	    setWatch('subscribes', $scope);
	});
    }

});

// GPIO config
configControllers.controller('GpioCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.pin_list = []; for(var i=1; i<50; i++){ $scope.pin_list.push(i); }
    $scope.mode_list = ["in", "out"];
    $scope.edge_list = ["rising", "falling", "both", "none"];
    $scope.pull_list = ["up", "down", "none"];

    $scope.gpio = undefined;

    var Gpio = $resource('/api/config/gpio.json', {});
    var gpio = Gpio.get(function() {
	$scope.gpio = gpio;
	setWatch('gpio', $scope);
    });

    $scope.save = function() {
	gpio.$save(function() {
	    $scope.changed = false;
	    setWatch('gpio', $scope);
	})
    }

});

// Arduino config
configControllers.controller('ArduinoCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.analogList = []; for(var i=0; i<5; i++){ $scope.analogList.push(i); }
    $scope.analogUsingState = [false, false, false, false, false, false];
    $scope.mode_list = ["in", "out", "servo", "pwm"];
    $scope.pull_list = ["up", "none"];
    $scope.arduino = undefined;

    var Arduino = $resource('/api/config/arduino.json', {});
    var arduino = Arduino.get(function() {
	$scope.arduino = arduino;
	arduino.analog.forEach(function(aiNo) {
	    $scope.analogUsingState[aiNo] = true;
	});
	setWatch('arduino', $scope);
    });

    $scope.save = function() {
	arduino.$save(function() {
	    $scope.changed = false;
	    setWatch('arduino', $scope);
	})
    }

    $scope.analogSelectChanged = function() {
	var newAnalogs = [];

	for(var aiNo = 0; aiNo < $scope.analogUsingState.length; aiNo++) {
	    if ($scope.analogUsingState[aiNo]) { newAnalogs.push(aiNo); }
	}

	$scope.arduino.analog = newAnalogs;
    }

    $scope.toInteger = function(name) {
	arduino[name] = Number(arduino[name]);
    }
});

var setWatch = function(target, scope) {
    setTimeout(function() {
	scope.$watch(target, function() { scope.changed = true; });
    }, 1000);
}
<commit_msg>fix value watcher<commit_after>var configApp = angular.module('configApp', [
    'ngRoute',
    'ngResource',
    'configControllers']);

/***************************************************************************
 * Route Config
 ***************************************************************************/

configApp.config(['$routeProvider',
		  function($routeProvider) {
		      $routeProvider.
			  when('/base', {
			      templateUrl: 'partials/base.html',
			      controller: 'BaseCtrl'
			  }).
			  when('/mqtt_broker', {
			      templateUrl: 'partials/mqtt_broker.html',
			      controller: 'MqttBrokerCtrl'
			  }).
			  when('/subscribes', {
			      templateUrl: 'partials/subscribes.html',
			      controller: 'SubscribesCtrl'
			  }).
			  when('/gpio', {
			      templateUrl: 'partials/gpio.html',
			      controller: 'GpioCtrl'
			  }).
			  when('/arduino', {
			      templateUrl: 'partials/arduino.html',
			      controller: 'ArduinoCtrl'
			  }).
			  otherwise({
			      redirectTo: '/base'
			  });
		  }]);

/***************************************************************************
 * Controllers
 ***************************************************************************/

var configControllers = angular.module('configControllers', []);

// navigation var controller
configControllers.controller('NavCtrl', function($scope, $location) {
    $scope.selected = undefined;
    $scope.menuList = [
	{title: "Base"     , href:"#/base"       },
	{title: "MQTT"     , href:"#/mqtt_broker"},
	{title: "Subscribe", href:"#/subscribes" },
	{title: "GPIO"     , href:"#/gpio"       },
	{title: "Arduino  ", href:"#/arduino"    }
    ];

    $scope.setActionButton = function(path) {
	$scope.menuList.forEach(function(m) {
	    if (m.href === path) {
		$scope.selected = m;
	    }
	})
    }

    $scope.setActionButton("#" + $location.path());
});

// base config
configControllers.controller('BaseCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.base = undefined;

    var Base = $resource('/api/config/base.json', {});
    var base = Base.get(function() {
	$scope.base = base;
	setWatch('base', $scope);
    });

    $scope.save = function() {
	base.$save(function() {
	    $scope.changed = false;
	    setWatch('base', $scope);
	});
    }
});

// mqtt broker config
configControllers.controller('MqttBrokerCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.mqtt = undefined;

    var Mqtt = $resource('/api/config/mqtt_broker.json', {});
    var mqtt = Mqtt.get(function() {
	$scope.mqtt = mqtt;
	setWatch('mqtt', $scope);
    });

    $scope.save = function() {
	mqtt.$save(function(){
	    $scope.changed = false;
	    setWatch('mqtt', $scope);
	});
    }
});

// subscribes config
configControllers.controller('SubscribesCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.subscribes = undefined;
    $scope.isChangedFlag = [];
    $scope.qosList = [0, 1, 2];

    var Subscribe = $resource('/api/config/subscribes.json', {});
    var subscribes = Subscribe.get(function() {
	$scope.subscribes = subscribes;
	subscribes.subscribes.forEach(function(e) {
	    $scope.isChangedFlag.push(false);
	})
	setWatch('subscribes', $scope);
    });

    $scope.addSubscriber = function() {
	subscribes.subscribes.push({topic:"", qos:0});
    }

    $scope.delSubscriber = function(index) {
	var newArray = [];

	for(var i=0; i < subscribes.subscribes.length; i++) {
	    if (i != index) { newArray.push(subscribes.subscribes[i]); }
	}

	subscribes.subscribes = newArray;
    }

    $scope.save = function() {
	subscribes.$save(function() {
	    $scope.changed = false;
	    setWatch('subscribes', $scope);
	});
    }

});

// GPIO config
configControllers.controller('GpioCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.pin_list = []; for(var i=1; i<50; i++){ $scope.pin_list.push(i); }
    $scope.mode_list = ["in", "out"];
    $scope.edge_list = ["rising", "falling", "both", "none"];
    $scope.pull_list = ["up", "down", "none"];

    $scope.gpio = undefined;

    var Gpio = $resource('/api/config/gpio.json', {});
    var gpio = Gpio.get(function() {
	$scope.gpio = gpio;
	setWatch('gpio', $scope);
    });

    $scope.save = function() {
	gpio.$save(function() {
	    $scope.changed = false;
	    setWatch('gpio', $scope);
	})
    }

});

// Arduino config
configControllers.controller('ArduinoCtrl', function($scope, $resource) {
    $scope.changed = false;
    $scope.analogList = []; for(var i=0; i<5; i++){ $scope.analogList.push(i); }
    $scope.analogUsingState = [false, false, false, false, false, false];
    $scope.mode_list = ["in", "out", "servo", "pwm"];
    $scope.pull_list = ["up", "none"];
    $scope.arduino = undefined;

    var Arduino = $resource('/api/config/arduino.json', {});
    var arduino = Arduino.get(function() {
	$scope.arduino = arduino;
	arduino.analog.forEach(function(aiNo) {
	    $scope.analogUsingState[aiNo] = true;
	});
	setWatch('arduino', $scope);
    });

    $scope.save = function() {
	arduino.$save(function() {
	    $scope.changed = false;
	    setWatch('arduino', $scope);
	})
    }

    $scope.analogSelectChanged = function() {
	var newAnalogs = [];

	for(var aiNo = 0; aiNo < $scope.analogUsingState.length; aiNo++) {
	    if ($scope.analogUsingState[aiNo]) { newAnalogs.push(aiNo); }
	}

	$scope.arduino.analog = newAnalogs;
    }

    $scope.toInteger = function(name) {
	arduino[name] = Number(arduino[name]);
    }
});

var setWatch = function(target, scope) {
    setTimeout(function() {
	scope.changed = false;
	scope.$watch(target, function() { scope.changed = true; });
    }, 300);
}
<|endoftext|>


<commit_before>'use strict';

/*
 bins - a module for bins defined on an ordered set of maps
 such as the genomes in Gramene.

 Bin numbers are global so they can uniquely identify an interval
 on a chromosome (aka. region). This is why the maps and regions need to be ordered.

 Once the maps have been loaded, you can get a binMapper for a set of bins.

 The bins can be defined as follows:
 a bin size for uniform-width bins in nucleotides
 an arbitrary set of intervals {taxon_id: , region: , start: , end: }

 bins = require('bins.js')(map_info);
 mapper_2Mb = bins.binMapper('uniform',2000000);
 bin = mapper_2Mb.pos2bin(taxon_id, region, position); // returns -1 for positions not in a bin
 interval = mapper_2Mb.bin2pos(bin); // returns an interval that contains position
 */

var isNumber = require('is-number');
var _ = require('lodash');
var Genomes = require('./genomes');

module.exports = function(RAW_GENOME_DATA) {

  // generate new genome data structure from (immutable) raw data
  function genomesMap(binName, bins, getBinSizeForGenome) {
    return new Genomes(RAW_GENOME_DATA, binName, bins, getBinSizeForGenome);
  }

  function bins(binName, getBinSizeForGenome) {
    var bins = [];
    var genomeMaps = genomesMap(binName, bins, getBinSizeForGenome);

    return {
      binnedGenomes: function() { return genomeMaps; },
      bin2pos: function(bin) {
        if (bin < 0 || bin >= bins.length) {
          throw 'bin ' + bin + ' out of range';
        }
        return bins[bin];
      },
      pos2bin: function(tax, rname, position) {
        var genome = genomeMaps.get(tax);
        if (!genome) {
          throw tax + ' not a known taxonomy id';
        }
        var binSize = getBinSizeForGenome(genome);
        var region = genome.region(rname);
        if (!region) {
          // perhaps the user is requesting some scaffold
          // that we have lumped into the 'unanchored' category
          region = genome.region('UNANCHORED');
        }
        if (!region) {
          throw rname + ' not a known seq region';
        }
        if (region.name === 'UNANCHORED') {
          // the unanchored region only has one bin
          return region.startBin;
        }
        if (position < 1 || position >= region.size) {
          throw 'position ' + position + ' out of range';
        }
        return region.startBin + Math.floor((position-1)/binSize);
      },
      nbins: bins.length,
      _getBinSizeForGenome: getBinSizeForGenome
    };
  }

  function variableBins(bins) {
    // sort the bins to match the order given in the maps
    var genomes = genomesMap();

    // NB THIS FOREACH FUNCTION IS MODIFYING THE BIN OBJECTS
    // PASSED IN.
    bins.map(function(bin) {
      bin.assembly = genomes.get(bin.taxon_id);
      bin.region = bin.assembly.region(bin.region);
      return bin;
    }).sort(function(a,b) {
      // check species
      if (a.taxon_id > b.taxon_id) {
        return 1;
      }
      if (a.taxon_id < b.taxon_id) {
        return -1;
      }

      // same species, check index of region
      if (a.region.idx > b.region.idx) {
        return 1;
      }
      if (a.region.idx < b.region.idx) {
        return -1;
      }

      // same region,  check for overlap and compare bin start positions
      if (a.start > b.start) {
        if(a.start <= b.end) {
          throw new Error('overlapping bins found: ' + JSON.stringify(a) + ' and ' + JSON.stringify(b));
        }
        return 1;
      }
      if (a.start < b.start) {
        if(a.end >= b.start) {
          throw new Error('overlapping bins found: ' + JSON.stringify(a) + ' and ' + JSON.stringify(b));
        }
        return -1;
      }
      throw new Error('found two apparently identical bins: ' + JSON.stringify(a) + ' and ' + JSON.stringify(b));
    });

    var binPos = bins;
    var posBin = {};
    for(var i=0;i<binPos.length;i++) {
      var bin = binPos[i];
      var regionName = bin.region.name;
      if (! posBin.hasOwnProperty(bin.taxon_id)) {
        posBin[bin.taxon_id] = {};
      }
      if (! posBin[bin.taxon_id].hasOwnProperty(regionName)) {
        posBin[bin.taxon_id][regionName] = {o:i,bins:[]};
      }
      posBin[bin.taxon_id][regionName].bins.push(bin.start,bin.end);
    }

    return {
      bin2pos: function(bin) {
        if (bin < 0 || bin >= binPos.length) {
          throw 'bin ' + bin + ' out of range';
        }
        return binPos[bin];
      },
      pos2bin: function(tax, region, position) {
        if (!(posBin.hasOwnProperty(tax) && posBin[tax].hasOwnProperty(region))) {
          return -1; // no bins here
        }
        var rbins = posBin[tax][region].bins;
        // binary search in rbins for position
        var a = 0;
        var b = rbins.length-1;
        if (position < rbins[a] || position > rbins[b] || !isNumber(position)) { // possibly invalid position that doesn't fall into any bins
          return -1;
        }
        while (a<b) {
          // assume uniform bin distribution and guess a bin
          var f = Math.floor((b - a)*(position - rbins[a])/(rbins[b] - rbins[a]));
          if (f<0) return -1;
          if (f>a && f%2==1) f--;
          if (position < rbins[f]) {
            b = f-1;
          }
          else if (position > rbins[f+1]) {
            a = f+2;
          }
          else {
            return posBin[tax][region].o + f/2;
          }
        }
        return -1;
      },
      nbins: binPos.length
    };
  }

  return {
    uniformBinMapper: function(binWidth) {
      var name = 'uniform_' + binWidth + 'Mb__bin';
      if(!isNumber(binWidth)) {
        throw new Error('binWidth must be numeric: ' + binWidth);
      }
      return bins(name, function getGlobalBinWidth() {
        return binWidth;
      })
    },
    fixedBinMapper: function(binsPerGenome) {
      var name = 'fixed_' + binsPerGenome + '__bin';
      if(!isNumber(binsPerGenome)) {
        throw new Error('binsPerGenome must be numeric: ' + binsPerGenome);
      }
      return bins(name, function determineBinWidthForGenome(genome) {
        if (genome.assembledGenomeSize === 0) return 0;

        if (genome.assembledGenomeSize < 100000) {
          throw new Error('assembled genome sizes between 1 and 100000 are not supported');
        }

        var binSize = Math.floor(genome.assembledGenomeSize / binsPerGenome);

        function countBins(binSize) {
          var nbins = 0;
          genome.eachRegion(function(region) {
            if (region.name === 'UNANCHORED') {
              nbins++
            }
            else {
              nbins += Math.ceil(region.size / binSize);
            }
          });
          return nbins;
        }

        var nbins = countBins(binSize);
        if (nbins > binsPerGenome) {
          var a = Math.floor(genome.assembledGenomeSize / (binsPerGenome - genome.regionCount()));
          var b = binSize;
          while (countBins(a) != binsPerGenome) {
            var m = Math.floor((a+b)/2);
            var mbins = countBins(m);
            if (mbins <= binsPerGenome) {
              a = m;
            }
            else if (mbins > binsPerGenome) {
              b = m;
            }
          }
          binSize = a;
        }
        return binSize;
      })
    },
    // assume we've been given array of valid non-overlapping intervals as objects with keys
    // taxon_id, region, start, end
    // arg checking might be a good idea
    variableBinMapper: function(binsArray) {
      return variableBins(binsArray)
    }
  };
};
<commit_msg>prevent infinite loop<commit_after>'use strict';

/*
 bins - a module for bins defined on an ordered set of maps
 such as the genomes in Gramene.

 Bin numbers are global so they can uniquely identify an interval
 on a chromosome (aka. region). This is why the maps and regions need to be ordered.

 Once the maps have been loaded, you can get a binMapper for a set of bins.

 The bins can be defined as follows:
 a bin size for uniform-width bins in nucleotides
 an arbitrary set of intervals {taxon_id: , region: , start: , end: }

 bins = require('bins.js')(map_info);
 mapper_2Mb = bins.binMapper('uniform',2000000);
 bin = mapper_2Mb.pos2bin(taxon_id, region, position); // returns -1 for positions not in a bin
 interval = mapper_2Mb.bin2pos(bin); // returns an interval that contains position
 */

var isNumber = require('is-number');
var _ = require('lodash');
var Genomes = require('./genomes');

module.exports = function(RAW_GENOME_DATA) {

  // generate new genome data structure from (immutable) raw data
  function genomesMap(binName, bins, getBinSizeForGenome) {
    return new Genomes(RAW_GENOME_DATA, binName, bins, getBinSizeForGenome);
  }

  function bins(binName, getBinSizeForGenome) {
    var bins = [];
    var genomeMaps = genomesMap(binName, bins, getBinSizeForGenome);

    return {
      binnedGenomes: function() { return genomeMaps; },
      bin2pos: function(bin) {
        if (bin < 0 || bin >= bins.length) {
          throw 'bin ' + bin + ' out of range';
        }
        return bins[bin];
      },
      pos2bin: function(tax, rname, position) {
        var genome = genomeMaps.get(tax);
        if (!genome) {
          throw tax + ' not a known taxonomy id';
        }
        var binSize = getBinSizeForGenome(genome);
        var region = genome.region(rname);
        if (!region) {
          // perhaps the user is requesting some scaffold
          // that we have lumped into the 'unanchored' category
          region = genome.region('UNANCHORED');
        }
        if (!region) {
          throw rname + ' not a known seq region';
        }
        if (region.name === 'UNANCHORED') {
          // the unanchored region only has one bin
          return region.startBin;
        }
        if (position < 1 || position >= region.size) {
          throw 'position ' + position + ' out of range';
        }
        return region.startBin + Math.floor((position-1)/binSize);
      },
      nbins: bins.length,
      _getBinSizeForGenome: getBinSizeForGenome
    };
  }

  function variableBins(bins) {
    // sort the bins to match the order given in the maps
    var genomes = genomesMap();

    // NB THIS FOREACH FUNCTION IS MODIFYING THE BIN OBJECTS
    // PASSED IN.
    bins.map(function(bin) {
      bin.assembly = genomes.get(bin.taxon_id);
      bin.region = bin.assembly.region(bin.region);
      return bin;
    }).sort(function(a,b) {
      // check species
      if (a.taxon_id > b.taxon_id) {
        return 1;
      }
      if (a.taxon_id < b.taxon_id) {
        return -1;
      }

      // same species, check index of region
      if (a.region.idx > b.region.idx) {
        return 1;
      }
      if (a.region.idx < b.region.idx) {
        return -1;
      }

      // same region,  check for overlap and compare bin start positions
      if (a.start > b.start) {
        if(a.start <= b.end) {
          throw new Error('overlapping bins found: ' + JSON.stringify(a) + ' and ' + JSON.stringify(b));
        }
        return 1;
      }
      if (a.start < b.start) {
        if(a.end >= b.start) {
          throw new Error('overlapping bins found: ' + JSON.stringify(a) + ' and ' + JSON.stringify(b));
        }
        return -1;
      }
      throw new Error('found two apparently identical bins: ' + JSON.stringify(a) + ' and ' + JSON.stringify(b));
    });

    var binPos = bins;
    var posBin = {};
    for(var i=0;i<binPos.length;i++) {
      var bin = binPos[i];
      var regionName = bin.region.name;
      if (! posBin.hasOwnProperty(bin.taxon_id)) {
        posBin[bin.taxon_id] = {};
      }
      if (! posBin[bin.taxon_id].hasOwnProperty(regionName)) {
        posBin[bin.taxon_id][regionName] = {o:i,bins:[]};
      }
      posBin[bin.taxon_id][regionName].bins.push(bin.start,bin.end);
    }

    return {
      bin2pos: function(bin) {
        if (bin < 0 || bin >= binPos.length) {
          throw 'bin ' + bin + ' out of range';
        }
        return binPos[bin];
      },
      pos2bin: function(tax, region, position) {
        if (!(posBin.hasOwnProperty(tax) && posBin[tax].hasOwnProperty(region))) {
          return -1; // no bins here
        }
        var rbins = posBin[tax][region].bins;
        // binary search in rbins for position
        var a = 0;
        var b = rbins.length-1;
        if (position < rbins[a] || position > rbins[b] || !isNumber(position)) { // possibly invalid position that doesn't fall into any bins
          return -1;
        }
        while (a<b) {
          // assume uniform bin distribution and guess a bin
          var f = Math.floor((b - a)*(position - rbins[a])/(rbins[b] - rbins[a]));
          if (f<0) return -1;
          if (f>a && f%2==1) f--;
          if (position < rbins[f]) {
            b = f-1;
          }
          else if (position > rbins[f+1]) {
            a = f+2;
          }
          else {
            return posBin[tax][region].o + f/2;
          }
        }
        return -1;
      },
      nbins: binPos.length
    };
  }

  return {
    uniformBinMapper: function(binWidth) {
      var name = 'uniform_' + binWidth + 'Mb__bin';
      if(!isNumber(binWidth)) {
        throw new Error('binWidth must be numeric: ' + binWidth);
      }
      return bins(name, function getGlobalBinWidth() {
        return binWidth;
      })
    },
    fixedBinMapper: function(binsPerGenome) {
      var name = 'fixed_' + binsPerGenome + '__bin';
      if(!isNumber(binsPerGenome)) {
        throw new Error('binsPerGenome must be numeric: ' + binsPerGenome);
      }
      return bins(name, function determineBinWidthForGenome(genome) {
        if (genome.assembledGenomeSize === 0) return 0;

        if (genome.assembledGenomeSize < 100000) {
          throw new Error('assembled genome sizes between 1 and 100000 are not supported');
        }

        var binSize = Math.floor(genome.assembledGenomeSize / binsPerGenome);

        function countBins(binSize) {
          var nbins = 0;
          genome.eachRegion(function(region) {
            if (region.name === 'UNANCHORED') {
              nbins++
            }
            else {
              nbins += Math.ceil(region.size / binSize);
            }
          });
          return nbins;
        }

        var nbins = countBins(binSize);
        if (nbins > binsPerGenome) {
          var a = Math.floor(genome.assembledGenomeSize / (binsPerGenome - genome.regionCount()));
          var b = binSize;
          while (a != b && countBins(a) != binsPerGenome) { // infinite loop without a != b
            var m = Math.floor((a+b)/2);
            var mbins = countBins(m);
            if (mbins <= binsPerGenome) {
              a = m;
            }
            else if (mbins > binsPerGenome) {
              b = m;
            }
          }
          binSize = a;
        }
        return binSize;
      })
    },
    // assume we've been given array of valid non-overlapping intervals as objects with keys
    // taxon_id, region, start, end
    // arg checking might be a good idea
    variableBinMapper: function(binsArray) {
      return variableBins(binsArray)
    }
  };
};
<|endoftext|>


<commit_before>//fgnass.github.com/spin.js#v1.1
(function(window, document, undefined) {

/**
 * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
 * Licensed under the MIT license
 */

  var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
      animations = {}, /* Animation rules keyed by their name */
      useCssAnimations;

  /**
   * Utility function to create elements. If no tag name is given,
   * a DIV is created. Optionally properties can be passed.
   */
  function createEl(tag, prop) {
    var el = document.createElement(tag || 'div'),
        n;

    for(n in prop) {
      el[n] = prop[n];
    }
    return el;
  }

  /**
   * Inserts child1 before child2. If child2 is not specified,
   * child1 is appended. If child2 has no parentNode, child2 is
   * appended first.
   */
  function ins(parent, child1, child2) {
    if(child2 && !child2.parentNode) ins(parent, child2);
    parent.insertBefore(child1, child2||null);
    return parent;
  }

  /**
   * Insert a new stylesheet to hold the @keyframe or VML rules.
   */
  ins(document.getElementsByTagName('head')[0], createEl('style'));
  var sheet = document.styleSheets[document.styleSheets.length-1];

  /**
   * Creates an opacity keyframe animation rule and returns its name.
   * Since most mobile Webkits have timing issues with animation-delay,
   * we create separate rules for each line/segment.
   */
  function addAnimation(alpha, trail, i, lines) {
    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
        start = 0.01 + i/lines*100,
        z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
        prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
        pre = prefix && '-'+prefix+'-' || '';

    if (!animations[name]) {
      sheet.insertRule(
        '@' + pre + 'keyframes ' + name + '{' +
        '0%{opacity:'+z+'}' +
        start + '%{opacity:'+ alpha + '}' +
        (start+0.01) + '%{opacity:1}' +
        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
        '100%{opacity:'+ z + '}' +
        '}', 0);
      animations[name] = 1;
    }
    return name;
  }

  /**
   * Tries various vendor prefixes and returns the first supported property.
   **/
  function vendor(el, prop) {
    var s = el.style,
        pp,
        i;

    if(s[prop] !== undefined) return prop;
    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
    for(i=0; i<prefixes.length; i++) {
      pp = prefixes[i]+prop;
      if(s[pp] !== undefined) return pp;
    }
  }

  /**
   * Sets multiple style properties at once.
   */
  function css(el, prop) {
    for (var n in prop) {
      el.style[vendor(el, n)||n] = prop[n];
    }
    return el;
  }

  /**
   * Fills in default values.
   */
  function defaults(obj, def) {
    for (var n in def) {
      if (obj[n] === undefined) obj[n] = def[n];
    }
    return obj;
  }

  /**
   * Returns the absolute page-offset of the given element.
   */
  function pos(el) {
    var o = {x:el.offsetLeft, y:el.offsetTop};
    while((el = el.offsetParent)) {
      o.x+=el.offsetLeft;
      o.y+=el.offsetTop;
    }
    return o;
  }

  /** The constructor */
  var Spinner = function Spinner(o) {
    this.opts = defaults(o || {}, {
      lines: 12, // The number of lines to draw
      length: 7, // The length of each line
      width: 5, // The line thickness
      radius: 10, // The radius of the inner circle
      color: '#000', // #rgb or #rrggbb
      speed: 1, // Rounds per second
      trail: 100, // Afterglow percentage
      opacity: 1/4,
      fps: 16
    });
  },
  proto = Spinner.prototype = {
    spin: function(target) {
      var self = this,
          el = self.el = css(createEl(), {position: 'relative'}),
          ep, // element position
          tp; // target position

      if (target) {
        tp = pos(ins(target, el, target.firstChild));
        ep = pos(el);
        css(el, {
          left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
          top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
        });
      }
      el.setAttribute('aria-role', 'progressbar');
      self.lines(el, self.opts);
      if (!useCssAnimations) {
        // No CSS animation support, use setTimeout() instead
        var o = self.opts,
            i = 0,
            fps = o.fps,
            f = fps/o.speed,
            ostep = (1-o.opacity)/(f*o.trail / 100),
            astep = f/o.lines;

        (function anim() {
          i++;
          for (var s=o.lines; s; s--) {
            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
            self.opacity(el, o.lines-s, alpha, o);
          }
          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
        })();
      }
      return self;
    },
    stop: function() {
      var self = this,
          el = self.el;

      clearTimeout(self.timeout);
      if (el && el.parentNode) el.parentNode.removeChild(el);
      self.el = undefined;
      return self;
    }
  };
  proto.lines = function(el, o) {
    var i = 0,
        seg;

    function fill(color, shadow) {
      return css(createEl(), {
        position: 'absolute',
        width: (o.length+o.width) + 'px',
        height: o.width + 'px',
        background: color,
        boxShadow: shadow,
        transformOrigin: 'left',
        transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
        borderRadius: (o.width>>1) + 'px'
      });
    }
    for (; i < o.lines; i++) {
      seg = css(createEl(), {
        position: 'absolute',
        top: 1+~(o.width/2) + 'px',
        transform: 'translate3d(0,0,0)',
        opacity: o.opacity,
        animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
      });
      if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
      ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
    }
    return el;
  };
  proto.opacity = function(el, i, val) {
    el.childNodes[i].style.opacity = val;
  };

  /////////////////////////////////////////////////////////////////////////
  // VML rendering for IE
  /////////////////////////////////////////////////////////////////////////

  /**
   * Check and init VML support
   */
  (function() {
    var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
        i;

    if (!vendor(s, 'transform') && s.adj) {

      // VML support detected. Insert CSS rules ...
      for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');

      proto.lines = function(el, o) {
        var r = o.length+o.width,
            s = 2*r;

        function grp() {
          return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
        }

        var g = grp(),
            margin = ~(o.length+o.radius+o.width)+'px',
            i;

        function seg(i, dx, filter) {
          ins(g,
            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
              ins(css(createEl('roundrect', {arcsize: 1}), {
                  width: r,
                  height: o.width,
                  left: o.radius,
                  top: -o.width>>1,
                  filter: filter
                }),
                createEl('fill', {color: o.color, opacity: o.opacity}),
                createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
              )
            )
          );
        }

        if (o.shadow) {
          for (i = 1; i <= o.lines; i++) {
            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
          }
        }
        for (i = 1; i <= o.lines; i++) {
          seg(i);
        }
        return ins(css(el, {
          margin: margin + ' 0 0 ' + margin
        }), g);
      };
      proto.opacity = function(el, i, val, o) {
        o = o.shadow && o.lines || 0;
        el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
      };
    }
    else {
      useCssAnimations = vendor(s, 'animation');
    }
  })();

  window.Spinner = Spinner;

})(window, document);
<commit_msg>The new operator is now optional. Closes #14<commit_after>//fgnass.github.com/spin.js#v1.1
(function(window, document, undefined) {

/**
 * Copyright (c) 2011 Felix Gnass [fgnass at neteye dot de]
 * Licensed under the MIT license
 */

  var prefixes = ['webkit', 'Moz', 'ms', 'O'], /* Vendor prefixes */
      animations = {}, /* Animation rules keyed by their name */
      useCssAnimations;

  /**
   * Utility function to create elements. If no tag name is given,
   * a DIV is created. Optionally properties can be passed.
   */
  function createEl(tag, prop) {
    var el = document.createElement(tag || 'div'),
        n;

    for(n in prop) {
      el[n] = prop[n];
    }
    return el;
  }

  /**
   * Inserts child1 before child2. If child2 is not specified,
   * child1 is appended. If child2 has no parentNode, child2 is
   * appended first.
   */
  function ins(parent, child1, child2) {
    if(child2 && !child2.parentNode) ins(parent, child2);
    parent.insertBefore(child1, child2||null);
    return parent;
  }

  /**
   * Insert a new stylesheet to hold the @keyframe or VML rules.
   */
  ins(document.getElementsByTagName('head')[0], createEl('style'));
  var sheet = document.styleSheets[document.styleSheets.length-1];

  /**
   * Creates an opacity keyframe animation rule and returns its name.
   * Since most mobile Webkits have timing issues with animation-delay,
   * we create separate rules for each line/segment.
   */
  function addAnimation(alpha, trail, i, lines) {
    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-'),
        start = 0.01 + i/lines*100,
        z = Math.max(1-(1-alpha)/trail*(100-start) , alpha),
        prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase(),
        pre = prefix && '-'+prefix+'-' || '';

    if (!animations[name]) {
      sheet.insertRule(
        '@' + pre + 'keyframes ' + name + '{' +
        '0%{opacity:'+z+'}' +
        start + '%{opacity:'+ alpha + '}' +
        (start+0.01) + '%{opacity:1}' +
        (start+trail)%100 + '%{opacity:'+ alpha + '}' +
        '100%{opacity:'+ z + '}' +
        '}', 0);
      animations[name] = 1;
    }
    return name;
  }

  /**
   * Tries various vendor prefixes and returns the first supported property.
   **/
  function vendor(el, prop) {
    var s = el.style,
        pp,
        i;

    if(s[prop] !== undefined) return prop;
    prop = prop.charAt(0).toUpperCase() + prop.slice(1);
    for(i=0; i<prefixes.length; i++) {
      pp = prefixes[i]+prop;
      if(s[pp] !== undefined) return pp;
    }
  }

  /**
   * Sets multiple style properties at once.
   */
  function css(el, prop) {
    for (var n in prop) {
      el.style[vendor(el, n)||n] = prop[n];
    }
    return el;
  }

  /**
   * Fills in default values.
   */
  function defaults(obj, def) {
    for (var n in def) {
      if (obj[n] === undefined) obj[n] = def[n];
    }
    return obj;
  }

  /**
   * Returns the absolute page-offset of the given element.
   */
  function pos(el) {
    var o = {x:el.offsetLeft, y:el.offsetTop};
    while((el = el.offsetParent)) {
      o.x+=el.offsetLeft;
      o.y+=el.offsetTop;
    }
    return o;
  }

  /** The constructor */
  var Spinner = function Spinner(o) {
    if (!this.spin) return new Spinner(o);
    this.opts = defaults(o || {}, {
      lines: 12, // The number of lines to draw
      length: 7, // The length of each line
      width: 5, // The line thickness
      radius: 10, // The radius of the inner circle
      color: '#000', // #rgb or #rrggbb
      speed: 1, // Rounds per second
      trail: 100, // Afterglow percentage
      opacity: 1/4,
      fps: 16
    });
  },
  proto = Spinner.prototype = {
    spin: function(target) {
      var self = this,
          el = self.el = css(createEl(), {position: 'relative'}),
          ep, // element position
          tp; // target position

      if (target) {
        tp = pos(ins(target, el, target.firstChild));
        ep = pos(el);
        css(el, {
          left: (target.offsetWidth >> 1) - ep.x+tp.x + 'px',
          top: (target.offsetHeight >> 1) - ep.y+tp.y + 'px'
        });
      }
      el.setAttribute('aria-role', 'progressbar');
      self.lines(el, self.opts);
      if (!useCssAnimations) {
        // No CSS animation support, use setTimeout() instead
        var o = self.opts,
            i = 0,
            fps = o.fps,
            f = fps/o.speed,
            ostep = (1-o.opacity)/(f*o.trail / 100),
            astep = f/o.lines;

        (function anim() {
          i++;
          for (var s=o.lines; s; s--) {
            var alpha = Math.max(1-(i+s*astep)%f * ostep, o.opacity);
            self.opacity(el, o.lines-s, alpha, o);
          }
          self.timeout = self.el && setTimeout(anim, ~~(1000/fps));
        })();
      }
      return self;
    },
    stop: function() {
      var self = this,
          el = self.el;

      clearTimeout(self.timeout);
      if (el && el.parentNode) el.parentNode.removeChild(el);
      self.el = undefined;
      return self;
    }
  };
  proto.lines = function(el, o) {
    var i = 0,
        seg;

    function fill(color, shadow) {
      return css(createEl(), {
        position: 'absolute',
        width: (o.length+o.width) + 'px',
        height: o.width + 'px',
        background: color,
        boxShadow: shadow,
        transformOrigin: 'left',
        transform: 'rotate(' + ~~(360/o.lines*i) + 'deg) translate(' + o.radius+'px' +',0)',
        borderRadius: (o.width>>1) + 'px'
      });
    }
    for (; i < o.lines; i++) {
      seg = css(createEl(), {
        position: 'absolute',
        top: 1+~(o.width/2) + 'px',
        transform: 'translate3d(0,0,0)',
        opacity: o.opacity,
        animation: useCssAnimations && addAnimation(o.opacity, o.trail, i, o.lines) + ' ' + 1/o.speed + 's linear infinite'
      });
      if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}));
      ins(el, ins(seg, fill(o.color, '0 0 1px rgba(0,0,0,.1)')));
    }
    return el;
  };
  proto.opacity = function(el, i, val) {
    el.childNodes[i].style.opacity = val;
  };

  /////////////////////////////////////////////////////////////////////////
  // VML rendering for IE
  /////////////////////////////////////////////////////////////////////////

  /**
   * Check and init VML support
   */
  (function() {
    var s = css(createEl('group'), {behavior: 'url(#default#VML)'}),
        i;

    if (!vendor(s, 'transform') && s.adj) {

      // VML support detected. Insert CSS rules ...
      for (i=4; i--;) sheet.addRule(['group', 'roundrect', 'fill', 'stroke'][i], 'behavior:url(#default#VML)');

      proto.lines = function(el, o) {
        var r = o.length+o.width,
            s = 2*r;

        function grp() {
          return css(createEl('group', {coordsize: s +' '+s, coordorigin: -r +' '+-r}), {width: s, height: s});
        }

        var g = grp(),
            margin = ~(o.length+o.radius+o.width)+'px',
            i;

        function seg(i, dx, filter) {
          ins(g,
            ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
              ins(css(createEl('roundrect', {arcsize: 1}), {
                  width: r,
                  height: o.width,
                  left: o.radius,
                  top: -o.width>>1,
                  filter: filter
                }),
                createEl('fill', {color: o.color, opacity: o.opacity}),
                createEl('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
              )
            )
          );
        }

        if (o.shadow) {
          for (i = 1; i <= o.lines; i++) {
            seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)');
          }
        }
        for (i = 1; i <= o.lines; i++) {
          seg(i);
        }
        return ins(css(el, {
          margin: margin + ' 0 0 ' + margin
        }), g);
      };
      proto.opacity = function(el, i, val, o) {
        o = o.shadow && o.lines || 0;
        el.firstChild.childNodes[i+o].firstChild.firstChild.opacity = val;
      };
    }
    else {
      useCssAnimations = vendor(s, 'animation');
    }
  })();

  window.Spinner = Spinner;

})(window, document);
<|endoftext|>


<commit_before>import React from 'react';
import {findDOMNode} from 'react-dom';

const {any, bool} = React.PropTypes;

export class GenericInput extends React.Component {

  static propTypes = {
    value: any,
    disabled: bool,
    placeholder: any,
    className: any
  };
  static defaultProps = {
    disabled: false
  };

  getSubstringBoundingClientRect(start, end) {
    let el = findDOMNode(this.refs.content),
        value = el.textContent;
    el.innerHTML = `${value.substring(0, start)}<span>${value.substring(start, end)}</span>${value.substring(end)}`;
    return el.firstElementChild.getBoundingClientRect();
  }

  render () {
    const {value, disabled, placeholder, className, children, ...rest} = this.props;
    let textValue = String(value);
    if (value == null) {
      textValue = '';
    }
    let classNames = ['text-input'];
    if (className) {
      classNames = classNames.concat(className);
    }
    if (disabled) {
      classNames.push('text-input--disabled');
    }
    if (textValue) {
      classNames.push('text-input--filled');
    }
    return (

{placeholder}

        {children}

          {textValue}

    );
  }
}
<commit_msg>Fixed: `GenericInput` is not focusable<commit_after>import React from 'react';
import {findDOMNode} from 'react-dom';

const {any, bool} = React.PropTypes;

export class GenericInput extends React.Component {

  static propTypes = {
    value: any,
    disabled: bool,
    placeholder: any,
    className: any
  };
  static defaultProps = {
    disabled: false
  };

  getSubstringBoundingClientRect(start, end) {
    let el = findDOMNode(this.refs.content),
        value = el.textContent;
    el.innerHTML = `${value.substring(0, start)}<span>${value.substring(start, end)}</span>${value.substring(end)}`;
    return el.firstElementChild.getBoundingClientRect();
  }

  render () {
    const {value, disabled, placeholder, className, children, ...rest} = this.props;
    let textValue = String(value);
    if (value == null) {
      textValue = '';
    }
    let classNames = ['text-input'];
    if (className) {
      classNames = classNames.concat(className);
    }
    if (disabled) {
      classNames.push('text-input--disabled');
    }
    if (textValue) {
      classNames.push('text-input--filled');
    }
    return (

{placeholder}

        {children}

          {textValue}

    );
  }
}
<|endoftext|>


<commit_before>export default (app) => {
  app.commandLine.appendSwitch('enable-smooth-scrolling', '1');
  app.commandLine.appendSwitch('enable-overlay-scrollbar', '1');
  // DEV: Enables the HTML5 WebAudio API extensions to allow selection of sinkId
  //      --> Choosing audio output device
  app.commandLine.appendSwitch('enable-experimental-web-platform-features', '1');
};
<commit_msg>Disable hardware acceleration on linux.  Fixes #1037<commit_after>export default (app) => {
  app.commandLine.appendSwitch('enable-smooth-scrolling', '1');
  app.commandLine.appendSwitch('enable-overlay-scrollbar', '1');
  // DEV: Enables the HTML5 WebAudio API extensions to allow selection of sinkId
  //      --> Choosing audio output device
  app.commandLine.appendSwitch('enable-experimental-web-platform-features', '1');

  if (process.platform === 'linux') {
    app.disableHardwareAcceleration();
  }
};
<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope){

// bootstrap parsing
function bootstrap() {
  // parse document
  CustomElements.parser.parse(document);
  // one more pass before register is 'live'
  CustomElements.upgradeDocument(document);
  // choose async
  var async = window.Platform && Platform.endOfMicrotask ?
    Platform.endOfMicrotask :
    setTimeout;
  async(function() {
    // set internal 'ready' flag, now document.register will trigger
    // synchronous upgrades
    CustomElements.ready = true;
    // capture blunt profiling data
    CustomElements.readyTime = Date.now();
    if (window.HTMLImports) {
      CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
    }
    // notify the system that we are bootstrapped
    document.body.dispatchEvent(
      new CustomEvent('WebComponentsReady', {bubbles: true})
    );
  });
}

// CustomEvent shim for IE
if (typeof window.CustomEvent !== 'function') {
  window.CustomEvent = function(inType) {
    var e = document.createEvent('HTMLEvents');
    e.initEvent(inType, true, true);
    return e;
  };
}

// When loading at readyState complete time (or via flag), boot custom elements
// immediately.
// If relevant, HTMLImports must already be loaded.
if (document.readyState === 'complete' || scope.flags.eager) {
  bootstrap();
// When loading at readyState interactive time, bootstrap only if HTMLImports
// are not pending. Also avoid IE as the semantics of this state are unreliable.
} else if (document.readyState === 'interactive' && !window.attachEvent &&
    (!window.HTMLImports || window.HTMLImports.ready)) {
  bootstrap();
// When loading at other readyStates, wait for the appropriate DOM event to
// bootstrap.
} else {
  var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded';
  window.addEventListener(loadEvent, bootstrap);
}

})(window.CustomElements);
<commit_msg>dispatch WebComponentsReady event on document instead of body.<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope){

// bootstrap parsing
function bootstrap() {
  // parse document
  CustomElements.parser.parse(document);
  // one more pass before register is 'live'
  CustomElements.upgradeDocument(document);
  // choose async
  var async = window.Platform && Platform.endOfMicrotask ?
    Platform.endOfMicrotask :
    setTimeout;
  async(function() {
    // set internal 'ready' flag, now document.register will trigger
    // synchronous upgrades
    CustomElements.ready = true;
    // capture blunt profiling data
    CustomElements.readyTime = Date.now();
    if (window.HTMLImports) {
      CustomElements.elapsed = CustomElements.readyTime - HTMLImports.readyTime;
    }
    // notify the system that we are bootstrapped
    document.dispatchEvent(
      new CustomEvent('WebComponentsReady', {bubbles: true})
    );
  });
}

// CustomEvent shim for IE
if (typeof window.CustomEvent !== 'function') {
  window.CustomEvent = function(inType) {
    var e = document.createEvent('HTMLEvents');
    e.initEvent(inType, true, true);
    return e;
  };
}

// When loading at readyState complete time (or via flag), boot custom elements
// immediately.
// If relevant, HTMLImports must already be loaded.
if (document.readyState === 'complete' || scope.flags.eager) {
  bootstrap();
// When loading at readyState interactive time, bootstrap only if HTMLImports
// are not pending. Also avoid IE as the semantics of this state are unreliable.
} else if (document.readyState === 'interactive' && !window.attachEvent &&
    (!window.HTMLImports || window.HTMLImports.ready)) {
  bootstrap();
// When loading at other readyStates, wait for the appropriate DOM event to
// bootstrap.
} else {
  var loadEvent = window.HTMLImports ? 'HTMLImportsLoaded' : 'DOMContentLoaded';
  window.addEventListener(loadEvent, bootstrap);
}

})(window.CustomElements);
<|endoftext|>


<commit_before>import { isObject } from 'lodash';

const mewApiError = 'Websocket connection failed';

export const knownErrors = {
  'Can\'t assign to property "request"': mewApiError,
  "Cannot create property 'request'": mewApiError,
  "CONNECTION ERROR: Couldn't connect to node on WS":
    "Couldn't connect to WS node. Please refresh and try again.",
  'connection not open on send': mewApiError,
  'transaction underpriced': 'Transaction gas price too low'
};

const handleError = err => {
  const errorValues = Object.keys(knownErrors);
  const foundError = errorValues.find(item => {
    const message =
      err && err.message
        ? isObject(err.message)
          ? err.message.message
          : err.message
        : err;
    if (!message) return false;
    return message.includes(item);
  });
  return foundError ? true : false;
};

export default handleError;
<commit_msg>fix: 🐛 sentry invalid remainder error<commit_after>import { isObject } from 'lodash';

const mewApiError = 'Websocket connection failed';

export const knownErrors = {
  'Can\'t assign to property "request"': mewApiError,
  "Cannot create property 'request'": mewApiError,
  "CONNECTION ERROR: Couldn't connect to node on WS":
    "Couldn't connect to WS node. Please refresh and try again.",
  'connection not open on send': mewApiError,
  'transaction underpriced': 'Transaction gas price too low',
  'invalid remainder': 'invalid remainder'
};

const handleError = err => {
  const errorValues = Object.keys(knownErrors);
  const foundError = errorValues.find(item => {
    const message =
      err && err.message
        ? isObject(err.message)
          ? err.message.message
          : err.message
        : err;
    if (!message) return false;
    return message.includes(item);
  });
  return foundError ? true : false;
};

export default handleError;
<|endoftext|>