<commit_before>/**
 *
 *   ___| |   | |  |
 *  |     |   | |  |
 *  |     ___ |___ __|
 * \____|_|  _|   _|
 *
 * @author Shinichirow KAMITO
 * @license MIT
 */
import {
  createStore,
  destroyStore,
  getAllStores,
  destroyAllStores,
  trigger,
  regist
} from './core';
import dispatcher from './dispatcher';

let ch4 = {
  createStore: createStore,
  getAllStores: getAllStores,
  destroyStore: destroyStore,
  destroyAllStores: destroyAllStores,
  trigger: trigger,
  regist: regist,
  dispatcher: dispatcher
};

export {
  createStore,
  destroyStore,
  getAllStores,
  destroyAllStores,
  trigger,
  regist,
  dispatcher
}
export default ch4;
<commit_msg>Add logger to export modules.<commit_after>/**
 *
 *   ___| |   | |  |
 *  |     |   | |  |
 *  |     ___ |___ __|
 * \____|_|  _|   _|
 *
 * @author Shinichirow KAMITO
 * @license MIT
 */
import {
  createStore,
  destroyStore,
  getAllStores,
  destroyAllStores,
  trigger,
  regist
} from './core';
import dispatcher from './dispatcher';
import logger from './logger';

let ch4 = {
  createStore: createStore,
  getAllStores: getAllStores,
  destroyStore: destroyStore,
  destroyAllStores: destroyAllStores,
  trigger: trigger,
  regist: regist,
  dispatcher: dispatcher,
  logger: logger
};

export {
  createStore,
  destroyStore,
  getAllStores,
  destroyAllStores,
  trigger,
  regist,
  dispatcher,
  logger
}
export default ch4;
<|endoftext|>


<commit_before>
var tfmarkdown = {
	parse: function(md) {

		md = md.replace(/(^)\n{0,1}(#+)(.*)\n{0,1}/gm, function(all, newline, hashcount, title){
			var hc = hashcount.length;
			return newline+'<h'+hc+'>'+title+'</h'+hc+'>';
		});

		md = md.replace(/\n{0,1}(.*)\n([=-]{2,})\n{0,1}/g, function(all, title, ttype){
			var hc = ttype[0] === '=' ? '1' : '2';
			return '<h'+hc+'>'+title+'</h'+hc+'>';
		});

		md = md.replace(/(?:\*\*|__)(.*)(?:\*\*|__)/g, function(all, bold){
			return ''+bold+'';
		});

		md = md.replace(/[\*_](.*)[\*_]/g, function(all, italics){
			return ''+italics+'';
		});

		md = md.replace(/\[(.*)\]\((.*)\)/g, function(all, text, url){
			return ''+text+'';
		});

		md = md.replace(/^>\s((.+\n{0,1})+)/gm, function(all, text){
			text = text.replace(/(\n>\s|\n)/g, '
\n');
			return '
'+text+'
';
		});

		md = md.replace(/^(\*\s.+\n{0,1})+/gm, function(all){
			all = all.replace(/^\*\s/gm, '
');
			return '
'+all+'
';
		});

		md = md.replace(/^([0-9]+\.\s.+\n{0,1})+/gm, function(all){
			all = all.replace(/^[0-9]+\.\s/gm, '
');
			return '
'+all+'
';
		});

		md = md.replace(/\n\n/g, '

');

		md = md.replace(/\n/g, ' ');

		return md;
	}
}

// If we are using node or browserify!
if (module && module.exports) module.exports = tfmarkdown;
<commit_msg>Improved regex.<commit_after>
var tfmarkdown = {
	parse: function(md) {

		// Titles
		md = md.replace(/^(#+)\s(.*)/gm, function(all, hashcount, title){
			var hc = hashcount.length;
			return '<h'+hc+'>'+title+'</h'+hc+'>';
		});
		md = md.replace(/^(.*)\n([=-]{2,})/gm, function(all, title, ttype){
			var hc = ttype[0] === '=' ? '1' : '2';
			return '<h'+hc+'>'+title+'</h'+hc+'>';
		});

		// Blockquotes and code blocks
		md = md.replace(/^>\s((.+\n{0,1})+)/gm, function(all, text){
			text = text.replace(/(\n>\s|\n)/g, '
\n');
			return '
'+text+'
';
		});
		md = md.replace(/^(((\t+|\s{2,}).*\n)+)/gm, function(all, text){
			console.log('---');
			console.log(text);
			console.log('---');
			text = text.replace(/&/g, '&').replace(/</g, '<');
			text = text.replace(/\n/g, '
\n');
			return ''+text+'\n';
		});

		// Ordered and unordered lists
		md = md.replace(/^(\*\s.+\n?)+/gm, function(all){
			all = all.replace(/^\*\s(.*)\n?/gm, '
$1
');
			return '
'+all+'
';
		});
		md = md.replace(/^([0-9]+\.\s.+\n?)+/gm, function(all){
			all = all.replace(/^[0-9]+\.\s(.*)\n?/gm, '
$1
');
			return '
'+all+'
';
		});

		// Paragraphs
		md = md.replace(/(^|\n{2,})([^<])(.*)/g, '\n
$2$3
');

		// Bold, italics and links
		md = md.replace(/(\*\*|__)(.*)(\*\*|__)/g, '$2');
		md = md.replace(/[\*_](.*)[\*_]/g, '$1');
		md = md.replace(/\[(.*?)\]\((.*?)\)/g, '$1');

		// Remove extra line breaks etc
		md = md.replace('
', '');

		return md;
	}
}

// If we are using node or browserify!
if (module && module.exports) module.exports = tfmarkdown;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

 foam.CLASS({
  package: 'foam.nanos.ruler',
  name: 'Rule',

  documentation: 'Rule model represents rules(actions) that need to be applied in case passed object satisfies provided predicate.',

  implements: [
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  javaImports: [
    'foam.core.ContextAware',
    'foam.core.FObject',
    'foam.core.X',
    'foam.core.DirectAgency',
    'foam.nanos.logger.Logger',
    'java.util.Collection',
    'foam.nanos.ruler.RuleGroup'
  ],

  tableColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'documentation',
    'createdBy',
    'lastModifiedBy'
  ],

  searchColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'operation',
    'after',
    'validity'
  ],

  sections: [
    {
      name: 'basicInfo',
      order: 100
    },
    {
      name: '_defaultSection',
      permissionRequired: true
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'id',
      updateMode: 'RO',
      tableWidth: 200,
      section: 'basicInfo'
    },
    {
      class: 'Int',
      name: 'priority',
      documentation: 'Priority defines the order in which rules are to be applied.'+
      'Rules with a higher priority are to be applied first.'+
      'The convention for values is ints that are multiple of 10.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 50,
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'documentation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: {
        class: 'foam.u2.tag.TextArea',
        rows: 12, cols: 80
      },
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'daoKey',
      documentation: 'dao name that the rule is applied on.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return {
          class: 'foam.u2.view.RichChoiceView',
          search: true,
          sections: [
            {
              heading: 'Services',
              dao: X.nSpecDAO.where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            }
          ]
        };
      },
      tableWidth: 125
    },
    {
      class: 'Enum',
      of: 'foam.nanos.ruler.Operations',
      name: 'operation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines when the rules is to be applied: put/removed'
    },
    {
      class: 'Boolean',
      name: 'after',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines if the rule needs to be applied before or after operation is completed'+
      'E.g. on dao.put: before object was stored in a dao or after.'
    },
    {
      class: 'foam.mlang.predicate.PredicateProperty',
      name: 'predicate',
      javaFactory: `
      return foam.mlang.MLang.TRUE;
      `,
      documentation: 'predicate is checked against an object; if returns true, the action is executed.'+
      'Defaults to return true.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'action',
      view: { class: 'foam.u2.view.JSONTextView' },
      documentation: 'The action to be executed if predicates returns true for passed object.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'asyncAction',
      hidden: true,
      documentation: 'The action to be executed asynchronously if predicates returns true for passed object.'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: true,
      documentation: 'Enables the rule.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 70,
      section: 'basicInfo'
    },
    {
      class: 'Boolean',
      name: 'saveHistory',
      value: false,
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Determines if history of rule execution should be saved.',
      help: 'Automatically sets to true when validity is greater than zero.',
      adapt: function(_, nu) {
        return nu || this.validity > 0;
      }
    },
    {
      class: 'Int',
      name: 'validity',
      documentation: 'Validity of the rule (in days) for automatic rescheduling.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      postSet: function(_, nu) {
        if ( nu > 0
          && ! this.saveHistory
        ) {
          this.saveHistory = true;
        }
      }
    },
    {
      class: 'Object',
      name: 'cmd',
      transient: true,
      hidden: true,
      javaFactory: `
        if ( Operations.CREATE == getOperation()
          || Operations.UPDATE == getOperation()
          || Operations.CREATE_OR_UPDATE == getOperation()
        ) {
          return RulerDAO.PUT_CMD;
        }
        return null;
      `
    },
    {
      class: 'DateTime',
      name: 'created',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    }
  ],

  methods: [
    {
      name: 'f',
      type: 'Boolean',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        }
      ],
      javaCode: `
        try {
          return getEnabled()
            && getPredicate().f(
              x.put("NEW", obj).put("OLD", oldObj)
            );
        } catch ( Throwable t ) {
          try {
            return getPredicate().f(obj);
          } catch ( Throwable th ) { }

          ((Logger) x.get("logger")).error(
            "Failed to evaluate predicate of rule: " + getId(), t);
          return false;
        }
      `
    },
    {
      name: 'apply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
        {
          name: 'agency',
          type: 'foam.core.Agency'
        }
      ],
      javaCode: `
        getAction().applyAction(x, obj, oldObj, ruler, rule, agency);
      `
    },
    {
      name: 'asyncApply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
      ],
      javaCode: `
        getAsyncAction().applyAction(x, obj, oldObj, ruler, rule, new DirectAgency());
        if ( ! getAfter() ) {
          ruler.getDelegate().cmd_(x.put("OBJ", obj), getCmd());
        }
      `
    },
    {
      name: 'updateRule',
      type: 'foam.nanos.ruler.Rule',
      documentation: 'since rules are stored as lists in the RulerDAO we use listeners to update them whenever ruleDAO is updated.' +
      'the method provides logic for modifying already stored rule. If not overridden, the incoming rule will be stored in the list as it is.',
      args: [
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        }
      ],
      javaCode: `
      return rule;`
    }
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(`
        public static Rule findById(Collection<Rule> listRule, String passedId) {
          return listRule.stream().filter(rule -> passedId.equals(rule.getId())).findFirst().orElse(null);
        }
        `);
      }
    }
  ]
});
<commit_msg>Import userDAO<commit_after>/**
 * @license
 * Copyright 2019 The FOAM Authors. All Rights Reserved.
 *     http://www.apache.org/licenses/LICENSE-2.0
 */

 foam.CLASS({
  package: 'foam.nanos.ruler',
  name: 'Rule',

  documentation: 'Rule model represents rules(actions) that need to be applied in case passed object satisfies provided predicate.',

  implements: [
    'foam.nanos.auth.CreatedAware',
    'foam.nanos.auth.CreatedByAware',
    'foam.nanos.auth.LastModifiedAware',
    'foam.nanos.auth.LastModifiedByAware'
  ],

  imports: [
    'userDAO?'
  ],

  javaImports: [
    'foam.core.ContextAware',
    'foam.core.FObject',
    'foam.core.X',
    'foam.core.DirectAgency',
    'foam.nanos.logger.Logger',
    'java.util.Collection',
    'foam.nanos.ruler.RuleGroup'
  ],

  tableColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'documentation',
    'createdBy',
    'lastModifiedBy'
  ],

  searchColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    'operation',
    'after',
    'validity'
  ],

  sections: [
    {
      name: 'basicInfo',
      order: 100
    },
    {
      name: '_defaultSection',
      permissionRequired: true
    }
  ],

  properties: [
    {
      class: 'String',
      name: 'id',
      updateMode: 'RO',
      tableWidth: 200,
      section: 'basicInfo'
    },
    {
      class: 'Int',
      name: 'priority',
      documentation: 'Priority defines the order in which rules are to be applied.'+
      'Rules with a higher priority are to be applied first.'+
      'The convention for values is ints that are multiple of 10.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 50,
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'documentation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: {
        class: 'foam.u2.tag.TextArea',
        rows: 12, cols: 80
      },
      section: 'basicInfo'
    },
    {
      class: 'String',
      name: 'daoKey',
      documentation: 'dao name that the rule is applied on.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      view: function(_, X) {
        var E = foam.mlang.Expressions.create();
        return {
          class: 'foam.u2.view.RichChoiceView',
          search: true,
          sections: [
            {
              heading: 'Services',
              dao: X.nSpecDAO.where(E.ENDS_WITH(foam.nanos.boot.NSpec.ID, 'DAO'))
            }
          ]
        };
      },
      tableWidth: 125
    },
    {
      class: 'Enum',
      of: 'foam.nanos.ruler.Operations',
      name: 'operation',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines when the rules is to be applied: put/removed'
    },
    {
      class: 'Boolean',
      name: 'after',
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Defines if the rule needs to be applied before or after operation is completed'+
      'E.g. on dao.put: before object was stored in a dao or after.'
    },
    {
      class: 'foam.mlang.predicate.PredicateProperty',
      name: 'predicate',
      javaFactory: `
      return foam.mlang.MLang.TRUE;
      `,
      documentation: 'predicate is checked against an object; if returns true, the action is executed.'+
      'Defaults to return true.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'action',
      view: { class: 'foam.u2.view.JSONTextView' },
      documentation: 'The action to be executed if predicates returns true for passed object.'
    },
    {
      class: 'FObjectProperty',
      of: 'foam.nanos.ruler.RuleAction',
      name: 'asyncAction',
      hidden: true,
      documentation: 'The action to be executed asynchronously if predicates returns true for passed object.'
    },
    {
      class: 'Boolean',
      name: 'enabled',
      value: true,
      documentation: 'Enables the rule.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      tableWidth: 70,
      section: 'basicInfo'
    },
    {
      class: 'Boolean',
      name: 'saveHistory',
      value: false,
      readPermissionRequired: true,
      writePermissionRequired: true,
      documentation: 'Determines if history of rule execution should be saved.',
      help: 'Automatically sets to true when validity is greater than zero.',
      adapt: function(_, nu) {
        return nu || this.validity > 0;
      }
    },
    {
      class: 'Int',
      name: 'validity',
      documentation: 'Validity of the rule (in days) for automatic rescheduling.',
      readPermissionRequired: true,
      writePermissionRequired: true,
      postSet: function(_, nu) {
        if ( nu > 0
          && ! this.saveHistory
        ) {
          this.saveHistory = true;
        }
      }
    },
    {
      class: 'Object',
      name: 'cmd',
      transient: true,
      hidden: true,
      javaFactory: `
        if ( Operations.CREATE == getOperation()
          || Operations.UPDATE == getOperation()
          || Operations.CREATE_OR_UPDATE == getOperation()
        ) {
          return RulerDAO.PUT_CMD;
        }
        return null;
      `
    },
    {
      class: 'DateTime',
      name: 'created',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      visibility: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      visibility: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    }
  ],

  methods: [
    {
      name: 'f',
      type: 'Boolean',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        }
      ],
      javaCode: `
        try {
          return getEnabled()
            && getPredicate().f(
              x.put("NEW", obj).put("OLD", oldObj)
            );
        } catch ( Throwable t ) {
          try {
            return getPredicate().f(obj);
          } catch ( Throwable th ) { }

          ((Logger) x.get("logger")).error(
            "Failed to evaluate predicate of rule: " + getId(), t);
          return false;
        }
      `
    },
    {
      name: 'apply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
        {
          name: 'agency',
          type: 'foam.core.Agency'
        }
      ],
      javaCode: `
        getAction().applyAction(x, obj, oldObj, ruler, rule, agency);
      `
    },
    {
      name: 'asyncApply',
      args: [
        {
          name: 'x',
          type: 'Context'
        },
        {
          name: 'obj',
          type: 'FObject'
        },
        {
          name: 'oldObj',
          type: 'FObject'
        },
        {
          name: 'ruler',
          type: 'foam.nanos.ruler.RuleEngine'
        },
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        },
      ],
      javaCode: `
        getAsyncAction().applyAction(x, obj, oldObj, ruler, rule, new DirectAgency());
        if ( ! getAfter() ) {
          ruler.getDelegate().cmd_(x.put("OBJ", obj), getCmd());
        }
      `
    },
    {
      name: 'updateRule',
      type: 'foam.nanos.ruler.Rule',
      documentation: 'since rules are stored as lists in the RulerDAO we use listeners to update them whenever ruleDAO is updated.' +
      'the method provides logic for modifying already stored rule. If not overridden, the incoming rule will be stored in the list as it is.',
      args: [
        {
          name: 'rule',
          type: 'foam.nanos.ruler.Rule'
        }
      ],
      javaCode: `
      return rule;`
    }
  ],

  axioms: [
    {
      name: 'javaExtras',
      buildJavaClass: function(cls) {
        cls.extras.push(`
        public static Rule findById(Collection<Rule> listRule, String passedId) {
          return listRule.stream().filter(rule -> passedId.equals(rule.getId())).findFirst().orElse(null);
        }
        `);
      }
    }
  ]
});
<|endoftext|>


