<commit_before>const jsforce = require('jsforce');
const fs = require('fs');
const os = require('os');
const mkdirp = require('mkdirp');

// Here is the process:
// 1. Log into the org.
// 2. List the desired metadata as objects.
// 3. Query metadata fields for each returned object.
// 4. Return result to STDOUT
// 5. STDOUT is captured via a filestream.

/**
 * Gets Certificate metadata (and .crt files) from Salesforce with provided username and password.
 *
 * @param {string} username - String representing a Salesforce's username.
 * @param {string} password - String representing a Salesforce's password
 * @return {null} None
 */
function getSalesforceCertificates(username, password) {

  var conn = new jsforce.Connection();

  conn.login(username, password, function (err, res) {
    if (err) {
      console.log("Error raised for:", username)
      console.error('err', err);
    }

    console.log("Logging in...")

    var types = [{ type: 'Certificate', folder: null }];
    listMetaDataObjects(types, conn)
  });
}

function listMetaDataObjects(types, conn) {
  conn.metadata.list(types, '39.0', function (err, metadata) {
    if (err) {
      handleError(err, username)
    }
    if (metadata) {
      console.log("Found", metadata.length, "certificates:");
      var fullNames = []; // Create array of results.
      metadata.forEach(function (meta) {
        //console.log(meta);
        fullNames.push(meta.fullName)
      })
    }
    if (fullNames) {
      readMetaData(fullNames, conn);
    }
  });
}

function readMetaData(fullNames, conn) {
  if (fullNames) {
    conn.metadata.read('Certificate', fullNames, function (err, metadata) {
      if (err) {
        handleError(err, username)
      }
      //console.log("Getting metadata...")
      var logger = fs.createWriteStream('log.txt', {
        flags: 'a' // 'a' means appending (old data will be preserved)
      })
      for (var i = 0; i < metadata.length; i++) {
        var meta = metadata[i];
        console.log({ 'fullName': meta.fullName, 'caSigned': meta.caSigned, 'expirationDate': meta.expirationDate });
        writeCert(meta.fullName, meta.content)
        logger.write(`${username}, ${meta.fullName}, ${meta.caSigned}, ${meta.expirationDate}` + os.EOL)
      }
    });
  } else {
    console.log("A fullNames object was not passed in.")
  }
}

/**
 * Gets SamlSSOConfig metadata from Salesforce with provided username and password.
 *
 * @param {string} username - String representing a Salesforce's user instance.
 * @param {string} password - String representing a Salesforce's user instance's password.
 * @return {null} None
 */
function getSalesforceSSO(username, password) {

  // create new connection object for jsforce library
  var conn = new jsforce.Connection();

  conn.login(username, password, function (err, res) {
    if (err) {
      return handleError(err, username);
    }

    console.log(`Successfully logged in as ${username}.`)

    var types = [{ type: 'SamlSsoConfig', folder: null }];
    return getMetadataObjects(conn, types, username);
  });
}

/**
 * Gets all the objects from Salesforce which match the passed in 'types' object.
 *
 * @param {jsforce.Connection()} connection - Connection object from JSForce for Salesforce session. Should be pre-authenticated thru connection.login.
 * @param { type: 'TypeConfig', folder: null } types.type - The meta-data type to pull.
 * @return {null} None
 */
function getMetadataObjects(connection, types, username) {
  connection.metadata.list(types, '39.0', function (err, metadata) {
    if (err) {
      return handleError(err, username);
    }
    if (metadata) {
      // Collect identifying names from metadata objects to be parsed later.
      // fullName == identifying field name on a Metadata object.
      var fullNames = [];

      // Salesforce returns a single object if one result, or an array if more than one.
      var logString = function (count, username, metaDataObject) {
        return `Found ${count} SSOconfig(s) for ${username}: ${metaDataObject}`
      }

      if (metadata.constructor === Array) {
        metadata.forEach(function (meta) {
          // Grab the identifying field name aka "fullName"
          fullNames.push(meta.fullName)
        })
        console.log(logString(metadata.length, username, fullNames));
      } else {
        fullNames.push(metadata.fullName)
        console.log(logString("one", username, fullNames));
      }
    }
    if (fullNames) {
      readMetaDataFields(connection, 'SamlSsoConfig', fullNames, username);
    }
  });
}

/**
 * Writes a SSO config to json from SFDC SSO metadata.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function readMetaDataFields(connection, type, fullNames, username) {
  connection.metadata.read(type, fullNames, function (err, metadata) {
    console.log(username, fullNames)
    if (err) {
      return handleError(err, username);
    }
    //console.log("Getting metadata...")

    for (var i = 0; i < metadata.length; i++) {
      var meta = metadata[i];
      writeSSO(`${meta.fullName}_${username.split("@")[0]}`, meta)
    }
  });
}

/**
 * Handle errors raised from async functions
 *
 * @param {error~object} error - The error message object
 * @param {string} username - The username from the function context which was scoped during error raise.
 * @return {null} None
 */
function handleError(error, username) {
  console.log("Error raised for:", username)
  console.error('err', err);
}

/**
 * Writes a certificate to file from SFDC certificate metadata.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function writeCert(fileName, data) {
  data = decodeBase64(data);

  if (fs.existsSync('certs/') !== true) {
    handleFolder('certs/')
  }
  outputFile = `certs/${fileName}.crt`

  fs.writeFile(outputFile, data, function (err) {
    if (err) { console.log(err); }
  });
}

/**
 * Writes a SSO config to json from SFDC SSO metadata.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function writeSSO(fileName, data) {
  data = JSON.stringify(data) // Convert input to string.

  if (fs.existsSync('sso') !== true) {
    handleFolder('sso')
  }
  outputFile = `sso/${fileName}.json`

  fs.writeFile(outputFile, data, function (err) {
    if (err) { console.error(err); }
  });

}

/**
 * Creates a folder if it does not already exist in the file system.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function handleFolder(folderPath) {
  mkdirp(folderPath, function (err) {
    if (err) { console.error(err); }
  });
}

/**
 * Decodes Base64 text into its ASCII equivalent.
 *
 * @param {string} base64string - The string which should be converted to ASCII.
 * @return {string} The ASCII equivalent of base64string
 */
function decodeBase64(base64string) {
  var newString = new Buffer(base64string, 'base64').toString("ascii")
  return newString
}

module.exports = {
  getSalesforceCertificates: getSalesforceCertificates,
  getSalesforceSSO: getSalesforceSSO
}<commit_msg>Add handleError() where appropriate, seperate type from readMetadata() function.<commit_after>const jsforce = require('jsforce');
const fs = require('fs');
const os = require('os');
const mkdirp = require('mkdirp');

// Here is the process:
// 1. Log into the org.
// 2. List the desired metadata as objects.
// 3. Query metadata fields for each returned object.
// 4. Return result to STDOUT
// 5. STDOUT is captured via a filestream.

// TODO: Refactor READ and LIST metadata functions to be DRY.

/**
 * Gets Certificate metadata (and .crt files) from Salesforce with provided username and password.
 *
 * @param {string} username - String representing a Salesforce's username.
 * @param {string} password - String representing a Salesforce's password
 * @return {null} None
 */
function getSalesforceCertificates(username, password) {

  var conn = new jsforce.Connection();

  conn.login(username, password, function (err, res) {
    if (err) {
      handleError(err, username)
    }

    console.log("Logging in...")

    var types = [{ type: 'Certificate', folder: null }];
    var fields = ['fullName','caSigned', 'expirationDate']
    listMetaDataObjects(types, conn)
  });
}

function listMetaDataObjects(types, conn) {
  var type = types[0].type // Pull type property from input types array.
  conn.metadata.list(types, '39.0', function (err, metadata) {
    if (err) {
      handleError(err, username)
    }
    if (metadata) {
      console.log("Found", metadata.length, type, ":");
      var fullNames = []; // Create array of results.
      metadata.forEach(function (meta) {
        //console.log(meta);
        fullNames.push(meta.fullName)
      })
    } else {
      console.log("No metadata was returned from conn.metadata.list method().")
      return false;
    }
    if (fullNames) {
      readMetaData(fullNames, conn, type);
    }
  });
}

