<commit_before>  /**
   * Shows a dialog to start merging two tables
   *  new MergeTablesDialog({
   *    model: table
   *  })
   *
   */

  cdb.admin.MergeTablesDialog = cdb.admin.BaseDialog.extend({

    FILTERED_COLUMNS: [
      'cartodb_id',
      'created_at',
      'updated_at',
      'the_geom_webmercator',
      'cartodb_georef_status'
    ],

    events: function(){
      return _.extend({},cdb.admin.BaseDialog.prototype.events,{
        "keydown input":              "_onKeyDown" //,
        //"click ul.join_types li a":   "_selectJoinType"
      });
    },

    initialize: function() {

      _.bindAll(this, "_onKeyDown", "_checkKeyColumns");

      _.extend(this.options, {
        template_name: 'table/views/merge_tables_dialog_base',
        title: _t("Merge with another table"),
        description: _t("Merges let use join two tables by a common column and get a new table as result."),
        clean_on_hide: true,
        cancel_button_classes: "margin15",
        ok_button_classes: "button disabled grey",
        ok_title: _t("Next"),
        modal_type: "creation tables_selector",
        width: 633,
        modal_class: 'merge_tables_dialog'
      });

      this.constructor.__super__.initialize.apply(this);

      this.join_type  = "regular";
      this.state      = 0;
      this.enabled    = false;
      this.table_name = this.model.get("name") + "_merge";
    },

    render_content: function() {
      var $content = $(this.getTemplate('table/views/merge_tables_content')(this.model.toJSON()));

      // Create actual table column preview
      var actual_table = this.actual_table = new cdb.admin.TableColumnSelector({
        el: $content.find('.actual_table'),
        model: this.model,
        choose_table_text: '',
        filteredColumns: this.FILTERED_COLUMNS,
        joinType: 'regular'
      })
        .render()
        .bind('keyColumnChanged', this._checkKeyColumns);

      this.addView(actual_table);

      // Create merge table component
      var merge_table = this.merge_table = new cdb.admin.TableColumnSelector({
        el: $content.find('.merge_table'),
        url: '/api/v1/tables/',
        choose_table_text: 'Choose a table to merge with ' + this.model.get("name"),
        filteredColumns: this.FILTERED_COLUMNS,
        filteredTables: [this.model.get('name')],
        joinType: 'regular'
      })
        .render()
        .bind('keyColumnChanged', this._checkKeyColumns);

      this.addView(merge_table);

      return $content;
    },

    /**
     * STATE 1 - Selecting tables > columns
     */

    // Check if there are two key columns
    // if not, disable next step
    _checkKeyColumns: function() {
      var $ok_button = this.$el.find("section:eq(0) a.ok");

      if (this.merge_table.keyColumn && this.actual_table.keyColumn) {
        this.enabled = true;
        $ok_button.removeClass('disabled');
        // this._checkAffectedRows();
      } else {
        this.enabled = false;
        $ok_button.addClass('disabled');
      }
    },

    // Select a join type
    _selectJoinType: function(e) {
      this.killEvent(e);
      var $a  = $(e.target).closest("a")
        , $li = $a.closest("li")
        , $ul = $li.closest("ul");

      // Animate first change
      this._animateFirst();

      // Change selected
      $ul.find("a")
        .removeClass("selected")
        .addClass("inactive");

      $a.addClass("selected")
        .removeClass("inactive");

      // If already selected -> go
      if ($li.attr("class") == this.join_type) return false;

      // Set new join
      this.join_type = $li.attr("class");

      // Change table selectors
      this.actual_table.setJoinType(this.join_type);
      this.merge_table.setJoinType(this.join_type);
    },

    // Animate fist interaction, clicking first time
    _animateFirst: function() {
      var $selector = this.$el.find("section:eq(0) div.selector");
      if (!$selector.find('div.tables').is("visible")) {

        $selector.find("ul.join_types").animate({marginTop:0},250);
        $selector.parent()
          .animate({
            height: 380
          },250)
          .find('div.tables')
          .animate({
            opacity:1
          },250);

        $selector.find("p.intro")
          .animate({
            height:0,
            opacity:0
          },250);
      }
    },

    // Check how many rows will be created when merge those tables :)
    _checkAffectedRows: function() {
      this.$el.find('p.approx_rows').hide();

      $.ajax({
        type: "PUT",
        url: '/api/v1/queries/',
        dataType: 'jsonp',
        data: {
          sql: this._generateSQL(),
          rows_per_page: null
        },
        success: function(r) {
          console.log(r);
        },
        error: function(e) {
          console.log(e);
        }
      });

      this.$el.find('p.approx_rows').show();
    },

    /**
     * STATE 2 - Choosing new table name
     */

    // Focus over text input
    _focusInput: function() {
      // Hack to prevent animation remove input focus
      var self = this
        , $input = self.$el.find("section.naming input.text");

      $input.val(this.model.get("name") + "_merge");

      setTimeout(function() {
        $input.focus()
      });
    },

    // Check merge name
    _checkMergeName: function(table_name, merge_table_name) {
      if (merge_table_name.length > 0 && table_name != merge_table_name) {
        return true
      } else {
        return false
      }
    },

    // On key down
    _onKeyDown: function(ev) {
      var merge_table_name = $(ev.target).val();

      if (ev.keyCode === 13) {
        if (this._checkMergeName(this.model.get("name"),merge_table_name)) {
          this._toggleInputError(false);
          this.table_name = merge_table_name;
          this._ok();
        } else {
          this._toggleInputError(true);
        }

      }
    },

    // Show or hide input error
    _toggleInputError: function(active) {
      if (active) {
        this.$el.find("div.info").addClass("active");
      } else {
        this.$el.find("div.info").removeClass("active");
      }
    },

    /**
     *  STATE 3 - Merging
     */

    // Generate the necessary SQL
    _generateSQL: function() {
      var sql   = "SELECT "
        , self  = this;

      // Add actual table columns
      _.each(this.actual_table.mergeColumns, function(col){
        sql += self.actual_table.table_name + "." + col + ",";
      });

      // Add merge table columns
      _.each(this.merge_table.mergeColumns, function(col){
        sql += self.merge_table.table_name + "." + col + " ";
        // If the column is already present in the actual_table
        if (_.contains(self.actual_table.mergeColumns, col)) {
          sql += " AS " + self.merge_table.table_name + "_" + col;
        }
        sql += ",";
      });

      // Remove last comma
      sql = sql.slice(0,sql.length-1);

      // LEFT JOIN
      sql += " FROM " + this.actual_table.table_name + " LEFT JOIN " + this.merge_table.table_name + " ON ";

      // JOIN FIELD
      sql += this.actual_table.table_name + "." + this.actual_table.keyColumn + "=" + this.merge_table.table_name + "." + this.merge_table.keyColumn;

      return sql;
    },

    // Start duplication of the table
    _startMerging: function() {
      var self = this
        , data = {
          table_name: this.table_name,
          sql: this._generateSQL()
        }

      $.ajax({
        type: "POST",
        url: "/api/v1/imports",
        data: data,
        success: function(r) {
          self._importCopy(r.item_queue_id)
        },
        error: function(e) {
          try {
            self._showError(e.attributes.error_code,e.attributes.get_error_text.title,e.attributes.get_error_text.what_about);
          } catch(e) {
            self._showError('99999','Unknown', 'Sorry, something went wrong and we\'re not sure what. Contact us at contact@cartodb.com.');
          }

        }
      });
    },

    // Starts duplication copy
    _importCopy: function(item_queue_id) {
      var self = this
        , imp = this.importation = new cdb.admin.Import({item_queue_id: item_queue_id})
              .bind("importComplete", function(e){
                imp.unbind();
                window.location.href = "/tables/" + imp.get("table_id") + "/";
              },this)
              .bind("importError", function(e){
                self._showError(e.attributes.error_code,e.attributes.get_error_text.title,e.attributes.get_error_text.what_about);
              },this);

      imp.pollCheck();
    },

    /**
     *  STATE 4 - Merging error :S
     */

    //Show the error when duplication fails
    _showError: function(number,description,wadus) {
      // Add data
      var template = cdb.templates.getTemplate("dashboard/views/error_dialog_content")
        , opts = {number: number, description: description, about:wadus};

      this.$el.find("div.error_content").html(template(opts));

      // Show error and hide importation window
      this._changeState();
    },

    /**
     *  GENERIC
     */

    // Changes state, just animate the change and add to state 1 (yes, always it goes forward, never backward)
    _changeState: function() {
      // Next state
      this.$el.find(".modal:eq(0)").animate({
        opacity: 0,
        marginTop: 0,
        height: 0,
        top: 0
      },function(){
        $(this).remove();
      });

      this.$el.find(".modal:eq(1)")
        .css({
          opacity:0,
          display:"block",
          marginTop: "0px"
        })
        .animate({
          opacity: 1,
          marginTop: "100px"
        },600);
    },

    // ESC prevent event
    _keydown: function(e) {
      // If clicks esc, goodbye unless select is opened!
      if (e.keyCode === 27) {
        if (!$('.select2-drop-active').is(':visible')) {
          this._cancel();
        } else {
          this.$el.find('select').select2('close')
        }

      // If clicks enter, same as you click on ok button.
      } else if (e.keyCode === 13 && this.options.enter_to_confirm) {
        this._ok();
      }
    },

    // When clicks on ok button or submit input
    _ok: function(ev) {
      if (ev) {ev.preventDefault()}
      if (!this.enabled) return false;

      // New state
      ++this.state;

      // Depending state
      switch (this.state) {
        case 1: this._focusInput();   break;
        case 2: this._startMerging(); break;
        default:
      }

      this._changeState();
    }
  });<commit_msg>fixed merge-tables dialog position<commit_after>  /**
   * Shows a dialog to start merging two tables
   *  new MergeTablesDialog({
   *    model: table
   *  })
   *
   */

  cdb.admin.MergeTablesDialog = cdb.admin.BaseDialog.extend({

    FILTERED_COLUMNS: [
      'cartodb_id',
      'created_at',
      'updated_at',
      'the_geom_webmercator',
      'cartodb_georef_status'
    ],

    events: function(){
      return _.extend({},cdb.admin.BaseDialog.prototype.events,{
        "keydown input":              "_onKeyDown" //,
        //"click ul.join_types li a":   "_selectJoinType"
      });
    },

    initialize: function() {

      _.bindAll(this, "_onKeyDown", "_checkKeyColumns");

      _.extend(this.options, {
        template_name: 'table/views/merge_tables_dialog_base',
        title: _t("Merge with another table"),
        description: _t("Merges let use join two tables by a common column and get a new table as result."),
        clean_on_hide: true,
        cancel_button_classes: "margin15",
        ok_button_classes: "button disabled grey",
        ok_title: _t("Next"),
        modal_type: "creation tables_selector",
        width: 633,
        modal_class: 'merge_tables_dialog'
      });

      this.constructor.__super__.initialize.apply(this);

      this.join_type  = "regular";
      this.state      = 0;
      this.enabled    = false;
      this.table_name = this.model.get("name") + "_merge";
    },

    render_content: function() {
      var $content = $(this.getTemplate('table/views/merge_tables_content')(this.model.toJSON()));

      // Create actual table column preview
      var actual_table = this.actual_table = new cdb.admin.TableColumnSelector({
        el: $content.find('.actual_table'),
        model: this.model,
        choose_table_text: '',
        filteredColumns: this.FILTERED_COLUMNS,
        joinType: 'regular'
      })
        .render()
        .bind('keyColumnChanged', this._checkKeyColumns);

      this.addView(actual_table);

      // Create merge table component
      var merge_table = this.merge_table = new cdb.admin.TableColumnSelector({
        el: $content.find('.merge_table'),
        url: '/api/v1/tables/',
        choose_table_text: 'Choose a table to merge with ' + this.model.get("name"),
        filteredColumns: this.FILTERED_COLUMNS,
        filteredTables: [this.model.get('name')],
        joinType: 'regular'
      })
        .render()
        .bind('keyColumnChanged', this._checkKeyColumns);

      this.addView(merge_table);

      return $content;
    },

    /**
     * STATE 1 - Selecting tables > columns
     */

    // Check if there are two key columns
    // if not, disable next step
    _checkKeyColumns: function() {
      var $ok_button = this.$el.find("section:eq(0) a.ok");

      if (this.merge_table.keyColumn && this.actual_table.keyColumn) {
        this.enabled = true;
        $ok_button.removeClass('disabled');
        // this._checkAffectedRows();
      } else {
        this.enabled = false;
        $ok_button.addClass('disabled');
      }
    },

    // Select a join type
    _selectJoinType: function(e) {
      this.killEvent(e);
      var $a  = $(e.target).closest("a")
        , $li = $a.closest("li")
        , $ul = $li.closest("ul");

      // Animate first change
      this._animateFirst();

      // Change selected
      $ul.find("a")
        .removeClass("selected")
        .addClass("inactive");

      $a.addClass("selected")
        .removeClass("inactive");

      // If already selected -> go
      if ($li.attr("class") == this.join_type) return false;

      // Set new join
      this.join_type = $li.attr("class");

      // Change table selectors
      this.actual_table.setJoinType(this.join_type);
      this.merge_table.setJoinType(this.join_type);
    },

    // Animate fist interaction, clicking first time
    _animateFirst: function() {
      var $selector = this.$el.find("section:eq(0) div.selector");
      if (!$selector.find('div.tables').is("visible")) {

        $selector.find("ul.join_types").animate({marginTop:0},250);
        $selector.parent()
          .animate({
            height: 380
          },250)
          .find('div.tables')
          .animate({
            opacity:1
          },250);

        $selector.find("p.intro")
          .animate({
            height:0,
            opacity:0
          },250);
      }
    },

    // Check how many rows will be created when merge those tables :)
    _checkAffectedRows: function() {
      this.$el.find('p.approx_rows').hide();

      $.ajax({
        type: "PUT",
        url: '/api/v1/queries/',
        dataType: 'jsonp',
        data: {
          sql: this._generateSQL(),
          rows_per_page: null
        },
        success: function(r) {
          console.log(r);
        },
        error: function(e) {
          console.log(e);
        }
      });

      this.$el.find('p.approx_rows').show();
    },

    /**
     * STATE 2 - Choosing new table name
     */

    // Focus over text input
    _focusInput: function() {
      // Hack to prevent animation remove input focus
      var self = this
        , $input = self.$el.find("section.naming input.text");

      $input.val(this.model.get("name") + "_merge");

      setTimeout(function() {
        $input.focus()
      });
    },

    // Check merge name
    _checkMergeName: function(table_name, merge_table_name) {
      if (merge_table_name.length > 0 && table_name != merge_table_name) {
        return true
      } else {
        return false
      }
    },

    // On key down
    _onKeyDown: function(ev) {
      var merge_table_name = $(ev.target).val();

      if (ev.keyCode === 13) {
        if (this._checkMergeName(this.model.get("name"),merge_table_name)) {
          this._toggleInputError(false);
          this.table_name = merge_table_name;
          this._ok();
        } else {
          this._toggleInputError(true);
        }

      }
    },

    // Show or hide input error
    _toggleInputError: function(active) {
      if (active) {
        this.$el.find("div.info").addClass("active");
      } else {
        this.$el.find("div.info").removeClass("active");
      }
    },

    /**
     *  STATE 3 - Merging
     */

    // Generate the necessary SQL
    _generateSQL: function() {
      var sql   = "SELECT "
        , self  = this;

      // Add actual table columns
      _.each(this.actual_table.mergeColumns, function(col){
        sql += self.actual_table.table_name + "." + col + ",";
      });

      // Add merge table columns
      _.each(this.merge_table.mergeColumns, function(col){
        sql += self.merge_table.table_name + "." + col + " ";
        // If the column is already present in the actual_table
        if (_.contains(self.actual_table.mergeColumns, col)) {
          sql += " AS " + self.merge_table.table_name + "_" + col;
        }
        sql += ",";
      });

      // Remove last comma
      sql = sql.slice(0,sql.length-1);

      // LEFT JOIN
      sql += " FROM " + this.actual_table.table_name + " LEFT JOIN " + this.merge_table.table_name + " ON ";

      // JOIN FIELD
      sql += this.actual_table.table_name + "." + this.actual_table.keyColumn + "=" + this.merge_table.table_name + "." + this.merge_table.keyColumn;

      return sql;
    },

    // Start duplication of the table
    _startMerging: function() {
      var self = this
        , data = {
          table_name: this.table_name,
          sql: this._generateSQL()
        }

      $.ajax({
        type: "POST",
        url: "/api/v1/imports",
        data: data,
        success: function(r) {
          self._importCopy(r.item_queue_id)
        },
        error: function(e) {
          try {
            self._showError(e.attributes.error_code,e.attributes.get_error_text.title,e.attributes.get_error_text.what_about);
          } catch(e) {
            self._showError('99999','Unknown', 'Sorry, something went wrong and we\'re not sure what. Contact us at contact@cartodb.com.');
          }

        }
      });
    },

    // Starts duplication copy
    _importCopy: function(item_queue_id) {
      var self = this
        , imp = this.importation = new cdb.admin.Import({item_queue_id: item_queue_id})
              .bind("importComplete", function(e){
                imp.unbind();
                window.location.href = "/tables/" + imp.get("table_id") + "/";
              },this)
              .bind("importError", function(e){
                self._showError(e.attributes.error_code,e.attributes.get_error_text.title,e.attributes.get_error_text.what_about);
              },this);

      imp.pollCheck();
    },

    /**
     *  STATE 4 - Merging error :S
     */

    //Show the error when duplication fails
    _showError: function(number,description,wadus) {
      // Add data
      var template = cdb.templates.getTemplate("dashboard/views/error_dialog_content")
        , opts = {number: number, description: description, about:wadus};

      this.$el.find("div.error_content").html(template(opts));

      // Show error and hide importation window
      this._changeState();
    },

    /**
     *  GENERIC
     */

    // Changes state, just animate the change and add to state 1 (yes, always it goes forward, never backward)
    _changeState: function() {
      // Next state
      this.$el.find(".modal:eq(0)").animate({
        opacity: 0,
        marginTop: 0,
        height: 0,
        top: 0
      },600,function(){
        $(this).remove();
      });

      this.$el.find(".modal:eq(1)")
        .css({
          opacity:0,
          display:"block",
          marginTop: "0px"
        })
        .animate({
          opacity: 1,
          marginTop: -200
        },600);
    },

    // ESC prevent event
    _keydown: function(e) {
      // If clicks esc, goodbye unless select is opened!
      if (e.keyCode === 27) {
        if (!$('.select2-drop-active').is(':visible')) {
          this._cancel();
        } else {
          this.$el.find('select').select2('close')
        }

      // If clicks enter, same as you click on ok button.
      } else if (e.keyCode === 13 && this.options.enter_to_confirm) {
        this._ok();
      }
    },

    // When clicks on ok button or submit input
    _ok: function(ev) {
      if (ev) {ev.preventDefault()}
      if (!this.enabled) return false;

      // New state
      ++this.state;

      // Depending state
      switch (this.state) {
        case 1: this._focusInput();   break;
        case 2: this._startMerging(); break;
        default:
      }

      this._changeState();
    }
  });<|endoftext|>


