<commit_before>// Load in dependencies
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var async = require('async');
var templater = require('spritesheet-templates');
var spritesmith = require('spritesmith');
var url = require('url2');

// Define class to contain different extension handlers
function ExtFormat() {
  this.formatObj = {};
}
ExtFormat.prototype = {
  add: function (name, val) {
    this.formatObj[name] = val;
  },
  get: function (filepath) {
    // Grab the extension from the filepath
    var ext = path.extname(filepath);
    var lowerExt = ext.toLowerCase();

    // Look up the file extenion from our format object
    var formatObj = this.formatObj;
    var format = formatObj[lowerExt];
    return format;
  }
};

// Create img and css formats
var imgFormats = new ExtFormat();
var cssFormats = new ExtFormat();

// Add our img formats
imgFormats.add('.png', 'png');
imgFormats.add('.jpg', 'jpeg');
imgFormats.add('.jpeg', 'jpeg');

// Add our css formats
cssFormats.add('.styl', 'stylus');
cssFormats.add('.stylus', 'stylus');
cssFormats.add('.sass', 'sass');
cssFormats.add('.scss', 'scss');
cssFormats.add('.less', 'less');
cssFormats.add('.json', 'json');
cssFormats.add('.css', 'css');

function getCoordinateName(filepath) {
  // Extract the image name (exlcuding extension)
  var fullname = path.basename(filepath);
  var nameParts = fullname.split('.');

  // If there is are more than 2 parts, pop the last one
  if (nameParts.length >= 2) {
    nameParts.pop();
  }

  // Return our modified filename
  return nameParts.join('.');
}

module.exports = function gruntSpritesmith (grunt) {
  // Create a SpriteMaker function
  function SpriteMaker() {
    // Grab the raw configuration
    var data = this.data;

    // If we were invoked via `grunt-newer`, re-localize the info
    if (data.src === undefined && data.files) {
      data = data.files[0] || {};
    }

    // Determine the origin and destinations
    var src = data.src;
    var destImg = data.dest;
    var destCss = data.destCss;
    var cssTemplate = data.cssTemplate;
    var that = this;

    // Verify all properties are here
    if (!src || !destImg || !destCss) {
      return grunt.fatal('grunt.sprite requires a src, dest (img), and destCss property');
    }

    // Expand all filepaths (e.g. `*.png` -> `home.png`)
    var srcFiles = grunt.file.expand(src);

    // If there are settings for retina
    var retinaSrcFiles;
    var retinaSrcFilter = data.retinaSrcFilter;
    var retinaDestImg = data.retinaDest;
    if (retinaSrcFilter || retinaDestImg) {
      grunt.log.debug('Retina settings detected');

      // Verify our required set is present
      if (!retinaSrcFilter || !retinaDestImg) {
        return grunt.fatal('Retina settings detected. We must have both `retinaSrcFilter` and `retinaDest` ' +
          'provided for retina to work');
      }

      // Filter out our retina files
      retinaSrcFiles = [];
      srcFiles = srcFiles.filter(function filterSrcFile (filepath) {
        // If we have a retina file, filter it out
        if (grunt.file.match(retinaSrcFilter, filepath).length) {
          retinaSrcFiles.push(filepath);
          return false;
        // Otherwise, keep it in the src files
        } else {
          return true;
        }
      });
      grunt.verbose.writeln('Retina images found: ' + retinaSrcFiles.join(', '));

      // If we have a different amount of normal and retina images, complain and leave
      if (srcFiles.length !== retinaSrcFiles.length) {
        return grunt.fatal('Retina settings detected but ' + retinaSrcFiles.length + ' retina images were found. ' +
          'We have ' + srcFiles.length + ' normal images and expect these numbers to line up. ' +
          'Please double check `retinaSrcFilter`.');
      }
    }

    // Create an async callback
    var cb = this.async();

    // Determine the format of the image
    var imgOpts = data.imgOpts || {};
    var imgFormat = imgOpts.format || imgFormats.get(destImg) || 'png';

    // Set up the defautls for imgOpts
    _.defaults(imgOpts, {format: imgFormat});

    // Prepare spritesmith parameters
    var spritesmithParams = {
      src: srcFiles,
      engine: data.engine,
      algorithm: data.algorithm,
      padding: data.padding || 0,
      algorithmOpts: data.algorithmOpts || {},
      engineOpts: data.engineOpts || {},
      exportOpts: imgOpts
    };

    // In parallel
    async.parallel([
      // Run our normal task
      function normalSpritesheet (callback) {
        spritesmith(spritesmithParams, callback);
      },
      // If we have a retina task, run it as well
      function retinaSpritesheet (callback) {
        // DEV: We don't check length since we could have no images passed in
        if (retinaSrcFiles) {
          var retinaParams = _.defaults({
            src: retinaSrcFiles
          }, spritesmithParams);
          spritesmith(retinaParams, callback);
        } else {
          process.nextTick(callback);
        }
      }
    ], function handleSpritesheets (err, resultArr) {
      // If an error occurred, callback with it
      if (err) {
        grunt.fatal(err);
        return cb(err);
      }

      // Otherwise, write out the result to destImg
      var result = resultArr[0];
      var destImgDir = path.dirname(destImg);
      grunt.file.mkdir(destImgDir);
      fs.writeFileSync(destImg, result.image, 'binary');

      // Generate a listing of CSS variables
      var coordinates = result.coordinates;
      var properties = result.properties;
      var spritePath = data.imgPath || url.relative(destCss, destImg);
      var spritesheetInfo = {
        width: properties.width,
        height: properties.height,
        image: spritePath
      };
      var cssVarMap = data.cssVarMap || function noop () {};
      var cleanCoords = [];

      // Clean up the file name of the file
      Object.getOwnPropertyNames(coordinates).sort().forEach(function prepareTemplateData (file) {
        // Extract out our name
        var name = getCoordinateName(file);
        var coords = coordinates[file];

        // Specify the image for the sprite
        coords.name = name;
        coords.source_image = file;
        // DEV: `image`, `total_width`, `total_height` are deprecated as they are overwritten in `spritesheet-templates`
        coords.image = spritePath;
        coords.total_width = properties.width;
        coords.total_height = properties.height;

        // Map the coordinates through cssVarMap
        coords = cssVarMap(coords) || coords;

        // Save the cleaned name and coordinates
        cleanCoords.push(coords);
      });

      // If we have retina sprites
      var retinaCleanCoords;
      var retinaPairs;
      var retinaResult = resultArr[1];
      var retinaSpritesheetInfo;
      if (retinaResult) {
        // Write out the result to destImg
        var retinaDestImgDir = path.dirname(retinaDestImg);
        grunt.file.mkdir(retinaDestImgDir);
        fs.writeFileSync(retinaDestImg, retinaResult.image, 'binary');

        // Generate a listing of CSS variables
        var retinaCoordinates = retinaResult.coordinates;
        var retinaProperties = retinaResult.properties;
        var retinaSpritePath = data.retinaImgPath || url.relative(destCss, retinaDestImg);
        retinaSpritesheetInfo = {
          width: retinaProperties.width,
          height: retinaProperties.height,
          image: retinaSpritePath
        };
        // DEV: We reuse cssVarMap
        retinaCleanCoords = [];

        // Clean up the file name of the file
        Object.getOwnPropertyNames(retinaCoordinates).sort().forEach(function prepareRetinaTemplateData (file) {
          var name = getCoordinateName(file);
          var coords = retinaCoordinates[file];
          coords.name = name;
          coords.source_image = file;
          coords.image = retinaSpritePath;
          coords.total_width = retinaProperties.width;
          coords.total_height = retinaProperties.height;
          coords = cssVarMap(coords) || coords;
          retinaCleanCoords.push(coords);
        });

        // Generate pairings for our coordinates
        // TODO: Should renaming occur here or within spritesheet-templates?
        retinaPairs = cleanCoords.map(function getSpritePairs (normalSprite, i) {
          // Assert that image sizes line up for debugging purposes
          var retinaSprite = retinaCleanCoords[i];
          if (retinaSprite.width !== normalSprite.width * 2 || retinaSprite.height !== normalSprite.height * 2) {
            grunt.log.warn('Normal sprite has inconsistent size with retina sprite. ' +
              '"' + normalSprite.name + '" is ' + normalSprite.width + 'x' + normalSprite.height + ' while ' +
              '"' + retinaSprite.name + '" is ' + retinaSprite.width + 'x' + retinaSprite.height + '.');
          }

          // Generate our pair
          // TODO: Renaming should come earlier in `cssVarMap`
          var name = normalSprite.name;
          normalSprite.name += '-normal';
          return {
            name: name,
            normal: normalSprite,
            retina: retinaSprite
          };
        });
      }

      // If there is a custom template, use it
      var cssFormat = 'spritesmith-custom';
      var cssOptions = data.cssOpts || {};
      if (cssTemplate) {
        if (typeof cssTemplate === 'function') {
          templater.addTemplate(cssFormat, cssTemplate);
        } else {
          templater.addHandlebarsTemplate(cssFormat, fs.readFileSync(cssTemplate, 'utf8'));
        }
      } else {
      // Otherwise, override the cssFormat and fallback to 'json'
      // TODO: Concatenate on `-retina` to `destCss`
        // cssFormat = data.cssFormat || cssFormats.get(destCss) || 'json';
        cssFormat = 'scss-retina';
      }

      // Render the variables via `spritesheet-templates`
      var cssStr = templater({
        sprites: cleanCoords,
        spritesheet: spritesheetInfo,
        retinaPairs: retinaPairs,
        retinaSprites: retinaCleanCoords,
        retinaSpritesheet: retinaSpritesheetInfo
      }, {
        format: cssFormat,
        formatOpts: cssOptions,
        spritesheetName: data.cssSpritesheetName,
        retinaSpritesheetName: data.retinaCssSpritesheetName
      });

      // Write it out to the CSS file
      var destCssDir = path.dirname(destCss);
      grunt.file.mkdir(destCssDir);
      fs.writeFileSync(destCss, cssStr, 'utf8');

      // Fail task if errors were logged.
      if (that.errorCount) { cb(false); }

      // Otherwise, print a success message.
      grunt.log.writeln('Files "' + destCss + '", "' + destImg + '" created.');

      // Callback
      cb(true);
    });
  }

  // Export the SpriteMaker function
  grunt.registerMultiTask('sprite', 'Spritesheet making utility', SpriteMaker);
};
<commit_msg>Added TODO to consider<commit_after>// Load in dependencies
var fs = require('fs');
var path = require('path');
var _ = require('underscore');
var async = require('async');
var templater = require('spritesheet-templates');
var spritesmith = require('spritesmith');
var url = require('url2');

// TODO: Prefix `spritesheet` with `normal`?

// Define class to contain different extension handlers
function ExtFormat() {
  this.formatObj = {};
}
ExtFormat.prototype = {
  add: function (name, val) {
    this.formatObj[name] = val;
  },
  get: function (filepath) {
    // Grab the extension from the filepath
    var ext = path.extname(filepath);
    var lowerExt = ext.toLowerCase();

    // Look up the file extenion from our format object
    var formatObj = this.formatObj;
    var format = formatObj[lowerExt];
    return format;
  }
};

