<commit_before>/*
 * Rebind bootstrap UI components after Primefaces ajax calls
 */
function bind_bsui_components(){
    //console.log('bind_bsui_components');
    // Breadcrumb Tree Keep Open
    $(document).on('click', '.dropdown-menu', function (e) {
        $(this).hasClass('keep-open'),
        e.stopPropagation();
    });
    // Collapse Header Icons
    $('div[id^="collapse"]').on('shown.bs.collapse', function () {
      //console.log('hello block');
      $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
    });

    $('div[id^="collapse"]').on('hidden.bs.collapse', function () {
      //console.log('goodbye block');
       $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
    });

    // Permissions + Dataset Tooltips/Popovers
    $("[data-toggle='tooltip'], #citation span.glyphicon").tooltip({container: 'body'});
    $("a[data-toggle='popover']").popover();

}

/*
 * show breadcrumb navigation
 */
function show_breadcrumb(){
   $('#breadcrumbNavBlock').show();
}

/*
 * hide breadcrumb navigation
 */
function hide_breadcrumb(){
    $('#breadcrumbNavBlock').hide();
}

/*
 * Hide notification message
 */
function hide_info_msg(){
    if ($('div.messagePanel').length > 0){
        $('div.messagePanel').html('');
    }
}

/*
 * Show notification message
 */
function show_info_msg(mtitle, mtext){
   if ($('div.messagePanel').length > 0){
     //  alert('msg panel exists');
       edit_msg = '
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>'
                       + ''
                       + ' ' + mtitle + ' – ' + mtext + '
';
       $('div.messagePanel').html(edit_msg );
   }else{
     //console.log('message panel does not exist');
   }
}

/*
 * Called after "Edit Dataverse" - "General Information"
 */
function post_edit_dv_general_info(){
    show_info_msg('Edit Dataverse', 'Edit your dataverse and click Save Changes. Asterisks indicate required fields.');
    post_edit_dv();
}

/*
 * Called after "Edit Dataverse" - "Setup"
 */
function post_edit_dv_setup(){
    show_info_msg('Dataverse Setup', 'Edit the Metadata Blocks and Facets you want to associate with your dataverse. Note: facets will appear in the order shown on the list.');
    post_edit_dv();
}
/*
 * Called after "Edit Dataverse" -  "General Information" or "Setup"
 */
function post_edit_dv(){
   hide_breadcrumb();
   hide_search_panels();
   bind_bsui_components();
   //console.log('hide after edit3');
}

/*
 * Used after cancelling "Edit Dataverse"
 */
function post_cancel_edit_dv(){
   show_breadcrumb();
   show_search_panels()
   hide_info_msg();
   bind_bsui_components();
   //console.log('show after cancel edit3');
}

/*
 * Hide search panels when editing a dv
 */
function hide_search_panels(){
    if($(".panelSerchForm").length>0){
       $(".panelSerchForm").hide();
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().hide();
        }
   }
}

/*
 * Show search panels when cancel a dv edit
 */

function show_search_panels(){
    if($(".panelSerchForm").length>0){
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().show();
        }
       $(".panelSerchForm").show();
   }
}

/*
 * Called after "Upload + Edit Files"
 */
function post_edit_files(){
   //console.log('post_edit_files');
   hide_breadcrumb();
   bind_bsui_components();
   addDeleteTooltip();
   show_info_msg('Upload + Edit Dataset Files', 'You can drag and drop your files from your desktop, directly into the upload widget.');
}

function addDeleteTooltip(){
    var fileChckbx = $('div[id$="filesTable"] table td.ui-selection-column div.ui-chkbox-box span.ui-chkbox-icon');
    $(fileChckbx).wrapInner('');
    $(fileChckbx).children('a[data-toggle="tooltip"]').tooltip();
}

/*
 * Called after "Edit Metadta"
 */
function post_edit_metadata(){
   //console.log('post_edit_metadata');
   hide_breadcrumb();
   bind_bsui_components();
   show_info_msg('Edit Dataset Metadata ', 'Add more metadata about your dataset to help others easily find it.');

}

/*
 *  Used when cancelling either "Upload + Edit Files" or "Edit Metadata"
 */
function post_cancel_edit_files_or_metadata(){
   //console.log('post_cancel_edit_metadata');
   show_breadcrumb();
   bind_bsui_components();
   hide_info_msg();
}

/*
 * Dialog Height-Scrollable
 */
function post_differences(){
       var dialogHeight = $('div[id$="detailsBlocks"].ui-dialog').outerHeight();
       var dialogHeader = $('div[id$="detailsBlocks"] .ui-dialog-titlebar').outerHeight();
       var dialogScroll = dialogHeight - dialogHeader;
       $('div[id$="detailsBlocks"] .ui-dialog-content').css('height', dialogScroll);
}
<commit_msg>Fixed bug with tooltip for delete file checkbox that was causing the page to jump to the top when you clicked a checkbox at the bottom of the page that's been scrolled down.<commit_after>/*
 * Rebind bootstrap UI components after Primefaces ajax calls
 */
function bind_bsui_components(){
    //console.log('bind_bsui_components');
    // Breadcrumb Tree Keep Open
    $(document).on('click', '.dropdown-menu', function (e) {
        $(this).hasClass('keep-open'),
        e.stopPropagation();
    });
    // Collapse Header Icons
    $('div[id^="collapse"]').on('shown.bs.collapse', function () {
      //console.log('hello block');
      $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-down").addClass("glyphicon-chevron-up");
    });

    $('div[id^="collapse"]').on('hidden.bs.collapse', function () {
      //console.log('goodbye block');
       $(this).siblings('div.panel-heading').children('span.glyphicon').removeClass("glyphicon-chevron-up").addClass("glyphicon-chevron-down");
    });

    // Permissions + Dataset Tooltips/Popovers
    $("[data-toggle='tooltip'], #citation span.glyphicon").tooltip({container: 'body'});
    $("a[data-toggle='popover']").popover();

}

/*
 * show breadcrumb navigation
 */
function show_breadcrumb(){
   $('#breadcrumbNavBlock').show();
}

/*
 * hide breadcrumb navigation
 */
function hide_breadcrumb(){
    $('#breadcrumbNavBlock').hide();
}

/*
 * Hide notification message
 */
function hide_info_msg(){
    if ($('div.messagePanel').length > 0){
        $('div.messagePanel').html('');
    }
}

/*
 * Show notification message
 */
function show_info_msg(mtitle, mtext){
   if ($('div.messagePanel').length > 0){
     //  alert('msg panel exists');
       edit_msg = '
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">x</button>'
                       + ''
                       + ' ' + mtitle + ' – ' + mtext + '
';
       $('div.messagePanel').html(edit_msg );
   }else{
     //console.log('message panel does not exist');
   }
}

/*
 * Called after "Edit Dataverse" - "General Information"
 */
function post_edit_dv_general_info(){
    show_info_msg('Edit Dataverse', 'Edit your dataverse and click Save Changes. Asterisks indicate required fields.');
    post_edit_dv();
}

/*
 * Called after "Edit Dataverse" - "Setup"
 */
function post_edit_dv_setup(){
    show_info_msg('Dataverse Setup', 'Edit the Metadata Blocks and Facets you want to associate with your dataverse. Note: facets will appear in the order shown on the list.');
    post_edit_dv();
}
/*
 * Called after "Edit Dataverse" -  "General Information" or "Setup"
 */
function post_edit_dv(){
   hide_breadcrumb();
   hide_search_panels();
   bind_bsui_components();
   //console.log('hide after edit3');
}

/*
 * Used after cancelling "Edit Dataverse"
 */
function post_cancel_edit_dv(){
   show_breadcrumb();
   show_search_panels()
   hide_info_msg();
   bind_bsui_components();
   //console.log('show after cancel edit3');
}

/*
 * Hide search panels when editing a dv
 */
function hide_search_panels(){
    if($(".panelSerchForm").length>0){
       $(".panelSerchForm").hide();
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().hide();
        }
   }
}

/*
 * Show search panels when cancel a dv edit
 */

function show_search_panels(){
    if($(".panelSerchForm").length>0){
        if($(".panelSerchForm").next().length>0){
            $(".panelSerchForm").next().show();
        }
       $(".panelSerchForm").show();
   }
}

/*
 * Called after "Upload + Edit Files"
 */
function post_edit_files(){
   //console.log('post_edit_files');
   hide_breadcrumb();
   bind_bsui_components();
   addDeleteTooltip();
   show_info_msg('Upload + Edit Dataset Files', 'You can drag and drop your files from your desktop, directly into the upload widget.');
}

function addDeleteTooltip(){
    var fileChckbx = $('div[id$="filesTable"] table td.ui-selection-column div.ui-chkbox-box span.ui-chkbox-icon');
    $(fileChckbx).wrapInner('');
    $(fileChckbx).children('a[data-toggle="tooltip"]').tooltip();
}

/*
 * Called after "Edit Metadta"
 */
function post_edit_metadata(){
   //console.log('post_edit_metadata');
   hide_breadcrumb();
   bind_bsui_components();
   show_info_msg('Edit Dataset Metadata ', 'Add more metadata about your dataset to help others easily find it.');

}

/*
 *  Used when cancelling either "Upload + Edit Files" or "Edit Metadata"
 */
function post_cancel_edit_files_or_metadata(){
   //console.log('post_cancel_edit_metadata');
   show_breadcrumb();
   bind_bsui_components();
   hide_info_msg();
}

/*
 * Dialog Height-Scrollable
 */
function post_differences(){
       var dialogHeight = $('div[id$="detailsBlocks"].ui-dialog').outerHeight();
       var dialogHeader = $('div[id$="detailsBlocks"] .ui-dialog-titlebar').outerHeight();
       var dialogScroll = dialogHeight - dialogHeader;
       $('div[id$="detailsBlocks"] .ui-dialog-content').css('height', dialogScroll);
}
<|endoftext|>


<commit_before>import Node from './node';
import { getNodeKey } from './util';

export default class TreeStore {
  constructor(options) {
    this.currentNode = null;
    this.currentNodeKey = null;

    for (let option in options) {
      if (options.hasOwnProperty(option)) {
        this[option] = options[option];
      }
    }

    this.nodesMap = {};

    this.root = new Node({
      data: this.data,
      store: this
    });

    if (this.lazy && this.load) {
      const loadFn = this.load;
      loadFn(this.root, (data) => {
        this.root.doCreateChildren(data);
        this._initDefaultCheckedNodes();
      });
    } else {
      this._initDefaultCheckedNodes();
    }
  }

  filter(value) {
    const filterNodeMethod = this.filterNodeMethod;
    const traverse = function(node) {
      const childNodes = node.root ? node.root.childNodes : node.childNodes;

      childNodes.forEach((child) => {
        child.visible = filterNodeMethod.call(child, value, child.data, child);

        traverse(child);
      });

      if (!node.visible && childNodes.length) {
        let allHidden = true;

        childNodes.forEach((child) => {
          if (child.visible) allHidden = false;
        });

        if (node.root) {
          node.root.visible = allHidden === false;
        } else {
          node.visible = allHidden === false;
        }
      }
      if (!value) return;

      if (node.visible && !node.isLeaf) node.expand();
    };

    traverse(this);
  }

  setData(newVal) {
    const instanceChanged = newVal !== this.root.data;
    if (instanceChanged) {
      this.root.setData(newVal);
      this._initDefaultCheckedNodes();
    } else {
      this.root.updateChildren();
    }
  }

  getNode(data) {
    if (data instanceof Node) return data;
    const key = typeof data !== 'object' ? data : getNodeKey(this.key, data);
    return this.nodesMap[key] || null;
  }

  insertBefore(data, refData) {
    const refNode = this.getNode(refData);
    refNode.parent.insertBefore({ data }, refNode);
  }

