<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'
  ],

  imports: [
    'userDAO'
  ],

  javaImports: [
    'foam.core.DirectAgency',
    'foam.nanos.logger.Logger',
    'java.util.Collection'
  ],

  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: 'Boolean',
      name: 'debug',
      documentation: 'Test this boolean before generating expensive logger.debug calls, to speed rule execution.'
    },
    {
      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',
      createMode: 'HIDDEN',
      updateMode: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      createMode: 'HIDDEN',
      updateMode: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdByAgent',
      createMode: 'HIDDEN',
      updateMode: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      createMode: 'HIDDEN',
      updateMode: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      createMode: 'HIDDEN',
      updateMode: '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")).debug(this.getClass().getSimpleName(), "id", getId(), "\\nrule", this, "\\nobj", obj, "\\nold", oldObj, "\\n", t);
          ((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>Improve Rule tableView appearance.<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.DirectAgency',
    'foam.nanos.logger.Logger',
    'java.util.Collection'
  ],

  tableColumns: [
    'id',
    'ruleGroup',
    'enabled',
    'priority',
    'daoKey',
    '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: 300,
      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: 66,
      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',
      label: 'DAO Key',
      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: 'Boolean',
      name: 'debug',
      documentation: 'Test this boolean before generating expensive logger.debug calls, to speed rule execution.'
    },
    {
      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',
      createMode: 'HIDDEN',
      updateMode: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdBy',
      createMode: 'HIDDEN',
      updateMode: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'createdByAgent',
      createMode: 'HIDDEN',
      updateMode: 'RO',
      tableCellFormatter: function(value, obj) {
        obj.userDAO.find(value).then(function(user) {
          if ( user ) {
            this.add(user.legalName);
          }
        }.bind(this));
      }
    },
    {
      class: 'DateTime',
      name: 'lastModified',
      createMode: 'HIDDEN',
      updateMode: 'RO'
    },
    {
      class: 'Reference',
      of: 'foam.nanos.auth.User',
      name: 'lastModifiedBy',
      createMode: 'HIDDEN',
      updateMode: '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")).debug(this.getClass().getSimpleName(), "id", getId(), "\\nrule", this, "\\nobj", obj, "\\nold", oldObj, "\\n", t);
          ((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>/* eslint-disable no-useless-escape */
/* eslint-disable no-unused-expressions */
/* eslint-disable no-mixed-operators */

import Vue from 'vue'

export const isSSR = typeof window === 'undefined'
export let fromSSR = false
export let onSSR = isSSR

function getMatch (userAgent, platformMatch) {
  const match = /(edge)\/([\w.]+)/.exec(userAgent) ||
    /(opr)[\/]([\w.]+)/.exec(userAgent) ||
    /(vivaldi)[\/]([\w.]+)/.exec(userAgent) ||
    /(chrome)[\/]([\w.]+)/.exec(userAgent) ||
    /(iemobile)[\/]([\w.]+)/.exec(userAgent) ||
    /(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent) ||
    /(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent) ||
    /(webkit)[\/]([\w.]+)/.exec(userAgent) ||
    /(opera)(?:.*version|)[\/]([\w.]+)/.exec(userAgent) ||
    /(msie) ([\w.]+)/.exec(userAgent) ||
    userAgent.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(userAgent) ||
    userAgent.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(userAgent) ||
    []

  return {
    browser: match[5] || match[3] || match[1] || '',
    version: match[2] || match[4] || '0',
    versionNumber: match[4] || match[2] || '0',
    platform: platformMatch[0] || ''
  }
}

function getPlatformMatch (userAgent) {
  return /(ipad)/.exec(userAgent) ||
    /(ipod)/.exec(userAgent) ||
    /(windows phone)/.exec(userAgent) ||
    /(iphone)/.exec(userAgent) ||
    /(kindle)/.exec(userAgent) ||
    /(silk)/.exec(userAgent) ||
    /(android)/.exec(userAgent) ||
    /(win)/.exec(userAgent) ||
    /(mac)/.exec(userAgent) ||
    /(linux)/.exec(userAgent) ||
    /(cros)/.exec(userAgent) ||
    /(playbook)/.exec(userAgent) ||
    /(bb)/.exec(userAgent) ||
    /(blackberry)/.exec(userAgent) ||
    []
}

function getPlatform (userAgent) {
  userAgent = (userAgent || navigator.userAgent || navigator.vendor || window.opera).toLowerCase()

  const
    platformMatch = getPlatformMatch(userAgent),
    matched = getMatch(userAgent, platformMatch),
    browser = {}

  if (matched.browser) {
    browser[matched.browser] = true
    browser.version = matched.version
    browser.versionNumber = parseInt(matched.versionNumber, 10)
  }

  if (matched.platform) {
    browser[matched.platform] = true
  }

  const knownMobiles = browser.android ||
    browser.bb ||
    browser.blackberry ||
    browser.ipad ||
    browser.iphone ||
    browser.ipod ||
    browser.kindle ||
    browser.playbook ||
    browser.silk ||
    browser['windows phone']

  // These are all considered mobile platforms, meaning they run a mobile browser
  if (knownMobiles === true || userAgent.indexOf('mobile') > -1) {
    browser.mobile = true
  }
  // If it's not mobile we should consider it's desktop platform, meaning it runs a desktop browser
  // It's a workaround for anonymized user agents
  // (browser.cros || browser.mac || browser.linux || browser.win)
  else {
    browser.desktop = true
  }

  // Set iOS if on iPod, iPad or iPhone
  if (browser.ipod || browser.ipad || browser.iphone) {
    browser.ios = true
  }

  if (browser['windows phone']) {
    browser.winphone = true
    delete browser['windows phone']
  }

  // Chrome, Opera 15+, Vivaldi and Safari are webkit based browsers
  if (
    browser.chrome ||
    browser.opr ||
    browser.safari ||
    browser.vivaldi ||
    // we expect unknown, non iOS mobile browsers to be webkit based
    (
      browser.mobile === true &&
      browser.ios !== true &&
      knownMobiles !== true
    )
  ) {
    browser.webkit = true
  }

  // IE11 has a new token so we will assign it msie to avoid breaking changes
  if (browser.rv || browser.iemobile) {
    matched.browser = 'ie'
    browser.ie = true
  }

  // Edge is officially known as Microsoft Edge, so rewrite the key to match
  if (browser.edge) {
    matched.browser = 'edge'
    browser.edge = true
  }

  // Blackberry browsers are marked as Safari on BlackBerry
  if (browser.safari && browser.blackberry || browser.bb) {
    matched.browser = 'blackberry'
    browser.blackberry = true
  }

  // Playbook browsers are marked as Safari on Playbook
  if (browser.safari && browser.playbook) {
    matched.browser = 'playbook'
    browser.playbook = true
  }

  // Opera 15+ are identified as opr
  if (browser.opr) {
    matched.browser = 'opera'
    browser.opera = true
  }

  // Stock Android browsers are marked as Safari on Android.
  if (browser.safari && browser.android) {
    matched.browser = 'android'
    browser.android = true
  }

  // Kindle browsers are marked as Safari on Kindle
  if (browser.safari && browser.kindle) {
    matched.browser = 'kindle'
    browser.kindle = true
  }

  // Kindle Silk browsers are marked as Safari on Kindle
  if (browser.safari && browser.silk) {
    matched.browser = 'silk'
    browser.silk = true
  }

  if (browser.vivaldi) {
    matched.browser = 'vivaldi'
    browser.vivaldi = true
  }

  // Assign the name and platform variable
  browser.name = matched.browser
  browser.platform = matched.platform

  if (isSSR === false) {
    if (window.process && window.process.versions && window.process.versions.electron) {
      browser.electron = true
    }
    else if (document.location.href.indexOf('chrome-extension://') === 0) {
      browser.chromeExt = true
    }
    else if (window._cordovaNative || window.cordova) {
      browser.cordova = true
    }

    fromSSR = browser.cordova === void 0 &&
      browser.electron === void 0 &&
      !!document.querySelector('[data-server-rendered]')

    fromSSR === true && (onSSR = true)
  }

  return browser
}

let webStorage

export function hasWebStorage () {
  if (webStorage !== void 0) {
    return webStorage
  }

  try {
    if (window.localStorage) {
      webStorage = true
      return true
    }
  }
  catch (e) {}

  webStorage = false
  return false
}

function getClientProperties () {
  return {
    has: {
      touch: (() => 'ontouchstart' in window ||
        window.navigator.maxTouchPoints > 0
      )(),
      webStorage: hasWebStorage()
    },
    within: {
      iframe: window.self !== window.top
    }
  }
}

export default {
  has: {
    touch: false,
    webStorage: false
  },
  within: { iframe: false },

  parseSSR (/* ssrContext */ ssr) {
    return ssr ? {
      is: getPlatform(ssr.req.headers['user-agent'] || ssr.req.headers['User-Agent']),
      has: this.has,
      within: this.within
    } : {
      is: getPlatform(),
      ...getClientProperties()
    }
  },

  install ($q, queues) {
    if (isSSR === true) {
      queues.server.push((q, ctx) => {
        q.platform = this.parseSSR(ctx.ssr)
      })
      return
    }

    this.is = getPlatform()

    if (fromSSR === true) {
      queues.takeover.push(q => {
        onSSR = fromSSR = false
        Object.assign(q.platform, getClientProperties())
      })
      Vue.util.defineReactive($q, 'platform', this)
    }
    else {
      Object.assign(this, getClientProperties())
      $q.platform = this
    }
  }
}
<commit_msg>feat(Platform): Detect mobile edge #4573<commit_after>/* eslint-disable no-useless-escape */
/* eslint-disable no-unused-expressions */
/* eslint-disable no-mixed-operators */

import Vue from 'vue'

export const isSSR = typeof window === 'undefined'
export let fromSSR = false
export let onSSR = isSSR

function getMatch (userAgent, platformMatch) {
  const match = /(edge|edga|edgios)\/([\w.]+)/.exec(userAgent) ||
    /(opr)[\/]([\w.]+)/.exec(userAgent) ||
    /(vivaldi)[\/]([\w.]+)/.exec(userAgent) ||
    /(chrome)[\/]([\w.]+)/.exec(userAgent) ||
    /(iemobile)[\/]([\w.]+)/.exec(userAgent) ||
    /(version)(applewebkit)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent) ||
    /(webkit)[\/]([\w.]+).*(version)[\/]([\w.]+).*(safari)[\/]([\w.]+)/.exec(userAgent) ||
    /(webkit)[\/]([\w.]+)/.exec(userAgent) ||
    /(opera)(?:.*version|)[\/]([\w.]+)/.exec(userAgent) ||
    /(msie) ([\w.]+)/.exec(userAgent) ||
    userAgent.indexOf('trident') >= 0 && /(rv)(?::| )([\w.]+)/.exec(userAgent) ||
    userAgent.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(userAgent) ||
    []

  return {
    browser: match[5] || match[3] || match[1] || '',
    version: match[2] || match[4] || '0',
    versionNumber: match[4] || match[2] || '0',
    platform: platformMatch[0] || ''
  }
}

function getPlatformMatch (userAgent) {
  return /(ipad)/.exec(userAgent) ||
    /(ipod)/.exec(userAgent) ||
    /(windows phone)/.exec(userAgent) ||
    /(iphone)/.exec(userAgent) ||
    /(kindle)/.exec(userAgent) ||
    /(silk)/.exec(userAgent) ||
    /(android)/.exec(userAgent) ||
    /(win)/.exec(userAgent) ||
    /(mac)/.exec(userAgent) ||
    /(linux)/.exec(userAgent) ||
    /(cros)/.exec(userAgent) ||
    /(playbook)/.exec(userAgent) ||
    /(bb)/.exec(userAgent) ||
    /(blackberry)/.exec(userAgent) ||
    []
}

function getPlatform (userAgent) {
  userAgent = (userAgent || navigator.userAgent || navigator.vendor || window.opera).toLowerCase()

  const
    platformMatch = getPlatformMatch(userAgent),
    matched = getMatch(userAgent, platformMatch),
    browser = { userAgent }

  if (matched.browser) {
    browser[matched.browser] = true
    browser.version = matched.version
    browser.versionNumber = parseInt(matched.versionNumber, 10)
  }

  if (matched.platform) {
    browser[matched.platform] = true
  }

  const knownMobiles = browser.android ||
    browser.ios ||
    browser.bb ||
    browser.blackberry ||
    browser.ipad ||
    browser.iphone ||
    browser.ipod ||
    browser.kindle ||
    browser.playbook ||
    browser.silk ||
    browser['windows phone']

  // These are all considered mobile platforms, meaning they run a mobile browser
  if (knownMobiles === true || userAgent.indexOf('mobile') > -1) {
    browser.mobile = true

    if (browser.edga || browser.edgios) {
      browser.edge = true
    }
  }
  // If it's not mobile we should consider it's desktop platform, meaning it runs a desktop browser
  // It's a workaround for anonymized user agents
  // (browser.cros || browser.mac || browser.linux || browser.win)
  else {
    browser.desktop = true
  }

  // Set iOS if on iPod, iPad or iPhone
  if (browser.ipod || browser.ipad || browser.iphone) {
    browser.ios = true
  }

  if (browser['windows phone']) {
    browser.winphone = true
    delete browser['windows phone']
  }

  // Chrome, Opera 15+, Vivaldi and Safari are webkit based browsers
  if (
    browser.chrome ||
    browser.opr ||
    browser.safari ||
    browser.vivaldi ||
    // we expect unknown, non iOS mobile browsers to be webkit based
    (
      browser.mobile === true &&
      browser.ios !== true &&
      knownMobiles !== true
    )
  ) {
    browser.webkit = true
  }

  // IE11 has a new token so we will assign it msie to avoid breaking changes
  if (browser.rv || browser.iemobile) {
    matched.browser = 'ie'
    browser.ie = true
  }

  // Edge is officially known as Microsoft Edge, so rewrite the key to match
  if (browser.edge) {
    matched.browser = 'edge'
    browser.edge = true
  }

  // Blackberry browsers are marked as Safari on BlackBerry
  if (browser.safari && browser.blackberry || browser.bb) {
    matched.browser = 'blackberry'
    browser.blackberry = true
  }

  // Playbook browsers are marked as Safari on Playbook
  if (browser.safari && browser.playbook) {
    matched.browser = 'playbook'
    browser.playbook = true
  }

  // Opera 15+ are identified as opr
  if (browser.opr) {
    matched.browser = 'opera'
    browser.opera = true
  }

  // Stock Android browsers are marked as Safari on Android.
  if (browser.safari && browser.android) {
    matched.browser = 'android'
    browser.android = true
  }

  // Kindle browsers are marked as Safari on Kindle
  if (browser.safari && browser.kindle) {
    matched.browser = 'kindle'
    browser.kindle = true
  }

  // Kindle Silk browsers are marked as Safari on Kindle
  if (browser.safari && browser.silk) {
    matched.browser = 'silk'
    browser.silk = true
  }

  if (browser.vivaldi) {
    matched.browser = 'vivaldi'
    browser.vivaldi = true
  }

  // Assign the name and platform variable
  browser.name = matched.browser
  browser.platform = matched.platform

  if (isSSR === false) {
    if (window.process && window.process.versions && window.process.versions.electron) {
      browser.electron = true
    }
    else if (document.location.href.indexOf('chrome-extension://') === 0) {
      browser.chromeExt = true
    }
    else if (window._cordovaNative || window.cordova) {
      browser.cordova = true
    }

    fromSSR = browser.cordova === void 0 &&
      browser.electron === void 0 &&
      !!document.querySelector('[data-server-rendered]')

    fromSSR === true && (onSSR = true)
  }

  return browser
}

let webStorage

export function hasWebStorage () {
  if (webStorage !== void 0) {
    return webStorage
  }

  try {
    if (window.localStorage) {
      webStorage = true
      return true
    }
  }
  catch (e) {}

  webStorage = false
  return false
}

function getClientProperties () {
  return {
    has: {
      touch: (() => 'ontouchstart' in window ||
        window.navigator.maxTouchPoints > 0
      )(),
      webStorage: hasWebStorage()
    },
    within: {
      iframe: window.self !== window.top
    }
  }
}

export default {
  has: {
    touch: false,
    webStorage: false
  },
  within: { iframe: false },

  parseSSR (/* ssrContext */ ssr) {
    return ssr ? {
      is: getPlatform(ssr.req.headers['user-agent'] || ssr.req.headers['User-Agent']),
      has: this.has,
      within: this.within
    } : {
      is: getPlatform(),
      ...getClientProperties()
    }
  },

  install ($q, queues) {
    if (isSSR === true) {
      queues.server.push((q, ctx) => {
        q.platform = this.parseSSR(ctx.ssr)
      })
      return
    }

    this.is = getPlatform()

    if (fromSSR === true) {
      queues.takeover.push(q => {
        onSSR = fromSSR = false
        Object.assign(q.platform, getClientProperties())
      })
      Vue.util.defineReactive($q, 'platform', this)
    }
    else {
      Object.assign(this, getClientProperties())
      $q.platform = this
    }
  }
}
<|endoftext|>


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

foam.CLASS({
  package: 'foam.u2',
  name: 'FoamTagLoader',

  documentation: 'Converts <foam> tags in document into Views.',

  imports: [ 'document', 'window', 'classloader' ],

  methods: [
    function init() {
      this.window.addEventListener('load', this.onLoad, false);
    },

    function findPropertyIC(cls, name) {
      var ps = cls.getAxiomsByClass(foam.core.Property);
      for ( var i = 0 ; i < ps.length ; i++ ) {
        if ( name === ps[i].name.toLowerCase() ) return ps[i];
      }
    },

    function loadTag(el) {
      var clsName = el.getAttribute('class');

      this.classloader.load(clsName).then(function(cls) {
        var obj = cls.create(null, foam.__context__);

        if ( obj.then ) {
          var p = new Promise(function(resolve) {
            obj.then(function() { resolve(); });
          });
          return p;
        }

        if ( obj.promiseE ) {
          obj.promiseE().then(function(view) { this.installView(el, view); });
        } else if ( obj.toE ) {
          this.installView(el, obj.toE({}, foam.__context__));
        } else if ( ! foam.u2.Element.isInstance(view) )  {
          installView(el, foam.u2.DetailView.create({data: view, showActions: true}));
        }
        return new Promise.resolve();
      }.bind(this), function(e) {
        console.error(e);
        console.error('Failed to load class: ', clsName);
      });
    },

    function installView(el, view) {
      var id  = el.id;

      for ( var j = 0 ; j < el.attributes.length ; j++ ) {
        var attr = el.attributes[j];
        var p    = this.findPropertyIC(view.cls_, attr.name);
        if ( p ) p.set(view, attr.value);
      }

      el.outerHTML = view.outerHTML;
      view.load();

      // Store view in global variable if named. Useful for testing.
      if ( id ) global[id] = view;
    },

    function aForEach(a, f, opt_i) {
      var i = opt_i || 0;
      if ( ! a || ! a.length || i >= a.length ) return;
      f(a[i]).then(this.aForEach.bind(this, a, f, i+1));
    }
  ],

  listeners: [
    function onLoad() {
      var els = Array.from(this.document.getElementsByTagName('foam'));
      this.window.removeEventListener('load', this.onLoad);

      aForEach(els, this.loadTag.bind(this));
//      els.forEach(this.loadTag.bind(this));
    }
  ]
});

foam.u2.FoamTagLoader.create();
<commit_msg>Fix for FoamTagLoader.<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 * Copyright 2018 The FOAM Authors.  All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'FoamTagLoader',

  documentation: 'Converts <foam> tags in document into Views.',

  imports: [ 'document', 'window', 'classloader' ],

  methods: [
    function init() {
      this.window.addEventListener('load', this.onLoad, false);
    },

    function findPropertyIC(cls, name) {
      var ps = cls.getAxiomsByClass(foam.core.Property);
      for ( var i = 0 ; i < ps.length ; i++ ) {
        if ( name === ps[i].name.toLowerCase() ) return ps[i];
      }
    },

    function loadTag(el) {
      var clsName = el.getAttribute('class');

      return new Promise(function(resolve, reject) {
        this.classloader.load(clsName).then(function(cls) {
          var obj = cls.create(null, foam.__context__);

          /*
          if ( obj.then ) {
            var p = new Promise(function(resolve) {
              obj.then(function() { resolve(); });
            });
            return p;
          }
          */

          if ( obj.promiseE ) {
            obj.promiseE().then(function(view) { this.installView(el, view); });
          } else if ( obj.toE ) {
            this.installView(el, obj.toE({}, foam.__context__));
          } else if ( ! foam.u2.Element.isInstance(view) )  {
            installView(el, foam.u2.DetailView.create({data: view, showActions: true}));
          }
          resolve();
        }.bind(this), function(e) {
          console.error(e);
          console.error('Failed to load class: ', clsName);
        });
      }.bind(this));
    },

    function installView(el, view) {
      var id  = el.id;

      for ( var j = 0 ; j < el.attributes.length ; j++ ) {
        var attr = el.attributes[j];
        var p    = this.findPropertyIC(view.cls_, attr.name);
        if ( p ) p.set(view, attr.value);
      }

      el.outerHTML = view.outerHTML;
      view.load();

      // Store view in global variable if named. Useful for testing.
      if ( id ) global[id] = view;
    },

    function aForEach(a, f, opt_i) {
      var i = opt_i || 0;
      if ( ! a || ! a.length || i >= a.length ) return;
      f(a[i]).then(this.aForEach.bind(this, a, f, i+1));
    }
  ],

  listeners: [
    function onLoad() {
      var els = Array.from(this.document.getElementsByTagName('foam'));
      this.window.removeEventListener('load', this.onLoad);

      this.aForEach(els, this.loadTag.bind(this));
//      els.forEach(this.loadTag.bind(this));
    }
  ]
});

foam.u2.FoamTagLoader.create();
<|endoftext|>


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

foam.CLASS({
  package: 'foam.u2',
  name: 'PropertyModal',
  extends: 'foam.u2.View',

  documentation: 'View for attaching a choice to a modal',

  imports: [
    'notify'
  ],

  requires: [
    'foam.u2.ControllerMode',
    'foam.u2.detail.SectionedDetailPropertyView'
  ],

  css: `
    ^ {
      border-radius: 3px;
      background-color: #fff;
      max-width: calc(100vw - 48px);
      max-height: calc(100vh - 116px);
      overflow-y: auto;
    }
    ^title {
      padding: 32px 0px;
      font-size: 1.5em;
      font-weight: bold;
    }
    ^main {
      padding: 0px 32px;
    }
    ^ .buttons {
      padding: 32px;
      box-sizing: border-box;
      display: flex;
      justify-content: flex-end;
    }
  `,

  messages: [
    { name: 'CONFIRM_DELETE_1', message: 'Are you sure you want to delete' },
    { name: 'SUCCESS_MSG', message: ' deleted' },
    { name: 'FAIL_MSG', message: 'Failed to delete' }
  ],

  properties: [
    {
      class: 'Function',
      name: 'onExecute'
    },
    {
      class: 'String',
      name: 'title',
      expression: function(isModalRequired) {
        if ( isModalRequired ) return 'Please fill out the following (required)';
        return 'Please fill out the following (optional)';
      }
    },
    {
      class: 'Property',
      name: 'property'
    },
    {
      class: 'Boolean',
      name: 'isModalRequired'
    },
    {
      name: 'propertyData',
      attribute: true
    },
  ],

  methods: [
    function initE() {
      this.SUPER();
      this
        .addClass(this.myClass())
        .start()
          .addClass(this.myClass('main'))
          .start()
            .addClass(this.myClass('title'))
            .add(this.title)
          .end()
          .startContext({ data: this, controllerMode: this.ControllerMode.EDIT })
          .tag(this.SectionedDetailPropertyView, {
            prop: this.property,
            data$: this.data$
          })
          .endContext()
        .end()
        .start()
          .addClass('buttons')
          .startContext({ data: this })
            .tag(this.CANCEL, { buttonStyle: 'SECONDARY' })
            .tag(this.OK)
          .endContext()
        .end();
    }
  ],

  actions: [
    {
      name: 'ok',
      isEnabled: (isModalRequired, propertyData) => {
        if ( ! isModalRequired ) return true;

        return propertyData;
      },
      code: function(X) {
        this.onExecute();
        X.closeDialog();
      }
    },
    {
      name: 'cancel',
      code: function(X) {
        X.closeDialog();
      }
    }
  ]
});
<commit_msg>Np 3647/nature code approval view (#4983)<commit_after>/**
 * @license
 * Copyright 2020 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.u2',
  name: 'PropertyModal',
  extends: 'foam.u2.View',

  documentation: 'View for attaching a choice to a modal',

  imports: [
    'notify'
  ],

  requires: [
    'foam.u2.ControllerMode',
    'foam.u2.detail.SectionedDetailPropertyView'
  ],

  css: `
    ^ {
      border-radius: 3px;
      background-color: #fff;
      max-width: calc(100vw - 48px);
      max-height: calc(100vh - 116px);
      overflow-y: auto;
      min-width: 20vw;
    }
    ^title {
      max-width: fit-content;
      padding: 32px 0px;
      font-size: 1.5em;
      font-weight: bold;
    }
    ^main {
      padding: 0px 32px;
    }
    ^ .buttons {
      padding: 32px;
      box-sizing: border-box;
      display: flex;
      justify-content: flex-end;
    }
  `,

  messages: [
    { name: 'CONFIRM_DELETE_1', message: 'Are you sure you want to delete' },
    { name: 'SUCCESS_MSG', message: ' deleted' },
    { name: 'FAIL_MSG', message: 'Failed to delete' }
  ],

  properties: [
    {
      class: 'Function',
      name: 'onExecute'
    },
    {
      class: 'String',
      name: 'title',
      expression: function(isModalRequired) {
        if ( isModalRequired ) return 'Please fill out the following (required)';
        return 'Please fill out the following (optional)';
      }
    },
    {
      class: 'Property',
      name: 'property'
    },
    {
      class: 'Boolean',
      name: 'isModalRequired'
    },
    {
      name: 'propertyData',
      attribute: true
    },
  ],

  methods: [
    function initE() {
      this.SUPER();
      this
        .addClass(this.myClass())
        .start()
          .addClass(this.myClass('main'))
          .start()
            .addClass(this.myClass('title'))
            .add(this.title$)
          .end()
          .startContext({ data: this, controllerMode: this.ControllerMode.EDIT })
          .tag(this.SectionedDetailPropertyView, {
            prop: this.property,
            data$: this.data$
          })
          .endContext()
        .end()
        .start()
          .addClass('buttons')
          .startContext({ data: this })
            .tag(this.CANCEL, { buttonStyle: 'SECONDARY' })
            .tag(this.OK)
          .endContext()
        .end();
    }
  ],

  actions: [
    {
      name: 'ok',
      isEnabled: (isModalRequired, propertyData) => {
        if ( ! isModalRequired ) return true;

        return propertyData;
      },
      code: function(X) {
        this.onExecute();
        X.closeDialog();
      }
    },
    {
      name: 'cancel',
      code: function(X) {
        X.closeDialog();
      }
    }
  ]
});
<|endoftext|>


<commit_before>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

(() => {
	// Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
	const isNodeJS = typeof process !== "undefined";
	if (isNodeJS) {
		global.require = require;
		global.fs = require("fs");

		const nodeCrypto = require("crypto");
		global.crypto = {
			getRandomValues(b) {
				nodeCrypto.randomFillSync(b);
			},
		};

		const now = () => {
			const [sec, nsec] = process.hrtime();
			return sec * 1000 + nsec / 1000000;
		};
		global.performance = {
			timeOrigin: Date.now() - now(),
			now: now,
		};

		const util = require("util");
		global.TextEncoder = util.TextEncoder;
		global.TextDecoder = util.TextDecoder;
	} else {
		window.global = window;

		let outputBuf = "";
		global.fs = {
			constants: {},
			writeSync(fd, buf) {
				outputBuf += decoder.decode(buf);
				const nl = outputBuf.lastIndexOf("\n");
				if (nl != -1) {
					console.log(outputBuf.substr(0, nl));
					outputBuf = outputBuf.substr(nl + 1);
				}
				return buf.length;
			},
		};
	}

	const encoder = new TextEncoder("utf-8");
	const decoder = new TextDecoder("utf-8");

	global.Go = class {
		constructor() {
			this.argv = ["js"];
			this.env = {};
			this.exit = (code) => {
				if (code !== 0) {
					console.warn("exit code:", code);
				}
			};

			const mem = () => {
				// The buffer may change when requesting more memory.
				return new DataView(this._inst.exports.mem.buffer);
			}

			const setInt64 = (addr, v) => {
				mem().setUint32(addr + 0, v, true);
				mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
			}

			const getInt64 = (addr) => {
				const low = mem().getUint32(addr + 0, true);
				const high = mem().getInt32(addr + 4, true);
				return low + high * 4294967296;
			}

			const loadValue = (addr) => {
				const id = mem().getUint32(addr, true);
				return this._values[id];
			}

			const storeValue = (addr, v) => {
				if (v === undefined) {
					mem().setUint32(addr, 0, true);
					return;
				}
				if (v === null) {
					mem().setUint32(addr, 1, true);
					return;
				}
				this._values.push(v);
				mem().setUint32(addr, this._values.length - 1, true);
			}

			const loadSlice = (addr) => {
				const array = getInt64(addr + 0);
				const len = getInt64(addr + 8);
				return new Uint8Array(this._inst.exports.mem.buffer, array, len);
			}

			const loadSliceOfValues = (addr) => {
				const array = getInt64(addr + 0);
				const len = getInt64(addr + 8);
				const a = new Array(len);
				for (let i = 0; i < len; i++) {
					const id = mem().getUint32(array + i * 4, true);
					a[i] = this._values[id];
				}
				return a;
			}

			const loadString = (addr) => {
				const saddr = getInt64(addr + 0);
				const len = getInt64(addr + 8);
				return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
			}

			this.importObject = {
				go: {
					// func wasmExit(code int32)
					"runtime.wasmExit": (sp) => {
						this.exit(mem().getInt32(sp + 8, true));
					},

					// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
					"runtime.wasmWrite": (sp) => {
						const fd = getInt64(sp + 8);
						const p = getInt64(sp + 16);
						const n = mem().getInt32(sp + 24, true);
						fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
					},

					// func nanotime() int64
					"runtime.nanotime": (sp) => {
						setInt64(sp + 8, (performance.timeOrigin + performance.now()) * 1000000);
					},

					// func walltime() (sec int64, nsec int32)
					"runtime.walltime": (sp) => {
						const msec = (new Date).getTime();
						setInt64(sp + 8, msec / 1000);
						mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
					},

					// func getRandomData(r []byte)
					"runtime.getRandomData": (sp) => {
						crypto.getRandomValues(loadSlice(sp + 8));
					},

					// func boolVal(value bool) Value
					"syscall/js.boolVal": (sp) => {
						storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
					},

					// func intVal(value int) Value
					"syscall/js.intVal": (sp) => {
						storeValue(sp + 16, getInt64(sp + 8));
					},

					// func floatVal(value float64) Value
					"syscall/js.floatVal": (sp) => {
						storeValue(sp + 16, mem().getFloat64(sp + 8, true));
					},

					// func stringVal(value string) Value
					"syscall/js.stringVal": (sp) => {
						storeValue(sp + 24, loadString(sp + 8));
					},

					// func (v Value) Get(key string) Value
					"syscall/js.Value.Get": (sp) => {
						storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
					},

					// func (v Value) set(key string, value Value)
					"syscall/js.Value.set": (sp) => {
						Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
					},

					// func (v Value) Index(i int) Value
					"syscall/js.Value.Index": (sp) => {
						storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
					},

					// func (v Value) setIndex(i int, value Value)
					"syscall/js.Value.setIndex": (sp) => {
						Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
					},

					// func (v Value) call(name string, args []Value) (Value, bool)
					"syscall/js.Value.call": (sp) => {
						try {
							const v = loadValue(sp + 8);
							const m = Reflect.get(v, loadString(sp + 16));
							const args = loadSliceOfValues(sp + 32);
							storeValue(sp + 56, Reflect.apply(m, v, args));
							mem().setUint8(sp + 60, 1);
						} catch (err) {
							storeValue(sp + 56, err);
							mem().setUint8(sp + 60, 0);
						}
					},

					// func (v Value) invoke(args []Value) (Value, bool)
					"syscall/js.Value.invoke": (sp) => {
						try {
							const v = loadValue(sp + 8);
							const args = loadSliceOfValues(sp + 16);
							storeValue(sp + 40, Reflect.apply(v, undefined, args));
							mem().setUint8(sp + 44, 1);
						} catch (err) {
							storeValue(sp + 40, err);
							mem().setUint8(sp + 44, 0);
						}
					},

					// func (v Value) new(args []Value) (Value, bool)
					"syscall/js.Value.new": (sp) => {
						try {
							const v = loadValue(sp + 8);
							const args = loadSliceOfValues(sp + 16);
							storeValue(sp + 40, Reflect.construct(v, args));
							mem().setUint8(sp + 44, 1);
						} catch (err) {
							storeValue(sp + 40, err);
							mem().setUint8(sp + 44, 0);
						}
					},

					// func (v Value) Float() float64
					"syscall/js.Value.Float": (sp) => {
						mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
					},

					// func (v Value) Int() int
					"syscall/js.Value.Int": (sp) => {
						setInt64(sp + 16, parseInt(loadValue(sp + 8)));
					},

					// func (v Value) Bool() bool
					"syscall/js.Value.Bool": (sp) => {
						mem().setUint8(sp + 16, !!loadValue(sp + 8));
					},

					// func (v Value) Length() int
					"syscall/js.Value.Length": (sp) => {
						setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
					},

					// func (v Value) prepareString() (Value, int)
					"syscall/js.Value.prepareString": (sp) => {
						const str = encoder.encode(String(loadValue(sp + 8)));
						storeValue(sp + 16, str);
						setInt64(sp + 24, str.length);
					},

					// func (v Value) loadString(b []byte)
					"syscall/js.Value.loadString": (sp) => {
						const str = loadValue(sp + 8);
						loadSlice(sp + 16).set(str);
					},

					"debug": (value) => {
						console.log(value);
					},
				}
			};
		}

		async run(instance) {
			this._inst = instance;
			this._values = [undefined, null, global, this._inst.exports.mem]; // TODO: garbage collection

			const mem = new DataView(this._inst.exports.mem.buffer)

			// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
			let offset = 4096;

			const strPtr = (str) => {
				let ptr = offset;
				new Uint8Array(mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
				offset += str.length + (8 - (str.length % 8));
				return ptr;
			};

			const argc = this.argv.length;

			const argvPtrs = [];
			this.argv.forEach((arg) => {
				argvPtrs.push(strPtr(arg));
			});

			const keys = Object.keys(this.env).sort();
			argvPtrs.push(keys.length);
			keys.forEach((key) => {
				argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
			});

			const argv = offset;
			argvPtrs.forEach((ptr) => {
				mem.setUint32(offset, ptr, true);
				mem.setUint32(offset + 4, 0, true);
				offset += 8;
			});

			this._inst.exports.run(argc, argv);
		}
	}

	if (isNodeJS) {
		if (process.argv.length < 3) {
			process.stderr.write("usage: go_js_wasm_exec [wasm binary] [arguments]\n");
			process.exit(1);
		}

		const go = new Go();
		go.argv = process.argv.slice(2);
		go.env = process.env;
		go.exit = process.exit;
		WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
			return go.run(result.instance);
		}).catch((err) => {
			console.error(err);
			process.exit(1);
		});
	}
})();
<commit_msg>misc/wasm: remove use of performance.timeOrigin<commit_after>// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