// Create img and css formats
var imgFormats = new ExtFormat();
var cssFormats = new ExtFormat();

// Add our img formats
imgFormats.add('.png', 'png');
imgFormats.add('.jpg', 'jpeg');
imgFormats.add('.jpeg', 'jpeg');

// Add our css formats
cssFormats.add('.styl', 'stylus');
cssFormats.add('.stylus', 'stylus');
cssFormats.add('.sass', 'sass');
cssFormats.add('.scss', 'scss');
cssFormats.add('.less', 'less');
cssFormats.add('.json', 'json');
cssFormats.add('.css', 'css');

function getCoordinateName(filepath) {
  // Extract the image name (exlcuding extension)
  var fullname = path.basename(filepath);
  var nameParts = fullname.split('.');

  // If there is are more than 2 parts, pop the last one
  if (nameParts.length >= 2) {
    nameParts.pop();
  }

  // Return our modified filename
  return nameParts.join('.');
}

module.exports = function gruntSpritesmith (grunt) {
  // Create a SpriteMaker function
  function SpriteMaker() {
    // Grab the raw configuration
    var data = this.data;

    // If we were invoked via `grunt-newer`, re-localize the info
    if (data.src === undefined && data.files) {
      data = data.files[0] || {};
    }

    // Determine the origin and destinations
    var src = data.src;
    var destImg = data.dest;
    var destCss = data.destCss;
    var cssTemplate = data.cssTemplate;
    var that = this;

    // Verify all properties are here
    if (!src || !destImg || !destCss) {
      return grunt.fatal('grunt.sprite requires a src, dest (img), and destCss property');
    }

    // Expand all filepaths (e.g. `*.png` -> `home.png`)
    var srcFiles = grunt.file.expand(src);

    // If there are settings for retina
    var retinaSrcFiles;
    var retinaSrcFilter = data.retinaSrcFilter;
    var retinaDestImg = data.retinaDest;
    if (retinaSrcFilter || retinaDestImg) {
      grunt.log.debug('Retina settings detected');

      // Verify our required set is present
      if (!retinaSrcFilter || !retinaDestImg) {
        return grunt.fatal('Retina settings detected. We must have both `retinaSrcFilter` and `retinaDest` ' +
          'provided for retina to work');
      }

      // Filter out our retina files
      retinaSrcFiles = [];
      srcFiles = srcFiles.filter(function filterSrcFile (filepath) {
        // If we have a retina file, filter it out
        if (grunt.file.match(retinaSrcFilter, filepath).length) {
          retinaSrcFiles.push(filepath);
          return false;
        // Otherwise, keep it in the src files
        } else {
          return true;
        }
      });
      grunt.verbose.writeln('Retina images found: ' + retinaSrcFiles.join(', '));

      // If we have a different amount of normal and retina images, complain and leave
      if (srcFiles.length !== retinaSrcFiles.length) {
        return grunt.fatal('Retina settings detected but ' + retinaSrcFiles.length + ' retina images were found. ' +
          'We have ' + srcFiles.length + ' normal images and expect these numbers to line up. ' +
          'Please double check `retinaSrcFilter`.');
      }
    }

    // Create an async callback
    var cb = this.async();

    // Determine the format of the image
    var imgOpts = data.imgOpts || {};
    var imgFormat = imgOpts.format || imgFormats.get(destImg) || 'png';

    // Set up the defautls for imgOpts
    _.defaults(imgOpts, {format: imgFormat});

    // Prepare spritesmith parameters
    var spritesmithParams = {
      src: srcFiles,
      engine: data.engine,
      algorithm: data.algorithm,
      padding: data.padding || 0,
      algorithmOpts: data.algorithmOpts || {},
      engineOpts: data.engineOpts || {},
      exportOpts: imgOpts
    };

    // In parallel
    async.parallel([
      // Run our normal task
      function normalSpritesheet (callback) {
        spritesmith(spritesmithParams, callback);
      },
      // If we have a retina task, run it as well
      function retinaSpritesheet (callback) {
        // DEV: We don't check length since we could have no images passed in
        if (retinaSrcFiles) {
          var retinaParams = _.defaults({
            src: retinaSrcFiles
          }, spritesmithParams);
          spritesmith(retinaParams, callback);
        } else {
          process.nextTick(callback);
        }
      }
    ], function handleSpritesheets (err, resultArr) {
      // If an error occurred, callback with it
      if (err) {
        grunt.fatal(err);
        return cb(err);
      }

      // Otherwise, write out the result to destImg
      var result = resultArr[0];
      var destImgDir = path.dirname(destImg);
      grunt.file.mkdir(destImgDir);
      fs.writeFileSync(destImg, result.image, 'binary');

      // Generate a listing of CSS variables
      var coordinates = result.coordinates;
      var properties = result.properties;
      var spritePath = data.imgPath || url.relative(destCss, destImg);
      var spritesheetInfo = {
        width: properties.width,
        height: properties.height,
        image: spritePath
      };
      var cssVarMap = data.cssVarMap || function noop () {};
      var cleanCoords = [];

      // Clean up the file name of the file
      Object.getOwnPropertyNames(coordinates).sort().forEach(function prepareTemplateData (file) {
        // Extract out our name
        var name = getCoordinateName(file);
        var coords = coordinates[file];

        // Specify the image for the sprite
        coords.name = name;
        coords.source_image = file;
        // DEV: `image`, `total_width`, `total_height` are deprecated as they are overwritten in `spritesheet-templates`
        coords.image = spritePath;
        coords.total_width = properties.width;
        coords.total_height = properties.height;

        // Map the coordinates through cssVarMap
        coords = cssVarMap(coords) || coords;

        // Save the cleaned name and coordinates
        cleanCoords.push(coords);
      });

      // If we have retina sprites
      var retinaCleanCoords;
      var retinaPairs;
      var retinaResult = resultArr[1];
      var retinaSpritesheetInfo;
      if (retinaResult) {
        // Write out the result to destImg
        var retinaDestImgDir = path.dirname(retinaDestImg);
        grunt.file.mkdir(retinaDestImgDir);
        fs.writeFileSync(retinaDestImg, retinaResult.image, 'binary');

        // Generate a listing of CSS variables
        var retinaCoordinates = retinaResult.coordinates;
        var retinaProperties = retinaResult.properties;
        var retinaSpritePath = data.retinaImgPath || url.relative(destCss, retinaDestImg);
        retinaSpritesheetInfo = {
          width: retinaProperties.width,
          height: retinaProperties.height,
          image: retinaSpritePath
        };
        // DEV: We reuse cssVarMap
        retinaCleanCoords = [];

        // Clean up the file name of the file
        Object.getOwnPropertyNames(retinaCoordinates).sort().forEach(function prepareRetinaTemplateData (file) {
          var name = getCoordinateName(file);
          var coords = retinaCoordinates[file];
          coords.name = name;
          coords.source_image = file;
          coords.image = retinaSpritePath;
          coords.total_width = retinaProperties.width;
          coords.total_height = retinaProperties.height;
          coords = cssVarMap(coords) || coords;
          retinaCleanCoords.push(coords);
        });

        // Generate pairings for our coordinates
        // TODO: Should renaming occur here or within spritesheet-templates?
        retinaPairs = cleanCoords.map(function getSpritePairs (normalSprite, i) {
          // Assert that image sizes line up for debugging purposes
          var retinaSprite = retinaCleanCoords[i];
          if (retinaSprite.width !== normalSprite.width * 2 || retinaSprite.height !== normalSprite.height * 2) {
            grunt.log.warn('Normal sprite has inconsistent size with retina sprite. ' +
              '"' + normalSprite.name + '" is ' + normalSprite.width + 'x' + normalSprite.height + ' while ' +
              '"' + retinaSprite.name + '" is ' + retinaSprite.width + 'x' + retinaSprite.height + '.');
          }

          // Generate our pair
          // TODO: Renaming should come earlier in `cssVarMap`
          var name = normalSprite.name;
          normalSprite.name += '-normal';
          return {
            name: name,
            normal: normalSprite,
            retina: retinaSprite
          };
        });
      }

      // If there is a custom template, use it
      var cssFormat = 'spritesmith-custom';
      var cssOptions = data.cssOpts || {};
      if (cssTemplate) {
        if (typeof cssTemplate === 'function') {
          templater.addTemplate(cssFormat, cssTemplate);
        } else {
          templater.addHandlebarsTemplate(cssFormat, fs.readFileSync(cssTemplate, 'utf8'));
        }
      } else {
      // Otherwise, override the cssFormat and fallback to 'json'
      // TODO: Concatenate on `-retina` to `destCss`
        // cssFormat = data.cssFormat || cssFormats.get(destCss) || 'json';
        cssFormat = 'scss-retina';
      }

      // Render the variables via `spritesheet-templates`
      var cssStr = templater({
        sprites: cleanCoords,
        spritesheet: spritesheetInfo,
        retinaPairs: retinaPairs,
        retinaSprites: retinaCleanCoords,
        retinaSpritesheet: retinaSpritesheetInfo
      }, {
        format: cssFormat,
        formatOpts: cssOptions,
        spritesheetName: data.cssSpritesheetName,
        retinaSpritesheetName: data.retinaCssSpritesheetName
      });

      // Write it out to the CSS file
      var destCssDir = path.dirname(destCss);
      grunt.file.mkdir(destCssDir);
      fs.writeFileSync(destCss, cssStr, 'utf8');

      // Fail task if errors were logged.
      if (that.errorCount) { cb(false); }

      // Otherwise, print a success message.
      grunt.log.writeln('Files "' + destCss + '", "' + destImg + '" created.');

      // Callback
      cb(true);
    });
  }

  // Export the SpriteMaker function
  grunt.registerMultiTask('sprite', 'Spritesheet making utility', SpriteMaker);
};
<|endoftext|>


<commit_before>import debounce                          from 'lodash.debounce';
import {
    action,
    observable,
    runInAction,
    reaction }                           from 'mobx';
import Client                            from '_common/base/client_base';
import {
    getMinPayout,
    isCryptocurrency  }                  from '_common/base/currency_base';
import BinarySocket                      from '_common/base/socket_base';
import { cloneObject, isEmptyObject }    from '_common/utility';
import { WS }                            from 'Services';
import GTM                               from 'Utils/gtm';
import URLHelper                         from 'Utils/URL/url_helper';
import { processPurchase }               from './Actions/purchase';
import * as Symbol                       from './Actions/symbol';
import {
    allowed_query_string_variables,
    non_proposal_query_string_variable } from './Constants/query_string';
import getValidationRules                from './Constants/validation_rules';
import { setChartBarrier }               from './Helpers/chart';
import ContractType                      from './Helpers/contract_type';
import { convertDurationLimit }          from './Helpers/duration';
import { processTradeParams }            from './Helpers/process';
import {
    createProposalRequests,
    getProposalInfo,
    getProposalParametersName }          from './Helpers/proposal';
