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

/**
 * Context Support
 *
 * Contexts, also known as frames, scopes or environments, are used to store
 * named resources. They provide an object-oriented replacement for global
 * variables. Contexts are immutable. New bindings are added by creating
 * "sub-contexts" with new bindings, from an existing parent context.
 * Sub-contexts inherit bindings from their parent.
 *
 * Contexts provide a form of inversion-of-control or dependendency-injection.
 * Normally, contexts are not explicitly used because FOAM's imports/exports
 * mechanism provides a high-level declarative method of dependency management
 * which hides their use.
 *
 * foam.__context__ references the root context, which is the ancestor of all other
 * contexts.
 */

(function() {
  var __context__ = {
    /**
     * Lookup a class in the context.  Throws an exception if the value
     * couldn't be found, unless opt_suppress is true.
     *
     * @param id The id of the class to lookup.
     * @param opt_suppress Suppress throwing an error.
     **/
    lookup: function(id, opt_suppress) {
      var ret = typeof id === 'string' && this.__cache__[id];

      if ( ! opt_suppress ) {
        foam.assert(
            ret,
            'Could not find any registered class for ' + id);
      }

      return foam.Function.isInstance(ret) ? ret() : ret;
    },

    /**
     * Register a class into the given context.  After registration
     * the class can be found again by calling foam.lookup('com.foo.SomeClass');
     *
     * @param cls    The class to register.
     * @param opt_id Optional id under which to register class.
     */
    register: function(cls, opt_id) {
      foam.assert(
        typeof cls === 'object',
        'Cannot register non-objects into a context.');

      if ( opt_id ) {
        this.registerInCache_(cls, this.__cache__, opt_id);
      } else {
        foam.assert(
            typeof cls.id === 'string',
            'Must have an .id property to be registered in a context.');

        this.registerInCache_(cls, this.__cache__, cls.id);

        if ( cls.package === 'foam.core' ) {
          this.registerInCache_(cls, this.__cache__, cls.name);
        }
      }
    },

    /**
     * Register a class factory into the given context.
     * When the class is first accessed the factory is used
     * to create the value which is used.
     */
    registerFactory: function(m, factory) {
      this.registerInCache_(factory, this.__cache__, m.id);

      if ( m.package === 'foam.core' ) {
        this.registerInCache_(factory, this.__cache__, m.name);
      }
    },

    /** Internal method to register a context binding in an internal cache */
    registerInCache_: function registerInCache_(cls, cache, name) {
      var hasOld = Object.prototype.hasOwnProperty.call(cache, name);
      var old = cache[name];

      // Okay to replace a function with an actual class.
      // This happens after a lazy class is initialized.
      foam.assert(
          ! hasOld ||
              (foam.Function.isInstance(old) && ! foam.Function.isInstance(cls)),
          cls.id + ' is already registered in this context.');

      cache[name] = cls;
    },

    /** Internal method to create a slot name for a specified key. */
    toSlotName_: foam.Function.memoize1(function toSlotName_(key) {
      return key + '$';
    }),

    /**
     * Creates a sub context of the context that this is called upon.
     * @param opt_args A map of bindings to set up in the sub context.
     *     Currently unused.
     */
    createSubContext: function createSubContext(opt_args, opt_name) {
      if ( ! opt_args ) return this;

      foam.assert(
          opt_name === undefined || typeof opt_name === 'string',
          'opt_name must be left undefined or be a string.');

      var sub = Object.create(this);

      if ( opt_name ) {
        Object.defineProperty(sub, 'NAME', {
          value: opt_name,
          enumerable: false
        });
      }

      for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var v = opt_args[key];

          if ( ! foam.core.Slot.isInstance(v) ) {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: foam.core.ConstantSlot.create({ value: v })
            });

            Object.defineProperty(sub, key, {
              value: v
            });
          } else {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: v
            });

            (function(v) {
              Object.defineProperty(sub, key, {
                get: function() { return v.get(); },
                enumerable: false
              });
            })(v);
          }
        }
      }

      Object.defineProperty(sub, '__cache__', {
        value: Object.create(this.__cache__),
        enumerable: false
      });

      foam.Object.freeze(sub);

      return sub;
    }
  };

  Object.defineProperty(__context__, '__cache__', {
    value: {},
    enumerable: false
  });

  // Create short-cuts for foam.__context__.[createSubContext, register, lookup]
  // in foam.
  foam.lookup = function(id, opt_suppress) {
    return foam.__context__.lookup(id, opt_suppress);
  };
  foam.register = function(cls) { foam.__context__.register(cls); };
  foam.createSubContext = function(opt_args, opt_name) {
    return foam.__context__.createSubContext(opt_args, opt_name);
  };

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

/**
 * Context Support
 *
 * Contexts, also known as frames, scopes or environments, are used to store
 * named resources. They provide an object-oriented replacement for global
 * variables. Contexts are immutable. New bindings are added by creating
 * "sub-contexts" with new bindings, from an existing parent context.
 * Sub-contexts inherit bindings from their parent.
 *
 * Contexts provide a form of inversion-of-control or dependendency-injection.
 * Normally, contexts are not explicitly used because FOAM's imports/exports
 * mechanism provides a high-level declarative method of dependency management
 * which hides their use.
 *
 * foam.__context__ references the root context, which is the ancestor of all other
 * contexts.
 */

(function() {
  var __context__ = {
    /**
     * Lookup a class in the context.  Throws an exception if the value
     * couldn't be found, unless opt_suppress is true.
     *
     * @param id The id of the class to lookup.
     * @param opt_suppress Suppress throwing an error.
     **/
    lookup: function(id, opt_suppress) {
      var ret = typeof id === 'string' && this.__cache__[id];

      if ( ! opt_suppress ) {
        foam.assert(
            ret,
            'Could not find any registered class for ' + id);
      }

      return foam.Function.isInstance(ret) ? ret() : ret;
    },

    /**
     * Register a class into the given context.  After registration
     * the class can be found again by calling foam.lookup('com.foo.SomeClass');
     *
     * @param cls    The class to register.
     * @param opt_id Optional id under which to register class.
     */
    register: function(cls, opt_id) {
      foam.assert(
        typeof cls === 'object',
        'Cannot register non-objects into a context.');

      if ( opt_id ) {
        this.registerInCache_(cls, this.__cache__, opt_id);
      } else {
        foam.assert(
            typeof cls.id === 'string',
            'Must have an .id property to be registered in a context.');

        this.registerInCache_(cls, this.__cache__, cls.id);

        if ( cls.package === 'foam.core' ) {
          this.registerInCache_(cls, this.__cache__, cls.name);
        }
      }
    },

    /**
     * Register a class factory into the given context.
     * When the class is first accessed the factory is used
     * to create the value which is used.
     */
    registerFactory: function(m, factory) {
      this.registerInCache_(factory, this.__cache__, m.id);

      if ( m.package === 'foam.core' ) {
        this.registerInCache_(factory, this.__cache__, m.name);
      }
    },

    /**
     * Returns true if the model ID has been registered. False otherwise.
     */
    isRegistered: function(modelId) {
      return !!this.__cache__[modelId];
    },

    /** Internal method to register a context binding in an internal cache */
    registerInCache_: function registerInCache_(cls, cache, name) {
      var hasOld = Object.prototype.hasOwnProperty.call(cache, name);
      var old = cache[name];

      // Okay to replace a function with an actual class.
      // This happens after a lazy class is initialized.
      foam.assert(
          ! hasOld ||
              (foam.Function.isInstance(old) && ! foam.Function.isInstance(cls)),
          cls.id + ' is already registered in this context.');

      cache[name] = cls;
    },

    /** Internal method to create a slot name for a specified key. */
    toSlotName_: foam.Function.memoize1(function toSlotName_(key) {
      return key + '$';
    }),

    /**
     * Creates a sub context of the context that this is called upon.
     * @param opt_args A map of bindings to set up in the sub context.
     *     Currently unused.
     */
    createSubContext: function createSubContext(opt_args, opt_name) {
      if ( ! opt_args ) return this;

      foam.assert(
          opt_name === undefined || typeof opt_name === 'string',
          'opt_name must be left undefined or be a string.');

      var sub = Object.create(this);

      if ( opt_name ) {
        Object.defineProperty(sub, 'NAME', {
          value: opt_name,
          enumerable: false
        });
      }

      for ( var key in opt_args ) {
        if ( opt_args.hasOwnProperty(key) ) {
          var v = opt_args[key];

          if ( ! foam.core.Slot.isInstance(v) ) {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: foam.core.ConstantSlot.create({ value: v })
            });

            Object.defineProperty(sub, key, {
              value: v
            });
          } else {
            Object.defineProperty(sub, this.toSlotName_(key), {
              value: v
            });

            (function(v) {
              Object.defineProperty(sub, key, {
                get: function() { return v.get(); },
                enumerable: false
              });
            })(v);
          }
        }
      }

      Object.defineProperty(sub, '__cache__', {
        value: Object.create(this.__cache__),
        enumerable: false
      });

      foam.Object.freeze(sub);

      return sub;
    }
  };

  Object.defineProperty(__context__, '__cache__', {
    value: {},
    enumerable: false
  });

  // Create short-cuts for foam.__context__.[createSubContext, register, lookup]
  // in foam.
  foam.lookup = function(id, opt_suppress) {
    return foam.__context__.lookup(id, opt_suppress);
  };
  foam.register = function(cls) { foam.__context__.register(cls); };
  foam.createSubContext = function(opt_args, opt_name) {
    return foam.__context__.createSubContext(opt_args, opt_name);
  };

  foam.__context__ = __context__;
})();
<|endoftext|>


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

