<commit_before>angular.module('cesium.market.settings.services', ['cesium.services', 'cesium.es.http.services'])
.config(function(PluginServiceProvider, csConfig) {
    'ngInject';

    var enable = csConfig.plugins && csConfig.plugins.es;
    if (enable) {
      // Will force to load this service
      PluginServiceProvider.registerEagerLoadingService('mkSettings');
    }

  })

.factory('mkSettings', function($rootScope, $q, $timeout, $ionicHistory, Api, csHttp, esHttp,
                            csConfig, csSettings, esSettings, csCurrency) {
  'ngInject';

  var
    SETTINGS_SAVE_SPEC = {
      includes: ['geoDistance', 'compactMode', 'maxAdAge'],
      excludes: ['enable', 'homeMessage', 'defaultTags', 'defaultAdminPubkeys', 'record', 'defaultSearch'],
      defaultSearch: {},
      cesiumApi: {}
    },
    defaultSettings = angular.merge({
        plugins: {
          market: {
            enable: true,
            compactMode: false,
            cesiumApi: {
              enable: true,
              baseUrl: "https://g1.duniter.fr/api"
            },
            maxAdAge: 60 * 60 * 24 * 365 // Max age of a Ad (in seconds) (=1 year)
          },
          converse: {
            jid : "anonymous.duniter.org",
            bosh_service_url: "https://chat.duniter.org/http-bind/",
            auto_join_rooms : [
              "gchange@muc.duniter.org"
            ]
          }
        }
      },
      // Market plugin
      {plugins: {market: csConfig.plugins && csConfig.plugins.market || {}}},
      // Converse plugin
      {plugins: {converse: csConfig.plugins && csConfig.plugins.converse || {}}}
    ),
    that = this,
    readyDeferred = $q.defer(),
    listeners,
    ignoreSettingsChanged = false
  ;

  // Define settings to save remotely
  esSettings.setPluginSaveSpecs('market', SETTINGS_SAVE_SPEC);

  that.raw = {
    currencies: undefined
  };

  that.isEnable = function(data) {
    data = data || csSettings.data;
    return data.plugins && data.plugins.es && data.plugins.es.enable &&
           data.plugins.market && data.plugins.market.enable;
  };

  that.currencies = function() {
    if (readyDeferred) {
      return readyDeferred.promise.then(function() {
        return that.raw.currencies;
      });
    }
    return $q.when(that.raw.currencies);
  };

  /**
   * Max age of a Ad (in seconds)
   * @returns {number|*}
   */
  that.getMaxAdAge = function() {
    return csSettings.data.plugins.market && csSettings.data.plugins.market.maxAdAge ||
      defaultSettings.plugins.market.maxAdAge;
  };

  /**
   * Max age of a Ad (in seconds)
   * @returns {number|*}
   */
  that.getMinAdTime = function() {
    return (Date.now() / 1000) - that.getMaxAdAge();
  };

  function _initCurrencies(data, deferred) {
    deferred = deferred || $q.defer();
    if (that.enable) {
      that.raw.currencies = data.plugins.market.currencies;
      if (!that.raw.currencies && data.plugins.market.defaultCurrency) {
        that.raw.currencies = [data.plugins.market.defaultCurrency];
        console.debug('[market] [settings] Currencies: ', that.raw.currencies);
        if (deferred) deferred.resolve(that.raw.currencies);
      }
      else {
        return csCurrency.get()
            .then(function(currency) {
              that.raw.currencies = [currency.name];
              console.debug('[market] [settings] Currencies: ', that.raw.currencies);
              if (deferred) deferred.resolve(that.raw.currencies);
            })
            .catch(function(err) {
              if (deferred) {
                deferred.reject(err);
              }
              else {
                throw err;
              }
            });
      }

    }
    else {
      that.raw.currencies = [];
      if (deferred) deferred.resolve(that.raw.currencies);
    }
    return deferred.promise;
  }

  function onSettingsReset(data, deferred) {
    deferred = deferred || $q.defer();
    data.plugins = data.plugins || {};

    // reset plugin settings, then restore defaults
    data.plugins.market = {};
    angular.merge(data, defaultSettings);

    deferred.resolve(data);
    return deferred.promise;
  }

  // Listen for settings changed
  function onSettingsChanged(data) {

    // Workaround (version < 1.2.6) : fix older settings
    var isVersionPrevious_1_2_6 = csHttp.version.compare(data.version, '1.2.6') <= 0;
    if (isVersionPrevious_1_2_6 && data.plugins && data.plugins.market) {
      console.info('[market] [settings] Detected version previous <= 1.2.6 - Fix older settings...');
      delete data.plugins.es.market;
      var geoDistance = data.plugins.market.geoDistance;
      delete data.plugins.market.geoDistance;
      data.plugins.market.defaultSearch = data.plugins.market.defaultSearch || {};
      data.plugins.market.defaultSearch.geoDistance = data.plugins.market.defaultSearch.geoDistance || geoDistance;
      data.plugins.market.maxAdAge = defaultSettings.plugins.market.maxAdAge;
    }

    data.plugins.es.document = data.plugins.es.document || {};
    data.plugins.es.document.index = 'user,page,group,market';
    data.plugins.es.document.type = 'profile,record,comment';

    // Init currencies
    _initCurrencies(data);

  }

  function removeListeners() {
    _.forEach(listeners, function(remove){
      remove();
    });
    listeners = [];
  }

  function addListeners() {
    // Listening some events
    listeners = [
      csSettings.api.data.on.reset($rootScope, onSettingsReset, this),
      csSettings.api.data.on.changed($rootScope, onSettingsChanged, this)
    ];
  }

  that.ready = function() {
    if (!readyDeferred) return $q.when();
    return readyDeferred.promise;
  };

  esSettings.api.state.on.changed($rootScope, function(enable) {
    enable = enable && that.isEnable();
    if (enable === that.enable) return; // nothing changed

    that.enable = enable;
    if (enable) {
      console.debug('[market] [settings] Enable');
      addListeners();
    }
    else {
      console.debug('[market] [settings] Disable');
      removeListeners();
    }
    // Init currencies
    onSettingsChanged(csSettings.data);
    if (readyDeferred) {
      readyDeferred.resolve();
      readyDeferred = null;
    }
  });

  return that;
});
<commit_msg>[fix] Add default settings geoDistance<commit_after>angular.module('cesium.market.settings.services', ['cesium.services', 'cesium.es.http.services'])
.config(function(PluginServiceProvider, csConfig) {
    'ngInject';

    var enable = csConfig.plugins && csConfig.plugins.es;
    if (enable) {
      // Will force to load this service
      PluginServiceProvider.registerEagerLoadingService('mkSettings');
    }

  })

.factory('mkSettings', function($rootScope, $q, $timeout, $ionicHistory, Api, csHttp, esHttp,
                            csConfig, csSettings, esSettings, csCurrency) {
  'ngInject';

  var
    SETTINGS_SAVE_SPEC = {
      includes: ['geoDistance', 'compactMode', 'maxAdAge'],
      excludes: ['enable', 'homeMessage', 'defaultTags', 'defaultAdminPubkeys', 'record', 'defaultSearch'],
      defaultSearch: {},
      cesiumApi: {}
    },
    defaultSettings = angular.merge({
        plugins: {
          market: {
            enable: true,
            compactMode: false,
            cesiumApi: {
              enable: true,
              baseUrl: "https://g1.duniter.fr/api"
            },
            defaultSearch: {
              geoDistance: 50
            },
            maxAdAge: 60 * 60 * 24 * 365 // Max age of a Ad (in seconds) (=1 year)
          },
          converse: {
            jid : "anonymous.duniter.org",
            bosh_service_url: "https://chat.duniter.org/http-bind/",
            auto_join_rooms : [
              "gchange@muc.duniter.org"
            ]
          }
        }
      },
      // Market plugin
      {plugins: {market: csConfig.plugins && csConfig.plugins.market || {}}},
      // Converse plugin
      {plugins: {converse: csConfig.plugins && csConfig.plugins.converse || {}}}
    ),
    that = this,
    readyDeferred = $q.defer(),
    listeners,
    ignoreSettingsChanged = false
  ;

  // Define settings to save remotely
  esSettings.setPluginSaveSpecs('market', SETTINGS_SAVE_SPEC);

  that.raw = {
    currencies: undefined
  };

  that.isEnable = function(data) {
    data = data || csSettings.data;
    return data.plugins && data.plugins.es && data.plugins.es.enable &&
           data.plugins.market && data.plugins.market.enable;
  };

  that.currencies = function() {
    if (readyDeferred) {
      return readyDeferred.promise.then(function() {
        return that.raw.currencies;
      });
    }
    return $q.when(that.raw.currencies);
  };

  /**
   * Max age of a Ad (in seconds)
   * @returns {number|*}
   */
  that.getMaxAdAge = function() {
    return csSettings.data.plugins.market && csSettings.data.plugins.market.maxAdAge ||
      defaultSettings.plugins.market.maxAdAge;
  };

  /**
   * Max age of a Ad (in seconds)
   * @returns {number|*}
   */
  that.getMinAdTime = function() {
    return (Date.now() / 1000) - that.getMaxAdAge();
  };

  function _initCurrencies(data, deferred) {
    deferred = deferred || $q.defer();
    if (that.enable) {
      that.raw.currencies = data.plugins.market.currencies;
      if (!that.raw.currencies && data.plugins.market.defaultCurrency) {
        that.raw.currencies = [data.plugins.market.defaultCurrency];
        console.debug('[market] [settings] Currencies: ', that.raw.currencies);
        if (deferred) deferred.resolve(that.raw.currencies);
      }
      else {
        return csCurrency.get()
            .then(function(currency) {
              that.raw.currencies = [currency.name];
              console.debug('[market] [settings] Currencies: ', that.raw.currencies);
              if (deferred) deferred.resolve(that.raw.currencies);
            })
            .catch(function(err) {
              if (deferred) {
                deferred.reject(err);
              }
              else {
                throw err;
              }
            });
      }

    }
    else {
      that.raw.currencies = [];
      if (deferred) deferred.resolve(that.raw.currencies);
    }
    return deferred.promise;
  }

  function onSettingsReset(data, deferred) {
    deferred = deferred || $q.defer();
    data.plugins = data.plugins || {};

    // reset plugin settings, then restore defaults
    data.plugins.market = {};
    angular.merge(data, defaultSettings);

    deferred.resolve(data);
    return deferred.promise;
  }

  // Listen for settings changed
  function onSettingsChanged(data) {

    // Workaround (version < 1.2.6) : fix older settings
    var isVersionPrevious_1_2_6 = csHttp.version.compare(data.version, '1.2.6') <= 0;
    if (isVersionPrevious_1_2_6 && data.plugins && data.plugins.market) {
      console.info('[market] [settings] Detected version previous <= 1.2.6 - Fix older settings...');
      delete data.plugins.es.market;
      var geoDistance = data.plugins.market.geoDistance;
      delete data.plugins.market.geoDistance;
      data.plugins.market.defaultSearch = data.plugins.market.defaultSearch || {};
      data.plugins.market.defaultSearch.geoDistance = data.plugins.market.defaultSearch.geoDistance || geoDistance;
      data.plugins.market.maxAdAge = defaultSettings.plugins.market.maxAdAge;
    }

    data.plugins.es.document = data.plugins.es.document || {};
    data.plugins.es.document.index = 'user,page,group,market';
    data.plugins.es.document.type = 'profile,record,comment';

    // Init currencies
    _initCurrencies(data);

  }

  function removeListeners() {
    _.forEach(listeners, function(remove){
      remove();
    });
    listeners = [];
  }

  function addListeners() {
    // Listening some events
    listeners = [
      csSettings.api.data.on.reset($rootScope, onSettingsReset, this),
      csSettings.api.data.on.changed($rootScope, onSettingsChanged, this)
    ];
  }

  that.ready = function() {
    if (!readyDeferred) return $q.when();
    return readyDeferred.promise;
  };

  esSettings.api.state.on.changed($rootScope, function(enable) {
    enable = enable && that.isEnable();
    if (enable === that.enable) return; // nothing changed

    that.enable = enable;
    if (enable) {
      console.debug('[market] [settings] Enable');
      addListeners();
    }
    else {
      console.debug('[market] [settings] Disable');
      removeListeners();
    }
    // Init currencies
    onSettingsChanged(csSettings.data);
    if (readyDeferred) {
      readyDeferred.resolve();
      readyDeferred = null;
    }
  });

  return that;
});
<|endoftext|>


