<commit_before>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { Close20, Menu20 } from '@carbon/icons-react';

import { settings } from 'carbon-components';
import cx from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';
import { AriaLabelPropType } from '../../prop-types/AriaPropTypes';

const { prefix } = settings;

const HeaderMenuButton = ({
  'aria-label': ariaLabel,
  'aria-labelledby': ariaLabelledBy,
  className: customClassName,
  onClick,
  isActive,
  isCollapsible,
  ...rest
}) => {
  const className = cx({
    [customClassName]: !!customClassName,
    [`${prefix}--header__action`]: true,
    [`${prefix}--header__menu-trigger`]: true,
    [`${prefix}--header__action--active`]: isActive,
    [`${prefix}--header__menu-toggle`]: true,
    [`${prefix}--header__menu-toggle__hidden`]: !isCollapsible,
  });
  const accessibilityLabel = {
    'aria-label': ariaLabel,
    'aria-labelledby': ariaLabelledBy,
  };

  return (
    <button
      {...rest}
      {...accessibilityLabel}
      className={className}
      title={ariaLabel}
      type="button"
      onClick={onClick}>
      {isActive ? <Close20 /> : <Menu20 />}
    </button>
  );
};

HeaderMenuButton.propTypes = {
  /**
   * Required props for accessibility label on the underlying menu button
   */
  ...AriaLabelPropType,

  /**
   * Optionally provide a custom class name that is applied to the underlying
   * button
   */
  className: PropTypes.string,

  isActive: PropTypes.bool,

  /**
   * Optionally provide an onClick handler that is called when the underlying
   * button fires it's onclick event
   */
  onClick: PropTypes.func,
};

export default HeaderMenuButton;
<commit_msg>feat(UIShell): custom icons in header menu button (#8468)<commit_after>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import { Close20, Menu20 } from '@carbon/icons-react';

import { settings } from 'carbon-components';
import cx from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';
import { AriaLabelPropType } from '../../prop-types/AriaPropTypes';

const { prefix } = settings;

const HeaderMenuButton = ({
  'aria-label': ariaLabel,
  'aria-labelledby': ariaLabelledBy,
  className: customClassName,
  renderMenuIcon,
  renderCloseIcon,
  onClick,
  isActive,
  isCollapsible,
  ...rest
}) => {
  const className = cx({
    [customClassName]: !!customClassName,
    [`${prefix}--header__action`]: true,
    [`${prefix}--header__menu-trigger`]: true,
    [`${prefix}--header__action--active`]: isActive,
    [`${prefix}--header__menu-toggle`]: true,
    [`${prefix}--header__menu-toggle__hidden`]: !isCollapsible,
  });
  const accessibilityLabel = {
    'aria-label': ariaLabel,
    'aria-labelledby': ariaLabelledBy,
  };
  const menuIcon = renderMenuIcon ? renderMenuIcon : <Menu20 />;
  const closeIcon = renderCloseIcon ? renderCloseIcon : <Close20 />;

  return (
    <button
      {...rest}
      {...accessibilityLabel}
      className={className}
      title={ariaLabel}
      type="button"
      onClick={onClick}>
      {isActive ? closeIcon : menuIcon}
    </button>
  );
};

HeaderMenuButton.propTypes = {
  /**
   * Required props for accessibility label on the underlying menu button
   */
  ...AriaLabelPropType,

  /**
   * Optionally provide a custom class name that is applied to the underlying
   * button
   */
  className: PropTypes.string,

  isActive: PropTypes.bool,

  /**
   * Optionally provide an onClick handler that is called when the underlying
   * button fires it's onclick event
   */
  onClick: PropTypes.func,
};

export default HeaderMenuButton;
<|endoftext|>


<commit_before>var VeryCollection = require('./collection');
var VeryValidator = require('./validator');
var Types = require('./definition').Types;
var underscore = require('underscore');

/* VeryModel, for spawning models out of a definition
 * Instances of VeryModel are factories for models themselves.
 */
function VeryModel(definition, opts) {
    this.opts = opts || {};
    if (Array.isArray(definition)) {
        this.definition = [];
    } else {
        this.definition = {};
    }
    this.controllers = {};

    //initialize sub model definitions recursively
    this.fields = [];
    this.addDefinition(definition);
}

(function () {

    function merge(a, b) {
        Object.keys(b).forEach(function (key) {
            if (key !== 'type' && typeof b[key] === 'object' && !Array.isArray(b[key]) && !(b[key] instanceof VeryModel)) {
                if (!a.hasOwnProperty(key)) {
                    a[key] = {};
                }
                merge(a[key], b[key]);
            } else {
                a[key] = b[key];
            }
        });
    }

    this.addDefinition = function (defs) {
        var newfields = Object.keys(defs);
        if (!Array.isArray(this.definition)) {
            merge(this.definition, defs);
        } else {
            this.definition = this.definition.concat(defs);
        }
        this.fields = underscore.union(newfields, this.fields);
        newfields.forEach(function (field) {
            this.setupField(field);
        }.bind(this));
    };

    this.inherit = function (parentModel) {
        var fields = parentModel.fields;

        fields.forEach(function _inheritField(field) {
            if (this.definition[field]) return;

            this.fields.push(field);
            this.definition[field] = parentModel.definition[field];

            this.setupField(field);
        }.bind(this));
    };

    this.setupField = function (field) {
        var submodel;
        if (this.definition[field].hasOwnProperty('model')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].model;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subModel = submodel;
                this.definition[field].model = this.definition[field].subModel.definition;
            } else {
                //initialize sub VeryModel
                this.definition[field].subModel = new VeryModel(submodel);
            }
        } else if (this.definition[field].hasOwnProperty('collection')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].collection;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subVeryCollection = submodel;
                this.definition[field].collection = this.definition[field].subVeryCollection.definition;
            } else {
                //initialize sub model defintion
                this.definition[field].subVeryCollection = new VeryModel(submodel);
            }
        }
    };

    /* create (optionally with the value object)
     * generates a model for populating, reading, and validating
     * the object over time
     */
    this.create = function (value, ctx) {
        var model = {};
        model.ctx = ctx;

        var meta = model.__verymeta = {
            model: this,
            defs: this.definition,
            data: {},
            map: {},
            reverseMap: {},
            primaryKey: null,
            creating: true,
            isEmpty: true
        };

        if (Array.isArray(meta.defs)) {
            meta.data = [];
        }

        //run through the definition fields
        this.fields.forEach(function _createField(field) {

            //hidden value attribute accessor
            if (typeof meta.defs[field].keyword !== 'undefined') {
                meta.map[meta.defs[field].keyword] = field;
                meta.reverseMap[field] = meta.defs[field].keyword;
                model.__defineGetter__(meta.defs[field].keyword, function () {
                    return model[meta.map[meta.defs[field].keyword]];
                });
            }

            if (meta.defs[field].primary === true) {
                meta.primaryKey = field;
            }

            model.__defineGetter__(field, function () {
                var meta = this.__verymeta;
                if (meta.defs[field].hasOwnProperty('derive')) {
                    meta.data[field] = meta.defs[field].derive.call(this, this);
                }
                return meta.data[field];
            }.bind(model));

            //handle assignment to sub models, sub arraymodels, and values differently
            if (meta.defs[field].hasOwnProperty('model')) {
                //recursively instatiate submodel
                meta.data[field] = meta.defs[field].subModel.create();
                meta.data[field].__verymeta.parent = model;

                //assigning to the submodel should call loadData on it
                model.__defineSetter__(field, function (value) {
                    this.__verymeta.data[field].loadData(value, false);
                });

                return;
            }

            if (meta.defs[field].hasOwnProperty('collection')) {
                //create an array-like object for a collection of the sub model
                meta.data[field] = new VeryCollection(meta.defs[field].subVeryCollection, model);

                return;
            }

            //assign the default value to required fields
            //this could get overwritten later at the loadData phase
            if (meta.defs[field].required) {
                if (typeof meta.defs[field].default === 'function') {
                    meta.data[field] = meta.defs[field].default(model);
                } else {
                    meta.data[field] = meta.defs[field].default;
                }
            }

            //validate values as they come in
            //hidden value style setter
            model.__defineSetter__(field, function (value) {
                var meta = this.__verymeta;

                if (meta.defs[field].static === true && !meta.creating) {
                    throw new Error('Cannot set static values');
                }

                meta.data[field] = value;

                meta.isEmpty = false;
            });
        }.bind(this));

        //load data en masse into the model
        //works recursively
        model.loadData = function (value, process) {
            process = process !== false;
            var meta = this.__verymeta;
            var processIn;

            if (Array.isArray(meta.defs)) {
                meta.data = [];
                var valueoff = 0;
                for (var vidx in meta.defs) {
                    processIn = process && meta.defs[vidx].processIn && typeof meta.defs[vidx].processIn === 'function' ? meta.defs[vidx].processIn.bind(this) : false;
                    if (!meta.defs[vidx].required && value.length + valueoff < meta.defs.length) {
                        if (meta.defs[vidx].default === 'function') {
                            this[vidx] = meta.defs[vidx].default(this);
                        } else {
                            this[vidx] = meta.defs[vidx].default;
                        }
                        valueoff += 1;
                    } else {
                        if (processIn) {
                            this[vidx] = processIn(value[vidx - valueoff]).bind(this);
                        } else {
                            this[vidx] = value[vidx - valueoff];
                        }
                    }
                }
            } else {
                Object.keys(value).forEach(function (key) {
                    if (!meta.defs.hasOwnProperty(key)) return;
                    processIn = process && meta.defs[key].processIn && typeof meta.defs[key].processIn === 'function' ? meta.defs[key].processIn.bind(this) : false;

                    if (meta.defs[key].hasOwnProperty('collection')) {
                        for (var vidx in value[key]) {
                            meta.isEmpty = false;
                            if (processIn) {
                                meta.data[key].push(processIn(value[key][vidx]));
                            } else {
                                meta.data[key].push(value[key][vidx]);
                            }
                        }
                    } else if (meta.defs[key].hasOwnProperty('model') && meta.creating) {
                        meta.data[key].loadData(value[key]);
                    } else {
                        meta.isEmpty = false;
                        if (processIn) {
                            model[key] = processIn(value[key]);
                        } else {
                            model[key] = value[key];
                        }
                    }
                }.bind(this));
            }
        };

        //create a JSON serializable Javascript object out of the model data
        //no more helper functions or accessors
        model.toJSON = function (opts) {
            opts = opts || {};

            var meta = this.__verymeta;
            var obj;

            if (Array.isArray(meta.defs) && !opts.useKeywords) {
                obj = [];
            } else {
                obj = {};
            }

            Object.keys(meta.defs).forEach(function (field) {
                var processOut = meta.defs[field].processOut && typeof meta.defs[field].processOut === 'function' ? meta.defs[field].processOut.bind(this) : false;
                var key = field;
                if (meta.defs[field].private && !opts.withPrivate) {
                    return;
                }

                if (opts.useKeywords && meta.reverseMap.hasOwnProperty(field)) {
                    key = meta.reverseMap[field];
                }

                if (meta.defs[field].hasOwnProperty('model')) {
                    if (!meta.data[field].__verymeta.isEmpty) {
                        obj[key] = meta.data[field].toJSON();
                    }
                    return;
                }

                if (meta.defs[field].hasOwnProperty('collection')) {
                    obj[key] = [];
                    meta.data[field].forEach(function (inst) {
                        if (!inst.__verymeta.isEmpty) {
                            obj[key].push(inst.toJSON());
                        }
                    });
                    if (obj[key].length === 0) {
                        delete obj[key];
                    }

                    return;
                }

                obj[key] = processOut ? processOut(this[field]) : this[field];
                if (typeof obj[key] === 'undefined') {
                    delete obj[key];
                }
            }.bind(this));

            return obj;
        };

        //validate that a model follows the rules and types
        //works recursively
        //returns a list of errors
        //if the list of errors.length === 0, you're golden
        model.doValidate = function () {
            var meta = this.__verymeta;
            var errors = [];

            Object.keys(meta.defs).forEach(function (field) {
                var fidx;
                var merrors;
                //if field is set and dependency is set
                if (meta.data.hasOwnProperty(field) && meta.defs[field].depends) {
                    for (fidx in meta.defs[field].depends) {
                        //check to see if other field is set
                        if (!meta.data.hasOwnProperty(fidx) || meta.data[fidx] === undefined) {
                            errors.push(field + ": Dependency -> " + fidx + ": not set");
                        //check to see if dependency has a validator
                        } else if (meta.defs[field].depends instanceof VeryValidator) {
                            merrors = meta.defs[field].depends[fidx].validate(meta.data[fidx]);
                            merrors.forEach(function (error) {
                                errors.push(field + ": Dependency  -> " + fidx + ": " + error);
                            });
                        }
                    }
                }
                //if field is reuqired and it's not set
                if (meta.defs[field].required && (!meta.data.hasOwnProperty(field) || meta.data[field] === undefined)) {
                    errors.push(field + ": required");
                }
                //if this field is another model
                //recursively validate it
                //add errors to our own
                //only if the submodule is required or has been populated
                if (meta.defs[field].hasOwnProperty('model') && meta.data.hasOwnProperty(field) && (!meta.data[field].__verymeta.isEmpty || meta.defs[field].required)) {
                    merrors = meta.data[field].doValidate();
                    for (var eidx in merrors) {
                        merrors[eidx] = field + '.' + merrors[eidx];
                    }
                    errors = errors.concat(merrors);
                //if field is an array of models
                //recursively validate them
                //and add their errors to our own
                } else if (meta.defs[field].hasOwnProperty('collection') && meta.data.hasOwnProperty(field)) {
                    var arrayerrors = [];
                    var idx = 0;
                    meta.data[field].forEach(function (model) {
                        //is this collection required? has the model been populated?
                        if (meta.defs[field].required || !model.__verymeta.isEmpty) {
                            merrors = model.doValidate();
                            for (var eidx in merrors) {
                                merrors[eidx] = field + '[' + idx + '].' + merrors[eidx];
                            }
                            errors = errors.concat(merrors);
                        }
                        idx += 1;
                    }.bind(this));
                //if we have a VeryValidator to validate against, validate it
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('type')) {
                    if (typeof meta.defs[field].type === 'string' && Types.hasOwnProperty(meta.defs[field].type)) {
                        meta.defs[field].type = Types[meta.defs[field].type];
                    }
                    merrors = meta.defs[field].type.validate(meta.data[field]);
                    if (typeof merrors === 'boolean') {
                        if (merrors) {
                            merrors = [];
                        } else {
                            merrors = ["Failed."];
                        }
                    }
                    merrors.forEach(function (error) {
                        errors.push(field + ": " + error);
                    });
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('array')) {
                    var tidx = 0;
                    meta.defs[field].array.forEach(function (type) {
                        merrors = type.validate(meta.data[field][tidx]);
                        merrors.forEach(function (error) {
                            errors.push(field + "[" + tidx + "]: " + error);
                        });
                        tidx++;
                    }.bind(this));
                }

            }.bind(this));
            return errors;
        };

        model.makeClone = function () {
            return this.__verymeta.model.create(this.toJSON());
        };

        //generate a JSON string from the model data
        model.toString = function (args) {
            return JSON.stringify(this.toJSON(args));
        };

        //extend controllers
        Object.keys(this.controllers).forEach(function (controller) {
            model[controller] = this.controllers[controller];
        }.bind(this));

        //if model.create passed in initial values, load them
        if (typeof value !== 'undefined') {
            model.loadData(value);
        }

        meta.creating = false;

        return model;
    };

    this.extendModel = function (controllers) {
        this.controllers = underscore.extend(this.controllers, controllers);
    };

    this.addModelVar = function (name, value) {
        this.controllers[name] = value;
    };

}).call(VeryModel.prototype);