(() => {
	// Map web browser API and Node.js API to a single common API (preferring web standards over Node.js API).
	const isNodeJS = typeof process !== "undefined";
	if (isNodeJS) {
		global.require = require;
		global.fs = require("fs");

		const nodeCrypto = require("crypto");
		global.crypto = {
			getRandomValues(b) {
				nodeCrypto.randomFillSync(b);
			},
		};

		global.performance = {
			now() {
				const [sec, nsec] = process.hrtime();
				return sec * 1000 + nsec / 1000000;
			},
		};

		const util = require("util");
		global.TextEncoder = util.TextEncoder;
		global.TextDecoder = util.TextDecoder;
	} else {
		window.global = window;

		let outputBuf = "";
		global.fs = {
			constants: {},
			writeSync(fd, buf) {
				outputBuf += decoder.decode(buf);
				const nl = outputBuf.lastIndexOf("\n");
				if (nl != -1) {
					console.log(outputBuf.substr(0, nl));
					outputBuf = outputBuf.substr(nl + 1);
				}
				return buf.length;
			},
		};
	}

	const encoder = new TextEncoder("utf-8");
	const decoder = new TextDecoder("utf-8");

	global.Go = class {
		constructor() {
			this.argv = ["js"];
			this.env = {};
			this.exit = (code) => {
				if (code !== 0) {
					console.warn("exit code:", code);
				}
			};

			const mem = () => {
				// The buffer may change when requesting more memory.
				return new DataView(this._inst.exports.mem.buffer);
			}

			const setInt64 = (addr, v) => {
				mem().setUint32(addr + 0, v, true);
				mem().setUint32(addr + 4, Math.floor(v / 4294967296), true);
			}

			const getInt64 = (addr) => {
				const low = mem().getUint32(addr + 0, true);
				const high = mem().getInt32(addr + 4, true);
				return low + high * 4294967296;
			}

			const loadValue = (addr) => {
				const id = mem().getUint32(addr, true);
				return this._values[id];
			}

			const storeValue = (addr, v) => {
				if (v === undefined) {
					mem().setUint32(addr, 0, true);
					return;
				}
				if (v === null) {
					mem().setUint32(addr, 1, true);
					return;
				}
				this._values.push(v);
				mem().setUint32(addr, this._values.length - 1, true);
			}

			const loadSlice = (addr) => {
				const array = getInt64(addr + 0);
				const len = getInt64(addr + 8);
				return new Uint8Array(this._inst.exports.mem.buffer, array, len);
			}

			const loadSliceOfValues = (addr) => {
				const array = getInt64(addr + 0);
				const len = getInt64(addr + 8);
				const a = new Array(len);
				for (let i = 0; i < len; i++) {
					const id = mem().getUint32(array + i * 4, true);
					a[i] = this._values[id];
				}
				return a;
			}

			const loadString = (addr) => {
				const saddr = getInt64(addr + 0);
				const len = getInt64(addr + 8);
				return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len));
			}

			const timeOrigin = Date.now() - performance.now();
			this.importObject = {
				go: {
					// func wasmExit(code int32)
					"runtime.wasmExit": (sp) => {
						this.exit(mem().getInt32(sp + 8, true));
					},

					// func wasmWrite(fd uintptr, p unsafe.Pointer, n int32)
					"runtime.wasmWrite": (sp) => {
						const fd = getInt64(sp + 8);
						const p = getInt64(sp + 16);
						const n = mem().getInt32(sp + 24, true);
						fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n));
					},

					// func nanotime() int64
					"runtime.nanotime": (sp) => {
						setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000);
					},

					// func walltime() (sec int64, nsec int32)
					"runtime.walltime": (sp) => {
						const msec = (new Date).getTime();
						setInt64(sp + 8, msec / 1000);
						mem().setInt32(sp + 16, (msec % 1000) * 1000000, true);
					},

					// func getRandomData(r []byte)
					"runtime.getRandomData": (sp) => {
						crypto.getRandomValues(loadSlice(sp + 8));
					},

					// func boolVal(value bool) Value
					"syscall/js.boolVal": (sp) => {
						storeValue(sp + 16, mem().getUint8(sp + 8) !== 0);
					},

					// func intVal(value int) Value
					"syscall/js.intVal": (sp) => {
						storeValue(sp + 16, getInt64(sp + 8));
					},

					// func floatVal(value float64) Value
					"syscall/js.floatVal": (sp) => {
						storeValue(sp + 16, mem().getFloat64(sp + 8, true));
					},

					// func stringVal(value string) Value
					"syscall/js.stringVal": (sp) => {
						storeValue(sp + 24, loadString(sp + 8));
					},

					// func (v Value) Get(key string) Value
					"syscall/js.Value.Get": (sp) => {
						storeValue(sp + 32, Reflect.get(loadValue(sp + 8), loadString(sp + 16)));
					},

					// func (v Value) set(key string, value Value)
					"syscall/js.Value.set": (sp) => {
						Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32));
					},

					// func (v Value) Index(i int) Value
					"syscall/js.Value.Index": (sp) => {
						storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16)));
					},

					// func (v Value) setIndex(i int, value Value)
					"syscall/js.Value.setIndex": (sp) => {
						Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24));
					},

					// func (v Value) call(name string, args []Value) (Value, bool)
					"syscall/js.Value.call": (sp) => {
						try {
							const v = loadValue(sp + 8);
							const m = Reflect.get(v, loadString(sp + 16));
							const args = loadSliceOfValues(sp + 32);
							storeValue(sp + 56, Reflect.apply(m, v, args));
							mem().setUint8(sp + 60, 1);
						} catch (err) {
							storeValue(sp + 56, err);
							mem().setUint8(sp + 60, 0);
						}
					},

					// func (v Value) invoke(args []Value) (Value, bool)
					"syscall/js.Value.invoke": (sp) => {
						try {
							const v = loadValue(sp + 8);
							const args = loadSliceOfValues(sp + 16);
							storeValue(sp + 40, Reflect.apply(v, undefined, args));
							mem().setUint8(sp + 44, 1);
						} catch (err) {
							storeValue(sp + 40, err);
							mem().setUint8(sp + 44, 0);
						}
					},

					// func (v Value) new(args []Value) (Value, bool)
					"syscall/js.Value.new": (sp) => {
						try {
							const v = loadValue(sp + 8);
							const args = loadSliceOfValues(sp + 16);
							storeValue(sp + 40, Reflect.construct(v, args));
							mem().setUint8(sp + 44, 1);
						} catch (err) {
							storeValue(sp + 40, err);
							mem().setUint8(sp + 44, 0);
						}
					},

					// func (v Value) Float() float64
					"syscall/js.Value.Float": (sp) => {
						mem().setFloat64(sp + 16, parseFloat(loadValue(sp + 8)), true);
					},

					// func (v Value) Int() int
					"syscall/js.Value.Int": (sp) => {
						setInt64(sp + 16, parseInt(loadValue(sp + 8)));
					},

					// func (v Value) Bool() bool
					"syscall/js.Value.Bool": (sp) => {
						mem().setUint8(sp + 16, !!loadValue(sp + 8));
					},

					// func (v Value) Length() int
					"syscall/js.Value.Length": (sp) => {
						setInt64(sp + 16, parseInt(loadValue(sp + 8).length));
					},

					// func (v Value) prepareString() (Value, int)
					"syscall/js.Value.prepareString": (sp) => {
						const str = encoder.encode(String(loadValue(sp + 8)));
						storeValue(sp + 16, str);
						setInt64(sp + 24, str.length);
					},

					// func (v Value) loadString(b []byte)
					"syscall/js.Value.loadString": (sp) => {
						const str = loadValue(sp + 8);
						loadSlice(sp + 16).set(str);
					},

					"debug": (value) => {
						console.log(value);
					},
				}
			};
		}

		async run(instance) {
			this._inst = instance;
			this._values = [undefined, null, global, this._inst.exports.mem]; // TODO: garbage collection

			const mem = new DataView(this._inst.exports.mem.buffer)

			// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
			let offset = 4096;

			const strPtr = (str) => {
				let ptr = offset;
				new Uint8Array(mem.buffer, offset, str.length + 1).set(encoder.encode(str + "\0"));
				offset += str.length + (8 - (str.length % 8));
				return ptr;
			};

			const argc = this.argv.length;

			const argvPtrs = [];
			this.argv.forEach((arg) => {
				argvPtrs.push(strPtr(arg));
			});

			const keys = Object.keys(this.env).sort();
			argvPtrs.push(keys.length);
			keys.forEach((key) => {
				argvPtrs.push(strPtr(`${key}=${this.env[key]}`));
			});

			const argv = offset;
			argvPtrs.forEach((ptr) => {
				mem.setUint32(offset, ptr, true);
				mem.setUint32(offset + 4, 0, true);
				offset += 8;
			});

			this._inst.exports.run(argc, argv);
		}
	}

	if (isNodeJS) {
		if (process.argv.length < 3) {
			process.stderr.write("usage: go_js_wasm_exec [wasm binary] [arguments]\n");
			process.exit(1);
		}

		const go = new Go();
		go.argv = process.argv.slice(2);
		go.env = process.env;
		go.exit = process.exit;
		WebAssembly.instantiate(fs.readFileSync(process.argv[2]), go.importObject).then((result) => {
			return go.run(result.instance);
		}).catch((err) => {
			console.error(err);
			process.exit(1);
		});
	}
})();
<|endoftext|>