  insertAfter(data, refData) {
    const refNode = this.getNode(refData);
    refNode.parent.insertAfter({ data }, refNode);
  }

  remove(data) {
    const node = this.getNode(data);
    if (node) {
      node.parent.removeChild(node);
    }
  }

  append(data, parentData) {
    const parentNode = parentData ? this.getNode(parentData) : this.root;

    if (parentNode) {
      parentNode.insertChild({ data });
    }
  }

  _initDefaultCheckedNodes() {
    const defaultCheckedKeys = this.defaultCheckedKeys || [];
    const nodesMap = this.nodesMap;

    defaultCheckedKeys.forEach((checkedKey) => {
      const node = nodesMap[checkedKey];

      if (node) {
        node.setChecked(true, !this.checkStrictly);
      }
    });
  }

  _initDefaultCheckedNode(node) {
    const defaultCheckedKeys = this.defaultCheckedKeys || [];

    if (defaultCheckedKeys.indexOf(node.key) !== -1) {
      node.setChecked(true, !this.checkStrictly);
    }
  }

  setDefaultCheckedKey(newVal) {
    if (newVal !== this.defaultCheckedKeys) {
      this.defaultCheckedKeys = newVal;
      this._initDefaultCheckedNodes();
    }
  }

  registerNode(node) {
    const key = this.key;
    if (!key || !node || !node.data) return;

    const nodeKey = node.key;
    if (nodeKey !== undefined) this.nodesMap[node.key] = node;
  }

  deregisterNode(node) {
    const key = this.key;
    if (!key || !node || !node.data) return;

    const childNodes = node.childNodes;
    for (let i = 0, j = childNodes.length; i < j; i++) {
      const child = childNodes[i];
      this.deregisterNode(child);
    }

    delete this.nodesMap[node.key];
  }

  getCheckedNodes(leafOnly = false) {
    const checkedNodes = [];
    const traverse = function(node) {
      const childNodes = node.root ? node.root.childNodes : node.childNodes;

      childNodes.forEach((child) => {
        if (child.checked && (!leafOnly || (leafOnly && child.isLeaf))) {
          checkedNodes.push(child.data);
        }

        traverse(child);
      });
    };

    traverse(this);

    return checkedNodes;
  }

  getCheckedKeys(leafOnly = false) {
    return this.getCheckedNodes(leafOnly).map((data) => (data || {})[this.key]);
  }

  getHalfCheckedNodes() {
    const nodes = [];
    const traverse = function(node) {
      const childNodes = node.root ? node.root.childNodes : node.childNodes;

      childNodes.forEach((child) => {
        if (child.indeterminate) {
          nodes.push(child.data);
        }

        traverse(child);
      });
    };

    traverse(this);

    return nodes;
  }

  getHalfCheckedKeys() {
    return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]);
  }

  _getAllNodes() {
    const allNodes = [];
    const nodesMap = this.nodesMap;
    for (let nodeKey in nodesMap) {
      if (nodesMap.hasOwnProperty(nodeKey)) {
        allNodes.push(nodesMap[nodeKey]);
      }
    }

    return allNodes;
  }

  updateChildren(key, data) {
    const node = this.nodesMap[key];
    if (!node) return;
    const childNodes = node.childNodes;
    for (let i = childNodes.length - 1; i >= 0; i--) {
      const child = childNodes[i];
      this.remove(child.data);
    }
    for (let i = 0, j = data.length; i < j; i++) {
      const child = data[i];
      this.append(child, node.data);
    }
  }

  _setCheckedKeys(key, leafOnly = false, checkedKeys) {
    const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level);
    const cache = Object.create(null);
    const keys = Object.keys(checkedKeys);
    allNodes.forEach(node => node.setChecked(false, false));
    for (let i = 0, j = allNodes.length; i < j; i++) {
      const node = allNodes[i];
      const nodeKey = node.data[key].toString();
      let checked = keys.indexOf(nodeKey) > -1;
      if (!checked) {
        if (node.checked && !cache[nodeKey]) {
          node.setChecked(false, false);
        }
        continue;
      }

      let parent = node.parent;
      while (parent && parent.level > 0) {
        cache[parent.data[key]] = true;
        parent = parent.parent;
      }

      if (node.isLeaf || this.checkStrictly) {
        node.setChecked(true, false);
        continue;
      }
      node.setChecked(true, true);

      if (leafOnly) {
        node.setChecked(false, false);
        const traverse = function(node) {
          const childNodes = node.childNodes;
          childNodes.forEach((child) => {
            if (!child.isLeaf) {
              child.setChecked(false, false);
            }
            traverse(child);
          });
        };
        traverse(node);
      }
    }
  }

  setCheckedNodes(array, leafOnly = false) {
    const key = this.key;
    const checkedKeys = {};
    array.forEach((item) => {
      checkedKeys[(item || {})[key]] = true;
    });

    this._setCheckedKeys(key, leafOnly, checkedKeys);
  }

  setCheckedKeys(keys, leafOnly = false) {
    this.defaultCheckedKeys = keys;
    const key = this.key;
    const checkedKeys = {};
    keys.forEach((key) => {
      checkedKeys[key] = true;
    });

    this._setCheckedKeys(key, leafOnly, checkedKeys);
  }

  setDefaultExpandedKeys(keys) {
    keys = keys || [];
    this.defaultExpandedKeys = keys;

    keys.forEach((key) => {
      const node = this.getNode(key);
      if (node) node.expand(null, this.autoExpandParent);
    });
  }

  setChecked(data, checked, deep) {
    const node = this.getNode(data);

    if (node) {
      node.setChecked(!!checked, deep);
    }
  }

  getCurrentNode() {
    return this.currentNode;
  }

  setCurrentNode(node) {
    this.currentNode = node;
  }

  setUserCurrentNode(node) {
    const key = node[this.key];
    const currNode = this.nodesMap[key];
    this.setCurrentNode(currNode);
  }

  setCurrentNodeKey(key) {
    if (key === null) {
      this.currentNode = null;
      return;
    }
    const node = this.getNode(key);
    if (node) {
      this.currentNode = node;
    }
  }
};
<commit_msg>Tree: when tree nodes filtered, don't expand node in lazy mode (#11395)<commit_after>import Node from './node';
import { getNodeKey } from './util';

export default class TreeStore {
  constructor(options) {
    this.currentNode = null;
    this.currentNodeKey = null;

    for (let option in options) {
      if (options.hasOwnProperty(option)) {
        this[option] = options[option];
      }
    }

    this.nodesMap = {};

    this.root = new Node({
      data: this.data,
      store: this
    });

    if (this.lazy && this.load) {
      const loadFn = this.load;
      loadFn(this.root, (data) => {
        this.root.doCreateChildren(data);
        this._initDefaultCheckedNodes();
      });
    } else {
      this._initDefaultCheckedNodes();
    }
  }

  filter(value) {
    const filterNodeMethod = this.filterNodeMethod;
    const lazy = this.lazy;
    const traverse = function(node) {
      const childNodes = node.root ? node.root.childNodes : node.childNodes;

      childNodes.forEach((child) => {
        child.visible = filterNodeMethod.call(child, value, child.data, child);

        traverse(child);
      });

      if (!node.visible && childNodes.length) {
        let allHidden = true;

        childNodes.forEach((child) => {
          if (child.visible) allHidden = false;
        });

        if (node.root) {
          node.root.visible = allHidden === false;
        } else {
          node.visible = allHidden === false;
        }
      }
      if (!value) return;

      if (node.visible && !node.isLeaf && !lazy) node.expand();
    };

    traverse(this);
  }

  setData(newVal) {
    const instanceChanged = newVal !== this.root.data;
    if (instanceChanged) {
      this.root.setData(newVal);
      this._initDefaultCheckedNodes();
    } else {
      this.root.updateChildren();
    }
  }

  getNode(data) {
    if (data instanceof Node) return data;
    const key = typeof data !== 'object' ? data : getNodeKey(this.key, data);
    return this.nodesMap[key] || null;
  }

  insertBefore(data, refData) {
    const refNode = this.getNode(refData);
    refNode.parent.insertBefore({ data }, refNode);
  }

  insertAfter(data, refData) {
    const refNode = this.getNode(refData);
    refNode.parent.insertAfter({ data }, refNode);
  }

  remove(data) {
    const node = this.getNode(data);
    if (node) {
      node.parent.removeChild(node);
    }
  }

  append(data, parentData) {
    const parentNode = parentData ? this.getNode(parentData) : this.root;

    if (parentNode) {
      parentNode.insertChild({ data });
    }
  }

  _initDefaultCheckedNodes() {
    const defaultCheckedKeys = this.defaultCheckedKeys || [];
    const nodesMap = this.nodesMap;

    defaultCheckedKeys.forEach((checkedKey) => {
      const node = nodesMap[checkedKey];

      if (node) {
        node.setChecked(true, !this.checkStrictly);
      }
    });
  }

  _initDefaultCheckedNode(node) {
    const defaultCheckedKeys = this.defaultCheckedKeys || [];

    if (defaultCheckedKeys.indexOf(node.key) !== -1) {
      node.setChecked(true, !this.checkStrictly);
    }
  }

  setDefaultCheckedKey(newVal) {
    if (newVal !== this.defaultCheckedKeys) {
      this.defaultCheckedKeys = newVal;
      this._initDefaultCheckedNodes();
    }
  }

  registerNode(node) {
    const key = this.key;
    if (!key || !node || !node.data) return;

    const nodeKey = node.key;
    if (nodeKey !== undefined) this.nodesMap[node.key] = node;
  }

  deregisterNode(node) {
    const key = this.key;
    if (!key || !node || !node.data) return;

    const childNodes = node.childNodes;
    for (let i = 0, j = childNodes.length; i < j; i++) {
      const child = childNodes[i];
      this.deregisterNode(child);
    }

    delete this.nodesMap[node.key];
  }

  getCheckedNodes(leafOnly = false) {
    const checkedNodes = [];
    const traverse = function(node) {
      const childNodes = node.root ? node.root.childNodes : node.childNodes;

      childNodes.forEach((child) => {
        if (child.checked && (!leafOnly || (leafOnly && child.isLeaf))) {
          checkedNodes.push(child.data);
        }

        traverse(child);
      });
    };

    traverse(this);

    return checkedNodes;
  }

  getCheckedKeys(leafOnly = false) {
    return this.getCheckedNodes(leafOnly).map((data) => (data || {})[this.key]);
  }

  getHalfCheckedNodes() {
    const nodes = [];
    const traverse = function(node) {
      const childNodes = node.root ? node.root.childNodes : node.childNodes;

      childNodes.forEach((child) => {
        if (child.indeterminate) {
          nodes.push(child.data);
        }

        traverse(child);
      });
    };

    traverse(this);

    return nodes;
  }

  getHalfCheckedKeys() {
    return this.getHalfCheckedNodes().map((data) => (data || {})[this.key]);
  }

  _getAllNodes() {
    const allNodes = [];
    const nodesMap = this.nodesMap;
    for (let nodeKey in nodesMap) {
      if (nodesMap.hasOwnProperty(nodeKey)) {
        allNodes.push(nodesMap[nodeKey]);
      }
    }

    return allNodes;
  }

  updateChildren(key, data) {
    const node = this.nodesMap[key];
    if (!node) return;
    const childNodes = node.childNodes;
    for (let i = childNodes.length - 1; i >= 0; i--) {
      const child = childNodes[i];
      this.remove(child.data);
    }
    for (let i = 0, j = data.length; i < j; i++) {
      const child = data[i];
      this.append(child, node.data);
    }
  }