function readMetaData(fullNames, conn, type) {
  if (fullNames) {
    conn.metadata.read(type, fullNames, function (err, metadata) {
      if (err) {
        handleError(err, username)
      }
      //console.log("Getting metadata...")
      var logger = fs.createWriteStream('log.txt', {
        flags: 'a' // 'a' means appending (old data will be preserved)
      })
      for (var i = 0; i < metadata.length; i++) {
        var meta = metadata[i];
        console.log({ 'fullName': meta.fullName, 'caSigned': meta.caSigned, 'expirationDate': meta.expirationDate });
        writeCert(meta.fullName, meta.content)
        logger.write(`${username}, ${meta.fullName}, ${meta.caSigned}, ${meta.expirationDate}` + os.EOL)
      }
    });
  } else {
    console.log("A fullNames object was not passed in.")
  }
}

/**
 * Gets SamlSSOConfig metadata from Salesforce with provided username and password.
 *
 * @param {string} username - String representing a Salesforce's user instance.
 * @param {string} password - String representing a Salesforce's user instance's password.
 * @return {null} None
 */
function getSalesforceSSO(username, password) {

  // create new connection object for jsforce library
  var conn = new jsforce.Connection();

  conn.login(username, password, function (err, res) {
    if (err) {
      return handleError(err, username);
    }

    console.log(`Successfully logged in as ${username}.`)

    var types = [{ type: 'SamlSsoConfig', folder: null }];
    return getMetadataObjects(conn, types, username);
  });
}

/**
 * Gets all the objects from Salesforce which match the passed in 'types' object.
 *
 * @param {jsforce.Connection()} connection - Connection object from JSForce for Salesforce session. Should be pre-authenticated thru connection.login.
 * @param { type: 'TypeConfig', folder: null } types.type - The meta-data type to pull.
 * @return {null} None
 */
function getMetadataObjects(connection, types, username) {
  connection.metadata.list(types, '39.0', function (err, metadata) {
    if (err) {
      return handleError(err, username);
    }
    if (metadata) {
      // Collect identifying names from metadata objects to be parsed later.
      // fullName == identifying field name on a Metadata object.
      var fullNames = [];

      // Salesforce returns a single object if one result, or an array if more than one.
      var logString = function (count, username, metaDataObject) {
        return `Found ${count} SSOconfig(s) for ${username}: ${metaDataObject}`
      }

      if (metadata.constructor === Array) {
        metadata.forEach(function (meta) {
          // Grab the identifying field name aka "fullName"
          fullNames.push(meta.fullName)
        })
        console.log(logString(metadata.length, username, fullNames));
      } else {
        fullNames.push(metadata.fullName)
        console.log(logString("one", username, fullNames));
      }
    }
    if (fullNames) {
      readMetaDataFields(connection, 'SamlSsoConfig', fullNames, username);
    }
  });
}

/**
 * Writes a SSO config to json from SFDC SSO metadata.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function readMetaDataFields(connection, type, fullNames, username) {
  connection.metadata.read(type, fullNames, function (err, metadata) {
    console.log(username, fullNames)
    if (err) {
      return handleError(err, username);
    }
    //console.log("Getting metadata...")

    for (var i = 0; i < metadata.length; i++) {
      var meta = metadata[i];
      writeSSO(`${meta.fullName}_${username.split("@")[0]}`, meta)
    }
  });
}

/**
 * Handle errors raised from async functions
 *
 * @param {error~object} error - The error message object
 * @param {string} username - The username from the function context which was scoped during error raise.
 * @return {null} None
 */
function handleError(error, username) {
  console.log("Error raised for:", username)
  console.error('err', err);
}

/**
 * Writes a certificate to file from SFDC certificate metadata.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function writeCert(fileName, data) {
  data = decodeBase64(data);

  if (fs.existsSync('certs/') !== true) {
    handleFolder('certs/')
  }
  outputFile = `certs/${fileName}.crt`

  fs.writeFile(outputFile, data, function (err) {
    if (err) { console.log(err); }
  });
}

/**
 * Writes a SSO config to json from SFDC SSO metadata.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function writeSSO(fileName, data) {
  data = JSON.stringify(data) // Convert input to string.

  if (fs.existsSync('sso') !== true) {
    handleFolder('sso')
  }
  outputFile = `sso/${fileName}.json`

  fs.writeFile(outputFile, data, function (err) {
    if (err) { console.error(err); }
  });

}

/**
 * Creates a folder if it does not already exist in the file system.
 *
 * @param {string} fileName - The expected name of the output certificate. Is typically the metadata.fullName property.
 * @param {string} data - The content which should be written to file.
 * @return {null} None
 */
function handleFolder(folderPath) {
  mkdirp(folderPath, function (err) {
    if (err) { console.error(err); }
  });
}

/**
 * Decodes Base64 text into its ASCII equivalent.
 *
 * @param {string} base64string - The string which should be converted to ASCII.
 * @return {string} The ASCII equivalent of base64string
 */
function decodeBase64(base64string) {
  var newString = new Buffer(base64string, 'base64').toString("ascii")
  return newString
}

module.exports = {
  getSalesforceCertificates: getSalesforceCertificates,
  getSalesforceSSO: getSalesforceSSO
}<|endoftext|>


<commit_before>// Copyright 2002-2013, University of Colorado

/**
 * EXPERIMENTAL: USE AT YOUR OWN CAUTION
 *
 * A container that allows flexible layout generation based on layout methods that can be composed together.
 *
 * Experimental demo (for use in Scenery's playground):
 *   var n = new scenery.LayoutNode( scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignLeft ) );
 *   scene.addChild( n );
 *   n.addChild( new scenery.Text( 'Some Text' ) );
 *   n.addChild( new scenery.Text( 'Text pushed to the right' ), { padLeft: 10 } );
 *   n.addChild( new scenery.Text( 'Some padding on top and bottom' ), { padTop: 10, padBottom: 20 } );
 *   n.addChild( new scenery.Text( 'Just Regular Text' ) );
 *   n.addChild( new scenery.Text( 'Right-aligned' ), { layoutMethod: scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignRight ) } );
 *   n.addChild( new scenery.Text( 'Center-aligned' ), { layoutMethod: scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignHorizontalCenter ) } );
 *   n.addChild( new scenery.Text( 'Pad from right' ), { layoutMethod: scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignRight ), padRight: 10 } );
 *   n.children[2].text += ' and it updates!';
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

define( function( require ) {
  'use strict';

  var inherit = require( 'PHET_CORE/inherit' );
  var extend = require( 'PHET_CORE/extend' );
  var scenery = require( 'SCENERY/scenery' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Bounds2 = require( 'DOT/Bounds2' );

  scenery.LayoutNode = function LayoutNode( defaultMethod, options ) {
    var layoutNode = this;

    assert && assert( defaultMethod instanceof LayoutMethod, 'defaultMethod is required' );

    options = extend( {
      updateOnBounds: true,
      defaultMethod: defaultMethod
    }, options );

    this._activelyLayingOut = false;
    this._updateOnBounds = true;
    this._defaultMethod = null;
    this._elements = [];
    this._elementMap = {}; // maps node ID => element
    // this._invisibleBackground = new Rectangle( 0, 0, 0x1f, 0x1f, { visible: false } ); // takes up space that represents the bounds of all of the layout elements (with their padding)
    this._boundsListener = function() {
      if ( layoutNode._updateOnBounds ) {
        layoutNode.updateLayout();
      }
    };

    Node.call( this, options );

    // this.addChild( this._invisibleBackground );

    this.updateLayout();
  };
  var LayoutNode = scenery.LayoutNode;

  inherit( Node, LayoutNode, {
    get layoutProperties() { return new LayoutProperties( this._elements ); },

    get layoutBounds() {
      var result = Bounds2.NOTHING.copy();
      _.each( this._elements, function( element ) {
        result.includeBounds( element.layoutBounds );
      } );
      return result;
    },

    set defaultMethod( value ) { this._defaultMethod = value; this.updateLayout(); return this; },
    get defaultMethod() { return this._defaultMethod; },

    set updateOnBounds( value ) { this._updateOnBounds = value; return this; },
    get updateOnBounds() { return this._updateOnBounds; },

    /*
     * Options can consist of:
     *   layoutMethod - layout method
     *   useVisibleBounds - (false) whether to use visible bounds instead of normal bounds - TODO how to auto-update when using these?
     *   padLeft / padRight / padTop / padBottom
     *   boundsMethod - custom overriding of entire boundsMethod
     */
    insertChild: function( index, node, options ) {
      var layoutNode = this;

      options = extend( {
        useVisibleBounds: false,
        padLeft: 0,
        padRight: 0,
        padTop: 0,
        padBottom: 0
      }, options );

      Node.prototype.insertChild.call( this, index, node );

      var methodGetter = options.layoutMethod ? function() { return options.layoutMethod; } : function() { return layoutNode._defaultMethod; };
      var element = new LayoutElement( node, methodGetter, options.boundsMethod ? options.boundsMethod : function( bounds ) {
        if ( options.useVisibleBounds ) {
          bounds = node.visibleBounds;
        }

        return new Bounds2( bounds.minX - options.padLeft, bounds.minY - options.padTop, bounds.maxX + options.padRight, bounds.maxY + options.padBottom );
      } );
      this.addElement( element );

      this.updateLayout();
    },

    addChild: function( node, options ) {
      this.insertChild( this._children.length, node, options );
    },

    // override
    removeChildWithIndex: function( node, indexOfChild ) {
      Node.prototype.removeChildWithIndex.call( this, node, indexOfChild );
      if ( this._elementMap[node.id] ) {
        delete this._elementMap[node.id];
      }

      this.updateLayout();
    },

    addElement: function( element ) {
      this._elements.push( element );
      element.node.addEventListener( 'bounds', this._boundsListener );
    },

    removeElement: function( element ) {
      this._elements.splice( this._elements.indexOf( element ), 1 ); // TODO: replace with some remove() instead of splice()
      element.node.removeEventListener( 'bounds', this._boundsListener );
    },

    // overrides the Node's bounds computation in a strictly increasing way (for Canvas support)
    overrideBounds: function( computedBounds ) {
      return this.layoutBounds;
    },

    updateLayout: function() {
      if ( this._activelyLayingOut ) {
        // don't start another layout while one is going on!
        return;
      }
      this._activelyLayingOut = true;
      var layoutProperties = this.layoutProperties;
      for ( var i = 0; i < this._elements.length; i++ ) {
        var element = this._elements[i];
        element.layoutMethod.layout( element, i, ( i > 0 ? this._elements[i-1] : null ), layoutProperties );
      }

      // use the invisible background to take up all of our layout areas
      // this._invisibleBackground.removeAllChildren();
      // var bounds = this.layoutBounds;
      // if ( !bounds.isEmpty() ) {
      //   this._invisibleBackground.addChild( new Rectangle( bounds, { visible: false } ) );
      // }

      // if ( debug ) {
      //   this._invisibleBackground.visible = true;
      //   this._invisibleBackground.fill = 'rgba(255,0,0,0.4)';

      //   _.each( this._elements, function( element ) {
      //     this._invisibleBackground.addChild( new Rectangle( element.node.bounds ), {
      //       fill: 'rgba(255,0,0,0.4)',
      //       stroke: 'blue'
      //     } );
      //   } );
      // }
      this._activelyLayingOut = false;
    }
  } );

  /*
   * LayoutMethod - function layout( element, index, previousElement, layoutProperties )
   */
  var LayoutMethod = LayoutNode.LayoutMethod = function LayoutMethod( layout ) {
    if ( layout ) {
      this.layout = layout;
    }
  };
  LayoutMethod.prototype = {
    constructor: LayoutMethod,

    and: function( otherLayoutMethod ) {
      var thisLayoutMethod = this;

      return new LayoutMethod( function compositeLayout( element, index, previousElement, layoutProperties ) {
        thisLayoutMethod.layout( element, index, previousElement, layoutProperties );
        otherLayoutMethod.layout( element, index, previousElement, layoutProperties );
      } );
    }
  };

  /*---------------------------------------------------------------------------*
  * Layout Methods
  *----------------------------------------------------------------------------*/