<commit_before>'use strict';

var products = [
    {
        "id": "1",
        "name": "BB-8",
        "descrition": "App-Enabled Droid™ by Sphero",
        "price": 149.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/ijgi_sphero_bb8.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/ijgi_sphero_bb8_add1.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/ijgi_sphero_bb8_add3.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/ijgi_sphero_bb8_add4.jpg"
        ]
    },
    {
        "id": "2",
        "name": "Phaser",
        "descrition": "Exclusive Star Trek Phaser Remote Replica",
        "price": 149.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/1db4_star_trek_phaser_remote_replica.jpg",
            "",
            "",
            "",
            ""
        ]
    },
    {
        "id": "3",
        "name": "",
        "descrition": "",
        "price":,
        "images": [
            ""
        ]
    },
    {
        "id": "4",
        "name": "",
        "descrition": "",
        "price":,
        "images": [
            ""
        ]
    },
    {
        "id": "5",
        "name": "",
        "descrition": "",
        "price":,
        "images": [
            ""
        ]
    }
]<commit_msg>adding products<commit_after>'use strict';

var products = [
    {
        "id": "1",
        "name": "BB-8",
        "descrition": "App-Enabled Droid™ by Sphero",
        "price": 149.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/ijgi_sphero_bb8.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/ijgi_sphero_bb8_add1.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/ijgi_sphero_bb8_add3.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/ijgi_sphero_bb8_add4.jpg"
        ]
    },
    {
        "id": "2",
        "name": "Phaser",
        "descrition": "Exclusive Star Trek Phaser Remote Replica",
        "price": 149.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/1db4_star_trek_phaser_remote_replica.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/1db4_star_trek_phaser_remote_replica_glow.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/1db4_star_trek_phaser_remote_replica_box_open.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/1db4_star_trek_phaser_remote_replica_box_closed.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/1db4_star_trek_phaser_remote_replica_scan.jpg"
        ]
    },
    {
        "id": "3",
        "name": "Talking Figures",
        "descrition": "Pulp Fiction 13\" Talking Figures",
        "price": 29.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/irjm_pulp_fiction_13in_talking_figs.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/irjm_pulp_fiction_13in_talking_figs_jimmie.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/irjm_pulp_fiction_13in_talking_figs_jules.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/irjm_pulp_fiction_13in_talking_figs_vincent.jpg"
        ]
    },
    {
        "id": "4",
        "name": "Lightsaber",
        "descrition": "Star Wars Darth Vader Lightsaber Laser Pointer",
        "price":14.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/c5e6_star_wars_laser_pointers.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/huih_sw_vader_lightsaber_laser_pointer_inhand.jpg"
        ]
    },
    {
        "id": "5",
        "name": "Tardis",
        "descrition": "Doctor Who: 11th Doctor 1/6 Scale Collectibles",
        "price":379.99,
        "images": [
            "http://www.thinkgeek.com/images/products/frontsquare/iqti_dw_11th_collectibles.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/iqti_dw_11th_collectibles_scale.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/iqti_dw_11th_collectibles_both.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/iqti_dw_11th_collectibles_fig2.jpg",
            "http://www.thinkgeek.com/images/products/additional/carousel/iqti_dw_11th_collectibles_parts.jpg"
        ]
    }
]<|endoftext|>