  _setCheckedKeys(key, leafOnly = false, checkedKeys) {
    const allNodes = this._getAllNodes().sort((a, b) => b.level - a.level);
    const cache = Object.create(null);
    const keys = Object.keys(checkedKeys);
    allNodes.forEach(node => node.setChecked(false, false));
    for (let i = 0, j = allNodes.length; i < j; i++) {
      const node = allNodes[i];
      const nodeKey = node.data[key].toString();
      let checked = keys.indexOf(nodeKey) > -1;
      if (!checked) {
        if (node.checked && !cache[nodeKey]) {
          node.setChecked(false, false);
        }
        continue;
      }

      let parent = node.parent;
      while (parent && parent.level > 0) {
        cache[parent.data[key]] = true;
        parent = parent.parent;
      }

      if (node.isLeaf || this.checkStrictly) {
        node.setChecked(true, false);
        continue;
      }
      node.setChecked(true, true);

      if (leafOnly) {
        node.setChecked(false, false);
        const traverse = function(node) {
          const childNodes = node.childNodes;
          childNodes.forEach((child) => {
            if (!child.isLeaf) {
              child.setChecked(false, false);
            }
            traverse(child);
          });
        };
        traverse(node);
      }
    }
  }

  setCheckedNodes(array, leafOnly = false) {
    const key = this.key;
    const checkedKeys = {};
    array.forEach((item) => {
      checkedKeys[(item || {})[key]] = true;
    });

    this._setCheckedKeys(key, leafOnly, checkedKeys);
  }

  setCheckedKeys(keys, leafOnly = false) {
    this.defaultCheckedKeys = keys;
    const key = this.key;
    const checkedKeys = {};
    keys.forEach((key) => {
      checkedKeys[key] = true;
    });

    this._setCheckedKeys(key, leafOnly, checkedKeys);
  }

  setDefaultExpandedKeys(keys) {
    keys = keys || [];
    this.defaultExpandedKeys = keys;

    keys.forEach((key) => {
      const node = this.getNode(key);
      if (node) node.expand(null, this.autoExpandParent);
    });
  }

  setChecked(data, checked, deep) {
    const node = this.getNode(data);

    if (node) {
      node.setChecked(!!checked, deep);
    }
  }

  getCurrentNode() {
    return this.currentNode;
  }

  setCurrentNode(node) {
    this.currentNode = node;
  }

  setUserCurrentNode(node) {
    const key = node[this.key];
    const currNode = this.nodesMap[key];
    this.setCurrentNode(currNode);
  }

  setCurrentNodeKey(key) {
    if (key === null) {
      this.currentNode = null;
      return;
    }
    const node = this.getNode(key);
    if (node) {
      this.currentNode = node;
    }
  }
};
<|endoftext|>


<commit_before>function NetworkError(msg) {
  this.msg = msg;
}
function HttpError(status, statusText, responseText) {
  this.status = status;
  this.statusText = statusText;
  this.responseText = responseText;
}

function corsRequest(method, url, data) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    // XHR with CORS
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    // XDomainRequest for IE9.
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    return Q.reject("CORS not supported.");
  }

  var deferred = Q.defer();
  xhr.onload = function() {
    if (this.status == 200) {
      deferred.resolve(this.responseText);
    } else if (this.status) {
      deferred.reject(new HttpError(this.status, this.statusText,
                                    this.responseText));
    } else {
      deferred.reject(new NetworkError("Request failed"));
    }
  };
  xhr.onerror = function() {
    deferred.reject("Request failed");
  };

  if (data !== undefined) {
    // TODO(davidben): Make the server handle text/plain Content-Types
    // too for IE9.
    if (xhr.setRequestHeader)
      xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(data));
  } else {
    xhr.send();
  }
  return deferred.promise;
}

var RECONNECT_DELAY = 500;
var RECONNECT_TRIES = 10;

function API(urlBase) {
  io.EventEmitter.call(this);
  this.urlBase_ = urlBase;
  this.token_ = null;

  this.socket_ = null;
  this.socketPending_ = false;
  this.reconnectDelay_ = RECONNECT_DELAY;
  this.reconnectTries_ = RECONNECT_TRIES;

  this.tryConnectSocket_();

  // If we go online, try to reconnect then and there.
  window.addEventListener("online", this.tryConnectSocket_.bind(this));
}
API.prototype = Object.create(io.EventEmitter.prototype);

API.prototype.refreshAuthToken_ = function() {
  // TODO(davidben): Actually authenticate and stuff. This will
  // potentially require emitting an event or something else to pop up
  // a dialog (with a button to Webathena) when cached tickets expire.
  return corsRequest("POST", this.urlBase_ + "/api/v1/auth", {
    principal: "davidben@ATHENA.MIT.EDU"
  }).then(function(token) {
    this.token_ = token.replace(/\s+$/, "");
    return this.token_;
  }.bind(this));
};

API.prototype.badToken_ = function() {
  console.log("Bad token!");
  this.token_ = null;
};

API.prototype.getAuthToken_ = function() {
  if (this.token_)
    return Q(this.token_);
  return this.refreshAuthToken_();
};

API.prototype.request = function(method, path, params, data, isRetry) {
  return this.getAuthToken_().then(function(token) {
    var url =
      this.urlBase_ + path + "?access_token=" + encodeURIComponent(token);
    for (var key in params) {
      url += "&" + key + "=" + encodeURIComponent(params[key]);
    }
    return corsRequest(method, url, data).then(function(responseText) {
      return JSON.parse(responseText);
    }, function(err) {
      // 401 means we had a bad token (it may have expired). Refresh it.
      if (err instanceof HttpError && err.status == 401) {
        this.badToken_();
        // TODO(davidben): Retry the request after we get a new
        // one. Only retry it once though.
        if (!isRetry)
          return this.request(method, path, params, data, true);
      }
      throw err;
    }.bind(this));
  }.bind(this));
};

API.prototype.get = function(path, params) {
  return this.request("GET", path, params);
};

API.prototype.post = function(path, data) {
  return this.request("POST", path, {}, data);
};

API.prototype.socket = function() {
  return this.socket_;
};

API.prototype.tryConnectSocket_ = function() {
  if (this.socket_ || this.socketPending_)
    return;

  this.socketPending_ = true;
  this.getAuthToken_().then(function(token) {
    // Socket.IO's reconnect behavior is weird (it buffers up what you
    // send and such). Don't bother. Also implementing it ourselves
    // means we can integrate with navigator.onLine and the like.
    var url =  this.urlBase_ + "/?access_token=" + encodeURIComponent(token);
    var socket = io.connect(url, {
      "reconnect": false,
      "force new connection": true
    });

    socket.once("connect", function() {
      this.socketPending_ = false;
      this.socket_ = socket;
      // Reset reconnect state.
      this.reconnectDelay_ = RECONNECT_DELAY;
      this.reconnectTries_ = RECONNECT_TRIES;

      this.emit("connect");
      this.socket_.once("disconnect", function() {
        this.emit("disconnect");
        this.socket_ = null;

        setTimeout(this.tryConnectSocket_.bind(this), this.reconnectDelay_);
      }.bind(this));
    }.bind(this));

    socket.once("error", function(err) {
      this.socketPending_ = false;
      // Blegh. Retry with a new token.
      if (err == "handshake unauthorized") {
        this.badToken_();
      }

      // Reconnect with exponential back-off.
      this.reconnectDelay_ *= 2;
      if (this.reconnectTries_-- > 0) {
        setTimeout(this.tryConnectSocket_.bind(this), this.reconnectDelay_);
      }
    }.bind(this));

    socket.once("connect_failed", function() {
      this.socketPending_ = false;
      // Reconnect with exponential back-off.
      this.reconnectDelay_ *= 2;
      if (this.reconnectTries_-- > 0) {
        setTimeout(this.tryConnectSocket_.bind(this), this.reconnectDelay_);
      }
    }.bind(this));

  }.bind(this), function(err) {
    // Failure to get auth token... should this also reconnect?
    this.socketPending_ = false;
    throw err;
  }.bind(this)).done();
};<commit_msg>Better error messages<commit_after>function NetworkError(msg) {
  this.msg = msg;
}
NetworkError.prototype.toString = function() {
  return "Network error";
};
function HttpError(status, statusText, responseText) {
  this.status = status;
  this.statusText = statusText;
  this.responseText = responseText;
}
HttpError.prototype.toString = function() {
  return this.responseText;
};

function corsRequest(method, url, data) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    // XHR with CORS
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    // XDomainRequest for IE9.
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    return Q.reject("CORS not supported.");
  }

  var deferred = Q.defer();
  xhr.onload = function() {
    if (this.status == 200) {
      deferred.resolve(this.responseText);
    } else if (this.status) {
      deferred.reject(new HttpError(this.status, this.statusText,
                                    this.responseText));
    } else {
      deferred.reject(new NetworkError());
    }
  };
  xhr.onerror = function() {
    deferred.reject("Request failed");
  };

  if (data !== undefined) {
    // TODO(davidben): Make the server handle text/plain Content-Types
    // too for IE9.
    if (xhr.setRequestHeader)
      xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(data));
  } else {
    xhr.send();
  }
  return deferred.promise;
}

var RECONNECT_DELAY = 500;
var RECONNECT_TRIES = 10;

function API(urlBase) {
  io.EventEmitter.call(this);
  this.urlBase_ = urlBase;
  this.token_ = null;

  this.socket_ = null;
  this.socketPending_ = false;
  this.reconnectDelay_ = RECONNECT_DELAY;
  this.reconnectTries_ = RECONNECT_TRIES;

  this.tryConnectSocket_();

  // If we go online, try to reconnect then and there.
  window.addEventListener("online", this.tryConnectSocket_.bind(this));
}
API.prototype = Object.create(io.EventEmitter.prototype);

API.prototype.refreshAuthToken_ = function() {
  // TODO(davidben): Actually authenticate and stuff. This will
  // potentially require emitting an event or something else to pop up
  // a dialog (with a button to Webathena) when cached tickets expire.
  return corsRequest("POST", this.urlBase_ + "/api/v1/auth", {
    principal: "davidben@ATHENA.MIT.EDU"
  }).then(function(token) {
    this.token_ = token.replace(/\s+$/, "");
    return this.token_;
  }.bind(this));
};

API.prototype.badToken_ = function() {
  console.log("Bad token!");
  this.token_ = null;
};

API.prototype.getAuthToken_ = function() {
  if (this.token_)
    return Q(this.token_);
  return this.refreshAuthToken_();
};

API.prototype.request = function(method, path, params, data, isRetry) {
  return this.getAuthToken_().then(function(token) {
    var url =
      this.urlBase_ + path + "?access_token=" + encodeURIComponent(token);
    for (var key in params) {
      url += "&" + key + "=" + encodeURIComponent(params[key]);
    }
    return corsRequest(method, url, data).then(function(responseText) {
      return JSON.parse(responseText);
    }, function(err) {
      // 401 means we had a bad token (it may have expired). Refresh it.
      if (err instanceof HttpError && err.status == 401) {
        this.badToken_();
        // TODO(davidben): Retry the request after we get a new
        // one. Only retry it once though.
        if (!isRetry)
          return this.request(method, path, params, data, true);
      }
      throw err;
    }.bind(this));
  }.bind(this));
};

API.prototype.get = function(path, params) {
  return this.request("GET", path, params);
};

API.prototype.post = function(path, data) {
  return this.request("POST", path, {}, data);
};

API.prototype.socket = function() {
  return this.socket_;
};

