<commit_before>import {inject} from 'aurelia-framework';
import {App} from '../app';
import {json} from 'aurelia-fetch-client';
import { ValidationControllerFactory, ValidationRules, Validator, validateTrigger } from 'aurelia-validation';
import {FormValidator} from '../classes/FormValidator';
//import {VolOpp} from '../classes/VolOpp';
@inject(App, ValidationControllerFactory, Validator)
export class Charity {
  controller = null;
  validator = null;
  constructor(app, controllerFactory, validator){
    this.app = app;
    this.charities = [];
    this.validator2 = new FormValidator(validator, (results) => this.updateCanSubmit2(results));
    this.controller2 = controllerFactory.createForCurrentScope(this.validator2);
    this.controller2.validateTrigger = validateTrigger.changeOrBlur;
    this.canSubmit2 = false;
    this.validType2 = false;
  }

  async activate(){
    this.update = false;
    this.types = ['Christian', 'Environmental', 'Hunger', 'Animal Rights', 'Homeless', 'Veterans', 'Elderly'];
    this.types.sort();
    this.types.push('other');
    this.uid = this.app.auth.getTokenPayload().sub;
    this.user = await this.app.appState.getUser(this.uid);
    this.app.dashboardTitle = this.user.userType;
    this.app.role = this.user.userType;
    const res = await this.app.httpClient.fetch('/charity/' + this.uid);
    this.charities = await res.json();
    if (this.charities.length !== 0){
      this.app.buildPTag(this.charities, 'charityTypes', 'charityTypeOther', 'charityTypesHtml');
      this.buildManagers();
      this.checkEvents();
    }
  }

  async checkEvents(){
    for (let i = 0; i < this.charities.length; i++){
      let foundEvents = [];
      this.charities[i].hasEvents = false;
      let res = await this.app.httpClient.fetch('/volopp/' + this.charities[i]._id);
      foundEvents = await res.json();
      if (foundEvents.length > 0){
        this.charities[i].hasEvents = true;
      }
    }
  }

  createNewCharity(){
    console.log('createNewCharity function populates a blank charity object and then runs the showUpdateCharity function');
    let charity = {
      'charityName': '',
      'charityStreet': '',
      'charityCity': '',
      'charityState': '',
      'charityZipCode': '',
      'charityTypes': [],
      'charityManagers': [],
      'charityMngIds': [],
      'charityTypeOther': '',
      'charityTypesHtml': ''
    };
    this.update = false;
    let charitiesTable = document.getElementById('charTable');
    if (charitiesTable !== null){
      charitiesTable.style.display = 'block';
    }
    this.updateScheduledEvent = false;
    let createNewButton = document.getElementById('createNewCharityButton');
    if (createNewButton !== null){
      createNewButton.style.display = 'none';
    }
    this.showUpdateCharity(charity);
  }

  updateCharityFunction(charity){
    this.update = true;
    this.canSubmit2 = true;
    this.validType2 = true;
    this.showUpdateCharity(charity);
  }

  showUpdateCharity(charity){
    // let updateDiv = document.getElementById('updateCharitySection');
    // updateDiv.style.display = 'block';
    // let scheduleDiv = document.getElementById('scheduleCharitySection');
    // if (scheduleDiv !== null){
    //   scheduleDiv.style.display = 'none';
    // }
    this.charityName = charity.charityName;
    this.updateCharity = charity;
    this.updateCharity.charityEmail = '';
    if (this.updateCharity.charityTypes.includes('other')){
      this.typeOther = true;
    } else {
      this.typeOther = false;
      this.updateCharity.charitytypeOther = '';
    }
    this.setupValidation2();
    if (this.update === true){
      document.getElementById('updateCharitySection').scrollIntoView();
    } else {
      document.getElementById('charityDash').scrollIntoView();
    }
  }

  updateTypePicked(){
    this.validType2 = false;
    let nub = document.getElementsByClassName('updateButton')[0];
    nub.style.display = 'none';
    for (let i = 0; i < this.types.length; i++) {
      if (this.updateCharity.charityTypes.indexOf(this.types[i]) > -1){
        this.validType2 = true;
        if (this.canSubmit2 && nub){
          nub.style.display = 'block';
        }
      }
    }
    this.validate2();
    console.log('the charity types picked are: ' + this.updateCharity.charityTypes);
    if (this.updateCharity.charityTypes.includes('other')){
      this.typeOther = true;
    } else {
      this.typeOther = false;
      this.updateCharity.charityTypeOther = '';
    }
  }

  setupValidation2() {
    ValidationRules
    .ensure('charityTypes').required().minLength(1).withMessage('charity type is required')
    .ensure('charityPhoneNumber').matches(/\b[2-9]\d{9}\b/).withMessage('10 digits only')
    .ensure('charityName').required().maxLength(40).withMessage('Charity name please')
    .ensure('charityEmail').email()
    .ensure('charityZipCode').required().matches(/\b\d{5}\b/).withMessage('5-digit zipcode')
    .ensure('charityCity').required().matches(/[^0-9]+/).maxLength(30).withMessage('City name please')
    .ensure('charityStreet').required().maxLength(40).withMessage('Charity street address please')
    .ensure('charityState').required().withMessage('Charity state please')
    .on(this.updateCharity);
  }

  validate2() {
    return this.validator2.validateObject(this.updateCharity);
  }

  updateCanSubmit2(validationResults) {
    let valid = true;
    console.log('Running updateCanSubmit2');
    let nub = document.getElementsByClassName('updateButton')[0];
    if (nub) {
      for (let result of validationResults) {
        if (result.valid === false){
          nub.style.display = 'none';
          valid = false;
          break;
        }
      }
      this.canSubmit2 = valid;
      if (this.canSubmit2 && this.validType2){
        nub.style.display = 'block';
      }
      return this.canSubmit2;
    }
  }

  createCharity(){
    this.updateCharity.charityManagers[0] = this.user.name;
    this.updateCharity.charityMngIds[0] = this.user._id;
    console.log('this is the update charity email: ' + this.updateCharity.charityEmail);
    if (this.updateCharity.charityEmail !== '' && this.updateCharity.charityEmail !== null){
      this.findUserByEmail('post');
    } else {
      this.postCharity();
    }
  }

  postCharity(){
    this.app.httpClient.fetch('/charity/create', {
      method: 'post',
      body: json(this.updateCharity)
    })
    .then((data) => {
      console.log(data);
      document.getElementById('charityDash').scrollIntoView();
      this.activate();
      this.createNewCharity();
    });
  }

  buildManagers(){
    for (let l = 0; l < this.charities.length; l++){
      let manHtml = '';
      for (let i = 0; i < this.charities[l].charityManagers.length; i++) {
        if (this.charities[l].charityManagers[i] !== ''){
          manHtml = manHtml + '
' + this.charities[l].charityManagers[i] + '
';
        }
      }
      if (manHtml === ''){
        manHtml = '
not specified
';
      }
      this.charities[l].charityManagersHtml = manHtml;
    }
  }

  async deleteCharity(charityId){
    await fetch;
    this.app.httpClient.fetch('/charity/' + charityId, {
      method: 'delete'
    })
    .then((data) => {
      console.log('your charity has been deleted');
      this.activate();
      this.createNewCharity();
    });
  }

  updateCharityFunct(){
    console.log('this is the update charity email: ' + this.updateCharity.charityEmail);
    if (this.updateCharity.charityEmail !== '' && this.updateCharity.charityEmail !== null){
      this.findUserByEmail('put');
    } else {
      this.putCharity();
    }
  }

  removeManager(charity){
    this.updateCharity = charity;
    const index = this.updateCharity.charityMngIds.indexOf(this.uid);
    if (index > -1){
      this.updateCharity.charityMngIds.splice(index, 1);
    }
    const index2 = this.updateCharity.charityManagers.indexOf(this.user.name);
    if (index > -1){
      this.updateCharity.charityManagers.splice(index2, 1);
    }
    this.putCharity();
  }

  afterUpdate(){
    this.updateCharity = {};
    document.getElementById('charityDash').scrollIntoView();
    this.activate();
    this.createNewCharity();
  }

  async putCharity(){
    await this.app.updateById('/charity/', this.updateCharity._id, this.updateCharity, null);
    this.afterUpdate();
    //console.log('this is the update charity');
    //console.log(this.updateCharity);
    //await fetch;
    // this.app.httpClient.fetch('/charity/' + this.updateCharity._id, {
    //   method: 'put',
    //   body: json(this.updateCharity)
    // })
    // .then((response) => response.json())
    // .then((data) => {
      // let updateDiv = document.getElementById('updateCharitySection');
      // if (updateDiv !== null){
      //   updateDiv.style.display = 'none';
      // }
    //});
  }