<commit_before>import fs from 'fs';
import path from 'path';
import walkdir from 'walkdir';
import minimatch from 'minimatch';
import component from './component';
import getNodes from './utils/get-nodes';
import requirePackageName from 'require-package-name';
import discoverPropertyDep from './utils/discover-property-dep';

function constructComponent(source, name) {
  return source[name].reduce((result, current) =>
    Object.assign(result, {
      [current]: require(path.resolve(__dirname, name, current)),
    }), {});
}

function objectValues(object) {
  return Object.keys(object).map(key => object[key]);
}

const availableParsers = constructComponent(component, 'parser');

const availableDetectors = constructComponent(component, 'detector');

const availableSpecials = constructComponent(component, 'special');

const defaultOptions = {
  withoutDev: false,
  ignoreBinPackage: false,
  ignoreMatches: [
  ],
  ignoreDirs: [
    '.git',
    '.svn',
    '.hg',
    '.idea',
    'node_modules',
    'bower_components',
  ],
  parsers: {
    '*.js': availableParsers.jsx,
    '*.jsx': availableParsers.jsx,
    '*.coffee': availableParsers.coffee,
    '*.litcoffee': availableParsers.coffee,
    '*.coffee.md': availableParsers.coffee,
  },
  detectors: [
    availableDetectors.importDeclaration,
    availableDetectors.requireCallExpression,
    availableDetectors.gruntLoadTaskCallExpression,
  ],
  specials: objectValues(availableSpecials),
};

function getOrDefault(opt, key) {
  return typeof opt[key] !== 'undefined' ? opt[key] : defaultOptions[key];
}

function unifyParser(parsers) {
  return Object.assign({}, ...Object.keys(parsers).map(key => ({
    [key]: parsers[key] instanceof Array ? parsers[key] : [parsers[key]],
  })));
}

function safeDetect(detector, node) {
  try {
    return detector(node);
  } catch (error) {
    return [];
  }
}

function minus(array1, array2) {
  return array1.filter(item => array2.indexOf(item) === -1);
}

function intersect(array1, array2) {
  return array1.filter(item => array2.indexOf(item) !== -1);
}

function unique(array, item) {
  return array.indexOf(item) === -1 ? array.concat([item]) : array;
}

function concat(array, item) {
  return array.concat(item);
}

function isStringArray(obj) {
  return obj instanceof Array && obj.every(item => typeof item === 'string');
}

function getDependencies(dir, filename, deps, parser, detectors) {
  const detect = node =>
    detectors.map(detector => safeDetect(detector, node)).reduce(concat, []);

  return new Promise((resolve, reject) => {
    fs.readFile(filename, 'utf8', (error, content) => {
      if (error) {
        reject(error);
      }

      try {
        resolve(parser(content, filename, deps, dir));
      } catch (syntaxError) {
        reject(syntaxError);
      }
    });
  }).then(ast => {
    // when parser returns string array, skip detector step and treat them as dependencies directly.
    if (isStringArray(ast)) {
      return ast;
    }

    const dependencies = getNodes(ast)
      .map(detect)
      .reduce(concat, [])
      .reduce(unique, [])
      .map(requirePackageName);

    const peerDeps = dependencies
      .map(dep => discoverPropertyDep(dep, 'peerDependencies', deps, dir))
      .reduce(concat, []);

    const optionalDeps = dependencies
      .map(dep => discoverPropertyDep(dep, 'optionalDependencies', deps, dir))
      .reduce(concat, []);

    return dependencies.concat(peerDeps).concat(optionalDeps);
  });
}

function checkFile(dir, filename, deps, devDeps, parsers, detectors) {
  const basename = path.basename(filename);
  const targets = [].concat(...Object.keys(parsers)
    .filter(glob => minimatch(basename, glob, { dot: true }))
    .map(key => parsers[key]));

  return targets.map(parser =>
    getDependencies(dir, filename, deps.concat(devDeps), parser, detectors)
      .then(used => ({
        dependencies: minus(deps, used),
        devDependencies: minus(devDeps, used),
      }), error => ({
        dependencies: deps,
        devDependencies: devDeps,
        invalidFiles: {
          [filename]: error,
        },
      })));
}

function checkDirectory(dir, ignoreDirs, deps, devDeps, parsers, detectors) {
  return new Promise(resolve => {
    const promises = [];
    const finder = walkdir(dir, { 'no_recurse': true });

    finder.on('directory', subdir =>
      ignoreDirs.indexOf(path.basename(subdir)) === -1 &&
      promises.push(
        checkDirectory(subdir, ignoreDirs, deps, devDeps, parsers, detectors)));

    finder.on('file', filename =>
      promises.push(
        ...checkFile(dir, filename, deps, devDeps, parsers, detectors)));

    finder.on('error', (dirPath, error) =>
      promises.push(Promise.resolve({
        dependencies: deps,
        devDependencies: devDeps,
        invalidDirs: {
          [dirPath]: error,
        },
      })));

    finder.on('end', () =>
      resolve(Promise.all(promises).then(results =>
        results.reduce((obj, current) => ({
          dependencies: intersect(obj.dependencies, current.dependencies),
          devDependencies: intersect(obj.devDependencies, current.devDependencies),
          invalidFiles: Object.assign(obj.invalidFiles, current.invalidFiles),
          invalidDirs: Object.assign(obj.invalidDirs, current.invalidDirs),
        }), {
          dependencies: deps,
          devDependencies: devDeps,
          invalidFiles: {},
          invalidDirs: {},
        }))));
  });
}