API.prototype.tryConnectSocket_ = function() {
  if (this.socket_ || this.socketPending_)
    return;

  this.socketPending_ = true;
  this.getAuthToken_().then(function(token) {
    // Socket.IO's reconnect behavior is weird (it buffers up what you
    // send and such). Don't bother. Also implementing it ourselves
    // means we can integrate with navigator.onLine and the like.
    var url =  this.urlBase_ + "/?access_token=" + encodeURIComponent(token);
    var socket = io.connect(url, {
      "reconnect": false,
      "force new connection": true
    });

    socket.once("connect", function() {
      this.socketPending_ = false;
      this.socket_ = socket;
      // Reset reconnect state.
      this.reconnectDelay_ = RECONNECT_DELAY;
      this.reconnectTries_ = RECONNECT_TRIES;

      this.emit("connect");
      this.socket_.once("disconnect", function() {
        this.emit("disconnect");
        this.socket_ = null;

        setTimeout(this.tryConnectSocket_.bind(this), this.reconnectDelay_);
      }.bind(this));
    }.bind(this));

    socket.once("error", function(err) {
      this.socketPending_ = false;
      // Blegh. Retry with a new token.
      if (err == "handshake unauthorized") {
        this.badToken_();
      }

      // Reconnect with exponential back-off.
      this.reconnectDelay_ *= 2;
      if (this.reconnectTries_-- > 0) {
        setTimeout(this.tryConnectSocket_.bind(this), this.reconnectDelay_);
      }
    }.bind(this));

    socket.once("connect_failed", function() {
      this.socketPending_ = false;
      // Reconnect with exponential back-off.
      this.reconnectDelay_ *= 2;
      if (this.reconnectTries_-- > 0) {
        setTimeout(this.tryConnectSocket_.bind(this), this.reconnectDelay_);
      }
    }.bind(this));

  }.bind(this), function(err) {
    // Failure to get auth token... should this also reconnect?
    this.socketPending_ = false;
    throw err;
  }.bind(this)).done();
};<|endoftext|>


<commit_before>// code modified from flot AJAX example
// http://www.flotcharts.org/flot/examples/ajax/index.html

	$(function() {

		// flot plot options!
		var options = {
			lines: {
				show: true
			},
			points: {
				show: false
			},
			legend: {
				show: true
			},
			grid: {
        		hoverable: true
      		}
	};

		// GLOBAL VARIABLES AND FUNCTIONS

		console.log('Initializing variables.');
		// initialize the arrays hold the data for plotting
		var data = [];
		var dataTarget = [];

		// IP address to access our UI
		// (empty for relative URLs)
		var publicIP = '';

		// building blocks of metadata table
		var tableTop = "
";
		var tableBottom = "
";
		var tableHeader = "
ID	Mean	StDev	Level	Blarg
";
		var metadataTable = tableTop + tableHeader;

		// helps with managing the uploaded time series
		var files;

		// initialize the timeseries plot (will be empty)
		console.log('Initializing flot plot (empty plot).');
		$.plot("#placeholder", data, options);

		// ACTIONS TO COMPLETE WHEN THE `SUBMIT` BUTTON IS CLICKED
		$("button#tsQuery").click(function () {

			console.log('Submit button has been clicked.');

			// show the progress bar so the user knows that stuff
			// is going on behind the scenes

			console.log('Adding in ticking progress bar.');
			$( "#progressbar" ).progressbar({
  				value: false
			});

			// reset everything in preparation for new data
			console.log('Resetting helper variables in preparation for new data.');
			document.getElementById('timeseriesMetadata').innerHTML = '';
			data = [];
			var simIDs = [];
			var idNum = {};
			var counter = 0;
			metadataTable = tableTop + tableHeader;

			$.plot("#placeholder", data, options);

			// retrieve the time series specified by the user, and the number of
			//   most similar time series
			var timeSeriesID = document.getElementById("tsID").value;
			var numSim = document.getElementById("n_closest").value;
			console.log('Retrieved timeseries ID #' + timeSeriesID + 'and will retrieve the ' + numSim + 'most similar timeseries.');

			// CONSTRUCT OUR QUERY
			// if the user has specified an ID, use that;
			//   otherwise assume there's an uploaded file.
			if (timeSeriesID != '') {

				// DECIDE WHETHER WE NEED A SIMQUERY
				// if the user hasn't provided a number of similar TS, or the
				//   number is zero, we won't bother sending off a simquery
				if (numSim == '' | numSim == 0) {

					// add on the ID number of the target TS
					simIDs.push(timeSeriesID);

					// now we loop over all the IDs and collect their data
					console.log("Collecting data of specified time series.");

					var dataurl = publicIP + "/timeseries/" + timeSeriesID;

					console.log('Retrieving data associated with TS ID#'+ timeSeriesID + '.');

					$.ajax({
						url: dataurl,
						type: "GET",
						dataType: "json",
						success: onDataReceived
					});

				} else {

					var simurl = publicIP + "/simquery?id=" + timeSeriesID + "&topn=" + numSim;
					console.log('Constructed simquery:', simurl);

					// get the IDs of the similar time series
					console.log('Retrieving the ID numbers of the similar TS (ID number supplied).');
					$.ajax({
						url: simurl,
						type: "GET",
						dataType: "json",
						success: function(data) {

									// parse the ID numbers returned from the server
									getSimIDs(data);

									// add on the ID number of the target TS
									simIDs.push(timeSeriesID);

									// now we loop over all the IDs and collect their data
									console.log("Looping over the retrieved ID numbers and collecting their data.");

									for(var i=0; i < simIDs.length; i++) {

										idNum   = simIDs[i];

										var dataurl = publicIP + "/timeseries/" + idNum;

										console.log('Retrieving data associated with TS ID#'+ idNum + '.');
										// solution from http://stackoverflow.com/questions/4201934/
										//               jquery-ajax-pass-additional-argument-to-success-callback
										$.ajax({
											url: dataurl,
											type: "GET",
											dataType: "json",
											success: onDataReceived
										});

									}
						 }
					});
				}

			} else if ( document.getElementById("fileSelect").files.length > 0  ) {

				// DECIDE WHETHER WE NEED A SIMQUERY
				// if the user hasn't provided a number of similar TS, or the
				//   number is zero, we won't bother sending off a simquery
				if (numSim == '' | numSim == 0) {

					console.log("Locally received data uploaded by user.");
					console.log( document.getElementById("fileSelect").files[0] );

					// parse the uploaded file
					// https://www.html5rocks.com/en/tutorials/file/dndfiles/
					read = new FileReader();
					read.readAsText(document.getElementById("fileSelect").files[0]);

					read.onloadend = function(){
						//console.log(read.result);
						//console.log(JSON.parse(read.result))
						//console.log(JSON.parse(read.result).ts)
						var dataTemp = JSON.parse(read.result).ts;
						dataTarget = dataTemp[0].map(function (e, i) {
												return [e, dataTemp[1][i]];});

						tsData = {label: "uploaded timeseries", data: dataTarget, lines: {lineWidth:6}};

						console.log('Appending uploaded time series to Flot data.');

						data.push(tsData);

						console.log(tsData);

						console.log('Plotting the data of the uploaded TS.');

						$.plot("#placeholder", data, options);

						console.log("Destroy the progress bar -- we don't need it anymore.");
						$("#progressbar").progressbar( "destroy" );

					}

				} else {

					console.log("Locally received data uploaded by user.");
					console.log( document.getElementById("fileSelect").files[0] );

					var simurl = publicIP + "/simquery?" + "topn=" + numSim;

					console.log("Sending user-loaded data off to be processed:" + simurl);
					$.ajax({
						url: simurl,
						type: 'POST',
						data: document.getElementById("fileSelect").files[0],
						cache: false,
						contentType: 'application/json; charset=utf-8',
						dataType: 'json',
						processData: false, // Don't process the files
						contentType: false, // Set content type to false as jQuery will tell the server its a query string request
						error: function(jqXHR, textStatus, errorThrown) {
					 			// Handle errors here
									console.log('ERRORS: ' + textStatus);
						}
					})
						.done(function (result) {

							simIDs = result.id;

							$.ajax({
								url: simurl,
								type: "GET",
								dataType: "json",
								success: function(data) {

										// loop over all the IDs and collect their data
										console.log("Looping over the retrieved ID numbers and collecting their data.");

										for(var i=0; i < simIDs.length; i++) {

											idNum   = simIDs[i];

											var dataurl = publicIP + "/timeseries/" + idNum;

											console.log('Retrieving data associated with TS ID#' + idNum + '.');
											// solution from http://stackoverflow.com/questions/4201934/
											//               jquery-ajax-pass-additional-argument-to-success-callback
											$.ajax({
												url: dataurl,
												type: "GET",
												dataType: "json",
												success: onDataReceived
											});

										}
							 }
						});

					// parse the uploaded file
					// https://www.html5rocks.com/en/tutorials/file/dndfiles/
					read = new FileReader();
					read.readAsText(document.getElementById("fileSelect").files[0]);

					read.onloadend = function(){
						//console.log(read.result);
						//console.log(JSON.parse(read.result))
						//console.log(JSON.parse(read.result).ts)
						var dataTemp = JSON.parse(read.result).ts;
						dataTarget = dataTemp[0].map(function (e, i) {
												return [e, dataTemp[1][i]];});

						tsData = {label: "uploaded timeseries", data: dataTarget, lines: {lineWidth:6}};

						console.log('Appending uploaded time series to Flot data.');

						data.push(tsData);

						console.log(tsData);

						console.log('Plotting the data of the uploaded TS.');

						$.plot("#placeholder", data, options);

					}
			});
				}

			} else {
				// user hasn't specified anything!
				alert("You gotta give us something valid to work with...");

				$("#progressbar").progressbar( "destroy" );
			}

			function onDataReceived(series) {

				// pull the similar TS
				//

				// * solution from Stack Overflow:
				//   http://stackoverflow.com/questions/22015684/
				//             how-do-i-zip-two-arrays-in-javascript
				console.log('Zipping TS ID#' + simIDs[counter] + ' into appropriate form for Flot to plot.');
				var dataTarget = series.ts[0].map(function (e, i) {
					return [e, series.ts[1][i]];
				});

				tsData = {label: "timeseries " + simIDs[counter], data: dataTarget};

				console.log('Appending TS ID#' + simIDs[counter] +' to Flot data.');
				data.push(tsData);

				$.plot("#placeholder", data, options);

				// if (1) we've reached the target TS ID, in the case of a specified TS ID
				//    (2) we've reached the end of the similar IDs, in the case of
				//        an uploaded TS,
				// we're done putting together the metadata table.
				// highlight the row of the targt TS ID and show the table to the world
				if( series.metadata[0].id == timeSeriesID ) {

					var tableRow = "
" + series.metadata[0].id + "	";
					tableRow    += "" +series.metadata[0].mean  + "	";
					tableRow    += "" +series.metadata[0].std   + "	";
					tableRow    += "" +series.metadata[0].level + "	";
					tableRow    += "" +series.metadata[0].blarg + "
";

					console.log("Adding ID #" + series.metadata[0].id + " to metadata table.")
					metadataTable += tableRow;

					console.log("Put together + display the metadata table.");
					metadataTable += tableBottom;
					document.getElementById('timeseriesMetadata').innerHTML = metadataTable;
					console.log("Destroy the progress bar -- we don't need it anymore.");
					$("#progressbar").progressbar( "destroy" );

				} else if ( counter == simIDs.length - 1 ) {

					var tableRow = "
" + series.metadata[0].id + "	";
					tableRow    += "" +series.metadata[0].mean  + "	";
					tableRow    += "" +series.metadata[0].std   + "	";
					tableRow    += "" +series.metadata[0].level + "	";
					tableRow    += "" +series.metadata[0].blarg + "
";

					console.log("Adding ID #" + series.metadata[0].id + " to metadata table.")
					metadataTable += tableRow;

					console.log("Put together + display the metadata table.");
					metadataTable += tableBottom;
					document.getElementById('timeseriesMetadata').innerHTML = metadataTable;
					console.log("Destroy the progress bar -- we don't need it anymore.");
					$("#progressbar").progressbar( "destroy" );

				} else {

					// put together the metadata
					var tableRow = "
" + series.metadata[0].id + "	";
					tableRow    += "" +series.metadata[0].mean  + "	";
					tableRow    += "" +series.metadata[0].std   + "	";
					tableRow    += "" +series.metadata[0].level + "	";
					tableRow    += "" +series.metadata[0].blarg + "
";

					console.log("Adding ID #" + series.metadata[0].id + " to metadata table.")
					metadataTable += tableRow;

				}

				// keeps track of where we are in the array of TS IDs to plot
				counter++;

			}

			function getSimIDs(series) {
				for(var i=0; i < series.id.length; i++) {
					simIDs.push(series.id[i]);
				}
			}

		});

		// Add the Flot version string to the footer
		$("#footer").prepend("Flot " + $.plot.version + " + ");
	});<commit_msg>Minor edit to simquery<commit_after>// code modified from flot AJAX example