<commit_before>// Copyright 2012 YDN Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Some utilities on top of goog.object module.
 *
 */

goog.provide('ydn.string');

/**
 * Split comma sperated tokens. Token can be possibly double quoted token.
 * @param {string} str string to split.
 * @return {Array.<string>} list of tokens.
 */
ydn.string.split_comma_seperated = function(str) {
  return str.match(/(?:"[^"]*"|[^,])+/g);
};

/**
 * Split string by space separated, possibly double quoted, string.
 * @param {string} str string to be split.
 * @return {Array.<string>} resulting split string.
 */
ydn.string.split_space_seperated = function(str) {
  return str.match(/\w+|"[^"]+"/g);
};

/**
 * Split string by space separated, possibly single or double quoted, string.
 * @param {string} str string to be split.
 * @return {Array.<string>} quote preserved tokens.
 */
ydn.string.split_space = function(str) {
  return str.match(/[^\s"']+|"[^"]*"|'[^']*'/g);
};

/**
 * Normalize phone number.
 * @param {string} ph
 * @return {string?} null if not a valid email.
 */
ydn.string.normalizePhone = function(ph) {
  if (!goog.isString(ph)) {
    return null;
  }
  return ph.replace(/\D/g, '').replace(/^0+/, '');
};

/**
 * Normalize email address.
 * @param {string|*} email
 * @return {string?} null if not a valid email.
 */
ydn.string.normalizeEmail = function(email) {
  if (!goog.isString(email)) {
    return null;
  }
  if (!/[\w\+]+@\w+\.\w+/.test(email)) {
    return null;
  }
  // remove name from email label, such as 'brandi steel <brandiengage@gmail.com>'
  email = email.replace(/.*</, '').replace(/>.*/, '');
  email = email.toLowerCase();
  // remove + and . before @ sign
  // http://gmailblog.blogspot.sg/2008/03/2-hidden-ways-to-get-more-from-your.html
  email = email.replace(/\+\w*?@/, '@'); // normalize for gmail using +
  // should we be using regexp?
  for (var i = email.indexOf('@'); i >= 0; i--) {
    if (email.charAt(i) == '.') {
      email.slice(i, 1);
    }
  }
  return email;
};

/**
 * Join list of string by comma and lastly by word 'and'.
 * @param {Array.<string>} items
 * @return {string} string joining all items by comma separated and and.
 */
ydn.string.joinWithCommaAnd = function(items) {
  var n = items.length;
  if (n == 0) {
    return '';
  } else if (n == 1) {
    return items[0];
  } else if (n == 2) {
    return items[0] + ' and ' + items[1];
  } else {
    var city_name = items.slice(0, n - 2).join(', ');
    return city_name + ', ' + items[n - 2] + ' and ' + items[n - 1];
  }
};

/**
 * Converts an ArrayBuffer directly to base64, without any intermediate
 * 'convert to string then use window.btoa' step. According to my tests, this
 * appears to be a faster approach:
 * http://jsperf.com/encoding-xhr-image-data/5
 * https://gist.github.com/jonleighton/958841
 * @param {ArrayBuffer} arrayBuffer
 * @return {string}
 */
ydn.string.encodeArrayBuffer2base64 = function(arrayBuffer) {
  var base64 = '';
  var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

  var bytes = new Uint8Array(arrayBuffer);
  var byteLength = bytes.byteLength;
  var byteRemainder = byteLength % 3;
  var mainLength = byteLength - byteRemainder;

  var a, b, c, d;
  var chunk;

  // Main loop deals with bytes in chunks of 3
  for (var i = 0; i < mainLength; i = i + 3) {
    // Combine the three bytes into a single integer
    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];

    // Use bitmasks to extract 6-bit segments from the triplet
    a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18;
    b = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12;
    c = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6;
    d = chunk & 63;               // 63       = 2^6 - 1;

    // Convert the raw binary segments to the appropriate ASCII encoding
    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
  }

  // Deal with the remaining bytes and padding
  if (byteRemainder == 1) {
    chunk = bytes[mainLength];

    a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2

    // Set the 4 least significant bits to zero
    b = (chunk & 3) << 4; // 3   = 2^2 - 1

    base64 += encodings[a] + encodings[b] + '==';
  } else if (byteRemainder == 2) {
    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];

    a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
    b = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4

    // Set the 2 least significant bits to zero
    c = (chunk & 15) << 2; // 15    = 2^4 - 1

    base64 += encodings[a] + encodings[b] + encodings[c] + '=';
  }

  return base64;
};

<commit_msg>query similar<commit_after>// Copyright 2012 YDN Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Some utilities on top of goog.object module.
 *
 */

goog.provide('ydn.string');

/**
 * Split comma sperated tokens. Token can be possibly double quoted token.
 * @param {string} str string to split.
 * @return {Array.<string>} list of tokens.
 */
ydn.string.split_comma_seperated = function(str) {
  return str.match(/(?:"[^"]*"|[^,])+/g);
};

/**
 * Split string by space separated, possibly double quoted, string.
 * @param {string} str string to be split.
 * @return {Array.<string>} resulting split string.
 */
ydn.string.split_space_seperated = function(str) {
  return str.match(/\w+|"[^"]+"/g);
};

/**
 * Split string by space separated, possibly single or double quoted, string.
 * @param {string} str string to be split.
 * @return {Array.<string>} quote preserved tokens.
 */
ydn.string.split_space = function(str) {
  return str.match(/[^\s"']+|"[^"]*"|'[^']*'/g);
};

/**
 * Normalize phone number.
 * @param {string} ph
 * @return {?string} null if not a valid email.
 */
ydn.string.normalizePhone = function(ph) {
  if (!goog.isString(ph)) {
    return null;
  }
  return ph.replace(/\D/g, '').replace(/^0+/, '');
};

/**
 * Normalize email address.
 * @param {string|*} email
 * @return {?string} null if not a valid email.
 */
ydn.string.normalizeEmail = function(email) {
  if (!goog.isString(email)) {
    return null;
  }
  if (!/[\w\+]+@\w+\.\w+/.test(email)) {
    return null;
  }
  // remove name from email label, such as 'brandi steel <brandiengage@gmail.com>'
  email = email.replace(/.*</, '').replace(/>.*/, '');
  email = email.toLowerCase();
  // remove + and . before @ sign
  // http://gmailblog.blogspot.sg/2008/03/2-hidden-ways-to-get-more-from-your.html
  email = email.replace(/\+\w*?@/, '@'); // normalize for gmail using +
  // should we be using regexp?
  for (var i = email.indexOf('@'); i >= 0; i--) {
    if (email.charAt(i) == '.') {
      email.slice(i, 1);
    }
  }
  return email;
};

/**
 * Join list of string by comma and lastly by word 'and'.
 * @param {Array.<string>} items
 * @return {string} string joining all items by comma separated and and.
 */
ydn.string.joinWithCommaAnd = function(items) {
  var n = items.length;
  if (n == 0) {
    return '';
  } else if (n == 1) {
    return items[0];
  } else if (n == 2) {
    return items[0] + ' and ' + items[1];
  } else {
    var city_name = items.slice(0, n - 2).join(', ');
    return city_name + ', ' + items[n - 2] + ' and ' + items[n - 1];
  }
};

/**
 * Converts an ArrayBuffer directly to base64, without any intermediate
 * 'convert to string then use window.btoa' step. According to my tests, this
 * appears to be a faster approach:
 * http://jsperf.com/encoding-xhr-image-data/5
 * https://gist.github.com/jonleighton/958841
 * @param {ArrayBuffer} arrayBuffer
 * @return {string}
 */
ydn.string.encodeArrayBuffer2base64 = function(arrayBuffer) {
  var base64 = '';
  var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

  var bytes = new Uint8Array(arrayBuffer);
  var byteLength = bytes.byteLength;
  var byteRemainder = byteLength % 3;
  var mainLength = byteLength - byteRemainder;

  var a, b, c, d;
  var chunk;

  // Main loop deals with bytes in chunks of 3
  for (var i = 0; i < mainLength; i = i + 3) {
    // Combine the three bytes into a single integer
    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];

    // Use bitmasks to extract 6-bit segments from the triplet
    a = (chunk & 16515072) >> 18; // 16515072 = (2^6 - 1) << 18;
    b = (chunk & 258048) >> 12; // 258048   = (2^6 - 1) << 12;
    c = (chunk & 4032) >> 6; // 4032     = (2^6 - 1) << 6;
    d = chunk & 63;               // 63       = 2^6 - 1;

    // Convert the raw binary segments to the appropriate ASCII encoding
    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d];
  }

  // Deal with the remaining bytes and padding
  if (byteRemainder == 1) {
    chunk = bytes[mainLength];

    a = (chunk & 252) >> 2; // 252 = (2^6 - 1) << 2

    // Set the 4 least significant bits to zero
    b = (chunk & 3) << 4; // 3   = 2^2 - 1

    base64 += encodings[a] + encodings[b] + '==';
  } else if (byteRemainder == 2) {
    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1];

    a = (chunk & 64512) >> 10; // 64512 = (2^6 - 1) << 10
    b = (chunk & 1008) >> 4; // 1008  = (2^6 - 1) << 4

    // Set the 2 least significant bits to zero
    c = (chunk & 15) << 2; // 15    = 2^4 - 1

    base64 += encodings[a] + encodings[b] + encodings[c] + '=';
  }

  return base64;
};

<|endoftext|>


<commit_before>'use strict';

const BaseHistogram = require('./base-histogram');
const debug = require('debug')('windshaft:dataview:numeric-histogram');
const utils = require('../../../utils/query-utils');

/** Query to get min and max values from the query */
const irqQueryTpl = ctx => `
    __cdb_filtered_source AS (
        SELECT *
        FROM (${ctx.query}) __cdb_filtered_source_query
        WHERE ${utils.handleFloatColumn(ctx)} IS NOT NULL
    ),
    __cdb_basics AS (
        SELECT
            max(${ctx.column}) AS __cdb_max_val,
            min(${ctx.column}) AS __cdb_min_val,
            count(1) AS __cdb_total_rows,
            ${ctx.irq ? ctx.irq : `0`} AS __cdb_iqr
        FROM __cdb_filtered_source
    )
`;

/* Query to calculate the number of bins (needs irqQueryTpl before it.
 * It uses the Freedman–Diaconis rule to calculate the witdh of the bins */
const binsQueryTpl = ctx => `
    __cdb_bins AS (
        SELECT
            CASE WHEN __cdb_total_rows = 0 OR __cdb_iqr = 0
            THEN 1
            ELSE GREATEST(
                LEAST(${ctx.minBins}, CAST(__cdb_total_rows AS INT)),
                LEAST(
                    CAST(((__cdb_max_val - __cdb_min_val) / (2 * __cdb_iqr * power(__cdb_total_rows, 1/3))) AS INT),
                    ${ctx.maxBins}
                )
            )
            END AS __cdb_bins_number
        FROM __cdb_basics, __cdb_filtered_source
        LIMIT 1
    )
`;

const BIN_MIN_NUMBER = 6;
const BIN_MAX_NUMBER = 48;

/**
Numeric histogram:
{
    type: 'histogram',
    options: {
        column: 'name', // column data type: numeric
        bins: 10 // OPTIONAL
    }
}
*/
module.exports = class NumericHistogram extends BaseHistogram {
    constructor (query, options, queries) {
        super(query, options, queries);
    }

    _buildQuery (psql, override, callback) {
        const histogramSql = this._buildQueryTpl({
            column: this._columnType === 'date' ? utils.columnCastTpl({ column: this.column }) : this.column,
            isFloatColumn: this._columnType === 'float',
            query: this.query,
            start: this._getBinStart(override),
            end: this._getBinEnd(override),
            bins: this._getBinsCount(override),
            minBins: BIN_MIN_NUMBER,
            maxBins: BIN_MAX_NUMBER
        });

        debug(histogramSql);

        return callback(null, histogramSql);
    }

/**
 * ctx: Object with the following values
 * ctx.column -- Column for the histogram
 * ctx.isFloatColumn - Whether the column is float or not
 * ctx.query -- Subquery to extract data
 * ctx.start -- Start value for the bins. [>= end to force calculation]
 * ctx.end -- End value for the bins.
 * ctx.bins -- Numbers of bins to generate [<0 to force calculation]
 * ctx.minBins - If !full min bins to calculate [Optional]
 * ctx.maxBins - If !full max bins to calculate [Optional]
 */
    _buildQueryTpl (ctx) {
        var extra_tables = ``;
        var extra_queries = ``;
        var extra_groupby = ``;
        var extra_filter = ``;

        if (ctx.start < ctx.end) {
            extra_filter = `
              WHERE __ctx_query.${ctx.column} >= ${ctx.start}
                AND __ctx_query.${ctx.column} <= ${ctx.end}
            `;
        } else {
            ctx.end = `__cdb_basics.__cdb_max_val`;
            ctx.start = `__cdb_basics.__cdb_min_val`;
            extra_groupby = `, __cdb_basics.__cdb_max_val, __cdb_basics.__cdb_min_val`;
            extra_tables = `, __cdb_basics`;
            extra_queries = `WITH ${irqQueryTpl(ctx)}`;
        }

        if (ctx.bins <= 0) {
            ctx.bins = `__cdb_bins.__cdb_bins_number`;
            ctx.irq = `percentile_disc(0.75) within group (order by ${ctx.column}) - percentile_disc(0.25) within group (order by ${ctx.column})`;
            extra_groupby += `, __cdb_bins.__cdb_bins_number`;
            extra_tables += `, __cdb_bins`;
            extra_queries = `WITH ${irqQueryTpl(ctx)}, ${binsQueryTpl(ctx)}`;
        }

        return `
${extra_queries}
SELECT
    (${ctx.end} - ${ctx.start}) / ${ctx.bins}::float AS bin_width,
    ${ctx.bins} as bins_number,
    ${utils.countNULLs(ctx)} AS nulls_count,
    ${utils.countInfinites(ctx)} AS infinities_count,
    ${utils.countNaNs(ctx)} AS nans_count,
    min(${utils.handleFloatColumn(ctx)}) AS min,
    max(${utils.handleFloatColumn(ctx)}) AS max,
    avg(${utils.handleFloatColumn(ctx)}) AS avg,
    sum(CASE WHEN (${utils.handleFloatColumn(ctx)} is not NULL) THEN 1 ELSE 0 END) as freq,
    CASE WHEN ${ctx.start} = ${ctx.end}
        THEN 0
        ELSE GREATEST(1, LEAST(
                    ${ctx.bins},
                    WIDTH_BUCKET(${utils.handleFloatColumn(ctx)}, ${ctx.start}, ${ctx.end}, ${ctx.bins}))) - 1
    END AS bin
FROM
(
    SELECT * FROM (${ctx.query}) __ctx_query${extra_tables} ${extra_filter}
) __cdb_filtered_source_query${extra_tables}
GROUP BY 10${extra_groupby}
ORDER BY 10;`;
    }

    _hasOverridenBins (override) {
        return override && override.hasOwnProperty('bins');
    }

    _getSummary (result, override) {
        const firstRow = result.rows[0] || {};

        var total_nulls = 0;
        var total_infinities = 0;
        var total_nans = 0;
        var total_avg = 0;
        var total_count = 0;

        result.rows.forEach(function(row) {
            total_nulls += row.nulls_count;
            total_infinities += row.infinities_count;
            total_nans += row.nans_count;
            total_avg += row.avg * row.freq;
            total_count += row.freq;
        });
        if (total_count !== 0) {
            total_avg /= total_count;
        }

        return {
            bin_width: firstRow.bin_width,
            bins_count: firstRow.bins_number,
            bins_start: this._populateBinStart(firstRow, override),
            nulls: total_nulls,
            infinities: total_infinities,
            nans: total_nans,
            avg: total_avg
        };
    }

    _getBuckets (result) {
        return result.rows.map(({ bin, min, max, avg, freq }) => ({ bin, min, max, avg, freq }));
    }

    _populateBinStart (firstRow, override = {}) {
        let binStart;

        if (override.hasOwnProperty('start')) {
            binStart = this._getBinStart(override);
        } else {
            binStart = firstRow.min;
        }

        return binStart;
    }

};
<commit_msg>Numeric histogram: Simplify bin calculation<commit_after>'use strict';

const BaseHistogram = require('./base-histogram');
const debug = require('debug')('windshaft:dataview:numeric-histogram');
const utils = require('../../../utils/query-utils');

/** Query to get min, max, count and (if necessary) bin number of the query */
const irqQueryTpl = ctx => `
 __cdb_basics AS (
    SELECT
        *,
        CASE
            WHEN __cdb_total_rows = 0 OR __cdb_iqr = 0 THEN 1
            ELSE GREATEST(
                LEAST(
                    ${ctx.minBins},
                    __cdb_total_rows::int),
                LEAST(
                    ${ctx.maxBins},
                    ((__cdb_max_val - __cdb_min_val) / (2 * __cdb_iqr * power(__cdb_total_rows, 1/3)))::int)
                )
            END AS __cdb_bins_number
    FROM
    (
        SELECT
            max(${ctx.column}) AS __cdb_max_val,
            min(${ctx.column}) AS __cdb_min_val,
            count(1) AS __cdb_total_rows,
            ${ctx.irq ? ctx.irq : `0`} AS __cdb_iqr
        FROM
        (
            SELECT *
            FROM (${ctx.query}) __cdb_filtered_source_query
            WHERE ${utils.handleFloatColumn(ctx)} IS NOT NULL
        ) __cdb_filtered_source
    ) __cdb_basics_2
)
`;

const BIN_MIN_NUMBER = 6;
const BIN_MAX_NUMBER = 48;

/**
Numeric histogram:
{
    type: 'histogram',
    options: {
        column: 'name', // column data type: numeric
        bins: 10 // OPTIONAL
    }
}
*/
module.exports = class NumericHistogram extends BaseHistogram {
    constructor (query, options, queries) {
        super(query, options, queries);
    }

    _buildQuery (psql, override, callback) {
        const histogramSql = this._buildQueryTpl({
            column: this._columnType === 'date' ? utils.columnCastTpl({ column: this.column }) : this.column,
            isFloatColumn: this._columnType === 'float',
            query: this.query,
            start: this._getBinStart(override),
            end: this._getBinEnd(override),
            bins: this._getBinsCount(override),
            minBins: BIN_MIN_NUMBER,
            maxBins: BIN_MAX_NUMBER
        });

        debug(histogramSql);

        return callback(null, histogramSql);
    }

/**
 * ctx: Object with the following values
 * ctx.column -- Column for the histogram
 * ctx.isFloatColumn - Whether the column is float or not
 * ctx.query -- Subquery to extract data
 * ctx.start -- Start value for the bins. [>= end to force calculation]
 * ctx.end -- End value for the bins.
 * ctx.bins -- Numbers of bins to generate [<0 to force calculation]
 * ctx.minBins - If !full min bins to calculate [Optional]
 * ctx.maxBins - If !full max bins to calculate [Optional]
 */
    _buildQueryTpl (ctx) {
        var extra_tables = ``;
        var extra_queries = ``;
        var extra_groupby = ``;
        var extra_filter = ``;

        if (ctx.start < ctx.end) {
            extra_filter = `
              WHERE __ctx_query.${ctx.column} >= ${ctx.start}
                AND __ctx_query.${ctx.column} <= ${ctx.end}
            `;
        } else {
            ctx.end = `__cdb_basics.__cdb_max_val`;
            ctx.start = `__cdb_basics.__cdb_min_val`;
            extra_groupby = `, __cdb_basics.__cdb_max_val, __cdb_basics.__cdb_min_val`;
            extra_tables = `, __cdb_basics`;
            extra_queries = `WITH ${irqQueryTpl(ctx)}`;
        }

        if (ctx.bins <= 0) {
            ctx.bins = `__cdb_basics.__cdb_bins_number`;
            ctx.irq = `percentile_disc(0.75) within group (order by ${ctx.column})
                         - percentile_disc(0.25) within group (order by ${ctx.column})`;
            extra_groupby += `, __cdb_basics.__cdb_bins_number`;
            extra_queries = `WITH ${irqQueryTpl(ctx)}`;
        }

        return `
${extra_queries}
SELECT
    (${ctx.end} - ${ctx.start}) / ${ctx.bins}::float AS bin_width,
    ${ctx.bins} as bins_number,
    ${utils.countNULLs(ctx)} AS nulls_count,
    ${utils.countInfinites(ctx)} AS infinities_count,
    ${utils.countNaNs(ctx)} AS nans_count,
    min(${utils.handleFloatColumn(ctx)}) AS min,
    max(${utils.handleFloatColumn(ctx)}) AS max,
    avg(${utils.handleFloatColumn(ctx)}) AS avg,
    sum(CASE WHEN (${utils.handleFloatColumn(ctx)} is not NULL) THEN 1 ELSE 0 END) as freq,
    CASE WHEN ${ctx.start} = ${ctx.end}
        THEN 0
        ELSE GREATEST(1, LEAST(
                    ${ctx.bins},
                    WIDTH_BUCKET(${utils.handleFloatColumn(ctx)}, ${ctx.start}, ${ctx.end}, ${ctx.bins}))) - 1
    END AS bin
FROM
(
    SELECT * FROM (${ctx.query}) __ctx_query${extra_tables} ${extra_filter}
) __cdb_filtered_source_query${extra_tables}
GROUP BY 10${extra_groupby}
ORDER BY 10;`;
    }

    _hasOverridenBins (override) {
        return override && override.hasOwnProperty('bins');
    }

    _getSummary (result, override) {
        const firstRow = result.rows[0] || {};

        var total_nulls = 0;
        var total_infinities = 0;
        var total_nans = 0;
        var total_avg = 0;
        var total_count = 0;

        result.rows.forEach(function(row) {
            total_nulls += row.nulls_count;
            total_infinities += row.infinities_count;
            total_nans += row.nans_count;
            total_avg += row.avg * row.freq;
            total_count += row.freq;
        });
        if (total_count !== 0) {
            total_avg /= total_count;
        }

        return {
            bin_width: firstRow.bin_width,
            bins_count: firstRow.bins_number,
            bins_start: this._populateBinStart(firstRow, override),
            nulls: total_nulls,
            infinities: total_infinities,
            nans: total_nans,
            avg: total_avg
        };
    }

    _getBuckets (result) {
        return result.rows.map(({ bin, min, max, avg, freq }) => ({ bin, min, max, avg, freq }));
    }

    _populateBinStart (firstRow, override = {}) {
        let binStart;

        if (override.hasOwnProperty('start')) {
            binStart = this._getBinStart(override);
        } else {
            binStart = firstRow.min;
        }

        return binStart;
    }

};
<|endoftext|>


<commit_before>'use strict'

const fs = require('fs')
const resolve = require('path').resolve

class CliGitfoContributor {

    constructor() {
        const content = fs.readFileSync((resolve('.actuator','info.json')), { encoding: 'utf-8'})
        this.info = JSON.parse(content)
    }

    getContext() {
        return "git"
    }

    getInfo() {
        return this.info.git
    }
}

module.exports = new CliGitfoContributor()<commit_msg>chore: catch errors reading info file<commit_after>'use strict'

const fs = require('fs')
const resolve = require('path').resolve

class CliGitfoContributor {

    constructor() {
        try {
            const content = fs.readFileSync((resolve('.actuator', 'info.json')), {
                encoding: 'utf-8'
            })
            this.info = JSON.parse(content)
        } catch (e) {
            this.info = {}
        }
    }

    getContext() {
        return "git"
    }

    getInfo() {
        return this.info.git
    }
}

module.exports = new CliGitfoContributor()<|endoftext|>


<commit_before>/*
** Copyright 2013 Google Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**    http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

define(
['config', 'bigl', 'stapes','mergemaps','sv_svc'],
function(config, L, Stapes, XMaps, sv_svc) {

  var SEARCH_FAIL_BALLOON_TIME = 1100;

  var ClickSearchModule = Stapes.subclass({
    constructor: function(map,provider) {
      var self = this;

      this.map = map;
      this.provider = provider;

      this.search_fail_balloon = new XMaps[provider].InfoWindow({
        content: '',
        disableAutoPan: true,
        map: this.map
      });
      this.ballon_close_timeout = null;

      XMaps[provider].addListener(this.map, 'click', function(event) {
        self.close_search_fail_balloon();

        // determine min/max search radius based on zoom level
        var min_search_radius;
        var max_search_radius;

        var current_zoom = self.map.getZoom();

        if (current_zoom <= 10) {
          min_search_radius = 400;
          max_search_radius = 3200;
        } else if (current_zoom <= 12) {
          min_search_radius = 100;
          max_search_radius = 800;
        } else if (current_zoom <= 14) {
          min_search_radius = 50;
          max_search_radius = 400;
        } else {
          min_search_radius = 50;
          max_search_radius = 200;
        }

        console.debug('min', min_search_radius, 'max', max_search_radius);
				console.log(this.getPosition());
        var pos = XMaps[provider].getEventPos(event); // event.latLng
        sv_svc[provider].getPanoramaByLocation(
          pos,
          min_search_radius,
          function(data, stat, search_latlng) {
            if(stat == XMaps[provider].StreetViewStatus.OK) {
              self.emit('search_result', data);
            } else {
              self.open_search_fail_balloon(search_latlng);
            }
          },
          max_search_radius
        );
      });
    },

    open_search_fail_balloon: function(latlng) {
      var self = this;
      this.close_search_fail_balloon();
      this.search_fail_balloon.openInfoWindow(this.map,latlng);
    //  this.search_fail_balloon.open(this.map);

      this.balloon_close_timeout = setTimeout(
        function() {
          self.close_search_fail_balloon();
        },
        SEARCH_FAIL_BALLOON_TIME
      );
    },

    close_search_fail_balloon: function() {
      clearTimeout(this.balloon_close_timeout);
      this.search_fail_balloon.closeInfoWindow(this.map);
    },
  });

  return ClickSearchModule;
});
<commit_msg>remove useless files<commit_after>/*
** Copyright 2013 Google Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**    http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

define(
['config', 'bigl', 'stapes','mergemaps','sv_svc'],
function(config, L, Stapes, XMaps, sv_svc) {

  var SEARCH_FAIL_BALLOON_TIME = 1100;

  var ClickSearchModule = Stapes.subclass({
    constructor: function(map,provider) {
      var self = this;

      this.map = map;
      this.provider = provider;

      this.search_fail_balloon = new XMaps[provider].InfoWindow({
        content: '',
        disableAutoPan: true,
        map: this.map
      });
      this.ballon_close_timeout = null;

      XMaps[provider].addListener(this.map, 'click', function(event) {
        self.close_search_fail_balloon();

        // determine min/max search radius based on zoom level
        var min_search_radius;
        var max_search_radius;

        var current_zoom = self.map.getZoom();

        if (current_zoom <= 10) {
          min_search_radius = 400;
          max_search_radius = 3200;
        } else if (current_zoom <= 12) {
          min_search_radius = 100;
          max_search_radius = 800;
        } else if (current_zoom <= 14) {
          min_search_radius = 50;
          max_search_radius = 400;
        } else {
          min_search_radius = 50;
          max_search_radius = 200;
        }

        console.debug('min', min_search_radius, 'max', max_search_radius);

        var pos = XMaps[provider].getEventPos(event); // event.latLng
        sv_svc[provider].getPanoramaByLocation(
          pos,
          min_search_radius,
          function(data, stat, search_latlng) {
            if(stat == XMaps[provider].StreetViewStatus.OK) {
              self.emit('search_result', data);
            } else {
              self.open_search_fail_balloon(search_latlng);
            }
          },
          max_search_radius
        );
      });
    },

    open_search_fail_balloon: function(latlng) {
      var self = this;
      this.close_search_fail_balloon();
      this.search_fail_balloon.openInfoWindow(this.map,latlng);
    //  this.search_fail_balloon.open(this.map);

      this.balloon_close_timeout = setTimeout(
        function() {
          self.close_search_fail_balloon();
        },
        SEARCH_FAIL_BALLOON_TIME
      );
    },

    close_search_fail_balloon: function() {
      clearTimeout(this.balloon_close_timeout);
      this.search_fail_balloon.closeInfoWindow(this.map);
    },
  });

  return ClickSearchModule;
});
<|endoftext|>


<commit_before>var PageFunctions = (function() {
  // ********** DOM Caching ********** //
  var $darkOverlay = $('.dark-overlay');

  var $navbarToggle = $('.navbar-toggle');
  var $navbarItems = $('#navbar-items > li > a');
  var $navbarBrand = $('.navbar-brand');

  var $offCanvasToggle = $('[data-toggle="offcanvas"]');
  var $offCanvasRow = $('.row-offcanvas');

  var $tabDataToggle = $('a[data-toggle="tab"]');

  var $levelBar = $('.level-bar-inner');

  var $contactForm = $('#contact-form');
  var $name = $('#name');
  var $email = $('#email');
  var $message = $('#email-message');
  var $formAjaxMessage = $('#contact-form-ajax-message');

  var $html = $('html');
  // ********** DOM Caching ********** //

  // ********** Basic initialization ********** //
  // Go to the latest tab, if it exists:
  var lastTab = localStorage.getItem('lastTab');
  if (lastTab) {
    var tab = $('[href="' + lastTab + '"]').tab('show');
    $navbarBrand.text($(tab).text());
  }

  // Set the progressbar widths to 0
  $levelBar.css('width', '0');
  // ********** Basic initialization ********** //

  // ********** Bind events ********** //
  // Collapse navbar on select
  $(document).on('click', '.navbar-collapse.in', _hideOverlayOnSelect);

  // Save the last selected tab to the local storage
  $tabDataToggle.on('shown.bs.tab', _showLastTab);

  // Change the brand name on navbar item select
  $navbarItems.on('click', _setNavbarBrandText);

  // Scroll to the top on navbar item select
  $navbarItems.on('click', _scrollToTop);

  // Off canvas toggle
  $offCanvasToggle.on('click', _offCanvasToggle);

  $(window).on('load', _animateProgressBars);

  // Function to show the dark overlay whenever the navmenu is expanded
  $navbarToggle.on('click', _toggleOverlay);

  $contactForm.on('submit', _sendEmail);
  // ********** Bind events ********** //

  // ********** Function declarations ********** //
  /**
   * Function to  hide the dark-overlay and reenable scrolling on the page
   * whenever a navbar item is selected.
   *
   * @param  {object} e The event.
   */
  function _hideOverlayOnSelect(e) {
    if( $(e.target).is('a') && $(e.target).attr('class') !== 'navbar-toggle') {
      $(this).collapse('hide');
      if ($darkOverlay.is(':visible')) {
        $darkOverlay.hide();
        $html.removeClass('no-scroll');
      }
    }
  }

  /**
   * Function to animate each progress bar in the DOM.
   */
  function _animateProgressBars() {
    $levelBar.each(_animateProgressBar);
  }

  /**
   * Function that will animate a single progress bar.
   */
  function _animateProgressBar() {
    var itemWidth = $(this).data('level');

    $(this).animate({width: itemWidth}, 800);
  }

  /**
   * Function to toggle the dark-overlay and toggle scrolling.
   */
  function _toggleOverlay() {
    $darkOverlay.toggle();
    $html.toggleClass('no-scroll');
  }

  /**
   * Function to toggle the offcanvas navmenu.
   */
  function _offCanvasToggle() {
    $offCanvasRow.toggleClass('active');
  }

  /**
   * Function to set the navbar brand text.
   */
  function _setNavbarBrandText() {
    $navbarBrand.text($(this).text());
  }

  /**
   * Function to show the last tab that was saved in the local storage.
   */
  function _showLastTab() {
    localStorage.setItem('lastTab', $(this).attr('href'));
  }

  /**
   * Function to scroll to the top of the page.
   */
  function _scrollToTop() {
    scrollTo(0, 0);
  }

  /**
   * Function to fire an AJAX request to send a contact email to my contact email from
   * a user on the page.
   *
   * @param  {object} e The event from the form submit.
   */
  function _sendEmail(e) {
    e.preventDefault();

    var name = $name.val();
    var email = $email.val();
    var message = $message.val();

    AjaxFunctions.sendEmail(name, email, message, _processEmailResponse);
  }

  /**
   * Function to process the AJAX response and show a snackbar to inform the user the
   * status of his contact email.
   *
   * @param  {object} response The JSON response from the AJAX call.
   */
  function _processEmailResponse(response) {
    if (response.responseType === 'SUCCESS') {
      $.snackbar({content: response.response,
                  timeout: 1500});
    } else {
      $.snackbar({content: 'Error Code: ' + response.responseType + '\nServer Response: ' + response.response,
                  timeout: 1500});
    }
  }
  // ********** Function declarations ********** //
})();
<commit_msg>brandon-page-functions.js<commit_after>var PageFunctions = (function() {
  // ********** DOM Caching ********** //
  var $darkOverlay = $('.dark-overlay');

  var $navbarToggle = $('.navbar-toggle');
  var $navbarItems = $('#navbar-items > li > a');
  var $navbarBrand = $('.navbar-brand');

  var $offCanvasToggle = $('[data-toggle="offcanvas"]');
  var $offCanvasRow = $('.row-offcanvas');

  var $tabDataToggle = $('a[data-toggle="tab"]');

  var $levelBar = $('.level-bar-inner');

  var $contactForm = $('#contact-form');
  var $name = $('#name');
  var $email = $('#email');
  var $message = $('#email-message');
  var $formAjaxMessage = $('#contact-form-ajax-message');

  var $html = $('html');
  // ********** DOM Caching ********** //

  // ********** Basic initialization ********** //
  // Go to the latest tab, if it exists:
  var lastTab = localStorage.getItem('lastTab');
  if (lastTab) {
    var tab = $('[href="' + lastTab + '"]').tab('show');
    $navbarBrand.text($(tab).text());
  }

  // Set the progressbar widths to 0
  $levelBar.css('width', '0');
  // ********** Basic initialization ********** //

  // ********** Bind events ********** //
  // Collapse navbar on select
  $(document).on('click', '.navbar-collapse.in', _hideOverlayOnSelect);

  // Save the last selected tab to the local storage
  $tabDataToggle.on('shown.bs.tab', _showLastTab);

  // Change the brand name on navbar item select
  $navbarItems.on('click', _setNavbarBrandText);

  // Scroll to the top on navbar item select
  $navbarItems.on('click', _scrollToTop);

  // Off canvas toggle
  $offCanvasToggle.on('click', _offCanvasToggle);

  $(window).on('load', _animateProgressBars);

  // Function to show the dark overlay whenever the navmenu is expanded
  $navbarToggle.on('click', _toggleOverlay);

  $contactForm.on('submit', _sendEmail);
  // ********** Bind events ********** //

  // ********** Function declarations ********** //
  /**
   * Function to  hide the dark-overlay and reenable scrolling on the page
   * whenever a navbar item is selected.
   *
   * @param  {object} e The event.
   */
  function _hideOverlayOnSelect(e) {
    if( $(e.target).is('a') && $(e.target).attr('class') !== 'navbar-toggle') {
      $(this).collapse('hide');
      if ($darkOverlay.is(':visible')) {
        $darkOverlay.hide();
        $html.removeClass('no-scroll');
      }
    }
  }

  /**
   * Function to animate each progress bar in the DOM.
   */
  function _animateProgressBars() {
    $levelBar.each(_animateProgressBar);
  }

  /**
   * Function that will animate a single progress bar.
   */
  function _animateProgressBar() {
    var itemWidth = $(this).data('level');

    $(this).animate({width: itemWidth}, 800);
  }

  /**
   * Function to toggle the dark-overlay and toggle scrolling.
   */
  function _toggleOverlay() {
    $darkOverlay.toggle();
    $html.toggleClass('no-scroll');
  }

  /**
   * Function to toggle the offcanvas navmenu.
   */
  function _offCanvasToggle() {
    $offCanvasRow.toggleClass('active');
  }

  /**
   * Function to set the navbar brand text.
   */
  function _setNavbarBrandText() {
    $navbarBrand.text($(this).text());
  }

  /**
   * Function to show the last tab that was saved in the local storage.
   */
  function _showLastTab() {
    localStorage.setItem('lastTab', $(this).attr('href'));
  }

  /**
   * Function to scroll to the top of the page.
   */
  function _scrollToTop() {
    scrollTo(0, 0);
  }

  /**
   * Function to fire an AJAX request to send a contact email to my contact email from
   * a user on the page.
   *
   * @param  {object} e The event from the form submit.
   */
  function _sendEmail(e) {
    e.preventDefault();

    var name = $name.val();
    var email = $email.val();
    var message = $message.val();

    AjaxFunctions.sendEmail(name, email, message, _processEmailResponse);
  }

  /**
   * Function to process the AJAX response and show a snackbar to inform the user the
   * status of his contact email.
   *
   * @param  {object} response The JSON response from the AJAX call.
   */
  function _processEmailResponse(response) {
    if (response.responseType === 'SUCCESS') {
      $.snackbar({content: response.response,
                  timeout: 1500});

      $name.val('');
      $email.val('');
      $message.val('');
    } else {
      $.snackbar({content: 'Error Code: ' + response.responseType + '\nServer Response: ' + response.response,
                  timeout: 1500});
    }
  }
  // ********** Function declarations ********** //
})();
<|endoftext|>