foam.CLASS({
  package: 'foam.u2',
  name: 'TextField',
  extends: 'foam.u2.tag.Input',

  axioms: [
    foam.u2.CSS.create({
      code: '^:read-only { border: none; background: rgba(0,0,0,0); }'
    })
  ],

  properties: [
    {
      class: 'Int',
      name: 'displayWidth'
    }
  ],

  methods: [
    function fromProperty(prop) {
      this.SUPER(prop);

      if ( ! this.displayWidth ) {
        this.displayWidth = prop.displayWidth;
      }

      if ( prop.visibility ) {
        this.visibility = prop.visibility;
      }
    }
  ]
});
<commit_msg>Set size from displayWidth in TextField.<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'TextField',
  extends: 'foam.u2.tag.Input',

  axioms: [
    foam.u2.CSS.create({
      code: '^:read-only { border: none; background: rgba(0,0,0,0); }'
    })
  ],

  properties: [
    {
      class: 'Int',
      name: 'displayWidth'
    }
  ],

  methods: [
    function fromProperty(prop) {
      this.SUPER(prop);

      if ( ! this.displayWidth ) {
        this.size = this.displayWidth = prop.displayWidth;
      }

      if ( prop.visibility ) {
        this.visibility = prop.visibility;
      }
    }
  ]
});
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import cn from 'classnames';
import _ from 'lodash';
import SelectRow from './SelectRow';

const propTypes = {
  selectable: PropTypes.bool,
  selectEnabled: PropTypes.func,
  row: PropTypes.object.isRequired,
  headers: PropTypes.object,
  columns: PropTypes.array.isRequired,
  CheckboxComponent: PropTypes.func,
  editable: PropTypes.bool,
  onChange: PropTypes.func,
  primaryKey: PropTypes.string,
};

const resolveProps = (row, componentProps, tableProps) => {
  if (!componentProps) {
    return {};
  } else if (_.isFunction(componentProps)) {
    return componentProps(row, tableProps);
  } else if (_.isObject(componentProps)) {
    return componentProps;
  }
  throw new Error('componentProps should be object or function!');
};

class TableRow extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: '',
      ...this.setInitialState(),
    };
  }

  onCellChange(key, value) {
    this.setState(prevState => ({
      editingRow: {
        ...prevState.editingRow,
        [key]: value,
      },
    }));
  }

  onCancelEdit() {
    this.setState({ editingRowId: null });
  }

  setInitialState() {
    let editingRow = null;
    let editingRowId = null;
    for (const [, value] of Object.entries(this.props.row)) {
      if (value === '') {
        editingRow = this.props.row;
        editingRowId = this.props.row[this.props.primaryKey];
      }
    }
    return (
      { editingRow, editingRowId }
    );
  }

  saveCell(row) {
    this.props.onChange(row);
    this.setState({ editingRowId: null });
  }

  editRow(cellValue, rowId, row) {
    this.setState({
      editingRowId: rowId,
      editingRow: row,
      value: cellValue,
    });
  }

  renderCellContent(col, row, otherProps, editable) {
    if (row.id === this.state.editingRowId && col.EditComponent) {
      return (
        <col.EditComponent
          value={this.state.editingRow[col.key]}
          onChange={(e) => this.onCellChange(col.key, e.target.value)}
        />
      );
    } else if (col.Component) {
      return (
        <col.Component
          row={row}
          key={col.key}
          {...resolveProps(row, col.componentProps, otherProps)}
        >
          {_.get(row, col.key)}
        </col.Component>
      );
    }
    return (

 editable && this.editRow(_.get(row, col.key), row.id, row)}
      >
        {_.get(row, col.key)}

    );
  }
  render() {
    const {
      row,
      selectable,
      selectEnabled,
      headers,
      columns,
      editable,
      CheckboxComponent,
      ...otherProps
    } = this.props;
    const select = headers && headers.select;
    const visibleColumns = columns.filter((c) => !c.hidden);
    let className = '';

    if (selectable && !select) {
      throw new Error('`headers` must be provided with `headers.select` when `selectable` is true');
    }

    if (selectable && select.isSelected(row)) {
      className = 'table-info';
    }
    const isEditingClass = this.state.editingRowId ? 'editing' : null;
    return (
      <React.Fragment>

          {selectable &&

              <SelectRow
                row={row}
                isEnabled={selectEnabled}
                CheckboxComponent={CheckboxComponent}
                {...select}
              />

          }
          {visibleColumns.map((col) => (

              {this.renderCellContent(col, row, otherProps, editable && col.EditComponent)}
            	))}

        {this.state.editingRowId &&

              <button
                className="btn btn-primary"
                onClick={() => this.saveCell(this.state.editingRow)}
              >Save</button>
              <button
                className="btn btn-secundary"
                onClick={() => this.onCancelEdit()}
              >Cancel</button>

        }
      </React.Fragment>
    );
  }
}
TableRow.propTypes = propTypes;

export default TableRow;
<commit_msg>Added the ability to edit custom components.<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import cn from 'classnames';
import _ from 'lodash';
import SelectRow from './SelectRow';

const propTypes = {
  selectable: PropTypes.bool,
  selectEnabled: PropTypes.func,
  row: PropTypes.object.isRequired,
  headers: PropTypes.object,
  columns: PropTypes.array.isRequired,
  CheckboxComponent: PropTypes.func,
  editable: PropTypes.bool,
  onChange: PropTypes.func,
  primaryKey: PropTypes.string,
};

const resolveProps = (row, componentProps, tableProps) => {
  if (!componentProps) {
    return {};
  } else if (_.isFunction(componentProps)) {
    return componentProps(row, tableProps);
  } else if (_.isObject(componentProps)) {
    return componentProps;
  }
  throw new Error('componentProps should be object or function!');
};

class TableRow extends Component {
  constructor(props) {
    super(props);

    this.state = {
      value: '',
      ...this.setInitialState(),
    };
  }

  onCellChange(key, value) {
    this.setState(prevState => ({
      editingRow: {
        ...prevState.editingRow,
        [key]: value,
      },
    }));
  }

  onCancelEdit() {
    this.setState({ editingRowId: null });
  }

  setInitialState() {
    let editingRow = null;
    let editingRowId = null;
    for (const [, value] of Object.entries(this.props.row)) {
      if (value === '') {
        editingRow = this.props.row;
        editingRowId = this.props.row[this.props.primaryKey];
      }
    }
    return (
      { editingRow, editingRowId }
    );
  }

  saveCell(row) {
    this.props.onChange(row);
    this.setState({ editingRowId: null });
  }

  editRow(cellValue, rowId, row) {
    this.setState({
      editingRowId: rowId,
      editingRow: row,
      value: cellValue,
    });
  }

  renderCellContent(col, row, otherProps, editable) {
    if (row.id === this.state.editingRowId && col.EditComponent) {
      return (
        <col.EditComponent
          value={this.state.editingRow[col.key]}
          onChange={(e) => this.onCellChange(col.key, e.target.value)}
          {...resolveProps(row, col.editComponentProps, otherProps)}
        />
      );
    } else if (col.Component) {
      return (
        <col.Component
          row={row}
          key={col.key}
          className={cn({ editable })}
          onClick={() => editable && this.editRow(_.get(row, col.key), row.id, row)}
          {...resolveProps(row, col.componentProps, otherProps)}
        >
          {_.get(row, col.key)}
        </col.Component>
      );
    }
    return (

 editable && this.editRow(_.get(row, col.key), row.id, row)}
      >
        {_.get(row, col.key)}

    );
  }
  render() {
    const {
      row,
      selectable,
      selectEnabled,
      headers,
      columns,
      editable,
      CheckboxComponent,
      ...otherProps
    } = this.props;
    const select = headers && headers.select;
    const visibleColumns = columns.filter((c) => !c.hidden);
    let className = '';

    if (selectable && !select) {
      throw new Error('`headers` must be provided with `headers.select` when `selectable` is true');
    }

    if (selectable && select.isSelected(row)) {
      className = 'table-info';
    }
    const isEditingClass = this.state.editingRowId ? 'editing' : null;
    return (
      <React.Fragment>

          {selectable &&

              <SelectRow
                row={row}
                isEnabled={selectEnabled}
                CheckboxComponent={CheckboxComponent}
                {...select}
              />

          }
          {visibleColumns.map((col) => (

              {this.renderCellContent(col, row, otherProps, editable && col.EditComponent)}
            	))}

        {this.state.editingRowId &&

              <button
                className="btn btn-primary"
                onClick={() => this.saveCell(this.state.editingRow)}
              >Save</button>
              <button
                className="btn btn-secundary"
                onClick={() => this.onCancelEdit()}
              >Cancel</button>

        }
      </React.Fragment>
    );
  }
}
TableRow.propTypes = propTypes;

