<commit_before>/**
 * Plugin: "placecomplete" (selectize.js)
 * @author @comerc (fork of placecomplete by Stephanie H. Chang <st@stchangg.com>)
 * fork me: https://github.com/comerc/selectize-placecomplete
 */

window.initPlacecomplete = function() {
  GooglePlacesAPI.completeInit();
};

/**
 * A wrapper to simplify communicating with and contain logic specific to the
 * Google Places API
 *
 * @return {object} An object with public methods getPredictions() and
 *                  getDetails()
 */
var GooglePlacesAPI = {

  deferred: new $.Deferred(),
  initialized: false,
  acService: null,
  pService: null,
  el: null,

  /**
   * Start loading Google Places API if it hasn't yet been loaded.
   *
   * @param  {HTMLDivElement} el
   *
   *     Container in which to "render attributions", according to
   *     https://developers.google.com/maps/documentation/javascript/reference#PlacesService.
   *     TODO: (stephanie) I still don't really understand why the element is
   *     necessary, hence why I'm only ever instantiating PlacesService
   *     once, no matter how many elements are initialized with the plugin.
   */
  init: function(el) {
    // Ensure init() is idempotent, just in case.
    if (this.initialized) {
      return;
    }

    // Store element so we can use it to intialize PlacesService in
    // completeInit()
    this.el = el;

    // Only fetch Google Maps API if it's not already loaded
    if (window.google && google.maps && google.maps.places) {
      // Skip to completeInit() directly
      this.completeInit();
    } else {
      $.ajax({
        // TODO: https://developers.google.com/maps/documentation/javascript/basics#Localization
        url: "https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false&callback=initPlacecomplete2",
        dataType: "script",
        cache: true
      });
    }
  },

  completeInit: function() {
    // AutocompleteService is needed for getting the list of options
    this.acService = new google.maps.places.AutocompleteService();

    // PlacesService is needed for getting details for the selected
    // option
    this.pService = new google.maps.places.PlacesService(this.el);

    this.initialized = true;
    this.deferred.resolve();
  },

  _handlePredictions: function(def, abbreviatedPlaceResults, status) {
    if (status !== google.maps.places.PlacesServiceStatus.OK) {
      def.reject(status);
      return;
    }
    def.resolve(abbreviatedPlaceResults);
  },

  _handleDetails: function(def, displayText, placeResult, status) {
    if (status !== google.maps.places.PlacesServiceStatus.OK) {
      def.reject(status);
      return;
    }
    placeResult["display_text"] = displayText;
    def.resolve(placeResult);
  },

  // Get list of autocomplete results for the provided search term
  getPredictions: function(searchTerm, requestParams) {
    return this.deferred.then($.proxy(function() {
      var deferred = new $.Deferred();
      if (typeof requestParams === "function")
      {
        requestParams = requestParams();
      }
      requestParams = $.extend({}, requestParams, {
        "input": searchTerm
      });
      this.acService.getPlacePredictions(
        requestParams,
        $.proxy(this._handlePredictions, null, deferred));
      return deferred.promise();
    }, this));
  },

  // Get details of the selected item
  getDetails: function(abbreviatedPlaceResult) {
    return this.deferred.then($.proxy(function() {
      var deferred = new $.Deferred();
      var displayText = abbreviatedPlaceResult.description;
      // FIXME: NOT_FOUND for "ChIJ--acWvtHDW0RF5miQ2HvAAU"-"Auckland, New Zealand"
      this.pService.getDetails({
        placeId: abbreviatedPlaceResult.place_id
      }, $.proxy(this._handleDetails, null, deferred, displayText));
      return deferred.promise();
    }, this));
  }
};

var pluginName = "placecomplete";

Selectize.define(pluginName, function(options) {
  var self = this;

  options = $.extend({
    placeholder: "City, State, Country",
    // Request parameters for the .getPlacePredictions() call
    // https://developers.google.com/maps/documentation/javascript/reference#AutocompletionRequest
    requestParams: {
      types: ["(cities)"]
    },
    filterResults: null,
    selectDetails: null,
  }, options);

  this.setup = (function() {
    var original = self.setup;
    return function() {
      if (options.placeholder)
        self.settings.placeholder = options.placeholder;
      original.apply(this, arguments);

      // Initialize
      GooglePlacesAPI.init(this.$input[0]);

      self.settings.load = function(query, callback) {
        if (!query.length) return callback();
        GooglePlacesAPI.getPredictions(query, options.requestParams)
          .done(function(aprs) {
            var results = $.map(aprs, function(apr) {
              // // BUGFIX: values that do not contain query: SAN > "Rissia, Saint Petersburg"
              var skipResult = apr.description.toUpperCase().indexOf(query.toUpperCase()) === -1;
              if (!skipResult && options.filterResults) {
                  skipResult = options.filterResults.call(null, apr);
              }
              if (skipResult) {
                  return null;
              }
              // selectize needs a "text" and "value" property set
              // for each autocomplete list item.
              apr["value"] = apr["text"] = apr["description"];
              return apr;
            });
            callback(results);
          })
          .fail(function(errorMsg) {
            // TODO: how to get plugin name?
            self.trigger(pluginName + ":error", errorMsg);
            callback();
          });
      };
      var render_option = self.settings.render.option;
      self.settings.render.option = function(data) {
        // BUGFIX: "Россия, город Санкт-Петербург, Санкт-Петербург" >>> "Россия, Санкт-Петербург"
        var re, m;
        re = /(.*), (city|Stadt|ville|ciudad|città|cidade|город|城市|kota|grad|ciutat|město|by|mji|pilsēta|miestas|város|bandar|നഗരം|stad|miasto|oraș|qytet|mesto|град|kaupunki|lungsod|thành phố|şehir|πόλη|місто|עיר|शहर|เมือง|街|도시) (.*), (.*)/;
        m = re.exec(data.text);
        if (m && (m[1] === m[3] || m[3] === m[4])) {
          data.text = m[1] + ", " + m[4];
        }
        return render_option.apply(this, arguments);
      };
    };
  })();
  this.onOptionSelect = (function() {
    var original = self.onOptionSelect;
    return function(e) {
      var self = this;
      var $target = $(e.currentTarget);
      var value = $target.attr('data-value');
      var data = self.options[value];
      if (self.settings.mode === "single") {
        self.close();
      }
      e.preventDefault();
      e.stopPropagation();
      // ok, google
      GooglePlacesAPI.getDetails(data)
        .done(function(placeResult) {
          var val = null;
          if (options.selectDetails)
          {
            val = options.selectDetails.call(null, placeResult);
          }
          if (!val) {
            // custom format of selected value
            // BUGFIX: placeResult.formatted_address: "01300 Vantaa, Finland" (postal_code)
            // BUGFIX: placeResult.display_text: "Россия, город Санкт-Петербург, Санкт-Петербург" (double values of "mono-city")
            var i, c, t, s0;
            var withoutTypes = [
              "postal_code",
              "administrative_area_level_2",
              "administrative_area_level_3",
              "administrative_area_level_4"
            ];
            var aLevel2 = "";
            val = s0 = placeResult.address_components[0].long_name;
            i = 1;
            while (i < placeResult.address_components.length) {
              c = placeResult.address_components[i];
              t = c.types[0];
              if (t === "administrative_area_level_2") {
                aLevel2 = c.long_name;
              }
              if (withoutTypes.indexOf(t) === -1) {
                // BUGFIX: double values of "mono-city": "St Petersburg, St Petersburg, Russia"
                // BUGFIX: administrative_area_level_1 restricted for "Смоленск, Смоленская область", but not for "Самара, Самарская область"
                if (t !== "administrative_area_level_1" || c.long_name !== aLevel2 && c.long_name !== s0) {
                  val += ", " + c.long_name;
                }
              }
              i++;
            }
          }
          data.text = data.value = val;
          self.removeOption(value);
          self.addOption(data);
          $target.attr('data-value', val);
          original.call(self, e);
        })
        .fail(function(errorMsg) {
          // TODO: how to get plugin name?
          self.trigger(pluginName + ":error", errorMsg);
        });
    }
  })();
});
<commit_msg>BUGFIX: for KEY_RETURN<commit_after>/**
 * Plugin: "placecomplete" (selectize.js)
 * @author @comerc (fork of placecomplete by Stephanie H. Chang <st@stchangg.com>)
 * fork me: https://github.com/comerc/selectize-placecomplete
 */