<commit_before>const config = require("./../../config.json");
const yt = require('ytdl-core');
const fs = require('fs');
const msg = require('./../msg/');
const Discord = require("discord.js");

var playlist = [];
var stream = [];
var current = [];

exports.sound = sound;
exports.play = play;
exports.add = add;
exports.skip = skip;
exports.stop = stop;
exports.get = get;
exports.list = list;

//A function to keep playing that stream
function sound(message) {
	var voiceChannel = message.member.voiceChannel;

	voiceChannel.join()
	.then(connnection => {
		//Declare a function that will be called by itself so the play(message) command will be called when required, instead of all at once.
		var looper = function() {
			play(message);
			const dispatcher = connnection.playStream(stream[message.guild.id]);
			dispatcher.on('end', () => {
				looper();
			});
		}
		looper();
	});
}

//A function to generate the streams from the playlist
function play(message) {
	var voiceChannel = message.member.voiceChannel;

	if(!voiceChannel) {
		//Not in voice
		return MSS.msg.react(message, false, "call");
	}

	if (playlist[message.guild.id].length > 0) {
		current[message.guild.id] = JSON.parse(playlist[message.guild.id].shift());
		message.channel.sendMessage('**Music Control Panel**')
			.then(function(message) {
				message.react(String.fromCodePoint(10145));
				message.react(String.fromCodePoint(8505));
				message.react(String.fromCodePoint(128240));
			});
		switch (current[message.guild.id]["type"]) {
			case "youtube":
				stream[message.guild.id] = yt(current[message.guild.id]["url"], {audioonly: true});
				break;
			case "local":
				stream[message.guild.id] = fs.createReadStream(current[message.guild.id]["url"]);
				break;
			case "url":
				request.get(message.content.substring(input[0].length + 1), function(res) {
					res.on('data', function(chunk) {
						stream[message.guild.id] += chunk;
					});
				});
				break;
		}
	} else {
		if (voiceChannel && voiceChannel.connection) voiceChannel.leave();
		playlist[message.guild.id] = [];
		if (stream[message.guild.id]) stream[message.guild.id].destroy();
		return;
	}
}