export default TableRow;
<|endoftext|>


<commit_before>const { Mixin } = require('hops-mixin');
const {
  uri: { resolveRelative },
} = require('@untool/express');
const ServiceWorkerPlugin = require('./lib/service-worker-plugin');

class PWAMixin extends Mixin {
  configureBuild(webpackConfig, { allLoaderConfigs }, target) {
    const webmanifestLoader = {
      test: /\.webmanifest$/,
      use: [
        {
          loader: require.resolve('file-loader'),
          options: {
            name: resolveRelative(
              this.config.assetPath,
              '[name]-[hash:16].[ext]'
            ),
            emitFile: target === 'build' || target === 'develop',
          },
        },
        {
          loader: require.resolve('app-manifest-loader'),
        },
      ],
    };
    allLoaderConfigs.splice(allLoaderConfigs.length - 1, 0, webmanifestLoader);

    if (target === 'build' || target === 'develop') {
      webpackConfig.resolve.alias = {
        ...webpackConfig.resolve.alias,
        'hops-worker-entry-point': this.config.workerFile,
      };
      webpackConfig.module.rules.unshift({
        test: require.resolve('./lib/loader-shim'),
        loader: require.resolve('@untool/webpack/lib/utils/loader'),
        options: { target: 'worker', config: this.config },
      });
      webpackConfig.plugins.push(
        new ServiceWorkerPlugin({
          workerFile: this.config.workerFile,
          workerPath: this.config.workerPath,
        })
      );
    }

    return webpackConfig;
  }
}

module.exports = PWAMixin;
<commit_msg>feat(pwa): allow browserconfig.xml as application manifest<commit_after>const { Mixin } = require('hops-mixin');
const {
  uri: { resolveRelative },
} = require('@untool/express');
const ServiceWorkerPlugin = require('./lib/service-worker-plugin');

class PWAMixin extends Mixin {
  configureBuild(webpackConfig, { allLoaderConfigs }, target) {
    const webmanifestLoader = {
      test: /(\.webmanifest|browserconfig\.xml)$/,
      use: [
        {
          loader: require.resolve('file-loader'),
          options: {
            name: resolveRelative(
              this.config.assetPath,
              '[name]-[hash:16].[ext]'
            ),
            emitFile: target === 'build' || target === 'develop',
          },
        },
        {
          loader: require.resolve('app-manifest-loader'),
        },
      ],
    };
    allLoaderConfigs.splice(allLoaderConfigs.length - 1, 0, webmanifestLoader);

    if (target === 'build' || target === 'develop') {
      webpackConfig.resolve.alias = {
        ...webpackConfig.resolve.alias,
        'hops-worker-entry-point': this.config.workerFile,
      };
      webpackConfig.module.rules.unshift({
        test: require.resolve('./lib/loader-shim'),
        loader: require.resolve('@untool/webpack/lib/utils/loader'),
        options: { target: 'worker', config: this.config },
      });
      webpackConfig.plugins.push(
        new ServiceWorkerPlugin({
          workerFile: this.config.workerFile,
          workerPath: this.config.workerPath,
        })
      );
    }

    return webpackConfig;
  }
}

module.exports = PWAMixin;
<|endoftext|>


<commit_before>// +----------------------------------------------------------------------+
// | Bitflux Editor                                                       |
// +----------------------------------------------------------------------+
// | Copyright (c) 2003 Bitflux GmbH                                      |
// +----------------------------------------------------------------------+
// | This software is published under the terms of the Apache Software    |
// | License a copy of which has been included with this distribution in  |
// | the LICENSE file and is available through the web at                 |
// | http://bitflux.ch/editor/license.html                                |
// +----------------------------------------------------------------------+
// | Author: Christian Stocker <chregu@bitflux.ch>                        |
// +----------------------------------------------------------------------+
//
// $Id: DocumentVDOM.js,v 1.13 2003/11/18 21:41:10 chregu Exp $

function DocumentVDOM() {}

DocumentVDOM.prototype = new NodeVDOM();

DocumentVDOM.prototype.parseSchema = function() {
	//if it's an XMLSchema File
	if (!this.xmldoc.documentElement) {

		alert("Validation Document could not be loaded. \n" + this.xmldoc.saveXML(this.xmldoc));
	}
	if (this.xmldoc.documentElement.localName == "schema" &&
		this.xmldoc.documentElement.namespaceURI == "http://www.w3.org/2001/XMLSchema" ) {
		alert("XML Schema validation is not supported at the moment");
		//this.parseXMLSchema();
	}
	else if (this.xmldoc.documentElement.localName == "grammar" &&
		this.xmldoc.documentElement.namespaceURI == "http://relaxng.org/ns/structure/1.0" ) {
		this.parseRelaxNG();
	} else {
		bxe_alert ("Validation-file is not valid :\n" + this.xmldoc.saveXML(this.xmldoc));
		return false;
	}
	this.onparse(this);
	return true;
}
/*
*   Starts the loading of the schema with a simple http-get
*
*   you can override this function, if you net another method than get
*
*   file: file to be loaded
*   callback: callback to be called, when schema is parsed
*/
DocumentVDOM.prototype.loadSchema = function(file, callback) {
	// set callback
	this.onparse = callback;
	// make XMLDocument
	this.xmldoc = document.implementation.createDocument("","",null);
	// set onload handler
	this.xmldoc.onload = function(e) {e.currentTarget.DocumentVDOM.parseSchema();};
	//set a reference to the DocumentVDOM, so we can access it in the callback
	this.xmldoc.DocumentVDOM = this;
	this.filename = file;

	if (file.substring(0,1) == "/" || file.indexOf("://") > 0) {
		this.directory = bxe_getDirPart(file);
	} else {
		var dir = bxe_getDirPart(window.location.toString());
		this.directory =  bxe_getDirPart(dir + file);
	}
	// load schema file

	try {
		this.xmldoc.load(file);
	} catch (e) {
		return false;
	}

	return true;
}

DocumentVDOM.prototype.getAllowedChildren = function (name) {
	//FIXME: toLowerCase is HTML specific... make switch later
	return this.globalElements[name.toLowerCase()].allowedChildren;
}

DocumentVDOM.prototype.isGlobalElement = function(name) {

	if (this.globalElements[name.toLowerCase()]) {
		return true;
	} else {
		return false;
	}
}

<commit_msg>information about Schema and not supported ;)<commit_after>// +----------------------------------------------------------------------+
// | Bitflux Editor                                                       |
// +----------------------------------------------------------------------+
// | Copyright (c) 2003 Bitflux GmbH                                      |
// +----------------------------------------------------------------------+
// | This software is published under the terms of the Apache Software    |
// | License a copy of which has been included with this distribution in  |
// | the LICENSE file and is available through the web at                 |
// | http://bitflux.ch/editor/license.html                                |
// +----------------------------------------------------------------------+
// | Author: Christian Stocker <chregu@bitflux.ch>                        |
// +----------------------------------------------------------------------+
//
// $Id$

function DocumentVDOM() {}

DocumentVDOM.prototype = new NodeVDOM();

DocumentVDOM.prototype.parseSchema = function() {
	//if it's an XMLSchema File
	if (!this.xmldoc.documentElement) {

		alert("Validation Document could not be loaded. \n" + this.xmldoc.saveXML(this.xmldoc));
	}
	if (this.xmldoc.documentElement.localName == "schema" &&
		this.xmldoc.documentElement.namespaceURI == "http://www.w3.org/2001/XMLSchema" ) {
		alert("XML Schema validation is not supported. You have to use Relax NG");
		//this.parseXMLSchema();
	}
	else if (this.xmldoc.documentElement.localName == "grammar" &&
		this.xmldoc.documentElement.namespaceURI == "http://relaxng.org/ns/structure/1.0" ) {
		this.parseRelaxNG();
	} else {
		bxe_alert ("Validation-file is not valid :\n" + this.xmldoc.saveXML(this.xmldoc));
		return false;
	}
	this.onparse(this);
	return true;
}
/*
*   Starts the loading of the schema with a simple http-get
*
*   you can override this function, if you net another method than get
*
*   file: file to be loaded
*   callback: callback to be called, when schema is parsed
*/
DocumentVDOM.prototype.loadSchema = function(file, callback) {
	// set callback
	this.onparse = callback;
	// make XMLDocument
	this.xmldoc = document.implementation.createDocument("","",null);
	// set onload handler
	this.xmldoc.onload = function(e) {e.currentTarget.DocumentVDOM.parseSchema();};
	//set a reference to the DocumentVDOM, so we can access it in the callback
	this.xmldoc.DocumentVDOM = this;
	this.filename = file;

	if (file.substring(0,1) == "/" || file.indexOf("://") > 0) {
		this.directory = bxe_getDirPart(file);
	} else {
		var dir = bxe_getDirPart(window.location.toString());
		this.directory =  bxe_getDirPart(dir + file);
	}
	// load schema file

	try {
		this.xmldoc.load(file);
	} catch (e) {
		return false;
	}

	return true;
}