  async findUserByEmail(thenDo){
    await fetch;
    this.app.httpClient.fetch('/user/', {
      method: 'post',
      body: json({email: this.updateCharity.charityEmail})
    })
    .then((response) => response.json())
    .then((data) => {
      if (data.length !== 0){
        //console.log('the additional manager is: ' + JSON.stringify(data));
        const tempManager = data;
        console.log('this is the additional manager: ');
        console.log(tempManager[0].name);
        console.log(tempManager[0]._id);
        //only do this if the array does not already contain the user id, else alert that the user is already a manager of this charity
        for (let l = 0; l < this.updateCharity.charityMngIds.length; l++){
          console.log('checking for already a manager');
          /* istanbul ignore else */
          if (this.updateCharity.charityMngIds.indexOf(tempManager[0]._id) > -1){
            return alert('this user is already a manager of this charity');
          }
        }
        this.updateCharity.charityMngIds.push(tempManager[0]._id);
        this.updateCharity.charityManagers.push(tempManager[0].name);
        if (thenDo === 'put'){
          this.putCharity();
        } else {
          this.postCharity();
        }
      } else {
        alert('There is no OHAF user with that email');
      }
    });
  }

  // removeHyphen(){
  //   console.log('running remove hyphen');
  //   let charityPhone = document.getElementById('charity-phone').value;
  //   console.log(charityPhone);
  //   if (charityPhone.indexOf('-') !== -1){
  //     charityPhone.replace('-', '');
  //   }
  // }

  attached(){
    this.createNewCharity();
  }
}
<commit_msg>update validate2 to validate charityType and display error when not valid. minor modifications made to other methods like updateTypePicked()<commit_after>import {inject} from 'aurelia-framework';
import {App} from '../app';
import {json} from 'aurelia-fetch-client';
import { ValidationControllerFactory, ValidationRules, Validator, validateTrigger } from 'aurelia-validation';
import {FormValidator} from '../classes/FormValidator';
//import {VolOpp} from '../classes/VolOpp';
@inject(App, ValidationControllerFactory, Validator)
export class Charity {
  controller = null;
  validator = null;
  constructor(app, controllerFactory, validator){
    this.app = app;
    this.charities = [];
    this.validator2 = new FormValidator(validator, (results) => this.updateCanSubmit2(results));
    this.controller2 = controllerFactory.createForCurrentScope(this.validator2);
    this.controller2.validateTrigger = validateTrigger.changeOrBlur;
    this.canSubmit2 = false;
    this.validType2 = false;
    this.charityTypeValid = false;
  }

  async activate(){
    this.update = false;
    this.types = ['Christian', 'Environmental', 'Hunger', 'Animal Rights', 'Homeless', 'Veterans', 'Elderly'];
    this.types.sort();
    this.types.push('other');
    this.uid = this.app.auth.getTokenPayload().sub;
    this.user = await this.app.appState.getUser(this.uid);
    this.app.dashboardTitle = this.user.userType;
    this.app.role = this.user.userType;
    const res = await this.app.httpClient.fetch('/charity/' + this.uid);
    this.charities = await res.json();
    if (this.charities.length !== 0){
      this.app.buildPTag(this.charities, 'charityTypes', 'charityTypeOther', 'charityTypesHtml');
      this.buildManagers();
      this.checkEvents();
    }
  }

  async checkEvents(){
    for (let i = 0; i < this.charities.length; i++){
      let foundEvents = [];
      this.charities[i].hasEvents = false;
      let res = await this.app.httpClient.fetch('/volopp/' + this.charities[i]._id);
      foundEvents = await res.json();
      if (foundEvents.length > 0){
        this.charities[i].hasEvents = true;
      }
    }
  }

  createNewCharity(){
    console.log('createNewCharity function populates a blank charity object and then runs the showUpdateCharity function');
    let charity = {
      'charityName': '',
      'charityStreet': '',
      'charityCity': '',
      'charityState': '',
      'charityZipCode': '',
      'charityTypes': [],
      'charityManagers': [],
      'charityMngIds': [],
      'charityTypeOther': '',
      'charityTypesHtml': ''
    };
    this.update = false;
    let charitiesTable = document.getElementById('charTable');
    if (charitiesTable !== null){
      charitiesTable.style.display = 'block';
    }
    this.updateScheduledEvent = false;
    let createNewButton = document.getElementById('createNewCharityButton');
    if (createNewButton !== null){
      createNewButton.style.display = 'none';
    }
    this.showUpdateCharity(charity);
  }

  updateCharityFunction(charity){
    this.update = true;
    this.canSubmit2 = true;
    this.validType2 = true;
    this.showUpdateCharity(charity);
  }

  showUpdateCharity(charity){
    // let updateDiv = document.getElementById('updateCharitySection');
    // updateDiv.style.display = 'block';
    // let scheduleDiv = document.getElementById('scheduleCharitySection');
    // if (scheduleDiv !== null){
    //   scheduleDiv.style.display = 'none';
    // }
    this.charityName = charity.charityName;
    this.updateCharity = charity;
    this.updateCharity.charityEmail = '';
    if (this.updateCharity.charityTypes.includes('other')){
      this.typeOther = true;
    } else {
      this.typeOther = false;
      this.updateCharity.charitytypeOther = '';
    }
    this.setupValidation2();
    if (this.update === true){
      document.getElementById('updateCharitySection').scrollIntoView();
    } else {
      document.getElementById('charityDash').scrollIntoView();
    }
  }

  openCheckboxAndValidate(e) {
    let open = this.app.showCheckboxes(e);
    if (open === false) {
      this.validate2();
    }
  }

  updateTypePicked(){
    this.validType2 = false;
    let nub = document.getElementsByClassName('updateButton')[0];
    nub.style.display = 'none';
    for (let i = 0; i < this.types.length; i++) {
      if (this.updateCharity.charityTypes.indexOf(this.types[i]) > -1){
        this.validType2 = true;
        if (this.canSubmit2 && nub){
          nub.style.display = 'block';
        }
      }
    }
    this.validate2();
    //console.log('the charity types picked are: ' + this.updateCharity.charityTypes);
    if (this.updateCharity.charityTypes.includes('other')){
      this.typeOther = true;
    } else {
      this.typeOther = false;
      this.updateCharity.charityTypeOther = '';
    }
  }

  setupValidation2() {
    ValidationRules
    .ensure('charityTypes').required().minLength(1).withMessage('charity type is required')
    .ensure('charityPhoneNumber').matches(/\b[2-9]\d{9}\b/).withMessage('10 digits only')
    .ensure('charityName').required().maxLength(40).withMessage('Charity name please')
    .ensure('charityEmail').email()
    .ensure('charityZipCode').required().matches(/\b\d{5}\b/).withMessage('5-digit zipcode')
    .ensure('charityCity').required().matches(/[^0-9]+/).maxLength(30).withMessage('City name please')
    .ensure('charityStreet').required().maxLength(40).withMessage('Charity street address please')
    .ensure('charityState').required().withMessage('Charity state please')
    .on(this.updateCharity);
  }

  validate2() {
    if (this.updateCharity.charityTypes.join(',') === '' && !this.charityTypeValid) {
      this.controller2.errors.push({ id: '_charityType', message: 'Charity Type is required', valid: false, __observer__: {} });
      this.charityTypeValid = true;
    } else if (this.updateCharity.charityTypes.join(',') !== '') {
      this.controller2.errors = [...this.controller2.errors.filter( (x) => x.id !== '_charityType')];
      this.charityTypeValid = false;
    }
  }

  updateCanSubmit2(validationResults) {
    let valid = true;
    console.log('Running updateCanSubmit2');
    let nub = document.getElementsByClassName('updateButton')[0];
    if (nub) {
      for (let result of validationResults) {
        if (result.valid === false){
          nub.style.display = 'none';
          valid = false;
          break;
        }
      }
      this.canSubmit2 = valid;
      if (this.canSubmit2 && this.validType2){
        nub.style.display = 'block';
      }
      return this.canSubmit2;
    }
  }

  createCharity(){
    this.updateCharity.charityManagers[0] = this.user.name;
    this.updateCharity.charityMngIds[0] = this.user._id;
    console.log('this is the update charity email: ' + this.updateCharity.charityEmail);
    if (this.updateCharity.charityEmail !== '' && this.updateCharity.charityEmail !== null){
      this.findUserByEmail('post');
    } else {
      this.postCharity();
    }
  }

  postCharity(){
    this.app.httpClient.fetch('/charity/create', {
      method: 'post',
      body: json(this.updateCharity)
    })
    .then((data) => {
      console.log(data);
      document.getElementById('charityDash').scrollIntoView();
      this.activate();
      this.createNewCharity();
    });
  }

  buildManagers(){
    for (let l = 0; l < this.charities.length; l++){
      let manHtml = '';
      for (let i = 0; i < this.charities[l].charityManagers.length; i++) {
        if (this.charities[l].charityManagers[i] !== ''){
          manHtml = manHtml + '
' + this.charities[l].charityManagers[i] + '
';
        }
      }
      if (manHtml === ''){
        manHtml = '
not specified
';
      }
      this.charities[l].charityManagersHtml = manHtml;
    }
  }

  async deleteCharity(charityId){
    await fetch;
    this.app.httpClient.fetch('/charity/' + charityId, {
      method: 'delete'
    })
    .then((data) => {
      console.log('your charity has been deleted');
      this.activate();
      this.createNewCharity();
    });
  }

  updateCharityFunct(){
    console.log('this is the update charity email: ' + this.updateCharity.charityEmail);
    if (this.updateCharity.charityEmail !== '' && this.updateCharity.charityEmail !== null){
      this.findUserByEmail('put');
    } else {
      this.putCharity();
    }
  }