import { pickDefaultSymbol }             from './Helpers/symbol';
import BaseStore                         from '../../base_store';

export default class TradeStore extends BaseStore {
    // Control values
    @observable is_trade_component_mounted = false;
    @observable is_purchase_enabled        = false;
    @observable is_trade_enabled           = false;

    // Underlying
    @observable symbol;

    // Contract Type
    @observable contract_expiry_type = '';
    @observable contract_start_type  = '';
    @observable contract_type        = '';
    @observable contract_types_list  = {};
    @observable form_components      = [];
    @observable trade_types          = {};

    // Amount
    @observable amount          = 10;
    @observable basis           = '';
    @observable basis_list      = [];
    @observable currencies_list = {};
    @observable currency        = Client.get('currency');

    // Duration
    @observable duration            = 5;
    @observable duration_unit       = '';
    @observable duration_units_list = [];
    @observable duration_min_max    = {};
    @observable expiry_date         = '';
    @observable expiry_time         = '09:40';
    @observable expiry_type         = 'duration';

    // Barrier
    @observable barrier_1     = '';
    @observable barrier_2     = '';
    @observable barrier_count = 0;

    // Start Time
    @observable start_date       = Number(0); // Number(0) refers to 'now'
    @observable start_dates_list = [];
    @observable start_time       = '12:30';
    @observable sessions         = [];

    // Last Digit
    @observable last_digit = 5;

    // Purchase
    @observable proposal_info = {};
    @observable purchase_info = {};

    // Chart
    chart_id = 1;

    debouncedProposal = debounce(this.requestProposal, 500);

    constructor({ root_store }) {
        URLHelper.pruneQueryString(allowed_query_string_variables);

        super({
            root_store,
            session_storage_properties: allowed_query_string_variables,
            validation_rules          : getValidationRules(),
        });

        Object.defineProperty(
            this,
            'is_query_string_applied',
            {
                enumerable: false,
                value     : false,
                writable  : true,
            }
        );

        if (Client.isLoggedIn) {
            this.processNewValuesAsync({ currency: Client.get('currency') });
        }

        // Adds intercept to change min_max value of duration validation
        reaction(
            ()=> [this.contract_expiry_type, this.duration_min_max, this.duration_unit, this.expiry_type],
            () => {
                this.changeDurationValidationRules();
            }
        );
    }

    @action.bound
    async prepareTradeStore() {
        const query_string_values = this.updateQueryString();
        this.smart_chart = this.root_store.modules.smart_chart;

        if (!this.symbol) {
            const active_symbols = await WS.activeSymbols();
            await this.processNewValuesAsync({
                symbol: pickDefaultSymbol(active_symbols.active_symbols),
                ...query_string_values,
            });
        }

        if (this.symbol) {
            ContractType.buildContractTypesConfig(this.symbol).then(action(async () => {
                await this.processNewValuesAsync({
                    ...ContractType.getContractValues(this),
                    ...ContractType.getContractCategories(),
                    ...query_string_values,
                });
            }));
        }
    }

    @action.bound
     init = async () => {
         // To be sure that the website_status response has been received before processing trading page.
         await BinarySocket.wait('website_status');
     };

    @action.bound
    onChange(e) {
        const { name, value } = e.target;
        if (!(name in this)) {
            throw new Error(`Invalid Argument: ${name}`);
        }

        this.processNewValuesAsync({ [name]: value }, true);
    }

    @action.bound
    onHoverPurchase(is_over, contract_type) {
        this.smart_chart.updateBarrierShade(is_over, contract_type);
    }

    @action.bound
    onPurchase(proposal_id, price, type) {
        if (proposal_id) {
            processPurchase(proposal_id, price).then(action((response) => {
                if (this.proposal_info[type].id !== proposal_id) {
                    throw new Error('Proposal ID does not match.');
                }
                if (response.buy && !Client.get('is_virtual')) {
                    const contract_data = {
                        ...this.proposal_requests[type],
                        ...this.proposal_info[type],
                        buy_price: response.buy.buy_price,
                    };
                    GTM.pushPurchaseData(contract_data, this.root_store);
                }
                WS.forgetAll('proposal');
                this.purchase_info = response;
            }));
        }
    }

    @action.bound
    onClickNewTrade(e) {
        this.requestProposal();
        e.preventDefault();
    }

    /**
     * Updates the store with new values
     * @param  {Object} new_state - new values to update the store with
     * @return {Object} returns the object having only those values that are updated
     */
    @action.bound
    updateStore(new_state) {
        Object.keys(cloneObject(new_state)).forEach((key) => {
            if (key === 'root_store' || ['validation_rules', 'validation_errors'].indexOf(key) > -1) return;
            if (JSON.stringify(this[key]) === JSON.stringify(new_state[key])) {
                delete new_state[key];
            } else {
                if (key === 'symbol') {
                    this.is_purchase_enabled = false;
                    this.is_trade_enabled    = false;
                }

                // Add changes to queryString of the url
                if (
                    allowed_query_string_variables.indexOf(key) !== -1 &&
                    this.is_trade_component_mounted
                ) {
                    URLHelper.setQueryParam({ [key]: new_state[key] });
                }

                this[key] = new_state[key];

                // validation is done in mobx intercept (base_store.js)
                // when barrier_1 is set, it is compared with store.barrier_2 (which is not updated yet)
                if (key === 'barrier_2' && new_state.barrier_1) {
                    this.barrier_1 = new_state.barrier_1; // set it again, after barrier_2 is updated in store
                }
            }
        });

        return new_state;
    }

    async processNewValuesAsync(obj_new_values = {}, is_changed_by_user = false) {

        // Sets the default value to Amount when Currency has changed from Fiat to Crypto and vice versa. The source of default values is the website_status response.
        if (is_changed_by_user && /\bcurrency\b/.test(Object.keys(obj_new_values)) &&
            isCryptocurrency(obj_new_values.currency) !== isCryptocurrency(this.currency)) {
            obj_new_values.amount = obj_new_values.amount || getMinPayout(obj_new_values.currency);
        }

        const new_state = this.updateStore(cloneObject(obj_new_values));

        if (is_changed_by_user || /\b(symbol|contract_types_list)\b/.test(Object.keys(new_state))) {
            if ('symbol' in new_state) {
                await Symbol.onChangeSymbolAsync(new_state.symbol);
            }

            this.updateStore({ // disable purchase button(s), clear contract info
                is_purchase_enabled: false,
                proposal_info      : {},
            });

            if (!this.smart_chart.is_contract_mode) {
                const is_barrier_changed = 'barrier_1' in new_state || 'barrier_2' in new_state;
                if (is_barrier_changed) {
                    this.smart_chart.updateBarriers(this.barrier_1, this.barrier_2);
                } else {
                    this.smart_chart.removeBarriers();
                }
            }

            const snapshot = await processTradeParams(this, new_state);
            const query_string_values = this.updateQueryString();
            snapshot.is_trade_enabled = true;

            this.updateStore({
                ...snapshot,
                ...(this.is_query_string_applied ? {} : query_string_values),
            });

            this.is_query_string_applied = true;

            if (/\bcontract_type\b/.test(Object.keys(new_state))) {
                this.validateAllProperties();
            }

            this.debouncedProposal();
        }
    }

    proposal_requests = {};

    @action.bound
    requestProposal() {
        const requests = createProposalRequests(this);
        if (Object.values(this.validation_errors).some(e => e.length)) {
            this.proposal_info     = {};
            this.purchase_info     = {};
            WS.forgetAll('proposal');
            return;
        }

        if (!isEmptyObject(requests)) {
            const proper_proposal_params_for_query_string = getProposalParametersName(requests);

            URLHelper.pruneQueryString(
                [
                    ...proper_proposal_params_for_query_string,
                    ...non_proposal_query_string_variable,
                ]
            );

            this.proposal_requests = requests;
            this.proposal_info     = {};
            this.purchase_info     = {};

            WS.forgetAll('proposal').then(() => {
                Object.keys(this.proposal_requests).forEach((type) => {
                    WS.subscribeProposal(this.proposal_requests[type], this.onProposalResponse);
                });
            });
        }
    }

    @action.bound
    onProposalResponse(response) {
        const contract_type = response.echo_req.contract_type;
        this.proposal_info = {
            ...this.proposal_info,
            [contract_type]: getProposalInfo(this, response),
        };

        if (!this.smart_chart.is_contract_mode) {
            setChartBarrier(this.smart_chart, response, this.onChartBarrierChange);
        }

        this.is_purchase_enabled = true;
    }

    @action.bound
    onChartBarrierChange(barrier_1, barrier_2) {
        this.processNewValuesAsync({ barrier_1, barrier_2 }, true);
    }

    @action.bound
    updateQueryString() {

        // Update the url's query string by default values of the store
        const query_params = URLHelper.updateQueryString(
            this,
            allowed_query_string_variables,
            this.is_trade_component_mounted
        );

        // update state values from query string
        const config = {};
        [...query_params].forEach(param => config[param[0]] = param[1]);
        return config;
    }

    @action.bound
    changeDurationValidationRules() {
        if (this.expiry_type === 'endtime') {
            this.validation_errors.duration = [];
            return;
        }

        const index = this.validation_rules.duration.findIndex(item => item[0] === 'number');
        const limits = this.duration_min_max[this.contract_expiry_type] || false;

        if (limits) {
            const duration_options = {
                min: convertDurationLimit(+limits.min, this.duration_unit),
                max: convertDurationLimit(+limits.max, this.duration_unit),
            };

            if (index > -1) {
                this.validation_rules.duration[index][1] = duration_options;
            } else {
                this.validation_rules.duration.push(['number', duration_options]);
            }
            this.validateProperty('duration', this.duration);
        }
    }

    @action.bound
    async onMount() {
        await this.prepareTradeStore();
        runInAction(() => {
            this.is_trade_component_mounted = true;
        });
        this.updateQueryString();
    }

    @action.bound
    onUnmount() {
        this.is_trade_component_mounted = false;
    }
}
<commit_msg>Unsubscribe proposals on unmount<commit_after>import debounce                          from 'lodash.debounce';
import {
    action,
    observable,
    runInAction,
    reaction }                           from 'mobx';
import Client                            from '_common/base/client_base';
import {
    getMinPayout,
    isCryptocurrency  }                  from '_common/base/currency_base';
import BinarySocket                      from '_common/base/socket_base';
import { cloneObject, isEmptyObject }    from '_common/utility';
import { WS }                            from 'Services';
import GTM                               from 'Utils/gtm';
import URLHelper                         from 'Utils/URL/url_helper';
import { processPurchase }               from './Actions/purchase';
import * as Symbol                       from './Actions/symbol';
import {
    allowed_query_string_variables,
    non_proposal_query_string_variable } from './Constants/query_string';
import getValidationRules                from './Constants/validation_rules';
import { setChartBarrier }               from './Helpers/chart';
import ContractType                      from './Helpers/contract_type';
import { convertDurationLimit }          from './Helpers/duration';
import { processTradeParams }            from './Helpers/process';
import {
    createProposalRequests,
    getProposalInfo,
    getProposalParametersName }          from './Helpers/proposal';