DocumentVDOM.prototype.getAllowedChildren = function (name) {
	//FIXME: toLowerCase is HTML specific... make switch later
	return this.globalElements[name.toLowerCase()].allowedChildren;
}

DocumentVDOM.prototype.isGlobalElement = function(name) {

	if (this.globalElements[name.toLowerCase()]) {
		return true;
	} else {
		return false;
	}
}

<|endoftext|>


<commit_before>/*
 * Chrome-Last.fm-Scrobbler BandCamp.com Connector by George Pollard
 *                (loosely based on Yasin Okumus's MySpace connector)
 * v0.1
 */
 var lastTrack = null;

$(function(){
	// bind page unload function to discard current "now listening"
	cancel();
});

var durationPart = ".track_info .time";
var durationRegex = /(\d+):(\d+)\/(\d+):(\d+)/;
function parseDuration(match){
	try{
		var m = durationRegex.exec(match);
		return {current: parseInt(m[1])*60 + parseInt(m[2]), total: parseInt(m[3])*60 + parseInt(m[4])};
	}catch(err){
		return 0;
	}
}

function parseArtist()
{
	var byLine = "";
	if (isAlbum())
	{
		byLine = $("dt.hiddenAccess:contains('band name') ~ dd").text();
	}
	else // isTrack
	{
		byLine = $(".albumTitle nobr").text();
	}

	return $.trim($.trim(byLine).substring(2));
}

function parseTitle()
{
	if (isAlbum())
	{
		return $(".track_info .title").text();
	}
	else //isTrack
	{
		return $(".trackTitle").first().text();
	}
}

function isAlbum()
{
	return document.location.toString().indexOf('bandcamp.com/album/') >= 0;
}

function cancel(){
	$(window).unload(function() {
		// reset the background scrobbler song data
		chrome.extension.sendRequest({type: 'reset'});
		return true;
	});
}

console.log('BandCampScrobbler: loaded');