module.exports = VeryModel;
<commit_msg>better name and setup for options<commit_after>var VeryCollection = require('./collection');
var VeryValidator = require('./validator');
var Types = require('./definition').Types;
var underscore = require('underscore');

/* VeryModel, for spawning models out of a definition
 * Instances of VeryModel are factories for models themselves.
 */
function VeryModel(definition, options) {
    if (Array.isArray(definition)) {
        this.definition = [];
    } else {
        this.definition = {};
    }
    this.controllers = {};
    this.options = {};

    //initialize sub model definitions recursively
    this.fields = [];
    this.addDefinition(definition);
    this.addOptions(options, true);
}

(function () {

    function merge(a, b) {
        Object.keys(b).forEach(function (key) {
            if (key !== 'type' && typeof b[key] === 'object' && !Array.isArray(b[key]) && !(b[key] instanceof VeryModel)) {
                if (!a.hasOwnProperty(key)) {
                    a[key] = {};
                }
                merge(a[key], b[key]);
            } else {
                a[key] = b[key];
            }
        });
    }

    this.addDefinition = function (defs) {
        var newfields = Object.keys(defs);
        if (!Array.isArray(this.definition)) {
            merge(this.definition, defs);
        } else {
            this.definition = this.definition.concat(defs);
        }
        this.fields = underscore.union(newfields, this.fields);
        newfields.forEach(function (field) {
            this.setupField(field);
        }.bind(this));
    };

    this.addOptions = function (options, overwrite) {
        if (!underscore.isObject(options)) return;
        var newOptions = Object.keys(options);
        newOptions.forEach(function (name) {
            if (!this.options.hasOwnProperty(name) || overwrite) {
                this.options[name] = options[name];
            }
        }, this);
    };

    this.inherit = function (parentModel) {
        var fields = parentModel.fields;

        fields.forEach(function _inheritField(field) {
            if (this.definition[field]) return;

            this.fields.push(field);
            this.definition[field] = parentModel.definition[field];

            this.setupField(field);
        }.bind(this));
    };

    this.setupField = function (field) {
        var submodel;
        if (this.definition[field].hasOwnProperty('model')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].model;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subModel = submodel;
                this.definition[field].model = this.definition[field].subModel.definition;
            } else {
                //initialize sub VeryModel
                this.definition[field].subModel = new VeryModel(submodel);
            }
        } else if (this.definition[field].hasOwnProperty('collection')) {
            //if we get a VeryModel instance instead of a definition object
            //we have to switch things up
            submodel = this.definition[field].collection;
            if (submodel === 'this') {
                submodel = this;
            }
            if (submodel instanceof VeryModel) {
                this.definition[field].subVeryCollection = submodel;
                this.definition[field].collection = this.definition[field].subVeryCollection.definition;
            } else {
                //initialize sub model defintion
                this.definition[field].subVeryCollection = new VeryModel(submodel);
            }
        }
    };

    /* create (optionally with the value object)
     * generates a model for populating, reading, and validating
     * the object over time
     */
    this.create = function (value, ctx) {
        var model = {};
        model.ctx = ctx;

        var meta = model.__verymeta = {
            model: this,
            defs: this.definition,
            data: {},
            map: {},
            reverseMap: {},
            primaryKey: null,
            creating: true,
            isEmpty: true
        };

        if (Array.isArray(meta.defs)) {
            meta.data = [];
        }

        //run through the definition fields
        this.fields.forEach(function _createField(field) {

            //hidden value attribute accessor
            if (typeof meta.defs[field].keyword !== 'undefined') {
                meta.map[meta.defs[field].keyword] = field;
                meta.reverseMap[field] = meta.defs[field].keyword;
                model.__defineGetter__(meta.defs[field].keyword, function () {
                    return model[meta.map[meta.defs[field].keyword]];
                });
            }

            if (meta.defs[field].primary === true) {
                meta.primaryKey = field;
            }

            model.__defineGetter__(field, function () {
                var meta = this.__verymeta;
                if (meta.defs[field].hasOwnProperty('derive')) {
                    meta.data[field] = meta.defs[field].derive.call(this, this);
                }
                return meta.data[field];
            }.bind(model));

            //handle assignment to sub models, sub arraymodels, and values differently
            if (meta.defs[field].hasOwnProperty('model')) {
                //recursively instatiate submodel
                meta.data[field] = meta.defs[field].subModel.create();
                meta.data[field].__verymeta.parent = model;

                //assigning to the submodel should call loadData on it
                model.__defineSetter__(field, function (value) {
                    this.__verymeta.data[field].loadData(value, false);
                });

                return;
            }

            if (meta.defs[field].hasOwnProperty('collection')) {
                //create an array-like object for a collection of the sub model
                meta.data[field] = new VeryCollection(meta.defs[field].subVeryCollection, model);

                return;
            }

            //assign the default value to required fields
            //this could get overwritten later at the loadData phase
            if (meta.defs[field].required) {
                if (typeof meta.defs[field].default === 'function') {
                    meta.data[field] = meta.defs[field].default(model);
                } else {
                    meta.data[field] = meta.defs[field].default;
                }
            }

            //validate values as they come in
            //hidden value style setter
            model.__defineSetter__(field, function (value) {
                var meta = this.__verymeta;

                if (meta.defs[field].static === true && !meta.creating) {
                    throw new Error('Cannot set static values');
                }

                meta.data[field] = value;

                meta.isEmpty = false;
            });
        }.bind(this));

        //load data en masse into the model
        //works recursively
        model.loadData = function (value, process) {
            process = process !== false;
            var meta = this.__verymeta;
            var processIn;

            if (Array.isArray(meta.defs)) {
                meta.data = [];
                var valueoff = 0;
                for (var vidx in meta.defs) {
                    processIn = process && meta.defs[vidx].processIn && typeof meta.defs[vidx].processIn === 'function' ? meta.defs[vidx].processIn.bind(this) : false;
                    if (!meta.defs[vidx].required && value.length + valueoff < meta.defs.length) {
                        if (meta.defs[vidx].default === 'function') {
                            this[vidx] = meta.defs[vidx].default(this);
                        } else {
                            this[vidx] = meta.defs[vidx].default;
                        }
                        valueoff += 1;
                    } else {
                        if (processIn) {
                            this[vidx] = processIn(value[vidx - valueoff]).bind(this);
                        } else {
                            this[vidx] = value[vidx - valueoff];
                        }
                    }
                }
            } else {
                Object.keys(value).forEach(function (key) {
                    if (!meta.defs.hasOwnProperty(key)) return;
                    processIn = process && meta.defs[key].processIn && typeof meta.defs[key].processIn === 'function' ? meta.defs[key].processIn.bind(this) : false;

                    if (meta.defs[key].hasOwnProperty('collection')) {
                        for (var vidx in value[key]) {
                            meta.isEmpty = false;
                            if (processIn) {
                                meta.data[key].push(processIn(value[key][vidx]));
                            } else {
                                meta.data[key].push(value[key][vidx]);
                            }
                        }
                    } else if (meta.defs[key].hasOwnProperty('model') && meta.creating) {
                        meta.data[key].loadData(value[key]);
                    } else {
                        meta.isEmpty = false;
                        if (processIn) {
                            model[key] = processIn(value[key]);
                        } else {
                            model[key] = value[key];
                        }
                    }
                }.bind(this));
            }
        };

        //create a JSON serializable Javascript object out of the model data
        //no more helper functions or accessors
        model.toJSON = function (opts) {
            opts = opts || {};

            var meta = this.__verymeta;
            var obj;

            if (Array.isArray(meta.defs) && !opts.useKeywords) {
                obj = [];
            } else {
                obj = {};
            }

            Object.keys(meta.defs).forEach(function (field) {
                var processOut = meta.defs[field].processOut && typeof meta.defs[field].processOut === 'function' ? meta.defs[field].processOut.bind(this) : false;
                var key = field;
                if (meta.defs[field].private && !opts.withPrivate) {
                    return;
                }

                if (opts.useKeywords && meta.reverseMap.hasOwnProperty(field)) {
                    key = meta.reverseMap[field];
                }

                if (meta.defs[field].hasOwnProperty('model')) {
                    if (!meta.data[field].__verymeta.isEmpty) {
                        obj[key] = meta.data[field].toJSON();
                    }
                    return;
                }

                if (meta.defs[field].hasOwnProperty('collection')) {
                    obj[key] = [];
                    meta.data[field].forEach(function (inst) {
                        if (!inst.__verymeta.isEmpty) {
                            obj[key].push(inst.toJSON());
                        }
                    });
                    if (obj[key].length === 0) {
                        delete obj[key];
                    }

                    return;
                }

                obj[key] = processOut ? processOut(this[field]) : this[field];
                if (typeof obj[key] === 'undefined') {
                    delete obj[key];
                }
            }.bind(this));

            return obj;
        };

        //validate that a model follows the rules and types
        //works recursively
        //returns a list of errors
        //if the list of errors.length === 0, you're golden
        model.doValidate = function () {
            var meta = this.__verymeta;
            var errors = [];

            Object.keys(meta.defs).forEach(function (field) {
                var fidx;
                var merrors;
                //if field is set and dependency is set
                if (meta.data.hasOwnProperty(field) && meta.defs[field].depends) {
                    for (fidx in meta.defs[field].depends) {
                        //check to see if other field is set
                        if (!meta.data.hasOwnProperty(fidx) || meta.data[fidx] === undefined) {
                            errors.push(field + ": Dependency -> " + fidx + ": not set");
                        //check to see if dependency has a validator
                        } else if (meta.defs[field].depends instanceof VeryValidator) {
                            merrors = meta.defs[field].depends[fidx].validate(meta.data[fidx]);
                            merrors.forEach(function (error) {
                                errors.push(field + ": Dependency  -> " + fidx + ": " + error);
                            });
                        }
                    }
                }
                //if field is reuqired and it's not set
                if (meta.defs[field].required && (!meta.data.hasOwnProperty(field) || meta.data[field] === undefined)) {
                    errors.push(field + ": required");
                }
                //if this field is another model
                //recursively validate it
                //add errors to our own
                //only if the submodule is required or has been populated
                if (meta.defs[field].hasOwnProperty('model') && meta.data.hasOwnProperty(field) && (!meta.data[field].__verymeta.isEmpty || meta.defs[field].required)) {
                    merrors = meta.data[field].doValidate();
                    for (var eidx in merrors) {
                        merrors[eidx] = field + '.' + merrors[eidx];
                    }
                    errors = errors.concat(merrors);
                //if field is an array of models
                //recursively validate them
                //and add their errors to our own
                } else if (meta.defs[field].hasOwnProperty('collection') && meta.data.hasOwnProperty(field)) {
                    var arrayerrors = [];
                    var idx = 0;
                    meta.data[field].forEach(function (model) {
                        //is this collection required? has the model been populated?
                        if (meta.defs[field].required || !model.__verymeta.isEmpty) {
                            merrors = model.doValidate();
                            for (var eidx in merrors) {
                                merrors[eidx] = field + '[' + idx + '].' + merrors[eidx];
                            }
                            errors = errors.concat(merrors);
                        }
                        idx += 1;
                    }.bind(this));
                //if we have a VeryValidator to validate against, validate it
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('type')) {
                    if (typeof meta.defs[field].type === 'string' && Types.hasOwnProperty(meta.defs[field].type)) {
                        meta.defs[field].type = Types[meta.defs[field].type];
                    }
                    merrors = meta.defs[field].type.validate(meta.data[field]);
                    if (typeof merrors === 'boolean') {
                        if (merrors) {
                            merrors = [];
                        } else {
                            merrors = ["Failed."];
                        }
                    }
                    merrors.forEach(function (error) {
                        errors.push(field + ": " + error);
                    });
                } else if (meta.data.hasOwnProperty(field) && meta.defs[field].hasOwnProperty('array')) {
                    var tidx = 0;
                    meta.defs[field].array.forEach(function (type) {
                        merrors = type.validate(meta.data[field][tidx]);
                        merrors.forEach(function (error) {
                            errors.push(field + "[" + tidx + "]: " + error);
                        });
                        tidx++;
                    }.bind(this));
                }

            }.bind(this));
            return errors;
        };

        model.makeClone = function () {
            return this.__verymeta.model.create(this.toJSON());
        };

        //generate a JSON string from the model data
        model.toString = function (args) {
            return JSON.stringify(this.toJSON(args));
        };

        //extend controllers
        Object.keys(this.controllers).forEach(function (controller) {
            model[controller] = this.controllers[controller];
        }.bind(this));

        //if model.create passed in initial values, load them
        if (typeof value !== 'undefined') {
            model.loadData(value);
        }

        meta.creating = false;

        return model;
    };

    this.extendModel = function (controllers) {
        this.controllers = underscore.extend(this.controllers, controllers);
    };

    this.addModelVar = function (name, value) {
        this.controllers[name] = value;
    };

}).call(VeryModel.prototype);