// http://www.flotcharts.org/flot/examples/ajax/index.html

	$(function() {

		// flot plot options!
		var options = {
			lines: {
				show: true
			},
			points: {
				show: false
			},
			legend: {
				show: true
			},
			grid: {
        		hoverable: true
      		}
	};

		// GLOBAL VARIABLES AND FUNCTIONS

		console.log('Initializing variables.');
		// initialize the arrays hold the data for plotting
		var data = [];
		var dataTarget = [];

		// IP address to access our UI
		// (empty for relative URLs)
		var publicIP = '';

		// building blocks of metadata table
		var tableTop = "
";
		var tableBottom = "
";
		var tableHeader = "
ID	Mean	StDev	Level	Blarg
";
		var metadataTable = tableTop + tableHeader;

		// helps with managing the uploaded time series
		var files;

		// initialize the timeseries plot (will be empty)
		console.log('Initializing flot plot (empty plot).');
		$.plot("#placeholder", data, options);

		// ACTIONS TO COMPLETE WHEN THE `SUBMIT` BUTTON IS CLICKED
		$("button#tsQuery").click(function () {

			console.log('Submit button has been clicked.');

			// show the progress bar so the user knows that stuff
			// is going on behind the scenes

			console.log('Adding in ticking progress bar.');
			$( "#progressbar" ).progressbar({
  				value: false
			});

			// reset everything in preparation for new data
			console.log('Resetting helper variables in preparation for new data.');
			document.getElementById('timeseriesMetadata').innerHTML = '';
			data = [];
			var simIDs = [];
			var idNum = {};
			var counter = 0;
			metadataTable = tableTop + tableHeader;

			$.plot("#placeholder", data, options);

			// retrieve the time series specified by the user, and the number of
			//   most similar time series
			var timeSeriesID = document.getElementById("tsID").value;
			var numSim = document.getElementById("n_closest").value;
			console.log('Retrieved timeseries ID #' + timeSeriesID + 'and will retrieve the ' + numSim + 'most similar timeseries.');

			// CONSTRUCT OUR QUERY
			// if the user has specified an ID, use that;
			//   otherwise assume there's an uploaded file.
			if (timeSeriesID != '') {

				// DECIDE WHETHER WE NEED A SIMQUERY
				// if the user hasn't provided a number of similar TS, or the
				//   number is zero, we won't bother sending off a simquery
				if (numSim == '' | numSim == 0) {

					// add on the ID number of the target TS
					simIDs.push(timeSeriesID);

					// now we loop over all the IDs and collect their data
					console.log("Collecting data of specified time series.");

					var dataurl = publicIP + "/timeseries/" + timeSeriesID;

					console.log('Retrieving data associated with TS ID#'+ timeSeriesID + '.');

					$.ajax({
						url: dataurl,
						type: "GET",
						dataType: "json",
						success: onDataReceived
					});

				} else {

					var simurl = publicIP + "/simquery?id=" + timeSeriesID + "&topn=" + numSim;
					console.log('Constructed simquery:', simurl);

					// get the IDs of the similar time series
					console.log('Retrieving the ID numbers of the similar TS (ID number supplied).');
					$.ajax({
						url: simurl,
						type: "GET",
						dataType: "json",
						success: function(data) {

									// parse the ID numbers returned from the server
									getSimIDs(data);

									// add on the ID number of the target TS
									simIDs.push(timeSeriesID);

									// now we loop over all the IDs and collect their data
									console.log("Looping over the retrieved ID numbers and collecting their data.");

									for(var i=0; i < simIDs.length; i++) {

										idNum   = simIDs[i];

										var dataurl = publicIP + "/timeseries/" + idNum;

										console.log('Retrieving data associated with TS ID#'+ idNum + '.');
										// solution from http://stackoverflow.com/questions/4201934/
										//               jquery-ajax-pass-additional-argument-to-success-callback
										$.ajax({
											url: dataurl,
											type: "GET",
											dataType: "json",
											success: onDataReceived
										});

									}
						 }
					});
				}

			} else if ( document.getElementById("fileSelect").files.length > 0  ) {

				// DECIDE WHETHER WE NEED A SIMQUERY
				// if the user hasn't provided a number of similar TS, or the
				//   number is zero, we won't bother sending off a simquery
				if (numSim == '' | numSim == 0) {

					console.log("Locally received data uploaded by user.");
					console.log( document.getElementById("fileSelect").files[0] );

					// parse the uploaded file
					// https://www.html5rocks.com/en/tutorials/file/dndfiles/
					read = new FileReader();
					read.readAsText(document.getElementById("fileSelect").files[0]);

					read.onloadend = function(){
						//console.log(read.result);
						//console.log(JSON.parse(read.result))
						//console.log(JSON.parse(read.result).ts)
						var dataTemp = JSON.parse(read.result).ts;
						dataTarget = dataTemp[0].map(function (e, i) {
												return [e, dataTemp[1][i]];});

						tsData = {label: "uploaded timeseries", data: dataTarget, lines: {lineWidth:6}};

						console.log('Appending uploaded time series to Flot data.');

						data.push(tsData);

						console.log(tsData);

						console.log('Plotting the data of the uploaded TS.');

						$.plot("#placeholder", data, options);

						console.log("Destroy the progress bar -- we don't need it anymore.");
						$("#progressbar").progressbar( "destroy" );

					}

				} else {

					console.log("Locally received data uploaded by user.");
					console.log( document.getElementById("fileSelect").files[0] );

					var simurl = publicIP + "/simquery?" + "id=" + "&topn=" + numSim;

					console.log("Sending user-loaded data off to be processed:" + simurl);
					$.ajax({
						url: simurl,
						type: 'POST',
						data: document.getElementById("fileSelect").files[0],
						cache: false,
						contentType: 'application/json; charset=utf-8',
						dataType: 'json',
						processData: false, // Don't process the files
						contentType: false, // Set content type to false as jQuery will tell the server its a query string request
						error: function(jqXHR, textStatus, errorThrown) {
					 			// Handle errors here
									console.log('ERRORS: ' + textStatus);
						}
					})
						.done(function (result) {

							simIDs = result.id;

							$.ajax({
								url: simurl,
								type: "GET",
								dataType: "json",
								success: function(data) {

										// loop over all the IDs and collect their data
										console.log("Looping over the retrieved ID numbers and collecting their data.");

										for(var i=0; i < simIDs.length; i++) {

											idNum   = simIDs[i];

											var dataurl = publicIP + "/timeseries/" + idNum;

											console.log('Retrieving data associated with TS ID#' + idNum + '.');
											// solution from http://stackoverflow.com/questions/4201934/
											//               jquery-ajax-pass-additional-argument-to-success-callback
											$.ajax({
												url: dataurl,
												type: "GET",
												dataType: "json",
												success: onDataReceived
											});

										}
							 }
						});

					// parse the uploaded file
					// https://www.html5rocks.com/en/tutorials/file/dndfiles/
					read = new FileReader();
					read.readAsText(document.getElementById("fileSelect").files[0]);

					read.onloadend = function(){
						//console.log(read.result);
						//console.log(JSON.parse(read.result))
						//console.log(JSON.parse(read.result).ts)
						var dataTemp = JSON.parse(read.result).ts;
						dataTarget = dataTemp[0].map(function (e, i) {
												return [e, dataTemp[1][i]];});

						tsData = {label: "uploaded timeseries", data: dataTarget, lines: {lineWidth:6}};

						console.log('Appending uploaded time series to Flot data.');

						data.push(tsData);

						console.log(tsData);

						console.log('Plotting the data of the uploaded TS.');

						$.plot("#placeholder", data, options);

					}
			});
				}

			} else {
				// user hasn't specified anything!
				alert("You gotta give us something valid to work with...");

				$("#progressbar").progressbar( "destroy" );
			}

			function onDataReceived(series) {

				// pull the similar TS
				//

				// * solution from Stack Overflow:
				//   http://stackoverflow.com/questions/22015684/
				//             how-do-i-zip-two-arrays-in-javascript
				console.log('Zipping TS ID#' + simIDs[counter] + ' into appropriate form for Flot to plot.');
				var dataTarget = series.ts[0].map(function (e, i) {
					return [e, series.ts[1][i]];
				});

				tsData = {label: "timeseries " + simIDs[counter], data: dataTarget};

				console.log('Appending TS ID#' + simIDs[counter] +' to Flot data.');
				data.push(tsData);

				$.plot("#placeholder", data, options);

				// if (1) we've reached the target TS ID, in the case of a specified TS ID
				//    (2) we've reached the end of the similar IDs, in the case of
				//        an uploaded TS,
				// we're done putting together the metadata table.
				// highlight the row of the targt TS ID and show the table to the world
				if( series.metadata[0].id == timeSeriesID ) {

					var tableRow = "
" + series.metadata[0].id + "	";
					tableRow    += "" +series.metadata[0].mean  + "	";
					tableRow    += "" +series.metadata[0].std   + "	";
					tableRow    += "" +series.metadata[0].level + "	";
					tableRow    += "" +series.metadata[0].blarg + "
";

					console.log("Adding ID #" + series.metadata[0].id + " to metadata table.")
					metadataTable += tableRow;

					console.log("Put together + display the metadata table.");
					metadataTable += tableBottom;
					document.getElementById('timeseriesMetadata').innerHTML = metadataTable;
					console.log("Destroy the progress bar -- we don't need it anymore.");
					$("#progressbar").progressbar( "destroy" );

				} else if ( counter == simIDs.length - 1 ) {

					var tableRow = "
" + series.metadata[0].id + "	";
					tableRow    += "" +series.metadata[0].mean  + "	";
					tableRow    += "" +series.metadata[0].std   + "	";
					tableRow    += "" +series.metadata[0].level + "	";
					tableRow    += "" +series.metadata[0].blarg + "
";

					console.log("Adding ID #" + series.metadata[0].id + " to metadata table.")
					metadataTable += tableRow;

					console.log("Put together + display the metadata table.");
					metadataTable += tableBottom;
					document.getElementById('timeseriesMetadata').innerHTML = metadataTable;
					console.log("Destroy the progress bar -- we don't need it anymore.");
					$("#progressbar").progressbar( "destroy" );

				} else {

					// put together the metadata
					var tableRow = "
" + series.metadata[0].id + "	";
					tableRow    += "" +series.metadata[0].mean  + "	";
					tableRow    += "" +series.metadata[0].std   + "	";
					tableRow    += "" +series.metadata[0].level + "	";
					tableRow    += "" +series.metadata[0].blarg + "
";

					console.log("Adding ID #" + series.metadata[0].id + " to metadata table.")
					metadataTable += tableRow;

				}

				// keeps track of where we are in the array of TS IDs to plot
				counter++;

			}

			function getSimIDs(series) {
				for(var i=0; i < series.id.length; i++) {
					simIDs.push(series.id[i]);
				}
			}

		});

		// Add the Flot version string to the footer
		$("#footer").prepend("Flot " + $.plot.version + " + ");
	});<|endoftext|>


<commit_before>/*
Language: Ruby
Description: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.
Website: https://www.ruby-lang.org/
Author: Anton Kovalyov <anton@kovalyov.net>
Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>
Category: common
*/

import * as regex from '../lib/regex.js';