$(durationPart).bind('DOMSubtreeModified',function(e){
	var duration = parseDuration($(durationPart).text());

	if (duration.current == 0)
	{
		cancel();
	}
	else if(duration.current > 0) { // it's playing

		var artist = parseArtist();
		var track = parseTitle();

		var dashIndex = track.indexOf('-');
		if (artist == 'Various Artists' && dashIndex >= 0)
		{
			artist = track.substring(0, dashIndex);
			track = track.substring(dashIndex + 1);
		}

		artist = $.trim(artist);
		track = $.trim(track);

		if (lastTrack != track)
		{
			lastTrack = track;

			//console.log("BandCampScrobbler: scrobbling '" + track + "' by " + artist);
			chrome.extension.sendRequest({type: 'validate', artist: artist, track: track}, function(response) {
				if (response != false){
					chrome.extension.sendRequest({type: 'nowPlaying', artist: response.artist, track: response.track, duration: duration.total});
				}
				else
				{
					chrome.extension.sendRequest({type: 'nowPlaying', duration: duration.total});
				}
			});
		}
	}
});
<commit_msg>Shouldn't cancel on 0.<commit_after>/*
 * Chrome-Last.fm-Scrobbler BandCamp.com Connector by George Pollard
 *                (loosely based on Yasin Okumus's MySpace connector)
 * v0.1
 */
 var lastTrack = null;

$(function(){
	// bind page unload function to discard current "now listening"
	cancel();
});

var durationPart = ".track_info .time";
var durationRegex = /(\d+):(\d+)\/(\d+):(\d+)/;
function parseDuration(match){
	try{
		var m = durationRegex.exec(match);
		return {current: parseInt(m[1])*60 + parseInt(m[2]), total: parseInt(m[3])*60 + parseInt(m[4])};
	}catch(err){
		return 0;
	}
}

function parseArtist()
{
	var byLine = "";
	if (isAlbum())
	{
		byLine = $("dt.hiddenAccess:contains('band name') ~ dd").text();
	}
	else // isTrack
	{
		byLine = $(".albumTitle nobr").text();
	}

	return $.trim($.trim(byLine).substring(2));
}

function parseTitle()
{
	if (isAlbum())
	{
		return $(".track_info .title").text();
	}
	else //isTrack
	{
		return $(".trackTitle").first().text();
	}
}

function isAlbum()
{
	return document.location.toString().indexOf('bandcamp.com/album/') >= 0;
}

function cancel(){
	$(window).unload(function() {
		// reset the background scrobbler song data
		chrome.extension.sendRequest({type: 'reset'});
		return true;
	});
}

console.log('BandCampScrobbler: loaded');

$(durationPart).bind('DOMSubtreeModified',function(e){
	var duration = parseDuration($(durationPart).text());

	if(duration.current > 0) { // it's playing

		var artist = parseArtist();
		var track = parseTitle();

		var dashIndex = track.indexOf('-');
		if (artist == 'Various Artists' && dashIndex >= 0)
		{
			artist = track.substring(0, dashIndex);
			track = track.substring(dashIndex + 1);
		}

		artist = $.trim(artist);
		track = $.trim(track);

		if (lastTrack != track)
		{
			lastTrack = track;

			//console.log("BandCampScrobbler: scrobbling '" + track + "' by " + artist);
			chrome.extension.sendRequest({type: 'validate', artist: artist, track: track}, function(response) {
				if (response != false){
					chrome.extension.sendRequest({type: 'nowPlaying', artist: response.artist, track: response.track, duration: duration.total});
				}
				else
				{
					chrome.extension.sendRequest({type: 'nowPlaying', duration: duration.total});
				}
			});
		}
	}
});
<|endoftext|>


<commit_before>const Discord = require('discord.js');
const Util = require('../classes/Util.js');
module.exports.name = 'delete';

module.exports.alias = [
  'delete',
  'del'
];

module.exports.isAllowed = (message, server) => {
  return server.guild.id == '189571157446492161' && (message.member.hasPermission('ADMINISTRATOR') || message.member.roles.has('543721608506900480'));
};

module.exports.help = '__Mods Only__ `,del [message_ids] [num_of_messages_to_delete=1(max=25)] [@mentions] [ has:link|file|"word" ]`\nDeletes messages by either specifying the IDs, or by searching.\n e.g. `,del 543252928496926722 542576315115634688` `,del 3 @geralt has:link` `,del 5 has:"mods suck"`\nAdmins can use `-n` to skip logging';

module.exports.command = async (message, content, bot, server) => {
  const delmsgs = [];
  const channel = message.channel;
  const users = message.mentions.users.keyArray();
  content = content.replace(Util.REGEX_USER, '');
  const message_ids = content.match(Util.REGEX_RAW_ID);
  let num_of_messages = (() => { const n = parseInt(content.split(' ')[0]); if (n && n > 0 && n <= 25) return n; else return 1;})();

  const link = /has:link/.test(content);
  const file = /has:file/.test(content);
  const word = (() => {const m = /has:"(.*)"/.exec(content); if (m) return m[1]; else return null;})();
  content = content.replace(/has:(link|file|".+")/g, '');

  if (message_ids) {
    for (let id of message_ids) {
      const msg = await channel.messages.fetch(id);
      if (msg) {
        delmsgs.push(msg);
      } else {
        channel.send(`Failed to find a message with the ID ${id} in this channel.`);
      }
    }
  } else {
    let MAX_LOOP = 5;
    let remaining = num_of_messages;
    let before = message.id;
    while (MAX_LOOP-- > 0 && remaining > 0) {
      let msgs = await channel.messages.fetch({limit:100, before});
      for (let msg of msgs.values()) {
        before = msg.id;
        if (users.length && !users.includes(msg.author.id)) continue;
        if (link && !Util.REGEX_URL.test(msg.content)) continue;
        if (file && msg.attachments.size == 0) continue;
        if (word && !msg.content.includes(word)) continue;
        delmsgs.push(msg);
        if (--remaining == 0) break;
      }
    }
  }
  if (delmsgs.length == 0) {
    channel.send('No messages to delete.');
    return;
  }

  if (!(content.includes('-n') && message.member.hasPermission('ADMINISTRATOR'))) {
    const ewbf = server.guild.channels.get('277384105245802497');
    let embed = new Discord.MessageEmbed();
    let date = new Date();
    embed.setAuthor(`${message.author.tag}`,message.author.avatarURL());
    embed.title = 'Message Delete';
    embed.color = Number('0xff283a');
    embed.setFooter(`In #${message.channel.name}`);
    embed.timestamp = date;

    let imgCount = 1;
    for (let msg of delmsgs) {
      if (msg.attachments.size) {
        await ewbf.send(`File ${imgCount}: ${msg.attachments.first().url}`);
        ++imgCount;
      }
      embed.addField(`Message by ${msg.author.tag}:`, `**Content**: ${msg.attachments.size ? `File ${imgCount - 1} ${msg.content}` : msg.content}`, false);
    }

    ewbf.send({embed});
  }

  message.delete();
  if (delmsgs.length == 1) {
    delmsgs[0].delete();
    let msg = await channel.send('✅ Deleted 1 message.');
    msg.delete({timeout:5000});
  } else {
    channel.bulkDelete(delmsgs);
    let msg = await channel.send(`✅ Deleted ${delmsgs.length} messages.`);
    msg.delete({timeout:5000});
  }
};
<commit_msg>show query<commit_after>const Discord = require('discord.js');
const Util = require('../classes/Util.js');
module.exports.name = 'delete';

module.exports.alias = [
  'delete',
  'del'
];

module.exports.isAllowed = (message, server) => {
  return server.guild.id == '189571157446492161' && (message.member.hasPermission('ADMINISTRATOR') || message.member.roles.has('543721608506900480'));
};

module.exports.help = '__Mods Only__ `,del [message_ids] [num_of_messages_to_delete=1(max=25)] [@mentions] [ has:link|file|"word" ]`\nDeletes messages by either specifying the IDs, or by searching.\n e.g. `,del 543252928496926722 542576315115634688` `,del 3 @geralt has:link` `,del 5 has:"mods suck"`\nAdmins can use `-n` to skip logging';

module.exports.command = async (message, content, bot, server) => {
  const delmsgs = [];
  const originalContent = content;
  const channel = message.channel;
  const users = message.mentions.users.keyArray();
  content = content.replace(Util.REGEX_USER, '');
  const message_ids = content.match(Util.REGEX_RAW_ID);
  let num_of_messages = (() => { const n = parseInt(content.split(' ')[0]); if (n && n > 0 && n <= 25) return n; else return 1;})();

  const link = /has:link/.test(content);
  const file = /has:file/.test(content);
  const word = (() => {const m = /has:"(.*)"/.exec(content); if (m) return m[1]; else return null;})();
  content = content.replace(/has:(link|file|".+")/g, '');

  if (message_ids) {
    for (let id of message_ids) {
      const msg = await channel.messages.fetch(id);
      if (msg) {
        delmsgs.push(msg);
      } else {
        channel.send(`Failed to find a message with the ID ${id} in this channel.`);
      }
    }
  } else {
    let MAX_LOOP = 5;
    let remaining = num_of_messages;
    let before = message.id;
    while (MAX_LOOP-- > 0 && remaining > 0) {
      let msgs = await channel.messages.fetch({limit:100, before});
      for (let msg of msgs.values()) {
        before = msg.id;
        if (users.length && !users.includes(msg.author.id)) continue;
        if (link && !Util.REGEX_URL.test(msg.content)) continue;
        if (file && msg.attachments.size == 0) continue;
        if (word && !msg.content.includes(word)) continue;
        delmsgs.push(msg);
        if (--remaining == 0) break;
      }
    }
  }
  if (delmsgs.length == 0) {
    channel.send('No messages to delete.');
    return;
  }

  if (!(content.includes('-n') && message.member.hasPermission('ADMINISTRATOR'))) {
    const ewbf = server.guild.channels.get('277384105245802497');
    let embed = new Discord.MessageEmbed();
    let date = new Date();
    embed.setAuthor(`${message.author.tag}`,message.author.avatarURL());
    embed.title = `Message Delete: ${originalContent}`;
    embed.color = Number('0xff283a');
    embed.setFooter(`In #${message.channel.name}`);
    embed.timestamp = date;

    let imgCount = 1;
    for (let msg of delmsgs) {
      if (msg.attachments.size) {
        await ewbf.send(`File ${imgCount}: ${msg.attachments.first().url}`);
        ++imgCount;
      }
      embed.addField(`Message by ${msg.author.tag}:`, `**Content**: ${msg.attachments.size ? `File ${imgCount - 1} ${msg.content}` : msg.content}`, false);
    }

    ewbf.send({embed});
  }

  message.delete();
  if (delmsgs.length == 1) {
    delmsgs[0].delete();
    let msg = await channel.send('✅ Deleted 1 message.');
    msg.delete({timeout:5000});
  } else {
    channel.bulkDelete(delmsgs);
    let msg = await channel.send(`✅ Deleted ${delmsgs.length} messages.`);
    msg.delete({timeout:5000});
  }
};
<|endoftext|>


<commit_before>//loads the commands in from ./commands and builds the help menu
//the help menu displays only the commands that a user can use
module.exports = function commandLoad(bot,info)
{
    "use strict";
    const commands = {};
    const config = info.config;
    const utility = info.utility;
    const fs = require('fs');

    fs.readdir(__dirname, function(err, items){
        if(err)
        {
            console.log(err);
        }
        else
        {
            items.sort();
            for(let i = 0; i < items.length; i ++)
            {
                const commandName = items[i].slice(0,-3);
                if(items[i] !== "loader.js" && items[i].endsWith('.js'))
                {
                    commands[commandName] = require(__dirname + '/' + items[i])(bot,info);

                    if(!commands[commandName])
                    {
                        delete commands[commandName];
                    }
                }
            }
        }
    });

    commands['help'] =
    {
        inline: true,
        alias: ['?'],
        description: "(Shows help menu)",
        permissions: "public",
        action: function(details)
        {
            //concatenates an array to one line
            const concatArr = function(arr)
            {
                    "use strict";
                    let s = "";
                    for(let i = 0; i < arr.length; i++)
                    {
                        if(arr[i] != null)
                        {
                            if(i == (arr.length - 1))
                            {
                                s += config.prefix + arr[i];
                            }
                            else
                            {
                                s += config.prefix + arr[i] + ", ";
                            }
                        }
                    }
                return s;
            }

            let lines = [];
            const filter = function(filterArr,key)
            {

                let aliasStr = "";
                let field = {};
                if(utility.searchArr(filterArr,commands[key]['permissions']))
                {
                    if(typeof commands[key]['alias'] === "object")
                    {
                        aliasStr= " " + concatArr(commands[key]['alias']);
                    }
                    field.name = config.prefix + key + ", " + aliasStr;
                    field.value = commands[key]['description'];
                    field.inline = commands[key].inline;
                    return field;
                }
                else
                {
                    return false;
                }
            }
            let filterArr =[];
            if(details.isAdministrator)
            {
                filterArr = ["public","mod","elevated","private"];
            }
            else if(details.isMod)
            {
                filterArr = ["public","mod","elevated"];
            }
            else if(details.isElevated)
            {
                filterArr = ["public","elevated"];
            }
            else
            {
                filterArr = ["public"]
            }
            let count = 0;
            Object.keys(commands).forEach(function(key)
            {
                let filtered = filter(filterArr,key);
                if(filtered != false)
                {
                    lines.push(filtered);
                }

                count ++;
                if(count == Object.keys(commands).length)
                {
                    bot.sendMessage({
                        to: details.channelID,
                        embed: {
                            title: 'Help',
                            description: 'You can PM the bot :heart:',
                            fields: lines
                        }
                    });
                }
            });

        }
    }

    return commands;
};<commit_msg>Forgot to update this too, RIIIP :sob:<commit_after>//loads the commands in from ./commands and builds the help menu
//the help menu displays only the commands that a user can use
module.exports = function commandLoad(bot,info)
{
  'use strict';
  const commands = {};
  const config = info.config;
  const utility = info.utility;
  const fs = require('fs');

  fs.readdir(__dirname, (err, items) =>
  {
    if(err)
    {
      console.log(err);
    }
    else
    {
      items.sort();
      for(let i = 0; i < items.length; i ++)
      {
        if(items[i] !== 'loader.js' && items[i].endsWith('.js'))
        {
          const commandName = items[i].slice(0,-3);
          commands[commandName] = require(__dirname + '/' + items[i])(bot,info);

          if(!commands[commandName])
          {
            delete commands[commandName];
          }
        }
      }
    }
  });

  commands['help'] =
  {
    inline: true,
    alias: ['?'],
    description: '(Shows help menu)',
    permissions: 'public',
    action: function(details)
    {
      //concatenates an array to one line
      const concatArr = function(arr)
      {
        let s = '';
        for(let i = 0; i < arr.length; i++)
        {
          if(arr[i] != null)
          {
            if(i == (arr.length - 1))
            {
              s += details.prefix + arr[i];
            }
            else
            {
              s += details.prefix + arr[i] + ', ';
            }
          }
        }
        return s;
      };

      let lines = [];
      const filter = function(filterArr,key)
      {

        let aliasStr = '';
        let field = {};
        if(utility.searchArr(filterArr,commands[key]['permissions']))
        {
          if(typeof commands[key]['alias'] === 'object')
          {
            aliasStr= ' ' + concatArr(commands[key]['alias']);
          }
          field.name = details.prefix + key + ', ' + aliasStr;
          field.value = commands[key]['description'];
          field.inline = commands[key].inline;
          return field;
        }
        else
        {
          return false;
        }
      };
      let filterArr =[];
      if(details.isAdministrator)
      {
        filterArr = ['public','mod','elevated','private'];
      }
      else if(details.isMod)
      {
        filterArr = ['public','mod','elevated'];
      }
      else if(details.isElevated)
      {
        filterArr = ['public','elevated'];
      }
      else
      {
        filterArr = ['public'];
      }
      let count = 0;
      Object.keys(commands).forEach(function(key)
      {
        let filtered = filter(filterArr,key);
        if(filtered != false)
        {
          lines.push(filtered);
        }

        count ++;
        if(count == Object.keys(commands).length)
        {
          bot.sendMessage({
            to: details.channelID,
            embed: {
              title: 'Help',
              description: 'You can PM the bot :heart:',
              fields: lines
            }
          });
        }
      });

    }
  };

  return commands;
};<|endoftext|>


<commit_before>tQuery.register('MinecraftCharAnimations', function(character){
	var animations	= this;
	// call parent ctor
	tQuery.MinecraftCharAnimations.parent.constructor.call(this)

	var tweenAngle	= function(baseValue, nextValue, timePercent){
		// compute the nextValue to get the shortest path - assume it is an angle
		if( nextValue - baseValue > +Math.PI )	nextValue -= Math.PI*2;
		if( nextValue - baseValue < -Math.PI )	nextValue += Math.PI*2;
		return (1-timePercent) * baseValue + timePercent * nextValue;
	}

	var onUpdate	= function(position){
		character.parts.armR.rotation.z	= position.armRRotationZ;
		character.parts.armL.rotation.z	= position.armLRotationZ;

		character.parts.armR.rotation.x	=  position.armRotationX;
		character.parts.armL.rotation.x = -position.armRotationX;

		character.parts.legR.rotation.x	=  position.legRotationX;
		character.parts.legL.rotation.x = -position.legRotationX;
	};
	var onCapture	= function(position){
		position.armLRotationZ	= character.parts.armL.rotation.z;
		position.armRRotationZ	= character.parts.armR.rotation.z;
		position.armRotationX	= character.parts.armR.rotation.x;
		position.legRotationX	= character.parts.legR.rotation.x;
	};
	var propTweens	= {
		armLRotationZ	: tweenAngle,
		armRRotationZ	: tweenAngle,
		armRotationX	: tweenAngle,
		legRotationX	: tweenAngle
	}

	// Setup 'run' animation
	var angleRange	= Math.PI/2-Math.PI/10;
	animations.add('run'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: +Math.PI/10,
		armRRotationZ	: -Math.PI/10,
		armRotationX	: +angleRange,
		legRotationX	: -angleRange
	}).pushKeyframe(0.5, {
		armLRotationZ	: +Math.PI/10,
		armRRotationZ	: -Math.PI/10,
		armRotationX	: -angleRange,
		legRotationX	: +angleRange
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'walk' animation
	var angleRange	= Math.PI/3-Math.PI/10;
	animations.add('walk'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: -Math.PI/30,
		armRRotationZ	: +Math.PI/30,
		armRotationX	: +angleRange,
		legRotationX	: -angleRange
	}).pushKeyframe(0.5, {
		armLRotationZ	: -Math.PI/30,
		armRRotationZ	: +Math.PI/30,
		armRotationX	: -angleRange,
		legRotationX	: +angleRange
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'stand' animation
	animations.add('stand', tQuery.createAnimation().pushKeyframe(0.3, {
		armLRotationZ	: 0,
		armRRotationZ	: 0,
		armRotationX	: 0,
		legRotationX	: 0
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'wave' animation
	var angleRange	= Math.PI/2-Math.PI/10;
	animations.add('wave'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: 0,
		armRRotationZ	: Math.PI+2*Math.PI/5,
		armRotationX	: 0,
		legRotationX	: 0
	}).pushKeyframe(0.5, {
		armLRotationZ	: 0,
		armRRotationZ	: Math.PI+Math.PI/10,
		armRotationX	: 0,
		legRotationX	: 0
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'hiwave' animation
	var angleRange	= Math.PI/2-Math.PI/10;
	animations.add('hiwave'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: Math.PI-3*Math.PI/5,
		armRRotationZ	: Math.PI+3*Math.PI/5,
		armRotationX	: 0,
		legRotationX	: 0
	}).pushKeyframe(0.5, {
		armLRotationZ	: Math.PI-Math.PI/10,
		armRRotationZ	: Math.PI+Math.PI/10,
		armRotationX	: 0,
		legRotationX	: 0
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));
});

tQuery.inherit(tQuery.MinecraftCharAnimations, tQuery.Animations);
<commit_msg>fix arm orientation in walk animation<commit_after>tQuery.register('MinecraftCharAnimations', function(character){
	var animations	= this;
	// call parent ctor
	tQuery.MinecraftCharAnimations.parent.constructor.call(this)

	var tweenAngle	= function(baseValue, nextValue, timePercent){
		// compute the nextValue to get the shortest path - assume it is an angle
		if( nextValue - baseValue > +Math.PI )	nextValue -= Math.PI*2;
		if( nextValue - baseValue < -Math.PI )	nextValue += Math.PI*2;
		return (1-timePercent) * baseValue + timePercent * nextValue;
	}

	var onUpdate	= function(position){
		character.parts.armR.rotation.z	= position.armRRotationZ;
		character.parts.armL.rotation.z	= position.armLRotationZ;

		character.parts.armR.rotation.x	=  position.armRotationX;
		character.parts.armL.rotation.x = -position.armRotationX;

		character.parts.legR.rotation.x	=  position.legRotationX;
		character.parts.legL.rotation.x = -position.legRotationX;
	};
	var onCapture	= function(position){
		position.armLRotationZ	= character.parts.armL.rotation.z;
		position.armRRotationZ	= character.parts.armR.rotation.z;
		position.armRotationX	= character.parts.armR.rotation.x;
		position.legRotationX	= character.parts.legR.rotation.x;
	};
	var propTweens	= {
		armLRotationZ	: tweenAngle,
		armRRotationZ	: tweenAngle,
		armRotationX	: tweenAngle,
		legRotationX	: tweenAngle
	}

	// Setup 'run' animation
	var angleRange	= Math.PI/2-Math.PI/10;
	animations.add('run'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: +Math.PI/10,
		armRRotationZ	: -Math.PI/10,
		armRotationX	: +angleRange,
		legRotationX	: -angleRange
	}).pushKeyframe(0.5, {
		armLRotationZ	: +Math.PI/10,
		armRRotationZ	: -Math.PI/10,
		armRotationX	: -angleRange,
		legRotationX	: +angleRange
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'walk' animation
	var angleRange	= Math.PI/3-Math.PI/10;
	animations.add('walk'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: +Math.PI/30,
		armRRotationZ	: -Math.PI/30,
		armRotationX	: +angleRange,
		legRotationX	: -angleRange
	}).pushKeyframe(0.5, {
		armLRotationZ	: +Math.PI/30,
		armRRotationZ	: -Math.PI/30,
		armRotationX	: -angleRange,
		legRotationX	: +angleRange
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'stand' animation
	animations.add('stand', tQuery.createAnimation().pushKeyframe(0.3, {
		armLRotationZ	: 0,
		armRRotationZ	: 0,
		armRotationX	: 0,
		legRotationX	: 0
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'wave' animation
	var angleRange	= Math.PI/2-Math.PI/10;
	animations.add('wave'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: 0,
		armRRotationZ	: Math.PI+2*Math.PI/5,
		armRotationX	: 0,
		legRotationX	: 0
	}).pushKeyframe(0.5, {
		armLRotationZ	: 0,
		armRRotationZ	: Math.PI+Math.PI/10,
		armRotationX	: 0,
		legRotationX	: 0
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));

	// Setup 'hiwave' animation
	var angleRange	= Math.PI/2-Math.PI/10;
	animations.add('hiwave'	, tQuery.createAnimation().pushKeyframe(0.5, {
		armLRotationZ	: Math.PI-3*Math.PI/5,
		armRRotationZ	: Math.PI+3*Math.PI/5,
		armRotationX	: 0,
		legRotationX	: 0
	}).pushKeyframe(0.5, {
		armLRotationZ	: Math.PI-Math.PI/10,
		armRRotationZ	: Math.PI+Math.PI/10,
		armRotationX	: 0,
		legRotationX	: 0
	}).propertyTweens(propTweens).onCapture(onCapture).onUpdate(onUpdate));
});

tQuery.inherit(tQuery.MinecraftCharAnimations, tQuery.Animations);
<|endoftext|>


<commit_before>import React from 'react';
import { Meteor } from 'meteor/meteor';
import Paper from 'material-ui/Paper';
import Subheader from 'material-ui/Subheader';
import FlatButton from 'material-ui/FlatButton';
import { Scrollbars } from 'react-custom-scrollbars';
import PaperCard from '../../layouts/paper-card';

import * as Helper from '../../../util/helper';
import * as GiveawaysHelper from '../../../util/giveaways';
import * as IconsHelper from '../../../util/icons';
import * as UsersHelper from '../../../util/users';

import { pushStatusUpdate } from '../../../api/giveaways/methods';

const statusUpdateRow = (owner) => (su, index) => (

    { IconsHelper.materialIcon("lens", { color: su.statusType.hexColour, fontSize: 10 }) }

      { su.statusType.label }: { UsersHelper.getUserLink(su.user, UsersHelper.getFullNameWithLabelIfEqual(su.user, owner, "author")) }
      { moment(su.date).fromNow() }

);

const statusTypeActionHandler = (giveawayId, statusTypeId) => (event) => {
  if (!Meteor.userId())
    return;

  pushStatusUpdate.call({ giveawayId, statusTypeId, userId: Meteor.userId() });
};

const statusTypeActionRow = (count, ga) => (statusType, index) => (

    <FlatButton
      label={ statusType.label }
      backgroundColor={ statusType.hexColour }
      hoverColor={ Helper.shadeColor(statusType.hexColour, -0.2) }
      labelStyle={{ fontSize: "13px", textTransform: "none", color: "#fff", padding: 5 }}
      style={{ width: "calc(100% - 10px)", margin: "0 auto 5px" }}
      onTouchTap={ statusTypeActionHandler(ga._id, statusType._id) } />

);

const LatestUpdate = ({ latestOwnerUpdate, owner }) => (

    <Subheader>Latest update from author</Subheader>

      { (statusUpdateRow(owner))(latestOwnerUpdate) }

);

const ContributeUpdate = ({ statusTypes, ga }) => (

    <Subheader>Contribute a status update</Subheader>

        { statusTypes.map(statusTypeActionRow(statusTypes.count(), ga)) }

);

const AllUpdates = ({ statusUpdates, owner }) => (

    <Subheader>All status updates</Subheader>

      <Scrollbars
        autoHide
        autoHeight
        autoHeightMin={22}
        autoHeightMax={150}>
        { statusUpdates.map(statusUpdateRow(owner)) }
      </Scrollbars>

);

export const GiveawayStatusUpdatesCard = ({ ga, statusUpdates, statusTypes, latestOwnerUpdate, owner }) => (
  <PaperCard className="giveaway">

Status Updates

        { LatestUpdate({ latestOwnerUpdate, owner }) }

        { GiveawaysHelper.is_ongoing(ga) ? ContributeUpdate({ statusTypes, ga }) : null }

        { AllUpdates({ statusUpdates, owner }) }

  </PaperCard>
);
<commit_msg>Open login dialog for status update button and not logged in<commit_after>import React from 'react';
import { Meteor } from 'meteor/meteor';
import Store from '../../../startup/client/redux-store';

import Paper from 'material-ui/Paper';
import Subheader from 'material-ui/Subheader';
import FlatButton from 'material-ui/FlatButton';
import { Scrollbars } from 'react-custom-scrollbars';
import PaperCard from '../../layouts/paper-card';

import * as Helper from '../../../util/helper';
import * as GiveawaysHelper from '../../../util/giveaways';
import * as IconsHelper from '../../../util/icons';
import * as UsersHelper from '../../../util/users';

import { pushStatusUpdate } from '../../../api/giveaways/methods';

const statusUpdateRow = (owner) => (su, index) => (

    { IconsHelper.materialIcon("lens", { color: su.statusType.hexColour, fontSize: 10 }) }

      { su.statusType.label }: { UsersHelper.getUserLink(su.user, UsersHelper.getFullNameWithLabelIfEqual(su.user, owner, "author")) }
      { moment(su.date).fromNow() }

);

const statusTypeActionHandler = (giveawayId, statusTypeId) => (event) => {
  if (!Meteor.userId())
    return Store.dispatch({ type: 'OPEN_LOGIN_DIALOG', message: "Login to add a status update!" });

  pushStatusUpdate.call({ giveawayId, statusTypeId, userId: Meteor.userId() });
};

const statusTypeActionRow = (count, ga) => (statusType, index) => (

    <FlatButton
      label={ statusType.label }
      backgroundColor={ statusType.hexColour }
      hoverColor={ Helper.shadeColor(statusType.hexColour, -0.2) }
      labelStyle={{ fontSize: "13px", textTransform: "none", color: "#fff", padding: 5 }}
      style={{ width: "calc(100% - 10px)", margin: "0 auto 5px" }}
      onTouchTap={ statusTypeActionHandler(ga._id, statusType._id) } />

);

const LatestUpdate = ({ latestOwnerUpdate, owner }) => (

    <Subheader>Latest update from author</Subheader>

      { (statusUpdateRow(owner))(latestOwnerUpdate) }

);

const ContributeUpdate = ({ statusTypes, ga }) => (

    <Subheader>Contribute a status update</Subheader>

        { statusTypes.map(statusTypeActionRow(statusTypes.count(), ga)) }

);

const AllUpdates = ({ statusUpdates, owner }) => (

    <Subheader>All status updates</Subheader>

      <Scrollbars
        autoHide
        autoHeight
        autoHeightMin={22}
        autoHeightMax={150}>
        { statusUpdates.map(statusUpdateRow(owner)) }
      </Scrollbars>

);

export const GiveawayStatusUpdatesCard = ({ ga, statusUpdates, statusTypes, latestOwnerUpdate, owner }) => (
  <PaperCard className="giveaway">

Status Updates

        { LatestUpdate({ latestOwnerUpdate, owner }) }

        { GiveawaysHelper.is_ongoing(ga) ? ContributeUpdate({ statusTypes, ga }) : null }

        { AllUpdates({ statusUpdates, owner }) }

  </PaperCard>
);
<|endoftext|>


<commit_before>/* global bowlineApp, moment, io */
bowlineApp.directive('navbar', function(){

	return {
		restrict: 'E',
		scope: {
			loggedin: '=loggedin',
		},
		templateUrl: 'views/navbar.html',
		controller: ['$scope','$http','$attrs','$location','ENV', 'loginModule', function ($scope,$http,$attrs,$location,ENV,login) {

			var socket = io.connect(ENV.api_url);

			$scope.messages = [];

			$scope.$on("loginStatus",function(event,status){
				socket.emit('subscribe_user',{ session: login.sessionpack });
				// console.log("!trace woot NAVBAR directive.");

				socket.on("buildbegins",function(data){
					// console.log("!trace buildbegins SOCKET",data);
					$scope.messages.unshift({
						mode: "buildbegins",
						slug: data.slug,
						releaseid: data.releaseid,
						read: false,
						indate: new Date(),
					});
					$scope.$apply();
				});

				socket.on("buildcomplete",function(data){
					// console.log("!trace buildcomplete SOCKET",data);
					$scope.messages.unshift({
						mode: "buildcomplete",
						slug: data.slug,
						releaseid: data.releaseid,
						success: data.success,
						read: false,
						indate: new Date(),
					});
					$scope.$apply();
				});

			});

			$scope.numberUnread = function() {
				if ($scope.messages.length) {
					var counted = 0;
					$scope.messages.forEach(function(message){
						if (!message.read) {
							counted++;
						}
					});
					return counted;
				} else {
					return 0;
				}
			};

			$scope.clearMessages = function() {
				$scope.messages = [];
			};

			$scope.clickMessage = function(index){

				switch ($scope.messages[index].mode) {

					case "buildbegins":
					case "buildcomplete":
						// Let's build a location for the knot build in progress.
						$location.path("/knots");
						$location.search("details",$scope.messages[index].releaseid);
						$location.search("showbuild","true");
						break;

					default:
						console.log("!ERROR: clickMessage mode doesn't exist: ",$scope.messages[index].mode);
						break;

				}

				$scope.messages[index].read = true;

			};

			$scope.messageReadClass = function(read) {

				if (read) {
					return "message-read";
				} else {
					return "message-unread";
				}

			};

			$scope.navClass = function (page) {

				// Get the route.
				var currentRoute = $location.path().substring(1) || 'home';

				// Set the onPage if it's wrong.
				if (currentRoute !== $scope.onPage) {
					$scope.onPage = currentRoute;
				}

				return page === currentRoute ? 'active' : '';
			};

			$scope.secondsAgo = function(indate) {

				return moment(indate).fromNow();

			};

			// Ok it's been opened.
			$scope.toggledAlerts = function(open) {
				// console.log("!trace opened? ",open);
			};

			$scope.myKnots = function() {
				$location.path("/knots");
				$location.search('mine','true');
				$location.search('add',null);
				$location.search('details',null);
			};

			$scope.addKnot = function() {
				$location.path("/knots");
				$location.search('add','true');
				$location.search('mine',null);
				$location.search('details',null);
			};

			$scope.goConsole = function() {
				$location.path("/console");
			};

			$scope.goProfile = function() {
				$location.path("/profile");
			};

			$scope.logOut = function() {

				login.setLoggedOut(function(){
					$location.path("/");
				});

			};

		}],
	};

});<commit_msg>[bugfix][minor] fixes clicking navbar messages when in add screen<commit_after>/* global bowlineApp, moment, io */
bowlineApp.directive('navbar', function(){

	return {
		restrict: 'E',
		scope: {
			loggedin: '=loggedin',
		},
		templateUrl: 'views/navbar.html',
		controller: ['$scope','$http','$attrs','$location','ENV', 'loginModule', function ($scope,$http,$attrs,$location,ENV,login) {

			var socket = io.connect(ENV.api_url);

			$scope.messages = [];

			$scope.$on("loginStatus",function(event,status){
				socket.emit('subscribe_user',{ session: login.sessionpack });
				// console.log("!trace woot NAVBAR directive.");

				socket.on("buildbegins",function(data){
					// console.log("!trace buildbegins SOCKET",data);
					$scope.messages.unshift({
						mode: "buildbegins",
						slug: data.slug,
						releaseid: data.releaseid,
						read: false,
						indate: new Date(),
					});
					$scope.$apply();
				});

				socket.on("buildcomplete",function(data){
					// console.log("!trace buildcomplete SOCKET",data);
					$scope.messages.unshift({
						mode: "buildcomplete",
						slug: data.slug,
						releaseid: data.releaseid,
						success: data.success,
						read: false,
						indate: new Date(),
					});
					$scope.$apply();
				});

			});

			$scope.numberUnread = function() {
				if ($scope.messages.length) {
					var counted = 0;
					$scope.messages.forEach(function(message){
						if (!message.read) {
							counted++;
						}
					});
					return counted;
				} else {
					return 0;
				}
			};

			$scope.clearMessages = function() {
				$scope.messages = [];
			};

			$scope.clickMessage = function(index){

				switch ($scope.messages[index].mode) {

					case "buildbegins":
					case "buildcomplete":
						// Let's build a location for the knot build in progress.
						$location.path("/knots")
							.search("details",$scope.messages[index].releaseid)
							.search('add',null)
							.search("showbuild","true");
						break;

					default:
						console.log("!ERROR: clickMessage mode doesn't exist: ",$scope.messages[index].mode);
						break;

				}

				$scope.messages[index].read = true;

			};

			$scope.messageReadClass = function(read) {

				if (read) {
					return "message-read";
				} else {
					return "message-unread";
				}

			};

			$scope.navClass = function (page) {

				// Get the route.
				var currentRoute = $location.path().substring(1) || 'home';

				// Set the onPage if it's wrong.
				if (currentRoute !== $scope.onPage) {
					$scope.onPage = currentRoute;
				}

				return page === currentRoute ? 'active' : '';
			};

			$scope.secondsAgo = function(indate) {

				return moment(indate).fromNow();

			};

			// Ok it's been opened.
			$scope.toggledAlerts = function(open) {
				// console.log("!trace opened? ",open);
			};

			$scope.myKnots = function() {
				$location.path("/knots")
					.search('mine','true')
					.search('add',null)
					.search('showbuild',null)
					.search('details',null);
			};

			$scope.addKnot = function() {
				$location.path("/knots")
					.search('add','true')
					.search('mine',null)
					.search('showbuild',null)
					.search('details',null);
			};

			$scope.goConsole = function() {
				$location.path("/console");
			};

			$scope.goProfile = function() {
				$location.path("/profile");
			};

			$scope.logOut = function() {

				login.setLoggedOut(function(){
					$location.path("/");
				});

			};

		}],
	};

});<|endoftext|>


<commit_before>const _ = require('../common');

//in days
const encounterSchedule = {
    "ANC 1": {due: 40, max: 84},
    "ANC 2": {due: 98, max: 182},
    "ANC 3": {due: 196, max: 238},
    "ANC 4": {due: 252, max: 273},
    "Delivery": {due: 270, max: 280},
    "PNC 1": {due: 1, max: 1},
    "PNC 2": {due: 3, max: 3},
    "PNC 3": {due: 7, max: 7},
    "PNC 4": {due: 42, max: 42}
};

const getNextScheduledVisits = function (programEnrolment, today, currentEncounter) {
    const lmpConceptName = 'Last Menstrual Period';

    const encounters = [];

    const lmpDate = programEnrolment.getObservationValue(lmpConceptName);

    function findEncounterTypeByName(encounterTypeName) {
        return programEnrolment.encounters.find(function (encounter) {
            return encounter.encounterType.name === encounterTypeName;
        })
    }

    const currentEncounters = programEnrolment.encounters;

    const deliveryEncounter = findEncounterTypeByName('Delivery');

    const deliveryDate = deliveryEncounter && deliveryEncounter.encounterDateTime;

    const addEncounter = function (baseDate, encounterType, name) {
        if (_.encounterExists(currentEncounters, encounterType, name)) return;

        var schedule = encounterSchedule[name === undefined ? encounterType : name];

        encounters.push({
            name: name,
            encounterType: encounterType,
            dueDate: _.addDays(baseDate, schedule.due),
            maxDate: _.addDays(baseDate, schedule.max)
        });
    };

    if (lmpDate) {
        addEncounter(lmpDate, 'ANC', 'ANC 1');
        addEncounter(lmpDate, 'ANC', 'ANC 2');
        addEncounter(lmpDate, 'ANC', 'ANC 3');
        addEncounter(lmpDate, 'ANC', 'ANC 4');
        addEncounter(lmpDate, 'Delivery', 'Delivery');
    }

    if (deliveryDate) {
        addEncounter(deliveryDate, 'PNC', 'PNC 1');
        addEncounter(deliveryDate, 'PNC', 'PNC 2');
        addEncounter(deliveryDate, 'PNC', 'PNC 3');
        addEncounter(deliveryDate, 'PNC', 'PNC 4');
    }

    return encounters;
};

module.exports = {
    getNextScheduledVisits: getNextScheduledVisits
};

<commit_msg>Ensure delivery encounter is found by name and type<commit_after>const _ = require('../common');

//in days
const encounterSchedule = {
    "ANC 1": {due: 40, max: 84},
    "ANC 2": {due: 98, max: 182},
    "ANC 3": {due: 196, max: 238},
    "ANC 4": {due: 252, max: 273},
    "Delivery": {due: 270, max: 280},
    "PNC 1": {due: 1, max: 1},
    "PNC 2": {due: 3, max: 3},
    "PNC 3": {due: 7, max: 7},
    "PNC 4": {due: 42, max: 42}
};

const getNextScheduledVisits = function (programEnrolment, today, currentEncounter) {
    const lmpConceptName = 'Last Menstrual Period';

    const encounters = [];

    const lmpDate = programEnrolment.getObservationValue(lmpConceptName);

    const matchingEncounter = function(encounters, encounterTypeName, encounterName) {
        return encounters.find(function(encounter) {
            return encounter.encounterType.name === encounterTypeName && encounter.name === encounterName;
        })
    };

    const currentEncounters = programEnrolment.encounters;

    const deliveryEncounter = matchingEncounter(currentEncounters, 'Delivery', 'Delivery');

    const deliveryDate = deliveryEncounter && deliveryEncounter.encounterDateTime;
    console.log("Delivery encounter is " + deliveryEncounter);
    console.log("Delivery date is " + deliveryDate);

    const addEncounter = function (baseDate, encounterType, name) {
        if (_.encounterExists(currentEncounters, encounterType, name)) return;

        var schedule = encounterSchedule[name === undefined ? encounterType : name];

        encounters.push({
            name: name,
            encounterType: encounterType,
            dueDate: _.addDays(baseDate, schedule.due),
            maxDate: _.addDays(baseDate, schedule.max)
        });
    };

    if (lmpDate) {
        addEncounter(lmpDate, 'ANC', 'ANC 1');
        addEncounter(lmpDate, 'ANC', 'ANC 2');
        addEncounter(lmpDate, 'ANC', 'ANC 3');
        addEncounter(lmpDate, 'ANC', 'ANC 4');
        addEncounter(lmpDate, 'Delivery', 'Delivery');
    }

    if (deliveryDate) {
        addEncounter(deliveryDate, 'PNC', 'PNC 1');
        addEncounter(deliveryDate, 'PNC', 'PNC 2');
        addEncounter(deliveryDate, 'PNC', 'PNC 3');
        addEncounter(deliveryDate, 'PNC', 'PNC 4');
    }

    return encounters;
};

module.exports = {
    getNextScheduledVisits: getNextScheduledVisits
};

<|endoftext|>