<commit_before>/*
 * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 *
 * Licensed 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.
 */

Ensembl.LayoutManager = new Base();

Ensembl.LayoutManager.extend({
  constructor: null,

  /**
   * Creates events on elements outside of the domain of panels
   */
  initialize: function () {
    this.id = 'LayoutManager';

    Ensembl.EventManager.register('reloadPage',    this, this.reloadPage);
    Ensembl.EventManager.register('validateForms', this, this.validateForms);
    Ensembl.EventManager.register('makeZMenu',     this, this.makeZMenu);
    Ensembl.EventManager.register('hashChange',    this, this.hashChange);
    Ensembl.EventManager.register('toggleContent', this, this.toggleContent);
    Ensembl.EventManager.register('changeWidth',   this, this.changeWidth);

    $('#page_nav .tool_buttons > p').show();

    $('#header a:not(#tabs a)').addClass('constant');

    if (window.location.hash.match(Ensembl.locationMatch)) {
      $('.ajax_load').val(function (i, val) {
        return Ensembl.urlFromHash(val);
      });

      this.hashChange(Ensembl.urlFromHash(window.location.href, true));
    }

    $(document).on('click', '.modal_link', function () {
      if (Ensembl.EventManager.trigger('modalOpen', this)) {
        return false;
      }
    }).on('click', '.popup', function () {
      if (window.name.match(/^popup_/)) {
        return true;
      }

      window.open(this.href, 'popup_' + window.name, 'width=950,height=500,resizable,scrollbars');
      return false;
    }).on('click', 'a[rel="external"]', function () {
      this.target = '_blank';
    }).on('click', 'a.update_panel', function () {
      var panelId = this.rel;
      var url     = Ensembl.updateURL({ update_panel: 1 }, this.href);

      if (Ensembl.PanelManager.panels[panelId] && this.href.split('?')[0].match(Ensembl.PanelManager.panels[panelId].params.updateURL.split('?')[0])) {
        var params = {};

        if (!$('.update_url', this).add($(this).siblings('.update_url')).each(function () { params[this.name] = this.value; }).length) {
          params = undefined;
        }

        Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, null, { updateURL: this.href }, params);
      } else {
        $.ajax({
          url: url,
          success: function () {
            Ensembl.EventManager.triggerSpecific('updatePanel', panelId);
          }
        });
      }

      return false;
    }).on('submit', 'form.update_panel', function (e) {
      var params    = $(this).serializeArray();
      var urlParams = {};
      var panelId, url, el;

      for (var i in params) {
        switch (params[i].name) {
          case 'panel_id': panelId = params[i].value; break;
          case 'url'     : url     = params[i].value; break;
          case 'element' : el      = params[i].value; break;
          default        : urlParams[params[i].name] = params[i].value; break;
        }
      }

      url = Ensembl.updateURL($.extend({ update_panel: 1 }, urlParams), url);

      Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, el, null, urlParams);

      return false;
    }).on({
      'keyup.ensembl': function (event) {
        if (event.keyCode === 27) {
          Ensembl.EventManager.trigger('modalClose', true); // Close modal window if the escape key is pressed
        }
      },
      'mouseup.ensembl': function (e) {
        // only fired on left click
        if (!e.which || e.which === 1) {
          Ensembl.EventManager.trigger('mouseUp', e);
        }
      }
    });

    $('.modal_link').show();

    this.validateForms(document);

    $(window).on({
      'resize.ensembl': function (e) {
        if (window.name.match(/^popup_/)) {
          return false;
        }

        // jquery ui resizable events cause window.resize to fire (all events bubble to window)
        // if target has no tagName it is window or document. Don't resize unless this is the case
        if (!e.target.tagName) {
          var width = Ensembl.width;

          if (Ensembl.dynamicWidth) {
            Ensembl.setWidth(undefined, true);
          }

          Ensembl.cookie.set('WINDOW_WIDTH', $(window).width());
          Ensembl.EventManager.trigger('windowResize');

          if (Ensembl.dynamicWidth && Ensembl.width !== width) {
            Ensembl.LayoutManager.changeWidth();
            Ensembl.EventManager.trigger('imageResize');
          }
        }
      },
      'hashchange.ensembl': $.proxy(this.popState, this),
      'popstate.ensembl'  : $.proxy(this.popState, this)
    });

    if (!this.showCookieMessage()) {
      this.handleMirrorRedirect();
    }
  },

  reloadPage: function (args, url) {
    if (typeof args === 'string') {
      Ensembl.EventManager.triggerSpecific('updatePanel', args);
    } else if (typeof args === 'object') {
      for (var i in args) {
        Ensembl.EventManager.triggerSpecific('updatePanel', i);
      }
    } else {
      return Ensembl.redirect(url);
    }

    $('.session_messages').hide();
  },

  validateForms: function (context) {
    $('form._check', context).validate().on('submit', function () {
      var form = $(this);

      if (form.parents('#modal_panel').length) {
        var panels = form.parents('.js_panel').map(function () { return this.id; }).toArray();
        var rtn;

        while (panels.length && typeof rtn === 'undefined') {
          rtn = Ensembl.EventManager.triggerSpecific('modalFormSubmit', panels.shift(), form);
        }

        return rtn;
      }
    });
  },

  makeZMenu: function (id, params) {
    if (!$('#' + id).length) {
      Ensembl.Panel.ZMenu.template.clone().attr('id', id).appendTo('body');
    }

    Ensembl.EventManager.trigger('addPanel', id, 'ZMenu', undefined, undefined, params, 'showExistingZMenu');
  },

  popState: function () {
    if (
      Ensembl.historyReady && // stops popState executing on initial page load in Chrome. This value is set to true in Ensembl.updateLocation
      // there is an r param in the hash/search EXCEPT WHEN the browser supports history API, and there is a hash which doesn't have an r param (ajax added content)
      ((window.location[Ensembl.locationURL].match(Ensembl.locationMatch) && !(Ensembl.locationURL === 'search' && window.location.hash && !window.location.hash.match(Ensembl.locationMatch))) ||
      (!window.location.hash && Ensembl.hash.match(Ensembl.locationMatch))) // there is no location.hash, but Ensembl.hash (previous hash value) had an r param (going back from no hash url to hash url)
    ) {
      Ensembl.setCoreParams();
      Ensembl.EventManager.trigger('hashChange', Ensembl.urlFromHash(window.location.href, true));
    }
  },

  hashChange: function (r) {
    if (!r) {
      return;
    }

    r = decodeURIComponent(r);

    var text = r.split(/\W/);
        text = text[0] + ': ' + Ensembl.thousandify(text[1]) + '-' + Ensembl.thousandify(text[2]);

    $('a:not(.constant)').attr('href', function () {
      var r;

      if (this.title === 'UCSC') {
        this.href = this.href.replace(/(&?position=)[^&]+(.?)/, '$1chr' + Ensembl.urlFromHash(this.href, true) + '$2');
      } else if (this.title === 'NCBI') {
        r = Ensembl.urlFromHash(this.href, true).split(/[:\-]/);
        this.href = this.href.replace(/(&?CHR=).+&BEG=.+&END=[^&]+(.?)/, '$1' + r[0] + '&BEG=' + r[1] + '&END=' + r[2] + '$2');
      } else {
        return Ensembl.urlFromHash(this.href);
      }
    });

    $('input[name=r]', 'form:not(#core_params)').val(r);

    $('h1.summary-heading').html(function (i, html) {
      return html.replace(/^(Chromosome ).+/, '$1' + text);
    });

    document.title = document.title.replace(/(Chromosome ).+/, '$1' + text);
  },

  toggleContent: function (rel, delay) {
    if (rel) {
      window.setTimeout(function() {
        $('a.toggle[rel="' + rel + '"]').toggleClass('open closed');
      }, delay && $('a.toggle[rel="' + rel + '"]').hasClass('open') ? delay : 0);
    }
  },

  changeWidth: function () {
    var modal = $('#modal_panel');
    $('.navbar, div.info, div.hint, div.warning, div.error').not('.fixed_width').not(function () { return modal.find(this).length; }).width(Ensembl.width);
    modal = null;
  },

  handleMirrorRedirect: function() {

    var redirectCode  = unescape(Ensembl.cookie.get('redirect_mirror'));
    var redirectURI   = unescape(Ensembl.cookie.get('redirect_mirror_url'));

    Ensembl.cookie.set('redirect_mirror_url');

    var noRedirectURI = function(uri) {
      uri = uri.replace(/(\&|\;)?redirect=[^\&\;]+/, '').replace(/(\&|\;)?debugip=[^\&\;]+/, '').replace(/\?[\;\&]+/, '?').replace(/\?$/, '');
      uri = uri + (uri.match(/\?/) ? ';redirect=no' : '?redirect=no');
      return uri;
    };

    if (redirectCode && redirectCode !== 'no') {
      redirectCode      = redirectCode.split(/\|/);
      if (redirectCode.length >= 2) {
        var currentURI    = noRedirectURI(window.location.href);
        var mirrorName    = redirectCode.shift();
        var remainingTime = parseInt(redirectCode.shift());
        var mirrorURI     = (redirectURI ? noRedirectURI($('').attr('href', redirectURI).prop('href')) : currentURI).replace(window.location.host, mirrorName);
        var messageDiv    = $([
          '
',
          '
You are being redirected to ', mirrorName, ' in ', remainingTime, ' seconds. Click here if you don\'t wish to be redirected.
',
          '
'
        ].join('')).appendTo($('body').prepend($('

').slideDown())).slideDown().find('a._redirect_no').on('click', function (e) {
          e.preventDefault();
          Ensembl.cookie.set('redirect_mirror', 'no');
          clearInterval(messageDiv.data('countdown'));
          window.location.replace(messageDiv.data('currentURI'));
        }).end().data({
          remainingTime : remainingTime,
          mirrorURI     : mirrorURI,
          currentURI    : currentURI,
          countdown     : setInterval(function() {
            var time  = messageDiv.data('remainingTime') - 1;
            messageDiv.data('remainingTime', time).find('._redirect_countdown').html(time > 0 ? time > 1 ? 'in ' + time + ' seconds' : 'in 1 second' : 'now');
            if (time <= 0) {
              clearInterval(messageDiv.data('countdown'));
              window.location.href = messageDiv.data('mirrorURI');
            }
          }, 1000)
        });
      }
    }
  },

  showCookieMessage: function() {
    var manager = this;
    var cookiesAccepted = Ensembl.cookie.get('cookies_ok');

    if (!cookiesAccepted) {
      $(['
',
        '
We use cookies to enhance the usability of our website. If you continue, we\'ll assume that you are happy to receive all cookies.<button>Don\'t show this again</button>
',
        '
Further details about our privacy and cookie policy can be found here
',
        '
'
      ].join(''))
        .prependTo(document.body).slideDown().find('button').on('click', function (e) {
          Ensembl.cookie.set('cookies_ok', 'yes');
          $(this).parents('div').first().slideUp();
          manager.handleMirrorRedirect();
      });
      return true;
    }

    return false;
  }
});
<commit_msg>add function to show message when viewing main site on mobile phone<commit_after>/*
 * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
 *
 * Licensed 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.
 */