  removeManager(charity){
    this.updateCharity = charity;
    const index = this.updateCharity.charityMngIds.indexOf(this.uid);
    if (index > -1){
      this.updateCharity.charityMngIds.splice(index, 1);
    }
    const index2 = this.updateCharity.charityManagers.indexOf(this.user.name);
    if (index > -1){
      this.updateCharity.charityManagers.splice(index2, 1);
    }
    this.putCharity();
  }

  afterUpdate(){
    this.updateCharity = {};
    document.getElementById('charityDash').scrollIntoView();
    this.activate();
    this.createNewCharity();
  }

  async putCharity(){
    await this.app.updateById('/charity/', this.updateCharity._id, this.updateCharity, null);
    this.afterUpdate();
    //console.log('this is the update charity');
    //console.log(this.updateCharity);
    //await fetch;
    // this.app.httpClient.fetch('/charity/' + this.updateCharity._id, {
    //   method: 'put',
    //   body: json(this.updateCharity)
    // })
    // .then((response) => response.json())
    // .then((data) => {
      // let updateDiv = document.getElementById('updateCharitySection');
      // if (updateDiv !== null){
      //   updateDiv.style.display = 'none';
      // }
    //});
  }

  async findUserByEmail(thenDo){
    await fetch;
    this.app.httpClient.fetch('/user/', {
      method: 'post',
      body: json({email: this.updateCharity.charityEmail})
    })
    .then((response) => response.json())
    .then((data) => {
      if (data.length !== 0){
        //console.log('the additional manager is: ' + JSON.stringify(data));
        const tempManager = data;
        console.log('this is the additional manager: ');
        console.log(tempManager[0].name);
        console.log(tempManager[0]._id);
        //only do this if the array does not already contain the user id, else alert that the user is already a manager of this charity
        for (let l = 0; l < this.updateCharity.charityMngIds.length; l++){
          console.log('checking for already a manager');
          /* istanbul ignore else */
          if (this.updateCharity.charityMngIds.indexOf(tempManager[0]._id) > -1){
            return alert('this user is already a manager of this charity');
          }
        }
        this.updateCharity.charityMngIds.push(tempManager[0]._id);
        this.updateCharity.charityManagers.push(tempManager[0].name);
        if (thenDo === 'put'){
          this.putCharity();
        } else {
          this.postCharity();
        }
      } else {
        alert('There is no OHAF user with that email');
      }
    });
  }

  // removeHyphen(){
  //   console.log('running remove hyphen');
  //   let charityPhone = document.getElementById('charity-phone').value;
  //   console.log(charityPhone);
  //   if (charityPhone.indexOf('-') !== -1){
  //     charityPhone.replace('-', '');
  //   }
  // }

  attached(){
    this.createNewCharity();
  }
}
<|endoftext|>


<commit_before>/*
 Licensed to the StackStorm, Inc ('StackStorm') under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You 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.
*/

/*jshint quotmark:false*/
/*global describe, it*/
"use strict";

var chai = require('chai'),
  expect = chai.expect,
  env = process.env,
  formatData = require('../lib/format_data.js'),
  DummyRobot = require('./dummy-robot.js');

env.ST2_MAX_MESSAGE_LENGTH = 500;

describe('SlackFormatter', function() {
  var adapterName = 'slack';

  it('should create a snippet for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should truncate text more than a certain length', function() {
    var org_max_length = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 10;
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('abcd efgh ijklm', null);
    env.ST2_MAX_MESSAGE_LENGTH = org_max_length;

    expect(o).to.be.an('string');
    expect(o).to.equal('abcd efgh ijklm');

  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should echo back recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local \u201cuname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });

  it('should normalize command with special double quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u201cuname -a" \u201dlocalhost, 127.0.0.1"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote "uname -a" "localhost, 127.0.0.1"');
  });

  it('should normalize command with special single quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u2018uname -a\' \u2019localhost, 127.0.0.1\'');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote \'uname -a\' \'localhost, 127.0.0.1\'');
  });
});

describe('MattermostFormatter', function() {
  var adapterName = 'mattermost';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command with special double quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u201cuname -a" \u201dlocalhost, 127.0.0.1"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote "uname -a" "localhost, 127.0.0.1"');
  });

  it('should normalize command with special single quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u2018uname -a\' \u2019localhost, 127.0.0.1\'');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote \'uname -a\' \'localhost, 127.0.0.1\'');
  });
});

describe('HipChatFormatter', function() {
  var adapterName = 'hipchat';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('/code DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    env.HUBOT_HIPCHAT_JID = '234x_y234@conf.hipchat.com';
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('234x_Estee@conf.hipchat.com');
  });

  it('should correctly format recepient with conf.btf.hipchat.com', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    env.HUBOT_HIPCHAT_JID = '234x_y234@conf.hipchat.com';
    env.HUBOT_HIPCHAT_XMPP_DOMAIN = "btf.hipchat.com";
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('234x_Estee@conf.btf.hipchat.com');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });
});

describe('RocketChatFormatter', function() {
  var adapterName = 'rocketchat';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });
});

describe('SparkFormatter', function() {
  var adapterName = 'spark';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA');
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('');
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should truncate text more than a certain length', function() {
    var old_ST2_MAX_MESSAGE_LENGTH = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 4;
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('asdfqwerty');
    expect(o).to.be.an('string');
    expect(o).to.equal('asdf...');
    env.ST2_MAX_MESSAGE_LENGTH = old_ST2_MAX_MESSAGE_LENGTH;
  });

  it('should not truncate text more than a certain length', function() {
    var old_ST2_MAX_MESSAGE_LENGTH = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 0;
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('asdfqwerty');
    expect(o).to.be.an('string');
    expect(o).to.equal('asdfqwerty');
    env.ST2_MAX_MESSAGE_LENGTH = old_ST2_MAX_MESSAGE_LENGTH;
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });
});

describe('DefaultFormatter', function() {
  var adapterName = 'unknown';
  var robot = new DummyRobot('dummy', null, false);

  it('should create a snippet for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should truncate text more than a certain length', function() {
    var org_max_length = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 10;
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('abcd efgh ijklm', null);
    env.ST2_MAX_MESSAGE_LENGTH = org_max_length;

    expect(o).to.be.an('string');
    expect(o).to.equal('abcd efgh ...');
  });

  it('should truncate text more than a certain length', function() {
    var org_max_length = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 0;
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('abcd efgh ijklm', null);
    env.ST2_MAX_MESSAGE_LENGTH = org_max_length;

    expect(o).to.be.an('string');
    expect(o).to.equal('abcd efgh ijklm');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should echo back recepient', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });
});
<commit_msg>Add tests for adapter normalizeAddressee<commit_after>/*
 Licensed to the StackStorm, Inc ('StackStorm') under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You 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.
*/

/*jshint quotmark:false*/
/*global describe, it*/
"use strict";

var chai = require('chai'),
  expect = chai.expect,
  env = process.env,
  formatData = require('../lib/format_data.js'),
  DummyRobot = require('./dummy-robot.js');

env.ST2_MAX_MESSAGE_LENGTH = 500;

describe('SlackFormatter', function() {
  var adapterName = 'slack';

  it('should create a snippet for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should truncate text more than a certain length', function() {
    var org_max_length = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 10;
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('abcd efgh ijklm', null);
    env.ST2_MAX_MESSAGE_LENGTH = org_max_length;

    expect(o).to.be.an('string');
    expect(o).to.equal('abcd efgh ijklm');

  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should echo back recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local \u201cuname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });

  it('should normalize command with special double quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u201cuname -a" \u201dlocalhost, 127.0.0.1"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote "uname -a" "localhost, 127.0.0.1"');
  });

  it('should normalize command with special single quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u2018uname -a\' \u2019localhost, 127.0.0.1\'');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote \'uname -a\' \'localhost, 127.0.0.1\'');
  });

  it('should normalize the addressee', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var msg = {
      message: {
        room: "SlackRoomName",
        user: {
          name: "SlackUserName"
        }
      }
    };
    var o = formatter.normalizeAddressee(msg);
    expect(o.name).to.be.an('string');
    expect(o.name).to.equal('SlackUserName');
    expect(o.room).to.be.an('string');
    expect(o.room).to.equal('SlackRoomName');
  });
});

describe('MattermostFormatter', function() {
  var adapterName = 'mattermost';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command with special double quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u201cuname -a" \u201dlocalhost, 127.0.0.1"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote "uname -a" "localhost, 127.0.0.1"');
  });

  it('should normalize command with special single quotes', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run remote \u2018uname -a\' \u2019localhost, 127.0.0.1\'');
    expect(o).to.be.an('string');
    expect(o).to.equal('run remote \'uname -a\' \'localhost, 127.0.0.1\'');
  });

  it('should normalize the addressee', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var msg = {
      message: {
        room: "MattermostRoomName",
        user: {
          name: "MattermostUserName"
        }
      }
    };
    var o = formatter.normalizeAddressee(msg);
    expect(o.name).to.be.an('string');
    expect(o.name).to.equal('MattermostUserName');
    expect(o.room).to.be.an('string');
    expect(o.room).to.equal('MattermostRoomName');
  });
});

