<commit_before>(function(){
    if(typeof EthereumProvider === "undefined"){
    var callbackId = 0;
    var callbacks = {};

    var bridgeSend = function (data) {
        ReactNativeWebView.postMessage(JSON.stringify(data));
    }

    var history = window.history;
    var pushState = history.pushState;
    history.pushState = function(state) {
        setTimeout(function () {
            bridgeSend({
               type: 'history-state-changed',
               navState: { url: location.href, title: document.title }
            });
        }, 100);
        return pushState.apply(history, arguments);
    };

    function sendAPIrequest(permission, params) {
        var messageId = callbackId++;
        var params = params || {};

        bridgeSend({
            type: 'api-request',
            permission: permission,
            messageId: messageId,
            params: params
        });

        return new Promise(function (resolve, reject) {
            params['resolve'] = resolve;
            params['reject'] = reject;
            callbacks[messageId] = params;
        });
    }

    function qrCodeResponse(data, callback){
        var result = data.data;
        var regex = new RegExp(callback.regex);
        if (!result) {
            if (callback.reject) {
                callback.reject(new Error("Cancelled"));
            }
        }
        else if (regex.test(result)) {
            if (callback.resolve) {
                callback.resolve(result);
            }
        } else {
            if (callback.reject) {
                callback.reject(new Error("Doesn't match"));
            }
        }
    }

    function Unauthorized() {
      this.name = "Unauthorized";
      this.id = 4100;
      this.code = 4100;
      this.message = "The requested method and/or account has not been authorized by the user.";
    }
    Unauthorized.prototype = Object.create(Error.prototype);

    function UserRejectedRequest() {
      this.name = "UserRejectedRequest";
      this.id = 4001;
      this.code = 4001;
      this.message = "The user rejected the request.";
    }
    UserRejectedRequest.prototype = Object.create(Error.prototype);
    ReactNativeWebView.onMessage = function (message)
    {
        data = JSON.parse(message);
        var id = data.messageId;
        var callback = callbacks[id];

        if (callback) {
            if (data.type === "api-response") {
                if (data.permission == 'qr-code'){
                    qrCodeResponse(data, callback);
                } else if (data.isAllowed) {
                    if (data.permission == 'web3') {
                        var selectedAddress = data.data[0]
                        window.statusAppcurrentAccountAddress = selectedAddress;
                        // Set deprecated metamask fields
                        window.ethereum.selectedAddress = selectedAddress;
                        window.ethereum.emit("accountsChanged", data.data);
                    }
                    callback.resolve(data.data);
                } else {
                    callback.reject(new UserRejectedRequest());
                }
            }
            else if (data.type === "web3-send-async-callback")
            {
                if (callback.beta)
                {
                    if (data.error)
                    {
                        if (data.error.code == 4100)
                            callback.reject(new Unauthorized());
                        else
                            callback.reject(data.error);
                    }
                    else
                    {
                        callback.resolve(data.result.result);
                    }
                }
                else if (callback.results)
                {
                    callback.results.push(data.error || data.result);
                    if (callback.results.length == callback.num)
                        callback.callback(undefined, callback.results);
                }
                else
                {
                    callback.callback(data.error, data.result);
                }
            }
        }
    };

    function web3Response (payload, result){
        return {id: payload.id,
                jsonrpc: "2.0",
                result: result};
    }

    function getSyncResponse (payload) {
        if (payload.method == "eth_accounts" && (typeof window.statusAppcurrentAccountAddress !== "undefined")) {
            return web3Response(payload, [window.statusAppcurrentAccountAddress])
        } else if (payload.method == "eth_coinbase" && (typeof window.statusAppcurrentAccountAddress !== "undefined")) {
            return web3Response(payload, window.statusAppcurrentAccountAddress)
        } else if (payload.method == "net_version"){
            return web3Response(payload, window.statusAppNetworkId)
        } else if (payload.method == "eth_chainId"){
            return web3Response(payload, "0x" + window.statusAppNetworkId.toString(16))
        } else if (payload.method == "eth_uninstallFilter"){
            return web3Response(payload, true);
        } else {
            return null;
        }
    }

    var StatusAPI = function () {};

    StatusAPI.prototype.getContactCode = function () {
        return sendAPIrequest('contact-code');
    };

    var EthereumProvider = function () {};

    EthereumProvider.prototype.isStatus = true;
    EthereumProvider.prototype.status = new StatusAPI();
    EthereumProvider.prototype.isConnected = function () { return true; };
    // Set legacy metamask fields https://docs.metamask.io/guide/ethereum-provider.html#legacy-api
    EthereumProvider.prototype.networkVersion = window.statusAppNetworkId;
    EthereumProvider.prototype.chainId = "0x" + window.statusAppNetworkId.toString(16);

    EthereumProvider.prototype._events = {};

    EthereumProvider.prototype.on = function(name, listener) {
        if (!this._events[name]) {
          this._events[name] = [];
        }
        this._events[name].push(listener);
    }

    EthereumProvider.prototype.removeListener = function (name, listenerToRemove) {
        if (!this._events[name]) {
          return
        }

        const filterListeners = (listener) => listener !== listenerToRemove;
        this._events[name] = this._events[name].filter(filterListeners);
    }

    EthereumProvider.prototype.emit = function (name, data) {
        if (!this._events[name]) {
          return
        }
        this._events[name].forEach(cb => cb(data));
    }
    EthereumProvider.prototype.enable = function () {
        if (window.statusAppDebug) { console.log("enable"); }
        return sendAPIrequest('web3');
    };

    EthereumProvider.prototype.scanQRCode = function (regex) {
        return sendAPIrequest('qr-code', {regex: regex});
    };

    EthereumProvider.prototype.request = function (requestArguments)
    {
         if (window.statusAppDebug) { console.log("request: " + JSON.stringify(requestArguments)); }
         if (!requestArguments) {
           return new Error('Request is not valid.');
         }
         var method = requestArguments.method;

         if (!method) {
           return new Error('Request is not valid.');
         }

         //Support for legacy send method
         if (typeof method !== 'string') {
           return this.sendSync(method);
         }

         if (method == 'eth_requestAccounts'){
             return sendAPIrequest('web3');
         }

         var syncResponse = getSyncResponse({method: method});
         if (syncResponse){
             return new Promise(function (resolve, reject) {
                                        resolve(syncResponse.result);
                                    });
         }

         var messageId = callbackId++;
         var payload = {id:      messageId,
                        jsonrpc: "2.0",
                        method:  method,
                        params:  requestArguments.params};

         bridgeSend({type:      'web3-send-async-read-only',
                     messageId: messageId,
                     payload:   payload});

         return new Promise(function (resolve, reject) {
                                callbacks[messageId] = {beta:    true,
                                                        resolve: resolve,
                                                        reject:  reject};
                            });
    };

    // (DEPRECATED) Support for legacy send method
    EthereumProvider.prototype.send = function (method, params = [])
    {
        if (window.statusAppDebug) { console.log("send (legacy): " + method);}
        return this.request({method: method, params: params});
    }

    // (DEPRECATED) Support for legacy sendSync method
    EthereumProvider.prototype.sendSync = function (payload)
    {
        if (window.statusAppDebug) { console.log("sendSync (legacy)" + JSON.stringify(payload));}
        if (payload.method == "eth_uninstallFilter"){
            this.sendAsync(payload, function (res, err) {})
        }
        var syncResponse = getSyncResponse(payload);
        if (syncResponse){
            return syncResponse;
        } else {
            return web3Response(payload, null);
        }
    };

    // (DEPRECATED) Support for legacy sendAsync method
    EthereumProvider.prototype.sendAsync = function (payload, callback)
    {
      if (window.statusAppDebug) { console.log("sendAsync (legacy)" + JSON.stringify(payload));}
      if (!payload) {
          return new Error('Request is not valid.');
      }
      if (payload.method == 'eth_requestAccounts'){
          return sendAPIrequest('web3');
      }
      var syncResponse = getSyncResponse(payload);
      if (syncResponse && callback) {
          callback(null, syncResponse);
      }
      else
      {
          var messageId = callbackId++;

          if (Array.isArray(payload))
          {
              callbacks[messageId] = {num:      payload.length,
                                      results:  [],
                                      callback: callback};
              for (var i in payload) {
                  bridgeSend({type:      'web3-send-async-read-only',
                              messageId: messageId,
                              payload:   payload[i]});
              }
          }
          else
          {
              callbacks[messageId] = {callback: callback};
              bridgeSend({type:      'web3-send-async-read-only',
                          messageId: messageId,
                          payload:   payload});
          }
      }
    };
    }

    window.ethereum = new EthereumProvider();
})();
<commit_msg>[#12744] Issue using app.ens in browsee<commit_after>(function(){
    if(typeof EthereumProvider === "undefined"){
    var callbackId = 0;
    var callbacks = {};

    var bridgeSend = function (data) {
        ReactNativeWebView.postMessage(JSON.stringify(data));
    }

    var history = window.history;
    var pushState = history.pushState;
    history.pushState = function(state) {
        setTimeout(function () {
            bridgeSend({
               type: 'history-state-changed',
               navState: { url: location.href, title: document.title }
            });
        }, 100);
        return pushState.apply(history, arguments);
    };

    function sendAPIrequest(permission, params) {
        var messageId = callbackId++;
        var params = params || {};

        bridgeSend({
            type: 'api-request',
            permission: permission,
            messageId: messageId,
            params: params
        });

        return new Promise(function (resolve, reject) {
            params['resolve'] = resolve;
            params['reject'] = reject;
            callbacks[messageId] = params;
        });
    }

    function qrCodeResponse(data, callback){
        var result = data.data;
        var regex = new RegExp(callback.regex);
        if (!result) {
            if (callback.reject) {
                callback.reject(new Error("Cancelled"));
            }
        }
        else if (regex.test(result)) {
            if (callback.resolve) {
                callback.resolve(result);
            }
        } else {
            if (callback.reject) {
                callback.reject(new Error("Doesn't match"));
            }
        }
    }

    function Unauthorized() {
      this.name = "Unauthorized";
      this.id = 4100;
      this.code = 4100;
      this.message = "The requested method and/or account has not been authorized by the user.";
    }
    Unauthorized.prototype = Object.create(Error.prototype);

    function UserRejectedRequest() {
      this.name = "UserRejectedRequest";
      this.id = 4001;
      this.code = 4001;
      this.message = "The user rejected the request.";
    }
    UserRejectedRequest.prototype = Object.create(Error.prototype);
    ReactNativeWebView.onMessage = function (message)
    {
        data = JSON.parse(message);
        var id = data.messageId;
        var callback = callbacks[id];

        if (callback) {
            if (data.type === "api-response") {
                if (data.permission == 'qr-code'){
                    qrCodeResponse(data, callback);
                } else if (data.isAllowed) {
                    if (data.permission == 'web3') {
                        var selectedAddress = data.data[0]
                        window.statusAppcurrentAccountAddress = selectedAddress;
                        // Set deprecated metamask fields
                        window.ethereum.selectedAddress = selectedAddress;
                        window.ethereum.emit("accountsChanged", data.data);
                    }
                    callback.resolve(data.data);
                } else {
                    callback.reject(new UserRejectedRequest());
                }
            }
            else if (data.type === "web3-send-async-callback")
            {
                if (callback.beta)
                {
                    if (data.error)
                    {
                        if (data.error.code == 4100)
                            callback.reject(new Unauthorized());
                        else
                            callback.reject(data.error);
                    }
                    else
                    {
                        callback.resolve(data.result.result);
                    }
                }
                else if (callback.results)
                {
                    callback.results.push(data.error || data.result);
                    if (callback.results.length == callback.num)
                        callback.callback(undefined, callback.results);
                }
                else
                {
                    callback.callback(data.error, data.result);
                }
            }
        }
    };

    function web3Response (payload, result){
        return {id: payload.id,
                jsonrpc: "2.0",
                result: result};
    }

    function getSyncResponse (payload) {
        if (payload.method == "eth_accounts" && (typeof window.statusAppcurrentAccountAddress !== "undefined")) {
            return web3Response(payload, [window.statusAppcurrentAccountAddress])
        } else if (payload.method == "eth_coinbase" && (typeof window.statusAppcurrentAccountAddress !== "undefined")) {
            return web3Response(payload, window.statusAppcurrentAccountAddress)
        } else if (payload.method == "net_version"){
            return web3Response(payload, window.statusAppNetworkId)
        } else if (payload.method == "eth_chainId"){
            return web3Response(payload, "0x" + window.statusAppNetworkId.toString(16))
        } else if (payload.method == "eth_uninstallFilter"){
            return web3Response(payload, true);
        } else {
            return null;
        }
    }

    var StatusAPI = function () {};

    StatusAPI.prototype.getContactCode = function () {
        return sendAPIrequest('contact-code');
    };

    var EthereumProvider = function () {};

    EthereumProvider.prototype.isStatus = true;
    EthereumProvider.prototype.status = new StatusAPI();
    EthereumProvider.prototype.isConnected = function () { return true; };
    // Set legacy metamask fields https://docs.metamask.io/guide/ethereum-provider.html#legacy-api
    EthereumProvider.prototype.networkVersion = window.statusAppNetworkId;
    EthereumProvider.prototype.chainId = "0x" + window.statusAppNetworkId.toString(16);

    EthereumProvider.prototype._events = {};

    EthereumProvider.prototype.on = function(name, listener) {
        if (!this._events[name]) {
          this._events[name] = [];
        }
        this._events[name].push(listener);
    }

    EthereumProvider.prototype.removeListener = function (name, listenerToRemove) {
        if (!this._events[name]) {
          return
        }

        const filterListeners = (listener) => listener !== listenerToRemove;
        this._events[name] = this._events[name].filter(filterListeners);
    }

    EthereumProvider.prototype.removeAllListeners = function () {
        this._events = {};
    }

    EthereumProvider.prototype.emit = function (name, data) {
        if (!this._events[name]) {
          return
        }
        this._events[name].forEach(cb => cb(data));
    }
    EthereumProvider.prototype.enable = function () {
        if (window.statusAppDebug) { console.log("enable"); }
        return sendAPIrequest('web3');
    };

    EthereumProvider.prototype.scanQRCode = function (regex) {
        return sendAPIrequest('qr-code', {regex: regex});
    };

    EthereumProvider.prototype.request = function (requestArguments)
    {
         if (window.statusAppDebug) { console.log("request: " + JSON.stringify(requestArguments)); }
         if (!requestArguments) {
           return new Error('Request is not valid.');
         }
         var method = requestArguments.method;

         if (!method) {
           return new Error('Request is not valid.');
         }

         //Support for legacy send method
         if (typeof method !== 'string') {
           return this.sendSync(method);
         }

         if (method == 'eth_requestAccounts'){
             return sendAPIrequest('web3');
         }

         var syncResponse = getSyncResponse({method: method});
         if (syncResponse){
             return new Promise(function (resolve, reject) {
                                        resolve(syncResponse.result);
                                    });
         }

         var messageId = callbackId++;
         var payload = {id:      messageId,
                        jsonrpc: "2.0",
                        method:  method,
                        params:  requestArguments.params};

         bridgeSend({type:      'web3-send-async-read-only',
                     messageId: messageId,
                     payload:   payload});

         return new Promise(function (resolve, reject) {
                                callbacks[messageId] = {beta:    true,
                                                        resolve: resolve,
                                                        reject:  reject};
                            });
    };

    // (DEPRECATED) Support for legacy send method
    EthereumProvider.prototype.send = function (method, params = [])
    {
        if (window.statusAppDebug) { console.log("send (legacy): " + method);}
        return this.request({method: method, params: params});
    }

    // (DEPRECATED) Support for legacy sendSync method
    EthereumProvider.prototype.sendSync = function (payload)
    {
        if (window.statusAppDebug) { console.log("sendSync (legacy)" + JSON.stringify(payload));}
        if (payload.method == "eth_uninstallFilter"){
            this.sendAsync(payload, function (res, err) {})
        }
        var syncResponse = getSyncResponse(payload);
        if (syncResponse){
            return syncResponse;
        } else {
            return web3Response(payload, null);
        }
    };

    // (DEPRECATED) Support for legacy sendAsync method
    EthereumProvider.prototype.sendAsync = function (payload, callback)
    {
      if (window.statusAppDebug) { console.log("sendAsync (legacy)" + JSON.stringify(payload));}
      if (!payload) {
          return new Error('Request is not valid.');
      }
      if (payload.method == 'eth_requestAccounts'){
          return sendAPIrequest('web3');
      }
      var syncResponse = getSyncResponse(payload);
      if (syncResponse && callback) {
          callback(null, syncResponse);
      }
      else
      {
          var messageId = callbackId++;

          if (Array.isArray(payload))
          {
              callbacks[messageId] = {num:      payload.length,
                                      results:  [],
                                      callback: callback};
              for (var i in payload) {
                  bridgeSend({type:      'web3-send-async-read-only',
                              messageId: messageId,
                              payload:   payload[i]});
              }
          }
          else
          {
              callbacks[messageId] = {callback: callback};
              bridgeSend({type:      'web3-send-async-read-only',
                          messageId: messageId,
                          payload:   payload});
          }
      }
    };
    }

    window.ethereum = new EthereumProvider();
})();
<|endoftext|>