import { pickDefaultSymbol }             from './Helpers/symbol';
import BaseStore                         from '../../base_store';

export default class TradeStore extends BaseStore {
    // Control values
    @observable is_trade_component_mounted = false;
    @observable is_purchase_enabled        = false;
    @observable is_trade_enabled           = false;

    // Underlying
    @observable symbol;

    // Contract Type
    @observable contract_expiry_type = '';
    @observable contract_start_type  = '';
    @observable contract_type        = '';
    @observable contract_types_list  = {};
    @observable form_components      = [];
    @observable trade_types          = {};

    // Amount
    @observable amount          = 10;
    @observable basis           = '';
    @observable basis_list      = [];
    @observable currencies_list = {};
    @observable currency        = Client.get('currency');

    // Duration
    @observable duration            = 5;
    @observable duration_unit       = '';
    @observable duration_units_list = [];
    @observable duration_min_max    = {};
    @observable expiry_date         = '';
    @observable expiry_time         = '09:40';
    @observable expiry_type         = 'duration';

    // Barrier
    @observable barrier_1     = '';
    @observable barrier_2     = '';
    @observable barrier_count = 0;

    // Start Time
    @observable start_date       = Number(0); // Number(0) refers to 'now'
    @observable start_dates_list = [];
    @observable start_time       = '12:30';
    @observable sessions         = [];

    // Last Digit
    @observable last_digit = 5;

    // Purchase
    @observable proposal_info = {};
    @observable purchase_info = {};

    // Chart
    chart_id = 1;

    debouncedProposal = debounce(this.requestProposal, 500);

    constructor({ root_store }) {
        URLHelper.pruneQueryString(allowed_query_string_variables);

        super({
            root_store,
            session_storage_properties: allowed_query_string_variables,
            validation_rules          : getValidationRules(),
        });

        Object.defineProperty(
            this,
            'is_query_string_applied',
            {
                enumerable: false,
                value     : false,
                writable  : true,
            }
        );

        if (Client.isLoggedIn) {
            this.processNewValuesAsync({ currency: Client.get('currency') });
        }

        // Adds intercept to change min_max value of duration validation
        reaction(
            ()=> [this.contract_expiry_type, this.duration_min_max, this.duration_unit, this.expiry_type],
            () => {
                this.changeDurationValidationRules();
            }
        );
    }

    @action.bound
    async prepareTradeStore() {
        const query_string_values = this.updateQueryString();
        this.smart_chart = this.root_store.modules.smart_chart;

        if (!this.symbol) {
            const active_symbols = await WS.activeSymbols();
            await this.processNewValuesAsync({
                symbol: pickDefaultSymbol(active_symbols.active_symbols),
                ...query_string_values,
            });
        }

        if (this.symbol) {
            ContractType.buildContractTypesConfig(this.symbol).then(action(async () => {
                await this.processNewValuesAsync({
                    ...ContractType.getContractValues(this),
                    ...ContractType.getContractCategories(),
                    ...query_string_values,
                });
            }));
        }
    }

    @action.bound
     init = async () => {
         // To be sure that the website_status response has been received before processing trading page.
         await BinarySocket.wait('website_status');
     };

    @action.bound
    onChange(e) {
        const { name, value } = e.target;
        if (!(name in this)) {
            throw new Error(`Invalid Argument: ${name}`);
        }

        this.processNewValuesAsync({ [name]: value }, true);
    }

    @action.bound
    onHoverPurchase(is_over, contract_type) {
        this.smart_chart.updateBarrierShade(is_over, contract_type);
    }

    @action.bound
    onPurchase(proposal_id, price, type) {
        if (proposal_id) {
            processPurchase(proposal_id, price).then(action((response) => {
                if (this.proposal_info[type].id !== proposal_id) {
                    throw new Error('Proposal ID does not match.');
                }
                if (response.buy && !Client.get('is_virtual')) {
                    const contract_data = {
                        ...this.proposal_requests[type],
                        ...this.proposal_info[type],
                        buy_price: response.buy.buy_price,
                    };
                    GTM.pushPurchaseData(contract_data, this.root_store);
                }
                WS.forgetAll('proposal');
                this.purchase_info = response;
            }));
        }
    }

    @action.bound
    onClickNewTrade(e) {
        this.requestProposal();
        e.preventDefault();
    }

    /**
     * Updates the store with new values
     * @param  {Object} new_state - new values to update the store with
     * @return {Object} returns the object having only those values that are updated
     */
    @action.bound
    updateStore(new_state) {
        Object.keys(cloneObject(new_state)).forEach((key) => {
            if (key === 'root_store' || ['validation_rules', 'validation_errors'].indexOf(key) > -1) return;
            if (JSON.stringify(this[key]) === JSON.stringify(new_state[key])) {
                delete new_state[key];
            } else {
                if (key === 'symbol') {
                    this.is_purchase_enabled = false;
                    this.is_trade_enabled    = false;
                }

                // Add changes to queryString of the url
                if (
                    allowed_query_string_variables.indexOf(key) !== -1 &&
                    this.is_trade_component_mounted
                ) {
                    URLHelper.setQueryParam({ [key]: new_state[key] });
                }

                this[key] = new_state[key];

                // validation is done in mobx intercept (base_store.js)
                // when barrier_1 is set, it is compared with store.barrier_2 (which is not updated yet)
                if (key === 'barrier_2' && new_state.barrier_1) {
                    this.barrier_1 = new_state.barrier_1; // set it again, after barrier_2 is updated in store
                }
            }
        });

        return new_state;
    }

    async processNewValuesAsync(obj_new_values = {}, is_changed_by_user = false) {
        // Sets the default value to Amount when Currency has changed from Fiat to Crypto and vice versa.
        // The source of default values is the website_status response.
        if (is_changed_by_user && /\bcurrency\b/.test(Object.keys(obj_new_values)) &&
            isCryptocurrency(obj_new_values.currency) !== isCryptocurrency(this.currency)) {
            obj_new_values.amount = obj_new_values.amount || getMinPayout(obj_new_values.currency);
        }

        const new_state = this.updateStore(cloneObject(obj_new_values));

        if (is_changed_by_user || /\b(symbol|contract_types_list)\b/.test(Object.keys(new_state))) {
            if ('symbol' in new_state) {
                await Symbol.onChangeSymbolAsync(new_state.symbol);
            }

            this.updateStore({ // disable purchase button(s), clear contract info
                is_purchase_enabled: false,
                proposal_info      : {},
            });

            if (!this.smart_chart.is_contract_mode) {
                const is_barrier_changed = 'barrier_1' in new_state || 'barrier_2' in new_state;
                if (is_barrier_changed) {
                    this.smart_chart.updateBarriers(this.barrier_1, this.barrier_2);
                } else {
                    this.smart_chart.removeBarriers();
                }
            }

            const snapshot = await processTradeParams(this, new_state);
            const query_string_values = this.updateQueryString();
            snapshot.is_trade_enabled = true;

            this.updateStore({
                ...snapshot,
                ...(this.is_query_string_applied ? {} : query_string_values),
            });

            this.is_query_string_applied = true;

            if (/\bcontract_type\b/.test(Object.keys(new_state))) {
                this.validateAllProperties();
            }

            this.debouncedProposal();
        }
    }

    proposal_requests = {};

    @action.bound
    requestProposal() {
        const requests = createProposalRequests(this);
        if (Object.values(this.validation_errors).some(e => e.length)) {
            this.proposal_info     = {};
            this.purchase_info     = {};
            WS.forgetAll('proposal');
            return;
        }

        if (!isEmptyObject(requests)) {
            const proper_proposal_params_for_query_string = getProposalParametersName(requests);

            URLHelper.pruneQueryString(
                [
                    ...proper_proposal_params_for_query_string,
                    ...non_proposal_query_string_variable,
                ]
            );

            this.proposal_requests = requests;
            this.proposal_info     = {};
            this.purchase_info     = {};

            WS.forgetAll('proposal').then(() => {
                Object.keys(this.proposal_requests).forEach((type) => {
                    WS.subscribeProposal(this.proposal_requests[type], this.onProposalResponse);
                });
            });
        }
    }

    @action.bound
    onProposalResponse(response) {
        const contract_type = response.echo_req.contract_type;
        this.proposal_info = {
            ...this.proposal_info,
            [contract_type]: getProposalInfo(this, response),
        };

        if (!this.smart_chart.is_contract_mode) {
            setChartBarrier(this.smart_chart, response, this.onChartBarrierChange);
        }

        this.is_purchase_enabled = true;
    }

    @action.bound
    onChartBarrierChange(barrier_1, barrier_2) {
        this.processNewValuesAsync({ barrier_1, barrier_2 }, true);
    }

    @action.bound
    updateQueryString() {

        // Update the url's query string by default values of the store
        const query_params = URLHelper.updateQueryString(
            this,
            allowed_query_string_variables,
            this.is_trade_component_mounted
        );

        // update state values from query string
        const config = {};
        [...query_params].forEach(param => config[param[0]] = param[1]);
        return config;
    }

    @action.bound
    changeDurationValidationRules() {
        if (this.expiry_type === 'endtime') {
            this.validation_errors.duration = [];
            return;
        }

        const index = this.validation_rules.duration.findIndex(item => item[0] === 'number');
        const limits = this.duration_min_max[this.contract_expiry_type] || false;

        if (limits) {
            const duration_options = {
                min: convertDurationLimit(+limits.min, this.duration_unit),
                max: convertDurationLimit(+limits.max, this.duration_unit),
            };

            if (index > -1) {
                this.validation_rules.duration[index][1] = duration_options;
            } else {
                this.validation_rules.duration.push(['number', duration_options]);
            }
            this.validateProperty('duration', this.duration);
        }
    }

    @action.bound
    async onMount() {
        await this.prepareTradeStore();
        this.debouncedProposal();
        runInAction(() => {
            this.is_trade_component_mounted = true;
        });
        this.updateQueryString();
    }

    @action.bound
    onUnmount() {
        WS.forgetAll('proposal');
        this.is_trade_component_mounted = false;
    }
}
<|endoftext|>


<commit_before>/*
 * not type checking this file because flow doesn't play well with
 * dynamically accessing methods on Array prototype
 */

import { def } from '../util/index'

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

/**
 * Intercept mutating methods and emit events
 */
;[
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]
.forEach(function (method) {
  // cache original method
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator () {
    // avoid leaking arguments:
    // http://jsperf.com/closure-with-arguments
    let i = arguments.length
    const args = new Array(i)
    while (i--) {
      args[i] = arguments[i]
    }
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
        inserted = args
        break
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    // notify change
    ob.dep.notify()
    return result
  })
})
<commit_msg>simplify source with rest params<commit_after>/*
 * not type checking this file because flow doesn't play well with
 * dynamically accessing methods on Array prototype
 */

import { def } from '../util/index'

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