describe('HipChatFormatter', function() {
  var adapterName = 'hipchat';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('/code DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    env.HUBOT_HIPCHAT_JID = '234x_y234@conf.hipchat.com';
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('234x_Estee@conf.hipchat.com');
  });

  it('should correctly format recepient with conf.btf.hipchat.com', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    env.HUBOT_HIPCHAT_JID = '234x_y234@conf.hipchat.com';
    env.HUBOT_HIPCHAT_XMPP_DOMAIN = "btf.hipchat.com";
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('234x_Estee@conf.btf.hipchat.com');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });

  it('should normalize the addressee', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    // HipChat packages the room and user name differently
    var msg = {
      message: {
        user: {
          jid: "HipChatRoomName",
          mention_name: "HipChatUserName"
        }
      }
    };
    var o = formatter.normalizeAddressee(msg);
    expect(o.name).to.be.an('string');
    expect(o.name).to.equal('HipChatUserName');
    expect(o.room).to.be.an('string');
    expect(o.room).to.equal('HipChatRoomName');
  });
});

describe('RocketChatFormatter', function() {
  var adapterName = 'rocketchat';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });

  it('should normalize the addressee', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var msg = {
      message: {
        room: "RocketChatRoomName",
        user: {
          name: "RocketChatUserName"
        }
      }
    };
    var o = formatter.normalizeAddressee(msg);
    expect(o.name).to.be.an('string');
    expect(o.name).to.equal('RocketChatUserName');
    expect(o.room).to.be.an('string');
    expect(o.room).to.equal('RocketChatRoomName');
  });
});

describe('SparkFormatter', function() {
  var adapterName = 'spark';

  it('should echo back for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('DATA');
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('');
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should truncate text more than a certain length', function() {
    var old_ST2_MAX_MESSAGE_LENGTH = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 4;
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('asdfqwerty');
    expect(o).to.be.an('string');
    expect(o).to.equal('asdf...');
    env.ST2_MAX_MESSAGE_LENGTH = old_ST2_MAX_MESSAGE_LENGTH;
  });

  it('should not truncate text more than a certain length', function() {
    var old_ST2_MAX_MESSAGE_LENGTH = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 0;
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatData('asdfqwerty');
    expect(o).to.be.an('string');
    expect(o).to.equal('asdfqwerty');
    env.ST2_MAX_MESSAGE_LENGTH = old_ST2_MAX_MESSAGE_LENGTH;
  });

  it('should correctly format recepient', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });

  it('should normalize the addressee', function() {
    var formatter = formatData.getFormatter(adapterName, null);
    var msg = {
      message: {
        user: {
          room: "SparkRoomName",
          name: "SparkUserName"
        }
      }
    };
    var o = formatter.normalizeAddressee(msg);
    expect(o.name).to.be.an('string');
    expect(o.name).to.equal('SparkUserName');
    expect(o.room).to.be.an('string');
    expect(o.room).to.equal('SparkRoomName');
  });
});

describe('DefaultFormatter', function() {
  var adapterName = 'unknown';
  var robot = new DummyRobot('dummy', null, false);

  it('should create a snippet for non-empty', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('DATA', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('DATA');
  });

  it('should truncate text more than a certain length', function() {
    var org_max_length = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 10;
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('abcd efgh ijklm', null);
    env.ST2_MAX_MESSAGE_LENGTH = org_max_length;

    expect(o).to.be.an('string');
    expect(o).to.equal('abcd efgh ...');
  });

  it('should truncate text more than a certain length', function() {
    var org_max_length = env.ST2_MAX_MESSAGE_LENGTH;
    env.ST2_MAX_MESSAGE_LENGTH = 0;
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('abcd efgh ijklm', null);
    env.ST2_MAX_MESSAGE_LENGTH = org_max_length;

    expect(o).to.be.an('string');
    expect(o).to.equal('abcd efgh ijklm');
  });

  it('should be an empty string for empty', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatData('', null);
    expect(o).to.be.an('string');
    expect(o).to.equal('');
  });

  it('should echo back recepient', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.formatRecepient('Estee');
    expect(o).to.be.an('string');
    expect(o).to.equal('Estee');
  });

  it('should normalize command', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var o = formatter.normalizeCommand('run local "uname -a"');
    expect(o).to.be.an('string');
    expect(o).to.equal('run local "uname -a"');
  });

  it('should normalize the addressee', function() {
    var formatter = formatData.getFormatter(adapterName, robot);
    var msg = {
      message: {
        room: "DefaultRoomName",
        user: {
          name: "DefaultUserName"
        }
      }
    };
    var o = formatter.normalizeAddressee(msg);
    expect(o.name).to.be.an('string');
    expect(o.name).to.equal('DefaultUserName');
    expect(o.room).to.be.an('string');
    expect(o.room).to.equal('DefaultRoomName');
  });
});
<|endoftext|>


<commit_before><commit_msg>Restore show call<commit_after><|endoftext|>


<commit_before><commit_msg>UK -> GB<commit_after><|endoftext|>


<commit_before><commit_msg>Issue #694. Get type instead of type name in generate-legacy-dbjs-mock.js.<commit_after><|endoftext|>


<commit_before><commit_msg>coverPhoto property is now populated when querying by slug<commit_after><|endoftext|>


<commit_before>import Statement from "./statement"
import Expression from "./expression"
import {Context, ContextTypes, Doc, ParserStateOption} from "./node"
import * as PHPType from "../php-type"
export default class Foreach extends Statement {
    /** @type {Expression} */
    get source() {
        return this.cacheNode("source")
    }
    /** @type {?Expression} */
    get key() {
        return this.cacheNode("key")
    }
    /** @type {Expression} */
    get value() {
        return this.cacheNode("value")
    }
    /** @type {Statement} */
    get body() {
        return this.cacheNode("body")
    }
    /** @type {boolean} */
    get shortForm() {
        return this.node.shortForm
    }
    /**
     * Checks that syntax seems ok
     * @param {Context} context
     * @param {Set<ParserStateOption.Base>} [parser_state]
     * @param {?Doc} [doc]
     * @returns {?ContextTypes} The set of types applicable to this value
     */
    check(context, parser_state = new Set(), doc = null) {
        super.check(context, parser_state, doc)
        this.source.check(context, new Set(), null)
        let assign_context = context.childContext(true)
        assign_context.assigningType = PHPType.Core.types.mixed
        if(this.key) {
            this.key.check(assign_context, new Set(), null)
        }
        this.value.check(assign_context, new Set(), null)
        this.body.check(context, new Set(), null)
        return ContextTypes.empty
    }
}
<commit_msg>Recognise keys as strings<commit_after>import Statement from "./statement"
import Expression from "./expression"
import {Context, ContextTypes, Doc, ParserStateOption} from "./node"
import * as PHPType from "../php-type"
export default class Foreach extends Statement {
    /** @type {Expression} */
    get source() {
        return this.cacheNode("source")
    }
    /** @type {?Expression} */
    get key() {
        return this.cacheNode("key")
    }
    /** @type {Expression} */
    get value() {
        return this.cacheNode("value")
    }
    /** @type {Statement} */
    get body() {
        return this.cacheNode("body")
    }
    /** @type {boolean} */
    get shortForm() {
        return this.node.shortForm
    }
    /**
     * Checks that syntax seems ok
     * @param {Context} context
     * @param {Set<ParserStateOption.Base>} [parser_state]
     * @param {?Doc} [doc]
     * @returns {?ContextTypes} The set of types applicable to this value
     */
    check(context, parser_state = new Set(), doc = null) {
        super.check(context, parser_state, doc)
        this.source.check(context, new Set(), null)
        let assign_context = context.childContext(true)
        if(this.key) {
            assign_context.assigningType = PHPType.Core.types.string
            this.key.check(assign_context, new Set(), null)
        }
        assign_context.assigningType = PHPType.Core.types.mixed
        this.value.check(assign_context, new Set(), null)
        this.body.check(context, new Set(), null)
        return ContextTypes.empty
    }
}
<|endoftext|>


<commit_before>const Piece = require('./interfaces/Piece');
const { mergeDefault } = require('../util/util');
const constants = require('../util/constants');
const ParsedUsage = require('../usage/ParsedUsage');

/**
 * Base class for all Klasa Commands. See {@tutorial CreatingCommands} for more information how to use this class
 * to build custom commands.
 * @tutorial CreatingCommands
 * @implements {Piece}
 */
class Command {