<commit_before>
var _data_list = [];

var partner_data = undefined;
var partner_profile = undefined;
var partner_limit = 5;

function fetchDataAndRenderContent () {
  _data_list.length = 0;
  renderCharts();
  extractDataAndUpdateContent();
}

function extractDataAndUpdateContent () {
  updateFetchProgress(100);

  renderOrUpdateGaugeRowItemsWithAnimation(extractGauageRowData());
  updateCharts(extractChartData());

  updateFetchCounter();
  updateFetchProgress(0);
}

function extractChartData (_limit) {
  _limit = _limit || 100;
  var _raw_list = _data_list.slice(-_limit);
  var _data_set = {};

  $.each(gauge_data, function (index, item) {
    var _list = [];
    $.each(_raw_list, function (index, record) {
      var _record = {};
      _record.date = $.format.date(record[item.id].time, 'yyyy-MM-dd HH:mm:ss');
      _record.value = _formatReadableFloat(record[item.id].value);
      _list.push(_record);
    });
    _data_set[item.id] = _list;
  });

  $.each(partner_data, function (index, item) {
    var _list = [];
    $.each(_raw_list, function (index, record) {
      var _record = {};
      _record.date = $.format.date(record[item.parent_id].time, 'yyyy-MM-dd HH:mm:ss');
      var _base_value = record[item.parent_id].value;
      for (var i = 0; i < partner_limit; i++) {
        _record["value" + i] = _formatReadableFloat(_base_value * 0.15 * (1 + (Math.random() - 0.35) * (partner_limit - i) / (partner_limit) ));
      };
      _list.push(_record);
    });
    _data_set[item.id] = _list;
  });

  return _data_set;
}

function extractGauageRowData () {
  if (!_data_list.length) {
    fetchMockupData();
  }
  var _set = _data_list.slice(-1)[0];
  var _data = $.extend(true, {}, gauge_data);
  $.each(_data, function (index, item) {
    item.time = _set[item.id].time;
    item.value = _set[item.id].value;
  });
  return _data;
}