//A function to push a new video onto the playlist stack
function add(message, type, url, title, thumb_url) {
	playlist[message.guild.id] = playlist[message.guild.id] || [];
	playlist[message.guild.id].push(JSON.stringify({type: type, url: url, title: title, thumb_url: thumb_url}));
	if (!message.member.voiceChannel.connection) {
		sound(message);
	}
}

function skip(message) {
	message.channel.send("Destroying stream...");
	stream[message.guild.id].destroy();
}

function stop(message) {
	playlist[message.guild.id] = [];
	skip(message);
}

function list(message) {
	if (playlist[message.guild.id].length > 0) {
		return msg.rich(message, "MSS Music Player", playlist[message.guild.id].map(function(sound){return JSON.parse(sound).title;}).join("\n"), "#00FF00");
	} else {
		return msg.rich(message, "MSS Music Player", "There is no music remaining in the playlist.", "#FF0000");
	}
}

function get(message) {
	var embed = new Discord.RichEmbed()
		.setTitle("MSS Music Player")
		.setAuthor("MSS", "http://moustacheminer.com/mss.png")
		.setColor("#00FF00")
		.setDescription("Now playing: " + current[message.guild.id]["title"])
		.setFooter("MSS-Discord, " + config.MSS.version, "")
		.setTimestamp()
		.setURL(current[message.guild.id]["url"])
		.setImage(current[message.guild.id]["thumb_url"]);

	message.channel.sendEmbed(embed, "", { disableEveryone: true });
}
<commit_msg>require request<commit_after>const config = require("./../../config.json");
const yt = require('ytdl-core');
const fs = require('fs');
const msg = require('./../msg/');
const Discord = require("discord.js");
const request = require("request");