// first window.initPlacecomplete in https://github.com/comerc/placecomplete
window.initPlacecomplete2 = function() {
  GooglePlacesAPI.completeInit();
};

/**
 * A wrapper to simplify communicating with and contain logic specific to the
 * Google Places API
 *
 * @return {object} An object with public methods getPredictions() and
 *                  getDetails()
 */
var GooglePlacesAPI = {

  deferred: new $.Deferred(),
  initialized: false,
  acService: null,
  pService: null,
  el: null,

  /**
   * Start loading Google Places API if it hasn't yet been loaded.
   *
   * @param  {HTMLDivElement} el
   *
   *     Container in which to "render attributions", according to
   *     https://developers.google.com/maps/documentation/javascript/reference#PlacesService.
   *     TODO: (stephanie) I still don't really understand why the element is
   *     necessary, hence why I'm only ever instantiating PlacesService
   *     once, no matter how many elements are initialized with the plugin.
   */
  init: function(el) {
    // Ensure init() is idempotent, just in case.
    if (this.initialized) {
      return;
    }

    // Store element so we can use it to intialize PlacesService in
    // completeInit()
    this.el = el;

    // Only fetch Google Maps API if it's not already loaded
    if (window.google && google.maps && google.maps.places) {
      // Skip to completeInit() directly
      this.completeInit();
    } else {
      $.ajax({
        // TODO: https://developers.google.com/maps/documentation/javascript/basics#Localization
        url: "https://maps.googleapis.com/maps/api/js?libraries=places&sensor=false&callback=initPlacecomplete2",
        dataType: "script",
        cache: true
      });
    }
  },

  completeInit: function() {
    // AutocompleteService is needed for getting the list of options
    this.acService = new google.maps.places.AutocompleteService();

    // PlacesService is needed for getting details for the selected
    // option
    this.pService = new google.maps.places.PlacesService(this.el);

    this.initialized = true;
    this.deferred.resolve();
  },

  _handlePredictions: function(def, abbreviatedPlaceResults, status) {
    if (status !== google.maps.places.PlacesServiceStatus.OK) {
      def.reject(status);
      return;
    }
    def.resolve(abbreviatedPlaceResults);
  },

  _handleDetails: function(def, displayText, placeResult, status) {
    if (status !== google.maps.places.PlacesServiceStatus.OK) {
      def.reject(status);
      return;
    }
    placeResult["display_text"] = displayText;
    def.resolve(placeResult);
  },

  // Get list of autocomplete results for the provided search term
  getPredictions: function(searchTerm, requestParams) {
    return this.deferred.then($.proxy(function() {
      var deferred = new $.Deferred();
      if (typeof requestParams === "function")
      {
        requestParams = requestParams();
      }
      requestParams = $.extend({}, requestParams, {
        "input": searchTerm
      });
      this.acService.getPlacePredictions(
        requestParams,
        $.proxy(this._handlePredictions, null, deferred));
      return deferred.promise();
    }, this));
  },

  // Get details of the selected item
  getDetails: function(abbreviatedPlaceResult) {
    return this.deferred.then($.proxy(function() {
      var deferred = new $.Deferred();
      var displayText = abbreviatedPlaceResult.description;
      // FIXME: NOT_FOUND for "ChIJ--acWvtHDW0RF5miQ2HvAAU"-"Auckland, New Zealand"
      this.pService.getDetails({
        placeId: abbreviatedPlaceResult.place_id
      }, $.proxy(this._handleDetails, null, deferred, displayText));
      return deferred.promise();
    }, this));
  }
};

var pluginName = "placecomplete";

Selectize.define(pluginName, function(options) {
  var self = this;
  var KEY_RETURN = 13;

  options = $.extend({
    placeholder: "City, State, Country",
    // Request parameters for the .getPlacePredictions() call
    // https://developers.google.com/maps/documentation/javascript/reference#AutocompletionRequest
    requestParams: {
      types: ["(cities)"]
    },
    filterResults: null,
    selectDetails: null,
  }, options);

  this.setup = (function() {
    var original = self.setup;
    return function() {
      if (options.placeholder)
        self.settings.placeholder = options.placeholder;
      original.apply(this, arguments);

      // Initialize
      GooglePlacesAPI.init(this.$input[0]);

      self.settings.load = function(query, callback) {
        if (!query.length) return callback();
        GooglePlacesAPI.getPredictions(query, options.requestParams)
          .done(function(aprs) {
            var results = $.map(aprs, function(apr) {
              // // BUGFIX: values that do not contain query: SAN > "Rissia, Saint Petersburg"
              var skipResult = apr.description.toUpperCase().indexOf(query.toUpperCase()) === -1;
              if (!skipResult && options.filterResults) {
                  skipResult = options.filterResults.call(null, apr);
              }
              if (skipResult) {
                  return null;
              }
              // selectize needs a "text" and "value" property set
              // for each autocomplete list item.
              apr["value"] = apr["text"] = apr["description"];
              return apr;
            });
            callback(results);
          })
          .fail(function(errorMsg) {
            // TODO: how to get plugin name?
            self.trigger(pluginName + ":error", errorMsg);
            callback();
          });
      };
      var render_option = self.settings.render.option;
      self.settings.render.option = function(data) {
        // BUGFIX: "Россия, город Санкт-Петербург, Санкт-Петербург" >>> "Россия, Санкт-Петербург"
        var re, m;
        re = /(.*), (city|Stadt|ville|ciudad|città|cidade|город|城市|kota|grad|ciutat|město|by|mji|pilsēta|miestas|város|bandar|നഗരം|stad|miasto|oraș|qytet|mesto|град|kaupunki|lungsod|thành phố|şehir|πόλη|місто|עיר|शहर|เมือง|街|도시) (.*), (.*)/;
        m = re.exec(data.text);
        if (m && (m[1] === m[3] || m[3] === m[4])) {
          data.text = m[1] + ", " + m[4];
        }
        return render_option.apply(this, arguments);
      };
    };
  })();
  this.onOptionSelect = (function() {
    var original = self.onOptionSelect;
    return function(e) {
      var self = this;
      var $target = $(e.currentTarget);
      var value = $target.attr('data-value');
      var data = self.options[value];
      if (self.settings.mode === "single") {
        self.close();
      }
      // ok, google
      GooglePlacesAPI.getDetails(data)
        .done(function(placeResult) {
          var val = null;
          if (options.selectDetails)
          {
            val = options.selectDetails.call(null, placeResult);
          }
          if (!val) {
            // custom format of selected value
            // BUGFIX: placeResult.formatted_address: "01300 Vantaa, Finland" (postal_code)
            // BUGFIX: placeResult.display_text: "Россия, город Санкт-Петербург, Санкт-Петербург" (double values of "mono-city")
            var i, c, t, s0;
            var withoutTypes = [
              "postal_code",
              "administrative_area_level_2",
              "administrative_area_level_3",
              "administrative_area_level_4"
            ];
            var aLevel2 = "";
            val = s0 = placeResult.address_components[0].long_name;
            i = 1;
            while (i < placeResult.address_components.length) {
              c = placeResult.address_components[i];
              t = c.types[0];
              if (t === "administrative_area_level_2") {
                aLevel2 = c.long_name;
              }
              if (withoutTypes.indexOf(t) === -1) {
                // BUGFIX: double values of "mono-city": "St Petersburg, St Petersburg, Russia"
                // BUGFIX: administrative_area_level_1 restricted for "Смоленск, Смоленская область", but not for "Самара, Самарская область"
                if (t !== "administrative_area_level_1" || c.long_name !== aLevel2 && c.long_name !== s0) {
                  val += ", " + c.long_name;
                }
              }
              i++;
            }
          }
          data.text = data.value = val;
          self.removeOption(value);
          self.addOption(data);
          $target.attr('data-value', val);
          original.call(self, e);
        })
        .fail(function(errorMsg) {
          // TODO: how to get plugin name?
          self.trigger(pluginName + ":error", errorMsg);
        });
    }
  })();
});
<|endoftext|>