function initializePartnersForCharts () {
  partner_profile = fetchMockupTopPartnersProfile(partner_limit);

  partner_data = $.extend(true, [], gauge_data);
  $.each(partner_data, function (index, label_data) {
    label_data.name = "Top Partners - " + label_data.name;
    label_data.parent_id = label_data.id;
    label_data.id += "-part";
  });
}

function fetchMockupTopPartnersProfile (_limit) {
  _limit = _limit || 5;
  var _list = flattenConfigIntoList(menu_part_data);
  _list.sort(function () { return 0.5 - Math.random() });
  return _list.slice(-_limit);
}

function fetchMockupData () {
  var _set = {};
  var _date = new Date();
  var _last_set = _data_list.length ? _data_list.slice(-1)[0] : undefined;
  $.each(gauge_data, function (index, item) {
    var _item = {};
    _item.time = _date;
    _item.value = _last_set ? _last_set[item.id].value : item.value;
    _item.value *= (1 + (Math.random() - 0.5) * 0.1);
    _set[item.id] = _item;
  });
  _data_list.push(_set);
}
<commit_msg>Adjust algorithm for mockup partner data -- not fully random, scalable<commit_after>
var _data_list = [];

var partner_data = undefined;
var partner_profile = undefined;
var partner_limit = 5;

function fetchDataAndRenderContent () {
  _data_list.length = 0;
  renderCharts();
  extractDataAndUpdateContent();
}

function extractDataAndUpdateContent () {
  updateFetchProgress(100);

  renderOrUpdateGaugeRowItemsWithAnimation(extractGauageRowData());
  updateCharts(extractChartData());

  updateFetchCounter();
  updateFetchProgress(0);
}

function extractChartData (_limit) {
  _limit = _limit || 100;
  var _raw_list = _data_list.slice(-_limit);
  var _data_set = {};

  $.each(gauge_data, function (index, item) {
    var _list = [];
    $.each(_raw_list, function (index, record) {
      var _record = {};
      _record.date = $.format.date(record[item.id].time, 'yyyy-MM-dd HH:mm:ss');
      _record.value = _formatReadableFloat(record[item.id].value);
      _list.push(_record);
    });
    _data_set[item.id] = _list;
  });

  $.each(partner_data, function (index, item) {
    var _list = [];
    $.each(_raw_list, function (index, record) {
      var _record = {};
      _record.date = $.format.date(record[item.parent_id].time, 'yyyy-MM-dd HH:mm:ss');
      var _base_value = record[item.parent_id].value;
      for (var i = 0; i < partner_limit; i++) {
        _record["value" + i] = _formatReadableFloat(_base_value * 0.17 * (2 * partner_limit - i) / (2 * partner_limit) );
      };
      _list.push(_record);
    });
    _data_set[item.id] = _list;
  });

  return _data_set;
}

function extractGauageRowData () {
  if (!_data_list.length) {
    fetchMockupData();
  }
  var _set = _data_list.slice(-1)[0];
  var _data = $.extend(true, {}, gauge_data);
  $.each(_data, function (index, item) {
    item.time = _set[item.id].time;
    item.value = _set[item.id].value;
  });
  return _data;
}

function initializePartnersForCharts () {
  partner_profile = fetchMockupTopPartnersProfile(partner_limit);

  partner_data = $.extend(true, [], gauge_data);
  $.each(partner_data, function (index, label_data) {
    label_data.name = "Top Partners - " + label_data.name;
    label_data.parent_id = label_data.id;
    label_data.id += "-part";
  });
}

function fetchMockupTopPartnersProfile (_limit) {
  _limit = _limit || 5;
  var _list = flattenConfigIntoList(menu_part_data);
  _list.sort(function () { return 0.5 - Math.random() });
  return _list.slice(-_limit);
}

function fetchMockupData () {
  var _set = {};
  var _date = new Date();
  var _last_set = _data_list.length ? _data_list.slice(-1)[0] : undefined;
  $.each(gauge_data, function (index, item) {
    var _item = {};
    _item.time = _date;
    _item.value = _last_set ? _last_set[item.id].value : item.value;
    _item.value *= (1 + (Math.random() - 0.5) * 0.1);
    _set[item.id] = _item;
  });
  _data_list.push(_set);
}
<|endoftext|>


<commit_before>"use strict";
VSettings.checkIfEnabled = function() {
  mainPort.safePost({
    handler: "checkIfEnabled",
    url: window.location.href
  });
};

DomUtils.documentReady(function() {
  if (MainPort.safePost({ handler: "reg", visible: true })) {
    return;
  }
  addEventListener("hashchange", VSettings.checkIfEnabled);
  VEventMode.onWndFocus(MainPort.safePost.bind(MainPort, {
    handler: "frameFocused"
  }, function() {
    setTimeout(function() {
      if (MainPort && !MainPort.port) {
        VSettings.destroy();
      }
    }, 50);
  }));
});

if (chrome.runtime.onMessageExternal) {
  VimiumInjector.alive = 1;
} else {
  VimiumInjector.alive = 0.5;
  console.log("%cVimium++%c: injected %cpartly%c into %c" + chrome.runtime.id
    , "color: red;", "color: auto;"
    , "color: red;", "color: auto;", "color: blue;");
}

VSettings.onDestroy = function() {
  removeEventListener("hashchange", VSettings.checkIfEnabled);
  if (MainPort.port) {
    try {
      MainPort.port.disconnect();
    } catch (e) {}
  }
  EventTarget.removeVimiumHooks && EventTarget.removeVimiumHooks();
  var injector = VimiumInjector;
  injector.alive = 0;
  injector.destroy = null;
  [].forEach.call(document.querySelectorAll(
  'script[src^="chrome-extension://hfjbmagddngcpeloejdejnfgbamkjaeg/"]'
  ), function(node) { node.remove(); });
};

VimiumInjector.destroy = VSettings.destroy;
<commit_msg>fix a typo of char case<commit_after>"use strict";
VSettings.checkIfEnabled = function() {
  MainPort.safePost({
    handler: "checkIfEnabled",
    url: window.location.href
  });
};

DomUtils.documentReady(function() {
  if (MainPort.safePost({ handler: "reg", visible: true })) {
    return;
  }
  addEventListener("hashchange", VSettings.checkIfEnabled);
  VEventMode.onWndFocus(MainPort.safePost.bind(MainPort, {
    handler: "frameFocused"
  }, function() {
    setTimeout(function() {
      if (MainPort && !MainPort.port) {
        VSettings.destroy();
      }
    }, 50);
  }));
});

if (chrome.runtime.onMessageExternal) {
  VimiumInjector.alive = 1;
} else {
  VimiumInjector.alive = 0.5;
  console.log("%cVimium++%c: injected %cpartly%c into %c" + chrome.runtime.id
    , "color: red;", "color: auto;"
    , "color: red;", "color: auto;", "color: blue;");
}

VSettings.onDestroy = function() {
  removeEventListener("hashchange", VSettings.checkIfEnabled);
  if (MainPort.port) {
    try {
      MainPort.port.disconnect();
    } catch (e) {}
  }
  EventTarget.removeVimiumHooks && EventTarget.removeVimiumHooks();
  var injector = VimiumInjector;
  injector.alive = 0;
  injector.destroy = null;
  [].forEach.call(document.querySelectorAll(
  'script[src^="chrome-extension://hfjbmagddngcpeloejdejnfgbamkjaeg/"]'
  ), function(node) { node.remove(); });
};

VimiumInjector.destroy = VSettings.destroy;
<|endoftext|>


<commit_before>
///////////////////////////////////

var PloverLearnQuiz = function(fields) {
	this.fields = fields;
	this.index = 0;
};

PloverLearnQuiz.prototype.title = function() {
	return this.fields['title'];
};

PloverLearnQuiz.prototype.subtitle = function() {
	return this.fields['subtitle'];
};

PloverLearnQuiz.prototype.currentQuestion = function() {
	return this.fields['questions'][this.index][0];
};

PloverLearnQuiz.prototype.currentHint = function() {
	return this.fields['questions'][this.index][1];
};

PloverLearnQuiz.prototype.answerMatches = function(answer) {
	var question = this.currentQuestion();

	return answer.toLowerCase() == question.toLowerCase();
};

PloverLearnQuiz.prototype.isLastQuestion = function() {
	return this.index == this.fields['questions'].length-1;
};

PloverLearnQuiz.prototype.moveToNextQuestion = function() {
	if (this.isLastQuestion()) {
		this.index = 0;
	} else {
		this.index++;
	}
};

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

var PloverLearnGame = function(fields) {

	this.quiz = new PloverLearnQuiz(fields);
	this.title = '';
	this.subtitle = '';
	this.buffer = '';
	this.strokeTimerID = 0;
	this.metricsDisplayTimerID = 0;

	this.gameStartTime = 0;
	this.wordCount = 0;
	this.previousStrokeWasGood = true;

	this.misstrokesThisQuestion = 0;
};

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

var STROKE_FINISHED_TIMEOUT = 30; // ms
var METRICS_DISPLAY_INTERVAL = 500; // ms
var HINT_OFFER_TIMES = 2;
var HINT_TEXT = '(hint?)';

PloverLearnGame.prototype.displayNextQuestion = function() {

	if (this.quiz.isLastQuestion()) {
		this.endGame();
	} else {
		this.quiz.moveToNextQuestion();

		$("#question").text(this.quiz.currentQuestion())
		$("#answer").text('');
		$("#hint").text('');

		this.buffer = '';
		this.misstrokesThisQuestion = 0;
	}
};

PloverLearnGame.prototype.displayMetrics = function() {

	var msElapsed = (new Date().getTime()) - this.gameStartTime;
	var gameClockMinutes = Math.floor(msElapsed/60000);
	var gameClockSeconds = Math.floor(msElapsed/1000)%60;
	var gameClock = gameClockMinutes+':';
	if (gameClockSeconds<10) {
		gameClock += '0';
	}
	gameClock += gameClockSeconds;

	$("#time").text(gameClock);
	$("#wpm").text(Math.floor(wordCount / (msElapsed/60000)));
	$("#misstrokes").text(this.misstrokes);
	$("#laststreak").text(this.lastStreak);
	$("#beststreak").text(this.bestStreak);
};