module.exports = VeryModel;
<|endoftext|>


<commit_before>import debugModule from "debug";
const debug = debugModule("debugger:solidity:selectors");

import { createSelectorTree, createLeaf } from "reselect-tree";
import SolidityUtils from "truffle-solidity-utils";
import CodeUtils from "truffle-code-utils";

import evm from "lib/evm/selectors";

function getSourceRange(instruction = {}) {
  return {
    start: instruction.start || 0,
    length: instruction.length || 0,
    lines: instruction.range || {
      start: {
        line: 0, column: 0
      },
      end: {
        line: 0, column: 0
      }
    }
  };
}

let solidity = createSelectorTree({
  /**
   * solidity.state
   */
  state: (state) => state.solidity,

  /**
   * solidity.info
   */
  info: {
    /**
     * solidity.info.sources
     */
    sources: createLeaf(['/state'], (state) => state.info.sources.byId),

    /**
     * solidity.info.sourceMaps
     */
    sourceMaps: createLeaf(['/state'], (state) => state.info.sourceMaps.byContext)
  },

  /**
   * solidity.current
   */
  current: {

    /**
     * solidity.current.sourceMap
     */
    sourceMap: createLeaf(
      [evm.current.context, "/info/sourceMaps"],

      ({context}, sourceMaps) => sourceMaps[context]
    ),

    /**
     * solidity.current.functionDepth
     */
    functionDepth: (state) => state.solidity.proc.functionDepth,

    /**
     * solidity.current.instructions
     */
    instructions: createLeaf(
      ["/info/sources", evm.current.context, "./sourceMap"],

      (sources, {binary}, {sourceMap}) => {
        let instructions = CodeUtils.parseCode(binary);

        if (!sourceMap) {
          // Let's create a source map to use since none exists. This source map
          // maps just as many ranges as there are instructions, and ensures every
          // instruction is marked as "jumping out". This will ensure all
          // available debugger commands step one instruction at a time.
          //
          // This is kindof a hack; perhaps this should be broken out into separate
          // context types. TODO
          sourceMap = "";
          for (var i = 0; i < instructions.length; i++) {
            sourceMap += i + ":" + i + ":1:o;";
          }
        }

        var lineAndColumnMappings = Object.assign({},
          ...Object.entries(sources).map(
            ([id, {source}]) => ({
              [id]: SolidityUtils.getCharacterOffsetToLineAndColumnMapping(source || "")
            })
          )
        );
        var humanReadableSourceMap = SolidityUtils.getHumanReadableSourceMap(sourceMap);

        instructions.forEach(function(instruction, instructionIndex) {
          var sourceMapInstruction = humanReadableSourceMap[instructionIndex];

          instruction.index = instructionIndex;

          if (sourceMapInstruction) {
            var lineAndColumnMapping =
              lineAndColumnMappings[sourceMapInstruction.file] || {};

            instruction.jump = sourceMapInstruction.jump;
            instruction.start = sourceMapInstruction.start;
            instruction.length = sourceMapInstruction.length;
            instruction.file = sourceMapInstruction.file;
            instruction.range = {
              start: lineAndColumnMapping[sourceMapInstruction.start],
              end: lineAndColumnMapping[sourceMapInstruction.start + sourceMapInstruction.length]
            }
          }
        });

        return instructions;
      }
    ),

    /**
     * solidity.current.instructionAtProgramCounter
     */
    instructionAtProgramCounter: createLeaf(
      ["./instructions"],

      (instructions) => {
        let map = [];
        instructions.forEach(function(instruction) {
          map[instruction.pc] = instruction;
        });
        return map;
      }
    )
  },

  /**
   * solidity.next
   */
  next: {

    /**
     * solidity.next.instruction
     */
    instruction: createLeaf(
      ["../current/instructionAtProgramCounter", evm.next.step.programCounter],

      (map, pc) => map[pc]
    ),

    /**
     * solidity.next.source
     */
    source: createLeaf(
      ["/info/sources", "./instruction"],

      (sources, {file: id}) => sources[id]
    ),

    /**
     * solidity.next.sourceRange
     */
    sourceRange: createLeaf(["./instruction"], getSourceRange),

    /**
     * solidity.next.isMultiline
     */
    isMultiline: createLeaf(
      ["./sourceRange"],

      ( {lines} ) => lines.start.line != lines.end.line
    ),

    /**
     * solidity.next.willJump
     */
    willJump: createLeaf([evm.next.step.isJump], (isJump) => isJump),

    /**
     * solidity.next.jumpDirection
     */
    jumpDirection: createLeaf(
      ["./instruction"], (i = {}) => (i.jump || "-")
    )
  }
});