<commit_before>import React from "react";
import ExperimentDetails from "./ExperimentDetails.js";
import ExperimentEvents from "./ExperimentEvents.js";
import LineChart from "./LineChart.js";
import Controls from "./Controls.js";
import reqwest from "reqwest";

class ExperimentHistory extends React.Component {

    constructor() {
        super();
        this.state = {events: [], configuration: {}, result:{}}
    }

    componentWillReceiveProps(props) {
        if(props.experiment._id) {
            this._getExperimentData(props)
        }
    }

    _getExperimentData(props) {
        var experimentId = props.experiment._id;
        var that = this;
        var succ = function(success) {
            console.log(success);
            if(success.length >0) {
                var experiment = success[0];
                that.setState({
                    events: experiment.events,
                    configuration: experiment.configuration,
                    result: experiment.result
                });
            }
        };
        reqwest({
            url: '/job/' + experimentId,
            type: 'json',
            contentType: 'application/json',
            method: 'get',
            success: succ
        });
    }

    render() {

        var experiment = this.props.experiment;
        var isExperiment = experiment._id ? true: false;

        return isExperiment ? (

               <Controls eid={experiment._id} running={experiment.running} onRemove={this.props.onRemove}/>

                         <LineChart data={this.state.events}></LineChart>

                        <ExperimentDetails details={experiment}
                                           configuration={this.state.configuration}
                                           result={this.state.result}>
                        </ExperimentDetails>

                        <ExperimentEvents events={this.state.events}></ExperimentEvents>

        ): null;
    }
}

module.exports = ExperimentHistory;<commit_msg>Link to raw json<commit_after>import React from "react";
import ExperimentDetails from "./ExperimentDetails.js";
import ExperimentEvents from "./ExperimentEvents.js";
import LineChart from "./LineChart.js";
import Controls from "./Controls.js";
import reqwest from "reqwest";

class ExperimentHistory extends React.Component {

    constructor() {
        super();
        this.state = {events: [], configuration: {}, result:{}}
    }

    componentWillReceiveProps(props) {
        if(props.experiment._id) {
            this._getExperimentData(props)
        }
    }

    _getExperimentData(props) {
        var experimentId = props.experiment._id;
        var that = this;
        var succ = function(success) {
            console.log(success);
            if(success.length >0) {
                var experiment = success[0];
                that.setState({
                    events: experiment.events,
                    configuration: experiment.configuration,
                    result: experiment.result
                });
            }
        };
        reqwest({
            url: '/job/' + experimentId,
            type: 'json',
            contentType: 'application/json',
            method: 'get',
            success: succ
        });
    }

    render() {

        var experiment = this.props.experiment;
        var isExperiment = experiment._id ? true: false;

        return isExperiment ? (

               <Controls eid={experiment._id} running={experiment.running} onRemove={this.props.onRemove}/>

                         <LineChart data={this.state.events}></LineChart>

                        <ExperimentDetails details={experiment}
                                           configuration={this.state.configuration}
                                           result={this.state.result}>
                        </ExperimentDetails>

                        <ExperimentEvents events={this.state.events}></ExperimentEvents>

                       Raw json data

        ): null;
    }
}

module.exports = ExperimentHistory;<|endoftext|>


<commit_before>window.getJasmineRequireObj().domMocker = function () {
    var oldDocument,

        getElementById = function (parent, id) {
            var children = parent.childNodes,
                child,
                result,
                i;

            for (i = 0; i < children.length; i++) {
                child = children[i];

                if (child.id === id) {
                    return child;
                }

                result = getElementById.call(this, child, id);

                if (result) {
                    return result;
                }
            }
        },

        stubElement = function (el) {
            var original = el.addEventListener;

            el.events = {};
            el.addEventListener = function (name, listener) {
                if (this.events[name]) {
                    this.events[name].push(listener);
                } else {
                    this.events[name] = [listener];
                }

                original.call(this, name, listener);
            };

            return el;
        },

        isAlreadyMocked = function (el) {
            return el.events;
        },

        processElement = function (el) {
            if (!isAlreadyMocked.call(this, el)) {
                return stubElement.call(this, el);
            }

            return el;
        },

        getSingleElement = function (el) {
            return el ? processElement.call(this, el) : null;
        },

        processElements = function (elements) {
            var i,
                length = elements.length;

            for (i = 0; i < length; i++) {
                processElement.call(this, elements[i]);
            }

            return elements;
        };

    this.mockWith = function (dom) {
        var docCreateElementBackup = document.createElement;

        oldDocument = {
            getElementsByTagName: document.getElementsByTagName,
            getElementById: document.getElementById,
            querySelector: document.querySelector,
            querySelectorAll: document.querySelectorAll,
            getElementsByClassName: document.getElementsByClassName,
            addEventListener: document.addEventListener
        };

        document.getElementsByTagName = function (tagName) {
            if (tagName.toLowerCase() === 'html') {
                // This array could lead to problems
                return processElements.call(this, [dom]);
            }
            return processElements.call(this, dom.getElementsByTagName(tagName));
        };

        document.getElementById = function (id) {
            return getSingleElement.call(this, getElementById.call(this, dom, id));
        };

        document.getElementsByClassName = function (className) {
            return processElements.call(this, dom.getElementsByClassName(className));
        };

        document.querySelector = function (selector) {
            return getSingleElement.call(this, dom.querySelector(selector));
        };

        document.querySelectorAll = function (selector) {
            return processElements.call(this, dom.querySelectorAll(selector));
        };

        processElement.call(this, document);

        document.createElement = function () {
            // when this method is spied in the specs there is a conflic because
            // the spies are set back after the virtual dom is set back
            // if (!oldDocument) {
            //     this.createElement = docCreateElementBackup;
            //     return this.createElement.apply(this, arguments);
            // } else {
            return processElement.call(this, docCreateElementBackup.apply(this, arguments));
            //}
        };
    };

    this.unMock = function () {
        var method;

        for (method in oldDocument) {
            if (oldDocument.hasOwnProperty(method)) {
                document[method] = oldDocument[method];
            }
        }

        delete document.events;
    };
};
<commit_msg>Add docs<commit_after>/**
 * Service to mock the document API
 *
 * @constructor domMocker
 */