//  var Vertical = LayoutNode.Vertical = new LayoutMethod( function verticalLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = previousElement ? previousElement.layoutBounds.bottom : 0;
//  } );
//
//  var Horizontal = LayoutNode.Horizontal = new LayoutMethod( function horizontalLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = previousElement ? previousElement.layoutBounds.right : 0;
//  } );
//
//  var AlignLeft = LayoutNode.AlignLeft = new LayoutMethod( function alignLeftLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = 0;
//  } );
//
//  var AlignHorizontalCenter = LayoutNode.AlignHorizontalCenter = new LayoutMethod( function alignHorizontalCenterLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = ( layoutProperties.maxWidth - element.layoutBounds.width ) / 2;
//  } );
//
//  var AlignRight = LayoutNode.AlignRight = new LayoutMethod( function alignRightLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = layoutProperties.maxWidth - element.layoutBounds.width;
//  } );
//
//  var AlignTop = LayoutNode.AlignTop = new LayoutMethod( function alignTopLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = 0;
//  } );
//
//  var AlignVerticalCenter = LayoutNode.AlignVerticalCenter = new LayoutMethod( function alignVerticalCenterLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = ( layoutProperties.maxHeight - element.layoutBounds.height ) / 2;
//  } );
//
//  var AlignBottom = LayoutNode.AlignBottom = new LayoutMethod( function alignBottomLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = layoutProperties.maxHeight - element.layoutBounds.height;
//  } );

  /*---------------------------------------------------------------------------*
  * Internals
  *----------------------------------------------------------------------------*/

  var LayoutProperties = LayoutNode.LayoutProperties = function LayoutProperties( elements ) {
    var largestWidth = 0;
    var largestHeight = 0;

    _.each( elements, function( element ) {
      largestWidth = Math.max( largestWidth, element.layoutBounds.width );
      largestHeight = Math.max( largestHeight, element.layoutBounds.height );
    } );

    this.maxWidth = largestWidth;
    this.maxHeight = largestHeight;
  };

  var LayoutElement = LayoutNode.LayoutElement = function LayoutElement( node, layoutMethodGetter, boundsMethod ) {
    this.node = node;
    this.layoutMethodGetter = layoutMethodGetter;
    this.boundsMethod = boundsMethod;
  };
  LayoutElement.prototype = {
    get bounds() { return this.node.bounds; },
    get layoutBounds() { return this.boundsMethod( this.bounds ); },
    get layoutMethod() { return this.layoutMethodGetter(); },

    get layoutTop() { throw new Error( 'JSHint wants this getter' ); },
    set layoutTop( y ) {
      var padding = this.bounds.top - this.layoutBounds.top;
      this.node.top = y + padding;
    },

    get layoutLeft() { throw new Error( 'JSHint wants this getter' ); },
    set layoutLeft( x ) {
      var padding = this.bounds.left - this.layoutBounds.left;
      this.node.left = x + padding;
    }
  };

  LayoutNode.prototype._mutatorKeys = [ 'defaultMethod', 'updateOnBounds' ].concat( Node.prototype._mutatorKeys );

  return LayoutNode;
} );

<commit_msg>add a comment about why I commented out unused functions<commit_after>// Copyright 2002-2013, University of Colorado