function isIgnored(ignoreMatches, dependency) {
  return ignoreMatches.some(match => minimatch(dependency, match));
}

function hasBin(rootDir, dependency) {
  try {
    const depPkg = require(path.join(rootDir, 'node_modules', dependency, 'package.json'));
    return depPkg.hasOwnProperty('bin');
  } catch (error) {
    return false;
  }
}

function filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, dependencies) {
  return Object.keys(dependencies).filter(dependency =>
    ignoreBinPackage && hasBin(rootDir, dependency) ||
    isIgnored(ignoreMatches, dependency)
    ? false
    : true);
}

export default function depcheck(rootDir, options, cb) {
  const withoutDev = getOrDefault(options, 'withoutDev');
  const ignoreBinPackage = getOrDefault(options, 'ignoreBinPackage');
  const ignoreMatches = getOrDefault(options, 'ignoreMatches');
  const ignoreDirs = defaultOptions.ignoreDirs.concat(options.ignoreDirs).reduce(unique, []);

  const detectors = getOrDefault(options, 'detectors');
  const parsers = Object.assign(
    { '*': getOrDefault(options, 'specials') },
    unifyParser(getOrDefault(options, 'parsers')));

  const metadata = options.package || require(path.join(rootDir, 'package.json'));
  const dependencies = metadata.dependencies || {};
  const devDependencies = metadata.devDependencies || {};
  const deps = filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, dependencies);
  const devDeps = filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, withoutDev ? [] : devDependencies);

  return checkDirectory(rootDir, ignoreDirs, deps, devDeps, parsers, detectors)
    .then(cb);
}

depcheck.parser = availableParsers;
depcheck.detector = availableDetectors;
depcheck.special = availableSpecials;
<commit_msg>Fix the nested peer dependencies issue.<commit_after>import fs from 'fs';
import path from 'path';
import walkdir from 'walkdir';
import minimatch from 'minimatch';
import component from './component';
import getNodes from './utils/get-nodes';
import requirePackageName from 'require-package-name';
import discoverPropertyDep from './utils/discover-property-dep';

function constructComponent(source, name) {
  return source[name].reduce((result, current) =>
    Object.assign(result, {
      [current]: require(path.resolve(__dirname, name, current)),
    }), {});
}

function objectValues(object) {
  return Object.keys(object).map(key => object[key]);
}

const availableParsers = constructComponent(component, 'parser');

const availableDetectors = constructComponent(component, 'detector');

const availableSpecials = constructComponent(component, 'special');

const defaultOptions = {
  withoutDev: false,
  ignoreBinPackage: false,
  ignoreMatches: [
  ],
  ignoreDirs: [
    '.git',
    '.svn',
    '.hg',
    '.idea',
    'node_modules',
    'bower_components',
  ],
  parsers: {
    '*.js': availableParsers.jsx,
    '*.jsx': availableParsers.jsx,
    '*.coffee': availableParsers.coffee,
    '*.litcoffee': availableParsers.coffee,
    '*.coffee.md': availableParsers.coffee,
  },
  detectors: [
    availableDetectors.importDeclaration,
    availableDetectors.requireCallExpression,
    availableDetectors.gruntLoadTaskCallExpression,
  ],
  specials: objectValues(availableSpecials),
};

function getOrDefault(opt, key) {
  return typeof opt[key] !== 'undefined' ? opt[key] : defaultOptions[key];
}

function unifyParser(parsers) {
  return Object.assign({}, ...Object.keys(parsers).map(key => ({
    [key]: parsers[key] instanceof Array ? parsers[key] : [parsers[key]],
  })));
}

function safeDetect(detector, node) {
  try {
    return detector(node);
  } catch (error) {
    return [];
  }
}

function minus(array1, array2) {
  return array1.filter(item => array2.indexOf(item) === -1);
}

function intersect(array1, array2) {
  return array1.filter(item => array2.indexOf(item) !== -1);
}

function unique(array, item) {
  return array.indexOf(item) === -1 ? array.concat([item]) : array;
}

function concat(array, item) {
  return array.concat(item);
}

function isStringArray(obj) {
  return obj instanceof Array && obj.every(item => typeof item === 'string');
}

function getDependencies(dir, filename, deps, parser, detectors) {
  const detect = node =>
    detectors.map(detector => safeDetect(detector, node)).reduce(concat, []);

  return new Promise((resolve, reject) => {
    fs.readFile(filename, 'utf8', (error, content) => {
      if (error) {
        reject(error);
      }

      try {
        resolve(parser(content, filename, deps, dir));
      } catch (syntaxError) {
        reject(syntaxError);
      }
    });
  }).then(ast => {
    // when parser returns string array, skip detector step and treat them as dependencies directly.
    if (isStringArray(ast)) {
      return ast;
    }

    const dependencies = getNodes(ast)
      .map(detect)
      .reduce(concat, [])
      .reduce(unique, [])
      .map(requirePackageName);

    const peerDeps = dependencies
      .map(dep => discoverPropertyDep(dep, 'peerDependencies', deps, dir))
      .reduce(concat, []);

    const optionalDeps = dependencies
      .map(dep => discoverPropertyDep(dep, 'optionalDependencies', deps, dir))
      .reduce(concat, []);

    return dependencies.concat(peerDeps).concat(optionalDeps);
  });
}

function checkFile(dir, filename, deps, devDeps, parsers, detectors) {
  const basename = path.basename(filename);
  const targets = [].concat(...Object.keys(parsers)
    .filter(glob => minimatch(basename, glob, { dot: true }))
    .map(key => parsers[key]));

  return targets.map(parser =>
    getDependencies(dir, filename, deps.concat(devDeps), parser, detectors)
      .then(used => ({
        dependencies: minus(deps, used),
        devDependencies: minus(devDeps, used),
      }), error => ({
        dependencies: deps,
        devDependencies: devDeps,
        invalidFiles: {
          [filename]: error,
        },
      })));
}

function checkDirectory(dir, rootDir, ignoreDirs, deps, devDeps, parsers, detectors) {
  return new Promise(resolve => {
    const promises = [];
    const finder = walkdir(dir, { 'no_recurse': true });

    finder.on('directory', subdir =>
      ignoreDirs.indexOf(path.basename(subdir)) === -1 &&
      promises.push(
        checkDirectory(subdir, rootDir, ignoreDirs, deps, devDeps, parsers, detectors)));

    finder.on('file', filename =>
      promises.push(
        ...checkFile(rootDir, filename, deps, devDeps, parsers, detectors)));

    finder.on('error', (dirPath, error) =>
      promises.push(Promise.resolve({
        dependencies: deps,
        devDependencies: devDeps,
        invalidDirs: {
          [dirPath]: error,
        },
      })));

    finder.on('end', () =>
      resolve(Promise.all(promises).then(results =>
        results.reduce((obj, current) => ({
          dependencies: intersect(obj.dependencies, current.dependencies),
          devDependencies: intersect(obj.devDependencies, current.devDependencies),
          invalidFiles: Object.assign(obj.invalidFiles, current.invalidFiles),
          invalidDirs: Object.assign(obj.invalidDirs, current.invalidDirs),
        }), {
          dependencies: deps,
          devDependencies: devDeps,
          invalidFiles: {},
          invalidDirs: {},
        }))));
  });
}

function isIgnored(ignoreMatches, dependency) {
  return ignoreMatches.some(match => minimatch(dependency, match));
}

function hasBin(rootDir, dependency) {
  try {
    const depPkg = require(path.join(rootDir, 'node_modules', dependency, 'package.json'));
    return depPkg.hasOwnProperty('bin');
  } catch (error) {
    return false;
  }
}

function filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, dependencies) {
  return Object.keys(dependencies).filter(dependency =>
    ignoreBinPackage && hasBin(rootDir, dependency) ||
    isIgnored(ignoreMatches, dependency)
    ? false
    : true);
}

export default function depcheck(rootDir, options, cb) {
  const withoutDev = getOrDefault(options, 'withoutDev');
  const ignoreBinPackage = getOrDefault(options, 'ignoreBinPackage');
  const ignoreMatches = getOrDefault(options, 'ignoreMatches');
  const ignoreDirs = defaultOptions.ignoreDirs.concat(options.ignoreDirs).reduce(unique, []);

  const detectors = getOrDefault(options, 'detectors');
  const parsers = Object.assign(
    { '*': getOrDefault(options, 'specials') },
    unifyParser(getOrDefault(options, 'parsers')));

  const metadata = options.package || require(path.join(rootDir, 'package.json'));
  const dependencies = metadata.dependencies || {};
  const devDependencies = metadata.devDependencies || {};
  const deps = filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, dependencies);
  const devDeps = filterDependencies(rootDir, ignoreBinPackage, ignoreMatches, withoutDev ? [] : devDependencies);

  return checkDirectory(rootDir, rootDir, ignoreDirs, deps, devDeps, parsers, detectors)
    .then(cb);
}

depcheck.parser = availableParsers;
depcheck.detector = availableDetectors;
depcheck.special = availableSpecials;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2014 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.
 */