var playlist = [];
var stream = [];
var current = [];

exports.sound = sound;
exports.play = play;
exports.add = add;
exports.skip = skip;
exports.stop = stop;
exports.get = get;
exports.list = list;

//A function to keep playing that stream
function sound(message) {
	var voiceChannel = message.member.voiceChannel;

	voiceChannel.join()
	.then(connnection => {
		//Declare a function that will be called by itself so the play(message) command will be called when required, instead of all at once.
		var looper = function() {
			play(message);
			const dispatcher = connnection.playStream(stream[message.guild.id]);
			dispatcher.on('end', () => {
				looper();
			});
		}
		looper();
	});
}

//A function to generate the streams from the playlist
function play(message) {
	var voiceChannel = message.member.voiceChannel;

	if(!voiceChannel) {
		//Not in voice
		return MSS.msg.react(message, false, "call");
	}

	if (playlist[message.guild.id].length > 0) {
		current[message.guild.id] = JSON.parse(playlist[message.guild.id].shift());
		message.channel.sendMessage('**Music Control Panel**')
			.then(function(message) {
				message.react(String.fromCodePoint(10145));
				message.react(String.fromCodePoint(8505));
				message.react(String.fromCodePoint(128240));
			});
		switch (current[message.guild.id]["type"]) {
			case "youtube":
				stream[message.guild.id] = yt(current[message.guild.id]["url"], {audioonly: true});
				break;
			case "local":
				stream[message.guild.id] = fs.createReadStream(current[message.guild.id]["url"]);
				break;
			case "url":
				request.get(message.content.substring(input[0].length + 1), function(res) {
					res.on('data', function(chunk) {
						stream[message.guild.id] += chunk;
					});
				});
				break;
		}
	} else {
		if (voiceChannel && voiceChannel.connection) voiceChannel.leave();
		playlist[message.guild.id] = [];
		if (stream[message.guild.id]) stream[message.guild.id].destroy();
		return;
	}
}

