<commit_before>/*
 * Copyright (c) 2011-2013 by Animatron.
 * All rights are reserved.
 *
 * Animatron Player is licensed under the MIT License, see LICENSE.
 *
 * @VERSION
 */

(function() { // anonymous wrapper to exclude global context clash
  var C = anm.C;
  var _ResMan = __anm.resource_manager;

  C.MOD_AUDIO = 'audio';
  if (anm.M[C.MOD_AUDIO]) throw new Error('AUDIO module already enabled');

  anm.M[C.MOD_AUDIO] = {};

  var E = anm.Element;

  // Element functions
  // ----------------------------------------------------------------------------------------------------------------

  var _audio_customRender = function(gtime, ltime, ctx) {
    // TODO: remove
    return false;
  };

  var _onAudioStart = function(ltime, duration) {
    if (!this._audio_is_loaded || this._audio_is_playing) {
      return false;
    }

    this._audio_is_playing = true;
    this._audio.currentTime = this._audio_band_offset + ltime;
    this._audio.volume = 1;
    this._audio.play();
  };

  var _onAudioStop = function(ltime, duration) {
    if (this._audio_is_playing) {
      this._audio.pause();
      this._audio_is_playing = false;
      this._audio.volume = 0;
    }
  };

  E.prototype.importCustomData = function(object, type, importer) {
    if ((14 == type)/*ANM*/ ||
        ("0e" == type)/*ANM_INTACT*/) {
      if (importer == "ANM") {
        /** audio **/
        /*
         * array {
         *     14;                         // 0
         *     string;                     // 1, url
         *     number;                     // 2, band offset
         * } *audio_element*;
         */
        this._audio_url = this._audio_format_url(object[1]);
        this._audio_band_offset = object[2];
      } else if (importer == "ANM_INTACT") {
        this._audio_band_offset = object.bandOffset;
        this._audio_url = this._audio_format_url(object.url);
      }

      this.isAudio = true;
      this._audio = null;
      this._audio_is_loaded = false;
      this._audio_is_playing = false;

      this.on(C.X_START, _onAudioStart);
      this.on(C.X_STOP, _onAudioStop);
      this.on(C.S_STOP, _onAudioStop);
      this.on(C.S_PAUSE, _onAudioStop);

      // assign custom render function
      this.__frameProcessors.push(_audio_customRender);

      this._audio_load();
    }
  };

  E.prototype._audio_format_url = function(url) {
    return url + (this._mpeg_supported() ? ".mp3" : ".ogg");
  };

  E.__test_elm = null;
  E.prototype._mpeg_supported = function() {
    var a = E.__test_elm ? E.__test_elm : (E.__test_elm = document.createElement('audio'), E.__test_elm);
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
  }

  var prev__hasRemoteResources = E.prototype._hasRemoteResources;
  E.prototype._hasRemoteResources = function() {
    return prev__hasRemoteResources.call(this, arguments) || this.isAudio;
  }

  var prev__getRemoteResources = E.prototype._getRemoteResources;
  E.prototype._getRemoteResources = function() {
    var prev = prev__getRemoteResources.call(this, arguments);
    if (!this.isAudio && !prev) return null;
    if (!this.isAudio) return prev;
        // return [ this._audio_url ].concat(prev || [])
    return prev ? [ this._audio_url ].concat(prev) : [ this._audio_url ];
  }

  function audioErrProxy(src, pass_to) {
    return function(err) {
      // e_.MEDIA_ERR_ABORTED=1
      // e_.MEDIA_ERR_NETWORK=2
      // e_.MEDIA_ERR_DECODE=3
      // e_.MEDIA_ERR_SRC_NOT_SUPPORTED=4
      // e_.MEDIA_ERR_ENCRYPTED=5
      pass_to(new Error('Failed to load audio file from ' + src + ' with error code: ' +
                        err.currentTarget.error.code));
    }
  };
  E.prototype._audio_load = function() {
    var me = this;

    _ResMan.loadOrGet(me._audio_url,
      function(notify_success, notify_error) { // loader
          var el = document.createElement("audio");
          el.setAttribute("preload", "auto");

          var listener = function(e) {
            var buffered = el.buffered;
            if (buffered.length == 1) {
                var end = buffered.end(0);
                if (el.duration - end < 0.05) {
                  el.removeEventListener("progress", listener, false);
                  notify_success(el);
                }

                if (window.chrome) {
                  el.volume = 0;
                  el.currentTime = end;
                  el.play();
                  el.pause();
                }
            }
          };

          el.addEventListener("progress", listener, false);
          el.addEventListener("error", audioErrProxy(me._audio_url, notify_error), false);

          try {
            document.getElementsByTagName("body")[0].appendChild(el);
            el.src = me._audio_url;
          } catch(e) { notify_error(e); }
      },
      function(audio) { // oncomplete
          me._audio = audio;
          me._audio_is_loaded = true;
      },
      function(err) { __anm.console.error(err.message || err); }); // onerror

  };

})();<commit_msg>fix chrome progress events for cached audio<commit_after>/*
 * Copyright (c) 2011-2013 by Animatron.
 * All rights are reserved.
 *
 * Animatron Player is licensed under the MIT License, see LICENSE.
 *
 * @VERSION
 */

(function() { // anonymous wrapper to exclude global context clash
  var C = anm.C;
  var _ResMan = __anm.resource_manager;

  C.MOD_AUDIO = 'audio';
  if (anm.M[C.MOD_AUDIO]) throw new Error('AUDIO module already enabled');

  anm.M[C.MOD_AUDIO] = {};

  var E = anm.Element;

  // Element functions
  // ----------------------------------------------------------------------------------------------------------------

  var _audio_customRender = function(gtime, ltime, ctx) {
    // TODO: remove
    return false;
  };

  var _onAudioStart = function(ltime, duration) {
    if (!this._audio_is_loaded || this._audio_is_playing) {
      return false;
    }

    this._audio_is_playing = true;
    this._audio.currentTime = this._audio_band_offset + ltime;
    this._audio.volume = 1;
    this._audio.play();
  };

  var _onAudioStop = function(ltime, duration) {
    if (this._audio_is_playing) {
      this._audio.pause();
      this._audio_is_playing = false;
      this._audio.volume = 0;
    }
  };

  E.prototype.importCustomData = function(object, type, importer) {
    if ((14 == type)/*ANM*/ ||
        ("0e" == type)/*ANM_INTACT*/) {
      if (importer == "ANM") {
        /** audio **/
        /*
         * array {
         *     14;                         // 0
         *     string;                     // 1, url
         *     number;                     // 2, band offset
         * } *audio_element*;
         */
        this._audio_url = this._audio_format_url(object[1]);
        this._audio_band_offset = object[2];
      } else if (importer == "ANM_INTACT") {
        this._audio_band_offset = object.bandOffset;
        this._audio_url = this._audio_format_url(object.url);
      }

      this.isAudio = true;
      this._audio = null;
      this._audio_is_loaded = false;
      this._audio_is_playing = false;
      this._audio_canPlay = false;

      this.on(C.X_START, _onAudioStart);
      this.on(C.X_STOP, _onAudioStop);
      this.on(C.S_STOP, _onAudioStop);
      this.on(C.S_PAUSE, _onAudioStop);

      // assign custom render function
      this.__frameProcessors.push(_audio_customRender);

      this._audio_load();
    }
  };

  E.prototype._audio_format_url = function(url) {
    return url + (this._mpeg_supported() ? ".mp3" : ".ogg");
  };

  E.__test_elm = null;
  E.prototype._mpeg_supported = function() {
    var a = E.__test_elm ? E.__test_elm : (E.__test_elm = document.createElement('audio'), E.__test_elm);
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
  }

  var prev__hasRemoteResources = E.prototype._hasRemoteResources;
  E.prototype._hasRemoteResources = function() {
    return prev__hasRemoteResources.call(this, arguments) || this.isAudio;
  }

  var prev__getRemoteResources = E.prototype._getRemoteResources;
  E.prototype._getRemoteResources = function() {
    var prev = prev__getRemoteResources.call(this, arguments);
    if (!this.isAudio && !prev) return null;
    if (!this.isAudio) return prev;
        // return [ this._audio_url ].concat(prev || [])
    return prev ? [ this._audio_url ].concat(prev) : [ this._audio_url ];
  }

  function audioErrProxy(src, pass_to) {
    return function(err) {
      // e_.MEDIA_ERR_ABORTED=1
      // e_.MEDIA_ERR_NETWORK=2
      // e_.MEDIA_ERR_DECODE=3
      // e_.MEDIA_ERR_SRC_NOT_SUPPORTED=4
      // e_.MEDIA_ERR_ENCRYPTED=5
      pass_to(new Error('Failed to load audio file from ' + src + ' with error code: ' +
                        err.currentTarget.error.code));
    }
  };
  E.prototype._audio_load = function() {
    var me = this;

    _ResMan.loadOrGet(me._audio_url,
      function(notify_success, notify_error) { // loader
          var el = document.createElement("audio");
          el.setAttribute("preload", "auto");

          var pingChromeToLoad = function(element) {
            if (me._audio_canPlay && window.chrome) {
              if (element.buffered.length == 1) {
                var end = element.buffered.end(0);
                if (element.duration - end > 0.05) {
                  element.volume = 0;
                  element.currentTime = end;
                  element.play();
                  element.pause();
                }
              }
            }
          };

          var progressListener = function(e) {
            var buffered = el.buffered;
            if (buffered.length == 1) {
                var end = buffered.end(0);
                if (el.duration - end < 0.05) {
                  el.removeEventListener("progress", progressListener, false);
                  el.removeEventListener("canplay", canPlayListener, false);
                  notify_success(el);
                }

                pingChromeToLoad(el);
            }
          };

          var canPlayListener = function(e) {
            me._audio_canPlay = true;
            pingChromeToLoad(el);
          };

          el.addEventListener("progress", progressListener, false);
          el.addEventListener("canplay", canPlayListener, false);
          el.addEventListener("error", audioErrProxy(me._audio_url, notify_error), false);

          try {
            document.getElementsByTagName("body")[0].appendChild(el);
            el.src = me._audio_url;
          } catch(e) { notify_error(e); }
      },
      function(audio) { // oncomplete
          me._audio = audio;
          me._audio_is_loaded = true;
      },
      function(err) { __anm.console.error(err.message || err); }); // onerror
  };

})();<|endoftext|>