export default solidity;
<commit_msg>Account for source-less opcodes<commit_after>import debugModule from "debug";
const debug = debugModule("debugger:solidity:selectors");

import { createSelectorTree, createLeaf } from "reselect-tree";
import SolidityUtils from "truffle-solidity-utils";
import CodeUtils from "truffle-code-utils";

import evm from "lib/evm/selectors";

function getSourceRange(instruction = {}) {
  return {
    start: instruction.start || 0,
    length: instruction.length || 0,
    lines: instruction.range || {
      start: {
        line: 0, column: 0
      },
      end: {
        line: 0, column: 0
      }
    }
  };
}

let solidity = createSelectorTree({
  /**
   * solidity.state
   */
  state: (state) => state.solidity,

  /**
   * solidity.info
   */
  info: {
    /**
     * solidity.info.sources
     */
    sources: createLeaf(['/state'], (state) => state.info.sources.byId),

    /**
     * solidity.info.sourceMaps
     */
    sourceMaps: createLeaf(['/state'], (state) => state.info.sourceMaps.byContext)
  },

  /**
   * solidity.current
   */
  current: {

    /**
     * solidity.current.sourceMap
     */
    sourceMap: createLeaf(
      [evm.current.context, "/info/sourceMaps"],

      ({context}, sourceMaps) => sourceMaps[context]
    ),

    /**
     * solidity.current.functionDepth
     */
    functionDepth: (state) => state.solidity.proc.functionDepth,

    /**
     * solidity.current.instructions
     */
    instructions: createLeaf(
      ["/info/sources", evm.current.context, "./sourceMap"],

      (sources, {binary}, {sourceMap}) => {
        let instructions = CodeUtils.parseCode(binary);

        if (!sourceMap) {
          // Let's create a source map to use since none exists. This source map
          // maps just as many ranges as there are instructions, and ensures every
          // instruction is marked as "jumping out". This will ensure all
          // available debugger commands step one instruction at a time.
          //
          // This is kindof a hack; perhaps this should be broken out into separate
          // context types. TODO
          sourceMap = "";
          for (var i = 0; i < instructions.length; i++) {
            sourceMap += i + ":" + i + ":1:o;";
          }
        }

        var lineAndColumnMappings = Object.assign({},
          ...Object.entries(sources).map(
            ([id, {source}]) => ({
              [id]: SolidityUtils.getCharacterOffsetToLineAndColumnMapping(source || "")
            })
          )
        );
        var humanReadableSourceMap = SolidityUtils.getHumanReadableSourceMap(sourceMap);

        instructions.forEach(function(instruction, instructionIndex) {
          var sourceMapInstruction = humanReadableSourceMap[instructionIndex];

          instruction.index = instructionIndex;

          if (sourceMapInstruction) {
            var lineAndColumnMapping =
              lineAndColumnMappings[sourceMapInstruction.file] || {};

            instruction.jump = sourceMapInstruction.jump;
            instruction.start = sourceMapInstruction.start;
            instruction.length = sourceMapInstruction.length;
            instruction.file = sourceMapInstruction.file;
            instruction.range = {
              start: lineAndColumnMapping[sourceMapInstruction.start],
              end: lineAndColumnMapping[sourceMapInstruction.start + sourceMapInstruction.length]
            }
          }
        });

        return instructions;
      }
    ),

    /**
     * solidity.current.instructionAtProgramCounter
     */
    instructionAtProgramCounter: createLeaf(
      ["./instructions"],

      (instructions) => {
        let map = [];
        instructions.forEach(function(instruction) {
          map[instruction.pc] = instruction;
        });

        // fill in gaps in map by defaulting to the last known instruction
        let lastSeen = null;
        for (let [pc, instruction] of map.entries()) {
          if (instruction) {
            lastSeen = instruction;
          } else {
            map[pc] = lastSeen;
          }
        }
        return map;
      }
    )
  },

  /**
   * solidity.next
   */
  next: {

    /**
     * solidity.next.instruction
     */
    instruction: createLeaf(
      ["../current/instructionAtProgramCounter", evm.next.step.programCounter],

      (map, pc) => map[pc] || {}
    ),

    /**
     * solidity.next.source
     */
    source: createLeaf(
      ["/info/sources", "./instruction"],

      (sources, {file: id}) => sources[id]
    ),

    /**
     * solidity.next.sourceRange
     */
    sourceRange: createLeaf(["./instruction"], getSourceRange),

    /**
     * solidity.next.isMultiline
     */
    isMultiline: createLeaf(
      ["./sourceRange"],

      ( {lines} ) => lines.start.line != lines.end.line
    ),

    /**
     * solidity.next.willJump
     */
    willJump: createLeaf([evm.next.step.isJump], (isJump) => isJump),

    /**
     * solidity.next.jumpDirection
     */
    jumpDirection: createLeaf(
      ["./instruction"], (i = {}) => (i.jump || "-")
    )
  }
});