Ensembl.LayoutManager = new Base();

Ensembl.LayoutManager.extend({
  constructor: null,

  /**
   * Creates events on elements outside of the domain of panels
   */
  initialize: function () {
    this.id = 'LayoutManager';

    Ensembl.EventManager.register('reloadPage',    this, this.reloadPage);
    Ensembl.EventManager.register('validateForms', this, this.validateForms);
    Ensembl.EventManager.register('makeZMenu',     this, this.makeZMenu);
    Ensembl.EventManager.register('hashChange',    this, this.hashChange);
    Ensembl.EventManager.register('toggleContent', this, this.toggleContent);
    Ensembl.EventManager.register('changeWidth',   this, this.changeWidth);

    $('#page_nav .tool_buttons > p').show();

    $('#header a:not(#tabs a)').addClass('constant');

    if (window.location.hash.match(Ensembl.locationMatch)) {
      $('.ajax_load').val(function (i, val) {
        return Ensembl.urlFromHash(val);
      });

      this.hashChange(Ensembl.urlFromHash(window.location.href, true));
    }

    $(document).on('click', '.modal_link', function () {
      if (Ensembl.EventManager.trigger('modalOpen', this)) {
        return false;
      }
    }).on('click', '.popup', function () {
      if (window.name.match(/^popup_/)) {
        return true;
      }

      window.open(this.href, 'popup_' + window.name, 'width=950,height=500,resizable,scrollbars');
      return false;
    }).on('click', 'a[rel="external"]', function () {
      this.target = '_blank';
    }).on('click', 'a.update_panel', function () {
      var panelId = this.rel;
      var url     = Ensembl.updateURL({ update_panel: 1 }, this.href);

      if (Ensembl.PanelManager.panels[panelId] && this.href.split('?')[0].match(Ensembl.PanelManager.panels[panelId].params.updateURL.split('?')[0])) {
        var params = {};

        if (!$('.update_url', this).add($(this).siblings('.update_url')).each(function () { params[this.name] = this.value; }).length) {
          params = undefined;
        }

        Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, null, { updateURL: this.href }, params);
      } else {
        $.ajax({
          url: url,
          success: function () {
            Ensembl.EventManager.triggerSpecific('updatePanel', panelId);
          }
        });
      }

      return false;
    }).on('submit', 'form.update_panel', function (e) {
      var params    = $(this).serializeArray();
      var urlParams = {};
      var panelId, url, el;

      for (var i in params) {
        switch (params[i].name) {
          case 'panel_id': panelId = params[i].value; break;
          case 'url'     : url     = params[i].value; break;
          case 'element' : el      = params[i].value; break;
          default        : urlParams[params[i].name] = params[i].value; break;
        }
      }

      url = Ensembl.updateURL($.extend({ update_panel: 1 }, urlParams), url);

      Ensembl.EventManager.triggerSpecific('updatePanel', panelId, url, el, null, urlParams);

      return false;
    }).on({
      'keyup.ensembl': function (event) {
        if (event.keyCode === 27) {
          Ensembl.EventManager.trigger('modalClose', true); // Close modal window if the escape key is pressed
        }
      },
      'mouseup.ensembl': function (e) {
        // only fired on left click
        if (!e.which || e.which === 1) {
          Ensembl.EventManager.trigger('mouseUp', e);
        }
      }
    });

    $('.modal_link').show();

    this.validateForms(document);

    $(window).on({
      'resize.ensembl': function (e) {
        if (window.name.match(/^popup_/)) {
          return false;
        }

        // jquery ui resizable events cause window.resize to fire (all events bubble to window)
        // if target has no tagName it is window or document. Don't resize unless this is the case
        if (!e.target.tagName) {
          var width = Ensembl.width;

          if (Ensembl.dynamicWidth) {
            Ensembl.setWidth(undefined, true);
          }

          Ensembl.cookie.set('WINDOW_WIDTH', $(window).width());
          Ensembl.EventManager.trigger('windowResize');

          if (Ensembl.dynamicWidth && Ensembl.width !== width) {
            Ensembl.LayoutManager.changeWidth();
            Ensembl.EventManager.trigger('imageResize');
          }
        }
      },
      'hashchange.ensembl': $.proxy(this.popState, this),
      'popstate.ensembl'  : $.proxy(this.popState, this)
    });

    this.showMobileMessage();
    if (!this.showCookieMessage()) {
      this.handleMirrorRedirect();
    }
  },

  reloadPage: function (args, url) {
    if (typeof args === 'string') {
      Ensembl.EventManager.triggerSpecific('updatePanel', args);
    } else if (typeof args === 'object') {
      for (var i in args) {
        Ensembl.EventManager.triggerSpecific('updatePanel', i);
      }
    } else {
      return Ensembl.redirect(url);
    }

    $('.session_messages').hide();
  },

  validateForms: function (context) {
    $('form._check', context).validate().on('submit', function () {
      var form = $(this);

      if (form.parents('#modal_panel').length) {
        var panels = form.parents('.js_panel').map(function () { return this.id; }).toArray();
        var rtn;

        while (panels.length && typeof rtn === 'undefined') {
          rtn = Ensembl.EventManager.triggerSpecific('modalFormSubmit', panels.shift(), form);
        }

        return rtn;
      }
    });
  },

  makeZMenu: function (id, params) {
    if (!$('#' + id).length) {
      Ensembl.Panel.ZMenu.template.clone().attr('id', id).appendTo('body');
    }

    Ensembl.EventManager.trigger('addPanel', id, 'ZMenu', undefined, undefined, params, 'showExistingZMenu');
  },

  popState: function () {
    if (
      Ensembl.historyReady && // stops popState executing on initial page load in Chrome. This value is set to true in Ensembl.updateLocation
      // there is an r param in the hash/search EXCEPT WHEN the browser supports history API, and there is a hash which doesn't have an r param (ajax added content)
      ((window.location[Ensembl.locationURL].match(Ensembl.locationMatch) && !(Ensembl.locationURL === 'search' && window.location.hash && !window.location.hash.match(Ensembl.locationMatch))) ||
      (!window.location.hash && Ensembl.hash.match(Ensembl.locationMatch))) // there is no location.hash, but Ensembl.hash (previous hash value) had an r param (going back from no hash url to hash url)
    ) {
      Ensembl.setCoreParams();
      Ensembl.EventManager.trigger('hashChange', Ensembl.urlFromHash(window.location.href, true));
    }
  },

  hashChange: function (r) {
    if (!r) {
      return;
    }

    r = decodeURIComponent(r);

    var text = r.split(/\W/);
        text = text[0] + ': ' + Ensembl.thousandify(text[1]) + '-' + Ensembl.thousandify(text[2]);

    $('a:not(.constant)').attr('href', function () {
      var r;

      if (this.title === 'UCSC') {
        this.href = this.href.replace(/(&?position=)[^&]+(.?)/, '$1chr' + Ensembl.urlFromHash(this.href, true) + '$2');
      } else if (this.title === 'NCBI') {
        r = Ensembl.urlFromHash(this.href, true).split(/[:\-]/);
        this.href = this.href.replace(/(&?CHR=).+&BEG=.+&END=[^&]+(.?)/, '$1' + r[0] + '&BEG=' + r[1] + '&END=' + r[2] + '$2');
      } else {
        return Ensembl.urlFromHash(this.href);
      }
    });

    $('input[name=r]', 'form:not(#core_params)').val(r);

    $('h1.summary-heading').html(function (i, html) {
      return html.replace(/^(Chromosome ).+/, '$1' + text);
    });

    document.title = document.title.replace(/(Chromosome ).+/, '$1' + text);
  },

  toggleContent: function (rel, delay) {
    if (rel) {
      window.setTimeout(function() {
        $('a.toggle[rel="' + rel + '"]').toggleClass('open closed');
      }, delay && $('a.toggle[rel="' + rel + '"]').hasClass('open') ? delay : 0);
    }
  },

  changeWidth: function () {
    var modal = $('#modal_panel');
    $('.navbar, div.info, div.hint, div.warning, div.error').not('.fixed_width').not(function () { return modal.find(this).length; }).width(Ensembl.width);
    modal = null;
  },

  handleMirrorRedirect: function() {

    var redirectCode  = unescape(Ensembl.cookie.get('redirect_mirror'));
    var redirectURI   = unescape(Ensembl.cookie.get('redirect_mirror_url'));

    Ensembl.cookie.set('redirect_mirror_url');

    var noRedirectURI = function(uri) {
      uri = uri.replace(/(\&|\;)?redirect=[^\&\;]+/, '').replace(/(\&|\;)?debugip=[^\&\;]+/, '').replace(/\?[\;\&]+/, '?').replace(/\?$/, '');
      uri = uri + (uri.match(/\?/) ? ';redirect=no' : '?redirect=no');
      return uri;
    };

    if (redirectCode && redirectCode !== 'no') {
      redirectCode      = redirectCode.split(/\|/);
      if (redirectCode.length >= 2) {
        var currentURI    = noRedirectURI(window.location.href);
        var mirrorName    = redirectCode.shift();
        var remainingTime = parseInt(redirectCode.shift());
        var mirrorURI     = (redirectURI ? noRedirectURI($('').attr('href', redirectURI).prop('href')) : currentURI).replace(window.location.host, mirrorName);
        var messageDiv    = $([
          '
',
          '
You are being redirected to ', mirrorName, ' in ', remainingTime, ' seconds. Click here if you don\'t wish to be redirected.
',
          '
'
        ].join('')).appendTo($('body').prepend($('

').slideDown())).slideDown().find('a._redirect_no').on('click', function (e) {
          e.preventDefault();
          Ensembl.cookie.set('redirect_mirror', 'no');
          clearInterval(messageDiv.data('countdown'));
          window.location.replace(messageDiv.data('currentURI'));
        }).end().data({
          remainingTime : remainingTime,
          mirrorURI     : mirrorURI,
          currentURI    : currentURI,
          countdown     : setInterval(function() {
            var time  = messageDiv.data('remainingTime') - 1;
            messageDiv.data('remainingTime', time).find('._redirect_countdown').html(time > 0 ? time > 1 ? 'in ' + time + ' seconds' : 'in 1 second' : 'now');
            if (time <= 0) {
              clearInterval(messageDiv.data('countdown'));
              window.location.href = messageDiv.data('mirrorURI');
            }
          }, 1000)
        });
      }
    }
  },

  showCookieMessage: function() {
    var manager = this;
    var cookiesAccepted = Ensembl.cookie.get('cookies_ok');

    if (!cookiesAccepted) {
      $(['
',
        '
We use cookies to enhance the usability of our website. If you continue, we\'ll assume that you are happy to receive all cookies.<button>Don\'t show this again</button>
',
        '
Further details about our privacy and cookie policy can be found here
',
        '
'
      ].join(''))
        .prependTo(document.body).slideDown().find('button').on('click', function (e) {
          Ensembl.cookie.set('cookies_ok', 'yes');
          $(this).parents('div').first().slideUp();
          manager.handleMirrorRedirect();
      });
      return true;
    }

    return false;
  },

  showMobileMessage: function() { }

});
<|endoftext|>