<commit_before>const env = require("dotenv")
const fs = require("fs")
const path = require("path")
const sharify = require("./sharify")

const webpack = require("webpack")
const webpackMerge = require("webpack-merge")
const { CheckerPlugin } = require("awesome-typescript-loader")

/**
 * Write out a file that stubs the data that’s normally shared with the client through the `sharify` module. This file
 * is then replaced in the product of webpack where normally the actual `sharify` module would be loaded.
 */
const { METAPHYSICS_ENDPOINT } = env.config().parsed
const sharifyPath = sharify({ METAPHYSICS_ENDPOINT })

/**
 * Only use HMR plugin in dev mode
 */
let plugins = [new CheckerPlugin()]
if (process.env.NODE_ENV === "development") {
  plugins.push(new webpack.HotModuleReplacementPlugin())
}

// A mix of  the base from Emission's webpack setup, and the simple config for
// storybooks: https://storybook.js.org/configurations/custom-webpack-config/

module.exports = {
  devtool: "#inline-source-map", // Otherwise getting errors about e.g. `Relay` not being defined.
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx"],
    alias: {
      sharify: sharifyPath.replace(/\.js$/, ""),
    },
  },
  module: {
    rules: [
      { test: /\.json$/, loader: "json-loader" },
      {
        exclude: [/node_modules/, /__tests__/],
        use: [
          {
            loader: "awesome-typescript-loader",
            options: {
              useBabel: true,
              useCache: true,
              useTranspileModule: true, // Supposedly faster, won’t work if/when we emit TS declaration files.
            },
          },
        ],
        test: /\.tsx?$/,
      },
    ],
  },
  plugins: plugins,
  node: {
    console: true,
    fs: "empty",
    net: "empty",
    tls: "empty",
  },
}
<commit_msg>Remove unnecessary storybook webpack config<commit_after>const env = require("dotenv")
const fs = require("fs")
const path = require("path")
const sharify = require("./sharify")

const webpack = require("webpack")
const webpackMerge = require("webpack-merge")
const { CheckerPlugin } = require("awesome-typescript-loader")

/**
 * Write out a file that stubs the data that’s normally shared with the client through the `sharify` module. This file
 * is then replaced in the product of webpack where normally the actual `sharify` module would be loaded.
 */
const { METAPHYSICS_ENDPOINT } = env.config().parsed
const sharifyPath = sharify({ METAPHYSICS_ENDPOINT })

/**
 * Only use HMR plugin in dev mode
 */
let plugins = [new CheckerPlugin()]
if (process.env.NODE_ENV === "development") {
  plugins.push(new webpack.HotModuleReplacementPlugin())
}

// A mix of  the base from Emission's webpack setup, and the simple config for
// storybooks: https://storybook.js.org/configurations/custom-webpack-config/

module.exports = {
  devtool: "#inline-source-map", // Otherwise getting errors about e.g. `Relay` not being defined.
  resolve: {
    extensions: [".js", ".jsx", ".ts", ".tsx"],
    alias: {
      sharify: sharifyPath.replace(/\.js$/, ""),
    },
  },
  module: {
    rules: [
      { test: /\.json$/, loader: "json-loader" },
      {
        exclude: [/node_modules/, /__tests__/],
        use: [
          {
            loader: "awesome-typescript-loader",
            options: {
              useBabel: true,
              useCache: true,
              useTranspileModule: true, // Supposedly faster, won’t work if/when we emit TS declaration files.
            },
          },
        ],
        test: /\.tsx?$/,
      },
    ],
  },
  plugins: plugins,
}
<|endoftext|>


<commit_before>/*!
 * Copyright 2008-2014 Alexander Kuzmin <roosit@abricos.org>
 * Licensed under the MIT license
 */