export default solidity;
<|endoftext|>


<commit_before>/* global HDO */

(function (HDO) {
  HDO.voteSearcher = {
    create: function (url) {
      var instance = Object.create(this);
      instance.url = url;
      return instance;
    },

    init: function () {
      var self = this;

      $('#reset').click(function () {
        $("#result").html('');
        $("#filter").val('selected-categories');
        $("#keyword").val('');

        return false;
      });

      $('#fetch-votes').click(function () {
        var params = {
          keyword: $('#keyword').val(),
          filter: $('#filter').val()
        };

        $("#result").html('');
        $("#spinner").show();

        self.loadVotes(params);

        return false;
      });
    },

    loadVotes: function (params) {
      $.ajax({
        url: this.url,
        type: "GET",
        dataType: "html",
        data: $.param(params),

        complete: function () {
          $("#spinner").hide();
        },

        success: function (html) {
          $("#result").html(html);
        },

        error: function (err) {
          $("#result").html(err);
        }
      });
    }
  };
}(HDO));
<commit_msg>For vote search, search instead of submitting the form when hitting enter. Closes #249.<commit_after>/* global HDO */

(function (HDO) {
  HDO.voteSearcher = {
    create: function (url) {
      var instance = Object.create(this);
      instance.url = url;
      return instance;
    },

    init: function () {
      var self = this;

      $('#reset').click(function () {
        $("#result").html('');
        $("#filter").val('selected-categories');
        $("#keyword").val('');

        return false;
      });

      $("#keyword").keypress(function (e) {
        if (e.keyCode === 13) {
          e.preventDefault();
          $("#fetch-votes").click();
        }
      });

      $('#fetch-votes').click(function () {
        var params = {
          keyword: $('#keyword').val(),
          filter: $('#filter').val()
        };

        $("#result").html('');
        $("#spinner").show();

        self.loadVotes(params);

        return false;
      });
    },

    loadVotes: function (params) {
      $.ajax({
        url: this.url,
        type: "GET",
        dataType: "html",
        data: $.param(params),

        complete: function () {
          $("#spinner").hide();
        },

        success: function (html) {
          $("#result").html(html);
        },

        error: function (err) {
          $("#result").html(err);
        }
      });
    }
  };
}(HDO));
<|endoftext|>


<commit_before>/**
* Models.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
*
* Example
* db.find('skolarapp','users',{ },function(e,d){
*   console.log(d);
* });
*

    #find by id
    Users.tenant('skolarapp').findById('56945402086e30355508472a').exec(function(e,d){
     console.log(d);
    });

    #create
    Users.tenant('skolarapp').create({name:'Saraí León López',email:'sleon90@gmail.com'}).exec(function(e,d){
       console.log(d);
     });

    #update
    Users.tenant('skolarapp').update('56959eb9dcb1e89660795175',{$set:{name:'Saraí León 2'}}).exec(function(e,d){
     console.log(d);
    });

    #remove
    Users.tenant('skolarapp').remove({name:'Saraí León 2'}).exec(function(e,d){
     console.log(d);
    });

    #count
    Users.tenant('skolarapp').count().exec(function(e,d){
     console.log(d);
    });

    #other stuff no supported in tenant
    Users.tenant('skolarapp').native(function(e,db,collection){
          // Group with a conditional
            collection.group([], {}, {"count":0}, "function (obj, prev) { prev.count++; }", false, function(err, results) {
             console.log(results);
            })
    });
*/

var Db            = require('mongodb').Db;
var MongoClient   = require('mongodb').MongoClient;
var ObjectID      = require('mongodb').ObjectID;
var ReplSet       = require('mongodb').ReplSet;
var Server        = require('mongodb').Server;
const assert      = require('assert');
const path        = require('path');
const fs          = require('fs');
const join        = require('path').join;

const connections = require(fs.realpathSync('config/connections.js',{}));

var credentials   = typeof(connections.default.user) && connections.default.user != '' ? connections.default.user+':'+connections.default.password+'@' : '';
const uri         = 'mongodb://'+credentials+connections.default.host+':'+connections.default.port+'/';

module.exports = {
    _limit : 0,
    _sort  : {},
    _skip  : 0,
    _data  : {},

    exec:function(callback){
      var that = this;
      this.connect(function(db) {
         that[that._method](db,function(e,r){callback(e,r)});
       });
    },
    connect:function(callback){

      var that = this;
      // Set up the connection to the local db
      var db = new Db(this.database, new Server(connections.default.host, connections.default.port ));
      //open connection
      db.open(function(err, db){
        if(!err){
           // Display output in testing mode
           //--------------------------------------------------
          //console.log("Connected to database server:", connections.default.host);
          callback(err||db);
        }else{

        }
      })
    },
    tenant:function(database){
      this.database = database;
      return this;
    },
    skip :function(skip){
      this._skip = skip;
      return this;
    },
    limit : function(limit){
      this._limit = limit;
      return this;
    },
    sort : function(sort){
      this._sort = sort;
      return this;
    },
    find : function(criteria,fields,options){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._fields    = typeof(fields) == 'undefined' ? [] : fields;
        this._opts      = typeof(options) == 'undefined' ? [] : options;
        this._method    = '_find';
        return this;
    },
    findOne : function(criteria,fields,options){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._fields    = typeof(fields) == 'undefined' ? [] : fields;
        this._opts      = typeof(options) == 'undefined' ? [] : options;
        this._method    = '_findOne';
        return this;
    },

    findById : function(id,fields,options){
        this._id        = id
        this._fields    = typeof(fields) == 'undefined' ? [] : fields;
        this._opts      = typeof(options) == 'undefined' ? [] : options;
        this._method    = '_findById';
        return this;
    },
     create : function(data,callback){
        this._data        = data
        this._method    = '_create';
        return this;
    },
    update : function(criteria,set,callback){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._set       = typeof(set) == 'undefined' ? [] : set;
        this._method    = '_update';
        return this;
    },
    remove : function(criteria,callback){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._method    = '_remove';
        return this;
    },
    count : function(criteria,fields,options){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._method    = '_count';
        return this;
    },
    native : function(callback){
      // local
      var that = this;
      // set up the connection to the local db
      var db = new Db(this.database, new Server(connections.default.host, connections.default.port ));
      // open connection
      db.open(function(e,db) {
         // collection
        var collection = db.collection(that.collection);
        callback(e,db,collection);
      })
    },

    /* Internal methods
    * map of methods mongo native db
    *
    --------------------------------------------------------------------------*/
    _find : function(db,callback){
      try{
        collection = db.collection(this.collection);
        collection.find(this._criteria,this._fields,this._opts).skip(this._skip).limit(this._limit).sort(this._sort).toArray(function(e,r) {
              db.close();
              callback(e,r);
         });
      }catch(e){
        callback(e,null);
      }
    },
     _findOne : function(db,callback){
        var that   = this;
        try{
        collection = db.collection(this.collection);
        collection.find(this._criteria,this._fields,this._opts).limit(1).toArray(function(e,r){
              db.close();
              if(r.length > 0){
                callback(e,that.result(r[0]));
              }else{
                callback(e,that.result({}));
              }

         });
      }catch(e){
        callback(e,null);
      }
    },
    _findById : function(db,callback){
        try{
          collection = db.collection(this.collection);
          collection.find({_id:ObjectID(this._id)},this._fields,this._opts).skip(this._skip).limit(this._limit).sort(this._sort).toArray(function(e,r) {
              db.close();
              callback(e,r);
           });
        }catch(e){
          db.close();
          callback(e,null);
        }
    },
    _create : function(db,callback){
      var that   = this;
      try{
      this._data.createdAt  = new Date();
      this._data.updatedAt  = new Date();
        var collection = db.collection(this.collection);
            collection.insert(this._data,function(e,r) {
            db.close();
            callback(e,r.ops);
        });
      }catch(e){
        db.close();
        callback(e,null);
      }
    },
    _update : function(db,callback){
        var that = this;
        this._set['$set'].updatedAt = new Date();

        try{
          if( typeof(this._criteria) == 'string' ){
              this._criteria = {_id:ObjectID(this._criteria)}
          }
         var collection = db.collection(this.collection);
             collection.update(this._criteria,this._set,function(e,r) {
                if(!e){
                  that._find(db,callback);
                  // db.close();
                }else{
                  db.close();
                  callback(e,r);
                }
          });
        }catch(e){
          db.close();
          callback(e,null);
        }
    },
    _remove : function(db,callback){
       var collection = db.collection(this.collection);
           collection.remove(this._criteria,function(e, r){
           // db.close();
           callback(e,r.result);
      });
    },
    _count : function(db,callback){
      var collection = db.collection(this.collection);
          collection.count(this._criteria,function(e,r) {
          // db.close();
          callback(e,r);
      });
    },
     _save : function(callback){
       var that = this;
      try{
          this.connect(function(db){
              if(db){
                that._set = {$set:that._data};
                that._criteria = {_id:ObjectID(that._data._id)};
                var collection = db.collection(that.collection);
                   collection.update(that._criteria,that._set,function(e,r) {
                    if(!e){
                      callback(e||that._data);
                       // db.close();
                    }else{
                      callback(e,r);
                    }
                });
              }
          });
        }catch(e){
          console.log(e);
          callback(e,null)
        }
    },
    result : function(r){
        that = this;
        Object.defineProperty(r,"save",{
          get: function() {
              that._data = this;
              return function(callback){
                that._save(function(data){
                    callback.call(this,data);
                });
              }
            }
          });
        return r;
    }

}