/**
 * EXPERIMENTAL: USE AT YOUR OWN CAUTION
 *
 * A container that allows flexible layout generation based on layout methods that can be composed together.
 *
 * Experimental demo (for use in Scenery's playground):
 *   var n = new scenery.LayoutNode( scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignLeft ) );
 *   scene.addChild( n );
 *   n.addChild( new scenery.Text( 'Some Text' ) );
 *   n.addChild( new scenery.Text( 'Text pushed to the right' ), { padLeft: 10 } );
 *   n.addChild( new scenery.Text( 'Some padding on top and bottom' ), { padTop: 10, padBottom: 20 } );
 *   n.addChild( new scenery.Text( 'Just Regular Text' ) );
 *   n.addChild( new scenery.Text( 'Right-aligned' ), { layoutMethod: scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignRight ) } );
 *   n.addChild( new scenery.Text( 'Center-aligned' ), { layoutMethod: scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignHorizontalCenter ) } );
 *   n.addChild( new scenery.Text( 'Pad from right' ), { layoutMethod: scenery.LayoutNode.Vertical.and( scenery.LayoutNode.AlignRight ), padRight: 10 } );
 *   n.children[2].text += ' and it updates!';
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

define( function( require ) {
  'use strict';

  var inherit = require( 'PHET_CORE/inherit' );
  var extend = require( 'PHET_CORE/extend' );
  var scenery = require( 'SCENERY/scenery' );
  var Node = require( 'SCENERY/nodes/Node' );
  var Bounds2 = require( 'DOT/Bounds2' );

  scenery.LayoutNode = function LayoutNode( defaultMethod, options ) {
    var layoutNode = this;

    assert && assert( defaultMethod instanceof LayoutMethod, 'defaultMethod is required' );

    options = extend( {
      updateOnBounds: true,
      defaultMethod: defaultMethod
    }, options );

    this._activelyLayingOut = false;
    this._updateOnBounds = true;
    this._defaultMethod = null;
    this._elements = [];
    this._elementMap = {}; // maps node ID => element
    // this._invisibleBackground = new Rectangle( 0, 0, 0x1f, 0x1f, { visible: false } ); // takes up space that represents the bounds of all of the layout elements (with their padding)
    this._boundsListener = function() {
      if ( layoutNode._updateOnBounds ) {
        layoutNode.updateLayout();
      }
    };

    Node.call( this, options );

    // this.addChild( this._invisibleBackground );

    this.updateLayout();
  };
  var LayoutNode = scenery.LayoutNode;

  inherit( Node, LayoutNode, {
    get layoutProperties() { return new LayoutProperties( this._elements ); },

    get layoutBounds() {
      var result = Bounds2.NOTHING.copy();
      _.each( this._elements, function( element ) {
        result.includeBounds( element.layoutBounds );
      } );
      return result;
    },

    set defaultMethod( value ) { this._defaultMethod = value; this.updateLayout(); return this; },
    get defaultMethod() { return this._defaultMethod; },

    set updateOnBounds( value ) { this._updateOnBounds = value; return this; },
    get updateOnBounds() { return this._updateOnBounds; },

    /*
     * Options can consist of:
     *   layoutMethod - layout method
     *   useVisibleBounds - (false) whether to use visible bounds instead of normal bounds - TODO how to auto-update when using these?
     *   padLeft / padRight / padTop / padBottom
     *   boundsMethod - custom overriding of entire boundsMethod
     */
    insertChild: function( index, node, options ) {
      var layoutNode = this;

      options = extend( {
        useVisibleBounds: false,
        padLeft: 0,
        padRight: 0,
        padTop: 0,
        padBottom: 0
      }, options );

      Node.prototype.insertChild.call( this, index, node );

      var methodGetter = options.layoutMethod ? function() { return options.layoutMethod; } : function() { return layoutNode._defaultMethod; };
      var element = new LayoutElement( node, methodGetter, options.boundsMethod ? options.boundsMethod : function( bounds ) {
        if ( options.useVisibleBounds ) {
          bounds = node.visibleBounds;
        }

        return new Bounds2( bounds.minX - options.padLeft, bounds.minY - options.padTop, bounds.maxX + options.padRight, bounds.maxY + options.padBottom );
      } );
      this.addElement( element );

      this.updateLayout();
    },

    addChild: function( node, options ) {
      this.insertChild( this._children.length, node, options );
    },

    // override
    removeChildWithIndex: function( node, indexOfChild ) {
      Node.prototype.removeChildWithIndex.call( this, node, indexOfChild );
      if ( this._elementMap[node.id] ) {
        delete this._elementMap[node.id];
      }

      this.updateLayout();
    },

    addElement: function( element ) {
      this._elements.push( element );
      element.node.addEventListener( 'bounds', this._boundsListener );
    },

    removeElement: function( element ) {
      this._elements.splice( this._elements.indexOf( element ), 1 ); // TODO: replace with some remove() instead of splice()
      element.node.removeEventListener( 'bounds', this._boundsListener );
    },

    // overrides the Node's bounds computation in a strictly increasing way (for Canvas support)
    overrideBounds: function( computedBounds ) {
      return this.layoutBounds;
    },

    updateLayout: function() {
      if ( this._activelyLayingOut ) {
        // don't start another layout while one is going on!
        return;
      }
      this._activelyLayingOut = true;
      var layoutProperties = this.layoutProperties;
      for ( var i = 0; i < this._elements.length; i++ ) {
        var element = this._elements[i];
        element.layoutMethod.layout( element, i, ( i > 0 ? this._elements[i-1] : null ), layoutProperties );
      }

      // use the invisible background to take up all of our layout areas
      // this._invisibleBackground.removeAllChildren();
      // var bounds = this.layoutBounds;
      // if ( !bounds.isEmpty() ) {
      //   this._invisibleBackground.addChild( new Rectangle( bounds, { visible: false } ) );
      // }

      // if ( debug ) {
      //   this._invisibleBackground.visible = true;
      //   this._invisibleBackground.fill = 'rgba(255,0,0,0.4)';

      //   _.each( this._elements, function( element ) {
      //     this._invisibleBackground.addChild( new Rectangle( element.node.bounds ), {
      //       fill: 'rgba(255,0,0,0.4)',
      //       stroke: 'blue'
      //     } );
      //   } );
      // }
      this._activelyLayingOut = false;
    }
  } );

  /*
   * LayoutMethod - function layout( element, index, previousElement, layoutProperties )
   */
  var LayoutMethod = LayoutNode.LayoutMethod = function LayoutMethod( layout ) {
    if ( layout ) {
      this.layout = layout;
    }
  };
  LayoutMethod.prototype = {
    constructor: LayoutMethod,

    and: function( otherLayoutMethod ) {
      var thisLayoutMethod = this;

      return new LayoutMethod( function compositeLayout( element, index, previousElement, layoutProperties ) {
        thisLayoutMethod.layout( element, index, previousElement, layoutProperties );
        otherLayoutMethod.layout( element, index, previousElement, layoutProperties );
      } );
    }
  };

  /*---------------------------------------------------------------------------*
  * Layout Methods
  *----------------------------------------------------------------------------*/

  //TODO Commented out because jhint identifies them as unused variables. Delete these functions if that are not going to be used.
//  var Vertical = LayoutNode.Vertical = new LayoutMethod( function verticalLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = previousElement ? previousElement.layoutBounds.bottom : 0;
//  } );
//
//  var Horizontal = LayoutNode.Horizontal = new LayoutMethod( function horizontalLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = previousElement ? previousElement.layoutBounds.right : 0;
//  } );
//
//  var AlignLeft = LayoutNode.AlignLeft = new LayoutMethod( function alignLeftLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = 0;
//  } );
//
//  var AlignHorizontalCenter = LayoutNode.AlignHorizontalCenter = new LayoutMethod( function alignHorizontalCenterLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = ( layoutProperties.maxWidth - element.layoutBounds.width ) / 2;
//  } );
//
//  var AlignRight = LayoutNode.AlignRight = new LayoutMethod( function alignRightLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutLeft = layoutProperties.maxWidth - element.layoutBounds.width;
//  } );
//
//  var AlignTop = LayoutNode.AlignTop = new LayoutMethod( function alignTopLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = 0;
//  } );
//
//  var AlignVerticalCenter = LayoutNode.AlignVerticalCenter = new LayoutMethod( function alignVerticalCenterLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = ( layoutProperties.maxHeight - element.layoutBounds.height ) / 2;
//  } );
//
//  var AlignBottom = LayoutNode.AlignBottom = new LayoutMethod( function alignBottomLayout( element, index, previousElement, layoutProperties ) {
//    element.layoutTop = layoutProperties.maxHeight - element.layoutBounds.height;
//  } );

  /*---------------------------------------------------------------------------*
  * Internals
  *----------------------------------------------------------------------------*/

  var LayoutProperties = LayoutNode.LayoutProperties = function LayoutProperties( elements ) {
    var largestWidth = 0;
    var largestHeight = 0;

    _.each( elements, function( element ) {
      largestWidth = Math.max( largestWidth, element.layoutBounds.width );
      largestHeight = Math.max( largestHeight, element.layoutBounds.height );
    } );

    this.maxWidth = largestWidth;
    this.maxHeight = largestHeight;
  };

  var LayoutElement = LayoutNode.LayoutElement = function LayoutElement( node, layoutMethodGetter, boundsMethod ) {
    this.node = node;
    this.layoutMethodGetter = layoutMethodGetter;
    this.boundsMethod = boundsMethod;
  };
  LayoutElement.prototype = {
    get bounds() { return this.node.bounds; },
    get layoutBounds() { return this.boundsMethod( this.bounds ); },
    get layoutMethod() { return this.layoutMethodGetter(); },

    get layoutTop() { throw new Error( 'JSHint wants this getter' ); },
    set layoutTop( y ) {
      var padding = this.bounds.top - this.layoutBounds.top;
      this.node.top = y + padding;
    },

    get layoutLeft() { throw new Error( 'JSHint wants this getter' ); },
    set layoutLeft( x ) {
      var padding = this.bounds.left - this.layoutBounds.left;
      this.node.left = x + padding;
    }
  };

  LayoutNode.prototype._mutatorKeys = [ 'defaultMethod', 'updateOnBounds' ].concat( Node.prototype._mutatorKeys );

  return LayoutNode;
} );

<|endoftext|>