/**
 * Intercept mutating methods and emit events
 */
;[
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]
.forEach(function (method) {
  // cache original method
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
        inserted = args
        break
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    // notify change
    ob.dep.notify()
    return result
  })
})
<|endoftext|>


<commit_before>var _ = require('lodash'),
    utils = require('../../../utils'),
    driver = utils.getDriver(),
    C = driver.constants,
    movement = require('../movement');

module.exports = function(spawn, creep, scope) {

    const {roomObjects, roomTerrain, bulk} = scope;

    var newX, newY, isOccupied, hostileOccupied;
    var checkObstacleFn = (i) => (i.x == newX && i.y == newY) && (
        _.contains(C.OBSTACLE_OBJECT_TYPES, i.type) ||                                          // just unwalkable
        (i.type == 'constructionSite' && _.contains(C.OBSTACLE_OBJECT_TYPES, i.structureType))  // unwalkable site
    );

    var directions = [1,2,3,4,5,6,7,8];
    if(spawn.spawning && spawn.spawning.directions) {
        directions = spawn.spawning.directions;
    }
    const otherDirections = _.difference([1,2,3,4,5,6,7,8], directions);
    // find the first direction where the creep can spawn
    for (var direction of directions) {
        var [dx,dy] = utils.getOffsetsByDirection(direction);

        newX = spawn.x + dx;
        newY = spawn.y + dy;
        isOccupied = _.any(roomObjects, checkObstacleFn) ||
            utils.checkTerrain(roomTerrain, newX, newY, C.TERRAIN_MASK_WALL) ||
            movement.isTileBusy(newX, newY);

        if (!isOccupied) {
            break;
        }

        // remember the first direction where we found a hostile creep
        if(!hostileOccupied) {
            hostileOccupied = _.find(roomObjects, i => i.x == newX && i.y == newY && i.type == 'creep' && i.user != spawn.user);
        }
    }

    // if we found a place to spawn, do so
    if(!isOccupied) {
        bulk.update(creep, {
            x: newX,
            y: newY,
            spawning: false
        });
        return true;
    }

    // spawn is surrounded, spawnstomp the first hostile we found above, unless...
    if(hostileOccupied) {
        // bail if there's an opening we could spawn to but chose not to
        for (var direction of otherDirections) {
            var [dx,dy] = utils.getOffsetsByDirection(direction);

            newX = spawn.x + dx;
            newY = spawn.y + dy;
            isOccupied = _.any(roomObjects, checkObstacleFn) ||
                utils.checkTerrain(roomTerrain, newX, newY, C.TERRAIN_MASK_WALL) ||
                movement.isTileBusy(newX, newY);

            if (!isOccupied) {
                return false;
            }
        }

        require('../creeps/_die')(hostileOccupied, undefined, true, scope);
        bulk.update(creep, {
            x: hostileOccupied.x,
            y: hostileOccupied.y,
            spawning: false
        });
        return true;
    }

    return false;
};<commit_msg>hotfix(processor): creep spawning into tunnels<commit_after>var _ = require('lodash'),
    utils = require('../../../utils'),
    driver = utils.getDriver(),
    C = driver.constants,
    movement = require('../movement');

module.exports = function(spawn, creep, scope) {

    const {roomObjects, roomTerrain, bulk} = scope;

    var newX, newY, isOccupied, hostileOccupied;
    var checkObstacleFn = (i) => (i.x == newX && i.y == newY) && (
        _.contains(C.OBSTACLE_OBJECT_TYPES, i.type) ||                                          // just unwalkable
        (i.type == 'constructionSite' && _.contains(C.OBSTACLE_OBJECT_TYPES, i.structureType))  // unwalkable site
    );

    var directions = [1,2,3,4,5,6,7,8];
    if(spawn.spawning && spawn.spawning.directions) {
        directions = spawn.spawning.directions;
    }
    const otherDirections = _.difference([1,2,3,4,5,6,7,8], directions);
    // find the first direction where the creep can spawn
    for (var direction of directions) {
        var [dx,dy] = utils.getOffsetsByDirection(direction);

        newX = spawn.x + dx;
        newY = spawn.y + dy;
        isOccupied = _.any(roomObjects, checkObstacleFn) ||
            movement.isTileBusy(newX, newY) ||
            (utils.checkTerrain(roomTerrain, newX, newY, C.TERRAIN_MASK_WALL) && !_.any(roomObjects, {type: 'road', x: newX, y: newY}));

        if (!isOccupied) {
            break;
        }

        // remember the first direction where we found a hostile creep
        if(!hostileOccupied) {
            hostileOccupied = _.find(roomObjects, i => i.x == newX && i.y == newY && i.type == 'creep' && i.user != spawn.user);
        }
    }

    // if we found a place to spawn, do so
    if(!isOccupied) {
        bulk.update(creep, {
            x: newX,
            y: newY,
            spawning: false
        });
        return true;
    }

    // spawn is surrounded, spawnstomp the first hostile we found above, unless...
    if(hostileOccupied) {
        // bail if there's an opening we could spawn to but chose not to
        for (var direction of otherDirections) {
            var [dx,dy] = utils.getOffsetsByDirection(direction);

            newX = spawn.x + dx;
            newY = spawn.y + dy;
            isOccupied = _.any(roomObjects, checkObstacleFn) ||
                utils.checkTerrain(roomTerrain, newX, newY, C.TERRAIN_MASK_WALL) ||
                movement.isTileBusy(newX, newY);

            if (!isOccupied) {
                return false;
            }
        }

        require('../creeps/_die')(hostileOccupied, undefined, true, scope);
        bulk.update(creep, {
            x: hostileOccupied.x,
            y: hostileOccupied.y,
            spawning: false
        });
        return true;
    }

    return false;
};
<|endoftext|>


<commit_before>var LS = {
  // *** DATA ***
  /*
    decode / encode  data to URL hash

    hash is split into the following sections delimited by '/'
    1. axiom
      example: F[A]
      chars: [A-Z]\[\]
    2. rules
      example: F:F+[F-FF]F+
      chars: [A-Z]\[\]\:\+\-
    3. instructions - delimited by ';' then split into parameters: distance(d), angle(d), push(u)/pop(o)
      example: F,d10,a25,u;A,d5,a10
      chars: [0-9],\.up
    4. iterations - max number of iterations
      example: 3
      chars: [0-9]
    5. starting drawing values - delimited by ',' : x, y, angle, iteration to display
      example: x500,y300,a10
      chars: [0-9]xyamwh
  */
  decodeHash: function () {
    var dataStrings = window.location.hash.substr(1).split('/');
    var axiomString = dataStrings[0];
    var rulesString = dataStrings[1];
    var instructionsString = dataStrings[2];
    var iterations = dataStrings[3];
    var startString = dataStrings[4];
    return {
      axiom: axiomString.split(''),
      rules: this.decodeRules(rulesString),
      instructions: this.decodeInstructions(instructionsString),
      iterations: iterations,
      start: this.decodeStart(startString),
      needsReparse: true,
      needsRedraw: true
    };
  },
  decodeRules: function (rulesString) {
    var rulesList = rulesString.split(',');
    return rulesList.reduce(function (rules, ruleString) {
      var splitRule = ruleString.split(':');
      var predecessor = splitRule[0];
      var successor = splitRule[1].split('');
      rules[predecessor] = successor;

      return rules;
    }, {});
  },
  decodeInstructions: function (instructionsString) {
    var instructionsList = instructionsString.split(';');
    return instructionsList.reduce(function (instructions, instructionParamString) {
      var instructionParams = instructionParamString.split(',');
      var instructionName = instructionParams.shift();

      // decode instruction params
      instructions[instructionName] = instructionParams.reduce(function (params, paramString) {
        var keyChar = paramString[0];
        var keyLookup = {
          'd':'distance',
          'a':'angle',
          'o':'pop',
          'u':'push'
        };
        var key = keyLookup[keyChar];
        var value = parseFloat(paramString.substr(1));
        params[key] = value;
        return params;
      }, {});

      return instructions;
    }, {});
  },
  decodeStart: function (startString) {
    var startList = startString.split(',');
    return startList.reduce(function (params, paramString) {
      var keyChar = paramString[0];
      var keyLookup = {
        'x':'x',
        'y':'y',
        'a':'angle',
        'i':'iterations'
      };
      var key = keyLookup[keyChar];
      var valueLookup = {
        'm':'middle',
        'w':'width',
        'h':'height'
      };
      var valueString = paramString.substr(1);
      var value;
      if ((String(valueString) === valueString) &&
          (valueLookup.hasOwnProperty(valueString))) {
        value = valueLookup[valueString];
      } else {
        value = parseFloat(valueString);
      }
      params[key] = value;
      return params;
    }, {});
  },
  encodeHash: function () {
  },

  // *** PARSING ***
  parseRules: function (rules, axiom, max_iter) {
    var generatedOutput = [axiom];
    var input = axiom;
    for (var i = 0; i < max_iter; i++) {
      var generated = input.reduce(function(output, char) {
        result = (rules[char] !== undefined) ? rules[char] : char;
        return output.concat(result);
      }, []);
      generatedOutput.push(generated);
      input = generated.concat();
    }
    return generatedOutput;
  },

  // *** UI ***
  ui: function(context, updateFunction, data) {
    var inputCollection = document.getElementsByTagName('input');
    var update = updateFunction.bind(context);
    var inputs = [];
    var i = inputCollection.length;
    while(i--) {
      inputs.push(inputCollection[i]);
    }
    inputs.map(function(input) {
      var splitInput = input.id.split('-');
      var type = splitInput[0];
      var param = splitInput[1];
      switch (type) {
        case 'initial':
          input.value = data.start[param];
          break;
      }
      input.addEventListener("input", function(event) {
        switch(type) {
          case 'initial':
            data.start[param] = parseInt(event.currentTarget.value);
            data.needsRedraw = true;
            break;
        }
        update();
      });
    });
  },

  // *** DRAWING ***
  draw: function (canvas, start, rules, instructions) {
    var ctx = canvas.getContext('2d');
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 1;
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    console.log('start x', start.x);

    var x;
    switch (start.x) {
      case 'middle':
        x = canvas.width/2;
        break;
      case 'width':
        x = canvas.width;
        break;
      default:
        x = start.x;
        break;
    }

    var y;
    switch (start.y) {
      case 'middle':
        y = canvas.height/2;
        break;
      case 'height':
        y = canvas.height;
        break;
      default:
        y = start.y;
        break;
    }
    var angle = start.angle;
    var stack = [];
    var forward = 5;
    var radians = Math.PI/180;
    ctx.moveTo(x,y);
    ctx.beginPath();
    for (var i = 0, len = rules.length; i < len; i++) {
      var rule = rules[i];
      if (instructions.hasOwnProperty(rule)) {
        var instruction = instructions[rule];
        if (instruction.hasOwnProperty('angle')) {
          angle += instruction.angle;
        }
        if (instruction.hasOwnProperty('distance')) {
          forward = instruction.distance;
          x += Math.cos(angle * radians) * forward;
          y += Math.sin(angle * radians) * forward;
          ctx.lineTo(x, y);
        }
        if (instruction.hasOwnProperty('push')) {
          stack.push({angle: angle, x: x, y: y});
        }
        if (instruction.hasOwnProperty('pop')) {
          var settings = stack.pop();
          angle = settings.angle;
          x = settings.x;
          y = settings.x;
          ctx.moveTo(x, y);
        }
      }
    }
    ctx.stroke();
    ctx.closePath();
  }
};