<commit_msg>services connections<commit_after>/**
* Models.js
*
* @description :: TODO: You might write a short summary of how this model works and what it represents here.
*
* Example
* db.find('skolarapp','users',{ },function(e,d){
*   console.log(d);
* });
*

    #find by id
    Users.tenant('skolarapp').findById('56945402086e30355508472a').exec(function(e,d){
     console.log(d);
    });

    #create
    Users.tenant('skolarapp').create({name:'Saraí León López',email:'sleon90@gmail.com'}).exec(function(e,d){
       console.log(d);
     });

    #update
    Users.tenant('skolarapp').update('56959eb9dcb1e89660795175',{$set:{name:'Saraí León 2'}}).exec(function(e,d){
     console.log(d);
    });

    #remove
    Users.tenant('skolarapp').remove({name:'Saraí León 2'}).exec(function(e,d){
     console.log(d);
    });

    #count
    Users.tenant('skolarapp').count().exec(function(e,d){
     console.log(d);
    });

    #other stuff no supported in tenant
    Users.tenant('skolarapp').native(function(e,db,collection){
          // Group with a conditional
            collection.group([], {}, {"count":0}, "function (obj, prev) { prev.count++; }", false, function(err, results) {
             console.log(results);
            })
    });
*/

var Db            = require('mongodb').Db;
var MongoClient   = require('mongodb').MongoClient;
var ObjectID      = require('mongodb').ObjectID;
var ReplSet       = require('mongodb').ReplSet;
var Server        = require('mongodb').Server;
const assert      = require('assert');
const path        = require('path');
const fs          = require('fs');
const join        = require('path').join;

const adapters    = require(fs.realpathSync('config/connections.js',{}));
const connections = adapters[adapters.default];

var credentials   = typeof(connections.user) && connections.user != '' ? connections.user+':'+connections.password+'@' : '';
const uri         = 'mongodb://'+credentials+connections.host+':'+connections.port+'/';

module.exports = {
    _limit : 0,
    _sort  : {},
    _skip  : 0,
    _data  : {},

    exec:function(callback){
      var that = this;
      this.connect(function(db) {
         that[that._method](db,function(e,r){callback(e,r)});
       });
    },
    connect:function(callback){

      var that = this;
      // Set up the connection to the local db
      var db = new Db(this.database, new Server(connections.host, connections.port ));
      //open connection
      db.open(function(err, db){
        if(!err){
           // Display output in testing mode
           //--------------------------------------------------
          //console.log("Connected to database server:", connections.host);
          callback(err||db);
        }else{

        }
      })
    },
    tenant:function(database){
      this.database = database;
      return this;
    },
    skip :function(skip){
      this._skip = skip;
      return this;
    },
    limit : function(limit){
      this._limit = limit;
      return this;
    },
    sort : function(sort){
      this._sort = sort;
      return this;
    },
    find : function(criteria,fields,options){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._fields    = typeof(fields) == 'undefined' ? [] : fields;
        this._opts      = typeof(options) == 'undefined' ? [] : options;
        this._method    = '_find';
        return this;
    },
    findOne : function(criteria,fields,options){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._fields    = typeof(fields) == 'undefined' ? [] : fields;
        this._opts      = typeof(options) == 'undefined' ? [] : options;
        this._method    = '_findOne';
        return this;
    },

    findById : function(id,fields,options){
        this._id        = id
        this._fields    = typeof(fields) == 'undefined' ? [] : fields;
        this._opts      = typeof(options) == 'undefined' ? [] : options;
        this._method    = '_findById';
        return this;
    },
     create : function(data,callback){
        this._data        = data
        this._method    = '_create';
        return this;
    },
    update : function(criteria,set,callback){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._set       = typeof(set) == 'undefined' ? [] : set;
        this._method    = '_update';
        return this;
    },
    remove : function(criteria,callback){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._method    = '_remove';
        return this;
    },
    count : function(criteria,fields,options){
        this._criteria  = typeof(criteria) == 'undefined' ? [] : criteria;
        this._method    = '_count';
        return this;
    },
    native : function(callback){
      // local
      var that = this;
      // set up the connection to the local db
      var db = new Db(this.database, new Server(connections.host, connections.port ));
      // open connection
      db.open(function(e,db) {
         // collection
        var collection = db.collection(that.collection);
        callback(e,db,collection);
      })
    },

    /* Internal methods
    * map of methods mongo native db
    *
    --------------------------------------------------------------------------*/
    _find : function(db,callback){
      try{
        collection = db.collection(this.collection);
        collection.find(this._criteria,this._fields,this._opts).skip(this._skip).limit(this._limit).sort(this._sort).toArray(function(e,r) {
              db.close();
              callback(e,r);
         });
      }catch(e){
        callback(e,null);
      }
    },
     _findOne : function(db,callback){
        var that   = this;
        try{
        collection = db.collection(this.collection);
        collection.find(this._criteria,this._fields,this._opts).limit(1).toArray(function(e,r){
              db.close();
              if(r.length > 0){
                callback(e,that.result(r[0]));
              }else{
                callback(e,that.result({}));
              }

         });
      }catch(e){
        callback(e,null);
      }
    },
    _findById : function(db,callback){
        try{
          collection = db.collection(this.collection);
          collection.find({_id:ObjectID(this._id)},this._fields,this._opts).skip(this._skip).limit(this._limit).sort(this._sort).toArray(function(e,r) {
              db.close();
              callback(e,r);
           });
        }catch(e){
          db.close();
          callback(e,null);
        }
    },
    _create : function(db,callback){
      var that   = this;
      try{
      this._data.createdAt  = new Date();
      this._data.updatedAt  = new Date();
        var collection = db.collection(this.collection);
            collection.insert(this._data,function(e,r) {
            db.close();
            callback(e,r.ops);
        });
      }catch(e){
        db.close();
        callback(e,null);
      }
    },
    _update : function(db,callback){
        var that = this;
        this._set['$set'].updatedAt = new Date();

        try{
          if( typeof(this._criteria) == 'string' ){
              this._criteria = {_id:ObjectID(this._criteria)}
          }
         var collection = db.collection(this.collection);
             collection.update(this._criteria,this._set,function(e,r) {
                if(!e){
                  that._find(db,callback);
                  // db.close();
                }else{
                  db.close();
                  callback(e,r);
                }
          });
        }catch(e){
          db.close();
          callback(e,null);
        }
    },
    _remove : function(db,callback){
       var collection = db.collection(this.collection);
           collection.remove(this._criteria,function(e, r){
           // db.close();
           callback(e,r.result);
      });
    },
    _count : function(db,callback){
      var collection = db.collection(this.collection);
          collection.count(this._criteria,function(e,r) {
          // db.close();
          callback(e,r);
      });
    },
     _save : function(callback){
       var that = this;
      try{
          this.connect(function(db){
              if(db){
                that._set = {$set:that._data};
                that._criteria = {_id:ObjectID(that._data._id)};
                var collection = db.collection(that.collection);
                   collection.update(that._criteria,that._set,function(e,r) {
                    if(!e){
                      callback(e||that._data);
                       // db.close();
                    }else{
                      callback(e,r);
                    }
                });
              }
          });
        }catch(e){
          console.log(e);
          callback(e,null)
        }
    },
    result : function(r){
        that = this;
        Object.defineProperty(r,"save",{
          get: function() {
              that._data = this;
              return function(callback){
                that._save(function(data){
                    callback.call(this,data);
                });
              }
            }
          });
        return r;
    }

}

<|endoftext|>


<commit_before>/* global phantom, require */

var fs = require( 'fs' );
var shouldAbort = true;

/*
	Parse parameters
*/

var casper = require( 'casper' ).create( {
	verbose: false,
	logLevel: 'debug',
	onStepTimeout: function _onStepTimeout(timeout, stepNum) {
		this.warn("Maximum step execution timeout exceeded for step " + stepNum);
	},
	onTimeout: function _onTimeout(timeout) {
		this.warn("Script timeout of " + timeout + "ms reached, exiting.");
	},
	onWaitTimeout: function _onWaitTimeout(timeout) {
		this.warn("Wait timeout of " + timeout + "ms expired, exiting.");
	},
	waitTimeout: 10000
} );