export default function(hljs) {
  var RUBY_METHOD_RE = '([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)';
  var RUBY_KEYWORDS = {
    keyword:
      'and then defined module in return redo if BEGIN retry end for self when ' +
      'next until do begin unless END rescue else break undef not super class case ' +
      'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor ' +
      '__FILE__',
    built_in: 'proc lambda',
    literal:
      'true false nil'
  };
  var YARDOCTAG = {
    className: 'doctag',
    begin: '@[A-Za-z]+'
  };
  var IRB_OBJECT = {
    begin: '#<', end: '>'
  };
  var COMMENT_MODES = [
    hljs.COMMENT(
      '#',
      '$',
      {
        contains: [YARDOCTAG]
      }
    ),
    hljs.COMMENT(
      '^=begin',
      '^=end',
      {
        contains: [YARDOCTAG],
        relevance: 10
      }
    ),
    hljs.COMMENT('^__END__', '\\n$')
  ];
  var SUBST = {
    className: 'subst',
    begin: /#\{/, end: /\}/,
    keywords: RUBY_KEYWORDS
  };
  var STRING = {
    className: 'string',
    contains: [hljs.BACKSLASH_ESCAPE, SUBST],
    variants: [
      {begin: /'/, end: /'/},
      {begin: /"/, end: /"/},
      {begin: /`/, end: /`/},
      {begin: /%[qQwWx]?\(/, end: /\)/},
      {begin: /%[qQwWx]?\[/, end: /\]/},
      {begin: /%[qQwWx]?\{/, end: /\}/},
      {begin: /%[qQwWx]?</, end: />/},
      {begin: /%[qQwWx]?\//, end: /\//},
      {begin: /%[qQwWx]?%/, end: /%/},
      {begin: /%[qQwWx]?-/, end: /-/},
      {begin: /%[qQwWx]?\|/, end: /\|/},
      {
        // \B in the beginning suppresses recognition of ?-sequences where ?
        // is the last character of a preceding identifier, as in: `func?4`
        begin: /\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/
      },
      { // heredocs
        begin: /<<[-~]?'?(\w+)\n(?:[^\n]*\n)*?\s*\1\b/,
        returnBegin: true,
        contains: [
          { begin: /<<[-~]?'?/ },
          hljs.END_SAME_AS_BEGIN({
            begin: /(\w+)/, end: /(\w+)/,
            contains: [hljs.BACKSLASH_ESCAPE, SUBST],
          })
        ]
      }
    ]
  };

  // Ruby syntax is underdocumented, but this grammar seems to be accurate
  // as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)
  // https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers
  var decimal = '[1-9](_?[0-9])*|0';
  var digits = '[0-9](_?[0-9])*';
  var NUMBER = {
    className: 'number', relevance: 0,
    variants: [
      // decimal integer/float, optionally exponential or rational, optionally imaginary
      { begin: `\\b(${decimal})(\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\b` },

      // explicit decimal/binary/octal/hexadecimal integer,
      // optionally rational and/or imaginary
      { begin: "\\b0[dD][0-9](_?[0-9])*r?i?\\b" },
      { begin: "\\b0[bB][0-1](_?[0-1])*r?i?\\b" },
      { begin: "\\b0[oO][0-7](_?[0-7])*r?i?\\b" },
      { begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b" },

      // 0-prefixed implicit octal integer, optionally rational and/or imaginary
      { begin: "\\b0(_?[0-7])+r?i?\\b" },
    ]
  };

  var PARAMS = {
    className: 'params',
    begin: '\\(', end: '\\)', endsParent: true,
    keywords: RUBY_KEYWORDS
  };

  var RUBY_DEFAULT_CONTAINS = [
    STRING,
    {
      className: 'class',
      beginKeywords: 'class module', end: '$|;',
      illegal: /=/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|!)?'}),
        {
          begin: '<\\s*',
          contains: [{
            begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
          }]
        }
      ].concat(COMMENT_MODES)
    },
    {
      className: 'function',
      // def method_name(
      // def method_name;
      // def method_name (end of line)
      begin: regex.concat(/def\s*/, regex.lookahead(RUBY_METHOD_RE + "\\s*(\\(|;|$)")),
      keywords: "def",
      end: '$|;',
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {begin: RUBY_METHOD_RE}),
        PARAMS
      ].concat(COMMENT_MODES)
    },
    {
      // swallow namespace qualifiers before symbols
      begin: hljs.IDENT_RE + '::'
    },
    {
      className: 'symbol',
      begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':(?!\\s)',
      contains: [STRING, {begin: RUBY_METHOD_RE}],
      relevance: 0
    },
    NUMBER,
    {
      // negative-look forward attemps to prevent false matches like:
      // @ident@ or $ident$ that might indicate this is not ruby at all
      className: "variable",
      begin: '(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`
    },
    {
      className: 'params',
      begin: /\|/,
      end: /\|/,
      relevance:0, // this could be a lot of things (in other languages) other than params
      keywords: RUBY_KEYWORDS
    },
    { // regexp container
      begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
      keywords: 'unless',
      contains: [
        {
          className: 'regexp',
          contains: [hljs.BACKSLASH_ESCAPE, SUBST],
          illegal: /\n/,
          variants: [
            {begin: '/', end: '/[a-z]*'},
            {begin: /%r\{/, end: /\}[a-z]*/},
            {begin: '%r\\(', end: '\\)[a-z]*'},
            {begin: '%r!', end: '![a-z]*'},
            {begin: '%r\\[', end: '\\][a-z]*'}
          ]
        }
      ].concat(IRB_OBJECT, COMMENT_MODES),
      relevance: 0
    }
  ].concat(IRB_OBJECT, COMMENT_MODES);

  SUBST.contains = RUBY_DEFAULT_CONTAINS
  PARAMS.contains = RUBY_DEFAULT_CONTAINS

  // >>
  // ?>
  var SIMPLE_PROMPT = "[>?]>";
  // irb(main):001:0>
  var DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+>";
  var RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>";

  var IRB_DEFAULT = [
    {
      begin: /^\s*=>/,
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    },
    {
      className: 'meta',
      begin: '^('+SIMPLE_PROMPT+"|"+DEFAULT_PROMPT+'|'+RVM_PROMPT+')(?=[ ])',
      starts: {
        end: '$', contains: RUBY_DEFAULT_CONTAINS
      }
    }
  ];

  COMMENT_MODES.unshift(IRB_OBJECT);

  return {
    name: 'Ruby',
    aliases: ['rb', 'gemspec', 'podspec', 'thor', 'irb'],
    keywords: RUBY_KEYWORDS,
    illegal: /\/\*/,
    contains: [
        hljs.SHEBANG({binary:"ruby"}),
      ]
      .concat(IRB_DEFAULT)
      .concat(COMMENT_MODES)
      .concat(RUBY_DEFAULT_CONTAINS)
  };
}
<commit_msg>chore(lint) ruby<commit_after>/*
Language: Ruby
Description: Ruby is a dynamic, open source programming language with a focus on simplicity and productivity.
Website: https://www.ruby-lang.org/
Author: Anton Kovalyov <anton@kovalyov.net>
Contributors: Peter Leonov <gojpeg@yandex.ru>, Vasily Polovnyov <vast@whiteants.net>, Loren Segal <lsegal@soen.ca>, Pascal Hurni <phi@ruby-reactive.org>, Cedric Sohrauer <sohrauer@googlemail.com>
Category: common
*/

import * as regex from '../lib/regex.js';

export default function(hljs) {
  const RUBY_METHOD_RE = '([a-zA-Z_]\\w*[!?=]?|[-+~]@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?)';
  const RUBY_KEYWORDS = {
    keyword:
      'and then defined module in return redo if BEGIN retry end for self when ' +
      'next until do begin unless END rescue else break undef not super class case ' +
      'require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor ' +
      '__FILE__',
    built_in: 'proc lambda',
    literal:
      'true false nil'
  };
  const YARDOCTAG = {
    className: 'doctag',
    begin: '@[A-Za-z]+'
  };
  const IRB_OBJECT = {
    begin: '#<',
    end: '>'
  };
  const COMMENT_MODES = [
    hljs.COMMENT(
      '#',
      '$',
      {
        contains: [ YARDOCTAG ]
      }
    ),
    hljs.COMMENT(
      '^=begin',
      '^=end',
      {
        contains: [ YARDOCTAG ],
        relevance: 10
      }
    ),
    hljs.COMMENT('^__END__', '\\n$')
  ];
  const SUBST = {
    className: 'subst',
    begin: /#\{/,
    end: /\}/,
    keywords: RUBY_KEYWORDS
  };
  const STRING = {
    className: 'string',
    contains: [
      hljs.BACKSLASH_ESCAPE,
      SUBST
    ],
    variants: [
      {
        begin: /'/,
        end: /'/
      },
      {
        begin: /"/,
        end: /"/
      },
      {
        begin: /`/,
        end: /`/
      },
      {
        begin: /%[qQwWx]?\(/,
        end: /\)/
      },
      {
        begin: /%[qQwWx]?\[/,
        end: /\]/
      },
      {
        begin: /%[qQwWx]?\{/,
        end: /\}/
      },
      {
        begin: /%[qQwWx]?</,
        end: />/
      },
      {
        begin: /%[qQwWx]?\//,
        end: /\//
      },
      {
        begin: /%[qQwWx]?%/,
        end: /%/
      },
      {
        begin: /%[qQwWx]?-/,
        end: /-/
      },
      {
        begin: /%[qQwWx]?\|/,
        end: /\|/
      },
      {
        // \B in the beginning suppresses recognition of ?-sequences where ?
        // is the last character of a preceding identifier, as in: `func?4`
        begin: /\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/
      },
      { // heredocs
        begin: /<<[-~]?'?(\w+)\n(?:[^\n]*\n)*?\s*\1\b/,
        returnBegin: true,
        contains: [
          {
            begin: /<<[-~]?'?/
          },
          hljs.END_SAME_AS_BEGIN({
            begin: /(\w+)/,
            end: /(\w+)/,
            contains: [
              hljs.BACKSLASH_ESCAPE,
              SUBST
            ]
          })
        ]
      }
    ]
  };

  // Ruby syntax is underdocumented, but this grammar seems to be accurate
  // as of version 2.7.2 (confirmed with (irb and `Ripper.sexp(...)`)
  // https://docs.ruby-lang.org/en/2.7.0/doc/syntax/literals_rdoc.html#label-Numbers
  const decimal = '[1-9](_?[0-9])*|0';
  const digits = '[0-9](_?[0-9])*';
  const NUMBER = {
    className: 'number',
    relevance: 0,
    variants: [
      // decimal integer/float, optionally exponential or rational, optionally imaginary
      {
        begin: `\\b(${decimal})(\\.(${digits}))?([eE][+-]?(${digits})|r)?i?\\b`
      },

      // explicit decimal/binary/octal/hexadecimal integer,
      // optionally rational and/or imaginary
      {
        begin: "\\b0[dD][0-9](_?[0-9])*r?i?\\b"
      },
      {
        begin: "\\b0[bB][0-1](_?[0-1])*r?i?\\b"
      },
      {
        begin: "\\b0[oO][0-7](_?[0-7])*r?i?\\b"
      },
      {
        begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*r?i?\\b"
      },

      // 0-prefixed implicit octal integer, optionally rational and/or imaginary
      {
        begin: "\\b0(_?[0-7])+r?i?\\b"
      }
    ]
  };

  const PARAMS = {
    className: 'params',
    begin: '\\(',
    end: '\\)',
    endsParent: true,
    keywords: RUBY_KEYWORDS
  };

  const RUBY_DEFAULT_CONTAINS = [
    STRING,
    {
      className: 'class',
      beginKeywords: 'class module',
      end: '$|;',
      illegal: /=/,
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {
          begin: '[A-Za-z_]\\w*(::\\w+)*(\\?|!)?'
        }),
        {
          begin: '<\\s*',
          contains: [
            {
              begin: '(' + hljs.IDENT_RE + '::)?' + hljs.IDENT_RE
            }
          ]
        }
      ].concat(COMMENT_MODES)
    },
    {
      className: 'function',
      // def method_name(
      // def method_name;
      // def method_name (end of line)
      begin: regex.concat(/def\s*/, regex.lookahead(RUBY_METHOD_RE + "\\s*(\\(|;|$)")),
      keywords: "def",
      end: '$|;',
      contains: [
        hljs.inherit(hljs.TITLE_MODE, {
          begin: RUBY_METHOD_RE
        }),
        PARAMS
      ].concat(COMMENT_MODES)
    },
    {
      // swallow namespace qualifiers before symbols
      begin: hljs.IDENT_RE + '::'
    },
    {
      className: 'symbol',
      begin: hljs.UNDERSCORE_IDENT_RE + '(!|\\?)?:',
      relevance: 0
    },
    {
      className: 'symbol',
      begin: ':(?!\\s)',
      contains: [
        STRING,
        {
          begin: RUBY_METHOD_RE
        }
      ],
      relevance: 0
    },
    NUMBER,
    {
      // negative-look forward attemps to prevent false matches like:
      // @ident@ or $ident$ that might indicate this is not ruby at all
      className: "variable",
      begin: '(\\$\\W)|((\\$|@@?)(\\w+))(?=[^@$?])' + `(?![A-Za-z])(?![@$?'])`
    },
    {
      className: 'params',
      begin: /\|/,
      end: /\|/,
      relevance: 0, // this could be a lot of things (in other languages) other than params
      keywords: RUBY_KEYWORDS
    },
    { // regexp container
      begin: '(' + hljs.RE_STARTERS_RE + '|unless)\\s*',
      keywords: 'unless',
      contains: [
        {
          className: 'regexp',
          contains: [
            hljs.BACKSLASH_ESCAPE,
            SUBST
          ],
          illegal: /\n/,
          variants: [
            {
              begin: '/',
              end: '/[a-z]*'
            },
            {
              begin: /%r\{/,
              end: /\}[a-z]*/
            },
            {
              begin: '%r\\(',
              end: '\\)[a-z]*'
            },
            {
              begin: '%r!',
              end: '![a-z]*'
            },
            {
              begin: '%r\\[',
              end: '\\][a-z]*'
            }
          ]
        }
      ].concat(IRB_OBJECT, COMMENT_MODES),
      relevance: 0
    }
  ].concat(IRB_OBJECT, COMMENT_MODES);

  SUBST.contains = RUBY_DEFAULT_CONTAINS;
  PARAMS.contains = RUBY_DEFAULT_CONTAINS;

  // >>
  // ?>
  const SIMPLE_PROMPT = "[>?]>";
  // irb(main):001:0>
  const DEFAULT_PROMPT = "[\\w#]+\\(\\w+\\):\\d+:\\d+>";
  const RVM_PROMPT = "(\\w+-)?\\d+\\.\\d+\\.\\d+(p\\d+)?[^\\d][^>]+>";

  const IRB_DEFAULT = [
    {
      begin: /^\s*=>/,
      starts: {
        end: '$',
        contains: RUBY_DEFAULT_CONTAINS
      }
    },
    {
      className: 'meta',
      begin: '^(' + SIMPLE_PROMPT + "|" + DEFAULT_PROMPT + '|' + RVM_PROMPT + ')(?=[ ])',
      starts: {
        end: '$',
        contains: RUBY_DEFAULT_CONTAINS
      }
    }
  ];

  COMMENT_MODES.unshift(IRB_OBJECT);

  return {
    name: 'Ruby',
    aliases: [
      'rb',
      'gemspec',
      'podspec',
      'thor',
      'irb'
    ],
    keywords: RUBY_KEYWORDS,
    illegal: /\/\*/,
    contains: [
      hljs.SHEBANG({
        binary: "ruby"
      })
    ]
      .concat(IRB_DEFAULT)
      .concat(COMMENT_MODES)
      .concat(RUBY_DEFAULT_CONTAINS)
  };
}
<|endoftext|>