<commit_before>/**
 * Used for JQuery Autocomplete dropdown input boxes
 */

/**
 * Helper function to call DWR search methods and put results into an autocomplete list
 *
 * Example use:
 *
 * new AutoComplete("person_name", new CreateCallback().personCallback(), {
 *			select: function(event, ui) {
 *				$j('#person_name_id').val(ui.item.object.personId);
 *			}
 *		});
 *
 * General options:
 * onerror: a function to deal with errors

 * onsuccess: a function that gets called with the results if there are some and no error occurred
 * maxresults: limit the results to this. -1 means show all (defaults to 50)
 *
 * See each *callback method below for more options that can be used
 *
 */
function CreateCallback(options) {
	if (options == null)
		options = {};

	var maxresults = options.maxresults;
	if (maxresults == null)
		maxresults = 50;

	// this will be the unique incrementing number assigned to the most recent query
	this.searchCounter = 0;

	/**
	 * Use this method if searching for general person objects
	 *
	 * additional options:
	 * roles: a comma separated list of role names to restrict to
	 */
	this.personCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		DWRPersonService.findPeopleByRoles(q, false, options.roles, thisObject.makeRows(q, response, thisObject.searchCounter + 1, thisObject.displayPerson));
	}}

	/**
	 * Use this method if searching for patients
	 */
	this.patientCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		DWRPatientService.findPatients(q, false, thisObject.makeRows(q, response, thisObject.searchCounter + 1, thisObject.displayPerson));
	}}

	/**
	 * Use this method if searching for users
	 *
	 * additional options:
	 * roles: a comma separated list of role names to restrict to
	 */
	this.userCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		var rolesArray = [];
		if (options.roles.length > 0)
			rolesArray = options.roles.split(",");

		DWRUserService.findUsers(q, rolesArray, false, thisObject.makeRows(q, response, thisObject.searchCounter + 1, thisObject.displayPerson));
	}}

	/**
	 * Additional options:
	 * includeClasses: an array of class names to restrict to
	 * excludeClasses: an array of class names to leave out of the results
	 * includeDatatypes: an array of datatype names to restrict to
	 * excludeDatatypes: an array of datatype names to leave out of the results
	 */
	this.conceptCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		// changes a single element into an array
		var includeClasses = $j.makeArray(options.includeClasses);
		var excludeClasses = $j.makeArray(options.excludeClasses);
		var includeDatatypes = $j.makeArray(options.includeDatatypes);
		var excludeDatatypes = $j.makeArray(options.excludeDatatypes);
		/*$j("#log").html($j("#log").html() + "
" + thisObject.test + "--" + thisObject.testing);*/
		DWRConceptService.findConcepts(q, false, includeClasses, excludeClasses, includeDatatypes, excludeDatatypes, false, thisObject.makeRows(q, response, thisObject.searchCounter + 1, thisObject.displayNamedObject));
	}}

	/**
	 * Additional options:
	 * showAnswersFor: a concept id. if non-null the search space is restricted to the answers to the given concept id
	 */
	this.conceptAnswersCallback = function() { var thisObject = this; return function(q, response) {
		// do NOT return false if no text given, instead should return all answers
		DWRConceptService.findConceptAnswers(q, options.showAnswersFor, false, false, thisObject.makeRows(q, response, thisObject.searchCounter + 1, thisObject.displayNamedObject));
	}}

	/**
	 * Additional options:
	 * showAnswersFor: a concept id. if non-null the search space is restricted to the answers to the given concept id
	 */
	this.encounterCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		// do NOT return false if no text given, instead should return all answers
		DWREncounterService.findEncounters(q, false, thisObject.makeRows(q, response, thisObject.searchCounter + 1, thisObject.displayEncounter));
	}}

	/*
	 * a 'private' method
	 * the method that dwr calls back with results
	 */
	this.makeRows = function(q, response, searchId, displayFunction) { var thisObject = this; return function(objs) {
		if (searchId <= thisObject.searchCounter) {
			//alert("got a slow query with: '" + q + "' main counter at: " + thisObject.searchCounter);
			return;
		}
		else {
			//alert("not a slow query, " + q + " searchId: " + searchId + " main counter: " + thisObject.searchCounter);
			thisObject.searchCounter = searchId;
		}

		//convert objs from single obj into array (if needed)
		objs = $j.makeArray(objs);

		//check if we have an error
		if(options.onerror) {
			if(objs.length >= 1) {
				if(typeof objs[0] == 'string') {
					// we have an error, tell the user
					options.onerror(objs[0]);
					// clear other results
					response(false);

					return;
				}
			}
		}

		// let the caller know about a success (if they sent us a function to call)
		if (options.onsuccess)
			options.onsuccess(objs);

		if (maxresults > 0 && maxresults < objs.length) {
			var objectsSliced = objs.length - maxresults;
			objs = objs.slice(0, maxresults);
			objs.push("(" + objectsSliced + " " + omsgs.resultsNotDisplayed +")");
		}

		response($j.map(objs, displayFunction(q)));
	}; }

	// a 'private' method
	// This is what maps each PersonListItem returned object to a name in the dropdown
	this.displayPerson = function(origQuery) { return function(person) {
		// dwr methods sometimes put strings into the results, just display those
		if (typeof person == 'string')
			return { label: person, value: "" };

		// item is a PersonListItem object
		var imageText = "";
		if (person.gender == 'M')
			imageText = "♂"; //";
		else if (person.gender == "F")
			imageText = "♀"; //""
		//else
		//	imageText = "?";

		// adding space here for both the regexp matching and the gap
		// between the image and the identifier
		var textShown = " ";

		if (person.identifier)
			textShown += person.identifier;

		textShown += " ";

		textShown += person.personName;

		// highlight each search term in the results
		textShown = highlightWords(textShown, origQuery);

		var ageText = "";
		if (person.age) {
			ageText = " (" + person.age + " " + omsgs.yearsOld + ")";
		}

		// append the gender image and age AFTER word highlighting so regex doesn't match it

		textShown = imageText + textShown + ageText; // space was inserted into beginning of 'textShown' var

		// wrap each result in a span tag (needed?)
		textShown = "" + textShown + "";

		return { label: textShown, value: person.personName, id: person.personId, object: person };
	}; }

	// a 'private' method
	// This is what maps each ConceptListItem or LocationListItem returned object to a name in the dropdown
	this.displayNamedObject = function(origQuery) { return function(item) {
		// dwr sometimes puts strings into the results, just display those
		if (typeof item == 'string')
			return { label: item, value: "" };

		// item is a ConceptListItem or LocationListItem object
		// add a space so the term highlighter below thinks the first word is a word
		var textShown = " " + item.name;

		// highlight each search term in the results
		textShown = highlightWords(textShown, origQuery);

		var value = item.name;
		if (item.preferredName) {
			textShown += " ⇒ " + item.preferredName + "";
			value = item.preferredName;
		}

		textShown = "" + textShown + "";

		return { label: textShown, value: value, object: item};
	}; };

	// a 'private' method
	// This is what maps each EncounterListItem returned object to a name in the dropdown
	this.displayEncounter = function(origQuery) { return function(enc) {
		// dwr sometimes puts strings into the results, just display those
		if (typeof enc == 'string')
			return { label: enc, value: "" };

		// enc is an EncounterListenc
		// add a space so the term highlighter below thinks the first word is a word
		var textShown = " " + enc.encounterDateString;
		textShown += " " + enc.encounterType;
		textShown += " - " + enc.personName;
		textShown += " - " + enc.providerName;
		textShown += " - " + enc.location;

		// highlight each search term in the results
		textShown = highlightWords(textShown, origQuery);

		textShown = "" + textShown + "";

		value = enc.location + " - " + enc.encounterDateString;

		return { label: textShown, value: value, object: enc};
	}; };

	/*
	 * Private method, used when display persons or concepts to show
	 * which part of the word was a match.
	 *
	 * Each separate word in "origQuery" will be highlighted with a 'hit' class in
	 * the "textShown" string.
	 */
	function highlightWords(textShown, origQuery) {
		var words = origQuery.split(" ");
		for (var x=0; x<words.length; x++) {
			if ($j.trim(words[x]).length > 0) {
				var word = " " + words[x]; // only match the beginning of words
				// replace each occurrence case insensitively while replacing with original case
				textShown = textShown.replace(word, function(matchedTxt) { return "" + matchedTxt + ""}, "gi");
			}
		}
		return textShown;
	}
}<commit_msg>Fixing results not showing up in autocomplete dropdowns - TRUNK-1967 Fixed css code showing up in search results if user searched and hit of "cla"<commit_after>/**
 * Used for JQuery Autocomplete dropdown input boxes
 */