<commit_before>#!/usr/bin/env node

const log = require('loglevel');
const colors = require('colors/safe');
const spawn = require('child_process').spawn;
const options = require('command-line-args')([
  { name: 'config', alias: 'c', type: String },
  { name: 'host', type: String },
]);

log.enableAll();

process.env.CONFIG = options.config || '';

const command = ['node_modules/webpack-dev-server/bin/webpack-dev-server.js', '--progress', '--hot', '--inline', '--port', '8080'];
if (options.host) {
  command.push('--host');
  command.push(`${options.host}`);
}

const devServer = spawn('node', command);

devServer.on('close', () => {
  log.error(colors.red('😓  webpack-dev-server was unexpectedly closed.'));
  process.exit(1);
});

devServer.stdout.on('data', (data) => process.stdout.write(data));
devServer.stderr.on('data', (data) => process.stderr.write(data));
<commit_msg>Updated start.js<commit_after>#!/usr/bin/env node

const log = require('loglevel');
const colors = require('colors/safe');
const spawn = require('child_process').spawn;
const options = require('command-line-args')([
  { name: 'config', alias: 'c', type: String },
  { name: 'host', type: String },
]);

log.enableAll();

process.env.CONFIG = options.config || '';

const command = ['node_modules/webpack-dev-server/bin/webpack-dev-server.js', '--progress', '--hot', '--inline', '--port', '8080'];
if (options.host) {
  command.push('--host');
  command.push(`${options.host}`);
}