var data = LS.decodeHash();
// console.log(data);
var rules = LS.parseRules(data.rules, data.axiom, data.iterations);
var canvas = document.getElementById('canvas');

// var stringRules = rules.map(function(item) {
//   return item.join('');
// });
// console.table(stringRules);

var update = function() {
  if (data.needsRedraw) {
    console.log('update');
    var iterations = Math.min(rules.length - 1, data.start.iterations);
    console.log(iterations);
    LS.draw(canvas, data.start, rules[iterations], data.instructions);
    requestAnimationFrame(update);
    data.needsRedraw = false;
  }
}

LS.ui(this, update, data);

requestAnimationFrame(update);
<commit_msg>remove middle, width, and height string values for x and y start positions<commit_after>var LS = {
  // *** DATA ***
  /*
    decode / encode  data to URL hash

    hash is split into the following sections delimited by '/'
    1. axiom
      example: F[A]
      chars: [A-Z]\[\]
    2. rules
      example: F:F+[F-FF]F+
      chars: [A-Z]\[\]\:\+\-
    3. instructions - delimited by ';' then split into parameters: distance(d), angle(d), push(u)/pop(o)
      example: F,d10,a25,u;A,d5,a10
      chars: [0-9],\.up
    4. iterations - max number of iterations
      example: 3
      chars: [0-9]
    5. starting drawing values - delimited by ',' : x, y, angle, iteration to display
      example: x500,y300,a10
      chars: [0-9]xyamwh
  */
  decodeHash: function () {
    var dataStrings = window.location.hash.substr(1).split('/');
    var axiomString = dataStrings[0];
    var rulesString = dataStrings[1];
    var instructionsString = dataStrings[2];
    var iterations = dataStrings[3];
    var startString = dataStrings[4];
    return {
      axiom: axiomString.split(''),
      rules: this.decodeRules(rulesString),
      instructions: this.decodeInstructions(instructionsString),
      iterations: iterations,
      start: this.decodeStart(startString),
      needsReparse: true,
      needsRedraw: true
    };
  },
  decodeRules: function (rulesString) {
    var rulesList = rulesString.split(',');
    return rulesList.reduce(function (rules, ruleString) {
      var splitRule = ruleString.split(':');
      var predecessor = splitRule[0];
      var successor = splitRule[1].split('');
      rules[predecessor] = successor;

      return rules;
    }, {});
  },
  decodeInstructions: function (instructionsString) {
    var instructionsList = instructionsString.split(';');
    return instructionsList.reduce(function (instructions, instructionParamString) {
      var instructionParams = instructionParamString.split(',');
      var instructionName = instructionParams.shift();

      // decode instruction params
      instructions[instructionName] = instructionParams.reduce(function (params, paramString) {
        var keyChar = paramString[0];
        var keyLookup = {
          'd':'distance',
          'a':'angle',
          'o':'pop',
          'u':'push'
        };
        var key = keyLookup[keyChar];
        var value = parseFloat(paramString.substr(1));
        params[key] = value;
        return params;
      }, {});

      return instructions;
    }, {});
  },
  decodeStart: function (startString) {
    var startList = startString.split(',');
    return startList.reduce(function (params, paramString) {
      var keyChar = paramString[0];
      var keyLookup = {
        'x':'x',
        'y':'y',
        'a':'angle',
        'i':'iterations'
      };
      var key = keyLookup[keyChar];
      var value = parseFloat(paramString.substr(1));
      params[key] = value;
      return params;
    }, {});
  },
  encodeHash: function () {
  },

  // *** PARSING ***
  parseRules: function (rules, axiom, max_iter) {
    var generatedOutput = [axiom];
    var input = axiom;
    for (var i = 0; i < max_iter; i++) {
      var generated = input.reduce(function(output, char) {
        result = (rules[char] !== undefined) ? rules[char] : char;
        return output.concat(result);
      }, []);
      generatedOutput.push(generated);
      input = generated.concat();
    }
    return generatedOutput;
  },

  // *** UI ***
  ui: function(context, updateFunction, data) {
    var inputCollection = document.getElementsByTagName('input');
    var update = updateFunction.bind(context);
    var inputs = [];
    var i = inputCollection.length;
    while(i--) {
      inputs.push(inputCollection[i]);
    }
    inputs.map(function(input) {
      var splitInput = input.id.split('-');
      var type = splitInput[0];
      var param = splitInput[1];
      switch (type) {
        case 'initial':
          input.value = data.start[param];
          break;
      }
      input.addEventListener("input", function(event) {
        switch(type) {
          case 'initial':
            data.start[param] = parseInt(event.currentTarget.value);
            data.needsRedraw = true;
            break;
        }
        update();
      });
    });
  },

  // *** DRAWING ***
  draw: function (canvas, start, rules, instructions) {
    var ctx = canvas.getContext('2d');
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 1;
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    var x = start.x;
    var y = start.y;
    var angle = start.angle;
    var stack = [];
    var forward = 5;
    var radians = Math.PI/180;
    ctx.moveTo(x,y);
    ctx.beginPath();
    for (var i = 0, len = rules.length; i < len; i++) {
      var rule = rules[i];
      if (instructions.hasOwnProperty(rule)) {
        var instruction = instructions[rule];
        if (instruction.hasOwnProperty('angle')) {
          angle += instruction.angle;
        }
        if (instruction.hasOwnProperty('distance')) {
          forward = instruction.distance;
          x += Math.cos(angle * radians) * forward;
          y += Math.sin(angle * radians) * forward;
          ctx.lineTo(x, y);
        }
        if (instruction.hasOwnProperty('push')) {
          stack.push({angle: angle, x: x, y: y});
        }
        if (instruction.hasOwnProperty('pop')) {
          var settings = stack.pop();
          angle = settings.angle;
          x = settings.x;
          y = settings.x;
          ctx.moveTo(x, y);
        }
      }
    }
    ctx.stroke();
    ctx.closePath();
  }
};

var data = LS.decodeHash();
// console.log(data);
var rules = LS.parseRules(data.rules, data.axiom, data.iterations);
var canvas = document.getElementById('canvas');

// var stringRules = rules.map(function(item) {
//   return item.join('');
// });
// console.table(stringRules);

var update = function() {
  if (data.needsRedraw) {
    console.log('update');
    var iterations = Math.min(rules.length - 1, data.start.iterations);
    console.log(iterations);
    LS.draw(canvas, data.start, rules[iterations], data.instructions);
    requestAnimationFrame(update);
    data.needsRedraw = false;
  }
}

LS.ui(this, update, data);

requestAnimationFrame(update);
<|endoftext|>


<commit_before>var gpio = require('rpi-gpio');
var sensorLib = require('node-dht-sensor');
var AM_PIN = 17;
var AM_RESET_PIN = 15;
var readingnumber = 0;
var readingInterval;

console.log("before gpio setup");
//gpio.setup(AM_PIN, gpio.DIR_OUT);
gpio.setup(AM_RESET_PIN, gpio.DIR_OUT, function(err){
  if (err) throw err;
  console.log("Calling amreset");
  amReset();
});
console.log("after gpio setup");

var sensor = {
    initialize: function () {
        return sensorLib.initialize(22, AM_PIN);
    },
    read: function () {
        var readout = sensorLib.read();
        readingnumber++;
        console.log("Reading Number: "+ readingnumber+' Temperature: ' + readout.temperature.toFixed(2) + 'C, ' +
            'humidity: ' + readout.humidity.toFixed(2) + '%');
        // setTimeout(function () {
        //     sensor.read();
        // }, 2000);
    }
};

var amReset = function(){
  console.log("Starting AMRESET")
  gpio.write(AM_RESET_PIN,0,function(err){
    if (err) throw err;
    console.log('RESETTING AM2302');
  });
  setTimeout(function(){
    gpio.write(AM_RESET_PIN,1,function(err){
      if (err) throw err;
      console.log('Power On AM2302');
      setTimeout(startReadings,5000);
    });
  },5000);
}
var startReadings = function(){
  readingInterval = setInterval(function(){
    if(!sensor.initialized){
        console.log("inialize sensor")
      if (sensor.initialize()) {
          sensor.read();
      } else {
          console.warn('Failed to initialize sensor');
          clearInterval(readingInterval);
          amReset();
      }
    }else{
      sensor.read();
    }
  },5000);
}
<commit_msg>updated sensor initialization in am2302test.js<commit_after>var gpio = require('rpi-gpio');
var sensorLib = require('node-dht-sensor');
var AM_PIN = 17;
var AM_RESET_PIN = 15;
var readingnumber = 0;
var readingInterval;

console.log("before gpio setup");
//gpio.setup(AM_PIN, gpio.DIR_OUT);
gpio.setup(AM_RESET_PIN, gpio.DIR_OUT, function(err){
  if (err) throw err;
  console.log("Calling amreset");
  amReset();
});
console.log("after gpio setup");

// var sensor = {
//     initialize: function () {
//         return sensorLib.initialize(22, AM_PIN);
//     },
//     read: function () {
//         var readout = sensorLib.read();
//         readingnumber++;
//         console.log("Reading Number: "+ readingnumber+' Temperature: ' + readout.temperature.toFixed(2) + 'C, ' +
//             'humidity: ' + readout.humidity.toFixed(2) + '%');
//         // setTimeout(function () {
//         //     sensor.read();
//         // }, 2000);
//     }
// };
var sensor = {
    sensors: [ {
        name: "Indoor",
        type: 22,
        pin: AM_PIN
    }],
    read: function() {
        for (var a in this.sensors) {
            var b = sensorLib.readSpec(this.sensors[a].type, this.sensors[a].pin);
            console.log(this.sensors[a].name + ": " +
              b.temperature.toFixed(1) + "C, " +
              b.humidity.toFixed(1) + "%");
        }
        // setTimeout(function() {
        //     sensor.read();
        // }, 2000);
    }
};

var amReset = function(){
  console.log("Starting AMRESET")
  gpio.write(AM_RESET_PIN,0,function(err){
    if (err) throw err;
    console.log('RESETTING AM2302');
  });
  setTimeout(function(){
    gpio.write(AM_RESET_PIN,1,function(err){
      if (err) throw err;
      console.log('Power On AM2302');
      setTimeout(startReadings,5000);
    });
  },5000);
}
var startReadings = function(){
  readingInterval = setInterval(function(){
    sensor.read();
    // if(!sensor.initialized){
    //     console.log("inialize sensor")
    //   if (sensor.initialize()) {
    //       sensor.read();
    //   } else {
    //       console.warn('Failed to initialize sensor');
    //       clearInterval(readingInterval);
    //       amReset();
    //   }
    // }else{
    //   sensor.read();
    // }
  },5000);
}
<|endoftext|>