	/**
	 * @typedef {Object} CommandOptions
	 * @memberof Command
	 * @property {string} [name=theFileName] The name of the command
	 * @property {boolean} [enabled=true] Whether the command is enabled or not
	 * @property {string[]} [runIn=['text','dm','group']] What channel types the command should run in
	 * @property {number} [cooldown=0] The amount of time before the user can run the command again in seconds
	 * @property {boolean} [nsfw=false] If the command should only run in nsfw channels
	 * @property {boolean} [deletable=false] If the responses should be deleted if the triggering message is deleted
	 * @property {boolean} [guarded=false] If the command can be disabled on a guild level (does not effect global disable)
	 * @property {string[]} [aliases=[]] Any comand aliases
	 * @property {boolean} [autoAliases=true] If automatic aliases should be added (adds aliases of name and aliases without dashes)
	 * @property {number} [permLevel=0] The required permission level to use the command
	 * @property {string[]} [botPerms=[]] The required Discord permissions for the bot to use this command
	 * @property {string[]} [requiredConfigs=[]] The required guild configs to use this command
	 * @property {(string|Function)} [description=''] The help description for the command
	 * @property {string} [usage=''] The usage string for the command
	 * @property {?string} [usageDelim=undefined] The string to deliminate the command input for usage
	 * @property {boolean} [quotedStringSupport=this.client.options.quotedStringSupport] Wheter args for this command should not deliminated inside quotes
	 * @property {(string|Function)} [extendedHelp=msg.language.get('COMMAND_HELP_NO_EXTENDED')] Extended help strings
	 */

	/**
	 * @since 0.0.1
	 * @param {KlasaClient} client The Klasa Client
	 * @param {string} dir The path to the core or user command pieces folder
	 * @param {Array} file The path from the pieces folder to the command file
	 * @param {CommandOptions} [options = {}] Optional Command settings
	 */
	constructor(client, dir, file, options = {}) {
		options = mergeDefault(constants.DEFAULTS.COMMAND, options);

		/**
		 * @since 0.0.1
		 * @type {KlasaClient}
		 */
		this.client = client;

		/**
		 * The type of Klasa piece this is
		 * @since 0.0.1
		 * @type {string}
		 */
		this.type = 'command';

		/**
		 * If the command is enabled or not
		 * @since 0.0.1
		 * @type {boolean}
		 */
		this.enabled = options.enabled;

		/**
		 * What channels the command should run in
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.runIn = options.runIn;

		/**
		 * The cooldown in seconds this command has
		 * @since 0.0.1
		 * @type {number}
		 */
		this.cooldown = options.cooldown;

		/**
		 * Whether this command should only run in NSFW channels or not
		 * @since 0.5.0
		 * @type {boolean}
		 */
		this.nsfw = options.nsfw;

		/**
		 * Whether this command shound not be able to be disabled in a guild or not
		 * @since 0.5.0
		 * @type {boolean}
		 */
		this.guarded = options.guarded;

		/**
		 * Whether this command should have it's responses deleted if the triggering message is deleted
		 * @since 0.5.0
		 * @type {boolean}
		 */
		this.deletable = options.deletable;

		/**
		 * The name of the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.name = options.name || file[file.length - 1].slice(0, -3).toLowerCase();

		/**
		 * The aliases for this command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.aliases = options.aliases;
		if (options.autoAliases) {
			if (this.name.includes('-')) this.aliases.push(this.name.replace(/-/g, ''));
			for (const alias of this.aliases) if (alias.includes('-')) this.aliases.push(alias.replace(/-/g, ''));
		}

		/**
		 * The required permLevel to run this command
		 * @since 0.0.1
		 * @type {number}
		 */
		this.permLevel = options.permLevel;

		/**
		 * The required bot permissions to run this command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.botPerms = options.botPerms;

		/**
		 * The required per guild configs to run this command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.requiredConfigs = options.requiredConfigs;

		/**
		 * The description of the command
		 * @since 0.0.1
		 * @type {(string|Function)}
		 * @param {KlasaMessage} msg The message used to trigger this command
		 * @returns {string}
		 */
		this.description = options.description;

		/**
		 * The extended help for the command
		 * @since 0.0.1
		 * @type {(string|Function)}
		 * @param {KlasaMessage} msg The message used to trigger this command
		 * @returns {string}
		 */
		this.extendedHelp = options.extendedHelp || (msg => msg.language.get('COMMAND_HELP_NO_EXTENDED'));

		/**
		 * The usage string for the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.usageString = options.usage;

		/**
		 * The usage deliminator for the command input
		 * @since 0.0.1
		 * @type {?string}
		 */
		this.usageDelim = options.usageDelim;

		/**
		 * Whether to use quoted string support for this command or not
		 * @since 0.2.1
		 * @type {boolean}
		 */
		this.quotedStringSupport = options.quotedStringSupport;

		/**
		 * The full category for the command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.fullCategory = file.slice(0, -1);

		/**
		 * The main category for the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.category = this.fullCategory[0] || 'General';

		/**
		 * The sub category for the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.subCategory = this.fullCategory[1] || 'General';

		/**
		 * The parsed usage for the command
		 * @since 0.0.1
		 * @type {ParsedUsage}
		 */
		this.usage = new ParsedUsage(client, this);

		/**
		 * Any active cooldowns for the command
		 * @since 0.0.1
		 * @type {Map}
		 * @private
		 */
		this.cooldowns = new Map();

		/**
		 * The file location where this command is stored
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.file = file;

		/**
		 * The directory to where this command piece is stored
		 * @since 0.0.1
		 * @type {string}
		 */
		this.dir = dir;
	}

	/**
	 * The run method to be overwritten in actual commands
	 * @since 0.0.1
	 * @param {KlasaMessage} msg The command message mapped on top of the message used to trigger this command
	 * @param {any[]} params The fully resolved parameters based on your usage / usageDelim
	 * @abstract
	 * @returns {Promise<KlasaMessage|KlasaMessage[]>} You should return the response message whenever possible
	 */
	async run() {
		// Defined in extension Classes
	}

	/**
	 * The init method to be optionaly overwritten in actual commands
	 * @since 0.0.1
	 * @abstract
	 * @returns {Promise<*>}
	 */
	async init() {
		// Optionally defined in extension Classes
	}

	// left for documentation
	/* eslint-disable no-empty-function */
	async reload() {}
	unload() {}
	disable() {}
	enable() {}
	/* eslint-enable no-empty-function */

}

Piece.applyToClass(Command);

module.exports = Command;
<commit_msg>fix the quotedStringSupport client option<commit_after>const Piece = require('./interfaces/Piece');
const { mergeDefault } = require('../util/util');
const constants = require('../util/constants');
const ParsedUsage = require('../usage/ParsedUsage');

/**
 * Base class for all Klasa Commands. See {@tutorial CreatingCommands} for more information how to use this class
 * to build custom commands.
 * @tutorial CreatingCommands
 * @implements {Piece}
 */
class Command {

	/**
	 * @typedef {Object} CommandOptions
	 * @memberof Command
	 * @property {string} [name=theFileName] The name of the command
	 * @property {boolean} [enabled=true] Whether the command is enabled or not
	 * @property {string[]} [runIn=['text','dm','group']] What channel types the command should run in
	 * @property {number} [cooldown=0] The amount of time before the user can run the command again in seconds
	 * @property {boolean} [nsfw=false] If the command should only run in nsfw channels
	 * @property {boolean} [deletable=false] If the responses should be deleted if the triggering message is deleted
	 * @property {boolean} [guarded=false] If the command can be disabled on a guild level (does not effect global disable)
	 * @property {string[]} [aliases=[]] Any comand aliases
	 * @property {boolean} [autoAliases=true] If automatic aliases should be added (adds aliases of name and aliases without dashes)
	 * @property {number} [permLevel=0] The required permission level to use the command
	 * @property {string[]} [botPerms=[]] The required Discord permissions for the bot to use this command
	 * @property {string[]} [requiredConfigs=[]] The required guild configs to use this command
	 * @property {(string|Function)} [description=''] The help description for the command
	 * @property {string} [usage=''] The usage string for the command
	 * @property {?string} [usageDelim=undefined] The string to deliminate the command input for usage
	 * @property {boolean} [quotedStringSupport=this.client.options.quotedStringSupport] Wheter args for this command should not deliminated inside quotes
	 * @property {(string|Function)} [extendedHelp=msg.language.get('COMMAND_HELP_NO_EXTENDED')] Extended help strings
	 */