const devServer = spawn('node', command, { stdio: 'inherit' });
devServer.on('close', (code) => {
  if (code) {
    log.error(colors.red('😓  webpack-dev-server was unexpectedly closed.'));
    process.exit(code);
  }
});
<|endoftext|>


<commit_before>/*
 * 流水步骤：
 * 1.访问某一个小组的URL
 * 2.找到相关URL，保存
 * 3.找到小组的title、member数量，保存
 */

var http                = require('http');
var $                   = require('cheerio');                     //cheerio用于解析DOM tree，类似于前端的jquery
var addContent          = require('./models/content.js');
var addQuickCheck       = require('./models/quick_check.js');

main();

function main(){

   //使用setInterval做计时器以及循环,每隔n分钟调用一次
   console.log('[Spider Run]');
   getWebSite();

   var timer = setInterval(function(){
      console.log('[Spider Run]');
      getWebSite();
      //clearInterval(timer);
   }, 1000*10);

}

function getWebSite(){
   var the_path = '/group/beijingzufang/';

   console.log('抓取地址： ' + the_path);

   var options={
      host:'www.douban.com',
      path:the_path,
      //method:'get',
      headers:{
         'Content-Type':'application/x-www-form-urlencoded',
         'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0',
         //'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
         'Referer':'http://www.douban.com/group/search?cat=1019&q=%E5%8C%97%E4%BA%AC%E7%A7%9F%E6%88%BF',
         'Host':'www.douban.com',
         'Connection':'keep-alive',
         'Cache-Control':'max-age=0',
         //'Accept-Language':'zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
         //'Accept-Encoding':'gzip, deflate',
      }
   };

   http.get(options, function(res) {
     var size = 0;
     var chunks = [];

     res.on('data', function(chunk){
         size += chunk.length;
         chunks.push(chunk);
         //
         console.log('[wait for]: ' + options.path);
     });

     res.on('end', function(){
         var data = Buffer.concat(chunks, size);
         var stringData = data.toString();
         if (stringData){
            console.log('[get website success]' + options.path);
         }
         else {
            console.log('[get website failed]' + options.path);
         }

         // 如果担心被屏蔽，就打印一下网页源码
         //console.log(stringData);

         // 取得title
         var titleHTML = $('#group-info', stringData).html();
         var title = $('h1', titleHTML).text();
         title = title.replace(/\s/g, "");
         console.log('=' + title);

         // 取得relative_group
         var relative_groupHTML = $('.bd', stringData).html();
         console.log(relative_groupHTML);
         var relative_group = $('.title', relative_groupHTML).text();
         //console.log('=' + relative_group);

         //var $html = cheerio.load(discussHTML);
         //var tiezi_urls = $('.title', discussHTML).children();

      });
   }).on('error', function(e){
      console.log("[check err all by my own]: " + e.message);
   });
}