/** Collision detection manager. **/
foam.CLASS({
  package: 'foam.physics',
  name: 'Collider',

  documentation: 'Apply physics when objects collide.',

  topics: [ 'onTick' ],

  properties: [
    {
      class: 'Boolean',
      name: 'bounceOnWalls'
    },
    {
      name: 'bounds',
      hidden: true
    },
    {
      name: 'children',
      factory: function() { return []; },
      hidden: true
    },
    {
      class: 'Boolean',
      name: 'stopped_',
      value: true,
      hidden: true
    }
  ],

  methods: [
    function updateChild(c) {
      if ( this.bounceOnWalls && this.bounds ) {

        if ( c.left_   < this.bounds.x      ) { c.vx =  Math.abs(c.vx); c.x++; }
        if ( c.top_    < this.bounds.y      ) { c.vy =  Math.abs(c.vy); c.y++; }
        if ( c.right_  > this.bounds.width  ) { c.vx = -Math.abs(c.vx); c.x--; }
        if ( c.bottom_ > this.bounds.height ) { c.vy = -Math.abs(c.vy); c.y--; }
      }
    },

    function updateChildren() {
      var cs = this.children;
      for ( var i = 0 ; i < cs.length ; i++ ) {
        this.updateChild(cs[i]);
      }
    },

    function detectCollisions() {
      /* implicit k-d-tree divide-and-conquer algorithm */
      this.detectCollisions_(0, this.children.length-1, 'x', false, '');

      // TODO: put back above line when properly supports mixing circles and squares
      // this.detectCollisions__(0, this.children.length-1, 'x', false, '');
    },

    function detectCollisions__(start, end) {
      /*
        Simple O(n^2) algorithm, used by more complex algorithm
        once data is partitioned.
      */
      var cs = this.children;
      for ( var i = start ; i <= end ; i++ ) {
        var c1 = cs[i];
        for ( var j = i+1 ; j <= end ; j++ ) {
          var c2 = cs[j];
          if ( c1.intersects && c1.intersects(c2) ) this.collide(c1, c2);
        }
      }
    },

    function choosePivot(start, end, axis) {
      var p = 0, cs = this.children, n = end-start;
      for ( var i = start ; i <= end ; i++ ) p += cs[i][axis] / n;
      return p;
    },

    // TODO: Add support for rectangular objects
    function detectCollisions_(start, end, axis, oneD) {
      if ( start >= end ) return;

      var cs = this.children;
      var pivot = this.choosePivot(start, end, axis);
      var nextAxis = oneD ? axis : axis === 'x' ? 'y' : 'x' ;

      var p = start;
      for ( var i = start ; i <= end ; i++ ) {
        var c = cs[i];
        if ( c[axis] - c.radius < pivot ) {
          var t = cs[p];
          cs[p] = c;
          cs[i] = t;
          p++;
        }
      }

      if ( p === end + 1 ) {
        if ( oneD ) {
          this.detectCollisions__(start, end);
        } else {
          this.detectCollisions_(start, end, nextAxis, true);
        }
      } else {
        this.detectCollisions_(start, p-1, nextAxis, oneD);

        p--;
        for ( var i = p ; i >= start ; i-- ) {
          var c = cs[i];
          if ( c[axis] + c.radius > pivot ) {
            var t = cs[p];
            cs[p] = c;
            cs[i] = t;
            p--;
          }
        }
        if ( p === start-1 ) {
          if ( oneD ) {
            this.detectCollisions__(start, end);
          } else {
            this.detectCollisions_(start, end, nextAxis, true);
          }
        } else {
          this.detectCollisions_(p+1, end, nextAxis, oneD);
        }
      }
    },

    // TODO: add support for rectangles
    function collide(c1, c2) {
      c1.collideWith && c1.collideWith(c2);
      c2.collideWith && c2.collideWith(c1);

      if ( ! c1.mass || ! c2.mass ) return;

      var a  = Math.atan2(c2.y-c1.y, c2.x-c1.x);
      var m1 =  c1.momentumAtAngle(a);
      var m2 = -c2.momentumAtAngle(a);
      var m  = ( m1 + m2 )/2;

      // ensure a minimum amount of momentum so that objects don't overlap
      if ( m >= 0 ) {
        m = Math.max(1, m);
        var tMass = c1.mass + c2.mass;
        c1.applyMomentum(-m * c2.mass/tMass, a);
        c2.applyMomentum( m * c1.mass/tMass, a);
      }
    },

    // add one or more components to be monitored for collisions
    function add() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        this.children.push(arguments[i]);
      }
      return this;
    },

    function findChildAt(x, y) {
      var c2 = { x: x, y: y, r: 1 };

      var cs = this.children;
      // Start from the end to find the child in the foreground
      for ( var i = cs.length-1 ; i >= 0 ; i-- ) {
        var c1 = cs[i];
        if ( c1.intersects(c2) ) return c1;
      }
    },

    function selectChildrenAt(x, y) {
      var c2 = { x: x, y: y, r: 1 };

      var children = [];
      var cs = this.children;
      for ( var i = 0 ; i < cs.length ; i++ ) {
        var c1 = cs[i];
        if ( c1.intersects(c2) ) children.push(c1);
      }
      return children;
    },

    function remove() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        foam.Array.remove(this.children, arguments[i]);
      }
      return this;
    },

    function detach() {
      this.stopped_ = true;
      this.children = [];
    }
  ],

  actions: [
    {
      name: 'start',
      isEnabled: function(stopped_) { return stopped_; },
      code: function start() {
        this.stopped_ = false;
        this.tick();
      }
    },
    {
      name: 'stop',
      isEnabled: function(stopped_) { return ! stopped_; },
      code: function start() { this.stopped_ = true; }
    }
  ],

  listeners: [
    {
      name: 'tick',
      isFramed: true,
      code: function tick() {
        if ( this.stopped_ ) return;
        this.onTick.pub();
        this.detectCollisions();
        this.updateChildren();

        this.tick();
      }
    }
  ]
});
<commit_msg>Make Collider not crash if exception thrown because an object has been removed.<commit_after>/**
 * @license
 * Copyright 2014 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.
 */

/** Collision detection manager. **/
foam.CLASS({
  package: 'foam.physics',
  name: 'Collider',

  documentation: 'Apply physics when objects collide.',

  topics: [ 'onTick' ],

  properties: [
    {
      class: 'Boolean',
      name: 'bounceOnWalls'
    },
    {
      name: 'bounds',
      hidden: true
    },
    {
      name: 'children',
      factory: function() { return []; },
      hidden: true
    },
    {
      class: 'Boolean',
      name: 'stopped_',
      value: true,
      hidden: true
    }
  ],

  methods: [
    function updateChild(c) {
      if ( this.bounceOnWalls && this.bounds ) {

        if ( c.left_   < this.bounds.x      ) { c.vx =  Math.abs(c.vx); c.x++; }
        if ( c.top_    < this.bounds.y      ) { c.vy =  Math.abs(c.vy); c.y++; }
        if ( c.right_  > this.bounds.width  ) { c.vx = -Math.abs(c.vx); c.x--; }
        if ( c.bottom_ > this.bounds.height ) { c.vy = -Math.abs(c.vy); c.y--; }
      }
    },

    function updateChildren() {
      var cs = this.children;
      for ( var i = 0 ; i < cs.length ; i++ ) {
        this.updateChild(cs[i]);
      }
    },

    function detectCollisions() {
      /* implicit k-d-tree divide-and-conquer algorithm */
      // this.detectCollisions_(0, this.children.length-1, 'x', false, '');
      // TODO: put back above line when properly supports mixing circles and squares
      this.detectCollisions__(0, this.children.length-1, 'x', false, '');
    },

    function detectCollisions__(start, end) {
      /*
        Simple O(n^2) algorithm, used by more complex algorithm
        once data is partitioned.
      */
      var cs = this.children;
      for ( var i = start ; i <= end ; i++ ) {
        var c1 = cs[i];
        for ( var j = i+1 ; j <= end ; j++ ) {
          var c2 = cs[j];
          try {
            if ( c1.intersects && c1.intersects(c2) ) this.collide(c1, c2);
          } catch (x) {
            console.warn('Exception in collider', x);
          }
        }
      }
    },

    function choosePivot(start, end, axis) {
      var p = 0, cs = this.children, n = end-start;
      for ( var i = start ; i <= end ; i++ ) p += cs[i][axis] / n;
      return p;
    },

    // TODO: Add support for rectangular objects
    function detectCollisions_(start, end, axis, oneD) {
      if ( start >= end ) return;

      var cs = this.children;
      var pivot = this.choosePivot(start, end, axis);
      var nextAxis = oneD ? axis : axis === 'x' ? 'y' : 'x' ;

      var p = start;
      for ( var i = start ; i <= end ; i++ ) {
        var c = cs[i];
        if ( c[axis] - c.radius < pivot ) {
          var t = cs[p];
          cs[p] = c;
          cs[i] = t;
          p++;
        }
      }

      if ( p === end + 1 ) {
        if ( oneD ) {
          this.detectCollisions__(start, end);
        } else {
          this.detectCollisions_(start, end, nextAxis, true);
        }
      } else {
        this.detectCollisions_(start, p-1, nextAxis, oneD);

        p--;
        for ( var i = p ; i >= start ; i-- ) {
          var c = cs[i];
          if ( c[axis] + c.radius > pivot ) {
            var t = cs[p];
            cs[p] = c;
            cs[i] = t;
            p--;
          }
        }
        if ( p === start-1 ) {
          if ( oneD ) {
            this.detectCollisions__(start, end);
          } else {
            this.detectCollisions_(start, end, nextAxis, true);
          }
        } else {
          this.detectCollisions_(p+1, end, nextAxis, oneD);
        }
      }
    },

    // TODO: add support for rectangles
    function collide(c1, c2) {
      c1.collideWith && c1.collideWith(c2);
      c2.collideWith && c2.collideWith(c1);

      if ( ! c1.mass || ! c2.mass ) return;

      var a  = Math.atan2(c2.y-c1.y, c2.x-c1.x);
      var m1 =  c1.momentumAtAngle(a);
      var m2 = -c2.momentumAtAngle(a);
      var m  = ( m1 + m2 )/2;

      // ensure a minimum amount of momentum so that objects don't overlap
      if ( m >= 0 ) {
        m = Math.max(1, m);
        var tMass = c1.mass + c2.mass;
        c1.applyMomentum(-m * c2.mass/tMass, a);
        c2.applyMomentum( m * c1.mass/tMass, a);
      }
    },

    // add one or more components to be monitored for collisions
    function add() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        this.children.push(arguments[i]);
      }
      return this;
    },

    function findChildAt(x, y) {
      var c2 = { x: x, y: y, r: 1 };

      var cs = this.children;
      // Start from the end to find the child in the foreground
      for ( var i = cs.length-1 ; i >= 0 ; i-- ) {
        var c1 = cs[i];
        if ( c1.intersects(c2) ) return c1;
      }
    },

    function selectChildrenAt(x, y) {
      var c2 = { x: x, y: y, r: 1 };

      var children = [];
      var cs = this.children;
      for ( var i = 0 ; i < cs.length ; i++ ) {
        var c1 = cs[i];
        if ( c1.intersects(c2) ) children.push(c1);
      }
      return children;
    },

    function remove() {
      for ( var i = 0 ; i < arguments.length ; i++ ) {
        foam.Array.remove(this.children, arguments[i]);
      }
      return this;
    },

    function detach() {
      this.stopped_ = true;
      this.children = [];
    }
  ],

  actions: [
    {
      name: 'start',
      isEnabled: function(stopped_) { return stopped_; },
      code: function start() {
        this.stopped_ = false;
        this.tick();
      }
    },
    {
      name: 'stop',
      isEnabled: function(stopped_) { return ! stopped_; },
      code: function start() { this.stopped_ = true; }
    }
  ],

  listeners: [
    {
      name: 'tick',
      isFramed: true,
      code: function tick() {
        if ( this.stopped_ ) return;
        this.onTick.pub();
        this.detectCollisions();
        this.updateChildren();

        this.tick();
      }
    }
  ]
});
<|endoftext|>


<commit_before>// cheap way of doing AA
c.width = 32e2, c.height = 18e2, // 16:9 aspect ratio
//c.width = 192, c.height = 108; // battery saving

b = new AudioContext;
a = b.createScriptProcessor(512, t = 1, K = 1);
a.connect(b.destination);

// bass & arpeggio sequencers
// (compresses better when inlined)

// s=(notes,octave,rate,len) =>
//   31 & t * Math.pow(2, notes[(t>>rate) % len] / 12 - octave)