// XXX problem here: does a streak include
// all strokes that make a correct word?
// Because then you'd get extra marks for fingerspelling everything.

PloverLearnGame.prototype.logGoodStroke = function() {

	if (this.previousStrokeWasGood) {
		this.lastStreak++;
	} else {
		// we're starting a new good streak
		this.lastStreak = 1;
	}

	if (this.bestStreak < this.lastStreak) {
		this.bestStreak = this.lastStreak;
	}

	this.previousStrokeWasGood = true;
};

PloverLearnGame.prototype.logMisstroke = function() {

	this.misstrokes++;
	this.misstrokesThisQuestion++;

	if (this.misstrokesThisQuestion >= HINT_OFFER_TIMES &&
		$("#hint").text()=='') {

		$("#hint").text(this.quiz.currentText());
	}

	this.previousStrokeWasGood = false;
};

PloverLearnGame.prototype.strokeFinished = function() {

	// XXX this needs a rethink,
	// because at present if you enter
	// two misstrokes and then delete one,
	// you get another misstroke for that.

	$("#answer").text(this.buffer.slice(-40));

	var question = $("#question").text()

// XXX this isn't going to work until we've fixed
// PloverLearnQuiz.answerMatches() to check for partial
// matches as well. Come back to it then.

	if (buffer==question) {
		// correct!

		logGoodStroke();

		wordCount += question.split(' ').length;
		displayNextQuestion();
	} else if (question.indexOf(buffer)==0) {
		// partial match
		logGoodStroke();
	} else if (buffer!='') {
		// misstroke
		logMisstroke();
	}
};

PloverLearnGame.prototype.startGame = function() {
	this.displayNextQuestion();
	$("body").addClass("playing");

	this.gameStartTime = new Date().getTime();
	this.wordCount = 0;
	this.misstrokes = 0;
	this.previousStrokeWasGood = true;
	this.lastStreak = 0;
	this.bestStreak = 0;
	this.metricsDisplayTimerID = window.setInterval(this.displayMetrics, METRICS_DISPLAY_INTERVAL);
};

PloverLearnGame.prototype.endGame = function() {
	this.displayMetrics();
	window.clearInterval(this.metricsDisplayTimerID);
	$("body").removeClass("playing");
};

PloverLearnGame.prototype.initialSetup = function() {

	$(document).keypress(function(event) {

		if (!$("body").hasClass("playing")) {
			this.startGame();
		} else {

			if (event.which==8) {
				// Backspace
				this.buffer = this.buffer.slice(0, -1);
			} else if (event.which==13) {
				// Return: erase buffer
				this.buffer = '';
			} else if (event.which>=32 && event.which<=126) {
				// Character input.
				this.buffer += String.fromCharCode(event.which);
			}

			window.clearTimeout(this.strokeTimerID);
			this.strokeTimerID = window.setTimeout(this.strokeFinished, STROKE_FINISHED_TIMEOUT);
		}
	});

	$("#splash").mousedown(function(event) {
		this.startGame();
	});

	$("#hint").mousedown(function(event) {
		$("#hint").text(this.quiz.hint());
	});

	$("#title").text(this.quiz.title());
	$("#subtitle").text(this.quiz.subtitle());
};

function ploverlearn(fields) {

	var game = new PloverLearnGame(fields);

	$( ploverLearn.initialSetup );

}
<commit_msg>doc comment for answerMatches()<commit_after>
///////////////////////////////////

var PloverLearnQuiz = function(fields) {
	this.fields = fields;
	this.index = 0;
};

PloverLearnQuiz.prototype.title = function() {
	return this.fields['title'];
};

PloverLearnQuiz.prototype.subtitle = function() {
	return this.fields['subtitle'];
};

PloverLearnQuiz.prototype.currentQuestion = function() {
	return this.fields['questions'][this.index][0];
};

PloverLearnQuiz.prototype.currentHint = function() {
	return this.fields['questions'][this.index][1];
};

// Returns whether the given answer matches the question,
// according to the current setup. (For example, case might
// or might not be significant, based on the flags.)
//
// Return values:
//   - 0: this is not a match
//   - "complete": this is a perfect match
//                    (the entire string matches)
//   - "partial": this is a partial match
//                    (it's partway to a complete match)
//
// For example, suppose the current rules mean an answer
// matches iff it's identical to the question, and that the
// question is "plover". Then:
//
//    ""       -> "partial"
//    "plov"   -> "partial"
//    "plover" -> "complete"
//    "xyzzy"  -> 0

PloverLearnQuiz.prototype.answerMatches = function(answer) {
	var question = this.currentQuestion();

	return answer.toLowerCase() == question.toLowerCase();
};

PloverLearnQuiz.prototype.isLastQuestion = function() {
	return this.index == this.fields['questions'].length-1;
};

PloverLearnQuiz.prototype.moveToNextQuestion = function() {
	if (this.isLastQuestion()) {
		this.index = 0;
	} else {
		this.index++;
	}
};

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

var PloverLearnGame = function(fields) {

	this.quiz = new PloverLearnQuiz(fields);
	this.title = '';
	this.subtitle = '';
	this.buffer = '';
	this.strokeTimerID = 0;
	this.metricsDisplayTimerID = 0;

	this.gameStartTime = 0;
	this.wordCount = 0;
	this.previousStrokeWasGood = true;

	this.misstrokesThisQuestion = 0;
};

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

var STROKE_FINISHED_TIMEOUT = 30; // ms
var METRICS_DISPLAY_INTERVAL = 500; // ms
var HINT_OFFER_TIMES = 2;
var HINT_TEXT = '(hint?)';

PloverLearnGame.prototype.displayNextQuestion = function() {

	if (this.quiz.isLastQuestion()) {
		this.endGame();
	} else {
		this.quiz.moveToNextQuestion();

		$("#question").text(this.quiz.currentQuestion())
		$("#answer").text('');
		$("#hint").text('');

		this.buffer = '';
		this.misstrokesThisQuestion = 0;
	}
};

PloverLearnGame.prototype.displayMetrics = function() {

	var msElapsed = (new Date().getTime()) - this.gameStartTime;
	var gameClockMinutes = Math.floor(msElapsed/60000);
	var gameClockSeconds = Math.floor(msElapsed/1000)%60;
	var gameClock = gameClockMinutes+':';
	if (gameClockSeconds<10) {
		gameClock += '0';
	}
	gameClock += gameClockSeconds;

	$("#time").text(gameClock);
	$("#wpm").text(Math.floor(wordCount / (msElapsed/60000)));
	$("#misstrokes").text(this.misstrokes);
	$("#laststreak").text(this.lastStreak);
	$("#beststreak").text(this.bestStreak);
};

// XXX problem here: does a streak include
// all strokes that make a correct word?
// Because then you'd get extra marks for fingerspelling everything.

PloverLearnGame.prototype.logGoodStroke = function() {

	if (this.previousStrokeWasGood) {
		this.lastStreak++;
	} else {
		// we're starting a new good streak
		this.lastStreak = 1;
	}

	if (this.bestStreak < this.lastStreak) {
		this.bestStreak = this.lastStreak;
	}

	this.previousStrokeWasGood = true;
};

PloverLearnGame.prototype.logMisstroke = function() {

	this.misstrokes++;
	this.misstrokesThisQuestion++;

	if (this.misstrokesThisQuestion >= HINT_OFFER_TIMES &&
		$("#hint").text()=='') {

		$("#hint").text(this.quiz.currentText());
	}

	this.previousStrokeWasGood = false;
};

PloverLearnGame.prototype.strokeFinished = function() {

	// XXX this needs a rethink,
	// because at present if you enter
	// two misstrokes and then delete one,
	// you get another misstroke for that.

	$("#answer").text(this.buffer.slice(-40));

	var question = $("#question").text()

// XXX this isn't going to work until we've fixed
// PloverLearnQuiz.answerMatches() to check for partial
// matches as well. Come back to it then.

	if (buffer==question) {
		// correct!

		logGoodStroke();

		wordCount += question.split(' ').length;
		displayNextQuestion();
	} else if (question.indexOf(buffer)==0) {
		// partial match
		logGoodStroke();
	} else if (buffer!='') {
		// misstroke
		logMisstroke();
	}
};

PloverLearnGame.prototype.startGame = function() {
	this.displayNextQuestion();
	$("body").addClass("playing");

	this.gameStartTime = new Date().getTime();
	this.wordCount = 0;
	this.misstrokes = 0;
	this.previousStrokeWasGood = true;
	this.lastStreak = 0;
	this.bestStreak = 0;
	this.metricsDisplayTimerID = window.setInterval(this.displayMetrics, METRICS_DISPLAY_INTERVAL);
};

PloverLearnGame.prototype.endGame = function() {
	this.displayMetrics();
	window.clearInterval(this.metricsDisplayTimerID);
	$("body").removeClass("playing");
};

PloverLearnGame.prototype.initialSetup = function() {

	$(document).keypress(function(event) {

		if (!$("body").hasClass("playing")) {
			this.startGame();
		} else {

			if (event.which==8) {
				// Backspace
				this.buffer = this.buffer.slice(0, -1);
			} else if (event.which==13) {
				// Return: erase buffer
				this.buffer = '';
			} else if (event.which>=32 && event.which<=126) {
				// Character input.
				this.buffer += String.fromCharCode(event.which);
			}

			window.clearTimeout(this.strokeTimerID);
			this.strokeTimerID = window.setTimeout(this.strokeFinished, STROKE_FINISHED_TIMEOUT);
		}
	});

	$("#splash").mousedown(function(event) {
		this.startGame();
	});

	$("#hint").mousedown(function(event) {
		$("#hint").text(this.quiz.hint());
	});

	$("#title").text(this.quiz.title());
	$("#subtitle").text(this.quiz.subtitle());
};