/**
 * Helper function to call DWR search methods and put results into an autocomplete list
 *
 * Example use:
 *
 * new AutoComplete("person_name", new CreateCallback().personCallback(), {
 *			select: function(event, ui) {
 *				$j('#person_name_id').val(ui.item.object.personId);
 *			}
 *		});
 *
 * General options:
 * onerror: a function to deal with errors

 * onsuccess: a function that gets called with the results if there are some and no error occurred
 * maxresults: limit the results to this. -1 means show all (defaults to 50)
 *
 * See each *callback method below for more options that can be used
 *
 */
function CreateCallback(options) {
	if (options == null)
		options = {};

	var maxresults = options.maxresults;
	if (maxresults == null)
		maxresults = 50;

	// this will be the unique incrementing number assigned to the most recent query
	this.searchCounter = 0;

	/**
	 * Use this method if searching for general person objects
	 *
	 * additional options:
	 * roles: a comma separated list of role names to restrict to
	 */
	this.personCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		thisObject.searchCounter += 1;
		DWRPersonService.findPeopleByRoles(q, false, options.roles, thisObject.makeRows(q, response, thisObject.searchCounter, thisObject.displayPerson));
	}}

	/**
	 * Use this method if searching for patients
	 */
	this.patientCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		thisObject.searchCounter += 1;
		DWRPatientService.findPatients(q, false, thisObject.makeRows(q, response, thisObject.searchCounter, thisObject.displayPerson));
	}}

	/**
	 * Use this method if searching for users
	 *
	 * additional options:
	 * roles: a comma separated list of role names to restrict to
	 */
	this.userCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		var rolesArray = [];
		if (options.roles.length > 0)
			rolesArray = options.roles.split(",");

		thisObject.searchCounter += 1;
		DWRUserService.findUsers(q, rolesArray, false, thisObject.makeRows(q, response, thisObject.searchCounter, thisObject.displayPerson));
	}}

	/**
	 * Additional options:
	 * includeClasses: an array of class names to restrict to
	 * excludeClasses: an array of class names to leave out of the results
	 * includeDatatypes: an array of datatype names to restrict to
	 * excludeDatatypes: an array of datatype names to leave out of the results
	 */
	this.conceptCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		// changes a single element into an array
		var includeClasses = $j.makeArray(options.includeClasses);
		var excludeClasses = $j.makeArray(options.excludeClasses);
		var includeDatatypes = $j.makeArray(options.includeDatatypes);
		var excludeDatatypes = $j.makeArray(options.excludeDatatypes);
		/*$j("#log").html($j("#log").html() + "
" + thisObject.test + "--" + thisObject.testing);*/

		thisObject.searchCounter += 1;
		DWRConceptService.findConcepts(q, false, includeClasses, excludeClasses, includeDatatypes, excludeDatatypes, false, thisObject.makeRows(q, response, thisObject.searchCounter, thisObject.displayNamedObject));
	}}

	/**
	 * Additional options:
	 * showAnswersFor: a concept id. if non-null the search space is restricted to the answers to the given concept id
	 */
	this.conceptAnswersCallback = function() { var thisObject = this; return function(q, response) {
		// do NOT return false if no text given, instead should return all answers
		thisObject.searchCounter += 1;
		DWRConceptService.findConceptAnswers(q, options.showAnswersFor, false, false, thisObject.makeRows(q, response, thisObject.searchCounter, thisObject.displayNamedObject));
	}}

	/**
	 * Additional options:
	 * showAnswersFor: a concept id. if non-null the search space is restricted to the answers to the given concept id
	 */
	this.encounterCallback = function() { var thisObject = this; return function(q, response) {
		if ($j.trim(q).length == 0)
			return response(false);

		// do NOT return false if no text given, instead should return all answers
		thisObject.searchCounter += 1;
		DWREncounterService.findEncounters(q, false, thisObject.makeRows(q, response, thisObject.searchCounter, thisObject.displayEncounter));
	}}

	/*
	 * a 'private' method
	 * the method that dwr calls back with results
	 */
	this.makeRows = function(q, response, searchId, displayFunction) { var thisObject = this; return function(objs) {
		if (searchId < thisObject.searchCounter) {
			//alert("got a slow query with: '" + q + "' main counter at: " + thisObject.searchCounter);
			return;
		}
		else {
			//alert("not a slow query, " + q + " searchId: " + searchId + " main counter: " + thisObject.searchCounter);
			thisObject.searchCounter = searchId;
		}

		//convert objs from single obj into array (if needed)
		objs = $j.makeArray(objs);

		//check if we have an error
		if(options.onerror) {
			if(objs.length >= 1) {
				if(typeof objs[0] == 'string') {
					// we have an error, tell the user
					options.onerror(objs[0]);
					// clear other results
					response(false);

					return;
				}
			}
		}

		// let the caller know about a success (if they sent us a function to call)
		if (options.onsuccess)
			options.onsuccess(objs);

		if (maxresults > 0 && maxresults < objs.length) {
			var objectsSliced = objs.length - maxresults;
			objs = objs.slice(0, maxresults);
			objs.push("(" + objectsSliced + " " + omsgs.resultsNotDisplayed +")");
		}

		response($j.map(objs, displayFunction(q)));
	}; }

	// a 'private' method
	// This is what maps each PersonListItem returned object to a name in the dropdown
	this.displayPerson = function(origQuery) { return function(person) {
		// dwr methods sometimes put strings into the results, just display those
		if (typeof person == 'string')
			return { label: person, value: "" };

		// item is a PersonListItem object
		var imageText = "";
		if (person.gender == 'M')
			imageText = "♂"; //";
		else if (person.gender == "F")
			imageText = "♀"; //""
		//else
		//	imageText = "?";

		// adding space here for both the regexp matching and the gap
		// between the image and the identifier
		var textShown = " ";

		if (person.identifier)
			textShown += person.identifier;

		textShown += " ";

		textShown += person.personName;

		// highlight each search term in the results
		textShown = highlightWords(textShown, origQuery);

		var ageText = "";
		if (person.age) {
			ageText = " (" + person.age + " " + omsgs.yearsOld + ")";
		}

		// append the gender image and age AFTER word highlighting so regex doesn't match it

		textShown = imageText + textShown + ageText; // space was inserted into beginning of 'textShown' var

		// wrap each result in a span tag (needed?)
		textShown = "" + textShown + "";

		return { label: textShown, value: person.personName, id: person.personId, object: person };
	}; }

	// a 'private' method
	// This is what maps each ConceptListItem or LocationListItem returned object to a name in the dropdown
	this.displayNamedObject = function(origQuery) { return function(item) {
		// dwr sometimes puts strings into the results, just display those
		if (typeof item == 'string')
			return { label: item, value: "" };

		// item is a ConceptListItem or LocationListItem object
		// add a space so the term highlighter below thinks the first word is a word
		var textShown = " " + item.name;

		// highlight each search term in the results
		textShown = highlightWords(textShown, origQuery);

		var value = item.name;
		if (item.preferredName) {
			textShown += " ⇒ " + item.preferredName + "";
			value = item.preferredName;
		}

		textShown = "" + textShown + "";

		return { label: textShown, value: value, object: item};
	}; };

	// a 'private' method
	// This is what maps each EncounterListItem returned object to a name in the dropdown
	this.displayEncounter = function(origQuery) { return function(enc) {
		// dwr sometimes puts strings into the results, just display those
		if (typeof enc == 'string')
			return { label: enc, value: "" };

		// enc is an EncounterListenc
		// add a space so the term highlighter below thinks the first word is a word
		var textShown = " " + enc.encounterDateString;
		textShown += " " + enc.encounterType;
		textShown += " - " + enc.personName;
		textShown += " - " + enc.providerName;
		textShown += " - " + enc.location;

		// highlight each search term in the results
		textShown = highlightWords(textShown, origQuery);

		textShown = "" + textShown + "";

		value = enc.location + " - " + enc.encounterDateString;

		return { label: textShown, value: value, object: enc};
	}; };

	/*
	 * Private method, used when display persons or concepts to show
	 * which part of the word was a match.
	 *
	 * Each separate word in "origQuery" will be highlighted with a 'hit' class in
	 * the "textShown" string.
	 */
	function highlightWords(textShown, origQuery) {
		var words = origQuery.split(" ");
		for (var x=0; x<words.length; x++) {
			if ($j.trim(words[x]).length > 0) {
				var word = " " + words[x]; // only match the beginning of words
				// replace each occurrence case insensitively while replacing with original case
				textShown = textShown.replace(word, function(matchedTxt) { return "{{{{" + matchedTxt + "}}}}"}, "gi");
			}
		}

		textShown = textShown.replace(/{{{{/g, "");
		textShown = textShown.replace(/}}}}/g, "");

		return textShown;
	}
}<|endoftext|>