//A function to push a new video onto the playlist stack
function add(message, type, url, title, thumb_url) {
	playlist[message.guild.id] = playlist[message.guild.id] || [];
	playlist[message.guild.id].push(JSON.stringify({type: type, url: url, title: title, thumb_url: thumb_url}));
	if (!message.member.voiceChannel.connection) {
		sound(message);
	}
}

function skip(message) {
	message.channel.send("Destroying stream...");
	stream[message.guild.id].destroy();
}

function stop(message) {
	playlist[message.guild.id] = [];
	skip(message);
}

function list(message) {
	if (playlist[message.guild.id].length > 0) {
		return msg.rich(message, "MSS Music Player", playlist[message.guild.id].map(function(sound){return JSON.parse(sound).title;}).join("\n"), "#00FF00");
	} else {
		return msg.rich(message, "MSS Music Player", "There is no music remaining in the playlist.", "#FF0000");
	}
}

function get(message) {
	var embed = new Discord.RichEmbed()
		.setTitle("MSS Music Player")
		.setAuthor("MSS", "http://moustacheminer.com/mss.png")
		.setColor("#00FF00")
		.setDescription("Now playing: " + current[message.guild.id]["title"])
		.setFooter("MSS-Discord, " + config.MSS.version, "")
		.setTimestamp()
		.setURL(current[message.guild.id]["url"])
		.setImage(current[message.guild.id]["thumb_url"]);

	message.channel.sendEmbed(embed, "", { disableEveryone: true });
}
<|endoftext|>


<commit_before>const config = require("./../../config.json");
const yt = require('ytdl-core');
const fs = require('fs');
const msg = require('./../msg/');

var playlist = [];
var stream = [];
var current = [];

exports.sound = sound;
exports.play = play;
exports.add = add;
exports.skip = skip;
exports.stop = stop;
exports.get = get;
exports.list = list;

//A function to keep playing that stream
function sound(message) {
	var voiceChannel = message.member.voiceChannel;

	voiceChannel.join()
	.then(connnection => {
		//Declare a function that will be called by itself so the play(message) command will be called when required, instead of all at once.
		var looper = function() {
			play(message);
			const dispatcher = connnection.playStream(stream[message.guild.id]);
			dispatcher.on('end', () => {
				looper();
			});
		}
		looper();
	});
}