function ploverlearn(fields) {

	var game = new PloverLearnGame(fields);

	$( ploverLearn.initialSetup );

}
<|endoftext|>


<commit_before>(function(){var q=function(){function c(a){return(""+a).replace(/&(?!\w+;)|[<>"']/g,function(a){return k[a]||a})}var e=Object.prototype.toString;Array.isArray=Array.isArray||function(a){return"[object Array]"==e.call(a)};var i=String.prototype.trim,g;if(i)g=function(a){return null==a?"":i.call(a)};else{var h,m;/\S/.test("\u00a0")?(h=/^[\s\xA0]+/,m=/[\s\xA0]+$/):(h=/^\s+/,m=/\s+$/);g=function(a){return null==a?"":a.toString().replace(h,"").replace(m,"")}}var k={"&":"&","<":"<",">":">",'"':""",
"'":"'"},o={},p=function(){};p.prototype={otag:"{{",ctag:"}}",pragmas:{},buffer:[],pragmas_implemented:{"IMPLICIT-ITERATOR":!0},context:{},render:function(a,d,b,f){if(!f)this.context=d,this.buffer=[];if(this.includes("",a)){var a=this.render_pragmas(a),j=this.render_section(a,d,b);!1===j&&(j=this.render_tags(a,d,b,f));if(f)return j;this.sendLines(j)}else{if(f)return a;this.send(a)}},send:function(a){""!==a&&this.buffer.push(a)},sendLines:function(a){if(a)for(var a=a.split("\n"),d=0;d<a.length;d++)this.send(a[d])},
render_pragmas:function(a){if(!this.includes("%",a))return a;var d=this,b=this.getCachedRegex("render_pragmas",function(a,d){return RegExp(a+"%([\\w-]+) ?([\\w]+=[\\w]+)?"+d,"g")});return a.replace(b,function(a,b,e){if(!d.pragmas_implemented[b])throw{message:"This implementation of mustache doesn't understand the '"+b+"' pragma"};d.pragmas[b]={};e&&(a=e.split("="),d.pragmas[b][a[0]]=a[1]);return""})},render_partial:function(a,d,b){a=g(a);if(!b||void 0===b[a])throw{message:"unknown_partial '"+a+"'"};
return!d||"object"!=typeof d[a]?this.render(b[a],d,b,!0):this.render(b[a],d[a],b,!0)},render_section:function(a,d,b){if(!this.includes("#",a)&&!this.includes("^",a))return!1;var f=this,j=this.getCachedRegex("render_section",function(a,b){return RegExp("^([\\s\\S]*?)"+a+"(\\^|\\#)\\s*(.+)\\s*"+b+"\n*([\\s\\S]*?)"+a+"\\/\\s*\\3\\s*"+b+"\\s*([\\s\\S]*)$","g")});return a.replace(j,function(a,j,e,c,g,h){var a=j?f.render_tags(j,d,b,!0):"",h=h?f.render(h,d,b,!0):"",n,c=f.find(c,d);"^"===e?n=!c||Array.isArray(c)&&
0===c.length?f.render(g,d,b,!0):"":"#"===e&&(n=Array.isArray(c)?f.map(c,function(a){return f.render(g,f.create_context(a),b,!0)}).join(""):f.is_object(c)?f.render(g,f.create_context(c),b,!0):"function"==typeof c?c.call(d,g,function(a){return f.render(a,d,b,!0)}):c?f.render(g,d,b,!0):"");return a+n+h})},render_tags:function(a,d,b,f){for(var j=this,e=function(){return j.getCachedRegex("render_tags",function(a,b){return RegExp(a+"(=|!|>|&|\\{|%)?([^#\\^]+?)\\1?"+b+"+","g")})},g=e(),h=function(a,f,h){switch(f){case "!":return"";
case "=":return j.set_delimiters(h),g=e(),"";case ">":return j.render_partial(h,d,b);case "{":case "&":return j.find(h,d);default:return c(j.find(h,d))}},a=a.split("\n"),i=0;i<a.length;i++)a[i]=a[i].replace(g,h,this),f||this.send(a[i]);if(f)return a.join("\n")},set_delimiters:function(a){a=a.split(" ");this.otag=this.escape_regex(a[0]);this.ctag=this.escape_regex(a[1])},escape_regex:function(a){if(!arguments.callee.sRE)arguments.callee.sRE=RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\)",
"g");return a.replace(arguments.callee.sRE,"\\$1")},find:function(a,d){function b(a){return!1===a||0===a||a}var a=g(a),f;if(a.match(/([a-z_]+)\./ig)){var c=this.walk_context(a,d);b(c)&&(f=c)}else b(d[a])?f=d[a]:b(this.context[a])&&(f=this.context[a]);return"function"==typeof f?f.apply(d):void 0!==f?f:""},walk_context:function(a,d){for(var b=a.split("."),f=void 0!=d[b[0]]?d:this.context,c=f[b.shift()];void 0!=c&&0<b.length;)f=c,c=c[b.shift()];return"function"==typeof c?c.apply(f):c},includes:function(a,
d){return-1!=d.indexOf(this.otag+a)},create_context:function(a){if(this.is_object(a))return a;var d=".";if(this.pragmas["IMPLICIT-ITERATOR"])d=this.pragmas["IMPLICIT-ITERATOR"].iterator;var b={};b[d]=a;return b},is_object:function(a){return a&&"object"==typeof a},map:function(a,d){if("function"==typeof a.map)return a.map(d);for(var b=[],c=a.length,e=0;e<c;e++)b.push(d(a[e]));return b},getCachedRegex:function(a,d){var b=o[this.otag];b||(b=o[this.otag]={});var c=b[this.ctag];c||(c=b[this.ctag]={});
(b=c[a])||(b=c[a]=d(this.otag,this.ctag));return b}};return{name:"mustache.js",version:"0.4.0",to_html:function(a,c,b,f){var e=new p;if(f)e.send=f;e.render(a,c||{},b);if(!f)return e.buffer.join("\n")}}}();(function(){var c={VERSION:"0.10",templates:{},$:"undefined"!==typeof window?window.jQuery||window.Zepto||null:null,addTemplate:function(e,i){if("object"===typeof e)for(var g in e)this.addTemplate(g,e[g]);else c[e]?console.error("Invalid name: "+e+"."):c.templates[e]?console.error('Template "'+e+
'  " exists'):(c.templates[e]=i,c[e]=function(g,i){var g=g||{},k=q.to_html(c.templates[e],g,c.templates);return c.$&&!i?c.$(k):k})},clearAll:function(){for(var e in c.templates)delete c[e];c.templates={}},refresh:function(){c.clearAll();c.grabTemplates()},grabTemplates:function(){var e,i=document.getElementsByTagName("script"),g,h=[];for(e=0,l=i.length;e<l;e++)if((g=i[e])&&g.innerHTML&&g.id&&("text/html"===g.type||"text/x-icanhaz"===g.type))c.addTemplate(g.id,"".trim?g.innerHTML.trim():g.innerHTML.replace(/^\s+/,
"").replace(/\s+$/,"")),h.unshift(g);for(e=0,l=h.length;e<l;e++)h[e].parentNode.removeChild(h[e])}};"undefined"!==typeof require?module.exports=c:window.ich=c;"undefined"!==typeof document&&(c.$?c.$(function(){c.grabTemplates()}):document.addEventListener("DOMContentLoaded",function(){c.grabTemplates()},!0))})()})();
<commit_msg>Remove ICanHaz.js<commit_after><|endoftext|>


<commit_before>import React from 'react'
import '../../assets/stylesheets/application.css';
import { WhitelistInputBlock } from './WhitelistInputBlock'
import { defaultCompanyEndDate } from '../../utils/utils'
import { InputField } from './InputField'
import { RadioInputField } from './RadioInputField'
import { inject, observer } from 'mobx-react'
import { VALIDATION_MESSAGES, VALIDATION_TYPES, TEXT_FIELDS } from '../../utils/constants'
const { EMPTY, VALID, INVALID } = VALIDATION_TYPES
const { START_TIME, END_TIME, RATE, SUPPLY, CROWDSALE_SETUP_NAME, ALLOWMODIFYING } = TEXT_FIELDS

@inject('tierStore')
@observer
export class CrowdsaleBlock extends React.Component {
  componentDidMount () {
    const { tierStore, num } = this.props
    const startTime = tierStore.tiers[num - 1].endTime
    const endTime = defaultCompanyEndDate(tierStore.tiers[num-1].startTime)
    tierStore.setTierProperty(startTime, 'startTime', num)
    tierStore.setTierProperty(endTime, 'endTime', num)
  }

  changeState = (event, parent, key, property) => {
    if (property.indexOf("whitelist_") === 0) {
      const { tierStore } = this.props
      const whitelistInputProps = { ...tierStore.tiers[key].whitelistInput }
      const prop = property.split("_")[1]

      whitelistInputProps[prop] = event.target.value
      tierStore.setTierProperty(whitelistInputProps, 'whitelistInput', key)
    }
  }

  updateTierStore = (event, property) => {
    const { tierStore, num } = this.props
    const value = event.target.value;
    tierStore.setTierProperty(value, property, num);
    tierStore.validateTiers(property, num)
  }