<commit_before>/**
 * ProgressBar component.
 *
 * Site Kit by Google, Copyright 2019 Google LLC
 *
 * Licensed 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import classnames from 'classnames';

export default function ProgressBar( {
	className,
	small,
	compress,
	indeterminate,
	height,
	progress,
} ) {
	const margin = typeof height !== 'undefined' ? Math.round( height / 2 ) : undefined;
	const transform = progress ? `scaleX(${ progress })` : undefined;

	return (

	);
}

ProgressBar.propTypes = {
	className: PropTypes.string,
	small: PropTypes.bool,
	compress: PropTypes.bool,
	indeterminate: PropTypes.bool,
	progress: PropTypes.number,
	height: PropTypes.number,
};

ProgressBar.defaultProps = {
	className: '',
	small: false,
	compress: false,
	indeterminate: true,
	progress: 0,
};
<commit_msg>Revert some changes in the ProgressBar component.<commit_after>/**
 * ProgressBar component.
 *
 * Site Kit by Google, Copyright 2019 Google LLC
 *
 * Licensed 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
 *
 *     https://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.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import classnames from 'classnames';

export default function ProgressBar( {
	className,
	small,
	compress,
	indeterminate,
	height,
	progress,
} ) {
	const margin = typeof height !== 'undefined' ? Math.round( height / 2 ) : undefined;
	const transform = progress ? `scaleX(${ progress })` : undefined;

	return (

	);
}

ProgressBar.propTypes = {
	className: PropTypes.string,
	small: PropTypes.bool,
	compress: PropTypes.bool,
	indeterminate: PropTypes.bool,
	progress: PropTypes.number,
	height: PropTypes.number,
};

ProgressBar.defaultProps = {
	className: '',
	small: false,
	compress: false,
	indeterminate: true,
	progress: 0,
};
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc function
 * @name Pear2Pear.controller:TimelineCtrl
 * @description
 * # TimelineCtrl
 * Controller of the Pear2Pear
 */

window.onWaveJSReady = function () {
  window.WaveJS.startSession(
    'https://wave.p2pvalue.eu',
    window.configTimelineTests.user,
    window.configTimelineTests.pass);
};

angular.module('Pear2Pear')
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/timeline', {
        templateUrl: 'views/timeline/show.html',
        controller: 'TimelineCtrl'
      })
      .when('/timeline/control', {
        templateUrl: 'views/timeline/show.html',
        controller: 'TimelineCtrl'
      })
      .when('/timeline/waveid', {
        templateUrl: 'views/timeline/waveid.html',
        controller: 'TimelineCtrl'
      });
  }])
  .filter('reverse', function () {
    return function (items) {
      return (items) ? items.slice().reverse(): [];
    };
  })
  .controller('TimelineCtrl', ['$scope', '$location', function ($scope, $location) {
    var apply = function () {
      var p = $scope.$$phase;
      if (p !== '$digest' && p !== '$apply') {
        $scope.$apply();
      }
    };

    $scope.init = function () {
      // following if avoids concurrency control error in wave
      if (window.WaveJS.listModel) {
        window.WaveJS.close(
          window.configTimelineTests.waveId);
      }

      window.WaveJS.openListModel(
        window.configTimelineTests.waveId,
        function (listModel) {
          window.WaveJS.listModel = listModel;
          window.WaveJS.listModel.list.registerEventHandler(
            'ITEM_ADDED', function (item) {
              var index = window.WaveJS.listModel.list.values.indexOf(item);
              $scope.timeline[index] = JSON.parse(item);
              apply();
            });
          window.WaveJS.listModel.list.registerEventHandler(
            'ITEM_REMOVED', function (item) {
              var index = window.WaveJS.listModel.list.values.indexOf(item);
              $scope.timeline.splice(index, 1);
              apply();
            });
          $scope.timeline = [];
          for (var i = 0; i < listModel.list.values.length; i++) {
            $scope.timeline[i] = JSON.parse(listModel.list.values[i]);
          }
          apply();

        }, function (error) {
          window.alert('Error accessing the collaborative list ' + error);
        });
    };

    // TODO: this should be set by the method above
    $scope.community = {
      name: 'Testing community'
    };

    if (typeof window.WaveJS !== 'undefined') {
      $scope.init();
    }
    else {
      window.onWaveJSReady = function () {
        window.WaveJS.startSession(
          'https://wave.p2pvalue.eu',
          window.configTimelineTests.user,
          window.configTimelineTests.pass,
          function () {
            $scope.init();
          },
          function (error) {
            window.alert('error: ' + error);
          });
      };
    }
    var nombre;
    var community = {};
    var machaca1;
    var machaca2;
    var proyectoQuiso;
    var tarea;
    var proyectoDuda;
    $scope.hipothesis = [
      {
        fun : function () {
          nombre = prompt('Nombre del entrevistado');
          community.name = prompt('Nombre de la comunidad');
          machaca1 = prompt('Nombre de persona activa en comunidad');
          proyectoQuiso = prompt('Proyecto en el que quiso y no pudo');
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'lightbulb-o',
            'heading': machaca1 + ' ha creado el proyecto ' + proyectoQuiso
          }));
        }
      },
      {
        fun : function () {
          var tarea = prompt('Tarea del proyecto en el que quiso y no pudo');

          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'magic',
            'heading': tarea,
            'body': machaca1 + ' ha creado una tarea en el proyecto ' + proyectoQuiso
          }));
        }
      },
      {      fun : function () {
          proyectoDuda = prompt('Proyecto en el que dudó si participar');

          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'lightbulb-o',
            'heading': machaca1 + ' ha creado el proyecto ' + proyectoDuda
          }));
        }
      },
      {
        fun : function () {
          tarea = prompt('Tarea del proyecto en el que dudó si participar');

          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'magic',
            'heading': tarea,
            'body': machaca1 + ' ha creado una tarea en el proyecto ' + proyectoDuda
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'pencil',
            'heading': proyectoDuda + ': En marcha!',
            'body': machaca1 + ' ha cambiado el estado del proyecto'
          }));
        }
      },
      {
        fun: function () {
          machaca2 = prompt('Nombre de otra persona activa en el proyecto');
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'life-ring',
            'heading': 'Ayuda a: ' + tarea,
            'body': machaca2 + ' ha pedido colaboración en la tarea'
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'life-ring',
            'heading': 'Ayuda a: ' + tarea,
            'body': machaca2 + ' ha pedido colaboración en la tarea'
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'life-ring',
            'heading': 'Ayudame ' + nombre + ' a: ' + tarea,
            'body': machaca2 + ' te ha pedido colaboración en la tarea'
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'lightbulb-o',
            'heading': 'Únete a : ' + proyectoDuda,
            'body': machaca2 + ' te ha invitado a participar en el proyecto'
          }));
        }
      }
    ];

    $scope.testIndex = 0;
    $scope.next = function () {
      if ($scope.testIndex < $scope.hipothesis.length) {
        ($scope.hipothesis[$scope.testIndex].fun)();
        $scope.testIndex++;
      }
    };
    $scope.clear = function () {
      var wjsList = window.WaveJS.listModel.list;
      for (var i = wjsList.values.length; i >= 0 ; i--) {
        wjsList.remove(i);
      }
      $scope.testIndex = 0;
    };

    $scope.isControl = function () {
      return $location.url().indexOf('control') > -1;
    };

    $scope.newWaveId = function () {
      window.alert(window.WaveJS.createListModel());
    };

  }]);

<commit_msg>Fix temporal community name<commit_after>'use strict';

/**
 * @ngdoc function
 * @name Pear2Pear.controller:TimelineCtrl
 * @description
 * # TimelineCtrl
 * Controller of the Pear2Pear
 */

window.onWaveJSReady = function () {
  window.WaveJS.startSession(
    'https://wave.p2pvalue.eu',
    window.configTimelineTests.user,
    window.configTimelineTests.pass);
};