<commit_before>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'js-whatever/js/base-page',
    'find/app/model/backbone-query-model',
    'find/app/model/query-model',
    'find/app/model/entity-collection',
    'find/app/model/indexes-collection',
    'find/app/page/indexes/indexes-view',
    'find/app/model/parametric-collection',
    'find/app/page/parametric/parametric-controller',
    'find/app/page/date/dates-filter-view',
    'find/app/page/results/results-view',
    'find/app/page/related-concepts/related-concepts-view',
    'find/app/util/collapsible',
    'find/app/router',
    'find/app/vent',
    'i18n!find/nls/bundle',
    'moment',
    'jquery',
    'underscore',
    'text!find/templates/app/page/find-search.html',
    'text!find/templates/app/page/index-popover.html',
    'text!find/templates/app/page/index-popover-contents.html',
    'text!find/templates/app/page/top-results-popover-contents.html',
    'text!find/templates/app/util/filter-header.html',
    'colorbox'
], function(BasePage, BackboneQueryModel, QueryModel, EntityCollection, IndexesCollection, IndexesView, ParametricCollection,
            ParametricController, DateView, ResultsView, RelatedConceptsView, Collapsible, router, vent, i18n, moment,
            $, _, template, indexPopover, indexPopoverContents, topResultsPopoverContents, filterHeader) {

    var filterHeaderTemplate = _.template(filterHeader);

    var collapseView = function(title, collapseParameter, view) {
        return new Collapsible({
            header: filterHeaderTemplate({
                title: i18n[title]
            }),
            name: collapseParameter,
            view: view
        });
    };

    return BasePage.extend({

        template: _.template(template),
        noResultsTemplate: _.template('
<%- i18n["search.noResults"] %>
'),
        topResultsPopoverContents: _.template(topResultsPopoverContents),

        events: {
            'keyup .find-input': 'keyupAnimation',
            'mouseover .entity-to-summary': function(e) {
                var title = $(e.currentTarget).find('a').html();
                this.$('[data-title="'+ title +'"]').addClass('label label-primary entity-to-summary').removeClass('label-info');
            },
            'mouseleave .entity-to-summary': function() {
                this.$('.suggestions-content li a').removeClass('label label-primary entity-to-summary');
                this.$('.main-results-content .entity-to-summary').removeClass('label-primary').addClass('label-info');
            }
        },

        initialize: function() {
            this.queryModel = new QueryModel(new BackboneQueryModel());

            this.listenTo(this.queryModel, 'change', function() {
                this.searchRequest();
            });

            this.entityCollection = new EntityCollection();

            this.indexesView = new IndexesView({
                queryModel: this.queryModel
            });

            this.resultsView = new ResultsView({
                queryModel: this.queryModel,
                entityCollection: this.entityCollection
            });

            // Left Collapsed Views
            this.parametricController = new ParametricController({
                queryModel: this.queryModel
            });

            this.dateView = new DateView({
                queryModel: this.queryModel
            });

            this.relatedConceptsView = new RelatedConceptsView({
                queryModel: this.queryModel,
                entityCollection: this.entityCollection
            });

            // Collapse wrappers

            this.parametricViewWrapper = collapseView('parametric.title', 'parametric-filter', this.parametricController.view);
            this.dateViewWrapper = collapseView('search.dates', 'dates-filter', this.dateView);
            this.relatedConceptsViewWrapper = collapseView('search.relatedConcepts', 'related-concepts', this.relatedConceptsView);

            router.on('route:search', function(text) {
                if (text) {
                    this.$('.find-input').val(text); //when clicking one of the suggested search links
                    this.keyupAnimation();
                } else {
                    this.reverseAnimation(); //when clicking the small 'find' logo
                }
            }, this);
        },

        render: function() {
            this.$el.html(this.template);

            this.$('.find-form').submit(function(e){ //preventing input form submit and page reload
                e.preventDefault();
            });

            this.indexesView.setElement(this.$('.indexes-container')).render();

            this.parametricViewWrapper.setElement(this.$('.parametric-container')).render();
            this.dateViewWrapper.setElement(this.$('.date-container')).render();

            this.relatedConceptsViewWrapper.render();

            this.$('.related-concepts-container').append(this.relatedConceptsViewWrapper.$el);

            this.resultsView.setElement(this.$('.results-container')).render();

            this.reverseAnimation();
        },

        searchRequest: function() {
            this.entityCollection.fetch({
                data: {
                    text: this.queryModel.get('queryText'),
                    index: this.queryModel.get('indexes'),
                    field_text: this.queryModel.getFieldTextString()
                }
            });

            vent.navigate('find/search/' + encodeURIComponent(this.queryModel.get('queryText')), {trigger: false});
        },

        keyupAnimation: _.debounce(function() {
            /*fancy animation*/
            if($.trim(this.$('.find-input').val()).length) { // input has at least one non whitespace character
                this.$('.find').addClass('animated-container').removeClass('reverse-animated-container');

                this.$('.main-results-content').show();
                this.$('.related-concepts-container').show();
                this.$('.parametric-container').show();
                this.$('.date-container').show();

                this.queryModel.set('queryText', this.$('.find-input').val())
            } else {
                this.reverseAnimation();
                vent.navigate('find/search', {trigger: false});
            }
        }, 500),

        reverseAnimation: function() {
            /*fancy reverse animation*/
            this.$('.find').removeClass('animated-container').addClass('reverse-animated-container');

            this.$('.main-results-content').hide();
            this.$('.related-concepts-container').hide();
            this.$('.parametric-container').hide();
            this.$('.date-container').hide();
        }
    });
});
<commit_msg>The known bug wherein has the input didn't update has been filled with a stop gap solution.<commit_after>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'js-whatever/js/base-page',
    'find/app/model/backbone-query-model',
    'find/app/model/query-model',
    'find/app/model/entity-collection',
    'find/app/model/indexes-collection',
    'find/app/page/indexes/indexes-view',
    'find/app/model/parametric-collection',
    'find/app/page/parametric/parametric-controller',
    'find/app/page/date/dates-filter-view',
    'find/app/page/results/results-view',
    'find/app/page/related-concepts/related-concepts-view',
    'find/app/util/collapsible',
    'find/app/router',
    'find/app/vent',
    'i18n!find/nls/bundle',
    'moment',
    'jquery',
    'underscore',
    'text!find/templates/app/page/find-search.html',
    'text!find/templates/app/page/index-popover.html',
    'text!find/templates/app/page/index-popover-contents.html',
    'text!find/templates/app/page/top-results-popover-contents.html',
    'text!find/templates/app/util/filter-header.html',
    'colorbox'
], function(BasePage, BackboneQueryModel, QueryModel, EntityCollection, IndexesCollection, IndexesView, ParametricCollection,
            ParametricController, DateView, ResultsView, RelatedConceptsView, Collapsible, router, vent, i18n, moment,
            $, _, template, indexPopover, indexPopoverContents, topResultsPopoverContents, filterHeader) {

    var filterHeaderTemplate = _.template(filterHeader);

    var collapseView = function(title, collapseParameter, view) {
        return new Collapsible({
            header: filterHeaderTemplate({
                title: i18n[title]
            }),
            name: collapseParameter,
            view: view
        });
    };

    return BasePage.extend({

        template: _.template(template),
        noResultsTemplate: _.template('
<%- i18n["search.noResults"] %>
'),
        topResultsPopoverContents: _.template(topResultsPopoverContents),

        events: {
            'keyup .find-input': 'keyupAnimation',
            'mouseover .entity-to-summary': function(e) {
                var title = $(e.currentTarget).find('a').html();
                this.$('[data-title="'+ title +'"]').addClass('label label-primary entity-to-summary').removeClass('label-info');
            },
            'mouseleave .entity-to-summary': function() {
                this.$('.suggestions-content li a').removeClass('label label-primary entity-to-summary');
                this.$('.main-results-content .entity-to-summary').removeClass('label-primary').addClass('label-info');
            }
        },

        initialize: function() {
            this.queryModel = new QueryModel(new BackboneQueryModel());

            this.listenTo(this.queryModel, 'change', function() {
                this.searchRequest();
            });

            this.entityCollection = new EntityCollection();

            this.indexesView = new IndexesView({
                queryModel: this.queryModel
            });

            this.resultsView = new ResultsView({
                queryModel: this.queryModel,
                entityCollection: this.entityCollection
            });

            // Left Collapsed Views
            this.parametricController = new ParametricController({
                queryModel: this.queryModel
            });

            this.dateView = new DateView({
                queryModel: this.queryModel
            });

            this.relatedConceptsView = new RelatedConceptsView({
                queryModel: this.queryModel,
                entityCollection: this.entityCollection
            });

            // Collapse wrappers

            this.parametricViewWrapper = collapseView('parametric.title', 'parametric-filter', this.parametricController.view);
            this.dateViewWrapper = collapseView('search.dates', 'dates-filter', this.dateView);
            this.relatedConceptsViewWrapper = collapseView('search.relatedConcepts', 'related-concepts', this.relatedConceptsView);

            router.on('route:search', function(text) {
                if (text) {
                    this.$('.find-input').val(text); //when clicking one of the suggested search links
                    this.keyupAnimation();
                } else {
                    this.reverseAnimation(); //when clicking the small 'find' logo
                }
            }, this);
        },

        render: function() {
            this.$el.html(this.template);

            this.$('.find-form').submit(function(e){ //preventing input form submit and page reload
                e.preventDefault();
            });

            this.indexesView.setElement(this.$('.indexes-container')).render();

            this.parametricViewWrapper.setElement(this.$('.parametric-container')).render();
            this.dateViewWrapper.setElement(this.$('.date-container')).render();

            this.relatedConceptsViewWrapper.render();

            this.$('.related-concepts-container').append(this.relatedConceptsViewWrapper.$el);

            this.resultsView.setElement(this.$('.results-container')).render();

            this.reverseAnimation();
        },

        searchRequest: function() {
            this.$('.find-input').val(this.queryModel.get('queryText')); //when clicking one of the suggested search links

            this.entityCollection.fetch({
                data: {
                    text: this.queryModel.get('queryText'),
                    index: this.queryModel.get('indexes'),
                    field_text: this.queryModel.getFieldTextString()
                }
            });

            vent.navigate('find/search/' + encodeURIComponent(this.queryModel.get('queryText')), {trigger: false});
        },

        keyupAnimation: _.debounce(function() {
            /*fancy animation*/
            if($.trim(this.$('.find-input').val()).length) { // input has at least one non whitespace character
                this.$('.find').addClass('animated-container').removeClass('reverse-animated-container');

                this.$('.main-results-content').show();
                this.$('.related-concepts-container').show();
                this.$('.parametric-container').show();
                this.$('.date-container').show();

                this.queryModel.set('queryText', this.$('.find-input').val())
            } else {
                this.reverseAnimation();
                vent.navigate('find/search', {trigger: false});
            }
        }, 500),

        reverseAnimation: function() {
            /*fancy reverse animation*/
            this.$('.find').removeClass('animated-container').addClass('reverse-animated-container');

            this.$('.main-results-content').hide();
            this.$('.related-concepts-container').hide();
            this.$('.parametric-container').hide();
            this.$('.date-container').hide();
        }
    });
});
<|endoftext|>