<commit_before>/**
 *  test_s3.js
 *
 *  David Janes
 *  IOTDB
 *  2017-01-18
 *
 *  Copyright (2013-2017) David Janes
 */

"use strict";

const _ = require("iotdb-helpers");

const assert = require("assert");

const AWS = require("aws-sdk");
const minimist = require('minimist');

const aws = require("../index");
const config = require("./aws.json")
const awsd = config.awsd

const ad = minimist(process.argv.slice(2));

const action = (name) => ad._.indexOf(name) > -1;

// create bucket
if (action("create-bucket")) {
    _.promise.make({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.create_bucket)
        .then(_self => console.log("+", "ok", _self.bucket_url)) // .result))
        .catch(error => console.log("#", _.error.message(error)))
}

if (action("bucket-exists")) {
    _.promise.make({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
    })
        .log("E.1")
        .then(aws.initialize)
        .log("E.2")
        .then(aws.s3.initialize)
        .log("E.3")
        .then(aws.s3.bucket_exists)
        .log("E.4")
        .then(_self => console.log("+", "ok", _self.exists))
        .catch(error => console.log("#", _.error.message(error)))
}

// list buckets
if (action("list-buckets")) {
    _.promise.make({
        awsd: awsd,
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.list_buckets)
        .then(_self => console.log("+", "ok", _self.buckets))
        .catch(error => console.log("#", _.error.message(error)))
}

// upload JSON
if (action("upload-json")) {
    _.promise.make({
        awsd: awsd,

        bucket: ad.bucket || "consensas-test1",
        key: ad.key || "name.json",
        json: {
            "hello": "world",
        },
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.upload_json)
        .then(_self => console.log("+", "ok", _self.aws_result))
        .catch(error => console.log("#", _.error.message(error)))
}

// upload document
if (action("upload-document")) {
    _.promise.make({
        awsd: awsd,

        bucket: ad.bucket || "consensas-test1",
        key: "test.txt",
        document: "The quick brown fox jumped over the lazy dog",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.upload_document)
        .then(_self => console.log("+", "ok", _self.aws_result))
        .catch(error => console.log("#", _.error.message(error)))
}

// delete object
if (action("delete-object")) {
    _.promise.make({
        awsd: awsd,

        bucket: ad.bucket || "consensas-test1",
        key: "test.txt",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.delete_object)
        .then(_self => console.log("+", "ok", _self.aws_result))
        .catch(error => console.log("#", _.error.message(error)))
}

// list files
if (action("list-objects")) {
    _.promise.make({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: "eLyccgRz",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.list_objects)
        .then(_self => console.log("+", "ok", _self.paths))
        .catch(error => console.log("#", _.error.message(error)))
}

// list files
if (action("list-objects-recursive")) {
    _.promise.make({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: "eLyccgRz",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.list_objects.recursive)
        .then(_self => console.log("+", "ok", _self.paths))
        .catch(error => console.log("#", _.error.message(error)))
}

// head files
if (action("head-object")) {
    _.promise.make({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: ad.key || "name.jsonx",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.head_object)
        .then(_self => console.log("+", "ok", _self.files))
        .catch(error => console.log("#", _.error.message(error)))
}

// object exists
if (action("object-exists")) {
    _.promise.make({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: ad.key || "name.json",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.object_exists)
        .then(_self => console.log("+", "ok", _self.exists))
        .catch(error => console.log("#", _.error.message(error)))
}

// object exists using path
if (action("object-exists-with-path")) {
    _.promise.make({
        awsd: awsd,
        path: "s3://consensas-test1/name.json",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.parse_path)
        .then(aws.s3.exists)
        .then(_self => console.log("+", "ok", _self.exists))
        .catch(error => console.log("#", _.error.message(error)))
}

<commit_msg>modernize S3<commit_after>/**
 *  test_s3.js
 *
 *  David Janes
 *  IOTDB
 *  2017-01-18
 *
 *  Copyright (2013-2017) David Janes
 */

"use strict"

const _ = require("iotdb-helpers")

const assert = require("assert")

const AWS = require("aws-sdk")
const minimist = require('minimist')

const aws = require("../index")
const config = require("./aws.json")
const awsd = config.awsd

const ad = minimist(process.argv.slice(2))
const action_name = ad._[0]

const actions = []
const action = name => {
    actions.push(name)

    return action_name === name
}

if (action("create-bucket")) {
    _.promise({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.create_bucket)
        .make(sd => console.log("+", "ok", sd.bucket_url)) // .result))
        .catch(_.error.log)
} else if (action("bucket-exists")) {
    _.promise({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.bucket_exists)
        .make(sd => console.log("+", "ok", sd.exists))
        .catch(_.error.log)
} else if (action("list-buckets")) {
    _.promise({
        awsd: awsd,
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.list_buckets)
        .make(sd => console.log("+", "ok", sd.buckets))
        .catch(_.error.log)
} else if (action("upload-json")) {
    _.promise({
        awsd: awsd,

        bucket: ad.bucket || "consensas-test1",
        key: ad.key || "name.json",
        json: {
            "hello": "world",
        },
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.upload_json)
        .make(sd => console.log("+", "ok", sd.aws_result))
        .catch(_.error.log)
} else if (action("upload-document")) {
    _.promise({
        awsd: awsd,

        bucket: ad.bucket || "consensas-test1",
        key: "test.txt",
        document: "The quick brown fox jumped over the lazy dog",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.upload_document)
        .make(sd => console.log("+", "ok", sd.aws_result))
        .catch(_.error.log)
} else if (action("delete-object")) {
    _.promise({
        awsd: awsd,

        bucket: ad.bucket || "consensas-test1",
        key: "test.txt",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.delete_object)
        .make(sd => console.log("+", "ok", sd.aws_result))
        .catch(_.error.log)
} else if (action("list-objects")) {
    _.promise({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: "eLyccgRz",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.list_objects)
        .make(sd => console.log("+", "ok", sd.paths))
        .catch(_.error.log)
} else if (action("list-objects-recursive")) {
    _.promise({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: "eLyccgRz",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.list_objects.recursive)
        .make(sd => console.log("+", "ok", sd.paths))
        .catch(_.error.log)
} else if (action("head-object")) {
    _.promise({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: ad.key || "name.jsonx",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.head_object)
        .make(sd => console.log("+", "ok", sd.files))
        .catch(_.error.log)
} else if (action("object-exists")) {
    _.promise({
        awsd: awsd,
        bucket: ad.bucket || "consensas-test1",
        key: ad.key || "name.json",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.object_exists)
        .make(sd => console.log("+", "ok", sd.exists))
        .catch(_.error.log)
} else if (action("object-exists-with-path")) {
    _.promise({
        awsd: awsd,
        path: "s3://consensas-test1/name.json",
    })
        .then(aws.initialize)
        .then(aws.s3.initialize)
        .then(aws.s3.parse_path)
        .then(aws.s3.exists)
        .make(sd => console.log("+", "ok", sd.exists))
        .catch(_.error.log)
} else if (!action_name) {
    console.log("#", "action required - should be one of:", actions.join(", "))
} else {
    console.log("#", "unknown action - should be one of:", actions.join(", "))
}

<|endoftext|>


<commit_before>

function Tree( name, id, root, parent ) { // root parameter only used internally

	if ( root === undefined ) {

		this.id = 0;
		this.maxId = 0;
		this.root = this;
		this.parent = null;

	} else {

		this.root = root;
		this.parent = parent;
		this.id =  ( id === null ) ? ++root.maxId : id;

	}

	this.name = name || '';
	this.children = [];

}

Tree.prototype.constructor = Tree;

Tree.prototype.traverse = function ( func ) {

	var children = this.children;

	func ( this );

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

		children[ i ].traverse( func );

	}

};

Tree.prototype.traverseDepthFirst = function ( func ) {

	var children = this.children;

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

		children[ i ].traverseDepthFirst( func );

	}

	func ( this );

};

Tree.prototype.forEachChild = function ( func, recurse ) {

	var children = this.children;
	var child;

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

		child = children[ i ];

		func( child );

		if ( recurse === true ) child.forEachChild( func, true );

	}

};

Tree.prototype.addById = function ( name, id, parentId, properties ) {

	var parentNode = this.findById( parentId );

	if ( parentNode ) {

		var node = new Tree( name, id, this.root, this );

		if ( properties !== undefined ) Object.assign( node, properties );

		parentNode.children.push ( node );

		var root = this.root;
		root.maxId = Math.max( root.maxId, id );

		return id;

	}

	return null;

};

Tree.prototype.findById = function ( id ) {

	if ( this.id == id ) return this;

	for ( var i = 0, l = this.children.length; i < l; i++ ) {

		var child = this.children[ i ];

		var found = child.findById( id );

		if ( found ) return found;

	}

	return undefined;

};

Tree.prototype.getByPath = function ( path ) {

	var pathArray = path.split( '.' );
	var node = this.getByPathArray( pathArray );

	return pathArray.length === 0 ? node : undefined;

};

Tree.prototype.getByPathArray = function ( path ) {

	var node  = this;
	var search = true;

	while ( search && path.length > 0 ) {

		search = false;

		for ( var i = 0, l = node.children.length; i < l; i++ ) {

			var child = node.children[ i ];

			if ( child.name === path[ 0 ] ) {

				node = child;
				path.shift();
				search = true;

				break;

			}

		}

	}

	return node;

};

Tree.prototype.addPath = function ( path, properties ) {

	var node;
	var newNode;

	// find part of path that exists already

	node = this.getByPathArray( path );

	if ( path.length === 0 ) return node.id;

	// add remainder of path to node

	while ( path.length > 0 ) {

		newNode = new Tree( path.shift(), null, this.root, node );

		node.children.push( newNode );
		node = newNode;

	}

	if ( properties !== undefined ) Object.assign( node, properties );

	return node.id;

};

Tree.prototype.getPath = function () {

	var node = this;
	var path = [];

	do {

		path.push( node.name );
		node = node.parent;

	} while ( node !== null );

	return path.reverse().join( '.' );

};

Tree.prototype.getSubtreeIds = function ( id, idSet ) {

	var node = this.findById( id );

	node.traverse( _getId );

	function _getId( node ) {

		idSet.add( node.id );

	}

};

Tree.prototype.getIdByPath = function ( path ) {

	var node = this.getByPathArray( path );

	if ( path.length === 0 ) {

		return node.id;

	} else {

		return undefined;

	}

};

export { Tree };

// EOF<commit_msg>fix bug (only effects lox files)<commit_after>

function Tree( name, id, root, parent ) { // root parameter only used internally

	if ( root === undefined ) {

		this.id = 0;
		this.maxId = 0;
		this.root = this;
		this.parent = null;

	} else {

		this.root = root;
		this.parent = parent;
		this.id =  ( id === null ) ? ++root.maxId : id;

	}

	this.name = name || '';
	this.children = [];

}

Tree.prototype.constructor = Tree;

Tree.prototype.traverse = function ( func ) {

	var children = this.children;

	func ( this );

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

		children[ i ].traverse( func );

	}

};

Tree.prototype.traverseDepthFirst = function ( func ) {

	var children = this.children;

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

		children[ i ].traverseDepthFirst( func );

	}

	func ( this );

};

Tree.prototype.forEachChild = function ( func, recurse ) {

	var children = this.children;
	var child;

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

		child = children[ i ];

		func( child );

		if ( recurse === true ) child.forEachChild( func, true );

	}

};

Tree.prototype.addById = function ( name, id, parentId, properties ) {

	var parentNode = this.findById( parentId );

	if ( parentNode ) {

		var node = new Tree( name, id, this.root, parentNode );

		if ( properties !== undefined ) Object.assign( node, properties );

		parentNode.children.push ( node );

		var root = this.root;
		root.maxId = Math.max( root.maxId, id );

		return id;

	}

	return null;

};

Tree.prototype.findById = function ( id ) {

	if ( this.id == id ) return this;

	for ( var i = 0, l = this.children.length; i < l; i++ ) {

		var child = this.children[ i ];

		var found = child.findById( id );

		if ( found ) return found;

	}

	return undefined;

};

Tree.prototype.getByPath = function ( path ) {

	var pathArray = path.split( '.' );
	var node = this.getByPathArray( pathArray );

	return pathArray.length === 0 ? node : undefined;

};

Tree.prototype.getByPathArray = function ( path ) {

	var node  = this;
	var search = true;

	while ( search && path.length > 0 ) {

		search = false;

		for ( var i = 0, l = node.children.length; i < l; i++ ) {

			var child = node.children[ i ];

			if ( child.name === path[ 0 ] ) {

				node = child;
				path.shift();
				search = true;

				break;

			}

		}

	}

	return node;

};

Tree.prototype.addPath = function ( path, properties ) {

	var node;
	var newNode;

	// find part of path that exists already

	node = this.getByPathArray( path );

	if ( path.length === 0 ) return node.id;

	// add remainder of path to node

	while ( path.length > 0 ) {

		newNode = new Tree( path.shift(), null, this.root, node );

		node.children.push( newNode );
		node = newNode;

	}

	if ( properties !== undefined ) Object.assign( node, properties );

	return node.id;

};

Tree.prototype.getPath = function () {

	var node = this;
	var path = [];

	do {

		path.push( node.name );
		node = node.parent;

	} while ( node !== null );

	return path.reverse().join( '.' );

};

Tree.prototype.getSubtreeIds = function ( id, idSet ) {

	var node = this.findById( id );

	node.traverse( _getId );

	function _getId( node ) {

		idSet.add( node.id );

	}

};

Tree.prototype.getIdByPath = function ( path ) {

	var node = this.getByPathArray( path );

	if ( path.length === 0 ) {

		return node.id;

	} else {

		return undefined;

	}

};

export { Tree };

// EOF<|endoftext|>


<commit_before>// Turn on full stack traces in errors to help debugging
Error.stackTraceLimit=Infinity;

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

// Cancel Karma's synchronous start,
// we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};

System.config({
    baseURL: '/base/',
    defaultJSExtensions: true,
    paths: {
        'angular2/*': 'node_modules/angular2/*.js',
        'rxjs/*': 'node_modules/rxjs/*.js'
    },
    meta: {
        'app/*': {
            format: 'register'
        }
    }
});

System.import('test/test-helpers/setup')
.then(function() {
    return Promise.all(
        Object.keys(window.__karma__.files)
        .filter(onlySpecFiles)
        .map(file2moduleName)
        .map(importModules)
    );
})
.then(function() {
    __karma__.start();
}, function(error) {
    __karma__.error(error.stack || error);
});

// Filter spec files
function onlySpecFiles(path) {
  return /\.spec\.js$/.test(path);
}

// Normalize paths to module names.
function file2moduleName(filePath) {
  return filePath.replace(/\\/g, '/')
    .replace(/^\/base\//, '')
    .replace(/\.js/, '');
}

// Import module path
function importModules(path) {
    return System.import(path);
}
<commit_msg>chore(test-shim): upgrade defaultJSExtensions<commit_after>// Turn on full stack traces in errors to help debugging
Error.stackTraceLimit=Infinity;

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000;

// Cancel Karma's synchronous start,
// we will call `__karma__.start()` later, once all the specs are loaded.
__karma__.loaded = function() {};

System.config({
    baseURL: '/base/',
    paths: {
        'n:*': 'node_modules/*'
    },
    map: {
        'angular2': 'n:angular2',
        'rxjs': 'n:rxjs'
    },
    packages: {
        'app': {
            format: 'register',
            defaultExtension: 'js'
        },
        'test': {
            format: 'register',
            defaultExtension: 'js'
        },
        'angular2': {
            defaultExtension: 'js'
        },
        'rxjs': {
            defaultExtension: 'js'
        }
    }
});

System.import('test/test-helpers/setup')
.then(function() {
    return Promise.all(
        Object.keys(window.__karma__.files)
        .filter(onlySpecFiles)
        .map(file2moduleName)
        .map(importModules)
    );
})
.then(function() {
    __karma__.start();
}, function(error) {
    __karma__.error(error.stack || error);
});

// Filter spec files
function onlySpecFiles(path) {
  return /\.spec\.js$/.test(path);
}

// Normalize paths to module names.
function file2moduleName(filePath) {
  return filePath.replace(/\\/g, '/')
    .replace(/^\/base\//, '')
    .replace(/\.js/, '');
}

// Import module path
function importModules(path) {
    return System.import(path);
}
<|endoftext|>