angular.module('Pear2Pear')
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/timeline', {
        templateUrl: 'views/timeline/show.html',
        controller: 'TimelineCtrl'
      })
      .when('/timeline/control', {
        templateUrl: 'views/timeline/show.html',
        controller: 'TimelineCtrl'
      })
      .when('/timeline/waveid', {
        templateUrl: 'views/timeline/waveid.html',
        controller: 'TimelineCtrl'
      });
  }])
  .filter('reverse', function () {
    return function (items) {
      return (items) ? items.slice().reverse(): [];
    };
  })
  .controller('TimelineCtrl', ['$scope', '$location', function ($scope, $location) {
    var apply = function () {
      var p = $scope.$$phase;
      if (p !== '$digest' && p !== '$apply') {
        $scope.$apply();
      }
    };

    $scope.init = function () {
      // following if avoids concurrency control error in wave
      if (window.WaveJS.listModel) {
        window.WaveJS.close(
          window.configTimelineTests.waveId);
      }

      window.WaveJS.openListModel(
        window.configTimelineTests.waveId,
        function (listModel) {
          window.WaveJS.listModel = listModel;
          window.WaveJS.listModel.list.registerEventHandler(
            'ITEM_ADDED', function (item) {
              var index = window.WaveJS.listModel.list.values.indexOf(item);
              $scope.timeline[index] = JSON.parse(item);
              apply();
            });
          window.WaveJS.listModel.list.registerEventHandler(
            'ITEM_REMOVED', function (item) {
              var index = window.WaveJS.listModel.list.values.indexOf(item);
              $scope.timeline.splice(index, 1);
              apply();
            });
          $scope.timeline = [];
          for (var i = 0; i < listModel.list.values.length; i++) {
            $scope.timeline[i] = JSON.parse(listModel.list.values[i]);
          }
          apply();

        }, function (error) {
          window.alert('Error accessing the collaborative list ' + error);
        });
    };

    // TODO: this should be set by the method above
    $scope.community = {
      name: 'UCM P2Pvalue'
    };

    if (typeof window.WaveJS !== 'undefined') {
      $scope.init();
    }
    else {
      window.onWaveJSReady = function () {
        window.WaveJS.startSession(
          'https://wave.p2pvalue.eu',
          window.configTimelineTests.user,
          window.configTimelineTests.pass,
          function () {
            $scope.init();
          },
          function (error) {
            window.alert('error: ' + error);
          });
      };
    }
    var nombre;
    var community = {};
    var machaca1;
    var machaca2;
    var proyectoQuiso;
    var tarea;
    var proyectoDuda;
    $scope.hipothesis = [
      {
        fun : function () {
          nombre = prompt('Nombre del entrevistado');
          community.name = prompt('Nombre de la comunidad');
          machaca1 = prompt('Nombre de persona activa en comunidad');
          proyectoQuiso = prompt('Proyecto en el que quiso y no pudo');
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'lightbulb-o',
            'heading': machaca1 + ' ha creado el proyecto ' + proyectoQuiso
          }));
        }
      },
      {
        fun : function () {
          var tarea = prompt('Tarea del proyecto en el que quiso y no pudo');

          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'magic',
            'heading': tarea,
            'body': machaca1 + ' ha creado una tarea en el proyecto ' + proyectoQuiso
          }));
        }
      },
      {      fun : function () {
          proyectoDuda = prompt('Proyecto en el que dudó si participar');

          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'lightbulb-o',
            'heading': machaca1 + ' ha creado el proyecto ' + proyectoDuda
          }));
        }
      },
      {
        fun : function () {
          tarea = prompt('Tarea del proyecto en el que dudó si participar');

          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'magic',
            'heading': tarea,
            'body': machaca1 + ' ha creado una tarea en el proyecto ' + proyectoDuda
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'pencil',
            'heading': proyectoDuda + ': En marcha!',
            'body': machaca1 + ' ha cambiado el estado del proyecto'
          }));
        }
      },
      {
        fun: function () {
          machaca2 = prompt('Nombre de otra persona activa en el proyecto');
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'life-ring',
            'heading': 'Ayuda a: ' + tarea,
            'body': machaca2 + ' ha pedido colaboración en la tarea'
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'life-ring',
            'heading': 'Ayuda a: ' + tarea,
            'body': machaca2 + ' ha pedido colaboración en la tarea'
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'life-ring',
            'heading': 'Ayudame ' + nombre + ' a: ' + tarea,
            'body': machaca2 + ' te ha pedido colaboración en la tarea'
          }));
        }
      },
      {
        fun: function () {
          window.WaveJS.listModel.list.add(JSON.stringify({
            'icon': 'lightbulb-o',
            'heading': 'Únete a : ' + proyectoDuda,
            'body': machaca2 + ' te ha invitado a participar en el proyecto'
          }));
        }
      }
    ];

    $scope.testIndex = 0;
    $scope.next = function () {
      if ($scope.testIndex < $scope.hipothesis.length) {
        ($scope.hipothesis[$scope.testIndex].fun)();
        $scope.testIndex++;
      }
    };
    $scope.clear = function () {
      var wjsList = window.WaveJS.listModel.list;
      for (var i = wjsList.values.length; i >= 0 ; i--) {
        wjsList.remove(i);
      }
      $scope.testIndex = 0;
    };

    $scope.isControl = function () {
      return $location.url().indexOf('control') > -1;
    };

    $scope.newWaveId = function () {
      window.alert(window.WaveJS.createListModel());
    };

  }]);

<|endoftext|>


<commit_before>// @flow
// Rows for our normal inbox view. A set of small items on top ordered by time, a set of teams/channels ordered by alpha
// If you have teams and a bunch of small chats we truncate and put a divider in between
import * as Types from '../../../constants/types/chat2'
import * as I from 'immutable'
import shallowEqual from 'shallowequal'
import * as Constants from '../../../constants/chat2'
import {memoize} from '../../../util/memoize'
import type {RowItem} from '../index.types'
import * as RPCChatTypes from '../../../constants/types/rpc-chat-gen'

const smallTeamsCollapsedMaxShown = 5

// Could make this faster by bookkeeping if this structure changed instead of if any item changed
const splitMetas = memoize((metaMap: Types.MetaMap, selectedConversation) => {
  const bigMetas: Array<Types.ConversationMeta> = []
  const smallMetas: Array<Types.ConversationMeta> = []
  metaMap.forEach((meta: Types.ConversationMeta, id) => {
    if (Constants.isValidConversationIDKey(id)) {
      if (meta.teamType === 'big') {
        bigMetas.push(meta)
      } else {
        if (
          meta.status !== RPCChatTypes.commonConversationStatus.ignored ||
          meta.conversationIDKey === selectedConversation
        ) {
          smallMetas.push(meta)
        }
      }
    }
  })
  return {bigMetas, smallMetas}
})

const sortByTimestamp = (a: Types.ConversationMeta, b: Types.ConversationMeta) => b.timestamp - a.timestamp
const getSmallRows = memoize(
  (smallMetas, showAllSmallRows, selectedConversation) => {
    let metas
    if (showAllSmallRows) {
      metas = smallMetas.sort(sortByTimestamp)
    } else {
      metas = I.Seq(smallMetas)
        .sort(sortByTimestamp)
        .take(smallTeamsCollapsedMaxShown)
        .toArray()
    }
    return metas.map(m => ({conversationIDKey: m.conversationIDKey, type: 'small'}))
  },
  (
    [newMetas, newShowSmallRows, newSelectedConversation],
    [oldMetas, oldShowSmallRows, oldSelectedConversation]
  ) =>
    newSelectedConversation === oldSelectedConversation &&
    newShowSmallRows === oldShowSmallRows &&
    newMetas.length === oldMetas.length &&
    newMetas.every((a, idx) => {
      const b = oldMetas[idx]
      return a.conversationIDKey === b.conversationIDKey && a.inboxVersion === b.inboxVersion
    })
)

const sortByTeamChannel = (a, b) =>
  a.teamname === b.teamname
    ? a.channelname.localeCompare(b.channelname)
    : a.teamname.localeCompare(b.teamname)
const getBigRows = memoize(
  bigMetas => {
    let lastTeam: ?string
    return bigMetas.sort(sortByTeamChannel).reduce((arr, meta) => {
      // headers for new teams
      if (meta.teamname !== lastTeam) {
        lastTeam = meta.teamname
        arr.push({teamname: lastTeam, type: 'bigHeader'})
      }
      // channels
      arr.push({
        channelname: meta.channelname,
        conversationIDKey: meta.conversationIDKey,
        teamname: lastTeam,
        type: 'big',
      })

      return arr
    }, [])
  },
  ([newMetas], [oldMetas]) => shallowEqual(newMetas, oldMetas)
)

// Get smallIDs and big RowItems. Figure out the divider if it exists and truncate the small list.
// Convert the smallIDs to the Small RowItems
const getRowsAndMetadata = memoize<Types.MetaMap, boolean, Types.ConversationIDKey, void, _>(
  (metaMap: Types.MetaMap, smallTeamsExpanded: boolean, selectedConversation: Types.ConversationIDKey) => {
    const {bigMetas, smallMetas} = splitMetas(metaMap, selectedConversation)
    const showAllSmallRows = smallTeamsExpanded || !bigMetas.length
    const smallRows = getSmallRows(smallMetas, showAllSmallRows)
    const bigRows = getBigRows(bigMetas)
    const smallTeamsBelowTheFold = smallMetas.length > smallRows.length
    const divider = bigRows.length !== 0 ? [{showButton: smallTeamsBelowTheFold, type: 'divider'}] : []
    const allowShowFloatingButton = smallRows.length > smallTeamsCollapsedMaxShown && !!bigMetas.length
    const rows: Array<RowItem> = [...smallRows, ...divider, ...bigRows]

    return {
      allowShowFloatingButton,
      rows,
      smallTeamsExpanded: showAllSmallRows, // only collapse if we're actually showing a divider,
    }
  }
)