var Component = new Brick.Component();
Component.requires = {
    yui: ['yui-base', 'model-list']
};
Component.entryPoint = function(NS){

    var Y = Brick.YUI;

    var AppItem = function(){
        AppItem.superclass.constructor.apply(this, arguments);
    };
    NS.AppItem = Y.extend(AppItem, Y.Base, {
        toJSON: function(){
            var attrs = this.getAttrs();

            delete attrs.destroyed;
            delete attrs.initialized;

            return attrs;
        }
    }, {
        NAME: 'appItem',
        ATTRS: {}
    });

    // Taken from YUI.ModelList
    var AppItemList = function(){
        AppItemList.superclass.constructor.apply(this, arguments);
    };
    NS.AppItemList = Y.extend(AppItemList, Y.Base, {

        _isAbricosAppItemList: true,

        appItem: NS.AppItem,

        idField: 'id',

        initializer: function(config){
            config || (config = {});

            this.idField = config.idField || this.idField;

            var appItem = this.appItem = config.appItem || this.appItem;

            if (typeof appItem === 'string'){
                this.appItem = Y.Object.getValue(Brick.mod, appItem.split('.'))
                if (this.appItem){
                    Y.error('AppItemList: AppItem class not found: ' + appItem);
                }
            }

            this.publish('add', {defaultFN: this._defAddFn});
            this.publish('remove', {defaultFN: this._defRemoveFn});

            this._clear();

            if (config.items){
                this.add(config.items, {silent: true});
            }
        },
        destructor: function(){
            this._clear();
        },
        _clear: function(){
            this._items = [];
            this._idMap = {};
        },
        add: function(appItems, options){
            var isList = appItems._isAbricosAppItemList;

            if (isList || Y.Lang.isArray(appItems)){
                return Y.Array.map(isList ? appItems.toArray() : appItems, function(appItem, index){
                    var appItemOptions = options || {};

                    // When an explicit insertion index is specified, ensure that
                    // the index is increased by one for each subsequent item in the
                    // array.
                    if ('index' in appItemOptions){
                        appItemOptions = Y.merge(appItemOptions, {
                            index: appItemOptions.index + index
                        });
                    }

                    return this._add(appItem, appItemOptions);
                }, this);
            } else {
                return this._add(appItem, options);
            }
        },
        _createAppItemInstance: function(data){
            return new (this.appItem)(data);
        },
        _add: function(appItem, options){
            if (!appItem._isAbricosAppItem){
                appItem = this._createAppItemInstance(appItem);
            }
            var id = appItem.get(this.idField);
            if (this._idMap[id]){
                this.fire('error', {
                    error: 'AppItem is already in the list.',
                    appItem: appItem,
                    src: 'add'
                });

                return;
            }

            var facade = Y.merge(options, {
                index: 'index' in options ? options.index : this._findIndex(appItem),
                appItem: appItem
            });

            if (options.silent){
                this._defAddFn(facade);
            } else {
                this.fire('add', facade);
            }

            return appItem;
        },
        _defAddFn: function(e){
            var appItem = e.appItem,
                id = appItem.get(this.idField);

            this._idMap[id] = appItem;
            this._items.splice(e.index, 0, appItem);
        },
        remote: function(appItem, options){
            this._remove(appItem, options);
        },
        _remove: function(appItem, options){
            var index, facade;

            options || (options = {});

            if (Lang.isNumber(appItem)){
                index = appItem;
                appItem = this.item(index);
            } else {
                index = this.indexOf(appItem);
            }

            if (index === -1 || !appItem){
                this.fire('error', {
                    error: 'AppItem is not in the list.',
                    index: index,
                    appItem: appItem,
                    src: 'remove'
                });

                return;
            }

            facade = Y.merge(options, {
                index: index,
                appItem: appItem
            });

            if (options.silent){
                this._defRemoveFn(facade);
            } else {
                this.fire('remove', facade);
            }

            return appItem;
        },
        _defRemoveFn: function(e){
            var appItem = e.appItem,
                id = appItem.get(this.idField);

            delete this._idMap[id];

            this._items.splice(e.index, 1);
        },
        _findIndex: function(appItem){
            var items = this._items,
                max = items.length,
                min = 0,
                item, middle, needle;

            if (!this.comparator || !max){
                return max;
            }

            needle = this.comparator(appItem);

            // Perform an iterative binary search to determine the correct position
            // based on the return value of the `comparator` function.
            while (min < max){
                middle = (min + max) >> 1; // Divide by two and discard remainder.
                item = items[middle];

                if (this._compare(this.comparator(item), needle) < 0){
                    min = middle + 1;
                } else {
                    max = middle;
                }
            }

            return min;
        },
        _compare: function(a, b){
            return a < b ? -1 : (a > b ? 1 : 0);
        },
        getById: function(id){
            return this._idMap[id] || null;
        },
        each: function(callback, context){
            var items = this._items.concat(),
                i, item, len;

            for (i = 0, len = items.length; i < len; i++){
                item = items[i];
                callback.call(context || item, item, i, this);
            }
            return this;
        },
        some: function(callback, context){
            var items = this._items.concat(),
                i, item, len;

            for (i = 0, len = items.length; i < len; i++){
                item = items[i];
                if (callback.call(context || item, item, i, this)){
                    return true;
                }
            }
            return false;
        },
        map: function(fn, context){
            return Y.Array.map(this._items, fn, context);
        },
        toArray: function(){
            return this._items.concat();
        },
        toJSON: function(){
            return this.map(function(appItem){
                return appItem.toJSON();
            });
        }
    }, {
        NAME: 'appItemList'
    });
    Y.augment(AppItemList, Y.ArrayList);

    NS.AppStructure = Y.Base.create('appStructure', Y.Base, [], {
        structureList: null,

        initializer: function(config){
            config || (config = {});

            this.structureList = new NS.AppStructure.StructureList({
                items: config.structures
            });
        }
    });

    NS.AppStructure.Field = Y.Base.create('appStructure_Field', NS.AppItem, [], {}, {
        ATTRS: {
            name: {value: ''},
            multiLang: {value: false},
            type: {value: 'string'},
            default: {value: ''},
            json: {value: ''}
        }
    });

    NS.AppStructure.FieldList = Y.Base.create('appStructure_FieldList', NS.AppItemList, [], {
        appItem: NS.AppStructure.Field,
        idField: 'name'
    });

    NS.AppStructure.Structure = Y.Base.create('appStructure_Structure', NS.AppItem, [], {
        fieldList: null,

        initializer: function(config){
            config || (config = {});

            this.fieldList = new NS.AppStructure.FieldList({
                items: config.fields
            });
        },
        toJSON: function(){
            var json = NS.AppStructure.Structure.superclass.toJSON.apply(this, arguments);
            json.fields = this.fieldList.toJSON();
            return json;
        }
    }, {
        ATTRS: {
            name: {value: ''}
        }
    });

    NS.AppStructure.StructureList = Y.Base.create('appStructure_StructureList', NS.AppItemList, [], {
        appItem: NS.AppStructure.Structure,
        idField: 'name'
    });

    NS.AppModel = Y.Base.create('appModel', NS.AppItem, [], {
        isAppModel: true,
        appInstance: null,
        structureName: null,
        structure: null,
        initializer: function(config){
            config || (config = {});
            if (config.appInstance){
                this.appInstance = config.appInstance;
            }
            this.buildAttributes();

            if (this.structure){
                this.structure.fieldList.each(function(field){
                    var fInfo = field.toJSON();
                    if (fInfo.json in config){
                        this.set(fInfo.name, config[fInfo.json]);
                    }
                }, this);
            }
        },
        buildAttributes: function(){
            if (!this.structure){
                if (!this.structureName || !this.appInstance){
                    return;
                }
                var appStructure = this.appInstance.get('appStructure');
                if (!appStructure){
                    return;
                }
                this.structure = appStructure.structureList.getById(this.structureName);
                if (!this.structure){
                    return;
                }
            }
            this.structure.fieldList.each(function(field){
                var name = field.get('name');
                if (this.attrAdded(name)){
                    return;
                }
                this.addAttr(name, {
                    field: field,
                    setter: '_attrFieldSetter',
                    getter: '_attrFieldGetter'
                });
            }, this);
        },
        getField: function(name){
            var attrCfg = this._state.data[name];
            if (!attrCfg){
                return null;
            }
            return attrCfg.field || null;
        },
        _attrFieldSetter: function(val, name){
            var field = this.getField(name);

            return NS.AppModel.convert(val, field);
        },
        _attrFieldGetter: function(val, name){
            var field = this.getField(name);
            return NS.AppModel.convert(val, field);
        },
        toJSON: function(toString){
            if (!toString){
                return NS.AppModel.superclass.toJSON.apply(this);
            }

            var ret = {}, val, name, type, langName,
                LANGS = Brick.env.languages, lng, i, lngValCur;

            this.structure.fieldList.each(function(field){
                name = field.get('name');
                if (!this.attrAdded(name)){
                    return;
                }
                val = this.get(name);
                if (field.get('type') === 'multilang'){
                    lngValCur = '';
                    for (i = 0; i < LANGS.length; i++){
                        lng = LANGS[i];
                        langName = NS.AppModel.langFieldName(name, lng);
                        ret[langName] = val[lng] || '';
                        if (lng === Brick.env.language){
                            lngValCur = ret[langName];
                        }
                    }
                    if (lngValCur === '' && LANGS.length > 1){
                        for (i = 0; i < LANGS.length; i++){
                            lng = LANGS[i];
                            if (lng === Brick.env.language){
                                continue;
                            }
                            if (val[lng] && val[lng] !== ''){
                                lngValCur = val[lng];
                                break;
                            }
                        }
                    }
                    ret[name] = lngValCur;
                } else {
                    ret[name] = val;
                }
            }, this);

            return ret;
        }
    }, {
        ATTRS: {}
    });
    NS.AppModel.langFieldName = function(name, lang){
        return name + '_' + lang;
    }
    NS.AppModel.convert = function(val, field){
        if (!field){
            return val
        }

        switch (field.get('type')) {
            case 'string':
                return Y.Lang.isString(val) ? val : '';
            case 'int':
                return (val | 0);
        }
        return val;
    };

    var AppModelList = function(){
        AppModelList.superclass.constructor.apply(this, arguments);
    };
    NS.AppModelList = Y.extend(AppModelList, NS.AppItemList, {
        appInstance: null,
        appItem: NS.AppModel,
        init: function(config){
            config || (config = {});
            if (config.appInstance){
                this.appInstance = config.appInstance;
            }
            AppModelList.superclass.init.apply(this, arguments);
        },
        /*
         initializer: function(){
         console.log(this);
         this.each(function(item){
         console.log(item.toJSON());
         });
         },
         /**/
        _createAppItemInstance: function(data){
            data = data || {};
            if (this.appInstance){
                data.appInstance = this.appInstance;
            }
            return new (this.appItem)(data);
        }
    }, {
        NAME: 'appModelList',
        ATTRS: {}
    });

};<commit_msg>bugfix: set ID attribute by json in AppModel<commit_after>var Component = new Brick.Component();
Component.requires = {
    yui: ['yui-base', 'model-list'] // TODO: change model-list to arraylist
};
Component.entryPoint = function(NS){

    var Y = Brick.YUI;

    var AppItem = function(){
        AppItem.superclass.constructor.apply(this, arguments);
    };
    NS.AppItem = Y.extend(AppItem, Y.Base, {
        toJSON: function(){
            var attrs = this.getAttrs();

            delete attrs.destroyed;
            delete attrs.initialized;

            return attrs;
        }
    }, {
        NAME: 'appItem',
        ATTRS: {}
    });

    // Taken from YUI.ModelList
    var AppItemList = function(){
        AppItemList.superclass.constructor.apply(this, arguments);
    };
    NS.AppItemList = Y.extend(AppItemList, Y.Base, {

        _isAbricosAppItemList: true,

        appItem: NS.AppItem,

        idField: 'id',

        initializer: function(config){
            config || (config = {});

            this.idField = config.idField || this.idField;

            var appItem = this.appItem = config.appItem || this.appItem;

            if (typeof appItem === 'string'){
                this.appItem = Y.Object.getValue(Brick.mod, appItem.split('.'))
                if (this.appItem){
                    Y.error('AppItemList: AppItem class not found: ' + appItem);
                }
            }

            this.publish('add', {defaultFN: this._defAddFn});
            this.publish('remove', {defaultFN: this._defRemoveFn});

            this._clear();

            if (config.items){
                this.add(config.items, {silent: true});
            }
        },
        destructor: function(){
            this._clear();
        },
        _clear: function(){
            this._items = [];
            this._idMap = {};
        },
        add: function(appItems, options){
            var isList = appItems._isAbricosAppItemList;

            if (isList || Y.Lang.isArray(appItems)){
                return Y.Array.map(isList ? appItems.toArray() : appItems, function(appItem, index){
                    var appItemOptions = options || {};

                    // When an explicit insertion index is specified, ensure that
                    // the index is increased by one for each subsequent item in the
                    // array.
                    if ('index' in appItemOptions){
                        appItemOptions = Y.merge(appItemOptions, {
                            index: appItemOptions.index + index
                        });
                    }

                    return this._add(appItem, appItemOptions);
                }, this);
            } else {
                return this._add(appItem, options);
            }
        },
        _createAppItemInstance: function(data){
            return new (this.appItem)(data);
        },
        _add: function(appItem, options){
            if (!appItem._isAbricosAppItem){
                appItem = this._createAppItemInstance(appItem);
            }
            var id = appItem.get(this.idField);
            if (this._idMap[id]){
                this.fire('error', {
                    error: 'AppItem is already in the list.',
                    appItem: appItem,
                    src: 'add'
                });

                return;
            }

            var facade = Y.merge(options, {
                index: 'index' in options ? options.index : this._findIndex(appItem),
                appItem: appItem
            });

            if (options.silent){
                this._defAddFn(facade);
            } else {
                this.fire('add', facade);
            }

            return appItem;
        },
        _defAddFn: function(e){
            var appItem = e.appItem,
                id = appItem.get(this.idField);

            this._idMap[id] = appItem;
            this._items.splice(e.index, 0, appItem);
        },
        remote: function(appItem, options){
            this._remove(appItem, options);
        },
        _remove: function(appItem, options){
            var index, facade;

            options || (options = {});

            if (Lang.isNumber(appItem)){
                index = appItem;
                appItem = this.item(index);
            } else {
                index = this.indexOf(appItem);
            }

            if (index === -1 || !appItem){
                this.fire('error', {
                    error: 'AppItem is not in the list.',
                    index: index,
                    appItem: appItem,
                    src: 'remove'
                });

                return;
            }

            facade = Y.merge(options, {
                index: index,
                appItem: appItem
            });

            if (options.silent){
                this._defRemoveFn(facade);
            } else {
                this.fire('remove', facade);
            }

            return appItem;
        },
        _defRemoveFn: function(e){
            var appItem = e.appItem,
                id = appItem.get(this.idField);

            delete this._idMap[id];

            this._items.splice(e.index, 1);
        },
        _findIndex: function(appItem){
            var items = this._items,
                max = items.length,
                min = 0,
                item, middle, needle;

            if (!this.comparator || !max){
                return max;
            }

            needle = this.comparator(appItem);

            // Perform an iterative binary search to determine the correct position
            // based on the return value of the `comparator` function.
            while (min < max){
                middle = (min + max) >> 1; // Divide by two and discard remainder.
                item = items[middle];

                if (this._compare(this.comparator(item), needle) < 0){
                    min = middle + 1;
                } else {
                    max = middle;
                }
            }

            return min;
        },
        _compare: function(a, b){
            return a < b ? -1 : (a > b ? 1 : 0);
        },
        getById: function(id){
            return this._idMap[id] || null;
        },
        each: function(callback, context){
            var items = this._items.concat(),
                i, item, len;

            for (i = 0, len = items.length; i < len; i++){
                item = items[i];
                callback.call(context || item, item, i, this);
            }
            return this;
        },
        some: function(callback, context){
            var items = this._items.concat(),
                i, item, len;

            for (i = 0, len = items.length; i < len; i++){
                item = items[i];
                if (callback.call(context || item, item, i, this)){
                    return true;
                }
            }
            return false;
        },
        map: function(fn, context){
            return Y.Array.map(this._items, fn, context);
        },
        toArray: function(){
            return this._items.concat();
        },
        toJSON: function(){
            return this.map(function(appItem){
                return appItem.toJSON();
            });
        }
    }, {
        NAME: 'appItemList'
    });
    Y.augment(AppItemList, Y.ArrayList);

    NS.AppStructure = Y.Base.create('appStructure', Y.Base, [], {
        structureList: null,

        initializer: function(config){
            config || (config = {});

            this.structureList = new NS.AppStructure.StructureList({
                items: config.structures
            });
        }
    });

    NS.AppStructure.Field = Y.Base.create('appStructure_Field', NS.AppItem, [], {}, {
        ATTRS: {
            name: {value: ''},
            multiLang: {value: false},
            type: {value: 'string'},
            default: {value: ''},
            json: {value: ''}
        }
    });

    NS.AppStructure.FieldList = Y.Base.create('appStructure_FieldList', NS.AppItemList, [], {
        appItem: NS.AppStructure.Field,
        idField: 'name'
    });

    NS.AppStructure.Structure = Y.Base.create('appStructure_Structure', NS.AppItem, [], {
        fieldList: null,

        initializer: function(config){
            config || (config = {});

            this.fieldList = new NS.AppStructure.FieldList({
                items: config.fields
            });
        },
        toJSON: function(){
            var json = NS.AppStructure.Structure.superclass.toJSON.apply(this, arguments);
            json.fields = this.fieldList.toJSON();
            return json;
        }
    }, {
        ATTRS: {
            name: {value: ''}
        }
    });

    NS.AppStructure.StructureList = Y.Base.create('appStructure_StructureList', NS.AppItemList, [], {
        appItem: NS.AppStructure.Structure,
        idField: 'name'
    });

    NS.AppModel = Y.Base.create('appModel', NS.AppItem, [], {
        isAppModel: true,
        appInstance: null,
        structureName: null,
        structure: null,
        init: function(config){
            config || (config = {});
            if (config.appInstance){
                this.appInstance = config.appInstance;
            }

            NS.AppModel.superclass.init.apply(this, arguments);
        },
        initializer: function(config){
            config || (config = {});

            this.buildAttributes();

            if (this.structure){
                this.structure.fieldList.each(function(field){
                    var fInfo = field.toJSON(),
                        name = fInfo.json ? fInfo.json : fInfo.name;

                    if (name in config){
                        this.set(fInfo.name, config[name]);
                    }
                }, this);
            }
        },
        buildAttributes: function(){
            if (!this.structure){
                if (!this.structureName || !this.appInstance){
                    return;
                }
                var appStructure = this.appInstance.get('appStructure');
                if (!appStructure){
                    return;
                }
                this.structure = appStructure.structureList.getById(this.structureName);
                if (!this.structure){
                    return;
                }
            }

            this.structure.fieldList.each(function(field){
                var name = field.get('name');
                if (this.attrAdded(name)){
                    return;
                }
                this.addAttr(name, {
                    field: field,
                    setter: '_attrFieldSetter',
                    getter: '_attrFieldGetter'
                });
            }, this);
        },
        getField: function(name){
            var attrCfg = this._state.data[name];
            if (!attrCfg){
                return null;
            }
            return attrCfg.field || null;
        },
        _attrFieldSetter: function(val, name){
            var field = this.getField(name);

            return NS.AppModel.convert(val, field);
        },
        _attrFieldGetter: function(val, name){
            var field = this.getField(name);
            return NS.AppModel.convert(val, field);
        },
        toJSON: function(toString){
            if (!toString){
                return NS.AppModel.superclass.toJSON.apply(this);
            }

            var ret = {}, val, name, type, langName,
                LANGS = Brick.env.languages, lng, i, lngValCur;

            this.structure.fieldList.each(function(field){
                name = field.get('name');
                if (!this.attrAdded(name)){
                    return;
                }
                val = this.get(name);
                if (field.get('type') === 'multilang'){
                    lngValCur = '';
                    for (i = 0; i < LANGS.length; i++){
                        lng = LANGS[i];
                        langName = NS.AppModel.langFieldName(name, lng);
                        ret[langName] = val[lng] || '';
                        if (lng === Brick.env.language){
                            lngValCur = ret[langName];
                        }
                    }
                    if (lngValCur === '' && LANGS.length > 1){
                        for (i = 0; i < LANGS.length; i++){
                            lng = LANGS[i];
                            if (lng === Brick.env.language){
                                continue;
                            }
                            if (val[lng] && val[lng] !== ''){
                                lngValCur = val[lng];
                                break;
                            }
                        }
                    }
                    ret[name] = lngValCur;
                } else {
                    ret[name] = val;
                }
            }, this);

            return ret;
        }
    }, {
        ATTRS: {}
    });
    NS.AppModel.langFieldName = function(name, lang){
        return name + '_' + lang;
    }
    NS.AppModel.convert = function(val, field){
        if (!field){
            return val
        }

        switch (field.get('type')) {
            case 'string':
                return Y.Lang.isString(val) ? val : '';
            case 'int':
                return (val | 0);
        }
        return val;
    };

    var AppModelList = function(){
        AppModelList.superclass.constructor.apply(this, arguments);
    };
    NS.AppModelList = Y.extend(AppModelList, NS.AppItemList, {
        appInstance: null,
        appItem: NS.AppModel,
        init: function(config){
            config || (config = {});
            if (config.appInstance){
                this.appInstance = config.appInstance;
            }
            AppModelList.superclass.init.apply(this, arguments);
        },
        _createAppItemInstance: function(data){
            data = data || {};
            if (this.appInstance){
                data.appInstance = this.appInstance;
            }
            return new (this.appItem)(data);
        }
    }, {
        NAME: 'appModelList',
        ATTRS: {}
    });

};<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redex/LICENSE