	/**
	 * @since 0.0.1
	 * @param {KlasaClient} client The Klasa Client
	 * @param {string} dir The path to the core or user command pieces folder
	 * @param {Array} file The path from the pieces folder to the command file
	 * @param {CommandOptions} [options = {}] Optional Command settings
	 */
	constructor(client, dir, file, options = {}) {
		options = mergeDefault(constants.DEFAULTS.COMMAND, options);

		/**
		 * @since 0.0.1
		 * @type {KlasaClient}
		 */
		this.client = client;

		/**
		 * The type of Klasa piece this is
		 * @since 0.0.1
		 * @type {string}
		 */
		this.type = 'command';

		/**
		 * If the command is enabled or not
		 * @since 0.0.1
		 * @type {boolean}
		 */
		this.enabled = options.enabled;

		/**
		 * What channels the command should run in
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.runIn = options.runIn;

		/**
		 * The cooldown in seconds this command has
		 * @since 0.0.1
		 * @type {number}
		 */
		this.cooldown = options.cooldown;

		/**
		 * Whether this command should only run in NSFW channels or not
		 * @since 0.5.0
		 * @type {boolean}
		 */
		this.nsfw = options.nsfw;

		/**
		 * Whether this command shound not be able to be disabled in a guild or not
		 * @since 0.5.0
		 * @type {boolean}
		 */
		this.guarded = options.guarded;

		/**
		 * Whether this command should have it's responses deleted if the triggering message is deleted
		 * @since 0.5.0
		 * @type {boolean}
		 */
		this.deletable = options.deletable;

		/**
		 * The name of the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.name = options.name || file[file.length - 1].slice(0, -3).toLowerCase();

		/**
		 * The aliases for this command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.aliases = options.aliases;
		if (options.autoAliases) {
			if (this.name.includes('-')) this.aliases.push(this.name.replace(/-/g, ''));
			for (const alias of this.aliases) if (alias.includes('-')) this.aliases.push(alias.replace(/-/g, ''));
		}

		/**
		 * The required permLevel to run this command
		 * @since 0.0.1
		 * @type {number}
		 */
		this.permLevel = options.permLevel;

		/**
		 * The required bot permissions to run this command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.botPerms = options.botPerms;

		/**
		 * The required per guild configs to run this command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.requiredConfigs = options.requiredConfigs;

		/**
		 * The description of the command
		 * @since 0.0.1
		 * @type {(string|Function)}
		 * @param {KlasaMessage} msg The message used to trigger this command
		 * @returns {string}
		 */
		this.description = options.description;

		/**
		 * The extended help for the command
		 * @since 0.0.1
		 * @type {(string|Function)}
		 * @param {KlasaMessage} msg The message used to trigger this command
		 * @returns {string}
		 */
		this.extendedHelp = options.extendedHelp || (msg => msg.language.get('COMMAND_HELP_NO_EXTENDED'));

		/**
		 * The usage string for the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.usageString = options.usage;

		/**
		 * The usage deliminator for the command input
		 * @since 0.0.1
		 * @type {?string}
		 */
		this.usageDelim = options.usageDelim;

		/**
		 * Whether to use quoted string support for this command or not
		 * @since 0.2.1
		 * @type {boolean}
		 */
		this.quotedStringSupport = options.quotedStringSupport || this.client.options.quotedStringSupport;

		/**
		 * The full category for the command
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.fullCategory = file.slice(0, -1);

		/**
		 * The main category for the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.category = this.fullCategory[0] || 'General';

		/**
		 * The sub category for the command
		 * @since 0.0.1
		 * @type {string}
		 */
		this.subCategory = this.fullCategory[1] || 'General';

		/**
		 * The parsed usage for the command
		 * @since 0.0.1
		 * @type {ParsedUsage}
		 */
		this.usage = new ParsedUsage(client, this);

		/**
		 * Any active cooldowns for the command
		 * @since 0.0.1
		 * @type {Map}
		 * @private
		 */
		this.cooldowns = new Map();

		/**
		 * The file location where this command is stored
		 * @since 0.0.1
		 * @type {string[]}
		 */
		this.file = file;

		/**
		 * The directory to where this command piece is stored
		 * @since 0.0.1
		 * @type {string}
		 */
		this.dir = dir;
	}

	/**
	 * The run method to be overwritten in actual commands
	 * @since 0.0.1
	 * @param {KlasaMessage} msg The command message mapped on top of the message used to trigger this command
	 * @param {any[]} params The fully resolved parameters based on your usage / usageDelim
	 * @abstract
	 * @returns {Promise<KlasaMessage|KlasaMessage[]>} You should return the response message whenever possible
	 */
	async run() {
		// Defined in extension Classes
	}

	/**
	 * The init method to be optionaly overwritten in actual commands
	 * @since 0.0.1
	 * @abstract
	 * @returns {Promise<*>}
	 */
	async init() {
		// Optionally defined in extension Classes
	}

	// left for documentation
	/* eslint-disable no-empty-function */
	async reload() {}
	unload() {}
	disable() {}
	enable() {}
	/* eslint-enable no-empty-function */

}

Piece.applyToClass(Command);

module.exports = Command;
<|endoftext|>


<commit_before>import { Vector2 } from '../math/Vector2';
import { FileLoader } from './FileLoader';
import { DefaultLoadingManager } from './LoadingManager';
import * as Materials from '../materials/Materials';

/**
 * @author mrdoob / http://mrdoob.com/
 */

function MaterialLoader( manager ) {

	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
	this.textures = {};

}

Object.assign( MaterialLoader.prototype, {

	load: function ( url, onLoad, onProgress, onError ) {

		var scope = this;

		var loader = new FileLoader( scope.manager );
		loader.load( url, function ( text ) {

			onLoad( scope.parse( JSON.parse( text ) ) );

		}, onProgress, onError );

	},

	setTextures: function ( value ) {

		this.textures = value;

	},

	parse: function ( json ) {

		var textures = this.textures;

		function getTexture( name ) {

			if ( textures[ name ] === undefined ) {

				console.warn( 'THREE.MaterialLoader: Undefined texture', name );

			}

			return textures[ name ];

		}

		var material = new Materials[ json.type ]();

		if ( json.uuid !== undefined ) material.uuid = json.uuid;
		if ( json.name !== undefined ) material.name = json.name;
		if ( json.color !== undefined ) material.color.setHex( json.color );
		if ( json.roughness !== undefined ) material.roughness = json.roughness;
		if ( json.metalness !== undefined ) material.metalness = json.metalness;
		if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );
		if ( json.specular !== undefined ) material.specular.setHex( json.specular );
		if ( json.shininess !== undefined ) material.shininess = json.shininess;
		if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;
		if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;
		if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
		if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
		if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
		if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;
		if ( json.fog !== undefined ) material.fog = json.fog;
		if ( json.shading !== undefined ) material.shading = json.shading;
		if ( json.blending !== undefined ) material.blending = json.blending;
		if ( json.side !== undefined ) material.side = json.side;
		if ( json.opacity !== undefined ) material.opacity = json.opacity;
		if ( json.transparent !== undefined ) material.transparent = json.transparent;
		if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
		if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
		if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
		if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
		if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
		if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
		if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
		if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
		if ( json.skinning !== undefined ) material.skinning = json.skinning;
		if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;

		// for PointsMaterial

		if ( json.size !== undefined ) material.size = json.size;
		if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;

		// maps

		if ( json.map !== undefined ) material.map = getTexture( json.map );

		if ( json.alphaMap !== undefined ) {

			material.alphaMap = getTexture( json.alphaMap );
			material.transparent = true;

		}

		if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );
		if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;

		if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );
		if ( json.normalScale !== undefined ) {

			var normalScale = json.normalScale;

			if ( Array.isArray( normalScale ) === false ) {

				// Blender exporter used to export a scalar. See #7459

				normalScale = [ normalScale, normalScale ];

			}

			material.normalScale = new Vector2().fromArray( normalScale );

		}

		if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );
		if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
		if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;

		if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );
		if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );

		if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );
		if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;

		if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );

		if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );

		if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;

		if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );
		if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;

		if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );
		if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;

		if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );

		return material;

	}

} );

export { MaterialLoader };
<commit_msg>MaterialLoader: Handle flatShading. See #11724<commit_after>import { Vector2 } from '../math/Vector2';
import { FileLoader } from './FileLoader';
import { DefaultLoadingManager } from './LoadingManager';
import * as Materials from '../materials/Materials';

/**
 * @author mrdoob / http://mrdoob.com/
 */

function MaterialLoader( manager ) {

	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
	this.textures = {};

}