/*
var discussHTML = $('.olt', stringData).html();   //获取帖子列表（一页的）
//var $html = cheerio.load(discussHTML);
var tiezi_urls = $('.title', discussHTML).children();

for (var i=0; i<=tiezi_urls.length-1; i++){
   var kk = tiezi_urls[i].attribs.href;    //获取帖子地址
   URLs.push(kk);
   console.log('url: ' + i);
}

//储存url数组到数据库
if (URLs.length > 25*(maxNum-1)+12){   //防止多次重复写入,加12是为了防止有时候一页超过25个
var uniqueURL = unique(URLs);    //数组去重
var newURLs = new addURLs({
   crawler_time: new Date(),             //爬取时间
   length: URLs.length,                  //帖子数量
   url: uniqueURL,                       //帖子数组
   city: group[0]
});
//debug断点
console.log('传递url到下一步');
data_url.getURLs(newURLs);  //进入第2步骤
*/
/*
newURLs.save(function(err, doc, num){
   if (err) {
      console.log("Got error: ");
   }
   console.log('save success: ' + num);
   data_url.getURLs();  //进入第2步骤
});
*/<commit_msg>'init'<commit_after>/*
 * 流水步骤：
 * 1.访问某一个小组的URL
 * 2.找到相关URL，保存
 * 3.找到小组的title、member数量，保存
 */