export function create(config, logger, context) {

   let that = {};

   logger.debug('config', config);

   for (let name in config.services) {
      let service = config.services[name];
      id (typeof service === 'string') {
         service = {url: service};
      }
      assert(service.url, 'url: ' + name);
      service.name = name;
      service.type = 'url';
      context.stores.service.add(service);
      logger.debug('service', service);
   }

   async function checkServices() {
      for (const [name, service] of context.stores.service.services) {
         await checkService(service);
      }
   }

   async function checkService(service) {
      try {
         let content = await Requests.request({url: service.url, method: 'head', timeout: config.timeout});
         assert(lodash.isEmpty(content), 'empty content'); // HEAD request has empty content
         context.components.tracker.processStatus(service, 'OK');
      } catch (err) {
         if (!err.code && !err.statusCode) {
            logger.warn('checkService', service.name, err);
         }
         context.components.tracker.processStatus(service, 'WARN', err.message);
      }
   }

   const those = {
      async pub() {
         return null;
      },
      async start() {
         assert(config.interval, 'interval');
         assert(!lodash.isEmpty(config.services), 'services');
         logger.info('started', context.stores.service.services.size, config.interval);
         await checkServices();
         that.checkIntervalId = setInterval(checkServices, config.interval);
      },
      async end() {
         if (that.checkIntervalId) {
            clearInterval(that.checkIntervalId);
            delete that.checkIntervalId;
         }
      },
      async scheduledTimeout() {
      },
      async scheduledInterval() {
      }
   };

   return those;
}
<commit_msg>update<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redex/LICENSE

export function create(config, logger, context) {

   let that = {};

   logger.debug('config', config);

   for (let name in config.services) {
      let service = config.services[name];
      if (typeof service === 'string') {
         service = {url: service};
      }
      assert(service.url, 'url: ' + name);
      service.name = name;
      service.type = 'url';
      context.stores.service.add(service);
      logger.debug('service', service);
   }

   async function checkServices() {
      for (const [name, service] of context.stores.service.services) {
         await checkService(service);
      }
   }

   async function checkService(service) {
      try {
         let content = await Requests.request({url: service.url, method: 'head', timeout: config.timeout});
         assert(lodash.isEmpty(content), 'empty content'); // HEAD request has empty content
         context.components.tracker.processStatus(service, 'OK');
      } catch (err) {
         if (!err.code && !err.statusCode) {
            logger.warn('checkService', service.name, err);
         }
         context.components.tracker.processStatus(service, 'WARN', err.message);
      }
   }

   const those = {
      async pub() {
         return null;
      },
      async start() {
         assert(config.interval, 'interval');
         assert(!lodash.isEmpty(config.services), 'services');
         logger.info('started', context.stores.service.services.size, config.interval);
         await checkServices();
         that.checkIntervalId = setInterval(checkServices, config.interval);
      },
      async end() {
         if (that.checkIntervalId) {
            clearInterval(that.checkIntervalId);
            delete that.checkIntervalId;
         }
      },
      async scheduledTimeout() {
      },
      async scheduledInterval() {
      }
   };

   return those;
}
<|endoftext|>