  render() {
    let { num, tierStore } = this.props
    let whitelistInputBlock =

Whitelist

        <WhitelistInputBlock
          num = {num}
          onChange={(e, cntrct, num, prop) => this.changeState(e, cntrct, num, prop)}
        ></WhitelistInputBlock>

    return (

          <InputField
            side='left'
            type='text'
            title={CROWDSALE_SETUP_NAME}
            value={tierStore.tiers[num].tier}
            valid={tierStore.validTiers[num].tier}
            errorMessage={VALIDATION_MESSAGES.TIER}
            onChange={(e) => this.updateTierStore(e, 'name')}
            description={`Name of a tier, e.g. PrePreIco, PreICO, ICO with bonus A, ICO with bonus B, etc. We simplified that and will increment a number after each tier.`}
          />
          <InputField
            side='right'
            type='number'
            title={RATE}
            value={tierStore.tiers[num].rate}
            valid={tierStore.validTiers[num].rate}
            errorMessage={VALIDATION_MESSAGES.RATE}
            onChange={(e) => this.updateTierStore(e,'rate')}
            description={`Exchange rate Ethereum to Tokens. If it's 100, then for 1 Ether you can buy 100 tokens`}
          />

          <InputField
            side='left'
            type='datetime-local'
            title={START_TIME}
            value={tierStore.tiers[num].startTimeTemp}
            valid={tierStore.validTiers[num].startTime}
            errorMessage={VALIDATION_MESSAGES.START_TIME}
            defaultValue={tierStore.tiers[num - 1].startTime}
            onChange={(e) => this.updateTierStore(e, 'startTime')}
            description={`Date and time when the tier starts. Can't be in the past from the current moment.`}
          />
          <InputField
            side='right'
            type='datetime-local'
            title={END_TIME}
            value={tierStore.tiers[num].endTimeTemp}
            valid={tierStore.validTiers[num].endTime}
            errorMessage={VALIDATION_MESSAGES.END_TIME}
            defaultValue={defaultCompanyEndDate(tierStore.tiers[num-1].endTime)}
            onChange={(e) => this.updateTierStore(e, 'endTime')}
            description={`Date and time when the tier ends. Can be only in the future.`}
          />

          <InputField
            side='left'
            type='number'
            title={SUPPLY}
            value={tierStore.tiers[num].supply}
            valid={tierStore.validTiers[num].supply}
            errorMessage={VALIDATION_MESSAGES.SUPPLY}
            onChange={(e) => this.updateTierStore(e, 'supply')}
            description={`How many tokens will be sold on this tier. Cap of crowdsale equals to sum of supply of all tiers`}
          />
          <RadioInputField
            side='right'
            title={ALLOWMODIFYING}
            items={["on", "off"]}
            vals={["on", "off"]}
            num={num}
            defaultValue={this.props.tierStore.tiers[num].updatable}
            name={'crowdsale-updatable-' + num}
            onChange={(e) => this.updateTierStore(e, 'updatable')}
            description={`Pandora box feature. If it's enabled, a creator of the crowdsale can modify Start time, End time, Rate, Limit after publishing.`}
          />

        {tierStore.tiers[0].whitelistdisabled === "yes"?"":whitelistInputBlock}

)
  }
}
<commit_msg>Fix Start/End Time for multiple Tiers<commit_after>import React from 'react'
import '../../assets/stylesheets/application.css';
import { WhitelistInputBlock } from './WhitelistInputBlock'
import { defaultCompanyEndDate } from '../../utils/utils'
import { InputField } from './InputField'
import { RadioInputField } from './RadioInputField'
import { inject, observer } from 'mobx-react'
import { VALIDATION_MESSAGES, VALIDATION_TYPES, TEXT_FIELDS } from '../../utils/constants'
const { EMPTY, VALID, INVALID } = VALIDATION_TYPES
const { START_TIME, END_TIME, RATE, SUPPLY, CROWDSALE_SETUP_NAME, ALLOWMODIFYING } = TEXT_FIELDS

@inject('tierStore')
@observer
export class CrowdsaleBlock extends React.Component {
  componentWillMount() {
    const { tierStore, num } = this.props
    const startTime = tierStore.tiers[num - 1].endTime
    const endTime = defaultCompanyEndDate(tierStore.tiers[num - 1].endTime)
    tierStore.setTierProperty(startTime, 'startTime', num)
    tierStore.setTierProperty(endTime, 'endTime', num)
  }
  changeState = (event, parent, key, property) => {
    if (property.indexOf("whitelist_") === 0) {
      const { tierStore } = this.props
      const whitelistInputProps = { ...tierStore.tiers[key].whitelistInput }
      const prop = property.split("_")[1]

      whitelistInputProps[prop] = event.target.value
      tierStore.setTierProperty(whitelistInputProps, 'whitelistInput', key)
    }
  }

  updateTierStore = (event, property) => {
    const { tierStore, num } = this.props
    const value = event.target.value;
    tierStore.setTierProperty(value, property, num);
    tierStore.validateTiers(property, num)
  }

  render() {
    let { num, tierStore } = this.props
    let whitelistInputBlock =

Whitelist

        <WhitelistInputBlock
          num = {num}
          onChange={(e, cntrct, num, prop) => this.changeState(e, cntrct, num, prop)}
        ></WhitelistInputBlock>

    return (

          <InputField
            side='left'
            type='text'
            title={CROWDSALE_SETUP_NAME}
            value={tierStore.tiers[num].tier}
            valid={tierStore.validTiers[num].tier}
            errorMessage={VALIDATION_MESSAGES.TIER}
            onChange={(e) => this.updateTierStore(e, 'name')}
            description={`Name of a tier, e.g. PrePreIco, PreICO, ICO with bonus A, ICO with bonus B, etc. We simplified that and will increment a number after each tier.`}
          />
          <InputField
            side='right'
            type='number'
            title={RATE}
            value={tierStore.tiers[num].rate}
            valid={tierStore.validTiers[num].rate}
            errorMessage={VALIDATION_MESSAGES.RATE}
            onChange={(e) => this.updateTierStore(e,'rate')}
            description={`Exchange rate Ethereum to Tokens. If it's 100, then for 1 Ether you can buy 100 tokens`}
          />

          <InputField
            side='left'
            type='datetime-local'
            title={START_TIME}
            value={tierStore.tiers[num].startTimeTemp}
            valid={tierStore.validTiers[num].startTime}
            errorMessage={VALIDATION_MESSAGES.START_TIME}
            defaultValue={tierStore.tiers[num].startTime}
            onChange={(e) => this.updateTierStore(e, 'startTime')}
            description={`Date and time when the tier starts. Can't be in the past from the current moment.`}
          />
          <InputField
            side='right'
            type='datetime-local'
            title={END_TIME}
            value={tierStore.tiers[num].endTimeTemp}
            valid={tierStore.validTiers[num].endTime}
            errorMessage={VALIDATION_MESSAGES.END_TIME}
            defaultValue={tierStore.tiers[num].endTime}
            onChange={(e) => this.updateTierStore(e, 'endTime')}
            description={`Date and time when the tier ends. Can be only in the future.`}
          />

          <InputField
            side='left'
            type='number'
            title={SUPPLY}
            value={tierStore.tiers[num].supply}
            valid={tierStore.validTiers[num].supply}
            errorMessage={VALIDATION_MESSAGES.SUPPLY}
            onChange={(e) => this.updateTierStore(e, 'supply')}
            description={`How many tokens will be sold on this tier. Cap of crowdsale equals to sum of supply of all tiers`}
          />
          <RadioInputField
            side='right'
            title={ALLOWMODIFYING}
            items={["on", "off"]}
            vals={["on", "off"]}
            num={num}
            defaultValue={this.props.tierStore.tiers[num].updatable}
            name={'crowdsale-updatable-' + num}
            onChange={(e) => this.updateTierStore(e, 'updatable')}
            description={`Pandora box feature. If it's enabled, a creator of the crowdsale can modify Start time, End time, Rate, Limit after publishing.`}
          />

        {tierStore.tiers[0].whitelistdisabled === "yes"?"":whitelistInputBlock}

)
  }
}
<|endoftext|>


<commit_before>/*jshint multistr: true, unused: false*/

'use strict';

var $ = require('jquery'),
    NavMainComponent = require('../../../js/NavMainComponent');

$.fx.off = !$.fx.off;