Object.assign( MaterialLoader.prototype, {

	load: function ( url, onLoad, onProgress, onError ) {

		var scope = this;

		var loader = new FileLoader( scope.manager );
		loader.load( url, function ( text ) {

			onLoad( scope.parse( JSON.parse( text ) ) );

		}, onProgress, onError );

	},

	setTextures: function ( value ) {

		this.textures = value;

	},

	parse: function ( json ) {

		var textures = this.textures;

		function getTexture( name ) {

			if ( textures[ name ] === undefined ) {

				console.warn( 'THREE.MaterialLoader: Undefined texture', name );

			}

			return textures[ name ];

		}

		var material = new Materials[ json.type ]();

		if ( json.uuid !== undefined ) material.uuid = json.uuid;
		if ( json.name !== undefined ) material.name = json.name;
		if ( json.color !== undefined ) material.color.setHex( json.color );
		if ( json.roughness !== undefined ) material.roughness = json.roughness;
		if ( json.metalness !== undefined ) material.metalness = json.metalness;
		if ( json.emissive !== undefined ) material.emissive.setHex( json.emissive );
		if ( json.specular !== undefined ) material.specular.setHex( json.specular );
		if ( json.shininess !== undefined ) material.shininess = json.shininess;
		if ( json.clearCoat !== undefined ) material.clearCoat = json.clearCoat;
		if ( json.clearCoatRoughness !== undefined ) material.clearCoatRoughness = json.clearCoatRoughness;
		if ( json.uniforms !== undefined ) material.uniforms = json.uniforms;
		if ( json.vertexShader !== undefined ) material.vertexShader = json.vertexShader;
		if ( json.fragmentShader !== undefined ) material.fragmentShader = json.fragmentShader;
		if ( json.vertexColors !== undefined ) material.vertexColors = json.vertexColors;
		if ( json.fog !== undefined ) material.fog = json.fog;
		if ( json.flatShading !== undefined ) material.flatShading = json.flatShading;
		if ( json.blending !== undefined ) material.blending = json.blending;
		if ( json.side !== undefined ) material.side = json.side;
		if ( json.opacity !== undefined ) material.opacity = json.opacity;
		if ( json.transparent !== undefined ) material.transparent = json.transparent;
		if ( json.alphaTest !== undefined ) material.alphaTest = json.alphaTest;
		if ( json.depthTest !== undefined ) material.depthTest = json.depthTest;
		if ( json.depthWrite !== undefined ) material.depthWrite = json.depthWrite;
		if ( json.colorWrite !== undefined ) material.colorWrite = json.colorWrite;
		if ( json.wireframe !== undefined ) material.wireframe = json.wireframe;
		if ( json.wireframeLinewidth !== undefined ) material.wireframeLinewidth = json.wireframeLinewidth;
		if ( json.wireframeLinecap !== undefined ) material.wireframeLinecap = json.wireframeLinecap;
		if ( json.wireframeLinejoin !== undefined ) material.wireframeLinejoin = json.wireframeLinejoin;
		if ( json.skinning !== undefined ) material.skinning = json.skinning;
		if ( json.morphTargets !== undefined ) material.morphTargets = json.morphTargets;

		// Deprecated

		if ( json.shading !== undefined ) material.shading = json.shading;

		// for PointsMaterial

		if ( json.size !== undefined ) material.size = json.size;
		if ( json.sizeAttenuation !== undefined ) material.sizeAttenuation = json.sizeAttenuation;

		// maps

		if ( json.map !== undefined ) material.map = getTexture( json.map );

		if ( json.alphaMap !== undefined ) {

			material.alphaMap = getTexture( json.alphaMap );
			material.transparent = true;

		}

		if ( json.bumpMap !== undefined ) material.bumpMap = getTexture( json.bumpMap );
		if ( json.bumpScale !== undefined ) material.bumpScale = json.bumpScale;

		if ( json.normalMap !== undefined ) material.normalMap = getTexture( json.normalMap );
		if ( json.normalScale !== undefined ) {

			var normalScale = json.normalScale;

			if ( Array.isArray( normalScale ) === false ) {

				// Blender exporter used to export a scalar. See #7459

				normalScale = [ normalScale, normalScale ];

			}

			material.normalScale = new Vector2().fromArray( normalScale );

		}

		if ( json.displacementMap !== undefined ) material.displacementMap = getTexture( json.displacementMap );
		if ( json.displacementScale !== undefined ) material.displacementScale = json.displacementScale;
		if ( json.displacementBias !== undefined ) material.displacementBias = json.displacementBias;

		if ( json.roughnessMap !== undefined ) material.roughnessMap = getTexture( json.roughnessMap );
		if ( json.metalnessMap !== undefined ) material.metalnessMap = getTexture( json.metalnessMap );

		if ( json.emissiveMap !== undefined ) material.emissiveMap = getTexture( json.emissiveMap );
		if ( json.emissiveIntensity !== undefined ) material.emissiveIntensity = json.emissiveIntensity;

		if ( json.specularMap !== undefined ) material.specularMap = getTexture( json.specularMap );

		if ( json.envMap !== undefined ) material.envMap = getTexture( json.envMap );

		if ( json.reflectivity !== undefined ) material.reflectivity = json.reflectivity;

		if ( json.lightMap !== undefined ) material.lightMap = getTexture( json.lightMap );
		if ( json.lightMapIntensity !== undefined ) material.lightMapIntensity = json.lightMapIntensity;

		if ( json.aoMap !== undefined ) material.aoMap = getTexture( json.aoMap );
		if ( json.aoMapIntensity !== undefined ) material.aoMapIntensity = json.aoMapIntensity;

		if ( json.gradientMap !== undefined ) material.gradientMap = getTexture( json.gradientMap );

		return material;

	}

} );

export { MaterialLoader };
<|endoftext|>


<commit_before>/** * Imports ***/
let pako = require('pako');

import LoadersBase from './loaders.base';
import ModelsSeries from '../../src/models/models.series';
import ModelsStack from '../../src/models/models.stack';
import ModelsFrame from '../../src/models/models.frame';
import ParsersDicom from '../../src/parsers/parsers.dicom';
import ParsersNifti from '../../src/parsers/parsers.nifti';
import ParsersNrrd from '../../src/parsers/parsers.nrrd';

/**
 *
 * It is typically used to load a DICOM image. Use loading manager for
 * advanced usage, such as multiple files handling.
 *
 * Demo: {@link https://fnndsc.github.io/vjs#loader_dicom}
 *
 * @module loaders/volumes
 *
 * @example
 * var files = ['/data/dcm/fruit'];
 *
 * // Instantiate a dicom loader
 * var lDicomoader = new dicom();
 *
 * // load a resource
 * loader.load(
 *   // resource URL
 *   files[0],
 *   // Function when resource is loaded
 *   function(object) {
 *     //scene.add( object );
 *     window.console.log(object);
 *   }
 * );
 */
export default class LoadersVolumes extends LoadersBase {

  parse(response) {
    // give a chance to the UI to update because after the rendering will be blocked with intensive JS
    if(this._progressBar) {
      this._progressBar.update(0, 100, 'parse');
    }

    return new Promise(
        (resolve, reject) => {
            window.setTimeout(
              () => {
                resolve(new Promise((resolve, reject) => {
                  let data = response;
                  data.gzcompressed = false;
                  data.filename = '';
                  data.extension = '';

                  // uncompress?
                  data.filename = response.url.split('/').pop();
                  data.gzcompressed = false;

                  // find extension
                  let splittedName = data.filename.split('.');
                  if(splittedName.length <= 1) {
                    data.extension = '';
                  } else{
                    data.extension = data.filename.split('.').pop();
                  }

                  // unzip if extension is '.gz'
                  if (data.extension === 'gz') {
                    data.gzcompressed = true;
                    data.extension = data.filename.split('.gz').shift().split('.').pop();
                    let decompressedData = pako.inflate(data.buffer);
                    data.buffer = decompressedData.buffer;
                  }

                  let parser = this._parser(data.extension);
                  if (!parser) {
                    reject(data.filename + ' can not be parsed.');
                  }

                  // check extension
                  let volumeParser = null;
                  try {
                    volumeParser = new parser(data, 0);
                  } catch (e) {
                    window.console.log(e);
                    reject(e);
                  }

                  // create a series
                  let series = new ModelsSeries();
                  series.seriesInstanceUID = volumeParser.seriesInstanceUID();
                  series.numberOfFrames = volumeParser.numberOfFrames();
                  if (!series.numberOfFrames) {
                    series.numberOfFrames = 1;
                  }
                  series.numberOfChannels = volumeParser.numberOfChannels();
                  series.modality = volumeParser.modality();
                  // if it is a segmentation, attach extra information
                  if(series.modality === 'SEG') {
                    // colors
                    // labels
                    // etc.
                    series.segmentationType = volumeParser.segmentationType();
                    series.segmentationSegments = volumeParser.segmentationSegments();
                  }

                  // just create 1 dummy stack for now
                  let stack = new ModelsStack();
                  stack.numberOfChannels = volumeParser.numberOfChannels();
                  stack.pixelRepresentation = volumeParser.pixelRepresentation();
                  stack.pixelType = volumeParser.pixelType();
                  stack.invert = volumeParser.invert();
                  stack.spacingBetweenSlices = volumeParser.spacingBetweenSlices();
                  stack.modality = series.modality;
                  // if it is a segmentation, attach extra information
                  if(stack.modality === 'SEG') {
                    // colors
                    // labels
                    // etc.
                    stack.segmentationType = series.segmentationType;
                    stack.segmentationSegments = series.segmentationSegments;
                  }
                  series.stack.push(stack);
                  // recursive call for each frame
                  // better than for loop to be able to update dom with "progress" callback
                  setTimeout(this.parseFrame(series, stack, response.url, 0, volumeParser, resolve, reject), 0);
                }));
             }, 10);
           }
        );
  }

  parseFrame(series, stack, url, i, dataParser, resolve, reject) {
    let frame = new ModelsFrame();
    frame.sopInstanceUID = dataParser.sopInstanceUID(i);
    frame.url = url;
    frame.index = i;
    frame.rows = dataParser.rows(i);
    frame.columns = dataParser.columns(i);
    frame.numberOfChannels = stack.numberOfChannels;
    frame.pixelRepresentation = stack.pixelRepresentation;
    frame.pixelType = stack.pixelType;
    frame.pixelData = dataParser.extractPixelData(i);
    frame.pixelSpacing = dataParser.pixelSpacing(i);
    frame.spacingBetweenSlices = dataParser.spacingBetweenSlices(i);
    frame.sliceThickness = dataParser.sliceThickness(i);
    frame.imageOrientation = dataParser.imageOrientation(i);
    frame.rightHanded = dataParser.rightHanded();
    stack.rightHanded = frame.rightHanded;
    if (frame.imageOrientation === null) {
      frame.imageOrientation = [1, 0, 0, 0, 1, 0];
    }
    frame.imagePosition = dataParser.imagePosition(i);
    if (frame.imagePosition === null) {
      frame.imagePosition = [0, 0, i];
    }
    frame.dimensionIndexValues = dataParser.dimensionIndexValues(i);
    frame.bitsAllocated = dataParser.bitsAllocated(i);
    frame.instanceNumber = dataParser.instanceNumber(i);
    frame.windowCenter = dataParser.windowCenter(i);
    frame.windowWidth = dataParser.windowWidth(i);
    frame.rescaleSlope = dataParser.rescaleSlope(i);
    frame.rescaleIntercept = dataParser.rescaleIntercept(i);
    // should pass frame index for consistency...
    frame.minMax = dataParser.minMaxPixelData(frame.pixelData);

    // if series.mo
    if(series.modality === 'SEG') {
      frame.referencedSegmentNumber = dataParser.referencedSegmentNumber(i);
    }

    stack.frame.push(frame);

    // update status
    this._parsed = i + 1;
    this._totalParsed = series.numberOfFrames;
    if(this._progressBar) {
      this._progressBar.update(this._parsed, this._totalParsed, 'parse');
    }

    if (this._parsed === this._totalParsed) {
      resolve(series);
    } else {
      setTimeout(this.parseFrame(series, stack, url, this._parsed, dataParser, resolve, reject), 0);
    }
  }