//A function to generate the streams from the playlist
function play(message) {
	var voiceChannel = message.member.voiceChannel;

	if(!voiceChannel) {
		//Not in voice
		return MSS.msg.react(message, false, "call");
	}

	if (playlist[message.guild.id].length > 0) {
		current[message.guild.id] = JSON.parse(playlist[message.guild.id].shift());
		message.channel.sendMessage('**Music Control Panel**')
			.then(function(message) {
				message.react(String.fromCodePoint(10145));
				message.react(String.fromCodePoint(8505));
				message.react(String.fromCodePoint(128240));
			});
		switch (current[message.guild.id]["type"]) {
			case "youtube":
				stream[message.guild.id] = yt(current[message.guild.id]["url"], {audioonly: true});
				break;
			case "local":
				stream[message.guild.id] = fs.createReadStream(current[message.guild.id]["url"]);
				break;
		}
	} else {
		if (voiceChannel && voiceChannel.connection) voiceChannel.leave();
		playlist[message.guild.id] = [];
		if (stream[message.guild.id]) stream[message.guild.id].destroy();
		return;
	}
}

//A function to push a new video onto the playlist stack
function add(message, type, url, title, thumb_url) {
	playlist[message.guild.id] = playlist[message.guild.id] || [];
	playlist[message.guild.id].push(JSON.stringify({type: type, url: url, title: title, thumb_url: thumb_url}));
	if (!message.member.voiceChannel.connection) {
		sound(message);
	}
}

function skip(message) {
	message.channel.send("Destroying stream...");
	stream[message.guild.id].destroy();
}

function stop(message) {
	playlist[message.guild.id] = [];
	skip(message);
}

function list(message) {
	if (playlist[message.guild.id].length > 0) {
		return richSend(message, "MSS Music Player", playlist[message.guild.id].map(function(sound){return JSON.parse(sound).title;}).join("\n"), "#00FF00");
	} else {
		return richSend(message, "MSS Music Player", "There is no music remaining in the playlist.", "#FF0000");
	}
}

function get(message) {
	var embed = new Discord.RichEmbed()
		.setTitle("MSS Music Player")
		.setAuthor("MSS", "http://moustacheminer.com/mss.png")
		.setColor("#00FF00")
		.setDescription("Now playing: " + current[messageReaction.message.guild.id]["title"])
		.setFooter("MSS-Discord, " + config.MSS.version, "")
		.setTimestamp()
		.setURL(current[messageReaction.message.guild.id]["url"])
		.setImage(current[messageReaction.message.guild.id]["thumb_url"]);

	message.channel.sendEmbed(embed, "", { disableEveryone: true });
}
<commit_msg>removed legacy rich send<commit_after>const config = require("./../../config.json");
const yt = require('ytdl-core');
const fs = require('fs');
const msg = require('./../msg/');

var playlist = [];
var stream = [];
var current = [];

exports.sound = sound;
exports.play = play;
exports.add = add;
exports.skip = skip;
exports.stop = stop;
exports.get = get;
exports.list = list;

//A function to keep playing that stream
function sound(message) {
	var voiceChannel = message.member.voiceChannel;

	voiceChannel.join()
	.then(connnection => {
		//Declare a function that will be called by itself so the play(message) command will be called when required, instead of all at once.
		var looper = function() {
			play(message);
			const dispatcher = connnection.playStream(stream[message.guild.id]);
			dispatcher.on('end', () => {
				looper();
			});
		}
		looper();
	});
}

//A function to generate the streams from the playlist
function play(message) {
	var voiceChannel = message.member.voiceChannel;

	if(!voiceChannel) {
		//Not in voice
		return MSS.msg.react(message, false, "call");
	}

	if (playlist[message.guild.id].length > 0) {
		current[message.guild.id] = JSON.parse(playlist[message.guild.id].shift());
		message.channel.sendMessage('**Music Control Panel**')
			.then(function(message) {
				message.react(String.fromCodePoint(10145));
				message.react(String.fromCodePoint(8505));
				message.react(String.fromCodePoint(128240));
			});
		switch (current[message.guild.id]["type"]) {
			case "youtube":
				stream[message.guild.id] = yt(current[message.guild.id]["url"], {audioonly: true});
				break;
			case "local":
				stream[message.guild.id] = fs.createReadStream(current[message.guild.id]["url"]);
				break;
		}
	} else {
		if (voiceChannel && voiceChannel.connection) voiceChannel.leave();
		playlist[message.guild.id] = [];
		if (stream[message.guild.id]) stream[message.guild.id].destroy();
		return;
	}
}

//A function to push a new video onto the playlist stack
function add(message, type, url, title, thumb_url) {
	playlist[message.guild.id] = playlist[message.guild.id] || [];
	playlist[message.guild.id].push(JSON.stringify({type: type, url: url, title: title, thumb_url: thumb_url}));
	if (!message.member.voiceChannel.connection) {
		sound(message);
	}
}

function skip(message) {
	message.channel.send("Destroying stream...");
	stream[message.guild.id].destroy();
}

function stop(message) {
	playlist[message.guild.id] = [];
	skip(message);
}

function list(message) {
	if (playlist[message.guild.id].length > 0) {
		return msg.rich(message, "MSS Music Player", playlist[message.guild.id].map(function(sound){return JSON.parse(sound).title;}).join("\n"), "#00FF00");
	} else {
		return msg.rich(message, "MSS Music Player", "There is no music remaining in the playlist.", "#FF0000");
	}
}

function get(message) {
	var embed = new Discord.RichEmbed()
		.setTitle("MSS Music Player")
		.setAuthor("MSS", "http://moustacheminer.com/mss.png")
		.setColor("#00FF00")
		.setDescription("Now playing: " + current[messageReaction.message.guild.id]["title"])
		.setFooter("MSS-Discord, " + config.MSS.version, "")
		.setTimestamp()
		.setURL(current[messageReaction.message.guild.id]["url"])
		.setImage(current[messageReaction.message.guild.id]["thumb_url"]);

	message.channel.sendEmbed(embed, "", { disableEveryone: true });
}
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Event = require('./event.js');
var BidCampaign = require('./bidCampaign.js');
var User = require('./user.js');
var TeamMember = require(('./teamMember.js');

var Notification = new Schema({
    //the status field is only used with an assignment type of notification, indicates the assignees response
    status: {
        type: String,
        enum: ['SUBMITTED', 'PENDING', 'ACCEPTED', 'REJECTED']
    },
    type: {
        type: String,
        required: true,
        enum: ['ASSIGNMENT', 'GENERAL', 'CLOSURE', 'NEW_EVENT', 'NEW_MESSAGE', 'MODIFIED_EVENT', 'BID']
    },
    //the position field is only used with an assignment type of notification, indicating which position the ref or trainer is assigned to.
    position: {
        type: String,
        enum: ['CENTER', 'SIDELINE', 'HEAD', 'ASSISTANT']
    },
    campaign: {
        type: Schema.Types.ObjectId,
        ref: 'BidCampaign'
    },
    event: {
        type: Schema.Types.ObjectId,
        ref: 'Event'
    },
    text: String,
    sender: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    recipient: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    team_recipient: {
        type: Schema.Types.ObjectId,
        ref: 'TeamMember'
    }
}, {
    timestamps: true
});

module.exports = mongoose.model('Notification', Notification);<commit_msg>Bug correction<commit_after>var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Event = require('./event.js');
var BidCampaign = require('./bidCampaign.js');
var User = require('./user.js');
var TeamMember = require('./teamMember.js');

var Notification = new Schema({
    //the status field is only used with an assignment type of notification, indicates the assignees response
    status: {
        type: String,
        enum: ['SUBMITTED', 'PENDING', 'ACCEPTED', 'REJECTED']
    },
    type: {
        type: String,
        required: true,
        enum: ['ASSIGNMENT', 'GENERAL', 'CLOSURE', 'NEW_EVENT', 'NEW_MESSAGE', 'MODIFIED_EVENT', 'BID']
    },
    //the position field is only used with an assignment type of notification, indicating which position the ref or trainer is assigned to.
    position: {
        type: String,
        enum: ['CENTER', 'SIDELINE', 'HEAD', 'ASSISTANT']
    },
    campaign: {
        type: Schema.Types.ObjectId,
        ref: 'BidCampaign'
    },
    event: {
        type: Schema.Types.ObjectId,
        ref: 'Event'
    },
    text: String,
    sender: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    recipient: {
        type: Schema.Types.ObjectId,
        ref: 'User'
    },
    team_recipient: {
        type: Schema.Types.ObjectId,
        ref: 'TeamMember'
    }
}, {
    timestamps: true
});

module.exports = mongoose.model('Notification', Notification);<|endoftext|>