// music
X = a.onaudioprocess = a =>
  a.outputBuffer.getChannelData(f=0).map(_ =>
    a.outputBuffer.getChannelData(0)[f++] =
    (
      (
        // kick drum
        ((
          // envelope
          K = 1e4 / (
            t & 16382
          )
        ) & 1) * 30

        // bass
        + (31 & t * Math.pow(2,
          // melody
          '7050'
        [(t>>
          // rate
          17
        ) %
          // melody length
          4
        ] / 12 -
          // octave
          4
        )) / K
      )

      // turn off above instruments after a while
      * !(t>>22)

      // hihat TODO improve/golf envelope
      + (t % 100 * t & 128) * Math.min(.2, (1e1 / ((t>>3) % 512)))

      // enable hihat after t>>19
      * !!(t>>19)

      // arpeggio
      + (31 & t * Math.pow(2, (
        // melody
        ((t>>17) % 2 ? '027' : '037')
      )[(t>>(
        // rate
        13 - 3 * (t>>20) % 12
      )) %
        // melody length
        4
      ] / 12 -
        // octave
        1
      )) / K

      // enable arpeggio after t>>20
      * !!(t>>20)
    ) * (
      // fade out
      X = Math.min(1, Math.max(0, 1e1-t++/5e5))
    ) / 2e2
  );

// gfx
g = c.getContext`webgl`;
P = g.createProgram();

// NOTE: 2nd argument to drawArrays used to be 0, but undefined works
r = a => g.drawArrays(g.TRIANGLE_FAN,
  // x-res, y-res, time (s), fade out
  g.uniform4f(g.getUniformLocation(P, 'a'), c.width, c.height, a / 1e3, X),
  3,
  // 1, 0, kick envelope, unused
  g.uniform4f(g.getUniformLocation(P, 'b'), 1, 0, .2/K, requestAnimationFrame(r))
);

// vertex shader
g.shaderSource(S=g.createShader(g.VERTEX_SHADER), require("./vertex.glsl"));
g.compileShader(S);g.attachShader(P,S);

// fragment shader
g.shaderSource(S=g.createShader(g.FRAGMENT_SHADER), require("./fragment.glsl"));
g.compileShader(S);g.attachShader(P,S);

// Log compilation errors
// if (!g.getShaderParameter(S, 35713)) { // COMPILE_STATUS = 35713
//   throw g.getShaderInfoLog(S);
// }

g.bindBuffer(g.ARRAY_BUFFER, g.createBuffer(c.parentElement.style.margin = 0));
// 1st argument to enableVertexAttribArray used to be 0, but undefined works
// 1st argument to vertexAttribPointer used to be 0, but undefined works
g.vertexAttribPointer(
  g.enableVertexAttribArray(
    g.bufferData(g.ARRAY_BUFFER, Int8Array.of(-3, 1, 1, -3, 1, 1), g.STATIC_DRAW)
  ),
2, g.BYTE, r(c.style.height = '1e2vh'), g.linkProgram(P), g.useProgram(P));
<commit_msg>golf (+14)<commit_after>// cheap way of doing AA
c.width = 32e2, c.height = 18e2, // 16:9 aspect ratio
//c.width = 192, c.height = 108; // battery saving

b = new AudioContext;
a = b.createScriptProcessor(512, t = 1, K = 1);
a.connect(b.destination);

// bass & arpeggio sequencers
// (compresses better when inlined)

// s=(notes,octave,rate,len) =>
//   31 & t * Math.pow(2, notes[(t>>rate) % len] / 12 - octave)

// music
X = a.onaudioprocess = a =>
  a.outputBuffer.getChannelData(f=0).map(_ =>
    a.outputBuffer.getChannelData(0)[f++] =
    (
      (
        // kick drum
        ((
          // envelope
          K = 1e4 / (
            t & 16382
          )
        ) & 1) * 30

        // bass
        + (31 & t * Math.pow(2,
          // melody
          '7050'
        [(t>>
          // rate
          17
        ) %
          // melody length
          4
        ] / 12 -
          // octave
          4
        )) / K
      )

      // turn off above instruments after a while
      * !(t>>22)

      // hihat TODO improve/golf envelope
      + (t % 100 * t & 128) * Math.min(.2, 1e1 / ((t>>3) % 512))

      // enable hihat after t>>19
      * !!(t>>19)

      // arpeggio
      + (31 & t * Math.pow(2, (
        // melody
        ((t>>17) % 2 ? '027' : '037')
      )[(t>>(
        // rate
        13 - 3 * (t>>20) % 12
      )) %
        // melody length
        4
      ] / 12 -
        // octave
        1
      )) / K

      // enable arpeggio after t>>20
      * !!(t>>20)
    ) * (
      // fade out
      X = Math.min(Math.max(0, 1e1-t++/5e5), 1)
    ) / 2e2
  );

// gfx
g = c.getContext`webgl`;
P = g.createProgram();

// NOTE: 2nd argument to drawArrays used to be 0, but undefined works
r = a => g.drawArrays(g.TRIANGLE_FAN,
  // x-res, y-res, time (s), fade out
  g.uniform4f(g.getUniformLocation(P, 'a'), c.width, c.height, a / 1e3, X),
  3,
  // 1, 0, kick envelope, unused
  g.uniform4f(g.getUniformLocation(P, 'b'), 1, 0, .2/K, requestAnimationFrame(r))
);

// vertex shader
g.shaderSource(S=g.createShader(g.VERTEX_SHADER), require("./vertex.glsl"));
g.compileShader(S);g.attachShader(P,S);

// fragment shader
g.shaderSource(S=g.createShader(g.FRAGMENT_SHADER), require("./fragment.glsl"));
g.compileShader(S);g.attachShader(P,S);

// Log compilation errors
// if (!g.getShaderParameter(S, 35713)) { // COMPILE_STATUS = 35713
//   throw g.getShaderInfoLog(S);
// }

g.bindBuffer(g.ARRAY_BUFFER, g.createBuffer(c.parentElement.style.margin = 0));
// 1st argument to enableVertexAttribArray used to be 0, but undefined works
// 1st argument to vertexAttribPointer used to be 0, but undefined works
g.vertexAttribPointer(
  g.enableVertexAttribArray(
    g.bufferData(g.ARRAY_BUFFER, Int8Array.of(-3, 1, 1, -3, 1, 1), g.STATIC_DRAW)
  ),
2, g.BYTE, r(c.style.height = '1e2vh'), g.linkProgram(P), g.useProgram(P));
<|endoftext|>


<commit_before>"use strict";
var APP_ID = undefined;  // TODO replace with your app ID (OPTIONAL).

var GAME_LENGTH = 5;  // The number of questions per trivia game.
var GAME_STATES = {
    TRIVIA: "_TRIVIAMODE", // Asking trivia questions.
    START: "_STARTMODE", // Entry point, start the game.
    HELP: "_HELPMODE" // The user is asking for help.
};
var questions = require("./questions");

/**
 * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods.
 * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in.
 */
var languageString = {
    "en-US": {
        "translation": {
            "QUESTIONS" : questions,
            "GAME_NAME" : "Capital quiz by Elroy and Rocco", // Be sure to change this for your skill.
            "HELP_MESSAGE": "I will ask you %s questions. Respond with the correct answer.",
            "REPEAT_QUESTION_MESSAGE": "To repeat the last question, say, repeat. ",
            "ASK_MESSAGE_START": "Would you like to start playing?",
            "HELP_REPROMPT": "To give an answer to a question, respond with the city name of your choice.",
            "STOP_MESSAGE": "Would you like to keep playing?",
            "CANCEL_MESSAGE": "Ok, let\'s play again soon.",
            "NO_MESSAGE": "Ok, we\'ll play another time. Goodbye!",
            "TRIVIA_UNHANDLED": "Try saying a number between 1 and %s",
            "HELP_UNHANDLED": "Say yes to continue, or no to end the game.",
            "START_UNHANDLED": "Say start to start a new game.",
            "NEW_GAME_MESSAGE": "Welcome to %s. ",
            "WELCOME_MESSAGE": "I will ask you %s questions, try to get as many right as you can. " +
            "Wub a lub a dub dub that's my catchphrase. You know how I always say",
            "ANSWER_CORRECT_MESSAGE": "correct. ",
            "ANSWER_WRONG_MESSAGE": "wrong. ",
            "CORRECT_ANSWER_MESSAGE": "The correct answer is %s: %s. ",
            "ANSWER_IS_MESSAGE": "That answer is ",
            "TELL_QUESTION_MESSAGE": "Question %s. %s ",
            "GAME_OVER_MESSAGE": "You got %s out of %s questions correct. Thank you for playing!",
            "SCORE_IS_MESSAGE": "Your score is %s. ",
            "CAPITAL_QUESTION": "What is the capital of %s?",
            "CAPITAL_ANSWER": "The capital of %s is %s"
        }
    }
};

var Alexa = require("alexa-sdk");
var APP_ID = undefined;  // TODO replace with your app ID (OPTIONAL).

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.appId = APP_ID;
    // To enable string internationalization (i18n) features, set a resources object.
    alexa.resources = languageString;
    alexa.registerHandlers(newSessionHandlers, startStateHandlers, triviaStateHandlers, helpStateHandlers);
    alexa.execute();
};

var newSessionHandlers = {
    "LaunchRequest": function () {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", true);
    }
    ,
    "AMAZON.StartOverIntent": function() {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", true);
    },
    "AMAZON.HelpIntent": function() {
        this.handler.state = GAME_STATES.HELP;
        this.emitWithState("helpTheUser", true);
    },
    "Unhandled": function () {
        var speechOutput = this.t("START_UNHANDLED");
        this.emit(":ask", speechOutput, speechOutput);
    }
};

var startStateHandlers = Alexa.CreateStateHandler(GAME_STATES.START, {
    "StartGame": function (newGame) {
        var speechOutput = newGame ? this.t("NEW_GAME_MESSAGE", this.t("GAME_NAME")) + this.t("WELCOME_MESSAGE", GAME_LENGTH.toString()) : "";
        // Select GAME_LENGTH questions for the game
        var translatedQuestions = this.t("QUESTIONS");
        var gameQuestions = populateGameQuestions(translatedQuestions);

        var currentQuestionIndex = 0;
        var country = translatedQuestions[gameQuestions[currentQuestionIndex]].country;
        var spokenQuestion = this.t("CAPITAL_QUESTION", country);
        var repromptText = this.t("TELL_QUESTION_MESSAGE", "1", spokenQuestion);

        speechOutput += repromptText;

        var answer = translatedQuestions[gameQuestions[currentQuestionIndex]].capital;
        var answerText = this.t("CAPITAL_ANSWER", country, answer);

        Object.assign(this.attributes, {
            "speechOutput": repromptText,
            "repromptText": repromptText,
            "currentQuestionIndex": currentQuestionIndex,
            "questions": gameQuestions,
            "score": 0,
            "correctAnswer": answer,
            "correctAnswerText": answerText
        });

        // Set the current state to trivia mode. The skill will now use handlers defined in triviaStateHandlers
        this.handler.state = GAME_STATES.TRIVIA;
        this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), repromptText);
    }
});