var debug = Number( casper.cli.get( 'flowdebug' ) ) || 0; //0|1|2

var includes = casper.cli.get( 'flowincludes' ) || "";
var testRoot = casper.cli.get( 'flowtestsroot' ) || "";
var libraryRoot = casper.cli.get( 'flowlibraryroot' ) || "";
var phantomCSSRoot = casper.cli.get( 'flowphantomcssroot' ) || "";
var files = casper.cli.get( 'flowtests' ) || "";
var novisuals = casper.cli.get( 'novisuals' );
var hideElements = casper.cli.get('hideelements');
var mismatchTolerance = casper.cli.get('mismatchTolerance');

var treeOutputRoot = casper.cli.get( 'flowoutputroot' ); // see phantomFlowAdaptor
var xUnitOutputRoot = casper.cli.get( 'flowxunitoutputroot' ); // see xUnit.js

var visualDebugRoot = casper.cli.get( 'flowvisualdebugroot' ); // see phantomFlowAdaptor

var visualTestsRoot = casper.cli.get( 'flowvisualstestroot' ); // see phantomCSSAdaptor
var visualResultsRoot = casper.cli.get( 'flowvisualsoutputroot' ); // see phantomCSSAdaptor

var emptyPage = pathJoin( [ libraryRoot, 'empty.html' ] );

/*
	Setup CasperJS
*/

casper.options.pageSettings = {
	loadImages: true, // Must be true for PhantomCSS to work
	loadPlugins: false,
	XSSAuditingEnabled: true,
	localToRemoteUrlAccessEnabled: true
};

if( debug >= 1 ) {
    casper.on( 'page.error', function( msg, trace ) {
        this.echo( 'Page JS Error: ' + JSON.stringify( msg ), 'ERROR');
    });

    casper.on( 'remote.message', function( msg ) {
        this.echo( 'Log: ' + JSON.stringify( msg ) );
    });

    casper.on( 'resource.error', function( resourceError ){
       this.echo( 'Resource Error: ' + JSON.stringify( resourceError, null, 2 ), 'ERROR');
    });

    casper.on( 'url.changed', function( newUrl ){
        this.echo( 'URL Changed:' + JSON.stringify( newUrl ) );
    });
}

/*
	Include core dependencies
*/

console.log( pathJoin( [ libraryRoot, 'phantomFlow.js' ] ) );

var phantomCSS = require( pathJoin( [ phantomCSSRoot, 'phantomcss.js' ] ) );
var phantomFlow = require( pathJoin( [ libraryRoot, 'phantomFlow.js' ] ) );

phantom.injectJs( pathJoin( [ libraryRoot, 'phantomCSSAdaptor.js' ] ) );
phantom.injectJs( pathJoin( [ libraryRoot, 'phantomFlowAdaptor.js' ] ) );
phantom.injectJs( pathJoin( [ libraryRoot, 'xUnit.js' ] ) );

/*
	Include custom dependencies
*/

findIncludes( includes );

/*
	Start Casper
*/

casper.start( /* 'http://localhost:9001/empty.html' */); // start before all else

casper.thenOpen( emptyPage );

/*
	Inject tests
*/

if ( files ) {
	injectTests( files );
} else {
	//findTests( testRoot );
	console.log( 'FAIL there are no tests to run!' );
}

casper.then( function () {

	console.log( 'TESTFILE', 'PhantomCSS' );
	casper.emit( 'test.source', {
		name: 'PhantomCSS'
	} );

	shouldAbort = false;

	if ( !novisuals ) {
		phantomCSS.compareSession();
	}

} );

/*
	Run the tests
*/

casper.
run( function () {
	console.log( '\n' );
	console.log( '\nFini.' );
	phantom.exit( 0 );
} );

/*
	Helper methods
*/

function associateFileNameWithTest( path ) {
	casper.then( function () {
		console.log( 'TESTFILE', path );
		casper.emit( 'test.source', {
			name: path
		} );
	} );
}