window.getJasmineRequireObj().domMocker = function () {
    var oldDocument,

        getElementById = function (parent, id) {
            var children = parent.childNodes,
                child,
                result,
                i;

            for (i = 0; i < children.length; i++) {
                child = children[i];

                if (child.id === id) {
                    return child;
                }

                result = getElementById.call(this, child, id);

                if (result) {
                    return result;
                }
            }
        },

        stubElement = function (el) {
            var original = el.addEventListener;

            el.events = {};
            el.addEventListener = function (name, listener) {
                if (this.events[name]) {
                    this.events[name].push(listener);
                } else {
                    this.events[name] = [listener];
                }

                original.call(this, name, listener);
            };

            return el;
        },

        isAlreadyMocked = function (el) {
            return el.events;
        },

        processElement = function (el) {
            if (!isAlreadyMocked.call(this, el)) {
                return stubElement.call(this, el);
            }

            return el;
        },

        getSingleElement = function (el) {
            return el ? processElement.call(this, el) : null;
        },

        processElements = function (elements) {
            var i,
                length = elements.length;

            for (i = 0; i < length; i++) {
                processElement.call(this, elements[i]);
            }

            return elements;
        };

    /**
     * @param  {HTMLElement} dom Virtual dom
     * @memberof domMocker
     */
    this.mockWith = function (dom) {
        var docCreateElementBackup = document.createElement;

        oldDocument = {
            getElementsByTagName: document.getElementsByTagName,
            getElementById: document.getElementById,
            querySelector: document.querySelector,
            querySelectorAll: document.querySelectorAll,
            getElementsByClassName: document.getElementsByClassName,
            addEventListener: document.addEventListener
        };

        document.getElementsByTagName = function (tagName) {
            if (tagName.toLowerCase() === 'html') {
                // This array could lead to problems
                return processElements.call(this, [dom]);
            }
            return processElements.call(this, dom.getElementsByTagName(tagName));
        };

        document.getElementById = function (id) {
            return getSingleElement.call(this, getElementById.call(this, dom, id));
        };

        document.getElementsByClassName = function (className) {
            return processElements.call(this, dom.getElementsByClassName(className));
        };

        document.querySelector = function (selector) {
            return getSingleElement.call(this, dom.querySelector(selector));
        };

        document.querySelectorAll = function (selector) {
            return processElements.call(this, dom.querySelectorAll(selector));
        };

        processElement.call(this, document);

        document.createElement = function () {
            // when this method is spied in the specs there is a conflic because
            // the spies are set back after the virtual dom is set back
            // if (!oldDocument) {
            //     this.createElement = docCreateElementBackup;
            //     return this.createElement.apply(this, arguments);
            // } else {
            return processElement.call(this, docCreateElementBackup.apply(this, arguments));
            //}
        };
    };

    /**
     * @memberof domMocker
     */
    this.unMock = function () {
        var method;

        for (method in oldDocument) {
            if (oldDocument.hasOwnProperty(method)) {
                document[method] = oldDocument[method];
            }
        }

        delete document.events;
    };
};
<|endoftext|>


<commit_before>// Copyright (c) 2018 Euan Ong
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the The GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Affero General Public
// License along with this library; if not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA

function StringHelper(Planet) {
    //[id, string, property (if present)]
    // append to innerhtml
    this.strings = [
        ["logo-container",_("Planet")],
        ["close-planet",_("Close Planet",_("data-tooltip")],
        ["planet-open-file",_("Open project from file",_("data-tooltip")],
        ["planet-new-project",_("New project",_("data-tooltip")],
        ["local-tab",_("Local")],
        ["global-tab",_("Global")],
        ["global-search",_("Search for a project",_("placeholder")],
        ["localtitle",_("My Projects")],
        ["publisher-ptitle",_("Publish Project")],
        ["publish-title-label",_("Project title")],
        ["publish-tags-label",_("Tags (max 5)")],
        ["publish-description-label",_("Description")],
        ["publisher-submit",_("Submit")],
        ["publisher-cancel",_("Cancel")],
        ["deleter-confirm",_("Delete \"\"?")],
        ["deleter-paragraph",_("Permanently delete project \"\"?")],
        ["deleter-button",_("Delete")],
        ["deleter-cancel",_("Cancel")],
        ["globaltitle",_("Explore Projects")],
        ["view-more-chips",_("View More")],
        ["option-recent",_("Most recent")],
        ["option-liked",_("Most liked")],
        ["option-downloaded",_("Most downloaded")],
        ["option-alphabetical",_("A-Z")],
        ["option-sort-by",_("Sort by")],
        ["load-more-projects",_("Load More Projects")],
        ["projectviewer-last-updated-heading",_("Last Updated")],
        ["projectviewer-date-heading",_("Creation Date")],
        ["projectviewer-downloads-heading",_("Number of Downloads:")],
        ["projectviewer-likes-heading",_("Number of Likes:")],
        ["projectviewer-tags-heading",_("Tags:")],
        ["projectviewer-description-heading",_("Description")],
        ["projectviewer-report-project",_("Report Project")],
        ["projectviewer-report-title",_("Report Project")],
        ["projectviewer-report-conduct",_("Report projects which violate the Sugar Labs Code of Conduct.")],
        ["projectviewer-report-reason",_("Reason for reporting project")],
        ["projectviewer-report-submit",_("Submit")],
        ["projectviewer-reportsubmit-title",_("Report Project")],
        ["projectviewer-report-close",_("Close")],
        ["projectviewer-download-file",_("Download as File")],
        ["projectviewer-open-mb",_("Open in Music Blocks")]
    ]

    this.init = function(){
        for (var i = 0; i<this.strings.length; i++){
            var obj = this.strings[i];
            var elem = document.getElementById(obj[0]);
            if (this.strings[i].length==3){
                elem.setAttribute(obj[2],obj[1]);
            } else {
                elem.innerHTML+=obj[1];
            }
        }
    };
};
<commit_msg>fix broken formatting<commit_after>// Copyright (c) 2018 Euan Ong
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the The GNU Affero General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// You should have received a copy of the GNU Affero General Public
// License along with this library; if not, write to the Free Software
// Foundation, 51 Franklin Street, Suite 500 Boston, MA 02110-1335 USA

function StringHelper(Planet) {
    //[id, string, property (if present)]
    // append to innerhtml
    this.strings = [
        ["logo-container",_("Planet")],
        ["close-planet",_("Close Planet"),"data-tooltip"],
        ["planet-open-file",_("Open project from file"),"data-tooltip"],
        ["planet-new-project",_("New project"),"data-tooltip"],
        ["local-tab",_("Local")],
        ["global-tab",_("Global")],
        ["global-search",_("Search for a project"),"placeholder"],
        ["localtitle",_("My Projects")],
        ["publisher-ptitle",_("Publish Project")],
        ["publish-title-label",_("Project title")],
        ["publish-tags-label",_("Tags (max 5)")],
        ["publish-description-label",_("Description")],
        ["publisher-submit",_("Submit")],
        ["publisher-cancel",_("Cancel")],
        ["deleter-confirm",_("Delete \"\"?")],
        ["deleter-paragraph",_("Permanently delete project \"\"?")],
        ["deleter-button",_("Delete")],
        ["deleter-cancel",_("Cancel")],
        ["globaltitle",_("Explore Projects")],
        ["view-more-chips",_("View More")],
        ["option-recent",_("Most recent")],
        ["option-liked",_("Most liked")],
        ["option-downloaded",_("Most downloaded")],
        ["option-alphabetical",_("A-Z")],
        ["option-sort-by",_("Sort by")],
        ["load-more-projects",_("Load More Projects")],
        ["projectviewer-last-updated-heading",_("Last Updated")],
        ["projectviewer-date-heading",_("Creation Date")],
        ["projectviewer-downloads-heading",_("Number of Downloads:")],
        ["projectviewer-likes-heading",_("Number of Likes:")],
        ["projectviewer-tags-heading",_("Tags:")],
        ["projectviewer-description-heading",_("Description")],
        ["projectviewer-report-project",_("Report Project")],
        ["projectviewer-report-title",_("Report Project")],
        ["projectviewer-report-conduct",_("Report projects which violate the Sugar Labs Code of Conduct.")],
        ["projectviewer-report-reason",_("Reason for reporting project")],
        ["projectviewer-report-submit",_("Submit")],
        ["projectviewer-reportsubmit-title",_("Report Project")],
        ["projectviewer-report-close",_("Close")],
        ["projectviewer-download-file",_("Download as File")],
        ["projectviewer-open-mb",_("Open in Music Blocks")]
    ]

    this.init = function(){
        for (var i = 0; i<this.strings.length; i++){
            var obj = this.strings[i];
            var elem = document.getElementById(obj[0]);
            if (this.strings[i].length==3){
                elem.setAttribute(obj[2],obj[1]);
            } else {
                elem.innerHTML+=obj[1];
            }
        }
    };
};
<|endoftext|>


<commit_before>/// <binding />
"use strict";
var gulp = require("gulp");
var concat = require("gulp-concat");
var sass = require('gulp-sass');
var rename = require("gulp-rename");
var uglify = require("gulp-uglify");
var bower = require('gulp-bower');
var clean = require("gulp-clean");
var ts = require("gulp-typescript");
var debug = require('gulp-debug');

// Set the global.Filename to override this
var OUTPUT_FILE_NAME = global.FileName || "site";

var BOWER_COMPONENTS = global.BowerComponents || "wwwroot/lib";

gulp.task("clean", ["clean:app", "clean:js", "clean:css"]);

gulp.task('clean:app', function () {
    return gulp.src('./wwwroot/app')
        .pipe(clean());
});

gulp.task("clean:js", function () {
    return gulp.src('./wwwroot/js/*.js')
        .pipe(clean());
});

gulp.task("clean:css", function () {
    return gulp.src("./wwwroot/css/*.css")
        .pipe(clean());
});

gulp.task("clean:bower", function () {
    return gulp.src('./' + BOWER_COMPONENTS + '')
        .pipe(clean());
});

gulp.task("concat", ["concat:js", "concat:css"]);

gulp.task('concat:js', ['clean:js', 'typescript'], function () {
    return gulp.src([
            './' + BOWER_COMPONENTS + '/jquery/dist/jquery.js',
            './' + BOWER_COMPONENTS + '/jquery-ui/jquery-ui.js',
            './' + BOWER_COMPONENTS + '/jquery-validation/dist/jquery.validate.js',
            './' + BOWER_COMPONENTS + '/jquery-validation/dist/additional-methods.js',
            './' + BOWER_COMPONENTS + '/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js',
            './' + BOWER_COMPONENTS + '/datatables.net/js/dataTables.js',
            './' + BOWER_COMPONENTS + '/datatables.net-buttons/js/*.js',
            './' + BOWER_COMPONENTS + '/system.js/dist/system.js',
            './wwwroot/app/iUS.UX/*.js'
    ])
    .pipe(debug())
        .pipe(concat(OUTPUT_FILE_NAME + '.js'))
        .pipe(gulp.dest('./wwwroot/js/'));
});

gulp.task('concat:css', ['clean:css', 'sass'], function () {
    return gulp.src([
            './' + BOWER_COMPONENTS + '/pure/pure.css',
            './' + BOWER_COMPONENTS + '/pure/grids-responsive.css',
            './' + BOWER_COMPONENTS + '/iUS.UX/fonts/icomoon/style.css',
            './' + BOWER_COMPONENTS + '/iUS.UX/css/external/jquery-ui.css',
            './' + BOWER_COMPONENTS + '/iUS.UX/css/external/jquery-ui.theme.css',
            './wwwroot/app/css/ius.css'
    ])
        .pipe(concat(OUTPUT_FILE_NAME + '.css'))
        .pipe(gulp.dest('./wwwroot/css/'));
});

gulp.task('uglify:js', ['concat:js'], function () {
    return gulp.src(['./wwwroot/js/*.js', '!./wwwroot/js/*.min.js'])
        .pipe(debug())
        .pipe(uglify())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest('./wwwroot/js/'));
});

gulp.task('sass', ['sass:ius'])

gulp.task('sass:ius', function () {
    return gulp.src('./' + BOWER_COMPONENTS + '/iUs.UX/scss/ius.scss')
        .pipe(sass())
        .pipe(rename("ius.css"))
        .pipe(gulp.dest('./wwwroot/app/css'));
});

gulp.task('typescript', ['typescript:ius'])

gulp.task('typescript:ius', function () {
    return gulp.src(['./' + BOWER_COMPONENTS + '/iUS.UX/typescript/**/*.ts'])
        .pipe(ts({
            noExternalResolve: false
        }))
        .pipe(gulp.dest('./wwwroot/app/iUS.UX'));
});

gulp.task('copyfonts', function () {
    return gulp.src(['./wwwroot/lib/iUS.UX/fonts/icomoon/fonts/**'])
      .pipe(debug())
      .pipe(gulp.dest('./wwwroot/css/fonts/'));
});

gulp.task('copyimages', function () {
    return gulp.src([ './wwwroot/lib/iUS.UX/images/**'])
      .pipe(debug())
      .pipe(gulp.dest('./wwwroot/images/'));
});

gulp.task('watch', function () {
    gulp.watch('./wwwroot/**/*.ts', ['typescript']);
    gulp.watch('./wwwroot/**/*.scss', ['sass']);
});

<commit_msg>Fixing reference to datatables<commit_after>/// <binding />
"use strict";
var gulp = require("gulp");
var concat = require("gulp-concat");
var sass = require('gulp-sass');
var rename = require("gulp-rename");
var uglify = require("gulp-uglify");
var bower = require('gulp-bower');
var clean = require("gulp-clean");
var ts = require("gulp-typescript");
var debug = require('gulp-debug');

// Set the global.Filename to override this
var OUTPUT_FILE_NAME = global.FileName || "site";

var BOWER_COMPONENTS = global.BowerComponents || "wwwroot/lib";

gulp.task("clean", ["clean:app", "clean:js", "clean:css"]);

gulp.task('clean:app', function () {
    return gulp.src('./wwwroot/app')
        .pipe(clean());
});

gulp.task("clean:js", function () {
    return gulp.src('./wwwroot/js/*.js')
        .pipe(clean());
});

gulp.task("clean:css", function () {
    return gulp.src("./wwwroot/css/*.css")
        .pipe(clean());
});

gulp.task("clean:bower", function () {
    return gulp.src('./' + BOWER_COMPONENTS + '')
        .pipe(clean());
});

gulp.task("concat", ["concat:js", "concat:css"]);

gulp.task('concat:js', ['clean:js', 'typescript'], function () {
    return gulp.src([
            './' + BOWER_COMPONENTS + '/jquery/dist/jquery.js',
            './' + BOWER_COMPONENTS + '/jquery-ui/jquery-ui.js',
            './' + BOWER_COMPONENTS + '/jquery-validation/dist/jquery.validate.js',
            './' + BOWER_COMPONENTS + '/jquery-validation/dist/additional-methods.js',
            './' + BOWER_COMPONENTS + '/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js',
            './' + BOWER_COMPONENTS + '/datatables.net/js/jquery.dataTables.js',
            './' + BOWER_COMPONENTS + '/datatables.net-buttons/js/dataTables.buttons.js',
            './' + BOWER_COMPONENTS + '/system.js/dist/system.js',
            './wwwroot/app/iUS.UX/*.js'
    ])
    .pipe(debug())
        .pipe(concat(OUTPUT_FILE_NAME + '.js'))
        .pipe(gulp.dest('./wwwroot/js/'));
});

gulp.task('concat:css', ['clean:css', 'sass'], function () {
    return gulp.src([
            './' + BOWER_COMPONENTS + '/pure/pure.css',
            './' + BOWER_COMPONENTS + '/pure/grids-responsive.css',
            './' + BOWER_COMPONENTS + '/iUS.UX/fonts/icomoon/style.css',
            './' + BOWER_COMPONENTS + '/iUS.UX/css/external/jquery-ui.css',
            './' + BOWER_COMPONENTS + '/iUS.UX/css/external/jquery-ui.theme.css',
            './wwwroot/app/css/ius.css'
    ])
        .pipe(concat(OUTPUT_FILE_NAME + '.css'))
        .pipe(gulp.dest('./wwwroot/css/'));
});

gulp.task('uglify:js', ['concat:js'], function () {
    return gulp.src(['./wwwroot/js/*.js', '!./wwwroot/js/*.min.js'])
        .pipe(debug())
        .pipe(uglify())
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulp.dest('./wwwroot/js/'));
});

gulp.task('sass', ['sass:ius'])

gulp.task('sass:ius', function () {
    return gulp.src('./' + BOWER_COMPONENTS + '/iUs.UX/scss/ius.scss')
        .pipe(sass())
        .pipe(rename("ius.css"))
        .pipe(gulp.dest('./wwwroot/app/css'));
});

gulp.task('typescript', ['typescript:ius'])

gulp.task('typescript:ius', function () {
    return gulp.src(['./' + BOWER_COMPONENTS + '/iUS.UX/typescript/**/*.ts'])
        .pipe(ts({
            noExternalResolve: false
        }))
        .pipe(gulp.dest('./wwwroot/app/iUS.UX'));
});

gulp.task('copyfonts', function () {
    return gulp.src(['./wwwroot/lib/iUS.UX/fonts/icomoon/fonts/**'])
      .pipe(debug())
      .pipe(gulp.dest('./wwwroot/css/fonts/'));
});

gulp.task('copyimages', function () {
    return gulp.src([ './wwwroot/lib/iUS.UX/images/**'])
      .pipe(debug())
      .pipe(gulp.dest('./wwwroot/images/'));
});

gulp.task('watch', function () {
    gulp.watch('./wwwroot/**/*.ts', ['typescript']);
    gulp.watch('./wwwroot/**/*.scss', ['sass']);
});

<|endoftext|>


<commit_before>// return a mapping from sites => markers
Map.layer_calculators['agents'] = function(){
  var mapping = {};
  $.each(This.agents, function(){
    var id = this.id;
    var marker = new google.maps.Marker({
      icon: 'i/map/' + this.map_icon + '.png',
      position: new google.maps.LatLng(this.lat, this.lng),
      shadow: new google.maps.MarkerImage("i/map/man.shadow.png",
        null,
        null,
        new google.maps.Point(15, 32)
      ),
      title: this.title
    });
    google.maps.event.addListener(marker, 'click', function() { go('@' + id); });
    google.maps.event.addListener(marker, 'dblclick', function() {
      GM.setCenter( marker.getPosition(), 15 );
    });
    mapping[this.id] = marker;
  });
  return mapping;
};
<commit_msg>hide overflow agents<commit_after>// return a mapping from sites => markers
Map.layer_calculators['agents'] = function(){
  var mapping = {};
  $.each(This.agents, function(){
    if (this.hidden) return;
    var id = this.id;
    var marker = new google.maps.Marker({
      icon: 'i/map/' + this.map_icon + '.png',
      position: new google.maps.LatLng(this.lat, this.lng),
      shadow: new google.maps.MarkerImage("i/map/man.shadow.png",
        null,
        null,
        new google.maps.Point(15, 32)
      ),
      title: this.title
    });
    google.maps.event.addListener(marker, 'click', function() { go('@' + id); });
    google.maps.event.addListener(marker, 'dblclick', function() {
      GM.setCenter( marker.getPosition(), 15 );
    });
    mapping[this.id] = marker;
  });
  return mapping;
};
<|endoftext|>


<commit_before>const request = require('request');
const config = require('./config');
const db = require('./db');
const { promisify } = require('util');
const reqAsync = promisify(request);
const path = require('path');
const debug = require('./debug');
const REGEX_RAW_GIST_URL = /^https?:\/\/gist\.githubusercontent\.com\/(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+\..+)$/i;
const CDN_URL = 'https://cdn.staticaly.com/gist';
const GIT_API_URL = 'https://api.github.com/';
const REGISTRY_URL = 'https://registry.npmjs.org/';
const GEO_IP = 'http://freegeoip.net/json/';

const pkgApi = async (repo, pkg) => {
  try {
    const res = await reqAsync(`https://umdfied-cdn.herokuapp.com/standalone/${repo}`);

    if (res.statusCode === 200 && res.body) {
      const cdnlink = await createGist(pkg, res.body);
      return cdnlink;
    }
    return false;
  } catch (e) {
    console.error(e.stack || e.message)
    return false;
  }
};
const validatePackage = async (pkg, ver) => {
  try {
    let payload = false;
    const isOrg = /^@/.test(pkg);
    pkg = encodeURIComponent(pkg);
    if (!isOrg) {
      ver = !ver ? 'latest' : ver;
      const res = await reqAsync(`${REGISTRY_URL + pkg}/${ver}`);
      const body = JSON.parse(res.body);
      if (res.statusCode === 200 && body) {
        payload = { name: body.name, version: body.version };
      }
    }else{
      if(ver && !/^v/.test(ver) && ver !== 'latest') {
        ver = `v${ver}`
      }else if (ver && ver === 'latest') {
        ver = ''
      }
      const res = await reqAsync(`${REGISTRY_URL + pkg}/${ver}`);
      const body = JSON.parse(res.body);
      if (res.statusCode === 200 && body) {
        payload = { name: body.name, version: ver ? body.version: body['dist-tags'].latest };
      }
    }
    return payload;
  } catch (e) {
    console.error(e.stack || e.message)
    return false;
  }
};
const createGist = async (pkg, content) => {
  try {
    const data = {
      'description': `Umdfied build of ${pkg}`,
      'public': true,
      'files': {}
    };
    pkg = pkg.replace(/@/,'').replace(/\//,'-')
    const fname = `${pkg}.min.js`;
    data.files[fname] = { content };

    const reqOpts = {
      method: 'POST',
      url: '/gists',
      headers: {
        'Authorization': `token ${config.GIT_TOKEN}`,
        'User-Agent': 'Umdfied-App'
      },
      baseUrl: GIT_API_URL,
      json: true,
      body: data
    };
    const res = await reqAsync(reqOpts);

    const body = res.body;
    debug(body, 'createGist');
    let cdnurl = body.files[fname].raw_url.replace(REGEX_RAW_GIST_URL, `${CDN_URL}/$1`);
    return cdnurl;
  } catch (e) {
    console.log(e);
  }
};
const getCountry = async ip => {
  try {
    const res = await reqAsync({ url: GEO_IP + ip, json: true });

    const country = res.body.country_name;
    if (country) {
      return country;
    }
    return 'anonymous';
  } catch (e) {
    return 'anonymous';
  }
};
const normalizeIp = ip => ip.replace(/^::ffff:/i, '');
const updateCdn = function(cdnurl) {
  return cdnurl.replace(/(cdn\.rawgit\.com|gistcdn\.githack\.com)/, 'cdn.staticaly.com/gist')
}
exports.umdfied = async (pkg, ver, ip) => {
  try {
    ip = normalizeIp(ip);
    const usrCountry = await getCountry(ip);
    debug(usrCountry, 'usrCountry');
    await db.saveUsrInfo({ ip, country: usrCountry });
    console.log('Checking DB', 'db');
    const repoInfo = await validatePackage(pkg, ver);
    if (!repoInfo) {
      return false;
    }
    let fromDb = await db.getPkg(repoInfo.name, repoInfo.version);
    if (fromDb && (fromDb.cdn.includes('rawgit.com') || fromDb.cdn.includes('githack.com'))) {
      fromDb = await db.updatePkg(repoInfo.name, repoInfo.version, updateCdn(fromDb.cdn));
    }
    if (fromDb) {
      return { gitCdn: fromDb.cdn, semver: fromDb.version };
    }
    const repo = `${encodeURIComponent(repoInfo.name)}@${repoInfo.version}`;
    console.log(repo, 'repo');
    const gitCdn = await pkgApi(repo, pkg);
    console.log(gitCdn, 'gitCdn');
    if (!gitCdn) {
      return false;
    }
    await db.savePkg(repoInfo.name, repoInfo.version, gitCdn);
    return { gitCdn, semver: repoInfo.version };
  } catch (e) {
    console.error(`${e.message}\n${e.stack}`, 'umdfied Error');
    return false;
  }
};
<commit_msg>fix depreciated geo url<commit_after>const request = require('request');
const config = require('./config');
const db = require('./db');
const { promisify } = require('util');
const reqAsync = promisify(request);
const path = require('path');
const debug = require('./debug');
const REGEX_RAW_GIST_URL = /^https?:\/\/gist\.githubusercontent\.com\/(.+?\/[0-9a-f]+\/raw\/(?:[0-9a-f]+\/)?.+\..+)$/i;
const CDN_URL = 'https://cdn.staticaly.com/gist';
const GIT_API_URL = 'https://api.github.com/';
const REGISTRY_URL = 'https://registry.npmjs.org/';
const GEO_IP = 'https://api.ipgeolocation.io/ipgeo';

const pkgApi = async (repo, pkg) => {
  try {
    const res = await reqAsync(`https://umdfied-cdn.herokuapp.com/standalone/${repo}`);

    if (res.statusCode === 200 && res.body) {
      const cdnlink = await createGist(pkg, res.body);
      return cdnlink;
    }
    return false;
  } catch (e) {
    console.error(e.stack || e.message)
    return false;
  }
};
const validatePackage = async (pkg, ver) => {
  try {
    let payload = false;
    const isOrg = /^@/.test(pkg);
    pkg = encodeURIComponent(pkg);
    if (!isOrg) {
      ver = !ver ? 'latest' : ver;
      const res = await reqAsync(`${REGISTRY_URL + pkg}/${ver}`);
      const body = JSON.parse(res.body);
      if (res.statusCode === 200 && body) {
        payload = { name: body.name, version: body.version };
      }
    }else{
      if(ver && !/^v/.test(ver) && ver !== 'latest') {
        ver = `v${ver}`
      }else if (ver && ver === 'latest') {
        ver = ''
      }
      const res = await reqAsync(`${REGISTRY_URL + pkg}/${ver}`);
      const body = JSON.parse(res.body);
      if (res.statusCode === 200 && body) {
        payload = { name: body.name, version: ver ? body.version: body['dist-tags'].latest };
      }
    }
    return payload;
  } catch (e) {
    console.error(e.stack || e.message)
    return false;
  }
};
const createGist = async (pkg, content) => {
  try {
    const data = {
      'description': `Umdfied build of ${pkg}`,
      'public': true,
      'files': {}
    };
    pkg = pkg.replace(/@/,'').replace(/\//,'-')
    const fname = `${pkg}.min.js`;
    data.files[fname] = { content };

    const reqOpts = {
      method: 'POST',
      url: '/gists',
      headers: {
        'Authorization': `token ${config.GIT_TOKEN}`,
        'User-Agent': 'Umdfied-App'
      },
      baseUrl: GIT_API_URL,
      json: true,
      body: data
    };
    const res = await reqAsync(reqOpts);

    const body = res.body;
    debug(body, 'createGist');
    let cdnurl = body.files[fname].raw_url.replace(REGEX_RAW_GIST_URL, `${CDN_URL}/$1`);
    return cdnurl;
  } catch (e) {
    console.log(e);
  }
};
const getCountry = async ip => {
  try {
    const geourl = `${GEO_IP}?apiKey=${process.env.GEO_KEY}&ip=${ip}&fields=geo`
    const res = await reqAsync({ url: geourl, json: true });

    const country = res.body.country_name;
    if (country) {
      return country;
    }
    return 'anonymous';
  } catch (e) {
    return 'anonymous';
  }
};
const normalizeIp = ip => ip.replace(/^::ffff:/i, '');
const updateCdn = function(cdnurl) {
  return cdnurl.replace(/(cdn\.rawgit\.com|gistcdn\.githack\.com)/, 'cdn.staticaly.com/gist')
}
exports.umdfied = async (pkg, ver, ip) => {
  try {
    ip = normalizeIp(ip);
    const usrCountry = await getCountry(ip);
    debug(usrCountry, 'usrCountry');
    await db.saveUsrInfo({ ip, country: usrCountry });
    console.log('Checking DB', 'db');
    const repoInfo = await validatePackage(pkg, ver);
    if (!repoInfo) {
      return false;
    }
    let fromDb = await db.getPkg(repoInfo.name, repoInfo.version);
    if (fromDb && (fromDb.cdn.includes('rawgit.com') || fromDb.cdn.includes('githack.com'))) {
      fromDb = await db.updatePkg(repoInfo.name, repoInfo.version, updateCdn(fromDb.cdn));
    }
    if (fromDb) {
      return { gitCdn: fromDb.cdn, semver: fromDb.version };
    }
    const repo = `${encodeURIComponent(repoInfo.name)}@${repoInfo.version}`;
    console.log(repo, 'repo');
    const gitCdn = await pkgApi(repo, pkg);
    console.log(gitCdn, 'gitCdn');
    if (!gitCdn) {
      return false;
    }
    await db.savePkg(repoInfo.name, repoInfo.version, gitCdn);
    return { gitCdn, semver: repoInfo.version };
  } catch (e) {
    console.error(`${e.message}\n${e.stack}`, 'umdfied Error');
    return false;
  }
};
<|endoftext|>


<commit_before>/**
 * @file Tbody component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import Tr from '../_Tr';

// Statics
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import Util from '../_vendors/Util';

class Tbody extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    isItemChecked = rowData => {

        const {selectMode, idProp, value} = this.props;

        if (!rowData || !value || selectMode === SelectMode.NORMAL) {
            return false;
        }

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                return value && value.findIndex(item => item[idProp] === rowData[idProp]) !== -1;
            case SelectMode.SINGLE_SELECT:
                return value[idProp] === rowData[idProp];
        }

    };

    handleTrMouseEnter = (e, rowIndex) => {
        const {onRowHover} = this.props;
        onRowHover && onRowHover(rowIndex);
    };

    handleTrMouseLeave = (e, rowIndex) => {
        const {onRowHover} = this.props;
        onRowHover && onRowHover(null);
    };

    render() {

        const {

            className, style, columns, data, startIndex, idProp, disabled, isMouseEventForbidden,

            // not passing down these props
            value,

            ...restProps

        } = this.props;

        return (
            <tbody className={className}
                   style={style}>
                {
                    data && data.map((row, index) => row ?
                        <Tr {...restProps}
                            key={idProp && idProp in row ? row[idProp] : index}
                            index={index}
                            rowIndex={startIndex + index}
                            columns={columns}
                            data={row}
                            tableData={data}
                            isChecked={this.isItemChecked(row)}
                            disabled={disabled || row.disabled}
                            isMouseEventForbidden={isMouseEventForbidden}
                            onMouseEnter={this.handleTrMouseEnter}
                            onMouseLeave={this.handleTrMouseLeave}/>
                        :
                        null
                    )
                }
            </tbody>
        );

    }
}

Tbody.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired,

    data: PropTypes.array,
    value: PropTypes.array,
    hoverRowIndex: PropTypes.number,
    startIndex: PropTypes.number,
    idProp: PropTypes.string,
    disabled: PropTypes.bool,
    baseColIndex: PropTypes.number,
    expandRows: PropTypes.array,
    isMouseEventForbidden: PropTypes.bool,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),

    /**
     * callback
     */
    onRowClick: PropTypes.func,
    onCellClick: PropTypes.func,
    onRowHover: PropTypes.func,
    onExpand: PropTypes.func,
    onCollapse: PropTypes.func

};

Tbody.defaultProps = {
    selectMode: SelectMode.SINGLE_SELECT,
    startIndex: 0,
    idProp: 'id',
    disabled: false,
    baseColIndex: 0,
    expandRows: [],
    isMouseEventForbidden: false
};

export default Tbody;
<commit_msg>update Tbody<commit_after>/**
 * @file Tbody component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

// Components
import Tr from '../_Tr';

// Statics
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

// Vendors
import Util from '../_vendors/Util';

class Tbody extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    isItemChecked = rowData => {

        const {selectMode, idProp, value} = this.props;

        if (!rowData || !value || selectMode === SelectMode.NORMAL) {
            return false;
        }

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                return value && value.findIndex(item => item[idProp] === rowData[idProp]) !== -1;
            case SelectMode.SINGLE_SELECT:
                return value[idProp] === rowData[idProp];
        }

    };

    handleTrMouseEnter = (e, rowData) => {
        const {onRowHover} = this.props;
        onRowHover && onRowHover(rowData);
    };

    handleTrMouseLeave = () => {
        const {onRowHover} = this.props;
        onRowHover && onRowHover(null);
    };

    render() {

        const {

            className, style, columns, data, startIndex, idProp, disabled, isMouseEventForbidden,

            // not passing down these props
            value,

            ...restProps

        } = this.props;

        return (
            <tbody className={className}
                   style={style}>
                {
                    data && data.map((row, index) => row ?
                        <Tr {...restProps}
                            key={idProp && idProp in row ? row[idProp] : index}
                            index={index}
                            rowIndex={startIndex + index}
                            columns={columns}
                            data={row}
                            tableData={data}
                            isChecked={this.isItemChecked(row)}
                            disabled={disabled || row.disabled}
                            isMouseEventForbidden={isMouseEventForbidden}
                            onMouseEnter={this.handleTrMouseEnter}
                            onMouseLeave={this.handleTrMouseLeave}/>
                        :
                        null
                    )
                }
            </tbody>
        );

    }
}

Tbody.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( 'left' / 'right' ).
         */
        fixed: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex, parentData, tableData, collapsed, depth, path) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired,

    data: PropTypes.array,
    value: PropTypes.array,
    hoverRow: PropTypes.object,
    startIndex: PropTypes.number,
    idProp: PropTypes.string,
    disabled: PropTypes.bool,
    baseColIndex: PropTypes.number,
    expandRows: PropTypes.array,
    isMouseEventForbidden: PropTypes.bool,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),

    /**
     * callback
     */
    onRowClick: PropTypes.func,
    onCellClick: PropTypes.func,
    onRowHover: PropTypes.func,
    onExpand: PropTypes.func,
    onCollapse: PropTypes.func

};

Tbody.defaultProps = {
    selectMode: SelectMode.SINGLE_SELECT,
    startIndex: 0,
    idProp: 'id',
    disabled: false,
    baseColIndex: 0,
    expandRows: [],
    isMouseEventForbidden: false
};

export default Tbody;
<|endoftext|>