var triviaStateHandlers = Alexa.CreateStateHandler(GAME_STATES.TRIVIA, {
    "AnswerIntent": function () {
        handleUserGuess.call(this, false);
    },
    "DontKnowIntent": function () {
        handleUserGuess.call(this, true);
    },
    "AMAZON.StartOverIntent": function () {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        this.emit(":ask", this.attributes["speechOutput"], this.attributes["repromptText"]);
    },
    "AMAZON.HelpIntent": function () {
        this.handler.state = GAME_STATES.HELP;
        this.emitWithState("helpTheUser", false);
    },
    "AMAZON.StopIntent": function () {
        this.handler.state = GAME_STATES.HELP;
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "AMAZON.CancelIntent": function () {
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "Unhandled": function () {
        var speechOutput = this.t("TRIVIA_UNHANDLED", ANSWER_COUNT.toString());
        this.emit(":ask", speechOutput, speechOutput);
    },
    "SessionEndedRequest": function () {
        console.log("Session ended in trivia state: " + this.event.request.reason);
    }
});

var helpStateHandlers = Alexa.CreateStateHandler(GAME_STATES.HELP, {
    "helpTheUser": function (newGame) {
        var askMessage = newGame ? this.t("ASK_MESSAGE_START") : this.t("REPEAT_QUESTION_MESSAGE") + this.t("STOP_MESSAGE");
        var speechOutput = this.t("HELP_MESSAGE", GAME_LENGTH) + askMessage;
        var repromptText = this.t("HELP_REPROMPT") + askMessage;
        this.emit(":ask", speechOutput, repromptText);
    },
    "AMAZON.StartOverIntent": function () {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        var newGame = (this.attributes["speechOutput"] && this.attributes["repromptText"]) ? false : true;
        this.emitWithState("helpTheUser", newGame);
    },
    "AMAZON.HelpIntent": function() {
        var newGame = (this.attributes["speechOutput"] && this.attributes["repromptText"]) ? false : true;
        this.emitWithState("helpTheUser", newGame);
    },
    "AMAZON.YesIntent": function() {
        if (this.attributes["speechOutput"] && this.attributes["repromptText"]) {
            this.handler.state = GAME_STATES.TRIVIA;
            this.emitWithState("AMAZON.RepeatIntent");
        } else {
            this.handler.state = GAME_STATES.START;
            this.emitWithState("StartGame", false);
        }
    },
    "AMAZON.NoIntent": function() {
        var speechOutput = this.t("NO_MESSAGE");
        this.emit(":tell", speechOutput);
    },
    "AMAZON.StopIntent": function () {
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "AMAZON.CancelIntent": function () {
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "Unhandled": function () {
        var speechOutput = this.t("HELP_UNHANDLED");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "SessionEndedRequest": function () {
        console.log("Session ended in help state: " + this.event.request.reason);
    }
});

function handleUserGuess(userGaveUp) {
    var answerSlotValid = isAnswerSlotValid(this.event.request.intent);
    var speechOutput = "";
    var speechOutputAnalysis = "";
    var gameQuestions = this.attributes.questions;
    var currentScore = parseInt(this.attributes.score);
    var currentQuestionIndex = parseInt(this.attributes.currentQuestionIndex);
    var correctAnswerText = this.attributes.correctAnswerText;
    var translatedQuestions = this.t("QUESTIONS");

    if (answerSlotValid && this.event.request.intent.slots.Answer.value == this.attributes.correctAnswer) {
        currentScore++;
        speechOutputAnalysis = this.t("ANSWER_CORRECT_MESSAGE");
    } else {
        if (!userGaveUp) {
            speechOutputAnalysis = this.t("ANSWER_WRONG_MESSAGE");
        }

        speechOutputAnalysis += correctAnswerText;
    }

    // Check if we can exit the game session after GAME_LENGTH questions (zero-indexed)
    if (currentQuestionIndex == GAME_LENGTH - 1) {
        speechOutput = userGaveUp ? "" : this.t("ANSWER_IS_MESSAGE");
        speechOutput += speechOutputAnalysis + this.t("GAME_OVER_MESSAGE", currentScore.toString(), GAME_LENGTH.toString());

        this.emit(":tell", speechOutput)
    } else {
        currentQuestionIndex += 1;
        var country = translatedQuestions[gameQuestions[currentQuestionIndex]].country;
        var spokenQuestion = this.t("CAPITAL_QUESTION", country);
        var questionIndexForSpeech = currentQuestionIndex + 1;
        var repromptText = this.t("TELL_QUESTION_MESSAGE", "1", spokenQuestion);

        speechOutput += userGaveUp ? "" : this.t("ANSWER_IS_MESSAGE");
        speechOutput += speechOutputAnalysis + this.t("SCORE_IS_MESSAGE", currentScore.toString()) + repromptText;

        var answer = translatedQuestions[gameQuestions[questionIndexForSpeech]].capital;
        var answerText = this.t("CAPITAL_ANSWER", country, answer);
        Object.assign(this.attributes, {
            "speechOutput": repromptText,
            "repromptText": repromptText,
            "currentQuestionIndex": questionIndexForSpeech,
            "questions": gameQuestions,
            "score": currentScore,
            "correctAnswer": answer,
            "correctAnswerText": answerText
        });

        this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), repromptText);
    }
}

function populateGameQuestions(translatedQuestions) {
    var gameQuestions = [];
    var indexList = [];
    var index = translatedQuestions.length;

    if (GAME_LENGTH > index){
        throw new Error("Invalid Game Length.");
    }

    for (var i = 0; i < translatedQuestions.length; i++){
        indexList.push(i);
    }

    // Pick GAME_LENGTH random questions from the list to ask the user, make sure there are no repeats.
    for (var j = 0; j < GAME_LENGTH; j++){
        var rand = Math.floor(Math.random() * index);
        index -= 1;

        var temp = indexList[index];
        indexList[index] = indexList[rand];
        indexList[rand] = temp;
        gameQuestions.push(indexList[index]);
    }

    return gameQuestions;
}

function isAnswerSlotValid(intent) {
    return intent && intent.slots && intent.slots.Answer && intent.slots.Answer.value;
}<commit_msg>Fix number question bug<commit_after>"use strict";
var APP_ID = undefined;  // TODO replace with your app ID (OPTIONAL).

var GAME_LENGTH = 5;  // The number of questions per trivia game.
var GAME_STATES = {
    TRIVIA: "_TRIVIAMODE", // Asking trivia questions.
    START: "_STARTMODE", // Entry point, start the game.
    HELP: "_HELPMODE" // The user is asking for help.
};
var questions = require("./questions");

/**
 * When editing your questions pay attention to your punctuation. Make sure you use question marks or periods.
 * Make sure the first answer is the correct one. Set at least ANSWER_COUNT answers, any extras will be shuffled in.
 */
var languageString = {
    "en-US": {
        "translation": {
            "QUESTIONS" : questions,
            "GAME_NAME" : "Capital quiz by Elroy and Rocco", // Be sure to change this for your skill.
            "HELP_MESSAGE": "I will ask you %s questions. Respond with the correct answer.",
            "REPEAT_QUESTION_MESSAGE": "To repeat the last question, say, repeat. ",
            "ASK_MESSAGE_START": "Would you like to start playing?",
            "HELP_REPROMPT": "To give an answer to a question, respond with the city name of your choice.",
            "STOP_MESSAGE": "Would you like to keep playing?",
            "CANCEL_MESSAGE": "Ok, let\'s play again soon.",
            "NO_MESSAGE": "Ok, we\'ll play another time. Goodbye!",
            "TRIVIA_UNHANDLED": "Try saying a number between 1 and %s",
            "HELP_UNHANDLED": "Say yes to continue, or no to end the game.",
            "START_UNHANDLED": "Say start to start a new game.",
            "NEW_GAME_MESSAGE": "Welcome to %s. ",
            "WELCOME_MESSAGE": "I will ask you %s questions, try to get as many right as you can. " +
            "Wub a lub a dub dub that's my catchphrase. You know how I always say",
            "ANSWER_CORRECT_MESSAGE": "correct. ",
            "ANSWER_WRONG_MESSAGE": "wrong. ",
            "CORRECT_ANSWER_MESSAGE": "The correct answer is %s: %s. ",
            "ANSWER_IS_MESSAGE": "That answer is ",
            "TELL_QUESTION_MESSAGE": "Question %s. %s ",
            "GAME_OVER_MESSAGE": "You got %s out of %s questions correct. Thank you for playing!",
            "SCORE_IS_MESSAGE": "Your score is %s. ",
            "CAPITAL_QUESTION": "What is the capital of %s?",
            "CAPITAL_ANSWER": "The capital of %s is %s"
        }
    }
};

var Alexa = require("alexa-sdk");
var APP_ID = undefined;  // TODO replace with your app ID (OPTIONAL).

exports.handler = function(event, context, callback) {
    var alexa = Alexa.handler(event, context);
    alexa.appId = APP_ID;
    // To enable string internationalization (i18n) features, set a resources object.
    alexa.resources = languageString;
    alexa.registerHandlers(newSessionHandlers, startStateHandlers, triviaStateHandlers, helpStateHandlers);
    alexa.execute();
};

var newSessionHandlers = {
    "LaunchRequest": function () {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", true);
    }
    ,
    "AMAZON.StartOverIntent": function() {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", true);
    },
    "AMAZON.HelpIntent": function() {
        this.handler.state = GAME_STATES.HELP;
        this.emitWithState("helpTheUser", true);
    },
    "Unhandled": function () {
        var speechOutput = this.t("START_UNHANDLED");
        this.emit(":ask", speechOutput, speechOutput);
    }
};

var startStateHandlers = Alexa.CreateStateHandler(GAME_STATES.START, {
    "StartGame": function (newGame) {
        var speechOutput = newGame ? this.t("NEW_GAME_MESSAGE", this.t("GAME_NAME")) + this.t("WELCOME_MESSAGE", GAME_LENGTH.toString()) : "";
        // Select GAME_LENGTH questions for the game
        var translatedQuestions = this.t("QUESTIONS");
        var gameQuestions = populateGameQuestions(translatedQuestions);

        var currentQuestionIndex = 0;
        var country = translatedQuestions[gameQuestions[currentQuestionIndex]].country;
        var spokenQuestion = this.t("CAPITAL_QUESTION", country);
        var repromptText = this.t("TELL_QUESTION_MESSAGE", "1", spokenQuestion);

        speechOutput += repromptText;

        var answer = translatedQuestions[gameQuestions[currentQuestionIndex]].capital;
        var answerText = this.t("CAPITAL_ANSWER", country, answer);

        Object.assign(this.attributes, {
            "speechOutput": repromptText,
            "repromptText": repromptText,
            "currentQuestionIndex": currentQuestionIndex,
            "questions": gameQuestions,
            "score": 0,
            "correctAnswer": answer,
            "correctAnswerText": answerText
        });

        // Set the current state to trivia mode. The skill will now use handlers defined in triviaStateHandlers
        this.handler.state = GAME_STATES.TRIVIA;
        this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), repromptText);
    }
});

var triviaStateHandlers = Alexa.CreateStateHandler(GAME_STATES.TRIVIA, {
    "AnswerIntent": function () {
        handleUserGuess.call(this, false);
    },
    "DontKnowIntent": function () {
        handleUserGuess.call(this, true);
    },
    "AMAZON.StartOverIntent": function () {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        this.emit(":ask", this.attributes["speechOutput"], this.attributes["repromptText"]);
    },
    "AMAZON.HelpIntent": function () {
        this.handler.state = GAME_STATES.HELP;
        this.emitWithState("helpTheUser", false);
    },
    "AMAZON.StopIntent": function () {
        this.handler.state = GAME_STATES.HELP;
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "AMAZON.CancelIntent": function () {
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "Unhandled": function () {
        var speechOutput = this.t("TRIVIA_UNHANDLED", ANSWER_COUNT.toString());
        this.emit(":ask", speechOutput, speechOutput);
    },
    "SessionEndedRequest": function () {
        console.log("Session ended in trivia state: " + this.event.request.reason);
    }
});

var helpStateHandlers = Alexa.CreateStateHandler(GAME_STATES.HELP, {
    "helpTheUser": function (newGame) {
        var askMessage = newGame ? this.t("ASK_MESSAGE_START") : this.t("REPEAT_QUESTION_MESSAGE") + this.t("STOP_MESSAGE");
        var speechOutput = this.t("HELP_MESSAGE", GAME_LENGTH) + askMessage;
        var repromptText = this.t("HELP_REPROMPT") + askMessage;
        this.emit(":ask", speechOutput, repromptText);
    },
    "AMAZON.StartOverIntent": function () {
        this.handler.state = GAME_STATES.START;
        this.emitWithState("StartGame", false);
    },
    "AMAZON.RepeatIntent": function () {
        var newGame = (this.attributes["speechOutput"] && this.attributes["repromptText"]) ? false : true;
        this.emitWithState("helpTheUser", newGame);
    },
    "AMAZON.HelpIntent": function() {
        var newGame = (this.attributes["speechOutput"] && this.attributes["repromptText"]) ? false : true;
        this.emitWithState("helpTheUser", newGame);
    },
    "AMAZON.YesIntent": function() {
        if (this.attributes["speechOutput"] && this.attributes["repromptText"]) {
            this.handler.state = GAME_STATES.TRIVIA;
            this.emitWithState("AMAZON.RepeatIntent");
        } else {
            this.handler.state = GAME_STATES.START;
            this.emitWithState("StartGame", false);
        }
    },
    "AMAZON.NoIntent": function() {
        var speechOutput = this.t("NO_MESSAGE");
        this.emit(":tell", speechOutput);
    },
    "AMAZON.StopIntent": function () {
        var speechOutput = this.t("STOP_MESSAGE");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "AMAZON.CancelIntent": function () {
        this.emit(":tell", this.t("CANCEL_MESSAGE"));
    },
    "Unhandled": function () {
        var speechOutput = this.t("HELP_UNHANDLED");
        this.emit(":ask", speechOutput, speechOutput);
    },
    "SessionEndedRequest": function () {
        console.log("Session ended in help state: " + this.event.request.reason);
    }
});

function handleUserGuess(userGaveUp) {
    var answerSlotValid = isAnswerSlotValid(this.event.request.intent);
    var speechOutput = "";
    var speechOutputAnalysis = "";
    var gameQuestions = this.attributes.questions;
    var currentScore = parseInt(this.attributes.score);
    var currentQuestionIndex = parseInt(this.attributes.currentQuestionIndex);
    var correctAnswerText = this.attributes.correctAnswerText;
    var translatedQuestions = this.t("QUESTIONS");

    if (answerSlotValid && this.event.request.intent.slots.Answer.value == this.attributes.correctAnswer) {
        currentScore++;
        speechOutputAnalysis = this.t("ANSWER_CORRECT_MESSAGE");
    } else {
        if (!userGaveUp) {
            speechOutputAnalysis = this.t("ANSWER_WRONG_MESSAGE");
        }

        speechOutputAnalysis += correctAnswerText;
    }

    // Check if we can exit the game session after GAME_LENGTH questions (zero-indexed)
    if (currentQuestionIndex == GAME_LENGTH - 1) {
        speechOutput = userGaveUp ? "" : this.t("ANSWER_IS_MESSAGE");
        speechOutput += speechOutputAnalysis + this.t("GAME_OVER_MESSAGE", currentScore.toString(), GAME_LENGTH.toString());

        this.emit(":tell", speechOutput)
    } else {
        currentQuestionIndex += 1;
        var country = translatedQuestions[gameQuestions[currentQuestionIndex]].country;
        var spokenQuestion = this.t("CAPITAL_QUESTION", country);
        var questionIndexForSpeech = currentQuestionIndex + 1;
        var repromptText = this.t("TELL_QUESTION_MESSAGE", questionIndexForSpeech, spokenQuestion);

        speechOutput += userGaveUp ? "" : this.t("ANSWER_IS_MESSAGE");
        speechOutput += speechOutputAnalysis + this.t("SCORE_IS_MESSAGE", currentScore.toString()) + repromptText;

        var answer = translatedQuestions[gameQuestions[currentQuestionIndex]].capital;
        var answerText = this.t("CAPITAL_ANSWER", country, answer);
        Object.assign(this.attributes, {
            "speechOutput": repromptText,
            "repromptText": repromptText,
            "currentQuestionIndex": currentQuestionIndex,
            "questions": gameQuestions,
            "score": currentScore,
            "correctAnswer": answer,
            "correctAnswerText": answerText
        });

        this.emit(":askWithCard", speechOutput, repromptText, this.t("GAME_NAME"), repromptText);
    }
}

function populateGameQuestions(translatedQuestions) {
    var gameQuestions = [];
    var indexList = [];
    var index = translatedQuestions.length;

    if (GAME_LENGTH > index){
        throw new Error("Invalid Game Length.");
    }

    for (var i = 0; i < translatedQuestions.length; i++){
        indexList.push(i);
    }

    // Pick GAME_LENGTH random questions from the list to ask the user, make sure there are no repeats.
    for (var j = 0; j < GAME_LENGTH; j++){
        var rand = Math.floor(Math.random() * index);
        index -= 1;

        var temp = indexList[index];
        indexList[index] = indexList[rand];
        indexList[rand] = temp;
        gameQuestions.push(indexList[index]);
    }

    return gameQuestions;
}

function isAnswerSlotValid(intent) {
    return intent && intent.slots && intent.slots.Answer && intent.slots.Answer.value;
}<|endoftext|>


<commit_before>import Catalog from './catalog/catalog';
import Translator from './translator/translator';
import ToolbarButton from './components/toolbar/toolbar-button';
import Ruler from './components/viewer2d/ruler';
import * as Models from './models';
import State2DViewer from './components/viewer2d/state';
import reducer from './reducers/reducer';
import ReactPlanner from './react-planner';
import Content from './components/content';
import Plugins from './plugins/plugins';
import WallFactory from './catalog/factories/wall-factory';
import AreaFactory from './catalog/factories/area-factory';
import Button from './components/style/button';
import CancelButton from './components/style/cancel-button';
import ContentContainer from './components/style/content-container';
import ContentTitle from './components/style/content-title';
import DeleteButton from './components/style/delete-button';
import FormBlock from './components/style/form-block';
import FormColorInput from './components/style/form-color-input';
import FormLabel from './components/style/form-label';
import FormNumberInput from './components/style/form-number-input';
import FormSelect from './components/style/form-select';
import FormSlider from './components/style/form-slider';
import FormSubmitButton from './components/style/form-submit-button';
import FormTextInput from './components/style/form-text-input';
import * as ReactPlannerConstants from './constants';
import {VERSION} from './version';

let ElementsFactories = {WallFactory, AreaFactory};
let StyleComponents = {
  Button, CancelButton, ContentContainer, ContentTitle, DeleteButton, FormBlock,
  FormColorInput, FormLabel, FormNumberInput, FormSelect, FormSlider, FormSubmitButton, FormTextInput
};

console.info(`react-planner ${VERSION} started`); //MIT LICENSE COMPLIANT

export {
  Catalog,
  Translator,
  ToolbarButton,
  Ruler,
  Models,
  State2DViewer,
  reducer,
  ReactPlanner,
  Content as ReactPlannerContent,
  Plugins,
  ElementsFactories,
  StyleComponents,
  ReactPlannerConstants
};
<commit_msg>Exported all reducers<commit_after>import Catalog from './catalog/catalog';
import Translator from './translator/translator';
import ToolbarButton from './components/toolbar/toolbar-button';
import Ruler from './components/viewer2d/ruler';
import * as Models from './models';
import State2DViewer from './components/viewer2d/state';
import reducer from './reducers/reducer';
import ReactPlanner from './react-planner';
import Content from './components/content';
import Plugins from './plugins/plugins';
import WallFactory from './catalog/factories/wall-factory';
import AreaFactory from './catalog/factories/area-factory';
import Button from './components/style/button';
import CancelButton from './components/style/cancel-button';
import ContentContainer from './components/style/content-container';
import ContentTitle from './components/style/content-title';
import DeleteButton from './components/style/delete-button';
import FormBlock from './components/style/form-block';
import FormColorInput from './components/style/form-color-input';
import FormLabel from './components/style/form-label';
import FormNumberInput from './components/style/form-number-input';
import FormSelect from './components/style/form-select';
import FormSlider from './components/style/form-slider';
import FormSubmitButton from './components/style/form-submit-button';
import FormTextInput from './components/style/form-text-input';
import * as ReactPlannerConstants from './constants';
import {VERSION} from './version';

import ReactPlannerAreasReducer from './reducers/areas-reducer';
import ReactPlannerHolesReducer from './reducers/holes-reducer';
import ReactPlannerItemsReducer from './reducers/items-reducer';
import ReactPlannerLinesReducer from './reducers/lines-reducer';
import ReactPlannerProjectReducer from './reducers/project-reducer';
import ReactPlannerSceneReducer from './reducers/scene-reducer';
import ReactPlannerVerticesReducer from './reducers/vertices-reducer';
import ReactPlannerViewer2dReducer from './reducers/viewer2d-reducer';
import ReactPlannerViewer3dReducer from './reducers/viewer3d-reducer';

let ElementsFactories = {WallFactory, AreaFactory};
let StyleComponents = {
  Button, CancelButton, ContentContainer, ContentTitle, DeleteButton, FormBlock,
  FormColorInput, FormLabel, FormNumberInput, FormSelect, FormSlider, FormSubmitButton, FormTextInput
};

console.info(`react-planner ${VERSION} started`); //MIT LICENSE COMPLIANT

let ReactPlannerReducers = {
  ReactPlannerAreasReducer,
  ReactPlannerHolesReducer,
  ReactPlannerItemsReducer,
  ReactPlannerLinesReducer,
  ReactPlannerProjectReducer,
  ReactPlannerSceneReducer,
  ReactPlannerVerticesReducer,
  ReactPlannerViewer2dReducer,
  ReactPlannerViewer3dReducer
};

export {
  Catalog,
  Translator,
  ToolbarButton,
  Ruler,
  Models,
  State2DViewer,
  reducer,
  ReactPlanner,
  Content as ReactPlannerContent,
  Plugins,
  ElementsFactories,
  StyleComponents,
  ReactPlannerConstants,
  ReactPlannerReducers
};
<|endoftext|>


<commit_before>module.exports = {
	Client: require('./lib/client'),
	util: require('./lib/util/util'),
	Command: require('./lib/structures/Command'),
	CommandMessage: require('./lib/structures/CommandMessage'),
	Event: require('./lib/structures/Event'),
	Extendable: require('./lib/structures/Extendable'),
	Finalizer: require('./lib/structures/Finalizer'),
	Inhibitor: require('./lib/structures/Inhibitor'),
	Language: require('./lib/structures/Language'),
	Monitor: require('./lib/structures/Monitor'),
	PermissionLevels: require('./lib/structures/PermissionLevels'),
	Provider: require('./lib/structures/Provider'),
	CommandStore: require('./lib/structures/CommandStore'),
	EventStore: require('./lib/structures/EventStore'),
	ExtendableStore: require('./lib/structures/ExtendableStore'),
	FinalizerStore: require('./lib/structures/FinalizerStore'),
	InhibitorStore: require('./lib/structures/InhibitorStore'),
	LanguageStore: require('./lib/structures/LanguageStore'),
	MonitorStore: require('./lib/structures/MonitorStore'),
	ProviderStore: require('./lib/structures/ProviderStore'),
	Piece: require('./lib/structures/interfaces/Piece'),
	Store: require('./lib/structures/interfaces/Store'),
	CacheManager: require('./lib/settings/cacheManager'),
	SchemaManager: require('./lib/settings/schemaManager'),
	SettingGateway: require('./lib/settings/settingGateway'),
	SQL: require('./lib/settings/SQL'),
	ArgResolver: require('./lib/parsers/ArgResolver'),
	Resolver: require('./lib/parsers/Resolver'),
	SettingResolver: require('./lib/parsers/SettingResolver'),
	ParsedUsage: require('./lib/usage/ParsedUsage'),
	Possible: require('./lib/usage/Possible'),
	Tag: require('./lib/usage/Tag'),
	version: require('../package').version
};

/**
 * @external Channel
 * @see {@link https://discord.js.org/#/docs/main/master/class/Channel}
 */
/**
 * @external Client
 * @see {@link https://discord.js.org/#/docs/main/master/class/Client}
 */
/**
 * @external DiscordJSConfig
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/ClientOptions}
 */
/**
 * @external Collection
 * @see {@link https://discord.js.org/#/docs/main/master/class/Collection}
 */
/**
 * @external DMChannel
 * @see {@link https://discord.js.org/#/docs/main/master/class/DMChannel}
 */
/**
 * @external GroupDMChannel
 * @see {@link https://discord.js.org/#/docs/main/master/class/GroupDMChannel}
 */
/**
 * @external Guild
 * @see {@link https://discord.js.org/#/docs/main/master/class/Guild}
 */
/**
 * @external GuildMember
 * @see {@link https://discord.js.org/#/docs/main/master/class/GuildMember}
 */
/**
 * @external GuildResolvable
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/GuildResolvable}
 */
/**
 * @external Message
 * @see {@link https://discord.js.org/#/docs/main/master/class/Message}
 */
/**
 * @external MessageAttachment
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageAttachment}
 */
/**
 * @external MessageEmbed
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageEmbed}
 */
/**
 * @external MessageReaction
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageReaction}
 */
/**
 * @external MessageOptions
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/MessageOptions}
 */
/**
 * @external Role
 * @see {@link https://discord.js.org/#/docs/main/master/class/Role}
 */
/**
 * @external StringResolvable
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/StringResolvable}
 */
/**
 * @external TextChannel
 * @see {@link https://discord.js.org/#/docs/main/master/class/TextChannel}
 */
/**
 * @external User
 * @see {@link https://discord.js.org/#/docs/main/master/class/User}
 */
/**
 * @external UserResolvable
 * @see {@link https://discord.js.org/#/docs/main/master/class/UserResolvable}
 */
/**
 * @external Emoji
 * @see {@link https://discord.js.org/#/docs/main/master/class/Emoji}
 */
/**
 * @external ReactionEmoji
 * @see {@link https://discord.js.org/#/docs/main/master/class/ReactionEmoji}
 */
/**
 * @external Webhook
 * @see {@link https://discord.js.org/#/docs/main/master/class/Webhook}
 */
/**
 * @external MessageEmbed
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageEmbed}
 */
/**
 * @external ShardingManager
 * @see {@link https://discord.js.org/#/docs/main/master/class/ShardingManager}
 */
<commit_msg>Update index.js<commit_after>module.exports = {
	Client: require('./lib/Client'),
	util: require('./lib/util/util'),
	Command: require('./lib/structures/Command'),
	CommandMessage: require('./lib/structures/CommandMessage'),
	Event: require('./lib/structures/Event'),
	Extendable: require('./lib/structures/Extendable'),
	Finalizer: require('./lib/structures/Finalizer'),
	Inhibitor: require('./lib/structures/Inhibitor'),
	Language: require('./lib/structures/Language'),
	Monitor: require('./lib/structures/Monitor'),
	PermissionLevels: require('./lib/structures/PermissionLevels'),
	Provider: require('./lib/structures/Provider'),
	CommandStore: require('./lib/structures/CommandStore'),
	EventStore: require('./lib/structures/EventStore'),
	ExtendableStore: require('./lib/structures/ExtendableStore'),
	FinalizerStore: require('./lib/structures/FinalizerStore'),
	InhibitorStore: require('./lib/structures/InhibitorStore'),
	LanguageStore: require('./lib/structures/LanguageStore'),
	MonitorStore: require('./lib/structures/MonitorStore'),
	ProviderStore: require('./lib/structures/ProviderStore'),
	Piece: require('./lib/structures/interfaces/Piece'),
	Store: require('./lib/structures/interfaces/Store'),
	CacheManager: require('./lib/settings/CacheManager'),
	SchemaManager: require('./lib/settings/SchemaManager'),
	SettingGateway: require('./lib/settings/SettingGateway'),
	SQL: require('./lib/settings/SQL'),
	ArgResolver: require('./lib/parsers/ArgResolver'),
	Resolver: require('./lib/parsers/Resolver'),
	SettingResolver: require('./lib/parsers/SettingResolver'),
	ParsedUsage: require('./lib/usage/ParsedUsage'),
	Possible: require('./lib/usage/Possible'),
	Tag: require('./lib/usage/Tag'),
	version: require('../package').version
};

/**
 * @external Channel
 * @see {@link https://discord.js.org/#/docs/main/master/class/Channel}
 */
/**
 * @external Client
 * @see {@link https://discord.js.org/#/docs/main/master/class/Client}
 */
/**
 * @external DiscordJSConfig
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/ClientOptions}
 */
/**
 * @external Collection
 * @see {@link https://discord.js.org/#/docs/main/master/class/Collection}
 */
/**
 * @external DMChannel
 * @see {@link https://discord.js.org/#/docs/main/master/class/DMChannel}
 */
/**
 * @external GroupDMChannel
 * @see {@link https://discord.js.org/#/docs/main/master/class/GroupDMChannel}
 */
/**
 * @external Guild
 * @see {@link https://discord.js.org/#/docs/main/master/class/Guild}
 */
/**
 * @external GuildMember
 * @see {@link https://discord.js.org/#/docs/main/master/class/GuildMember}
 */
/**
 * @external GuildResolvable
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/GuildResolvable}
 */
/**
 * @external Message
 * @see {@link https://discord.js.org/#/docs/main/master/class/Message}
 */
/**
 * @external MessageAttachment
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageAttachment}
 */
/**
 * @external MessageEmbed
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageEmbed}
 */
/**
 * @external MessageReaction
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageReaction}
 */
/**
 * @external MessageOptions
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/MessageOptions}
 */
/**
 * @external Role
 * @see {@link https://discord.js.org/#/docs/main/master/class/Role}
 */
/**
 * @external StringResolvable
 * @see {@link https://discord.js.org/#/docs/main/master/typedef/StringResolvable}
 */
/**
 * @external TextChannel
 * @see {@link https://discord.js.org/#/docs/main/master/class/TextChannel}
 */
/**
 * @external User
 * @see {@link https://discord.js.org/#/docs/main/master/class/User}
 */
/**
 * @external UserResolvable
 * @see {@link https://discord.js.org/#/docs/main/master/class/UserResolvable}
 */
/**
 * @external Emoji
 * @see {@link https://discord.js.org/#/docs/main/master/class/Emoji}
 */
/**
 * @external ReactionEmoji
 * @see {@link https://discord.js.org/#/docs/main/master/class/ReactionEmoji}
 */
/**
 * @external Webhook
 * @see {@link https://discord.js.org/#/docs/main/master/class/Webhook}
 */
/**
 * @external MessageEmbed
 * @see {@link https://discord.js.org/#/docs/main/master/class/MessageEmbed}
 */
/**
 * @external ShardingManager
 * @see {@link https://discord.js.org/#/docs/main/master/class/ShardingManager}
 */
<|endoftext|>


<commit_before>import BootstrapTable from './BootstrapTable';
import TableHeaderColumn from './TableHeaderColumn';

if (typeof window !== 'undefined') {
  window.BootstrapTable = BootstrapTable;
  window.TableHeaderColumn = TableHeaderColumn;
}
export {
  BootstrapTable,
  TableHeaderColumn
};
<commit_msg>export insert modal component<commit_after>import BootstrapTable from './BootstrapTable';
import TableHeaderColumn from './TableHeaderColumn';
import InsertModalHeader from './toolbar/InsertModalHeader';
import InsertModalBody from './toolbar/InsertModalBody';
import InsertModalFooter from './toolbar/InsertModalFooter';

if (typeof window !== 'undefined') {
  window.BootstrapTable = BootstrapTable;
  window.TableHeaderColumn = TableHeaderColumn;
  window.InsertModalHeader = InsertModalHeader;
  window.InsertModalBody = InsertModalBody;
  window.InsertModalFooter = InsertModalFooter;
}
export {
  BootstrapTable,
  TableHeaderColumn,
  InsertModalHeader,
  InsertModalBody,
  InsertModalFooter
};
<|endoftext|>


<commit_before>const cluster = require('cluster');

// Master
if (cluster.isMaster) {

	// Count the machine's CPUs
	const cpuCount = require('os').cpus().length;

	// Create a worker for each CPU
	for (let i = 0; i < cpuCount; i++) {
		cluster.fork();
	}
}
// Workers
else {
	require('./server');
}
<commit_msg>Fix  bug<commit_after>const cluster = require('cluster');
const accesses = require('accesses');

// Master
if (cluster.isMaster) {

	// Count the machine's CPUs
	const cpuCount = require('os').cpus().length;

	// Create a worker for each CPU
	for (let i = 0; i < cpuCount; i++) {
		cluster.fork();
	}

	accesses.serve({
		appName: 'Misskey',
		port: 616
	});
}
// Workers
else {
	require('./server');
}
<|endoftext|>