<commit_before>if ( THREE.LoaderSupport === undefined ) { THREE.LoaderSupport = {} }

/**
 * Validation functions.
 * @class
 */
THREE.LoaderSupport.Validator = {
	/**
	 * If given input is null or undefined, false is returned otherwise true.
	 *
	 * @param input Can be anything
	 * @returns {boolean}
	 */
	isValid: function( input ) {
		return ( input !== null && input !== undefined );
	},
	/**
	 * If given input is null or undefined, the defaultValue is returned otherwise the given input.
	 *
	 * @param input Can be anything
	 * @param defaultValue Can be anything
	 * @returns {*}
	 */
	verifyInput: function( input, defaultValue ) {
		return ( input === null || input === undefined ) ? defaultValue : input;
	}
};

/**
 * Callbacks utilized by loaders and builders.
 * @class
 */
THREE.LoaderSupport.Callbacks = (function () {

	var Validator = THREE.LoaderSupport.Validator;

	function Callbacks() {
		this.onProgress = null;
		this.onMeshAlter = null;
		this.onLoad = null;
		this.onLoadMaterials = null;
	}

	/**
	 * Register callback function that is invoked by internal function "announceProgress" to print feedback.
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnProgress Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnProgress = function ( callbackOnProgress ) {
		this.onProgress = Validator.verifyInput( callbackOnProgress, this.onProgress );
	};

	/**
	 * Register callback function that is called every time a mesh was loaded.
	 * Use {@link THREE.LoaderSupport.LoadedMeshUserOverride} for alteration instructions (geometry, material or disregard mesh).
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnMeshAlter Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnMeshAlter = function ( callbackOnMeshAlter ) {
		this.onMeshAlter = Validator.verifyInput( callbackOnMeshAlter, this.onMeshAlter );
	};

	/**
	 * Register callback function that is called once loading of the complete OBJ file is completed.
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnLoad Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnLoad = function ( callbackOnLoad ) {
		this.onLoad = Validator.verifyInput( callbackOnLoad, this.onLoad );
	};

	/**
	 * Register callback function that is called when materials have been loaded.
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnLoadMaterials Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnLoadMaterials = function ( callbackOnLoadMaterials ) {
		this.onLoadMaterials = Validator.verifyInput( callbackOnLoadMaterials, this.onLoadMaterials );
	};

	return Callbacks;
})();

/**
 * Object to return by callback onMeshAlter. Used to disregard a certain mesh or to return one to many meshes.
 * @class
 *
 * @param {boolean} disregardMesh=false Tell implementation to completely disregard this mesh
 * @param {boolean} disregardMesh=false Tell implementation that mesh(es) have been altered or added
 */
THREE.LoaderSupport.LoadedMeshUserOverride = (function () {

	function LoadedMeshUserOverride( disregardMesh, alteredMesh ) {
		this.disregardMesh = disregardMesh === true;
		this.alteredMesh = alteredMesh === true;
		this.meshes = [];
	}

	/**
	 * Add a mesh created within callback.
	 *
	 * @memberOf THREE.OBJLoader2.LoadedMeshUserOverride
	 *
	 * @param {THREE.Mesh} mesh
	 */
	LoadedMeshUserOverride.prototype.addMesh = function ( mesh ) {
		this.meshes.push( mesh );
		this.alteredMesh = true;
	};

	/**
	 * Answers if mesh shall be disregarded completely.
	 *
	 * @returns {boolean}
	 */
	LoadedMeshUserOverride.prototype.isDisregardMesh = function () {
		return this.disregardMesh;
	};

	/**
	 * Answers if new mesh(es) were created.
	 *
	 * @returns {boolean}
	 */
	LoadedMeshUserOverride.prototype.providesAlteredMeshes = function () {
		return this.alteredMesh;
	};

	return LoadedMeshUserOverride;
})();

/**
 * A resource description used by {@link THREE.LoaderSupport.PrepData} and others.
 * @class
 *
 * @param {string} url URL to the file
 * @param {string} extension The file extension (type)
 */
THREE.LoaderSupport.ResourceDescriptor = (function () {

	var Validator = THREE.LoaderSupport.Validator;

	function ResourceDescriptor( url, extension ) {
		var urlParts = url.split( '/' );

		if ( urlParts.length < 2 ) {

			this.path = null;
			this.name = url;
			this.url = url;

		} else {

			this.path = Validator.verifyInput( urlParts.slice( 0, urlParts.length - 1).join( '/' ) + '/', null );
			this.name = Validator.verifyInput( urlParts[ urlParts.length - 1 ], null );
			this.url = url;

		}
		this.extension = Validator.verifyInput( extension, "default" );
		this.extension = this.extension.trim();
		this.content = null;
	}

	/**
	 * Set the content of this resource
	 * @memberOf THREE.LoaderSupport.ResourceDescriptor
	 *
	 * @param {Object} content The file content as arraybuffer or text
	 */
	ResourceDescriptor.prototype.setContent = function ( content ) {
		this.content = Validator.verifyInput( content, null );
	};

	return ResourceDescriptor;
})();

/**
 * Configuration instructions to be used by run method.
 * @class
 */
THREE.LoaderSupport.PrepData = (function () {

	var Validator = THREE.LoaderSupport.Validator;

	function PrepData( modelName ) {
		this.logging = {
			enabled: true,
			debug: false
		};
		this.modelName = Validator.verifyInput( modelName, '' );
		this.resources = [];
		this.callbacks = new THREE.LoaderSupport.Callbacks();
	}

	/**
	 * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @param {boolean} enabled True or false.
	 * @param {boolean} debug True or false.
	 */
	PrepData.prototype.setLogging = function ( enabled, debug ) {
		this.logging.enabled = enabled === true;
		this.logging.debug = debug === true;
	};

	/**
	 * Returns all callbacks as {@link THREE.LoaderSupport.Callbacks}
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @returns {THREE.LoaderSupport.Callbacks}
	 */
	PrepData.prototype.getCallbacks = function () {
		return this.callbacks;
	};

	/**
	 * Add a resource description.
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @param {THREE.LoaderSupport.ResourceDescriptor} Adds a {@link THREE.LoaderSupport.ResourceDescriptor}
	 */
	PrepData.prototype.addResource = function ( resource ) {
		this.resources.push( resource );
	};

	/**
	 * Clones this object and returns it afterwards. Callbacks and resources are not cloned deep (references!).
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @returns {@link THREE.LoaderSupport.PrepData}
	 */
	PrepData.prototype.clone = function () {
		var clone = new THREE.LoaderSupport.PrepData( this.modelName );
		clone.logging.enabled = this.logging.enabled;
		clone.logging.debug = this.logging.debug;
		clone.resources = this.resources;
		clone.callbacks = this.callbacks;

		var property, value;
		for ( property in this ) {

			value = this[ property ];
			if ( ! clone.hasOwnProperty( property ) && typeof this[ property ] !== 'function' ) {

				clone[ property ] = value;

			}
		}

		return clone;
	};

	/**
	 * Identify files or content of interest from an Array of {@link THREE.LoaderSupport.ResourceDescriptor}.
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @param {THREE.LoaderSupport.ResourceDescriptor[]} resources Array of {@link THREE.LoaderSupport.ResourceDescriptor}
	 * @param Object fileDesc Object describing which resources are of interest (ext, type (string or UInt8Array) and ignore (boolean))
	 * @returns {{}} Object with each "ext" and the corresponding {@link THREE.LoaderSupport.ResourceDescriptor}
	 */
	PrepData.prototype.checkResourceDescriptorFiles = function ( resources, fileDesc ) {
		var resource, triple, i, found;
		var result = {};

		for ( var index in resources ) {

			resource = resources[ index ];
			found = false;
			if ( ! Validator.isValid( resource.name ) ) continue;
			if ( Validator.isValid( resource.content ) ) {

				for ( i = 0; i < fileDesc.length && !found; i++ ) {

					triple = fileDesc[ i ];
					if ( resource.extension.toLowerCase() === triple.ext.toLowerCase() ) {

						if ( triple.ignore ) {

							found = true;

						} else if ( triple.type === "ArrayBuffer" ) {

							// fast-fail on bad type
							if ( ! ( resource.content instanceof ArrayBuffer || resource.content instanceof Uint8Array ) ) throw 'Provided content is not of type ArrayBuffer! Aborting...';
							result[ triple.ext ] = resource;
							found = true;

						} else if ( triple.type === "String" ) {

							if ( ! ( typeof( resource.content ) === 'string' || resource.content instanceof String) ) throw 'Provided  content is not of type String! Aborting...';
							result[ triple.ext ] = resource;
							found = true;

						}

					}

				}
				if ( !found ) throw 'Unidentified resource "' + resource.name + '": ' + resource.url;

			} else {

				// fast-fail on bad type
				if ( ! ( typeof( resource.name ) === 'string' || resource.name instanceof String ) ) throw 'Provided file is not properly defined! Aborting...';
				for ( i = 0; i < fileDesc.length && !found; i++ ) {

					triple = fileDesc[ i ];
					if ( resource.extension.toLowerCase() === triple.ext.toLowerCase() ) {

						if ( ! triple.ignore ) result[ triple.ext ] = resource;
						found = true;

					}

				}
				if ( !found ) throw 'Unidentified resource "' + resource.name + '": ' + resource.url;

			}
		}

		return result;
	};

	return PrepData;
})();
<commit_msg>Ensure name of THREE.LoaderSupport.ResourceDescriptor always has a default name.<commit_after>if ( THREE.LoaderSupport === undefined ) { THREE.LoaderSupport = {} }

/**
 * Validation functions.
 * @class
 */
THREE.LoaderSupport.Validator = {
	/**
	 * If given input is null or undefined, false is returned otherwise true.
	 *
	 * @param input Can be anything
	 * @returns {boolean}
	 */
	isValid: function( input ) {
		return ( input !== null && input !== undefined );
	},
	/**
	 * If given input is null or undefined, the defaultValue is returned otherwise the given input.
	 *
	 * @param input Can be anything
	 * @param defaultValue Can be anything
	 * @returns {*}
	 */
	verifyInput: function( input, defaultValue ) {
		return ( input === null || input === undefined ) ? defaultValue : input;
	}
};

/**
 * Callbacks utilized by loaders and builders.
 * @class
 */
THREE.LoaderSupport.Callbacks = (function () {

	var Validator = THREE.LoaderSupport.Validator;

	function Callbacks() {
		this.onProgress = null;
		this.onMeshAlter = null;
		this.onLoad = null;
		this.onLoadMaterials = null;
	}

	/**
	 * Register callback function that is invoked by internal function "announceProgress" to print feedback.
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnProgress Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnProgress = function ( callbackOnProgress ) {
		this.onProgress = Validator.verifyInput( callbackOnProgress, this.onProgress );
	};

	/**
	 * Register callback function that is called every time a mesh was loaded.
	 * Use {@link THREE.LoaderSupport.LoadedMeshUserOverride} for alteration instructions (geometry, material or disregard mesh).
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnMeshAlter Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnMeshAlter = function ( callbackOnMeshAlter ) {
		this.onMeshAlter = Validator.verifyInput( callbackOnMeshAlter, this.onMeshAlter );
	};

	/**
	 * Register callback function that is called once loading of the complete OBJ file is completed.
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnLoad Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnLoad = function ( callbackOnLoad ) {
		this.onLoad = Validator.verifyInput( callbackOnLoad, this.onLoad );
	};

	/**
	 * Register callback function that is called when materials have been loaded.
	 * @memberOf THREE.LoaderSupport.Callbacks
	 *
	 * @param {callback} callbackOnLoadMaterials Callback function for described functionality
	 */
	Callbacks.prototype.setCallbackOnLoadMaterials = function ( callbackOnLoadMaterials ) {
		this.onLoadMaterials = Validator.verifyInput( callbackOnLoadMaterials, this.onLoadMaterials );
	};

	return Callbacks;
})();

/**
 * Object to return by callback onMeshAlter. Used to disregard a certain mesh or to return one to many meshes.
 * @class
 *
 * @param {boolean} disregardMesh=false Tell implementation to completely disregard this mesh
 * @param {boolean} disregardMesh=false Tell implementation that mesh(es) have been altered or added
 */
THREE.LoaderSupport.LoadedMeshUserOverride = (function () {

	function LoadedMeshUserOverride( disregardMesh, alteredMesh ) {
		this.disregardMesh = disregardMesh === true;
		this.alteredMesh = alteredMesh === true;
		this.meshes = [];
	}

	/**
	 * Add a mesh created within callback.
	 *
	 * @memberOf THREE.OBJLoader2.LoadedMeshUserOverride
	 *
	 * @param {THREE.Mesh} mesh
	 */
	LoadedMeshUserOverride.prototype.addMesh = function ( mesh ) {
		this.meshes.push( mesh );
		this.alteredMesh = true;
	};

	/**
	 * Answers if mesh shall be disregarded completely.
	 *
	 * @returns {boolean}
	 */
	LoadedMeshUserOverride.prototype.isDisregardMesh = function () {
		return this.disregardMesh;
	};

	/**
	 * Answers if new mesh(es) were created.
	 *
	 * @returns {boolean}
	 */
	LoadedMeshUserOverride.prototype.providesAlteredMeshes = function () {
		return this.alteredMesh;
	};

	return LoadedMeshUserOverride;
})();

/**
 * A resource description used by {@link THREE.LoaderSupport.PrepData} and others.
 * @class
 *
 * @param {string} url URL to the file
 * @param {string} extension The file extension (type)
 */
THREE.LoaderSupport.ResourceDescriptor = (function () {

	var Validator = THREE.LoaderSupport.Validator;

	function ResourceDescriptor( url, extension ) {
		var urlParts = url.split( '/' );

		if ( urlParts.length < 2 ) {

			this.path = null;
			this.name = url;
			this.url = url;

		} else {

			this.path = Validator.verifyInput( urlParts.slice( 0, urlParts.length - 1).join( '/' ) + '/', null );
			this.name = Validator.verifyInput( urlParts[ urlParts.length - 1 ], 'Unnamed_Resource' );
			this.url = url;

		}
		this.extension = Validator.verifyInput( extension, "default" );
		this.extension = this.extension.trim();
		this.content = null;
	}

	/**
	 * Set the content of this resource
	 * @memberOf THREE.LoaderSupport.ResourceDescriptor
	 *
	 * @param {Object} content The file content as arraybuffer or text
	 */
	ResourceDescriptor.prototype.setContent = function ( content ) {
		this.content = Validator.verifyInput( content, null );
	};

	return ResourceDescriptor;
})();

/**
 * Configuration instructions to be used by run method.
 * @class
 */
THREE.LoaderSupport.PrepData = (function () {

	var Validator = THREE.LoaderSupport.Validator;

	function PrepData( modelName ) {
		this.logging = {
			enabled: true,
			debug: false
		};
		this.modelName = Validator.verifyInput( modelName, '' );
		this.resources = [];
		this.callbacks = new THREE.LoaderSupport.Callbacks();
	}

	/**
	 * Enable or disable logging in general (except warn and error), plus enable or disable debug logging.
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @param {boolean} enabled True or false.
	 * @param {boolean} debug True or false.
	 */
	PrepData.prototype.setLogging = function ( enabled, debug ) {
		this.logging.enabled = enabled === true;
		this.logging.debug = debug === true;
	};

	/**
	 * Returns all callbacks as {@link THREE.LoaderSupport.Callbacks}
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @returns {THREE.LoaderSupport.Callbacks}
	 */
	PrepData.prototype.getCallbacks = function () {
		return this.callbacks;
	};

	/**
	 * Add a resource description.
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @param {THREE.LoaderSupport.ResourceDescriptor} Adds a {@link THREE.LoaderSupport.ResourceDescriptor}
	 */
	PrepData.prototype.addResource = function ( resource ) {
		this.resources.push( resource );
	};

	/**
	 * Clones this object and returns it afterwards. Callbacks and resources are not cloned deep (references!).
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @returns {@link THREE.LoaderSupport.PrepData}
	 */
	PrepData.prototype.clone = function () {
		var clone = new THREE.LoaderSupport.PrepData( this.modelName );
		clone.logging.enabled = this.logging.enabled;
		clone.logging.debug = this.logging.debug;
		clone.resources = this.resources;
		clone.callbacks = this.callbacks;

		var property, value;
		for ( property in this ) {

			value = this[ property ];
			if ( ! clone.hasOwnProperty( property ) && typeof this[ property ] !== 'function' ) {

				clone[ property ] = value;

			}
		}

		return clone;
	};

	/**
	 * Identify files or content of interest from an Array of {@link THREE.LoaderSupport.ResourceDescriptor}.
	 * @memberOf THREE.LoaderSupport.PrepData
	 *
	 * @param {THREE.LoaderSupport.ResourceDescriptor[]} resources Array of {@link THREE.LoaderSupport.ResourceDescriptor}
	 * @param Object fileDesc Object describing which resources are of interest (ext, type (string or UInt8Array) and ignore (boolean))
	 * @returns {{}} Object with each "ext" and the corresponding {@link THREE.LoaderSupport.ResourceDescriptor}
	 */
	PrepData.prototype.checkResourceDescriptorFiles = function ( resources, fileDesc ) {
		var resource, triple, i, found;
		var result = {};

		for ( var index in resources ) {

			resource = resources[ index ];
			found = false;
			if ( ! Validator.isValid( resource.name ) ) continue;
			if ( Validator.isValid( resource.content ) ) {

				for ( i = 0; i < fileDesc.length && !found; i++ ) {

					triple = fileDesc[ i ];
					if ( resource.extension.toLowerCase() === triple.ext.toLowerCase() ) {

						if ( triple.ignore ) {

							found = true;

						} else if ( triple.type === "ArrayBuffer" ) {

							// fast-fail on bad type
							if ( ! ( resource.content instanceof ArrayBuffer || resource.content instanceof Uint8Array ) ) throw 'Provided content is not of type ArrayBuffer! Aborting...';
							result[ triple.ext ] = resource;
							found = true;

						} else if ( triple.type === "String" ) {

							if ( ! ( typeof( resource.content ) === 'string' || resource.content instanceof String) ) throw 'Provided  content is not of type String! Aborting...';
							result[ triple.ext ] = resource;
							found = true;

						}

					}

				}
				if ( !found ) throw 'Unidentified resource "' + resource.name + '": ' + resource.url;

			} else {

				// fast-fail on bad type
				if ( ! ( typeof( resource.name ) === 'string' || resource.name instanceof String ) ) throw 'Provided file is not properly defined! Aborting...';
				for ( i = 0; i < fileDesc.length && !found; i++ ) {

					triple = fileDesc[ i ];
					if ( resource.extension.toLowerCase() === triple.ext.toLowerCase() ) {

						if ( ! triple.ignore ) result[ triple.ext ] = resource;
						found = true;

					}

				}
				if ( !found ) throw 'Unidentified resource "' + resource.name + '": ' + resource.url;

			}
		}

		return result;
	};

	return PrepData;
})();
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015-2016 Orange
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
angular.module('sandbox').controller('home', function ($scope, $http) {
    $scope.showprogressbar = true;
    $scope.connectionPhrase = "";
    $scope.messageTitle = 'Please wait...';
    $scope.messageBody = 'We\'re setting up the Cloud Foundry platform with a private space.';
    $scope.showConnectionDetails = false;

    $http.get('v1/sandboxes/me').success(function (data) {
            $scope.showprogressbar = false;
            $scope.connectionPhrase = "cf login --skip-ssl-validation -a " + data.apiUrl + " -u " + data.spaceName + " -o " + data.orgName + " -s " + data.spaceName;
            $scope.sandbox = data;
            $scope.messageTitle = "You're all set.";
            $scope.messageBody = "You're all set to discover the Cloud Foundry platform: a private space is now allocated to you for playing and trying things out.";
            $scope.showConnectionDetails = true;
        })
        .error(function (error) {
            $scope.showprogressbar = false;
            $scope.messageTitle = "Sorry, something goes wrong.";
            $scope.messageBody = "Error: " + error;
            Materialize.toast("Try again or contact your administrator !", 5000, 'rounded');
            jQuery('#toast-container').click(function(){
                jQuery(this).remove();
            });
        });
    $scope.showMessageCopied = function () {
        Materialize.toast('Copied !', 2000);
    };

});<commit_msg>Fix error message<commit_after>/*
 * Copyright (C) 2015-2016 Orange
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
angular.module('sandbox').controller('home', function ($scope, $http) {
    $scope.showprogressbar = true;
    $scope.connectionPhrase = "";
    $scope.messageTitle = 'Please wait...';
    $scope.messageBody = 'We\'re setting up the Cloud Foundry platform with a private space.';
    $scope.showConnectionDetails = false;

    $http.get('v1/sandboxes/me').success(function (data) {
            $scope.showprogressbar = false;
            $scope.connectionPhrase = "cf login --skip-ssl-validation -a " + data.apiUrl + " -u " + data.spaceName + " -o " + data.orgName + " -s " + data.spaceName;
            $scope.sandbox = data;
            $scope.messageTitle = "You're all set.";
            $scope.messageBody = "You're all set to discover the Cloud Foundry platform: a private space is now allocated to you for playing and trying things out.";
            $scope.showConnectionDetails = true;
        })
        .error(function (error) {
            $scope.showprogressbar = false;
            $scope.messageTitle = "Sorry, something goes wrong.";
            $scope.messageBody = "Error: " + error.message;
            Materialize.toast("Try again or contact your administrator !", 5000, 'rounded');
            jQuery('#toast-container').click(function(){
                jQuery(this).remove();
            });
        });
    $scope.showMessageCopied = function () {
        Materialize.toast('Copied !', 2000);
    };

});
<|endoftext|>