describe('NavMainComponent', function () {
    beforeEach(function() {
        this.$html = $('

').appendTo('html');
        this.$body = $('

').appendTo(this.$html);
        this.$window = $('

');
        this.$window.height(150);
        this.window = this.$window[0];

        this.$markup = $('\
\

\
    Jadu\
\

\

\
          1\

\

\
          2\

\

\
          3\

\

\

\
\
    x\
\
    <form>\
      <input type="search" placeholder="search" />\
      <button>Go</button>\
    </form>\
\

\

\

\
            1.1\

\

\

\
\

\

\

\
            2.1\

\

\

\
\

\
\
    x\
\

\

\
                3.1\

\

\

\
  \
    x\
    \

\

\
            4.1\

\

\

\
\

\
').appendTo(this.$body);

        this.$navMain = this.$html.find('.nav-main');
        this.$closeLink = this.$html.find('[data-nav-action="close"]');
        this.$contentMain = this.$html.find('.content-main');
        this.$navPrimary = this.$html.find('.nav-primary');
        this.$navTertiary = this.$navMain.find('.nav-tertiary');
        this.$navQuaternary = this.$navMain.find('.nav-quaternary');

        this.$linkOne = this.$html.find('[href="#one"]');
        this.$linkTwo = this.$html.find('[href="#two"]');
        this.$linkThree = this.$html.find('[href="#three"]');
        this.$secondaryLinkOne = this.$html.find('[href="#one_one"]');
        this.$secondaryLinkTwo = this.$html.find('[href="#two_one"]');
        this.$secondaryLinkThree = this.$html.find('[href="#three_one"]');
        this.$secondaryLinkFour = this.$html.find('[href="#four_one"]');

        // set height on nav items as no css in tests
        this.$html.find('.nav-item').height(20);
        this.$html.find('.more-icon').height(20);

        this.navMainComponent = new NavMainComponent(this.$html, this.window);
    });

    afterEach(function () {
        this.$html.remove(); // Detach test DOM from the real one
    });

    describe('when component is initalised, if html arguement is missing', function () {
        it('should throw the error \'html must be passed to NavMainComponent\' ', function () {
            this.navMainComponentWithoutHtmlArg = new NavMainComponent({}, this.window);

            expect(() => {
                this.navMainComponentWithoutHtmlArg.init();
            }).to.throw('html must be passed to NavMainComponent');
        })
    });

    describe('when component is initalised, if window arguement is missing', function () {
        it('should throw the error \'window must be passed to NavMainComponent\' ', function () {
            this.navMainComponentWithoutWindowArg = new NavMainComponent(this.$html, undefined);

            expect(() => {
                this.navMainComponentWithoutWindowArg.init();
            }).to.throw('window must be passed to NavMainComponent');
        })
    });

    describe('clicking on the first primary nav link', function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$linkOne.click();
        });

        it('should add the is-active class to the first link', function () {
            expect(this.$linkOne.hasClass('is-active')).to.be.true;
        });

        it('should open the secondary nav', function () {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.true;
        });

        it('should add the is-active class to the secondary sub navigation menu', function () {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.true;
        });

        it('should not add the is-active class to the other sub navigation menus', function () {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking the first, then the second primary nav link', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkTwo.click();
        });

        it('should add the is-active class to the second link', function () {
            expect(this.$linkTwo.hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first link', function () {
            expect(this.$linkOne.hasClass('is-active')).to.be.false;
        });

        it('should add the is-active class to the second sub navigation menu', function () {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first sub navigation menu', function () {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking a secondary nav link', function() {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
        });

        it('should add the is-active class to the clicked link', function () {
            expect(this.$secondaryLinkOne.hasClass('is-active')).to.be.true;
        });
    });

    describe('clicking a second secondary nav link', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
            this.$secondaryLinkTwo.click();
        });

        it('should add the is-active class to the clicked link', function () {
            expect(this.$secondaryLinkTwo.hasClass('is-active')).to.be.true;
        });
    });

    describe('clicking a primary nav link that has no sub navigation', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkThree.click();
        });

        it('should not open the secondary nav', function () {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });
    });

    describe('clicking a primary nav link that has no sub navigation when the subnavigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkThree.click();
        });

        it('should close the secondary nav', function () {
            expect(this.$html.find('.nav-main').hasClass('nav-main--open')).to.be.false;
        });
    });

    describe('clicking the close icon, when the sub navigation is closed', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$closeLink.click();
        });

        it('should have no effect on the subnavigation', function () {
            expect(this.$html.find('.nav-main').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking the close icon, when the sub navigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$closeLink.click();
        });

        it('should close the sub navigation', function () {
            expect(this.$html.find('.nav-main div').hasClass('is-open')).to.be.false;
        });

        it('should remove the highlight from that sections primary nav item', function () {
            expect(this.$html.find('.nav-primary .nav-link').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking outside of the navigation, when the sub navigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$contentMain.click();
        });

        it('should close the sub navigation', function () {
            expect(this.$html.find('.nav-main div').hasClass('is-open')).to.be.false;
        });
    });

    describe("when the window is too short for the whole primary navigation to be displayed", function () {
        beforeEach(function() {
            this.navMainComponent.init();
        });

        it('should show the more icon link', function () {
            expect(this.$html.find('.nav-primary .nav-items .more-icon').is(':visible')).to.be.true;
        });

        describe('when the more link is clicked', function () {
            beforeEach(function() {
                this.$moreIconLink = this.$navMain.find('.more-icon > .nav-link');
                this.$moreIconLink.click();
            });

            it('should open the sliding main nav if it is closed', function () {
                expect(this.$navTertiary.hasClass('is-open')).to.be.true;
            });
        });
    });

    describe('clicking the close icon, when the tertiary sub navigation is open', function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$secondaryLinkThree.click();
            this.$closeLink.click();
        });

        it('should close the tertiary sub navigation', function () {
            expect(this.$html.find('.nav-tertiary').hasClass('is-open')).to.be.false;
        });
    });

    describe('clicking the close icon, when the quaternary sub navigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$secondaryLinkFour.click();
            this.$closeLink.click();
        });

        it('should close the quaternary sub navigation', function () {
            expect(this.$html.find('.nav-quaternary').hasClass('is-open')).to.be.false;
        });
    });

    describe("When the window is resized from very short to large enough to fit nav", function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$window.height(200);
            this.$window.resize();
        });

        it('should show extra nav items', function () {
            expect(this.$html.find('.nav-primary .nav-items li:not(.more-icon)').is(':visible')).to.be.true;
        });
    });

    describe("When nav-items is bigger than the window and More Item exists", function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$window.resize();
        });

        it('should show the More link', function () {
            expect(this.$html.find('.nav-primary .nav-items .more-icon').is(':visible')).to.be.true;
        });
    });

    describe('When the window is resized', function () {
        beforeEach(function () {
            this.adjustNavStub = sinon.stub(this.navMainComponent, 'adjustNavItems');
        });

        it('should call adjustNavItems()', function () {
            this.navMainComponent.init();
            this.navMainComponent.$window.trigger('resize');

            expect(this.adjustNavStub).to.have.been.called;
        });
    });

    describe('When "More" nav item is getting hidden and tertiary and quaternary nav is already open', function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$window.height(200);
            this.$window.resize();
            this.$moreIconLink = this.$navMain.find('.more-icon > .nav-link');
            this.$moreIconLink.click();
            this.$window.height(1000);
            this.$window.resize();
            this.$window.resize();
        });

        it('should hide the open tertiary or quaternary nav', function () {
            expect(this.$navTertiary.hasClass('is-open')).to.be.false;
            expect(this.$navQuaternary.hasClass('is-open')).to.be.false;
        });
    });
});
<commit_msg>Temporary Test Comment<commit_after>/*jshint multistr: true, unused: false*/

'use strict';

var $ = require('jquery'),
    NavMainComponent = require('../../../js/NavMainComponent');

$.fx.off = !$.fx.off;