function correctSeparators( str ) {
	return str.replace( /\//g, fs.separator );
}

function injectTests( files ) {
	files = files.split( ',' );
	if ( files.length !== 0 ) {
		files.forEach( function ( file ) {
			var rootedFile = testRoot + '/' + file;
			if ( fs.isFile( rootedFile ) ) {
				associateFileNameWithTest( file );
				phantom.injectJs( rootedFile );
			}
		} );
	}
}

function findIncludes( root ) {
	fs.list( root ).forEach( function ( item ) {
		var path = root + '/' + item;
		if ( ( item === '.' ) || ( item === '..' ) ) {
			return;
		}
		if ( fs.isDirectory( path ) ) {
			findIncludes( path );
			return;
		}
		if ( /.js/.test( item.toLowerCase() ) ) {
			phantom.injectJs( path );
			return;
		}
	} );
}

function pathJoin( arr ) {
	return arr.join( '/' /*fs.separator*/ );
}<commit_msg>Errors on page fail tests<commit_after>/* global phantom, require */

var fs = require( 'fs' );
var shouldAbort = true;

/*
	Parse parameters
*/

var casper = require( 'casper' ).create( {
	verbose: false,
	logLevel: 'debug',
	onStepTimeout: function _onStepTimeout(timeout, stepNum) {
		this.warn("Maximum step execution timeout exceeded for step " + stepNum);
	},
	onTimeout: function _onTimeout(timeout) {
		this.warn("Script timeout of " + timeout + "ms reached, exiting.");
	},
	onWaitTimeout: function _onWaitTimeout(timeout) {
		this.warn("Wait timeout of " + timeout + "ms expired, exiting.");
	},
	waitTimeout: 10000
} );

var debug = Number( casper.cli.get( 'flowdebug' ) ) || 0; //0|1|2

var includes = casper.cli.get( 'flowincludes' ) || "";
var testRoot = casper.cli.get( 'flowtestsroot' ) || "";
var libraryRoot = casper.cli.get( 'flowlibraryroot' ) || "";
var phantomCSSRoot = casper.cli.get( 'flowphantomcssroot' ) || "";
var files = casper.cli.get( 'flowtests' ) || "";
var novisuals = casper.cli.get( 'novisuals' );
var hideElements = casper.cli.get('hideelements');
var mismatchTolerance = casper.cli.get('mismatchTolerance');

var treeOutputRoot = casper.cli.get( 'flowoutputroot' ); // see phantomFlowAdaptor
var xUnitOutputRoot = casper.cli.get( 'flowxunitoutputroot' ); // see xUnit.js

var visualDebugRoot = casper.cli.get( 'flowvisualdebugroot' ); // see phantomFlowAdaptor

var visualTestsRoot = casper.cli.get( 'flowvisualstestroot' ); // see phantomCSSAdaptor
var visualResultsRoot = casper.cli.get( 'flowvisualsoutputroot' ); // see phantomCSSAdaptor

var emptyPage = pathJoin( [ libraryRoot, 'empty.html' ] );

/*
	Setup CasperJS
*/

casper.options.pageSettings = {
	loadImages: true, // Must be true for PhantomCSS to work
	loadPlugins: false,
	XSSAuditingEnabled: true,
	localToRemoteUrlAccessEnabled: true
};

casper.on( 'page.error', function( msg, trace ) {
    this.echo( 'FAIL Page JS Error: ' + JSON.stringify( msg ), 'ERROR');
});

if( debug >= 1 ) {
    casper.on( 'remote.message', function( msg ) {
        this.echo( 'Log: ' + JSON.stringify( msg ) );
    });

    casper.on( 'resource.error', function( resourceError ){
       this.echo( 'Resource Error: ' + JSON.stringify( resourceError, null, 2 ), 'ERROR');
    });

    casper.on( 'url.changed', function( newUrl ){
        this.echo( 'URL Changed:' + JSON.stringify( newUrl ) );
    });
}

/*
	Include core dependencies
*/

console.log( pathJoin( [ libraryRoot, 'phantomFlow.js' ] ) );

var phantomCSS = require( pathJoin( [ phantomCSSRoot, 'phantomcss.js' ] ) );
var phantomFlow = require( pathJoin( [ libraryRoot, 'phantomFlow.js' ] ) );

phantom.injectJs( pathJoin( [ libraryRoot, 'phantomCSSAdaptor.js' ] ) );
phantom.injectJs( pathJoin( [ libraryRoot, 'phantomFlowAdaptor.js' ] ) );
phantom.injectJs( pathJoin( [ libraryRoot, 'xUnit.js' ] ) );

/*
	Include custom dependencies
*/

findIncludes( includes );

/*
	Start Casper
*/

casper.start( /* 'http://localhost:9001/empty.html' */); // start before all else

casper.thenOpen( emptyPage );

/*
	Inject tests
*/

if ( files ) {
	injectTests( files );
} else {
	//findTests( testRoot );
	console.log( 'FAIL there are no tests to run!' );
}

casper.then( function () {

	console.log( 'TESTFILE', 'PhantomCSS' );
	casper.emit( 'test.source', {
		name: 'PhantomCSS'
	} );

	shouldAbort = false;

	if ( !novisuals ) {
		phantomCSS.compareSession();
	}

} );

/*
	Run the tests
*/

casper.
run( function () {
	console.log( '\n' );
	console.log( '\nFini.' );
	phantom.exit( 0 );
} );

/*
	Helper methods
*/

function associateFileNameWithTest( path ) {
	casper.then( function () {
		console.log( 'TESTFILE', path );
		casper.emit( 'test.source', {
			name: path
		} );
	} );
}

function correctSeparators( str ) {
	return str.replace( /\//g, fs.separator );
}

function injectTests( files ) {
	files = files.split( ',' );
	if ( files.length !== 0 ) {
		files.forEach( function ( file ) {
			var rootedFile = testRoot + '/' + file;
			if ( fs.isFile( rootedFile ) ) {
				associateFileNameWithTest( file );
				phantom.injectJs( rootedFile );
			}
		} );
	}
}

function findIncludes( root ) {
	fs.list( root ).forEach( function ( item ) {
		var path = root + '/' + item;
		if ( ( item === '.' ) || ( item === '..' ) ) {
			return;
		}
		if ( fs.isDirectory( path ) ) {
			findIncludes( path );
			return;
		}
		if ( /.js/.test( item.toLowerCase() ) ) {
			phantom.injectJs( path );
			return;
		}
	} );
}

function pathJoin( arr ) {
	return arr.join( '/' /*fs.separator*/ );
}<|endoftext|>


<commit_before>"use strict";

const leap = require('../lib/isLeap.js');
const zellers = require('../lib/zeller.js');
const _ = require('lodash');

function howManyDays (year, month) {
  const toLeap = leap.leapYear(year);
  let manyDays = 31;

  if (month === 4 ||
      month === 6 ||
      month === 9 ||
      month === 11) {
    manyDays = 30;
  } else if (month === 2) {
    if (toLeap) {
      manyDays = 29;
    } else {
      manyDays = 28;
    }
  }

  return manyDays;
}

function weeks (year, month) {
  const days = howManyDays(year, month);
  const startDay = zellers.getDay(year, month, 1);

  let numweeks = Math.ceil( (days + startDay) / 7);

  return numweeks;
}

//Spaces on left should be based on the ratio of half the month + year length to get 20 characters
//September = 9 + 1space + 2016 = 4 === 14, so 3 spaces needed to center it?
//function monthHeaderSpace (year, month, os) {
function createMonthHeader (year, month, os) {
  const allMonths = ['January', 'February', 'March', 'April', 'May', ' June', ' July', 'August', 'September', 'October', ' November', ' December'];
  let thisMonth = allMonths[month-1];

  var base = `${thisMonth} ${year}`;
  var lspace = Math.floor((20 - base.length) / 2);
  var rspace = Math.ceil((20 - base.length) / 2);
  var lspacer = ' '.repeat(lspace);
  var rspacer = ' '.repeat(rspace) + '  ';
  var monthHeader;
  if (os === 'darwin') {
    monthHeader = `${lspacer}${base}\n`;
  } else {
    monthHeader = `${lspacer}${base}${rspacer}\n`;
  }

  return monthHeader;
}

//Day columns are always 20 characters wide
function printDayColumns (os) {
  var extraSpace;
  if (os === 'darwin') {
    extraSpace = ``;
  } else {
    extraSpace = `  `;
  }

  return `Su Mo Tu We Th Fr Sa${extraSpace}`;
}

function rowPrint (rowsByWeeks, os) {
  let numweeks = rowsByWeeks.length
  let calBody = '';
  var extraSpace;
  if (os === 'darwin') {
    extraSpace = ``;
  } else {
    extraSpace = `  `;
  }

  for (var i = 0; i < numweeks; i++) {
    calBody += `${rowsByWeeks[i].join(' ')}${extraSpace}`;

    if (os === 'darwin') {
      calBody = calBody.replace(/\s*$/,"");
    }

    if (i < numweeks) {
      calBody += `\n`;
    }

    if (os !== 'darwin' && i === numweeks) {
      calBody += `\n`;
    }

  }

  return calBody;

}

function createWeeks (year, month, os) {
  const days = howManyDays(year, month);
  const startDay = zellers.getDay(year, month, 1);
  let arraysForDays = [];
  var i = 0;
  var d = new Date();
  var n = d.getDate();
  var m = d.getMonth();
  var bold;

  for (i = 0; i < days; i++) {
    if (os !== 'darwin' && (n === i+1) && (month === m+1)) {
      bold = `\b`;
    } else {
      bold = ``;
    }

    if (i < 9) {
      arraysForDays[i] = `${bold} ${bold}${i+1}`;
    } else {
      arraysForDays[i] = `${bold}${i+1}`;
    }
  }

  for (i = 0; i < startDay; i++) {
    arraysForDays.unshift('  ');
  }

  var newIndex = arraysForDays.length;

  for (i = newIndex; i < 42; i++) {
    arraysForDays.push('  ');
  }

  return _.chunk(arraysForDays, 7);
}

function joinOutput (year, month, os) {
  let theMonth = createWeeks(year, month, os);
  let part = printDayColumns(os);
  let output = createMonthHeader(year, month, os);
  output += `${part}\n`;
  output += rowPrint(theMonth, os);
//  console.log(monthHeaderSpace(year, month, os));
  return output;
}

module.exports = {
  createWeeks: createWeeks,
  createMonthHeader: createMonthHeader,
  printDayColumns: printDayColumns,
  joinOutput: joinOutput,
  weeks: weeks,
  howManyDays: howManyDays,
  rowPrint: rowPrint
  }
<commit_msg>does this bold words or characters?<commit_after>"use strict";

const leap = require('../lib/isLeap.js');
const zellers = require('../lib/zeller.js');
const _ = require('lodash');

function howManyDays (year, month) {
  const toLeap = leap.leapYear(year);
  let manyDays = 31;

  if (month === 4 ||
      month === 6 ||
      month === 9 ||
      month === 11) {
    manyDays = 30;
  } else if (month === 2) {
    if (toLeap) {
      manyDays = 29;
    } else {
      manyDays = 28;
    }
  }

  return manyDays;
}

function weeks (year, month) {
  const days = howManyDays(year, month);
  const startDay = zellers.getDay(year, month, 1);

  let numweeks = Math.ceil( (days + startDay) / 7);

  return numweeks;
}

//Spaces on left should be based on the ratio of half the month + year length to get 20 characters
//September = 9 + 1space + 2016 = 4 === 14, so 3 spaces needed to center it?
//function monthHeaderSpace (year, month, os) {
function createMonthHeader (year, month, os) {
  const allMonths = ['January', 'February', 'March', 'April', 'May', ' June', ' July', 'August', 'September', 'October', ' November', ' December'];
  let thisMonth = allMonths[month-1];

  var base = `${thisMonth} ${year}`;
  var lspace = Math.floor((20 - base.length) / 2);
  var rspace = Math.ceil((20 - base.length) / 2);
  var lspacer = ' '.repeat(lspace);
  var rspacer = ' '.repeat(rspace) + '  ';
  var monthHeader;
  if (os === 'darwin') {
    monthHeader = `${lspacer}${base}\n`;
  } else {
    monthHeader = `${lspacer}${base}${rspacer}\n`;
  }

  return monthHeader;
}

//Day columns are always 20 characters wide
function printDayColumns (os) {
  var extraSpace;
  if (os === 'darwin') {
    extraSpace = ``;
  } else {
    extraSpace = `  `;
  }

  return `Su Mo Tu We Th Fr Sa${extraSpace}`;
}

function rowPrint (rowsByWeeks, os) {
  let numweeks = rowsByWeeks.length
  let calBody = '';
  var extraSpace;
  if (os === 'darwin') {
    extraSpace = ``;
  } else {
    extraSpace = `  `;
  }

  for (var i = 0; i < numweeks; i++) {
    calBody += `${rowsByWeeks[i].join(' ')}${extraSpace}`;

    if (os === 'darwin') {
      calBody = calBody.replace(/\s*$/,"");
    }

    if (i < numweeks) {
      calBody += `\n`;
    }

//    if (os !== 'darwin' && i === numweeks) {
//      calBody += `\n`;
//    }

  }

  return calBody;

}

function createWeeks (year, month, os) {
  const days = howManyDays(year, month);
  const startDay = zellers.getDay(year, month, 1);
  let arraysForDays = [];
  var i = 0;
  var d = new Date();
  var n = d.getDate();
  var m = d.getMonth();
  var bold;

  for (i = 0; i < days; i++) {
    if (os !== 'darwin' && (n === i+1) && (month === m+1)) {
      bold = `_\b`;
    } else {
      bold = ``;
    }

    if (i < 9) {
      arraysForDays[i] = `${bold} ${bold}${i+1}`;
    } else {
      arraysForDays[i] = `${bold}${i+1}`;
    }
  }

  for (i = 0; i < startDay; i++) {
    arraysForDays.unshift('  ');
  }

  var newIndex = arraysForDays.length;

  for (i = newIndex; i < 42; i++) {
    arraysForDays.push('  ');
  }

  return _.chunk(arraysForDays, 7);
}

function joinOutput (year, month, os) {
  let theMonth = createWeeks(year, month, os);
  let part = printDayColumns(os);
  let output = createMonthHeader(year, month, os);
  output += `${part}\n`;
  output += rowPrint(theMonth, os);
//  console.log(monthHeaderSpace(year, month, os));
  return output;
}

module.exports = {
  createWeeks: createWeeks,
  createMonthHeader: createMonthHeader,
  printDayColumns: printDayColumns,
  joinOutput: joinOutput,
  weeks: weeks,
  howManyDays: howManyDays,
  rowPrint: rowPrint
  }
<|endoftext|>