var http                = require('http');
var $                   = require('cheerio');                     //cheerio用于解析DOM tree，类似于前端的jquery
var addContent          = require('./models/content.js');
var addQuickCheck       = require('./models/quick_check.js');

main();

function main(){

   //使用setInterval做计时器以及循环,每隔n分钟调用一次
   console.log('[Spider Run]');
   getWebSite();

   var timer = setInterval(function(){
      console.log('[Spider Run]');
      getWebSite();
      //clearInterval(timer);
   }, 1000*10);

}

function getWebSite(){
   var the_path = '/group/beijingzufang/';

   console.log('抓取地址： ' + the_path);

   var options={
      host:'www.douban.com',
      path:the_path,
      //method:'get',
      headers:{
         'Content-Type':'application/x-www-form-urlencoded',
         'User-Agent':'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:18.0) Gecko/20100101 Firefox/18.0',
         //'User-Agent':'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)',
         'Referer':'http://www.douban.com/group/search?cat=1019&q=%E5%8C%97%E4%BA%AC%E7%A7%9F%E6%88%BF',
         'Host':'www.douban.com',
         'Connection':'keep-alive',
         'Cache-Control':'max-age=0',
         //'Accept-Language':'zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
         //'Accept-Encoding':'gzip, deflate',
      }
   };

   http.get(options, function(res) {
     var size = 0;
     var chunks = [];

     res.on('data', function(chunk){
         size += chunk.length;
         chunks.push(chunk);
         //
         console.log('[wait for]: ' + options.path);
     });

     res.on('end', function(){
         var data = Buffer.concat(chunks, size);
         var stringData = data.toString();
         if (stringData){
            console.log('[get website success]' + options.path);
         }
         else {
            console.log('[get website failed]' + options.path);
         }

         // 如果担心被屏蔽，就打印一下网页源码
         //console.log(stringData);

         // 从网页获取需要的内容
         analysWebSite(stringData);

      });
   }).on('error', function(e){
      console.log("[check err all by my own]: " + e.message);
   });
}