<commit_before>// copied from node_modules\intern\lib\reporters\runner.js
/*

This reporter aims to create JUnit XML files from the results of a Jasmine
test which uses a modified jasmine.junit_reporter.js.

jasmine.junit_reporter.js is modified to attach the results of the tests to
the "jasmine" global and not write to file.

The intern test waits for these results to be ready, and then evals this
result object via webdriver, and attaches these results to the driver instance
itself.

This reporter then takes these results from the driver instance and writes
them to files.

*/
define([
    // requires packages to be set up correctly in your intern config file. e.g.:
    //   packages: [ { name: 'intern', location: './node_modules/intern' } ],
    //   packages: [ { name: 'dojo', location: './node_modules/intern/node_modules/dojo' } ]
    'module',
    'intern/lib/args',
    'intern/lib/util',
    'dojo/node!path',
    'dojo/node!fs',
    './mkdirp'
], function (module, args, util, path, fs, mkdirp) {
    var MID = module.id,
        sessions = {},
        hasErrors = false;

    function FileHelper(dir) {
        this.dir = dir || './reports';
    }

    FileHelper.makeFilename = function (filename, dir, env) {
        // jasmine.junit_reporter.js passes filename with xml extension.
        // We want to preserve that extension, so we remove it to add it
        // again after the wnv details.
        var idx = filename.lastIndexOf(".");
        var extension = null;
        if (idx > -1) {
            extension = filename.substring(idx);
            filename = filename.substring(0, idx);
        }

        var file = filename + "-" + env.platform + "-" + env.browserName + "-" + env.version + (extension ? extension : "");
        return path.join(dir, file);
    };

    FileHelper.saveResult = function (filename, dir, env, content) {
        //console.log(MID, filename, dir);

        try {
            mkdirp.sync(dir);
        } catch (e) {
            if (e.code !== "EEXIST") {
                // already exists is ok, anything else is not
                throw e;
            }
        }

        filename = FileHelper.makeFilename(filename, dir, env);
        //console.log(MID, p);

        fs.writeFileSync(filename, content, {
            encoding: 'utf8',
            flags: 'w+'
        });

        console.log(MID, filename + " written");
    };

    FileHelper.prototype.saveResults = function (session, remotePropertyToSave) {
        remotePropertyToSave = remotePropertyToSave || "xmlResults";
        var results = session.remote[remotePropertyToSave];
        //console.log(MID, results);
        var env = session.remote.environmentType;
        for (sessionid in results) {
            var paths = results[sessionid];
            for (testpath in paths) {
                // testpath will always be blank for our jasmine reporter
                var filenames = paths[testpath];
                for (filename in filenames) {
                    try {
                        var content = filenames[filename];
                        //console.log(MID, content);
                        var contentStr = ("string" === typeof content) ? content : JSON.stringify(content);
                        FileHelper.saveResult(filename, this.dir, env, contentStr);
                    } catch (e) {
                        console.log(MID, filename, this.dir, e);
                    }
                }
            }
        }
    };

    /**
     * README!
     *
     * The mvn site tool that processes the XML doesn't like spaces or dots in
     * the test suites and test case names.
     *
     * So we turn the names from names like:
     *   "Adventures List"
     * to names like:
     *   "WINDOWS.internet_explorer.10.Adventures_List", or
     *   "XP.firefox.3_6_28.Units_Required"
     *
     * Maybe there is a better way of post-processing the XML that comes from
     * "jasmine.JUnitXMLReporter"?
     */
    function fixJUnitXmlForReporting(session) {
        // Very simple regex that 'does enough' in terms of fixing a string for java name compatibility.
        var JAVA_NAME_RE = /\s+|[:;-.]/gi;

        // Capture both the name and the bit before the name, for ease of replacement.
        // Simplistic regex for matching test suite or test case names.
        // e.g. if there is a ">" in the attribute value, it won't work.
        var TESTSUITE_NAME_RE = /(<testsuite[^>]name=")([^"]*)"/gi;
        var TESTCASE_NAME_RE = /(<testcase[^>]classname=")([^"]*)"/gi;

        function javaName(s) {
            return s.replace(JAVA_NAME_RE, "_");
        }

        function processXmlStr(xml) {
            [TESTSUITE_NAME_RE, TESTCASE_NAME_RE].forEach(function(re) {
                xml = xml.replace(re, function(match, $1, $2, offset, original) {
                    // synthesize a Java package name + class name.
                    var newSuiteName = javaName(env.platform) + "." + javaName(env.browserName) + "." + javaName(env.version) + "." + javaName($2);
                    return $1 + newSuiteName + '"';
                });
            });
            return xml;
        }

        var results = session.remote.xmlResults;
        //console.log(MID, results);
        var env = session.remote.environmentType;
        for (sessionid in results) {
            var paths = results[sessionid];
            for (testpath in paths) {
                // testpath will always be blank for our jasmine reporter
                var filenames = paths[testpath];
                for (filename in filenames) {
                    var xml = filenames[filename];
                    filenames[filename] = processXmlStr(xml);
                }
            }
        }
    }

    return {
        '/session/start': function (remote) {
            console.log(MID, '/session/start - ' + remote.sessionId + ' - ' + remote.environmentType);
            sessions[remote.sessionId] = {
                remote: remote
            };
        },

        '/test/fail': function (test) {
            console.error(MID, 'Test ' + test.id + ' FAILED on ' + sessions[test.sessionId].remote.environmentType + ':');
            util.logError(test.error);
        },

        '/error': function (error) {
            util.logError(error);
            hasErrors = true;
        },

        '/suite/end': function (suite) {
            if (suite.name === 'main') {
                if (!sessions[suite.sessionId]) {
                    args.proxyOnly || console.warn('BUG: /suite/end was received for session ' + suite.sessionId + ' without a /session/start');
                    return;
                }

                sessions[suite.sessionId].suite = suite;
            }
        },

        '/session/end': function (remote) {
            var session = sessions[remote.sessionId],
                suite = session.suite;

            // noop
        },

        '/runner/end': function () {
            console.log(MID, '/runner/end');
            var numEnvironments = 0,
                numTests = 0,
                numFailedTests = 0;

            for (var k in sessions) {
                //console.log(MID, k);
                var session = sessions[k];
                ++numEnvironments;
                numTests += session.suite.numTests;
                numFailedTests += session.suite.numFailedTests;

                // Save the JUnit XML as it is used by mvn site
                fixJUnitXmlForReporting(session);
                new FileHelper('./reports/junit').saveResults(session);

                // Save the JSON results, although we don't use them yet.
                new FileHelper('./reports/junit').saveResults(session, "jsonResults");

                //console.log(MID, session.remote.jsonResults);
            }
        }
    };
});
<commit_msg>Fix regex and add try/catch to let node/intern finish if there are errors.<commit_after>// copied from node_modules\intern\lib\reporters\runner.js
/*

This reporter aims to create JUnit XML files from the results of a Jasmine
test which uses a modified jasmine.junit_reporter.js.

jasmine.junit_reporter.js is modified to attach the results of the tests to
the "jasmine" global and not write to file.

The intern test waits for these results to be ready, and then evals this
result object via webdriver, and attaches these results to the driver instance
itself.

This reporter then takes these results from the driver instance and writes
them to files.

*/
define([
    // requires packages to be set up correctly in your intern config file. e.g.:
    //   packages: [ { name: 'intern', location: './node_modules/intern' } ],
    //   packages: [ { name: 'dojo', location: './node_modules/intern/node_modules/dojo' } ]
    'module',
    'intern/lib/args',
    'intern/lib/util',
    'dojo/node!path',
    'dojo/node!fs',
    './mkdirp'
], function (module, args, util, path, fs, mkdirp) {
    var MID = module.id,
        sessions = {},
        hasErrors = false;

    function FileHelper(dir) {
        this.dir = dir || './reports';
    }

    FileHelper.makeFilename = function (filename, dir, env) {
        // jasmine.junit_reporter.js passes filename with xml extension.
        // We want to preserve that extension, so we remove it to add it
        // again after the wnv details.
        var idx = filename.lastIndexOf(".");
        var extension = null;
        if (idx > -1) {
            extension = filename.substring(idx);
            filename = filename.substring(0, idx);
        }

        var file = filename + "-" + env.platform + "-" + env.browserName + "-" + env.version + (extension ? extension : "");
        return path.join(dir, file);
    };

    FileHelper.saveResult = function (filename, dir, env, content) {
        //console.log(MID, filename, dir);

        try {
            mkdirp.sync(dir);
        } catch (e) {
            if (e.code !== "EEXIST") {
                // already exists is ok, anything else is not
                throw e;
            }
        }

        filename = FileHelper.makeFilename(filename, dir, env);
        //console.log(MID, p);

        fs.writeFileSync(filename, content, {
            encoding: 'utf8',
            flags: 'w+'
        });

        console.log(MID, filename + " written");
    };

    FileHelper.prototype.saveResults = function (session, remotePropertyToSave) {
        remotePropertyToSave = remotePropertyToSave || "xmlResults";
        var results = session.remote[remotePropertyToSave];
        //console.log(MID, results);
        var env = session.remote.environmentType;
        for (sessionid in results) {
            var paths = results[sessionid];
            for (testpath in paths) {
                // testpath will always be blank for our jasmine reporter
                var filenames = paths[testpath];
                for (filename in filenames) {
                    try {
                        var content = filenames[filename];
                        //console.log(MID, content);
                        var contentStr = ("string" === typeof content) ? content : JSON.stringify(content);
                        FileHelper.saveResult(filename, this.dir, env, contentStr);
                    } catch (e) {
                        console.log(MID, filename, this.dir, e);
                    }
                }
            }
        }
    };

    /**
     * README!
     *
     * The mvn site tool that processes the XML doesn't like spaces or dots in
     * the test suites and test case names.
     *
     * So we turn the names from names like:
     *   "Adventures List"
     * to names like:
     *   "WINDOWS.internet_explorer.10.Adventures_List", or
     *   "XP.firefox.3_6_28.Units_Required"
     *
     * Maybe there is a better way of post-processing the XML that comes from
     * "jasmine.JUnitXMLReporter"?
     */
    function fixJUnitXmlForReporting(session) {
        // Very simple regex that 'does enough' in terms of fixing a string for java name compatibility.
        var JAVA_NAME_RE = /\s+|[:;.\-]/gi;

        // Capture both the name and the bit before the name, for ease of replacement.
        // Simplistic regex for matching test suite or test case names.
        // e.g. if there is a ">" in the attribute value, it won't work.
        var TESTSUITE_NAME_RE = /(<testsuite[^>]name=")([^"]*)"/gi;
        var TESTCASE_NAME_RE = /(<testcase[^>]classname=")([^"]*)"/gi;

        function javaName(s) {
            return s.replace(JAVA_NAME_RE, "_");
        }

        function processXmlStr(xml) {
            [TESTSUITE_NAME_RE, TESTCASE_NAME_RE].forEach(function(re) {
                xml = xml.replace(re, function(match, $1, $2, offset, original) {
                    // synthesize a Java package name + class name.
                    var newSuiteName = javaName(env.platform) + "." + javaName(env.browserName) + "." + javaName(env.version) + "." + javaName($2);
                    return $1 + newSuiteName + '"';
                });
            });
            return xml;
        }

        var results = session.remote.xmlResults;
        //console.log(MID, results);
        var env = session.remote.environmentType;
        for (sessionid in results) {
            var paths = results[sessionid];
            for (testpath in paths) {
                // testpath will always be blank for our jasmine reporter
                var filenames = paths[testpath];
                for (filename in filenames) {
                    var xml = filenames[filename];
                    filenames[filename] = processXmlStr(xml);
                }
            }
        }
    }

    return {
        '/session/start': function (remote) {
            console.log(MID, '/session/start - ' + remote.sessionId + ' - ' + remote.environmentType);
            sessions[remote.sessionId] = {
                remote: remote
            };
        },

        '/test/fail': function (test) {
            console.error(MID, 'Test ' + test.id + ' FAILED on ' + sessions[test.sessionId].remote.environmentType + ':');
            util.logError(test.error);
        },

        '/error': function (error) {
            util.logError(error);
            hasErrors = true;
        },

        '/suite/end': function (suite) {
            if (suite.name === 'main') {
                if (!sessions[suite.sessionId]) {
                    args.proxyOnly || console.warn('BUG: /suite/end was received for session ' + suite.sessionId + ' without a /session/start');
                    return;
                }

                sessions[suite.sessionId].suite = suite;
            }
        },

        '/session/end': function (remote) {
            var session = sessions[remote.sessionId],
                suite = session.suite;

            // noop
        },

        '/runner/end': function () {
            console.log(MID, '/runner/end', 'enter');
            var numEnvironments = 0,
                numTests = 0,
                numFailedTests = 0;

            try{
                for (var k in sessions) {
                    //console.log(MID, k);
                    var session = sessions[k];
                    ++numEnvironments;
                    numTests += session.suite.numTests;
                    numFailedTests += session.suite.numFailedTests;

                    // Save the JUnit XML as it is used by mvn site
                    fixJUnitXmlForReporting(session);
                    new FileHelper('./reports/junit').saveResults(session);

                    // Save the JSON results, although we don't use them yet.
                    new FileHelper('./reports/junit').saveResults(session, "jsonResults");

                    //console.log(MID, session.remote.jsonResults);
                }
            } catch (e) {
                console.log(MID, e);
            }

            console.log(MID, '/runner/end', 'exit');
        }
    };
});
<|endoftext|>