describe('NavMainComponent', function () {
    beforeEach(function() {
        this.$html = $('

').appendTo('html');
        this.$body = $('

').appendTo(this.$html);
        this.$window = $('

');
        this.$window.height(150);
        this.window = this.$window[0];

        this.$markup = $('\
\

\
    Jadu\
\

\

\
          1\

\

\
          2\

\

\
          3\

\

\

\
\
    x\
\
    <form>\
      <input type="search" placeholder="search" />\
      <button>Go</button>\
    </form>\
\

\

\

\
            1.1\

\

\

\
\

\

\

\
            2.1\

\

\

\
\

\
\
    x\
\

\

\
                3.1\

\

\

\
  \
    x\
    \

\

\
            4.1\

\

\

\
\

\
').appendTo(this.$body);

        this.$navMain = this.$html.find('.nav-main');
        this.$closeLink = this.$html.find('[data-nav-action="close"]');
        this.$contentMain = this.$html.find('.content-main');
        this.$navPrimary = this.$html.find('.nav-primary');
        this.$navTertiary = this.$navMain.find('.nav-tertiary');
        this.$navQuaternary = this.$navMain.find('.nav-quaternary');

        this.$linkOne = this.$html.find('[href="#one"]');
        this.$linkTwo = this.$html.find('[href="#two"]');
        this.$linkThree = this.$html.find('[href="#three"]');
        this.$secondaryLinkOne = this.$html.find('[href="#one_one"]');
        this.$secondaryLinkTwo = this.$html.find('[href="#two_one"]');
        this.$secondaryLinkThree = this.$html.find('[href="#three_one"]');
        this.$secondaryLinkFour = this.$html.find('[href="#four_one"]');

        // set height on nav items as no css in tests
        this.$html.find('.nav-item').height(20);
        this.$html.find('.more-icon').height(20);

        this.navMainComponent = new NavMainComponent(this.$html, this.window);
    });

    afterEach(function () {
        this.$html.remove(); // Detach test DOM from the real one
    });

    describe('when component is initalised, if html arguement is missing', function () {
        it('should throw the error \'html must be passed to NavMainComponent\' ', function () {
            this.navMainComponentWithoutHtmlArg = new NavMainComponent({}, this.window);

            expect(() => {
                this.navMainComponentWithoutHtmlArg.init();
            }).to.throw('html must be passed to NavMainComponent');
        })
    });

    describe('when component is initalised, if window arguement is missing', function () {
        it('should throw the error \'window must be passed to NavMainComponent\' ', function () {
            this.navMainComponentWithoutWindowArg = new NavMainComponent(this.$html, undefined);

            expect(() => {
                this.navMainComponentWithoutWindowArg.init();
            }).to.throw('window must be passed to NavMainComponent');
        })
    });

    describe('clicking on the first primary nav link', function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$linkOne.click();
        });

        it('should add the is-active class to the first link', function () {
            expect(this.$linkOne.hasClass('is-active')).to.be.true;
        });

        it('should open the secondary nav', function () {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.true;
        });

        it('should add the is-active class to the secondary sub navigation menu', function () {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.true;
        });

        it('should not add the is-active class to the other sub navigation menus', function () {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking the first, then the second primary nav link', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkTwo.click();
        });

        it('should add the is-active class to the second link', function () {
            expect(this.$linkTwo.hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first link', function () {
            expect(this.$linkOne.hasClass('is-active')).to.be.false;
        });

        it('should add the is-active class to the second sub navigation menu', function () {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first sub navigation menu', function () {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking a secondary nav link', function() {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
        });

        it('should add the is-active class to the clicked link', function () {
            expect(this.$secondaryLinkOne.hasClass('is-active')).to.be.true;
        });
    });

    describe('clicking a second secondary nav link', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
            this.$secondaryLinkTwo.click();
        });

        it('should add the is-active class to the clicked link', function () {
            expect(this.$secondaryLinkTwo.hasClass('is-active')).to.be.true;
        });
    });

    describe('clicking a primary nav link that has no sub navigation', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkThree.click();
        });

        it('should not open the secondary nav', function () {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });
    });

    describe('clicking a primary nav link that has no sub navigation when the subnavigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkThree.click();
        });

        it('should close the secondary nav', function () {
            expect(this.$html.find('.nav-main').hasClass('nav-main--open')).to.be.false;
        });
    });

    describe('clicking the close icon, when the sub navigation is closed', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$closeLink.click();
        });

        it('should have no effect on the subnavigation', function () {
            expect(this.$html.find('.nav-main').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking the close icon, when the sub navigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$closeLink.click();
        });

        it('should close the sub navigation', function () {
            expect(this.$html.find('.nav-main div').hasClass('is-open')).to.be.false;
        });

        it('should remove the highlight from that sections primary nav item', function () {
            expect(this.$html.find('.nav-primary .nav-link').hasClass('is-active')).to.be.false;
        });
    });

    describe('clicking outside of the navigation, when the sub navigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$contentMain.click();
        });

        it('should close the sub navigation', function () {
            expect(this.$html.find('.nav-main div').hasClass('is-open')).to.be.false;
        });
    });

    describe("when the window is too short for the whole primary navigation to be displayed", function () {
        beforeEach(function() {
            this.navMainComponent.init();
        });

        it('should show the more icon link', function () {
            expect(this.$html.find('.nav-primary .nav-items .more-icon').is(':visible')).to.be.true;
        });
    });

    /*describe('when the more link is clicked', function () {
        beforeEach(function() {
            this.$moreIconLink = this.$html.find('.more-icon > .nav-link');
            this.$moreIconLink.click();
        });

        it('should open the sliding main nav if it is closed', function () {
            expect(this.$navTertiary.hasClass('is-open')).to.be.true;
        });
    });*/

    describe('clicking the close icon, when the tertiary sub navigation is open', function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$secondaryLinkThree.click();
            this.$closeLink.click();
        });

        it('should close the tertiary sub navigation', function () {
            expect(this.$html.find('.nav-tertiary').hasClass('is-open')).to.be.false;
        });
    });

    describe('clicking the close icon, when the quaternary sub navigation is open', function () {
        beforeEach(function() {
            this.navMainComponent.init();
            this.$secondaryLinkFour.click();
            this.$closeLink.click();
        });

        it('should close the quaternary sub navigation', function () {
            expect(this.$html.find('.nav-quaternary').hasClass('is-open')).to.be.false;
        });
    });

    describe("When the window is resized from very short to large enough to fit nav", function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$window.height(200);
            this.$window.resize();
        });

        it('should show extra nav items', function () {
            expect(this.$html.find('.nav-primary .nav-items li:not(.more-icon)').is(':visible')).to.be.true;
        });
    });

    describe("When nav-items is bigger than the window and More Item exists", function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$window.resize();
        });

        it('should show the More link', function () {
            expect(this.$html.find('.nav-primary .nav-items .more-icon').is(':visible')).to.be.true;
        });
    });

    describe('When the window is resized', function () {
        beforeEach(function () {
            this.adjustNavStub = sinon.stub(this.navMainComponent, 'adjustNavItems');
        });

        it('should call adjustNavItems()', function () {
            this.navMainComponent.init();
            this.navMainComponent.$window.trigger('resize');

            expect(this.adjustNavStub).to.have.been.called;
        });
    });

    describe('When "More" nav item is getting hidden and tertiary and quaternary nav is already open', function () {
        beforeEach(function () {
            this.navMainComponent.init();
            this.$window.height(200);
            this.$window.resize();
            this.$moreIconLink = this.$navMain.find('.more-icon > .nav-link');
            this.$moreIconLink.click();
            this.$window.height(1000);
            this.$window.resize();
            this.$window.resize();
        });

        it('should hide the open tertiary or quaternary nav', function () {
            expect(this.$navTertiary.hasClass('is-open')).to.be.false;
            expect(this.$navQuaternary.hasClass('is-open')).to.be.false;
        });
    });
});
<|endoftext|>


<commit_before>'use strict';

const functionHelper = require('./functionHelper.js');
const LambdaContext = require('./LambdaContext.js');
const { createUniqueId } = require('./utils/index.js');
const { DEFAULT_LAMBDA_TIMEOUT } = require('./config/index.js');

const { now } = Date;

module.exports = class LambdaFunction {
  constructor(config, options) {
    this._awsRequestId = null;
    this._config = config;
    this._executionTimeEnded = null;
    this._executionTimeStarted = null;
    this._executionTimeout = null;
    this._options = options;
  }

  _startExecutionTimer() {
    const { timeout = DEFAULT_LAMBDA_TIMEOUT } = this._config;

    this._executionTimeStarted = now();
    this._executionTimeout = this._executionTimeStarted + timeout * 1000;
  }

  _stopExecutionTimer() {
    this._executionTimeEnded = now();
  }

  addEvent(event) {
    this._event = event;
  }

  getExecutionTimeInMillis() {
    return this._executionTimeEnded - this._executionTimeStarted;
  }

  getAwsRequestId() {
    return this._awsRequestId;
  }

  async runHandler() {
    const { functionName, lambdaName, memorySize } = this._config;

    this._awsRequestId = createUniqueId();

    const lambdaContext = new LambdaContext({
      awsRequestId: this._awsRequestId,
      getRemainingTimeInMillis: () => {
        const time = this._executionTimeout - now();

        // just return 0 for now if we are beyond alotted time (timeout)
        return time > 0 ? time : 0;
      },
      lambdaName,
      memorySize,
    });

    let callback;

    const callbackCalled = new Promise((resolve, reject) => {
      callback = (err, data) => {
        if (err) {
          reject(err);
        }
        resolve(data);
      };

      lambdaContext.once('contextCalled', callback);
    });

    const context = lambdaContext.getContext();

    this._startExecutionTimer();

    const handler = functionHelper.createHandler(this._config, this._options);

    let result;

    try {
      result = handler(this._event, context, callback);
    } catch (err) {
      // this only executes when we have an exception caused by syncronous code
      // TODO logging
      console.log(err);
      throw new Error(`Uncaught error in '${functionName}' handler.`);
    }

    // // not a Promise, which is not supported by aws
    // if (result == null || typeof result.then !== 'function') {
    //   throw new Error(`Syncronous function execution is not supported.`);
    // }

    const callbacks = [callbackCalled];

    // Promise was returned
    if (result != null && typeof result.then === 'function') {
      callbacks.push(result);
    }

    let callbackResult;

    try {
      callbackResult = await Promise.race(callbacks);
    } catch (err) {
      // TODO logging
      console.log(err);
      throw err;
    }

    this._stopExecutionTimer();

    return callbackResult;
  }
};
<commit_msg>Fix spelling<commit_after>'use strict';

const functionHelper = require('./functionHelper.js');
const LambdaContext = require('./LambdaContext.js');
const { createUniqueId } = require('./utils/index.js');
const { DEFAULT_LAMBDA_TIMEOUT } = require('./config/index.js');

const { now } = Date;

module.exports = class LambdaFunction {
  constructor(config, options) {
    this._awsRequestId = null;
    this._config = config;
    this._executionTimeEnded = null;
    this._executionTimeStarted = null;
    this._executionTimeout = null;
    this._options = options;
  }

  _startExecutionTimer() {
    const { timeout = DEFAULT_LAMBDA_TIMEOUT } = this._config;

    this._executionTimeStarted = now();
    this._executionTimeout = this._executionTimeStarted + timeout * 1000;
  }

  _stopExecutionTimer() {
    this._executionTimeEnded = now();
  }

  addEvent(event) {
    this._event = event;
  }

  getExecutionTimeInMillis() {
    return this._executionTimeEnded - this._executionTimeStarted;
  }

  getAwsRequestId() {
    return this._awsRequestId;
  }

  async runHandler() {
    const { functionName, lambdaName, memorySize } = this._config;

    this._awsRequestId = createUniqueId();

    const lambdaContext = new LambdaContext({
      awsRequestId: this._awsRequestId,
      getRemainingTimeInMillis: () => {
        const time = this._executionTimeout - now();

        // just return 0 for now if we are beyond alotted time (timeout)
        return time > 0 ? time : 0;
      },
      lambdaName,
      memorySize,
    });

    let callback;

    const callbackCalled = new Promise((resolve, reject) => {
      callback = (err, data) => {
        if (err) {
          reject(err);
        }
        resolve(data);
      };

      lambdaContext.once('contextCalled', callback);
    });

    const context = lambdaContext.getContext();

    this._startExecutionTimer();

    const handler = functionHelper.createHandler(this._config, this._options);

    let result;

    try {
      result = handler(this._event, context, callback);
    } catch (err) {
      // this only executes when we have an exception caused by synchronous code
      // TODO logging
      console.log(err);
      throw new Error(`Uncaught error in '${functionName}' handler.`);
    }

    // // not a Promise, which is not supported by aws
    // if (result == null || typeof result.then !== 'function') {
    //   throw new Error(`Synchronous function execution is not supported.`);
    // }

    const callbacks = [callbackCalled];

    // Promise was returned
    if (result != null && typeof result.then === 'function') {
      callbacks.push(result);
    }

    let callbackResult;

    try {
      callbackResult = await Promise.race(callbacks);
    } catch (err) {
      // TODO logging
      console.log(err);
      throw err;
    }

    this._stopExecutionTimer();

    return callbackResult;
  }
};
<|endoftext|>