function analysWebSite(stringData){
   // 取得title
   var titleHTML = $('#group-info', stringData).html();
   var title = $('h1', titleHTML).text();
   title = title.replace(/\s/g, "");
   console.log('=' + title);

   // 取得relative_group
   var asideHTML = $('.aside', stringData).html();
   var bdHTML = $('.bd', asideHTML).html();
   var group_listHTML = $('.group-list', bdHTML).children();
   console.log(group_listHTML);

   var length = group_listHTML.length;
   for (var i=0; i<=length; i++) {
      var xxx = group_listHTML[i].children();
      console.log(xxx);
   }

   return ;
}

/*
var discussHTML = $('.olt', stringData).html();   //获取帖子列表（一页的）
//var $html = cheerio.load(discussHTML);
var tiezi_urls = $('.title', discussHTML).children();

for (var i=0; i<=tiezi_urls.length-1; i++){
   var kk = tiezi_urls[i].attribs.href;    //获取帖子地址
   URLs.push(kk);
   console.log('url: ' + i);
}

//储存url数组到数据库
if (URLs.length > 25*(maxNum-1)+12){   //防止多次重复写入,加12是为了防止有时候一页超过25个
var uniqueURL = unique(URLs);    //数组去重
var newURLs = new addURLs({
   crawler_time: new Date(),             //爬取时间
   length: URLs.length,                  //帖子数量
   url: uniqueURL,                       //帖子数组
   city: group[0]
});
//debug断点
console.log('传递url到下一步');
data_url.getURLs(newURLs);  //进入第2步骤
*/
/*
newURLs.save(function(err, doc, num){
   if (err) {
      console.log("Got error: ");
   }
   console.log('save success: ' + num);
   data_url.getURLs();  //进入第2步骤
});
*/<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from '../../registerServiceWorker.js';

import Navbar from '../Navbar/Nav.js';
import Menu from '../Menu.js';
import * as Users from '../../Team4of5_Service/Users.js';
import * as firebase from 'firebase';
import * as Config from '../../Team4of5_Service/Config.js';

import {BrowserRouter as Router, Route, Link, Redirect, withRouter} from 'react-router-dom';

// import fetch from 'isomorphic-fetch';
// //reference: https://github.com/JedWatson/react-select
// import Select from 'react-select';

// style
import './Settings.css';
//import react-bootstrap
import {
    FormGroup,
    FormControl,
    ControlLabel,
    HelpBlock,
    Button
} from 'react-bootstrap';

class AdminSettings extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            company:'',
            email:'',
            redirectToMenu: false,
            userInfo: [],
            formBtnTxt: 'Update User'
        };
        this.handleSubmit = this.handleSubmit.bind(this);
        this.gotData = this.gotData.bind(this);
        this.handleChange = this.handleChange.bind(this);
    }

    componentDidMount() {
    var user = firebase.auth().currentUser;
    var uid;

        if (user != null) {
            uid = user.uid;

            var thisUser = firebase.database().ref().child('users/' + uid);
            thisUser.on('value', this.gotData, this.errData);
        }
    }

    gotData = (data) => {
        let newUser = []
        const userdata = data.val();
        //const keys = Object.keys(userdata);

        this.state.company = userdata.company;
    }

    handleChange(name, event) {
        let items = this.state;
        items[name] = event.target.value;
        this.setState(items);
    }
    handleSubmit(event) {

        event.preventDefault();
        if (this.state.email) {

            Users.updateToAdmin(this.state.email,this.state.company)
             .then((Users)=>{
                     //handle redirect
                this.setState({redirectToMenu: true});

            })
        } else {
            alert("Please select a user ");
        }

        this.state.email = '';
    }

    render() {

        const {from} = this.props.location.state || {
            from: {
                pathname: '/menu'
            }
        }
        const {redirectToMenu} = this.state

        if (redirectToMenu) {
            return (<Redirect to={from}/>)
        }

        return (

Admin Settings

Please enter the user who want to make an admin

                    <form onSubmit={this.handleSubmit}>

                                    Reset Role

                                <FormGroup controlId="formControlsSelect">
                                    <ControlLabel>User Email</ControlLabel>
                                    <FormControl componentClass="input" value={this.state.email} onChange={this.handleChange.bind(this, 'email')}/>

                                </FormGroup>

                        <button type="submit" id="setingBtn" className="btn btn-primary"> Update to Admin </button>
                        <Link to='/menu' className='btn btn-danger'>Cancel</Link>
                    </form>

        );
    }
}

export default AdminSettings
<commit_msg>Update the Admin page into autoComplete<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import registerServiceWorker from '../../registerServiceWorker.js';

import Navbar from '../Navbar/Nav.js';
import Menu from '../Menu.js';
import * as Users from '../../Team4of5_Service/Users.js';
import * as firebase from 'firebase';
import * as Config from '../../Team4of5_Service/Config.js';

import {BrowserRouter as Router, Route, Link, Redirect, withRouter} from 'react-router-dom';

import fetch from 'isomorphic-fetch';
//reference: https://github.com/JedWatson/react-select
import Select from 'react-select';

// style
import './Settings.css';
//import react-bootstrap
import {
    FormGroup,
    FormControl,
    ControlLabel,
    HelpBlock,
    Button
} from 'react-bootstrap';

class AdminSettings extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            company:'',
            email:'',
            value: [],
            redirectToMenu: false,
            userInfo: [],
            formBtnTxt: 'Update User'
        };
        this.handleSubmit = this.handleSubmit.bind(this);
        this.gotData = this.gotData.bind(this);
        //this.handleChange = this.handleChange.bind(this);
        this.handleEmailChange = this.handleEmailChange.bind(this);
        this.getUsers = this.getUsers.bind(this);
    }

    componentDidMount() {
    var user = firebase.auth().currentUser;
    var uid;

        if (user != null) {
            uid = user.uid;

            var thisUser = firebase.database().ref().child('users/' + uid);
            thisUser.on('value', this.gotData, this.errData);
        }
    }

    gotData = (data) => {
        let newUser = []
        const userdata = data.val();
        //const keys = Object.keys(userdata);
        this.state.company = userdata.company;
    }

    // handleChange(name, event) {
    //     let items = this.state;
    //     items[name] = event.target.value;
    //     this.setState(items);
    // }
    handleEmailChange(value) {
        console.log("change happening")
        console.log(value)
        this.setState({
            value: value,
        });
    }
    handleSubmit(event) {

        event.preventDefault();
        if (this.state.value.email) {

            Users.updateToAdmin(this.state.value.email,this.state.company)
             .then((Users)=>{
                     //handle redirect
                this.setState({redirectToMenu: true});

            })
        } else {
            alert("Please select a user ");
        }

        this.state.value = [];
    }
    getUsers(input) {

        let self = this;

        if (!input) {
            console.log('here')
            return Promise.resolve({ options: [] });
        }

        let contactEmails = []
        return fetch('https://team4of5-8d52e.firebaseio.com/users.json?&orderBy=%22email%22&startAt=%22'
            + input + '%22&endAt=%22' + input + '\uf8ff%22')

            .then((response) => response.json())
            .then((json) => {
                for (let key in json) {
                    //console.log(self.state.curUserCompany) self.state.curUserCompany
                    if (json[key].company == 'A') {
                        contactEmails.push({ email: json[key].email, label: json[key].email })
                    }
                }
                self.setState({ options: contactEmails })
                return {
                    options: contactEmails,
                    complete: true
                };
            });
    }

    render() {
const AsyncComponent = Select.Async
        const {from} = this.props.location.state || {
            from: {
                pathname: '/menu'
            }
        }
        const {redirectToMenu} = this.state

        if (redirectToMenu) {
            return (<Redirect to={from}/>)
        }

        return (

Admin Settings

Please enter the user who want to make an admin

                    <form onSubmit={this.handleSubmit}>

                                    Reset Role

                                <FormGroup controlId="formControlsSelect">
                                    <ControlLabel>User Email</ControlLabel>
                                    {/* <FormControl componentClass="input" value={this.state.email} onChange={this.handleChange.bind(this, 'email')}/> */}
                                    <AsyncComponent
                                        multi={false}
                                        value={this.state.value}
                                        onChange={this.handleEmailChange}
                                        //onValueClick={this.gotoUser}
                                        //Options={this.state.options}
                                        valueKey="value"
                                        labelKey="label"
                                        loadOptions={this.getUsers}
                                        backspaceRemoves={true} />
                                </FormGroup>

                        <button type="submit" id="setingBtn" className="btn btn-primary"> Update to Admin </button>
                        <Link to='/menu' className='btn btn-danger'>Cancel</Link>
                    </form>

        );
    }
}

export default AdminSettings
<|endoftext|>