  _parser(extension) {
    let parser = null;

    switch (extension.toUpperCase()) {
      case 'NII':
      case 'NII_':
        parser = ParsersNifti;
        break;
      case 'DCM':
      case 'DICOM':
      case 'IMA':
      case '':
        parser = ParsersDicom;
        break;
      case 'NRRD':
        parser = ParsersNrrd;
        break;
      default:
        window.console.log('unsupported extension: ' + extension);
        return false;
    }
    return parser;
  }
}
<commit_msg>improve URL parsing with Node URL<commit_after>/** * Imports ***/
const PAKO = require('pako');
const URL = require('url');

import LoadersBase from './loaders.base';
import ModelsSeries from '../../src/models/models.series';
import ModelsStack from '../../src/models/models.stack';
import ModelsFrame from '../../src/models/models.frame';
import ParsersDicom from '../../src/parsers/parsers.dicom';
import ParsersNifti from '../../src/parsers/parsers.nifti';
import ParsersNrrd from '../../src/parsers/parsers.nrrd';

/**
 *
 * It is typically used to load a DICOM image. Use loading manager for
 * advanced usage, such as multiple files handling.
 *
 * Demo: {@link https://fnndsc.github.io/vjs#loader_dicom}
 *
 * @module loaders/volumes
 *
 * @example
 * var files = ['/data/dcm/fruit'];
 *
 * // Instantiate a dicom loader
 * var lDicomoader = new dicom();
 *
 * // load a resource
 * loader.load(
 *   // resource URL
 *   files[0],
 *   // Function when resource is loaded
 *   function(object) {
 *     //scene.add( object );
 *     window.console.log(object);
 *   }
 * );
 */
export default class LoadersVolumes extends LoadersBase {

  /**
   * Parse response
   */
  parse(response) {
    // give a chance to the UI to update because
    // after the rendering will be blocked with intensive JS
    if(this._progressBar) {
      this._progressBar.update(0, 100, 'parse');
    }

    return new Promise(
        (resolve, reject) => {
            window.setTimeout(
              () => {
                resolve(new Promise((resolve, reject) => {
                  let data = response;
                  data.gzcompressed = false;
                  data.filename = '';
                  data.extension = '';
                  data.pathname = '';
                  data.query = '';

                  let parsedUrl = URL.parse(response.url);
                  data.pathname = parsedUrl.pathname;
                  data.query = parsedUrl.query;

                  // get file name
                  data.filename = data.pathname.split('/').pop();
                  data.gzcompressed = false;

                  // find extension
                  let splittedName = data.filename.split('.');
                  if(splittedName.length <= 1) {
                    data.extension = 'dicom';
                  } else{
                    data.extension = data.filename.split('.').pop();
                  }

                  if(!isNaN(data.extension)) {
                    data.extension = 'dicom';
                  }

                  if(data.query &&
                     data.query.includes('contentType=application%2Fdicom')) {
                    data.extension = 'dicom';
                  }

                  // unzip if extension is '.gz'
                  if (data.extension === 'gz') {
                    data.gzcompressed = true;
                    data.extension =
                      data.filename.split('.gz').shift().split('.').pop();
                    let decompressedData = PAKO.inflate(data.buffer);
                    data.buffer = decompressedData.buffer;
                  }

                  let Parser = this._parser(data.extension);
                  if (!Parser) {
                    reject(data.filename + ' can not be parsed.');
                  }

                  // check extension
                  let volumeParser = null;
                  try {
                    volumeParser = new Parser(data, 0);
                  } catch (e) {
                    window.console.log(e);
                    reject(e);
                  }

                  // create a series
                  let series = new ModelsSeries();
                  series.seriesInstanceUID = volumeParser.seriesInstanceUID();
                  series.numberOfFrames = volumeParser.numberOfFrames();
                  if (!series.numberOfFrames) {
                    series.numberOfFrames = 1;
                  }
                  series.numberOfChannels = volumeParser.numberOfChannels();
                  series.modality = volumeParser.modality();
                  // if it is a segmentation, attach extra information
                  if(series.modality === 'SEG') {
                    // colors
                    // labels
                    // etc.
                    series.segmentationType = volumeParser.segmentationType();
                    series.segmentationSegments =
                      volumeParser.segmentationSegments();
                  }

                  // just create 1 dummy stack for now
                  let stack = new ModelsStack();
                  stack.numberOfChannels = volumeParser.numberOfChannels();
                  stack.pixelRepresentation =
                    volumeParser.pixelRepresentation();
                  stack.pixelType = volumeParser.pixelType();
                  stack.invert = volumeParser.invert();
                  stack.spacingBetweenSlices =
                    volumeParser.spacingBetweenSlices();
                  stack.modality = series.modality;
                  // if it is a segmentation, attach extra information
                  if(stack.modality === 'SEG') {
                    // colors
                    // labels
                    // etc.
                    stack.segmentationType = series.segmentationType;
                    stack.segmentationSegments = series.segmentationSegments;
                  }
                  series.stack.push(stack);
                  // recursive call for each frame
                  // better than for loop to be able
                  // to update dom with "progress" callback
                  setTimeout(
                    this.parseFrame(
                      series, stack, response.url, 0,
                      volumeParser, resolve, reject), 0);
                }));
             }, 10);
           }
        );
  }

  /**
   * Parse frame
   */
  parseFrame(series, stack, url, i, dataParser, resolve, reject) {
    let frame = new ModelsFrame();
    frame.sopInstanceUID = dataParser.sopInstanceUID(i);
    frame.url = url;
    frame.index = i;
    frame.rows = dataParser.rows(i);
    frame.columns = dataParser.columns(i);
    frame.numberOfChannels = stack.numberOfChannels;
    frame.pixelRepresentation = stack.pixelRepresentation;
    frame.pixelType = stack.pixelType;
    frame.pixelData = dataParser.extractPixelData(i);
    frame.pixelSpacing = dataParser.pixelSpacing(i);
    frame.spacingBetweenSlices = dataParser.spacingBetweenSlices(i);
    frame.sliceThickness = dataParser.sliceThickness(i);
    frame.imageOrientation = dataParser.imageOrientation(i);
    frame.rightHanded = dataParser.rightHanded();
    stack.rightHanded = frame.rightHanded;
    if (frame.imageOrientation === null) {
      frame.imageOrientation = [1, 0, 0, 0, 1, 0];
    }
    frame.imagePosition = dataParser.imagePosition(i);
    if (frame.imagePosition === null) {
      frame.imagePosition = [0, 0, i];
    }
    frame.dimensionIndexValues = dataParser.dimensionIndexValues(i);
    frame.bitsAllocated = dataParser.bitsAllocated(i);
    frame.instanceNumber = dataParser.instanceNumber(i);
    frame.windowCenter = dataParser.windowCenter(i);
    frame.windowWidth = dataParser.windowWidth(i);
    frame.rescaleSlope = dataParser.rescaleSlope(i);
    frame.rescaleIntercept = dataParser.rescaleIntercept(i);
    // should pass frame index for consistency...
    frame.minMax = dataParser.minMaxPixelData(frame.pixelData);

    // if series.mo
    if(series.modality === 'SEG') {
      frame.referencedSegmentNumber = dataParser.referencedSegmentNumber(i);
    }

    stack.frame.push(frame);

    // update status
    this._parsed = i + 1;
    this._totalParsed = series.numberOfFrames;
    if(this._progressBar) {
      this._progressBar.update(this._parsed, this._totalParsed, 'parse');
    }

    if (this._parsed === this._totalParsed) {
      resolve(series);
    } else {
      setTimeout(
        this.parseFrame(
          series, stack, url, this._parsed, dataParser, resolve, reject), 0);
    }
  }

  /**
   * Return parser given an extension
   */
  _parser(extension) {
    let Parser = null;

    switch (extension.toUpperCase()) {
      case 'NII':
      case 'NII_':
        Parser = ParsersNifti;
        break;
      case 'DCM':
      case 'DICOM':
      case 'IMA':
      case '':
        Parser = ParsersDicom;
        break;
      case 'NRRD':
        Parser = ParsersNrrd;
        break;
      default:
        window.console.log('unsupported extension: ' + extension);
        return false;
    }
    return Parser;
  }
}
<|endoftext|>