<commit_before>import * as diagram from "./Diagram";
import "./Interface";

import Device from "./Device";
import {Flow} from "./Flow";
import {Shaft} from "./Shaft";
import Chart from 'chart.js';

diagram.setup();
diagram.on("ready", function () {

    let intake = new Device("intake");
    let compressor = new Device("compressor");
    let burner = new Device("burner");
    let turbine = new Device("gas_turbine");
    let exhaust = new Device("exhaust");
    let load = new Device("generator");

    intake.position = new Point(100, 120);
    compressor.position = new Point(250, 200);
    burner.position = new Point(420, 120);
    turbine.position = new Point(550, 200);
    exhaust.position = new Point(700, 120);
    load.position = new Point(670, 200);

    new Flow(intake.flowOutlets[0], compressor.flowOutlets[0]);
    new Flow(compressor.flowOutlets[1], burner.flowOutlets[0]);
    new Flow(burner.flowOutlets[1], turbine.flowOutlets[0]);
    new Flow(turbine.flowOutlets[1], exhaust.flowOutlets[0]);

    let shaft = new Shaft();
    shaft.addCoupling(compressor.shaftCouplings[0]);
    shaft.addCoupling(turbine.shaftCouplings[0]);
    shaft.addCoupling(load.shaftCouplings[0]);

    shaft.render(compressor);
});

/*
let ctx = document.getElementById("chart");
let myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255,99,132,1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});*/<commit_msg>ready message<commit_after>import * as diagram from "./Diagram";
import "./Interface";

import Device from "./Device";
import {Flow} from "./Flow";
import {Shaft} from "./Shaft";
import Chart from 'chart.js';

diagram.setup();
diagram.on("ready", function () {

    console.log("Hello there, Visualizer is ready :)")

    let intake = new Device("intake");
    let compressor = new Device("compressor");
    let burner = new Device("burner");
    let turbine = new Device("gas_turbine");
    let exhaust = new Device("exhaust");
    let load = new Device("generator");

    intake.position = new Point(100, 120);
    compressor.position = new Point(250, 200);
    burner.position = new Point(420, 120);
    turbine.position = new Point(550, 200);
    exhaust.position = new Point(700, 120);
    load.position = new Point(670, 200);

    new Flow(intake.flowOutlets[0], compressor.flowOutlets[0]);
    new Flow(compressor.flowOutlets[1], burner.flowOutlets[0]);
    new Flow(burner.flowOutlets[1], turbine.flowOutlets[0]);
    new Flow(turbine.flowOutlets[1], exhaust.flowOutlets[0]);

    let shaft = new Shaft();
    shaft.addCoupling(compressor.shaftCouplings[0]);
    shaft.addCoupling(turbine.shaftCouplings[0]);
    shaft.addCoupling(load.shaftCouplings[0]);

    shaft.render(compressor);
});

/*
let ctx = document.getElementById("chart");
let myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255,99,132,1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});*/<|endoftext|>


<commit_before>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
/*global $, Config, sakai, History, opensocial, Widgets */

/**
 * This is a widget that can be placed in other pages and widgets.
 * It shows an Add to contacts dialog.
 * All you have to do is provide a user object that contains:
 *  - first name
 *  - last name
 *  - uuid of the person you wish to add.
 *
 *  You can also set the personal note by using the setPersonalNote() method
 *  and select the type by using the setTypes().
 */