<commit_before>/*
 * common.js: Common utility functions for quill.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var fs = require('fs'),
    path = require('path'),
    flatiron = require('flatiron'),
    multimeter = require('multimeter'),
    quill = require('../../quill');

var common = module.exports = flatiron.common.mixin({}, flatiron.common);

common.authorizedKeys = require('./authorized-keys');

//
// ### function remkdirp (dir, callback)
// #### @dir {string} Directory to recreate
// #### @callback {function} Continuation to respond to when complete.
//
// Recreates the `dir` by removing it (`rimraf`) and recreating it (`mkdirp`).
//
common.remkdirp = function (dir, callback) {
  common.async.series([
    function tryRimraf(next) {
      common.rimraf(dir, function (err) {
        return err && err.code !== 'ENOENT'
          ? next(err)
          : next();
      })
    },
    common.async.apply(common.mkdirp, dir)
  ], callback);
};

//
// ### function isDirectory (file, callback)
//
// Async filter function which checks if a given
// `file` is a directory.
//
common.isDirectory = function (file, callback) {
  fs.stat(file, function (err, stat) {
    return !err
      ? callback(stat.isDirectory())
      : callback(false);
  });
};

//
// ### function tmpFile (dir, name, version, ext)
// #### @dir {string} Directory to place the temp file in
// #### @name {string} Name of the system
// #### @version {string} Version of the system
// #### @ext {string} **Optional** File extention of the temp file
//
// Returns a path for a unique temporary file for the system represented
// by `name` and `version`.
//
common.tmpFile = function (dir, name, version, ext) {
  ext = ext || '';
  return path.join(dir, ['__quill', name, version, Date.now() + ext].join('-'));
};

//
// ### function installDir (system)
// #### @system {string|Object} System to get the install dir for
//
// Returns the root installation directory for the specified `system`.
//
common.installDir = function (system) {
  if (typeof system === 'string') {
    system = { name: system };
  }

  return path.join(
    quill.config.get('directories:install'),
    system.name
  );
};

//
// ### function meter (callback)
// #### @callback {function} Continuation to respond to.
// Responds with a `multimeter` instance if
//   * One does not already exist
//   * quill is running in in a TTY
//   * `raw` is not true.
//
common.meter = function (callback) {
  var multi;

  if (!quill.config.get('raw') && quill.config.get('progress') && process.stdout.isTTY) {
    multi = multimeter(process);
    multi.charm.cursor(false);
    return multi.drop({
      pad: true,
      type: 'stack',
      width: 20,
      empty: { text : ' ' },
      solid: {
        text: '|',
        foreground: 'white',
        background: 'blue'
      },
    }, function (stack) {
      multi.stack = stack;
      callback(multi);
    });
  }

  return callback();
};

//
// ### @ignoreFiles {Object}
// Named sets of default files ignored by quill.
//
common.ignore = {
  defaults: [''],
  scm:      [
    'CVS/',
    '.hg/',
    '.git/',
    '.svn/'
  ],
  nodejs:   ['npm-debug.log', '.lock-wscript'],
  osx:      ['.DS_Store'],
  vim:      [
    '.netrwhist',
    'Session.vim',
    '.*.sw[a-z]',
    '*.un~'
  ]
};<commit_msg>[fix minor] s/multimeter/multimeter-stack/<commit_after>/*
 * common.js: Common utility functions for quill.
 *
 * (C) 2010, Nodejitsu Inc.
 *
 */

var fs = require('fs'),
    path = require('path'),
    flatiron = require('flatiron'),
    multimeter = require('multimeter-stack'),
    quill = require('../../quill');

var common = module.exports = flatiron.common.mixin({}, flatiron.common);

common.authorizedKeys = require('./authorized-keys');

//
// ### function remkdirp (dir, callback)
// #### @dir {string} Directory to recreate
// #### @callback {function} Continuation to respond to when complete.
//
// Recreates the `dir` by removing it (`rimraf`) and recreating it (`mkdirp`).
//
common.remkdirp = function (dir, callback) {
  common.async.series([
    function tryRimraf(next) {
      common.rimraf(dir, function (err) {
        return err && err.code !== 'ENOENT'
          ? next(err)
          : next();
      })
    },
    common.async.apply(common.mkdirp, dir)
  ], callback);
};

//
// ### function isDirectory (file, callback)
//
// Async filter function which checks if a given
// `file` is a directory.
//
common.isDirectory = function (file, callback) {
  fs.stat(file, function (err, stat) {
    return !err
      ? callback(stat.isDirectory())
      : callback(false);
  });
};

//
// ### function tmpFile (dir, name, version, ext)
// #### @dir {string} Directory to place the temp file in
// #### @name {string} Name of the system
// #### @version {string} Version of the system
// #### @ext {string} **Optional** File extention of the temp file
//
// Returns a path for a unique temporary file for the system represented
// by `name` and `version`.
//
common.tmpFile = function (dir, name, version, ext) {
  ext = ext || '';
  return path.join(dir, ['__quill', name, version, Date.now() + ext].join('-'));
};

//
// ### function installDir (system)
// #### @system {string|Object} System to get the install dir for
//
// Returns the root installation directory for the specified `system`.
//
common.installDir = function (system) {
  if (typeof system === 'string') {
    system = { name: system };
  }

  return path.join(
    quill.config.get('directories:install'),
    system.name
  );
};

//
// ### function meter (callback)
// #### @callback {function} Continuation to respond to.
// Responds with a `multimeter` instance if
//   * One does not already exist
//   * quill is running in in a TTY
//   * `raw` is not true.
//
common.meter = function (callback) {
  var multi;

  if (!quill.config.get('raw') && quill.config.get('progress') && process.stdout.isTTY) {
    multi = multimeter(process);
    multi.charm.cursor(false);
    return multi.drop({
      pad: true,
      type: 'stack',
      width: 20,
      empty: { text : ' ' },
      solid: {
        text: '|',
        foreground: 'white',
        background: 'blue'
      },
    }, function (stack) {
      multi.stack = stack;
      callback(multi);
    });
  }

  return callback();
};

//
// ### @ignoreFiles {Object}
// Named sets of default files ignored by quill.
//
common.ignore = {
  defaults: [''],
  scm:      [
    'CVS/',
    '.hg/',
    '.git/',
    '.svn/'
  ],
  nodejs:   ['npm-debug.log', '.lock-wscript'],
  osx:      ['.DS_Store'],
  vim:      [
    '.netrwhist',
    'Session.vim',
    '.*.sw[a-z]',
    '*.un~'
  ]
};<|endoftext|>


<commit_before>
/**
 * Module dependencies.
 */

var Base = require('./base');

/**
 * Expose `JSONCov`.
 */

exports = module.exports = JSONCov;

/**
 * Initialize a new `JsCoverage` reporter.
 *
 * @param {Runner} runner
 * @param {Boolean} output
 * @api public
 */

function JSONCov(runner, output) {
  var self = this
    , output = 1 == arguments.length ? true : output;

  Base.call(this, runner);

  var tests = []
    , failures = []
    , passes = [];

  runner.on('test end', function(test){
    tests.push(test);
  });

  runner.on('pass', function(test){
    passes.push(test);
  });

  runner.on('fail', function(test){
    failures.push(test);
  });

  runner.on('end', function(){
    var cov = global._$jscoverage || {};
    var result = self.cov = map(cov);
    result.stats = self.stats;
    result.tests = tests.map(clean);
    result.failures = failures.map(clean);
    result.passes = passes.map(clean);
    if (!output) return;
    process.stdout.write(JSON.stringify(result, null, 2 ));
  });
}

/**
 * Map jscoverage data to a JSON structure
 * suitable for reporting.
 *
 * @param {Object} cov
 * @return {Object}
 * @api private
 */

function map(cov) {
  var ret = {
      instrumentation: 'node-jscoverage'
    , sloc: 0
    , hits: 0
    , misses: 0
    , coverage: 0
    , files: []
  };

  for (var filename in cov) {
    var data = coverage(filename, cov[filename]);
    ret.files.push(data);
    ret.hits += data.hits;
    ret.misses += data.misses;
    ret.sloc += data.sloc;
  }

  if (ret.sloc > 0) {
    ret.coverage = (ret.hits / ret.sloc) * 100;
  }

  return ret;
};

/**
 * Map jscoverage data for a single source file
 * to a JSON structure suitable for reporting.
 *
 * @param {String} filename name of the source file
 * @param {Object} data jscoverage coverage data
 * @return {Object}
 * @api private
 */

function coverage(filename, data) {
  var ret = {
    filename: filename,
    coverage: 0,
    hits: 0,
    misses: 0,
    sloc: 0,
    source: {}
  };

  data.source.forEach(function(line, num){
    num++;

    if (data[num] === 0) {
      ret.misses++;
      ret.sloc++;
    } else if (data[num] !== undefined) {
      ret.hits++;
      ret.sloc++;
    }

    ret.source[num] = {
        source: line
      , coverage: data[num] === undefined
        ? ''
        : data[num]
    };
  });

  ret.coverage = ret.hits / ret.sloc * 100;

  return ret;
}

/**
 * Return a plain-object representation of `test`
 * free of cyclic properties etc.
 *
 * @param {Object} test
 * @return {Object}
 * @api private
 */

function clean(test) {
  return {
      title: test.title
    , fullTitle: test.fullTitle()
    , duration: test.duration
  }
}
<commit_msg>Sorted the results in the json coverage reporter on their filename.<commit_after>
/**
 * Module dependencies.
 */

var Base = require('./base');

/**
 * Expose `JSONCov`.
 */

exports = module.exports = JSONCov;

/**
 * Initialize a new `JsCoverage` reporter.
 *
 * @param {Runner} runner
 * @param {Boolean} output
 * @api public
 */

function JSONCov(runner, output) {
  var self = this
    , output = 1 == arguments.length ? true : output;

  Base.call(this, runner);

  var tests = []
    , failures = []
    , passes = [];

  runner.on('test end', function(test){
    tests.push(test);
  });

  runner.on('pass', function(test){
    passes.push(test);
  });

  runner.on('fail', function(test){
    failures.push(test);
  });

  runner.on('end', function(){
    var cov = global._$jscoverage || {};
    var result = self.cov = map(cov);
    result.stats = self.stats;
    result.tests = tests.map(clean);
    result.failures = failures.map(clean);
    result.passes = passes.map(clean);
    if (!output) return;
    process.stdout.write(JSON.stringify(result, null, 2 ));
  });
}

/**
 * Map jscoverage data to a JSON structure
 * suitable for reporting.
 *
 * @param {Object} cov
 * @return {Object}
 * @api private
 */

function map(cov) {
  var ret = {
      instrumentation: 'node-jscoverage'
    , sloc: 0
    , hits: 0
    , misses: 0
    , coverage: 0
    , files: []
  };

  for (var filename in cov) {
    var data = coverage(filename, cov[filename]);
    ret.files.push(data);
    ret.hits += data.hits;
    ret.misses += data.misses;
    ret.sloc += data.sloc;
  }

  ret.files.sort(function(a, b) {
    return a.filename.localeCompare(b.filename);
  });

  if (ret.sloc > 0) {
    ret.coverage = (ret.hits / ret.sloc) * 100;
  }

  return ret;
};

/**
 * Map jscoverage data for a single source file
 * to a JSON structure suitable for reporting.
 *
 * @param {String} filename name of the source file
 * @param {Object} data jscoverage coverage data
 * @return {Object}
 * @api private
 */

function coverage(filename, data) {
  var ret = {
    filename: filename,
    coverage: 0,
    hits: 0,
    misses: 0,
    sloc: 0,
    source: {}
  };

  data.source.forEach(function(line, num){
    num++;

    if (data[num] === 0) {
      ret.misses++;
      ret.sloc++;
    } else if (data[num] !== undefined) {
      ret.hits++;
      ret.sloc++;
    }

    ret.source[num] = {
        source: line
      , coverage: data[num] === undefined
        ? ''
        : data[num]
    };
  });

  ret.coverage = ret.hits / ret.sloc * 100;

  return ret;
}

/**
 * Return a plain-object representation of `test`
 * free of cyclic properties etc.
 *
 * @param {Object} test
 * @return {Object}
 * @api private
 */

function clean(test) {
  return {
      title: test.title
    , fullTitle: test.fullTitle()
    , duration: test.duration
  }
}
<|endoftext|>