export default getRowsAndMetadata
<commit_msg>android: Fix channel sorting (#17087)<commit_after>// @flow
// Rows for our normal inbox view. A set of small items on top ordered by time, a set of teams/channels ordered by alpha
// If you have teams and a bunch of small chats we truncate and put a divider in between
import * as Types from '../../../constants/types/chat2'
import * as I from 'immutable'
import shallowEqual from 'shallowequal'
import * as Constants from '../../../constants/chat2'
import {memoize} from '../../../util/memoize'
import type {RowItem} from '../index.types'
import * as RPCChatTypes from '../../../constants/types/rpc-chat-gen'

const smallTeamsCollapsedMaxShown = 5

// Could make this faster by bookkeeping if this structure changed instead of if any item changed
const splitMetas = memoize((metaMap: Types.MetaMap, selectedConversation) => {
  const bigMetas: Array<Types.ConversationMeta> = []
  const smallMetas: Array<Types.ConversationMeta> = []
  metaMap.forEach((meta: Types.ConversationMeta, id) => {
    if (Constants.isValidConversationIDKey(id)) {
      if (meta.teamType === 'big') {
        bigMetas.push(meta)
      } else {
        if (
          meta.status !== RPCChatTypes.commonConversationStatus.ignored ||
          meta.conversationIDKey === selectedConversation
        ) {
          smallMetas.push(meta)
        }
      }
    }
  })
  return {bigMetas, smallMetas}
})

const sortByTimestamp = (a: Types.ConversationMeta, b: Types.ConversationMeta) => b.timestamp - a.timestamp
const getSmallRows = memoize(
  (smallMetas, showAllSmallRows, selectedConversation) => {
    let metas
    if (showAllSmallRows) {
      metas = smallMetas.sort(sortByTimestamp)
    } else {
      metas = I.Seq(smallMetas)
        .sort(sortByTimestamp)
        .take(smallTeamsCollapsedMaxShown)
        .toArray()
    }
    return metas.map(m => ({conversationIDKey: m.conversationIDKey, type: 'small'}))
  },
  (
    [newMetas, newShowSmallRows, newSelectedConversation],
    [oldMetas, oldShowSmallRows, oldSelectedConversation]
  ) =>
    newSelectedConversation === oldSelectedConversation &&
    newShowSmallRows === oldShowSmallRows &&
    newMetas.length === oldMetas.length &&
    newMetas.every((a, idx) => {
      const b = oldMetas[idx]
      return a.conversationIDKey === b.conversationIDKey && a.inboxVersion === b.inboxVersion
    })
)

const sortByTeamChannel = (a, b) =>
  a.teamname === b.teamname
    ? a.channelname.localeCompare(b.channelname, undefined, {sensitivity: 'base'})
    : a.teamname.localeCompare(b.teamname) // team names are normalized to lowercase
const getBigRows = memoize(
  bigMetas => {
    let lastTeam: ?string
    return bigMetas.sort(sortByTeamChannel).reduce((arr, meta) => {
      // headers for new teams
      if (meta.teamname !== lastTeam) {
        lastTeam = meta.teamname
        arr.push({teamname: lastTeam, type: 'bigHeader'})
      }
      // channels
      arr.push({
        channelname: meta.channelname,
        conversationIDKey: meta.conversationIDKey,
        teamname: lastTeam,
        type: 'big',
      })

      return arr
    }, [])
  },
  ([newMetas], [oldMetas]) => shallowEqual(newMetas, oldMetas)
)

// Get smallIDs and big RowItems. Figure out the divider if it exists and truncate the small list.
// Convert the smallIDs to the Small RowItems
const getRowsAndMetadata = memoize<Types.MetaMap, boolean, Types.ConversationIDKey, void, _>(
  (metaMap: Types.MetaMap, smallTeamsExpanded: boolean, selectedConversation: Types.ConversationIDKey) => {
    const {bigMetas, smallMetas} = splitMetas(metaMap, selectedConversation)
    const showAllSmallRows = smallTeamsExpanded || !bigMetas.length
    const smallRows = getSmallRows(smallMetas, showAllSmallRows)
    const bigRows = getBigRows(bigMetas)
    const smallTeamsBelowTheFold = smallMetas.length > smallRows.length
    const divider = bigRows.length !== 0 ? [{showButton: smallTeamsBelowTheFold, type: 'divider'}] : []
    const allowShowFloatingButton = smallRows.length > smallTeamsCollapsedMaxShown && !!bigMetas.length
    const rows: Array<RowItem> = [...smallRows, ...divider, ...bigRows]

    return {
      allowShowFloatingButton,
      rows,
      smallTeamsExpanded: showAllSmallRows, // only collapse if we're actually showing a divider,
    }
  }
)

export default getRowsAndMetadata
<|endoftext|>


<commit_before>/**
 * @fileoverview Interprets a given command and calls workspace controller_.functions.
 * @author pandori@wisc.edu (Sahib Pandori)
 * @author david.liang@wisc.edu (David Liang)
 */

'use strict';

goog.provide('SpeechBlocks.Interpreter');

goog.require('SpeechBlocks.Predecessor');
goog.require('SpeechBlocks.StatementInput')
goog.require('SpeechBlocks.Successor');
goog.require('SpeechBlocks.Translation');
goog.require('SpeechBlocks.ValueInput');
goog.require('goog.structs.Map');

/**
 * Constructs an interpreter that takes actions as input and controls the Blockly Workspace.
 * @param {!SpeechBlocks.Controller} controller_.The workspace controller_.
 */
SpeechBlocks.Interpreter = function(controller) {
	/** @private @const */
	this.controller_ = controller;
	/** @private */
	this.id_ = 1;
	/** @private */
	this.blockTypeMap_ = new goog.structs.Map();
	this.blockTypeMap_.set('if','controls_if');
	this.blockTypeMap_.set('comparison','logic_compare');
	this.blockTypeMap_.set('repeat','controls_repeat_ext');
	this.blockTypeMap_.set('number','math_number');
	this.blockTypeMap_.set('arithmetic','math_arithmetic');
	this.blockTypeMap_.set('text','text');
	this.blockTypeMap_.set('print','text_print');
	this.blockTypeMap_.set('set','variables_set');
	this.blockTypeMap_.set('variable','variables_get');
}

/**
 * Initialize the mapping of types that the parser uses and the types that Blockly understands.
 */
SpeechBlocks.Interpreter.prototype.initializeBlockTypeMap = function() {
	//var inputReceived = false;
	/** does not work, unsure if we will keep this method for possible future use*/
	//this.blockTypeMap_ = this.initializeBlockTypeMap();
	//setTimeout(function() {
	// console.log(inputReceived);
	// if (this.blockTypeMap_ != null) {
	// console.log(this.blockTypeMap_.isEmpty());
	// console.log(this.blockTypeMap_.getValues())
	// console.log(this.blockTypeMap_.get('if'));
	// }
	// else {console.log("BLOCKTYPEMAP IS NULL")}
	// },5000);
	return;
	var inputText;
	var rawFile;
	try {
		console.log('a');
		rawFile = new XMLHttpRequest();
		rawFile.open("GET", 'https://aravart.github.io/speech-blocks/grammar/blockTypeMap.txt', true);
		rawFile.onreadystatechange = function () {
			//console.log(rawFile.readyState);
			if(rawFile.readyState == 4) {
				//console.log('b')
				if(rawFile.status == 200 || rawFile.status == 0) {
					//console.log('c');
					if (!inputReceived) {
						//console.log('INPUT BEING SET');
						inputText = rawFile.responseText;
						inputReceived = true;
						// console.log('INPUT SET');
						console.log(inputText);
						inputText = inputText.split(/\r\n|\r|\n/g);
						var blockTypeMap = new goog.structs.Map();
						for (var i = 0; i < inputText.length; i++) {
							var keyValuePair = inputText[i].split(":");
							//console.log(keyValuePair[0]);
							//console.log(keyValuePair[1]);
							if (keyValuePair[0] != null && keyValuePair[1] != null) {
								blockTypeMap.set(keyValuePair[0], keyValuePair[1]);
							}
						}
						this.blockTypeMap_ = blockTypeMap;
						console.log("SAVED");
						console.log(this.blockTypeMap_.get('if'))
						return;
					}
					else {console.log('input already set');}
				}
			}
			else {}
			if (rawFile.status == 200 || rawFile.status == 0) {rawFile.send();}
		}
	} catch(err) { console.log(err.stack) }

	try {
		setTimeout(function() {rawFile.onreadystatechange();},3000);
	}
	catch(err) {console.log(err.stack) }

}

/**
 * Interprets a given command by calling the corresponding action function.
 * @param {Object=} command Command object from parser.
 */
SpeechBlocks.Interpreter.prototype.interpret = function(command) {
	switch (command.action) {
	case 'run': this.run(command); break;
	case 'add': this.addBlock(command); break;
	case 'move': this.moveBlock(command); break;
	case 'modify': this.modifyBlock(command); break;
	case 'delete': this.deleteBlock(command); break;
	default: console.log('Unsupported command');
	}
};

/**
 * Compiles the Blockly code into JavaScript and runs it.
 * @param {Object=} command Object with command specifics from the parser.
 */
SpeechBlocks.Interpreter.prototype.run = function(command) {
	Blockly.JavaScript.addReservedWords('code');
	try {
		var code = Blockly.JavaScript.workspaceToCode(this.controller_.workspace);
		eval(code);
	} catch (err) { console.log(err.message); throw err; }
};

/**
 * Adds a specified block.
 * @param {Object=} command Command object from parser.
 */
SpeechBlocks.Interpreter.prototype.addBlock = function(command) {
  // var type = this.blockTypeMap_.get(command.type);
  // if (type == null) { return; }
  this.controller_.addBlock(this.blockTypeMap_.get(command.type), (this.id_++).toString(), new SpeechBlocks.Translation(0,0));
};

/**
 * @TODO Implement error checking
 * Moves a specified block.
 * @param {Object=} command Command object from parser.
 */
SpeechBlocks.Interpreter.prototype.moveBlock = function(command) {
	// ensure these fields are strings, so validity checking works properly
  command.block = command.block.toString();
  if (this.isBlockIdValid(command.block)) {
    if (command.where == 'trash') {
      this.deleteBlock(command.block);
      return;
    }
    if (command.where.block == null) { return; }
    else { command.where.block = command.where.block.toString(); }
    if (this.isBlockIdValid(command.where.block)) {
      switch (command.where.position) {
        // modify these so the 'where' field is right
        case 'after': this.controller_.moveBlock(command.block, new SpeechBlocks.Successor(command.where.block)); break;
        case 'before': this.controller_.moveBlock(command.block, new SpeechBlocks.Predecessor(command.where.block)); break;
        case 'lhs': case 'rhs': case 'to the right of':
        var inputList_ = this.controller_.getBlockValueInputs(command.where.block);
        if (inputList_.length < 1) { console.log('NO VALUE INPUTS FOR SPECIFIED BLOCK'); }
        else if (command.where.position == 'rhs' || command.where.position == 'to the right of') { this.controller_.moveBlock(command.block, new SpeechBlocks.ValueInput(command.where.block, inputList_[inputList_.length-1]));	}
        else { this.controller_.moveBlock(command.block, new SpeechBlocks.ValueInput(command.where.block, inputList_[0])); }
        case 'inside':
        var statementList_ = this.controller_.getBlockStatementInputs(command.where.block);
        if (statementList_.length < 1) { console.log('NO STATEMENT INPUTS FOR SPECIFIED BLOCK'); }
        else { this.controller_.moveBlock(command.block, new SpeechBlocks.StatementInput(command.where.block, statementList_[statementList_.length-1])); }
        break;
        default:
        console.log('Unsupported position');
      }
    }
    else {
      console.log("no")
    }

  }
	else {
		console.log('Invalid block Id');
	}
};

/**
 * @TODO Implement each case of property
 * Modifies a specified block.
 * @param {Object=} command Command object from parser.
 */
SpeechBlocks.Interpreter.prototype.modifyBlock = function(command) {
	command.block = command.block.toString();
	if (this.isBlockIdValid(command.block)) {
		var fields = this.controller_.getFieldsForBlock(command.block).getKeys();
		if (fields.length == 1) {
			this.controller_.setBlockField(command.block, fields[0], command.value);
			return;
		}
		// console.log(fields);
		// console.log(this.controller_.getFieldsForBlock(command.block).getValues());
		switch(command.property) {
		case 'number':
			command.value = Number(command.value);
			this.controller_.setBlockField(command.block, fields[0], command.value);
			break;
		case 'text':
			this.controller_.setBlockField(command.block, fields[0], command.value);
			break;
		case 'comparison':
			this.controller_.setBlockField(command.block, fields[0], command.value);
			break;
		case 'operation':
			this.controller_.setBlockField(command.block, fields[0], command.value);
			break;
		case 'name':
			this.controller_.setBlockField(command.block, fields[0], command.value);
			break;
		default:
			console.log('Unsupported property');
		}
	}
	else {
		console.log('Invalid block Id');
	}
};

/**
 * Delete a specified block.
 * @param {Object=} command Command object from parser.
 */
SpeechBlocks.Interpreter.prototype.deleteBlock = function(blockId) {
	if (this.isBlockIdValid(blockId)) { this.controller_.removeBlock(blockId); }
	else { console.log('Invalid block Id'); }
};

/**
 * Checks to see if a block Id is valid.
 * @param {!String=} blockId as string.
 */
SpeechBlocks.Interpreter.prototype.isBlockIdValid = function(blockRequestId) {
	return this.controller_.getAllBlockIds().contains(blockRequestId);
}
<commit_msg>Bug fixes: grammar specified commands should all work<commit_after>/**
* @fileoverview Interprets a given command and calls workspace controller_.functions.
* @author pandori@wisc.edu (Sahib Pandori)
* @author david.liang@wisc.edu (David Liang)
*/

'use strict';

goog.provide('SpeechBlocks.Interpreter');

goog.require('SpeechBlocks.Predecessor');
goog.require('SpeechBlocks.StatementInput')
goog.require('SpeechBlocks.Successor');
goog.require('SpeechBlocks.Translation');
goog.require('SpeechBlocks.ValueInput');
goog.require('goog.structs.Map');

/**
* Constructs an interpreter that takes actions as input and controls the Blockly Workspace.
* @param {!SpeechBlocks.Controller} controller_.The workspace controller_.
*/
SpeechBlocks.Interpreter = function(controller) {
  /** @private @const */
  this.controller_ = controller;
  /** @private */
  this.id_ = 1;
  /** @private */
  this.blockTypeMap_ = new goog.structs.Map();
  this.blockTypeMap_.set('if','controls_if');
  this.blockTypeMap_.set('comparison','logic_compare');
  this.blockTypeMap_.set('repeat','controls_repeat_ext');
  this.blockTypeMap_.set('number','math_number');
  this.blockTypeMap_.set('arithmetic','math_arithmetic');
  this.blockTypeMap_.set('text','text');
  this.blockTypeMap_.set('print','text_print');
  this.blockTypeMap_.set('set','variables_set');
  this.blockTypeMap_.set('variable','variables_get');
}

/**
* Initialize the mapping of types that the parser uses and the types that Blockly understands.
*/
SpeechBlocks.Interpreter.prototype.initializeBlockTypeMap = function() {
  //var inputReceived = false;
  /** does not work, unsure if we will keep this method for possible future use*/
  //this.blockTypeMap_ = this.initializeBlockTypeMap();
  //setTimeout(function() {
  // console.log(inputReceived);
  // if (this.blockTypeMap_ != null) {
  // console.log(this.blockTypeMap_.isEmpty());
  // console.log(this.blockTypeMap_.getValues())
  // console.log(this.blockTypeMap_.get('if'));
  // }
  // else {console.log("BLOCKTYPEMAP IS NULL")}
  // },5000);
  return;
  var inputText;
  var rawFile;
  try {
    console.log('a');
    rawFile = new XMLHttpRequest();
    rawFile.open("GET", 'https://aravart.github.io/speech-blocks/grammar/blockTypeMap.txt', true);
    rawFile.onreadystatechange = function () {
      //console.log(rawFile.readyState);
      if(rawFile.readyState == 4) {
        //console.log('b')
        if(rawFile.status == 200 || rawFile.status == 0) {
          //console.log('c');
          if (!inputReceived) {
            //console.log('INPUT BEING SET');
            inputText = rawFile.responseText;
            inputReceived = true;
            // console.log('INPUT SET');
            console.log(inputText);
            inputText = inputText.split(/\r\n|\r|\n/g);
            var blockTypeMap = new goog.structs.Map();
            for (var i = 0; i < inputText.length; i++) {
              var keyValuePair = inputText[i].split(":");
              //console.log(keyValuePair[0]);
              //console.log(keyValuePair[1]);
              if (keyValuePair[0] != null && keyValuePair[1] != null) {
                blockTypeMap.set(keyValuePair[0], keyValuePair[1]);
              }
            }
            this.blockTypeMap_ = blockTypeMap;
            console.log("SAVED");
            console.log(this.blockTypeMap_.get('if'))
            return;
          }
          else {console.log('input already set');}
        }
      }
      else {}
      if (rawFile.status == 200 || rawFile.status == 0) {rawFile.send();}
    }
  } catch(err) { console.log(err.stack) }

  try {
    setTimeout(function() {rawFile.onreadystatechange();},3000);
  }
  catch(err) {console.log(err.stack) }

}

/**
* Interprets a given command by calling the corresponding action function.
* @param {Object=} command Command object from parser.
*/
SpeechBlocks.Interpreter.prototype.interpret = function(command) {
  switch (command.action) {
    case 'run': this.run(command); break;
    case 'add': this.addBlock(command); break;
    case 'move': this.moveBlock(command); break;
    case 'modify': this.modifyBlock(command); break;
    case 'delete': this.deleteBlock(command); break;
  }
};

/**
* Compiles the Blockly code into JavaScript and runs it.
* @param {Object=} command Object with command specifics from the parser.
*/
SpeechBlocks.Interpreter.prototype.run = function(command) {
  Blockly.JavaScript.addReservedWords('code');
  try {
    var code = Blockly.JavaScript.workspaceToCode(this.controller_.workspace);
    eval(code);
  } catch (err) { console.log(err.message); throw err; }
};

/**
* Adds a specified block.
* @param {Object=} command Command object from parser.
*/
SpeechBlocks.Interpreter.prototype.addBlock = function(command) {
  this.controller_.addBlock(this.blockTypeMap_.get(command.type), (this.id_++).toString(), new SpeechBlocks.Translation(0,0));
};

/**
* @TODO Implement error checking
* Moves a specified block.
* @param {Object=} command Command object from parser.
*/
SpeechBlocks.Interpreter.prototype.moveBlock = function(command) {
  command.block = command.block.toString();
  if (this.isBlockIdValid(command.block)) {
    if (command.where == 'trash') { this.deleteBlock(command.block); return; }
    else if (command.where.block == null || !this.isBlockIdValid(command.where.block.toString())) { return; }
    command.where.block = command.where.block.toString();
    switch (command.where.position) {
      case 'after': this.controller_.moveBlock(command.block, new SpeechBlocks.Successor(command.where.block)); break;
      case 'before': this.controller_.moveBlock(command.block, new SpeechBlocks.Predecessor(command.where.block)); break;
      case 'lhs': case 'rhs': case 'to the right of': var inputList_ = this.controller_.getBlockValueInputs(command.where.block);
      if (inputList_.length < 1) { console.log('NO VALUE INPUTS FOR SPECIFIED BLOCK'); }
      else if (command.where.position == 'rhs' || command.where.position == 'to the right of') { this.controller_.moveBlock(command.block, new SpeechBlocks.ValueInput(command.where.block, inputList_[inputList_.length-1]));	}
      else { this.controller_.moveBlock(command.block, new SpeechBlocks.ValueInput(command.where.block, inputList_[0])); } break;
      case 'inside': var statementList_ = this.controller_.getBlockStatementInputs(command.where.block);
      if (statementList_.length < 1) { console.log('NO STATEMENT INPUTS FOR SPECIFIED BLOCK'); }
      else { this.controller_.moveBlock(command.block, new SpeechBlocks.StatementInput(command.where.block, statementList_[statementList_.length-1])); }break;
    }
  }
};

/**
* Modifies a specified block.
* @param {Object=} command Command object from parser.
*/
SpeechBlocks.Interpreter.prototype.modifyBlock = function(command) {
  command.block = command.block.toString();
  if (this.isBlockIdValid(command.block)) {
    var fields = this.controller_.getFieldsForBlock(command.block).getKeys();
    if (fields.length == 1) { this.controller_.setBlockField(command.block, fields[0], command.value); return; }
    switch(command.property) {
      case 'number': command.value = Number(command.value);
      case 'text':	case 'comparison': case 'operation': case 'name': this.controller_.setBlockField(command.block, fields[0], command.value);  break;
    }
  }
};

/**
* Delete a specified block.
* @param {Object=} command Command object from parser.
*/
SpeechBlocks.Interpreter.prototype.deleteBlock = function(blockId) {
  if (this.isBlockIdValid(blockId)) { this.controller_.removeBlock(blockId); }
};

/**
* Checks to see if a block Id is valid.
* @param {!String=} blockId as string.
*/
SpeechBlocks.Interpreter.prototype.isBlockIdValid = function(blockRequestId) {
  return this.controller_.getAllBlockIds().contains(blockRequestId);
}
<|endoftext|>


<commit_before>// whiskers.js templating library v0.1.0
(function(a){a.cache={},a.render=function(b,c,d){return c=c||{},d=d||{},a.cache[b]||(a.cache[b]=a.compile(b)),a.cache[b](c,d)},a.compile=function(b){b=(b||"")+"",b=b.replace(/\\/g,"\\\\").replace(/\'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,""),b=b.replace(/(\\*){![\s\S]*?!}/,function(a,b){return b?a.replace("\\\\",""):""});var c=[],d;b=b.replace(/(\\*){(?:([\w_.]+)|>([\w_.]+)|for +([\w_]+) +in +([\w_.]+)|if +(not +|)([\w_.]+)|\/(for|if))}/g,function(a,b,e,f,g,h,i,j,k,l,m){if(b)return a.replace("\\\\","");if(e){if(e=="else"){d=c[c.length-1];if(d&&!d.elsed){d.elsed=!0;if(d.statement=="if")return"'}else{b+='";if(d.statement=="for")return"'}if(!t._g(c,'"+d.key+"')){b+='"}return console.warn("extra {else} ignored"),""}return"'+t._g(c,'"+e+"')+'"}return f?"'+t.render(t._g(p,'"+f+"'),c,p)+'":h?(c.push({statement:"for",key:h}),"';var "+g+"A=t._g(c,'"+h+"');for(var "+g+"I=0;"+g+"I<"+g+"A.length;"+g+"I++){c['"+g+"']="+g+"A["+g+"I];b+='"):j?(c.push({statement:"if"}),"';if("+(i?"!":"")+"t._g(c,'"+j+"')){b+='"):k?(d=c[c.length-1],d&&d.statement==k?(c.pop(),"'}b+='"):(console.warn("extra {/"+k+"} ignored"),"")):a});for(var e=c.length-1;e>-1;e--)d=c[e],console.warn("extra {"+d.statement+"} closed at end of template"),b+="'}b+='";var f=new Function("var t=this;return function(c,p){var b='"+b+"';return b}");return f.apply(a)},a._g=function(a,b){var c=b.split(".");for(var d=0,e=c.length;d<e;d++){a=a[c[d]];if(!a)break}return a===undefined&&(a=""),a}})(typeof module=="object"?module.exports:window.whiskers={})
<commit_msg>Compile minified<commit_after>// whiskers.js templating library v0.1.0
(function(a){a.cache={},a.render=function(b,c,d){return c=c||{},d=d||{},a.cache[b]||(a.cache[b]=a.compile(b)),a.cache[b](c,d)},a.compile=function(b){b=(b||"")+"",b=b.replace(/\\/g,"\\\\").replace(/\'/g,"\\'").replace(/\n/g,"\\n").replace(/\r/g,""),b=b.replace(/(\\*){![\s\S]*?!}/,function(a,b){return b?a.replace("\\\\",""):""});var c=[],d;b=b.replace(/(\\*){(?:([\w_.]+)|>([\w_.]+)|for +([\w_]+) +in +([\w_.]+)|if +(not +|)([\w_.]+)|\/(for|if))}/g,function(a,b,e,f,g,h,i,j,k,l,m){if(b)return a.replace("\\\\","");if(e){if(e=="else"){d=c[c.length-1];if(d&&!d.elsed){d.elsed=!0;if(d.statement=="if")return"'}else{b+='";if(d.statement=="for")return"'}if(!t._g(c,'"+d.key+"')){b+='"}return console.warn("extra {else} ignored"),""}return"'+t._g(c,'"+e+"')+'"}return f?"'+t.render(t._g(p,'"+f+"'),c,p)+'":h?(c.push({statement:"for",key:h}),"';var "+g+"A=t._g(c,'"+h+"');for(var "+g+"I=0;"+g+"I<"+g+"A.length;"+g+"I++){c['"+g+"']="+g+"A["+g+"I];b+='"):j?(c.push({statement:"if"}),"';if("+(i?"!":"")+"t._g(c,'"+j+"')){b+='"):k?(d=c[c.length-1],d&&d.statement==k?(c.pop(),"'}b+='"):(console.warn("extra {/"+k+"} ignored"),"")):a});for(var e=c.length-1;e>-1;e--)d=c[e],console.warn("extra {"+d.statement+"} closed at end of template"),b+="'}b+='";var f=new Function("var t=this;return function(c,p){var b='"+b+"';return b}");return f.call(a)},a._g=function(a,b){var c=b.split(".");for(var d=0,e=c.length;d<e;d++){a=a[c[d]];if(!a)break}return a===undefined&&(a=""),a}})(typeof module=="object"?module.exports:window.whiskers={})
<|endoftext|>


<commit_before>'use strict';

app.directive('ngForm', [
  'pageService', '$animate',
  function (page, $animate) {
    var pre = function ($scope, $element, $attrs) {
      var name = $attrs.name || $attrs.ngForm;
      var form = name && $scope.$eval(name);
      if (!form)
        return;

      form.$element = $element;

      var controls = [];

      function checkDirty() {
        if (controls.every(function (control) {
            return control.$pristine;
          })) {
          /* effectively call form.$setPristine, without the controls. */
          $animate.removeClass($element, 'ng-dirty');
          $animate.addClass($element, 'ng-pristine');
          form.$dirty = false;
          form.$pristine = true;
        }
      }

      var $addControl = form.$addControl;
      var $removeControl = form.$removeControl;

      /* this is unfortunate, just because we can't access the existing controls list. */
      form.$addControl = function (control) {
        if ('$pristine' in control)
          controls.push(control);
        return $addControl(control);
      };
      form.$setUnsubmitted = function () {
        $animate.removeClass($element, 'ng-submitted');
        form.$submitted = false;
      };

      form.$removeControl = function (control) {
        controls.remove(control);
        checkDirty();
        return $removeControl(control);
      };

      form.subformControl = {
        $setPristine: checkDirty
      };

      if ('isolate' in $attrs) {
        form.$$parentForm.$removeControl(form);
        form.$setDirty = function() {
          $animate.removeClass($element, 'ng-pristine');
          $animate.addClass($element, 'ng-dirty');
          form.$dirty = true;
          form.$pristine = false;
        };
      }
      /* it'd be nicer to handle this in $addControl, but it happens too early */
      else if (form.$$parentForm.subformControl)
        form.$addControl(form.$$parentForm.subformControl);

      var unclaimed = {};
      form.validators = {};
      form.validator = {
        server: function (res, replace) {
          page.messages.clear(form);
          if ($.isEmptyObject(res)) {
            res.data = {};
          } else if (!angular.isObject(res.data)) {
            page.messages.addError({
              body: page.constants.message('error.generic'),
              report: res,
              owner: form
            });
            return;
          }

          var name;
          for (name in form.validators) {
            form.validators[name].server(res.data[name] || {}, replace);
          }

          for (name in res.data) {
            if (form.validators[name]) {
              form.validators[name].server(res.data[name], replace);
            } else {
              page.messages.add({
                type: 'red',
                body: Array.isArray(res.data[name]) ? res.data[name].join(', ') : res.data[name],
                owner: form
              });
            }
          }
        },

        clearServer: function () {
          _.each(form.validators, function (validator) {
            validator.server({}, true);
          });
        },

        client: function (data, replace) {
          for (var name in data) {
            if (!data.hasOwnProperty(name)) {
              continue;
            } else if (form.validators[name]) {
              form.validators[name].client(data[name], replace);
            } else {
              unclaimed[name] = data[name];
            }
          }
        },

        add: function (name, validator) {
          form.validators[name] = validator;

          if (unclaimed[name]) {
            validator.client(unclaimed[name], true);
            delete unclaimed[name];
          }
        },
      };

      form.resetAll = function (force, check) {
        if (!(force || form.$pristine || confirm(page.constants.message('navigation.confirmation'))))
          return false;
        if (check)
          return true;
        var x = window.pageXOffset,
            y = window.pageYOffset;
        page.$route.reload();
        page.$timeout(function () {
          window.scrollTo(x, y);
        });
        return true;
      };
    };

    return {
      restrict: 'EA',
      link: {
        pre: pre
      }
    };
  }
]);
<commit_msg>Add comments to the setUnsubmitted function<commit_after>'use strict';

app.directive('ngForm', [
  'pageService', '$animate',
  function (page, $animate) {
    var pre = function ($scope, $element, $attrs) {
      var name = $attrs.name || $attrs.ngForm;
      var form = name && $scope.$eval(name);
      if (!form)
        return;

      form.$element = $element;

      var controls = [];

      function checkDirty() {
        if (controls.every(function (control) {
            return control.$pristine;
          })) {
          /* effectively call form.$setPristine, without the controls. */
          $animate.removeClass($element, 'ng-dirty');
          $animate.addClass($element, 'ng-pristine');
          form.$dirty = false;
          form.$pristine = true;
        }
      }

      var $addControl = form.$addControl;
      var $removeControl = form.$removeControl;

      /* this is unfortunate, just because we can't access the existing controls list. */
      form.$addControl = function (control) {
        if ('$pristine' in control)
          controls.push(control);
        return $addControl(control);
      };

      // This method sets the form state back to its unsubitted state
      form.$setUnsubmitted = function () {

        // remove the angular helper classes that `setSubmit` creates.
        $animate.removeClass($element, 'ng-submitted');

        // actually set the state of the form.
        form.$submitted = false;
      };

      form.$removeControl = function (control) {
        controls.remove(control);
        checkDirty();
        return $removeControl(control);
      };

      form.subformControl = {
        $setPristine: checkDirty
      };

      if ('isolate' in $attrs) {
        form.$$parentForm.$removeControl(form);
        form.$setDirty = function() {
          $animate.removeClass($element, 'ng-pristine');
          $animate.addClass($element, 'ng-dirty');
          form.$dirty = true;
          form.$pristine = false;
        };
      }
      /* it'd be nicer to handle this in $addControl, but it happens too early */
      else if (form.$$parentForm.subformControl)
        form.$addControl(form.$$parentForm.subformControl);

      var unclaimed = {};
      form.validators = {};
      form.validator = {
        server: function (res, replace) {
          page.messages.clear(form);
          if ($.isEmptyObject(res)) {
            res.data = {};
          } else if (!angular.isObject(res.data)) {
            page.messages.addError({
              body: page.constants.message('error.generic'),
              report: res,
              owner: form
            });
            return;
          }

          var name;
          for (name in form.validators) {
            form.validators[name].server(res.data[name] || {}, replace);
          }

          for (name in res.data) {
            if (form.validators[name]) {
              form.validators[name].server(res.data[name], replace);
            } else {
              page.messages.add({
                type: 'red',
                body: Array.isArray(res.data[name]) ? res.data[name].join(', ') : res.data[name],
                owner: form
              });
            }
          }
        },

        clearServer: function () {
          _.each(form.validators, function (validator) {
            validator.server({}, true);
          });
        },

        client: function (data, replace) {
          for (var name in data) {
            if (!data.hasOwnProperty(name)) {
              continue;
            } else if (form.validators[name]) {
              form.validators[name].client(data[name], replace);
            } else {
              unclaimed[name] = data[name];
            }
          }
        },

        add: function (name, validator) {
          form.validators[name] = validator;

          if (unclaimed[name]) {
            validator.client(unclaimed[name], true);
            delete unclaimed[name];
          }
        },
      };

      form.resetAll = function (force, check) {
        if (!(force || form.$pristine || confirm(page.constants.message('navigation.confirmation'))))
          return false;
        if (check)
          return true;
        var x = window.pageXOffset,
            y = window.pageYOffset;
        page.$route.reload();
        page.$timeout(function () {
          window.scrollTo(x, y);
        });
        return true;
      };
    };

    return {
      restrict: 'EA',
      link: {
        pre: pre
      }
    };
  }
]);
<|endoftext|>