<commit_before>var KPlug = KPlug || {};

/**
 * This plugin is a wrapper around KEN.Button, allowing someone to create a
 * button from a tour.json, without having to access the javascript code and
 * instantiate itself a KEN.Button.
 */
KPlug.SimpleButton = function()
{
    // The button, a KEN.Button instance
    this._btn = null;
};

KPlug.SimpleButton.prototype = {

    /**
     * The boot function
     */
    boot: function()
    {
        // Create a KEN.Button instance
        this._btn = this.plugin.create.button();

        // Set properties to the button
        this._btn.top = this.plugin.options.top;
        this._btn.right = this.plugin.options.right;
        this._btn.bottom = this.plugin.options.bottom;
        this._btn.left = this.plugin.options.left;
        this._btn.horizontalCenter = this.plugin.options.horizontalCenter;
        this._btn.verticalCenter = this.plugin.options.verticalCenter;

        var skin = this._btn.skin;

        // Set the skin if any
        if (typeof this.plugin.options.skin !== "undefined")
        {
            // default state
            if (typeof this.plugin.options.skin.out !== "undefined")
            {
                skin.out = KEN.Utils.extendMultipleObjects((this.plugin.options.defaultSkin === true ? KEN.ButtonSkin.DEFAULT_STATE : {}), skin.out, this.plugin.options.skin.out);
            }

            // skin.out is the default skin state for over state
            if (typeof this.plugin.options.skin.over !== "undefined")
            {
                skin.over = KEN.Utils.extendMultipleObjects(skin.out, skin.over, this.plugin.options.skin.over);
            }

            // skin.out is the default skin state for down state
            if (typeof this.plugin.options.skin.down !== "undefined")
            {
                skin.down = KEN.Utils.extendMultipleObjects(skin.out, skin.down, this.plugin.options.skin.down);
            }
        }

        // Set the global value if any
        if (this.plugin.options.value !== undefined && this.plugin.options.value !== null)
        {
            if(typeof skin.out.label !== "undefined")
            {
                skin.out.label.value = this.plugin.options.value;
            }
            if(typeof skin.over.label !== "undefined")
            {
                skin.over.label.value = this.plugin.options.value;
            }
            if(typeof skin.down.label !== "undefined")
            {
                skin.down.label.value = this.plugin.options.value;
            }
        }

        this._btn.updateSkin();

        this._btn.width = this.plugin.options.width;
        this._btn.height = this.plugin.options.height;

        // Add the button to the main container
        this.plugin.container.addChild(this._btn);

        // Add the events handlers
        this._btn.pointer.onClick.add(this._btnClickHandler, this);
        this._btn.pointer.onOut.add(this._btnOutHandler, this);
        this._btn.pointer.onOver.add(this._btnOverHandler, this);
        this._btn.pointer.onDown.add(this._btnDownHandler, this);
    },

    /**
     * Fires the handler for a click on the button.
     */
    _btnClickHandler: function(event)
    {
        this.plugin.events.onClick.dispatch();
    },

    /**
     * Fires the handler for going out the button.
     */
    _btnOutHandler: function(event)
    {
        this.plugin.events.onOut.dispatch();
    },

    /**
     * Fires the handler for being over the button.
     */
    _btnOverHandler: function(event)
    {
        this.plugin.events.onOver.dispatch();
    },

    /**
     * Fires the handler for the button currently being click on (click
     * maintained).
     */
    _btnDownHandler: function(event)
    {
        this.plugin.events.onDown.dispatch();
    },

    /**
     * Placeholder, do nothing
     */
    update: function() {},

    /**
     * Placeholder, do nothing
     */
    reset: function() {},

    /**
     * Show the button
     */
    show: function()
    {
        this._btn.show();
    },

    /**
     * Hide the button
     */
    hide: function()
    {
        this._btn.hide();
    },

    /**
     * Destroy the button.
     */
    destroy: function()
    {
        this._btn.destroy();
        this._btn = null;
    }
};<commit_msg>Add a setText method to change text vale on the SimpleButton plugin.<commit_after>var KPlug = KPlug || {};

/**
 * This plugin is a wrapper around KEN.Button, allowing someone to create a
 * button from a tour.json, without having to access the javascript code and
 * instantiate itself a KEN.Button.
 */
KPlug.SimpleButton = function()
{
    // The button, a KEN.Button instance
    this._btn = null;
};

KPlug.SimpleButton.prototype = {

    /**
     * The boot function
     */
    boot: function()
    {
        // Create a KEN.Button instance
        this._btn = this.plugin.create.button();

        // Set properties to the button
        this._btn.top = this.plugin.options.top;
        this._btn.right = this.plugin.options.right;
        this._btn.bottom = this.plugin.options.bottom;
        this._btn.left = this.plugin.options.left;
        this._btn.horizontalCenter = this.plugin.options.horizontalCenter;
        this._btn.verticalCenter = this.plugin.options.verticalCenter;

        var skin = this._btn.skin;

        // Set the skin if any
        if (typeof this.plugin.options.skin !== "undefined")
        {
            // default state
            if (typeof this.plugin.options.skin.out !== "undefined")
            {
                skin.out = KEN.Utils.extendMultipleObjects((this.plugin.options.defaultSkin === true ? KEN.ButtonSkin.DEFAULT_STATE : {}), skin.out, this.plugin.options.skin.out);
            }

            // skin.out is the default skin state for over state
            if (typeof this.plugin.options.skin.over !== "undefined")
            {
                skin.over = KEN.Utils.extendMultipleObjects(skin.out, skin.over, this.plugin.options.skin.over);
            }

            // skin.out is the default skin state for down state
            if (typeof this.plugin.options.skin.down !== "undefined")
            {
                skin.down = KEN.Utils.extendMultipleObjects(skin.out, skin.down, this.plugin.options.skin.down);
            }
        }

        // Set the global value if any
        if (this.plugin.options.value !== undefined && this.plugin.options.value !== null)
        {
            if(typeof skin.out.label !== "undefined")
            {
                skin.out.label.value = this.plugin.options.value;
            }
            if(typeof skin.over.label !== "undefined")
            {
                skin.over.label.value = this.plugin.options.value;
            }
            if(typeof skin.down.label !== "undefined")
            {
                skin.down.label.value = this.plugin.options.value;
            }
        }

        this._btn.updateSkin();

        this._btn.width = this.plugin.options.width;
        this._btn.height = this.plugin.options.height;

        // Add the button to the main container
        this.plugin.container.addChild(this._btn);

        // Add the events handlers
        this._btn.pointer.onClick.add(this._btnClickHandler, this);
        this._btn.pointer.onOut.add(this._btnOutHandler, this);
        this._btn.pointer.onOver.add(this._btnOverHandler, this);
        this._btn.pointer.onDown.add(this._btnDownHandler, this);
    },

    /**
     * Fires the handler for a click on the button.
     */
    _btnClickHandler: function(event)
    {
        this.plugin.events.onClick.dispatch();
    },

    /**
     * Fires the handler for going out the button.
     */
    _btnOutHandler: function(event)
    {
        this.plugin.events.onOut.dispatch();
    },

    /**
     * Fires the handler for being over the button.
     */
    _btnOverHandler: function(event)
    {
        this.plugin.events.onOver.dispatch();
    },

    /**
     * Fires the handler for the button currently being click on (click
     * maintained).
     */
    _btnDownHandler: function(event)
    {
        this.plugin.events.onDown.dispatch();
    },

    /**
     * Placeholder, do nothing
     */
    update: function() {},

    /**
     * Placeholder, do nothing
     */
    reset: function() {},

    /**
     * Show the button
     */
    show: function()
    {
        this._btn.show();
    },

    /**
     * Hide the button
     */
    hide: function()
    {
        this._btn.hide();
    },

    /**
     * Set a new text
     * @param {string} value
     */
    setText: function(value)
    {
        if (value !== undefined && value !== null)
        {
            var skin = this._btn.skin;

            if(typeof skin.out.label !== "undefined")
            {
                skin.out.label.value = value;
            }
            if(typeof skin.over.label !== "undefined")
            {
                skin.over.label.value = value;
            }
            if(typeof skin.down.label !== "undefined")
            {
                skin.down.label.value = value;
            }

            this._btn.updateSkin();
        }
    },

    /**
     * Destroy the button.
     */
    destroy: function()
    {
        this._btn.destroy();
        this._btn = null;
    }
};<|endoftext|>