sakai.addtocontacts = function(tuid, showSettings){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    // Help variables
    var me = sakai.data.me;
    var friend = false;
    var callbackWhenDone = false;
    var fadeOutTime = 1000; // The amount of time it takes to fade out the message and hide the layover.
    // CSS selectors
    var addToContacts = "#addtocontacts";
    var addToContactsClass = ".addtocontacts";

    var addToContactsAdd = addToContacts + "_add";
    var addToContactsDialog = addToContacts + "_dialog";
    var addToContactsDone = addToContacts + "_done";
    var addToContactsDoneContainer = addToContacts + "_done_container";

    // Form elements
    var addToContactsForm = addToContacts + "_form";
    var addToContactsFormButtonInvite = addToContactsForm + "_invite";
    var addToContactsFormButtonCancel = addToContactsForm + "_cancel";
    var addToContactsFormPersonalNote = addToContactsForm + "_personalnote";
    var addToContactsFormPersonalNoteTemplate = addToContactsFormPersonalNote + "_template";
    var addToContactsFormType = addToContactsForm + "_type";
    var addToContactsFormTypeTemplate = addToContactsFormType + "_template";
    // Profile info
    var addToContactsInfoProfilePicture = addToContacts + "_profilepicture";
    var addToContactsInfoTypes = addToContacts + "_types";
    var addToContactsInfoDisplayName = addToContactsClass + "_displayname";

    // Error messages
    var addToContactsError = addToContacts + "_error";
    var addToContactsErrorMessage = addToContactsError + "_message";
    var addToContactsErrorRequest = addToContactsError + "_request";
    var addToContactsErrorNoTypeSelected = addToContactsError + "_noTypeSelected";

    var addToContactsResponse = addToContacts + "_response";

    ///////////////////
    // Functionality //
    ///////////////////

    /**
     * Render the templates that are needed for the add contacts widget.
     * It renders the contacts types and the personal note
     */
    var renderTemplates = function(){
        $.TemplateRenderer(addToContactsFormTypeTemplate.replace(/#/gi, ""), sakai.config.Relationships, $(addToContactsInfoTypes));
        var json = {
            me: me
        };
        $.TemplateRenderer(addToContactsFormPersonalNoteTemplate.replace(/#/gi, ""), json, $(addToContactsFormPersonalNote));
    };

    /**
     * This method will fill in the info for the user.
     * @param {Object} user The JSON object containing the user info. This follows the /rest/me format.
     */
    var fillInUserInfo = function(user){
        if (user) {
            $(addToContactsInfoDisplayName).text(sakai.api.User.getProfileBasicElementValue(user, "firstName"));

            // Check for picture
            if (user.picture && $.parseJSON(user.picture).name) {
                $(addToContactsInfoProfilePicture).attr("src", "/~" + user.uuid + "/public/profile/" + $.parseJSON(user.picture).name);
            }
            else {
                $(addToContactsInfoProfilePicture).attr("src", sakai.config.URL.USER_DEFAULT_ICON_URL);
            }
        }
    };

    /**
     * This function looks up and retrieves relationship information from a set of pre-defined relationships
     * @param {String} relationshipName
     */
    var getDefinedRelationship = function(relationshipName){
        for (var i = 0, j = sakai.config.Relationships.contacts.length; i < j; i++) {
            var definedRelationship = sakai.config.Relationships.contacts[i];
            if (definedRelationship.name === relationshipName) {
                return definedRelationship;
            }
        }
        return null;
    }

    /**
     * Does the invitation stuff. Will send a request for an invitation and a message to the user.
     * @param {String} userid
     */
    var doInvite = function(userid){
        var formValues = sakai.api.UI.Forms.form2json($(addToContactsForm));
        var types = formValues[addToContactsFormType.replace(/#/gi, "")];
        $(addToContactsResponse).text("");
        if (types.length) {
            var fromRelationshipsToSend = [];
            var toRelationshipsToSend = [];
            for (var i = 0, j = types.length; i < j; i++) {
                var type = types[i];
                fromRelationshipsToSend.push(type);
                var definedRelationshipToSend = getDefinedRelationship(type);
                if (definedRelationshipToSend && definedRelationshipToSend.inverse) {
                    toRelationshipsToSend.push(definedRelationshipToSend.inverse);
                }
                else {
                    toRelationshipsToSend.push(type);
                }
            }

            var personalnote = formValues[addToContactsFormPersonalNote.replace(/#/gi, '')];

            // send message to other person
            var userstring = sakai.api.User.getDisplayName(me.profile);

            var title = $("#addtocontacts_invitation_title").html().replace(/\$\{user\}/gi, userstring);
            var message = $("#addtocontacts_invitation_body").html().replace(/\$\{user\}/gi, userstring).replace(/\$\{comment\}/gi, personalnote);

            // Do the invite and send a message
            $.ajax({
                url: "/~" + sakai.data.me.user.userid + "/contacts.invite.html",
                type: "POST",
                traditional: true,
                data: {
                    "fromRelationships": fromRelationshipsToSend,
                    "toRelationships": toRelationshipsToSend,
                    "targetUserId": userid
                },
                success: function(data){
                    $(addToContactsDialog).jqmHide();
                    sakai.api.Communication.sendMessage(userid, title, message, "invitation");
                    callbackWhenDone(friend);
                    //reset the form to set original note
                    $(addToContactsForm)[0].reset();
                    sakai.api.Util.notification.show("", $(addToContactsDone).text());
                },
                error: function(xhr, textStatus, thrownError){
                    $(addToContactsResponse).text(sakai.api.Security.saneHTML($(addToContactsErrorRequest).text()));
                }
            });

        }
        else {
            $(addToContactsResponse).text(sakai.api.Security.saneHTML($(addToContactsErrorNoTypeSelected).text()));
        }
    };

    ///////////////////////
    // jqModal functions //
    ///////////////////////

    /**
     * This will load the overlay to add a new contact.
     * This method will fill in all the user info.
     * @param {Object} hash The layover object we get from jqModal
     */
    var loadDialog = function(hash){
        // Show the form
        $(addToContactsDoneContainer).hide();
        $(addToContactsAdd).show();

        hash.w.show();
    };

    ////////////////////
    // Public methods //
    ////////////////////

    /**
     * Set a personal note.
     * @param {string} note The text you wish to display in the note.
     */
    var setPersonalNote = function(note){
        $(addToContactsFormPersonalNote).val(note);
    };

    /////////////////////////
    // Initialise function //
    /////////////////////////

    /**
     * People should call this function if they want to initiate the widget
     * @param {Object} user The userid or the /rest/me info for this user.
     * @param {Function} callback The callback function that will be executed after the request.
     */
    sakai.addtocontacts.initialise = function(user, callback){
        callbackWhenDone = callback;
        // Check if we have a JSON object or a userid String.
        if (!user.preferences) {
            // This is a uuid. Fetch the info from /rest/me
            $.ajax({
                url: "/~" + user + "/public/authprofile.infinity.json",
                success: function(data){

                    friend = $.extend(data, {}, true);
                    friend.uuid = user;

                    // We have the data, render it.
                    fillInUserInfo(friend);
                }
            });
        }
        else {
            friend = user;
            friend.uuid = user.preferences.uuid;
            fillInUserInfo(friend);
        }

        // Render the templates
        renderTemplates();

        // Show the layover
        $(addToContactsDialog).jqmShow();

        // Give the user options to manipulate this widget.
        return {
            "setPersonalNote": setPersonalNote
        };
    };

    /////////////////////
    // Event listeners //
    /////////////////////

    // Bind the invite button
    $(addToContactsFormButtonInvite).bind("click", function(){
        // Invite this person.
        doInvite(friend.uuid);
    });

    // Bind the cancel button
 	$(addToContactsFormButtonCancel).click(function(){
 	    $(addToContactsForm)[0].reset();
 	});

    // Bind the jqModal
    $(addToContactsDialog).jqm({
        modal: true,
        overlay: 20,
        toTop: true,
        onShow: loadDialog
    });
};

sakai.api.Widgets.widgetLoader.informOnLoad("addtocontacts");<commit_msg>SAKIII-1596 Use display name instead of first name in ad to contact notification.<commit_after>/*
 * Licensed to the Sakai Foundation (SF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The SF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
/*global $, Config, sakai, History, opensocial, Widgets */

/**
 * This is a widget that can be placed in other pages and widgets.
 * It shows an Add to contacts dialog.
 * All you have to do is provide a user object that contains:
 *  - first name
 *  - last name
 *  - uuid of the person you wish to add.
 *
 *  You can also set the personal note by using the setPersonalNote() method
 *  and select the type by using the setTypes().
 */
sakai.addtocontacts = function(tuid, showSettings){

    /////////////////////////////
    // Configuration variables //
    /////////////////////////////

    // Help variables
    var me = sakai.data.me;
    var friend = false;
    var callbackWhenDone = false;
    var fadeOutTime = 1000; // The amount of time it takes to fade out the message and hide the layover.
    // CSS selectors
    var addToContacts = "#addtocontacts";
    var addToContactsClass = ".addtocontacts";

    var addToContactsAdd = addToContacts + "_add";
    var addToContactsDialog = addToContacts + "_dialog";
    var addToContactsDone = addToContacts + "_done";
    var addToContactsDoneContainer = addToContacts + "_done_container";

    // Form elements
    var addToContactsForm = addToContacts + "_form";
    var addToContactsFormButtonInvite = addToContactsForm + "_invite";
    var addToContactsFormButtonCancel = addToContactsForm + "_cancel";
    var addToContactsFormPersonalNote = addToContactsForm + "_personalnote";
    var addToContactsFormPersonalNoteTemplate = addToContactsFormPersonalNote + "_template";
    var addToContactsFormType = addToContactsForm + "_type";
    var addToContactsFormTypeTemplate = addToContactsFormType + "_template";
    // Profile info
    var addToContactsInfoProfilePicture = addToContacts + "_profilepicture";
    var addToContactsInfoTypes = addToContacts + "_types";
    var addToContactsInfoDisplayName = addToContactsClass + "_displayname";

    // Error messages
    var addToContactsError = addToContacts + "_error";
    var addToContactsErrorMessage = addToContactsError + "_message";
    var addToContactsErrorRequest = addToContactsError + "_request";
    var addToContactsErrorNoTypeSelected = addToContactsError + "_noTypeSelected";

    var addToContactsResponse = addToContacts + "_response";

    ///////////////////
    // Functionality //
    ///////////////////

    /**
     * Render the templates that are needed for the add contacts widget.
     * It renders the contacts types and the personal note
     */
    var renderTemplates = function(){
        $.TemplateRenderer(addToContactsFormTypeTemplate.replace(/#/gi, ""), sakai.config.Relationships, $(addToContactsInfoTypes));
        var json = {
            me: me
        };
        $.TemplateRenderer(addToContactsFormPersonalNoteTemplate.replace(/#/gi, ""), json, $(addToContactsFormPersonalNote));
    };

    /**
     * This method will fill in the info for the user.
     * @param {Object} user The JSON object containing the user info. This follows the /rest/me format.
     */
    var fillInUserInfo = function(user){
        if (user) {

            $(addToContactsInfoDisplayName).text(sakai.api.User.getDisplayName(user));

            // Check for picture
            if (user.picture && $.parseJSON(user.picture).name) {
                $(addToContactsInfoProfilePicture).attr("src", "/~" + user.uuid + "/public/profile/" + $.parseJSON(user.picture).name);
            }
            else {
                $(addToContactsInfoProfilePicture).attr("src", sakai.config.URL.USER_DEFAULT_ICON_URL);
            }
        }
    };

    /**
     * This function looks up and retrieves relationship information from a set of pre-defined relationships
     * @param {String} relationshipName
     */
    var getDefinedRelationship = function(relationshipName){
        for (var i = 0, j = sakai.config.Relationships.contacts.length; i < j; i++) {
            var definedRelationship = sakai.config.Relationships.contacts[i];
            if (definedRelationship.name === relationshipName) {
                return definedRelationship;
            }
        }
        return null;
    }

    /**
     * Does the invitation stuff. Will send a request for an invitation and a message to the user.
     * @param {String} userid
     */
    var doInvite = function(userid){
        var formValues = sakai.api.UI.Forms.form2json($(addToContactsForm));
        var types = formValues[addToContactsFormType.replace(/#/gi, "")];
        $(addToContactsResponse).text("");
        if (types.length) {
            var fromRelationshipsToSend = [];
            var toRelationshipsToSend = [];
            for (var i = 0, j = types.length; i < j; i++) {
                var type = types[i];
                fromRelationshipsToSend.push(type);
                var definedRelationshipToSend = getDefinedRelationship(type);
                if (definedRelationshipToSend && definedRelationshipToSend.inverse) {
                    toRelationshipsToSend.push(definedRelationshipToSend.inverse);
                }
                else {
                    toRelationshipsToSend.push(type);
                }
            }

            var personalnote = formValues[addToContactsFormPersonalNote.replace(/#/gi, '')];

            // send message to other person
            var userstring = sakai.api.User.getDisplayName(me.profile);

            var title = $("#addtocontacts_invitation_title").html().replace(/\$\{user\}/gi, userstring);
            var message = $("#addtocontacts_invitation_body").html().replace(/\$\{user\}/gi, userstring).replace(/\$\{comment\}/gi, personalnote);

            // Do the invite and send a message
            $.ajax({
                url: "/~" + sakai.data.me.user.userid + "/contacts.invite.html",
                type: "POST",
                traditional: true,
                data: {
                    "fromRelationships": fromRelationshipsToSend,
                    "toRelationships": toRelationshipsToSend,
                    "targetUserId": userid
                },
                success: function(data){
                    $(addToContactsDialog).jqmHide();
                    sakai.api.Communication.sendMessage(userid, title, message, "invitation");
                    callbackWhenDone(friend);
                    //reset the form to set original note
                    $(addToContactsForm)[0].reset();
                    sakai.api.Util.notification.show("", $(addToContactsDone).text());
                },
                error: function(xhr, textStatus, thrownError){
                    $(addToContactsResponse).text(sakai.api.Security.saneHTML($(addToContactsErrorRequest).text()));
                }
            });

        }
        else {
            $(addToContactsResponse).text(sakai.api.Security.saneHTML($(addToContactsErrorNoTypeSelected).text()));
        }
    };

    ///////////////////////
    // jqModal functions //
    ///////////////////////

    /**
     * This will load the overlay to add a new contact.
     * This method will fill in all the user info.
     * @param {Object} hash The layover object we get from jqModal
     */
    var loadDialog = function(hash){
        // Show the form
        $(addToContactsDoneContainer).hide();
        $(addToContactsAdd).show();

        hash.w.show();
    };

    ////////////////////
    // Public methods //
    ////////////////////

    /**
     * Set a personal note.
     * @param {string} note The text you wish to display in the note.
     */
    var setPersonalNote = function(note){
        $(addToContactsFormPersonalNote).val(note);
    };

    /////////////////////////
    // Initialise function //
    /////////////////////////

    /**
     * People should call this function if they want to initiate the widget
     * @param {Object} user The userid or the /rest/me info for this user.
     * @param {Function} callback The callback function that will be executed after the request.
     */
    sakai.addtocontacts.initialise = function(user, callback){
        callbackWhenDone = callback;
        // Check if we have a JSON object or a userid String.
        if (!user.preferences) {
            // This is a uuid. Fetch the info from /rest/me
            $.ajax({
                url: "/~" + user + "/public/authprofile.infinity.json",
                success: function(data){

                    friend = $.extend(data, {}, true);
                    friend.uuid = user;

                    // We have the data, render it.
                    fillInUserInfo(friend);
                }
            });
        }
        else {
            friend = user;
            friend.uuid = user.preferences.uuid;
            fillInUserInfo(friend);
        }

        // Render the templates
        renderTemplates();

        // Show the layover
        $(addToContactsDialog).jqmShow();

        // Give the user options to manipulate this widget.
        return {
            "setPersonalNote": setPersonalNote
        };
    };

    /////////////////////
    // Event listeners //
    /////////////////////

    // Bind the invite button
    $(addToContactsFormButtonInvite).bind("click", function(){
        // Invite this person.
        doInvite(friend.uuid);
    });

    // Bind the cancel button
 	$(addToContactsFormButtonCancel).click(function(){
 	    $(addToContactsForm)[0].reset();
 	});

    // Bind the jqModal
    $(addToContactsDialog).jqm({
        modal: true,
        overlay: 20,
        toTop: true,
        onShow: loadDialog
    });
};

sakai.api.Widgets.widgetLoader.informOnLoad("addtocontacts");<|endoftext|>


<commit_before>var EventEmitter = require('events').EventEmitter;
var util = require('util');

EventSequence = function()
{
  this.eventList_ = [];
  this.sequenceLength_ = 0;
}

util.inherits(EventSequence, EventEmitter);

// expects array of
// {
//   position: { beat: ; sixteenth: ; ticks: }
//   value: anything
// }

EventSequence.prototype.setContent = function(eventList, sequenceLength)
{
  CHECK_TYPE(sequenceLength, SequencingPosition);

  this.eventList_ = eventList;
  this.sequenceLength_ = sequenceLength;
}

EventSequence.prototype.tick = function(position)
{
  var needle = moduloPosition(position, this.sequenceLength_);
  var emitter = this;

  this.eventList_.forEach(function(e)
  {
      if ((e.position.beats_ == needle.beats_)
        &&(e.position.sixteenth_ == needle.sixteenth_)
        &&(e.position.ticks_ == needle.ticks_))
        {
          emitter.emit("tick", e.value);
        }
  });
}

EventSequence.prototype.connect = function(target)
{
  if (target instanceof Function)
  {
    this.on("tick", target);
  }
  else
  {
    this.on("tick", function(noteList)
      {
        console.log(target);
        target.onEvent(noteList);
      });
  }
}
<commit_msg>removed login<commit_after>var EventEmitter = require('events').EventEmitter;
var util = require('util');

EventSequence = function()
{
  this.eventList_ = [];
  this.sequenceLength_ = 0;
}

util.inherits(EventSequence, EventEmitter);

// expects array of
// {
//   position: { beat: ; sixteenth: ; ticks: }
//   value: anything
// }

EventSequence.prototype.setContent = function(eventList, sequenceLength)
{
  CHECK_TYPE(sequenceLength, SequencingPosition);

  this.eventList_ = eventList;
  this.sequenceLength_ = sequenceLength;
}

EventSequence.prototype.tick = function(position)
{
  var needle = moduloPosition(position, this.sequenceLength_);
  var emitter = this;

  this.eventList_.forEach(function(e)
  {
      if ((e.position.beats_ == needle.beats_)
        &&(e.position.sixteenth_ == needle.sixteenth_)
        &&(e.position.ticks_ == needle.ticks_))
        {
          emitter.emit("tick", e.value);
        }
  });
}

EventSequence.prototype.connect = function(target)
{
  if (target instanceof Function)
  {
    this.on("tick", target);
  }
  else
  {
    this.on("tick", function(noteList)
      {
        target.onEvent(noteList);
      });
  }
}
<|endoftext|>


<commit_before>// Simulate config options from your production environment by
// customising the .env file in your project's root folder.
import dotenv from 'dotenv';

try {
	dotenv.load();
} catch (err) {
	// this space intentionally left blank
}

// Require keystone
var keystone = require('keystone');
import componentRoutes from 'routes/component-routes';

// Initialise Keystone with your project's configuration.
// See http://keystonejs.com/guide/config for available options
// and documentation.

keystone.init({

	'name': 'universal-keystone',
	'brand': 'universal-keystone',

	'less': 'public',
	'static': 'public',
	'favicon': 'public/favicon.ico',
	'views': 'templates/views',
	'view engine': 'jade',
	'component routes': componentRoutes,

	'auto update': true,
	'session': true,
	'auth': true,
	'user model': 'User'

});

// Load your project's Models

keystone.import('models');

// Setup common locals for your templates. The following are required for the
// bundled templates and layouts. Any runtime locals (that should be set uniquely
// for each request) should be added to ./routes/middleware.js

keystone.set('locals', {
	_: require('underscore'),
	env: keystone.get('env'),
	utils: keystone.utils,
	editable: keystone.content.editable
});

// Load your project's Routes

keystone.set('routes', require('./routes'));

// Configure the navigation bar in Keystone's Admin UI

keystone.set('nav', {
	'posts': ['posts', 'post-categories'],
	'teams': 'teams',
	'users': 'users'
});

// Start Keystone to connect to your database and initialise the web server

keystone.start();

export default keystone;
<commit_msg>Attempt to appease CircleCI<commit_after>// Simulate config options from your production environment by
// customising the .env file in your project's root folder.
var dotenv = require('dotenv');

try {
	dotenv.load();
} catch (err) {
	// this space intentionally left blank
}

// Require keystone
var keystone = require('keystone');
import componentRoutes from 'routes/component-routes';

// Initialise Keystone with your project's configuration.
// See http://keystonejs.com/guide/config for available options
// and documentation.

keystone.init({

	'name': 'universal-keystone',
	'brand': 'universal-keystone',

	'less': 'public',
	'static': 'public',
	'favicon': 'public/favicon.ico',
	'views': 'templates/views',
	'view engine': 'jade',
	'component routes': componentRoutes,

	'auto update': true,
	'session': true,
	'auth': true,
	'user model': 'User'

});

// Load your project's Models

keystone.import('models');

// Setup common locals for your templates. The following are required for the
// bundled templates and layouts. Any runtime locals (that should be set uniquely
// for each request) should be added to ./routes/middleware.js

keystone.set('locals', {
	_: require('underscore'),
	env: keystone.get('env'),
	utils: keystone.utils,
	editable: keystone.content.editable
});

// Load your project's Routes

keystone.set('routes', require('./routes'));

// Configure the navigation bar in Keystone's Admin UI

keystone.set('nav', {
	'posts': ['posts', 'post-categories'],
	'teams': 'teams',
	'users': 'users'
});

// Start Keystone to connect to your database and initialise the web server

keystone.start();

export default keystone;
<|endoftext|>


<commit_before>import { firebase as config } from '../config'
const { apiKey, authDomain, databaseUrl, storageBucket } = config
import Firebase from 'firebase'

// Initialize Firebase
Firebase.initializeApp({ apiKey, authDomain, databaseUrl, storageBucket })

export default Firebase
<commit_msg>Fixes firebase variable name (#10)<commit_after>import { firebase as config } from '../config'
const { apiKey, authDomain, databaseURL, storageBucket } = config
import Firebase from 'firebase'

// Initialize Firebase
Firebase.initializeApp({ apiKey, authDomain, databaseURL, storageBucket })

export default Firebase
<|endoftext|>