<commit_before>const SuperPlug = require('superplug')
const http = require('../http')
const getFromObject = require('../utils/getFromObject')
const debug = require('debug')('genie-router:plugins/Loader')
const path = require('path')
const os = require('os')
const Promise = require('bluebird')
const stat = Promise.promisify(require('fs').stat)
const mkdir = Promise.promisify(require('fs').mkdir)
const writeFile = Promise.promisify(require('fs').writeFile)
const npmUtils = require('npm-utils')
const express = require('express')

class Loader
{
  constructor (config, clientStartObjectGenerator, brainSelector, eventEmitter) {
    this.config = config
    this.plugins = {}
    this.clients = {}
    this.clientStartObjectGenerator = clientStartObjectGenerator
    this.brainSelector = brainSelector
    this.eventEmitter = eventEmitter
  }

  setHttpEnabled (value) {
    this.httpEnabled = value
  }

  /**
   * Returns a promise that resolves when all plugins are loaded.
   * @return {Promise}
   */
  startPlugins () {
    return this._getPluginStoreLocation()
      .then((location) => {
        this.location = location
        return stat(path.join(location, 'node_modules'))
      })
      .catch((err) => {
        if (err.code === 'ENOENT') {
          return this._npmInstall()
        }
        throw err
      })
      .then(() => {
        this._superPlug = new SuperPlug({
          location: this.location,
          packageProperty: 'genieRouterPlugin'
        })
      })
      .then(this._loadPlugins.bind(this))
      .then(this._startPlugins.bind(this))
  }

  /**
   * If this a configured path, make sure we can access it, if it is the default, create it if it does not exists.
   * @return Promise
   */
  _getPluginStoreLocation () {
    const configuredPath = getFromObject(this.config, 'pluginStore.location', false)
    if (configuredPath) {
      debug('Found configured path', configuredPath)
      return this._checkConfiguredPath(configuredPath)
    } else {
      return this._useDefaultConfigurationPath()
    }
  }

  /**
   * Make sure that we can access the configured path.
   * @return Promise
   */
  _checkConfiguredPath (configuredPath) {
    return stat(configuredPath)
      .then((result) => {
        if (result.isDirectory()) {
          return configuredPath
        }
        throw new Error('Configured pluginStore location is not a directory.')
      })
      .then(this._checkPluginLocation)
  }

  /**
   * Check if the default configuration path ($HOME/.genie-router) exists,
   * if not, create it.
   */
  _useDefaultConfigurationPath () {
    const defaultPath = path.join(os.homedir(), '.genie-router')
    return stat(defaultPath)
      .then((result) => {
        debug(defaultPath, 'found')
        if (!result.isDirectory()) {
          throw new Error(defaultPath + ' exists, but is not a directory')
        }
        return defaultPath
      })
      .catch((err) => {
        if (err.code === 'ENOENT') {
          debug(defaultPath, 'did not exist.')
          // Attempt to create the folder
          return mkdir(defaultPath)
            .then(() => {
              debug('Created', defaultPath)
              return defaultPath
            })
        } else {
          throw err
        }
      })
      .then(this._checkPluginLocation)
  }

  _checkPluginLocation (pluginPath) {
    debug('Checking if ' + pluginPath + '/package.json exists')

    return stat(path.join(pluginPath, 'package.json'))
      .then((statResult) => {
        if (statResult.isFile()) {
          debug('Found package.json in ', pluginPath)
          return pluginPath // It exists, we can return the Promise
        }
        throw new Error(pluginPath + '/package.json is not a file.')
      })
      .catch((err) => {
        if (err.code !== 'ENOENT') {
          throw err
        }

        // Create package.json
        debug('Creating package.json in folder', pluginPath)
        return writeFile(
          path.join(pluginPath, 'package.json'),
          JSON.stringify({
            name: 'genie-router-plugins',
            dependencies: { // Default dependencies
              'genie-router-cli-local': 'github:matueranet/genie-router-plugin-cli-local',
              'genie-router-plugin-echo': 'github:matueranet/genie-router-plugin-echo'
            }
          })
        )
      })
      .then(() => {
        return pluginPath
      })
  }

  getClients () {
    return this.clients
  }

  _startPlugins () {
    const plugins = Object.keys(this.plugins)
    debug('Found plugins: ', plugins)
    let promises = []
    let brains = {}
    plugins.forEach((pluginName) => {
      const config = getFromObject(this.config, 'plugins.' + pluginName)
      const plugin = this.plugins[pluginName]
      if (plugin.brain) {
        promises.push(
          this.plugins[pluginName].brain.start(config)
          .then((brain) => {
            brains[pluginName] = brain
          })
        )
      }
      if (plugin.client) {
        // thing here is that the startObject needs the speak function, which
        // is only available after the start function has been invoked. Needed
        // some trickery to make it work.
        const startObject = this.clientStartObjectGenerator(pluginName, plugin)
        promises.push(
          this.plugins[pluginName].client.start(
            config,
            startObject
          ).then((client) => {
            this.clients[pluginName] = client
          })
        )
      }
      if (plugin.brainSelector) {
        promises.push(
          this.plugins[pluginName].brainSelector.start(config)
          .then((brainSelector) => {
            this.brainSelector.use(pluginName, brainSelector)
          })
        )
      }
      if (plugin.http) {
        if (!this.httpEnabled) {
          console.log('HTTP is not enabled, Ignoring http component of plugin', pluginName)
        } else {
          promises.push(
            http()
              .then((app) => {
                return this.plugins[pluginName].http.start(config, app, express)
              })
          )
        }
      }
      if (plugin.listener) {
        promises.push(
          this.plugins[pluginName].listener.start(config, this.eventEmitter)
        )
      }
    })
    return Promise.all(promises)
      .then(() => {
        this.brainSelector.setBrains(brains)
      })
  }

  _loadPlugins () {
    return this._superPlug.getPlugins()
      .then((foundPlugins) => {
        let promises = []
        for (var iter in foundPlugins) {
          let foundPlugin = foundPlugins[iter]
          // Only load the plugins which have a configuration
          if (getFromObject(this.config, 'plugins.' + foundPlugin.getName()) !== undefined) {
            const p = foundPlugin.getPlugin()
            p.then((pluginModule) => {
              this.plugins[foundPlugin.getName()] = pluginModule
            })
            promises.push(p)
          }
        }
        return Promise.all(promises)
      })
  }

  /**
   * Runs 'npm install' without a module name, so that the modules are installed/updated.
   * @return Promise
   */
  _npmInstall () {
    const cwd = process.cwd()
    process.chdir(this.location)
    return npmUtils.install({
      name: '',
      flags: ['--quiet', '--production']
    })
      .then(() => {
        // move back to the old current dir
        process.chdir(cwd)
      })
  }
}

module.exports = Loader
<commit_msg>Added the brain-mentions plugin as a default plugin.<commit_after>const SuperPlug = require('superplug')
const http = require('../http')
const getFromObject = require('../utils/getFromObject')
const debug = require('debug')('genie-router:plugins/Loader')
const path = require('path')
const os = require('os')
const Promise = require('bluebird')
const stat = Promise.promisify(require('fs').stat)
const mkdir = Promise.promisify(require('fs').mkdir)
const writeFile = Promise.promisify(require('fs').writeFile)
const npmUtils = require('npm-utils')
const express = require('express')

class Loader
{
  constructor (config, clientStartObjectGenerator, brainSelector, eventEmitter) {
    this.config = config
    this.plugins = {}
    this.clients = {}
    this.clientStartObjectGenerator = clientStartObjectGenerator
    this.brainSelector = brainSelector
    this.eventEmitter = eventEmitter
  }

  setHttpEnabled (value) {
    this.httpEnabled = value
  }

  /**
   * Returns a promise that resolves when all plugins are loaded.
   * @return {Promise}
   */
  startPlugins () {
    return this._getPluginStoreLocation()
      .then((location) => {
        this.location = location
        return stat(path.join(location, 'node_modules'))
      })
      .catch((err) => {
        if (err.code === 'ENOENT') {
          return this._npmInstall()
        }
        throw err
      })
      .then(() => {
        this._superPlug = new SuperPlug({
          location: this.location,
          packageProperty: 'genieRouterPlugin'
        })
      })
      .then(this._loadPlugins.bind(this))
      .then(this._startPlugins.bind(this))
  }

  /**
   * If this a configured path, make sure we can access it, if it is the default, create it if it does not exists.
   * @return Promise
   */
  _getPluginStoreLocation () {
    const configuredPath = getFromObject(this.config, 'pluginStore.location', false)
    if (configuredPath) {
      debug('Found configured path', configuredPath)
      return this._checkConfiguredPath(configuredPath)
    } else {
      return this._useDefaultConfigurationPath()
    }
  }

  /**
   * Make sure that we can access the configured path.
   * @return Promise
   */
  _checkConfiguredPath (configuredPath) {
    return stat(configuredPath)
      .then((result) => {
        if (result.isDirectory()) {
          return configuredPath
        }
        throw new Error('Configured pluginStore location is not a directory.')
      })
      .then(this._checkPluginLocation)
  }

  /**
   * Check if the default configuration path ($HOME/.genie-router) exists,
   * if not, create it.
   */
  _useDefaultConfigurationPath () {
    const defaultPath = path.join(os.homedir(), '.genie-router')
    return stat(defaultPath)
      .then((result) => {
        debug(defaultPath, 'found')
        if (!result.isDirectory()) {
          throw new Error(defaultPath + ' exists, but is not a directory')
        }
        return defaultPath
      })
      .catch((err) => {
        if (err.code === 'ENOENT') {
          debug(defaultPath, 'did not exist.')
          // Attempt to create the folder
          return mkdir(defaultPath)
            .then(() => {
              debug('Created', defaultPath)
              return defaultPath
            })
        } else {
          throw err
        }
      })
      .then(this._checkPluginLocation)
  }

  _checkPluginLocation (pluginPath) {
    debug('Checking if ' + pluginPath + '/package.json exists')

    return stat(path.join(pluginPath, 'package.json'))
      .then((statResult) => {
        if (statResult.isFile()) {
          debug('Found package.json in ', pluginPath)
          return pluginPath // It exists, we can return the Promise
        }
        throw new Error(pluginPath + '/package.json is not a file.')
      })
      .catch((err) => {
        if (err.code !== 'ENOENT') {
          throw err
        }

        // Create package.json
        debug('Creating package.json in folder', pluginPath)
        return writeFile(
          path.join(pluginPath, 'package.json'),
          JSON.stringify({
            name: 'genie-router-plugins',
            dependencies: { // Default dependencies
              'genie-router-cli-local': 'github:matueranet/genie-router-plugin-cli-local',
              'genie-router-plugin-echo': 'github:matueranet/genie-router-plugin-echo',
              'genie-router-plugin-brain-mentions': 'github:matueranet/genie-router-plugin-brain-mentions'
            }
          })
        )
      })
      .then(() => {
        return pluginPath
      })
  }

  getClients () {
    return this.clients
  }

  _startPlugins () {
    const plugins = Object.keys(this.plugins)
    debug('Found plugins: ', plugins)
    let promises = []
    let brains = {}
    plugins.forEach((pluginName) => {
      const config = getFromObject(this.config, 'plugins.' + pluginName)
      const plugin = this.plugins[pluginName]
      if (plugin.brain) {
        promises.push(
          this.plugins[pluginName].brain.start(config)
          .then((brain) => {
            brains[pluginName] = brain
          })
        )
      }
      if (plugin.client) {
        // thing here is that the startObject needs the speak function, which
        // is only available after the start function has been invoked. Needed
        // some trickery to make it work.
        const startObject = this.clientStartObjectGenerator(pluginName, plugin)
        promises.push(
          this.plugins[pluginName].client.start(
            config,
            startObject
          ).then((client) => {
            this.clients[pluginName] = client
          })
        )
      }
      if (plugin.brainSelector) {
        promises.push(
          this.plugins[pluginName].brainSelector.start(config)
          .then((brainSelector) => {
            this.brainSelector.use(pluginName, brainSelector)
          })
        )
      }
      if (plugin.http) {
        if (!this.httpEnabled) {
          console.log('HTTP is not enabled, Ignoring http component of plugin', pluginName)
        } else {
          promises.push(
            http()
              .then((app) => {
                return this.plugins[pluginName].http.start(config, app, express)
              })
          )
        }
      }
      if (plugin.listener) {
        promises.push(
          this.plugins[pluginName].listener.start(config, this.eventEmitter)
        )
      }
    })
    return Promise.all(promises)
      .then(() => {
        this.brainSelector.setBrains(brains)
      })
  }

  _loadPlugins () {
    return this._superPlug.getPlugins()
      .then((foundPlugins) => {
        let promises = []
        for (var iter in foundPlugins) {
          let foundPlugin = foundPlugins[iter]
          // Only load the plugins which have a configuration
          if (getFromObject(this.config, 'plugins.' + foundPlugin.getName()) !== undefined) {
            const p = foundPlugin.getPlugin()
            p.then((pluginModule) => {
              this.plugins[foundPlugin.getName()] = pluginModule
            })
            promises.push(p)
          }
        }
        return Promise.all(promises)
      })
  }

  /**
   * Runs 'npm install' without a module name, so that the modules are installed/updated.
   * @return Promise
   */
  _npmInstall () {
    const cwd = process.cwd()
    process.chdir(this.location)
    return npmUtils.install({
      name: '',
      flags: ['--quiet', '--production']
    })
      .then(() => {
        // move back to the old current dir
        process.chdir(cwd)
      })
  }
}

module.exports = Loader
<|endoftext|>


<commit_before>/**
 * @module echarts/chart/helper/Symbol
 */
define(function (require) {

    var zrUtil = require('zrender/core/util');
    var symbolUtil = require('../../util/symbol');
    var graphic = require('../../util/graphic');
    var numberUtil = require('../../util/number');

    function normalizeSymbolSize(symbolSize) {
        if (!zrUtil.isArray(symbolSize)) {
            symbolSize = [+symbolSize, +symbolSize];
        }
        return symbolSize;
    }

    /**
     * @constructor
     * @alias {module:echarts/chart/helper/Symbol}
     * @param {module:echarts/data/List} data
     * @param {number} idx
     * @extends {module:zrender/graphic/Group}
     */
    function Symbol(data, idx) {
        graphic.Group.call(this);

        this.updateData(data, idx);
    }

    var symbolProto = Symbol.prototype;

    function driftSymbol(dx, dy) {
        this.parent.drift(dx, dy);
    }

    symbolProto._createSymbol = function (symbolType, data, idx) {
        // Remove paths created before
        this.removeAll();

        var seriesModel = data.hostModel;
        var color = data.getItemVisual(idx, 'color');

        var symbolPath = symbolUtil.createSymbol(
            symbolType, -0.5, -0.5, 1, 1, color
        );

        symbolPath.attr({
            style: {
                strokeNoScale: true
            },
            z2: 100,
            culling: true,
            scale: [0, 0]
        });
        // Rewrite drift method
        symbolPath.drift = driftSymbol;

        var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));

        graphic.initProps(symbolPath, {
            scale: size
        }, seriesModel);

        this._symbolType = symbolType;

        this.add(symbolPath);
    };

    /**
     * Stop animation
     * @param {boolean} toLastFrame
     */
    symbolProto.stopSymbolAnimation = function (toLastFrame) {
        this.childAt(0).stopAnimation(toLastFrame);
    };

    /**
     * Get scale(aka, current symbol size).
     * Including the change caused by animation
     * @param {Array.<number>} toLastFrame
     */
    symbolProto.getScale = function () {
        return this.childAt(0).scale;
    };

    /**
     * Highlight symbol
     */
    symbolProto.highlight = function () {
        this.childAt(0).trigger('emphasis');
    };

    /**
     * Downplay symbol
     */
    symbolProto.downplay = function () {
        this.childAt(0).trigger('normal');
    };

    /**
     * @param {number} zlevel
     * @param {number} z
     */
    symbolProto.setZ = function (zlevel, z) {
        var symbolPath = this.childAt(0);
        symbolPath.zlevel = zlevel;
        symbolPath.z = z;
    };

    symbolProto.setDraggable = function (draggable) {
        var symbolPath = this.childAt(0);
        symbolPath.draggable = draggable;
        symbolPath.cursor = draggable ? 'move' : 'pointer';
    };
    /**
     * Update symbol properties
     * @param  {module:echarts/data/List} data
     * @param  {number} idx
     */
    symbolProto.updateData = function (data, idx) {
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
        var seriesModel = data.hostModel;
        var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
        if (symbolType !== this._symbolType) {
            this._createSymbol(symbolType, data, idx);
        }
        else {
            var symbolPath = this.childAt(0);
            graphic.updateProps(symbolPath, {
                scale: symbolSize
            }, seriesModel);
        }
        this._updateCommon(data, idx, symbolSize);

        this._seriesModel = seriesModel;
    };

    // Update common properties
    var normalStyleAccessPath = ['itemStyle', 'normal'];
    var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];
    var normalLabelAccessPath = ['label', 'normal'];
    var emphasisLabelAccessPath = ['label', 'emphasis'];

    symbolProto._updateCommon = function (data, idx, symbolSize) {
        var symbolPath = this.childAt(0);
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
        var color = data.getItemVisual(idx, 'color');

        var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();

        symbolPath.rotation = itemModel.getShallow('symbolRotate') * Math.PI / 180 || 0;

        var symbolOffset = itemModel.getShallow('symbolOffset');
        if (symbolOffset) {
            var pos = symbolPath.position;
            pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);
            pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);
        }

        symbolPath.setColor(color);

        zrUtil.extend(
            symbolPath.style,
            // Color must be excluded.
            // Because symbol provide setColor individually to set fill and stroke
            normalItemStyleModel.getItemStyle(['color'])
        );

        var labelModel = itemModel.getModel(normalLabelAccessPath);
        var hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath);
        var lastDim = data.dimensions[data.dimensions.length - 1];
        var elStyle = symbolPath.style;

        if (labelModel.get('show')) {
            graphic.setText(elStyle, labelModel, color);
            elStyle.text = zrUtil.retrieve(
                seriesModel.getFormattedLabel(idx, 'normal'),
                data.get(lastDim, idx)
            );
        }
        else {
            elStyle.text = '';
        }

        if (hoverLabelModel.getShallow('show')) {
            graphic.setText(hoverStyle, hoverLabelModel, color);
            hoverStyle.text = zrUtil.retrieve(
                seriesModel.getFormattedLabel(idx, 'emphasis'),
                data.get(lastDim, idx)
            );
        }
        else {
            hoverStyle.text = '';
        }

        var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));

        symbolPath.off('mouseover')
            .off('mouseout')
            .off('emphasis')
            .off('normal');

        graphic.setHoverStyle(symbolPath, hoverStyle);

        if (itemModel.getShallow('hoverAnimation')) {
            var onEmphasis = function() {
                var ratio = size[1] / size[0];
                this.animateTo({
                    scale: [
                        Math.max(size[0] * 1.1, size[0] + 3),
                        Math.max(size[1] * 1.1, size[1] + 3 * ratio)
                    ]
                }, 400, 'elasticOut');
            };
            var onNormal = function() {
                this.animateTo({
                    scale: size
                }, 400, 'elasticOut');
            };
            symbolPath.on('mouseover', onEmphasis)
                .on('mouseout', onNormal)
                .on('emphasis', onEmphasis)
                .on('normal', onNormal);
        }
    };

    symbolProto.fadeOut = function (cb) {
        var symbolPath = this.childAt(0);
        // Not show text when animating
        symbolPath.style.text = '';
        graphic.updateProps(symbolPath, {
            scale: [0, 0]
        }, this._seriesModel, cb);
    };

    zrUtil.inherits(Symbol, graphic.Group);

    return Symbol;
});<commit_msg>Symbol label default show the value on last value dim. Fix #2641<commit_after>/**
 * @module echarts/chart/helper/Symbol
 */
define(function (require) {

    var zrUtil = require('zrender/core/util');
    var symbolUtil = require('../../util/symbol');
    var graphic = require('../../util/graphic');
    var numberUtil = require('../../util/number');

    function normalizeSymbolSize(symbolSize) {
        if (!zrUtil.isArray(symbolSize)) {
            symbolSize = [+symbolSize, +symbolSize];
        }
        return symbolSize;
    }

    /**
     * @constructor
     * @alias {module:echarts/chart/helper/Symbol}
     * @param {module:echarts/data/List} data
     * @param {number} idx
     * @extends {module:zrender/graphic/Group}
     */
    function Symbol(data, idx) {
        graphic.Group.call(this);

        this.updateData(data, idx);
    }

    var symbolProto = Symbol.prototype;

    function driftSymbol(dx, dy) {
        this.parent.drift(dx, dy);
    }

    symbolProto._createSymbol = function (symbolType, data, idx) {
        // Remove paths created before
        this.removeAll();

        var seriesModel = data.hostModel;
        var color = data.getItemVisual(idx, 'color');

        var symbolPath = symbolUtil.createSymbol(
            symbolType, -0.5, -0.5, 1, 1, color
        );

        symbolPath.attr({
            style: {
                strokeNoScale: true
            },
            z2: 100,
            culling: true,
            scale: [0, 0]
        });
        // Rewrite drift method
        symbolPath.drift = driftSymbol;

        var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));

        graphic.initProps(symbolPath, {
            scale: size
        }, seriesModel);

        this._symbolType = symbolType;

        this.add(symbolPath);
    };

    /**
     * Stop animation
     * @param {boolean} toLastFrame
     */
    symbolProto.stopSymbolAnimation = function (toLastFrame) {
        this.childAt(0).stopAnimation(toLastFrame);
    };

    /**
     * Get scale(aka, current symbol size).
     * Including the change caused by animation
     * @param {Array.<number>} toLastFrame
     */
    symbolProto.getScale = function () {
        return this.childAt(0).scale;
    };

    /**
     * Highlight symbol
     */
    symbolProto.highlight = function () {
        this.childAt(0).trigger('emphasis');
    };

    /**
     * Downplay symbol
     */
    symbolProto.downplay = function () {
        this.childAt(0).trigger('normal');
    };

    /**
     * @param {number} zlevel
     * @param {number} z
     */
    symbolProto.setZ = function (zlevel, z) {
        var symbolPath = this.childAt(0);
        symbolPath.zlevel = zlevel;
        symbolPath.z = z;
    };

    symbolProto.setDraggable = function (draggable) {
        var symbolPath = this.childAt(0);
        symbolPath.draggable = draggable;
        symbolPath.cursor = draggable ? 'move' : 'pointer';
    };
    /**
     * Update symbol properties
     * @param  {module:echarts/data/List} data
     * @param  {number} idx
     */
    symbolProto.updateData = function (data, idx) {
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
        var seriesModel = data.hostModel;
        var symbolSize = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
        if (symbolType !== this._symbolType) {
            this._createSymbol(symbolType, data, idx);
        }
        else {
            var symbolPath = this.childAt(0);
            graphic.updateProps(symbolPath, {
                scale: symbolSize
            }, seriesModel);
        }
        this._updateCommon(data, idx, symbolSize);

        this._seriesModel = seriesModel;
    };

    // Update common properties
    var normalStyleAccessPath = ['itemStyle', 'normal'];
    var emphasisStyleAccessPath = ['itemStyle', 'emphasis'];
    var normalLabelAccessPath = ['label', 'normal'];
    var emphasisLabelAccessPath = ['label', 'emphasis'];

    symbolProto._updateCommon = function (data, idx, symbolSize) {
        var symbolPath = this.childAt(0);
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var normalItemStyleModel = itemModel.getModel(normalStyleAccessPath);
        var color = data.getItemVisual(idx, 'color');

        var hoverStyle = itemModel.getModel(emphasisStyleAccessPath).getItemStyle();

        symbolPath.rotation = itemModel.getShallow('symbolRotate') * Math.PI / 180 || 0;

        var symbolOffset = itemModel.getShallow('symbolOffset');
        if (symbolOffset) {
            var pos = symbolPath.position;
            pos[0] = numberUtil.parsePercent(symbolOffset[0], symbolSize[0]);
            pos[1] = numberUtil.parsePercent(symbolOffset[1], symbolSize[1]);
        }

        symbolPath.setColor(color);

        zrUtil.extend(
            symbolPath.style,
            // Color must be excluded.
            // Because symbol provide setColor individually to set fill and stroke
            normalItemStyleModel.getItemStyle(['color'])
        );

        var labelModel = itemModel.getModel(normalLabelAccessPath);
        var hoverLabelModel = itemModel.getModel(emphasisLabelAccessPath);

        var elStyle = symbolPath.style;

        // Get last value dim
        var dimensions = data.dimensions.slice();
        var valueDim = dimensions.pop();
        var dataType;
        while (
            ((dataType = data.getDimensionInfo(valueDim).type) === 'ordinal')
            || (dataType === 'time')
        ) {
            valueDim = dimensions.pop();
        }

        if (labelModel.get('show')) {
            graphic.setText(elStyle, labelModel, color);
            elStyle.text = zrUtil.retrieve(
                seriesModel.getFormattedLabel(idx, 'normal'),
                data.get(valueDim, idx)
            );
        }
        else {
            elStyle.text = '';
        }

        if (hoverLabelModel.getShallow('show')) {
            graphic.setText(hoverStyle, hoverLabelModel, color);
            hoverStyle.text = zrUtil.retrieve(
                seriesModel.getFormattedLabel(idx, 'emphasis'),
                data.get(valueDim, idx)
            );
        }
        else {
            hoverStyle.text = '';
        }

        var size = normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));

        symbolPath.off('mouseover')
            .off('mouseout')
            .off('emphasis')
            .off('normal');

        graphic.setHoverStyle(symbolPath, hoverStyle);

        if (itemModel.getShallow('hoverAnimation')) {
            var onEmphasis = function() {
                var ratio = size[1] / size[0];
                this.animateTo({
                    scale: [
                        Math.max(size[0] * 1.1, size[0] + 3),
                        Math.max(size[1] * 1.1, size[1] + 3 * ratio)
                    ]
                }, 400, 'elasticOut');
            };
            var onNormal = function() {
                this.animateTo({
                    scale: size
                }, 400, 'elasticOut');
            };
            symbolPath.on('mouseover', onEmphasis)
                .on('mouseout', onNormal)
                .on('emphasis', onEmphasis)
                .on('normal', onNormal);
        }
    };

    symbolProto.fadeOut = function (cb) {
        var symbolPath = this.childAt(0);
        // Not show text when animating
        symbolPath.style.text = '';
        graphic.updateProps(symbolPath, {
            scale: [0, 0]
        }, this._seriesModel, cb);
    };

    zrUtil.inherits(Symbol, graphic.Group);

    return Symbol;
});<|endoftext|>


<commit_before>/* Computing strongly connected components of a directed graph */
/* There are more than 800,000 vertices and 5,000,000 edges in the graph */
/* Memery management need to be very careful */
/* Adajcency list is used to represent the graph */
/* Kosaraju’s Two-Pass algorithm is used to find SCCs */
/* Recursive DFS will cause stack overflow because of the size of the graph */
/* Stack is used to implement DFS */

'use strict';

const { createReadStream } = require('fs');
const { createInterface } = require('readline');
const clone = require('clone');

const graph = [];
const reversedGraph = [];

const rl = createInterface({
	input: createReadStream('graph.txt')
});

rl.on('line', (line) => {
	const list = line.split(' ');
	const [tail, head] = list;

	// Build graph
	if(!graph[tail]) {
		graph[tail] = {heads: [head]};
	} else {
		graph[tail].heads.push(head);
	}

	// Build reversed graph
	if(!reversedGraph[head]) {
		reversedGraph[head] = {heads: [tail]};
	} else {
		reversedGraph[head].heads.push(tail);
	}
});

rl.on('close', () => {
	console.log(graph)
});<commit_msg>implementing dfs loop<commit_after>/* Computing strongly connected components of a directed graph */
/* There are more than 800,000 vertices and 5,000,000 edges in the graph */
/* Memery management need to be very careful */
/* Adajcency list is used to represent the graph */
/* Kosaraju’s Two-Pass algorithm is used to find SCCs */
/* Recursive DFS will cause stack overflow because of the size of the graph */
/* Stack is used to implement DFS */
/* TODO: do the first pass on original graph instead of constructing the reverse graph */

'use strict';

const { createReadStream } = require('fs');
const { createInterface } = require('readline');
const clone = require('clone');

const graph = [];
const reverseGraph = [];

const rl = createInterface({
	input: createReadStream('test.txt')
});

rl.on('line', (line) => {
	const list = line.split(' ');
	const [tail, head] = list;

	// Construct original graph
	if(!graph[tail]) {
		graph[tail] = {heads: [head], visited: false};
	} else {
		graph[tail].heads.push(head);
	}

	// Construct reverse graph
	if(!reverseGraph[head]) {
		reverseGraph[head] = {heads: [tail], visited: false};
	} else {
		reverseGraph[head].heads.push(tail);
	}
});

rl.on('close', () => {
	const sccCaculator = new SccCaculator(graph, reverseGraph);
	sccCaculator.traverse(false);
});

class SccCaculator {
	constructor(graph, reverseGraph) {
		this.graph = graph;
		this.reverseGraph = reverseGraph;
		this.finishingTime = 0;
		this.leaders = [];
		this.stack = [];
	}

	traverse(forward) {
		const graph = forward ? this.graph : this.reverseGraph;

		for(let i = 0; i < graph.length; i++) {
			if(graph[i] && !graph[i].visited) {
				this.leaders.push(i);
				this._dfs(i, graph);
			}
		}
		console.log(graph, this.stack)
	}

	_dfs(index, graph) {
		console.log(graph, index)
		const heads = graph[index].heads;
		this.stack.push(index);

		for(let j = 0; j < heads.length; j++) {
			if(!graph[heads[j]].visited && heads[j] !== index) {
				this.stack.push(j);
				this._dfs(j, graph);
			}
		}
	}
}<|endoftext|>


<commit_before>//bools
var simpleGame

//integers
var numCards, gameSpeed, roundsLeft, p1score, numGraphs, curCard, swapsLeft;

//arrays
var graphTypes, graphChosen, cardList, masterParms, distCard;

var distributions, intervalKey;

//jquery calls
$(document).ready(function() {

	$('#startup-modal').modal('show');

	$('#startup-modal').on('hidden.bs.modal', function (e) {
		boardSetup();
	});
	$(document).on('mouseenter', ".boardcard", function()
	{
		cardList[Number(this.id.substring(4,this.id.length))].highlight();
	});
	$(document).on('mouseleave', ".boardcard", function()
	{
		cardList[Number(this.id.substring(4,this.id.length))].unhighlight();
	});
	$(document).on('click', ".boardcard", function()
	{
		if(roundOn)
		{
			answerTimes[Number(this.id.substring(4,this.id.length))]=1-cardList[Number(this.id.substring(4,this.id.length))].p1select();
		}
	});
});

//sets up board for a new game
function boardSetup()
{
	numCards=Number($('input[name="numcards"]:checked').val());
	gameSpeed=Number($('input[name="gamespeed"]:checked').val());
	roundsLeft=Number($('input[name="gamelength"]:checked').val());
	cardList=new Array();
	masterParms=new Array();
	for(var j=0;j<31;j++)
	{
		masterParms[j]=getParms(j+1);
	}

	//checks for simplified or general veresion
	if($('input[name="gametype"]:checked').val()==1)
		simpleGame=false;
	else
		simpleGame=true;

	//determines list of selectable graphs
	if(simpleGame)
		numGraphs=22;
	else
		numGraphs=31;

	p1score=0;

	for(var j=0;j<numCards;j++)
	{
		cardList[j]=new monteClass(j);
	}

	//wipes instructions and creates board
	setBoard();
/* 	$("#scores").html('P1 Score: '+p1score+' P2 Score: '+p2score+'
P1 Combo Multiplier: x'+p1bonus+' P2 Combo Multiplier: x'+p2bonus+""); */

	window.setTimeout(function(){startRound()},2000);
}

//starts next round
function startRound()
{
	getGraphs();
	distCard=new Array()
	curCard=0;
	for(var j=0;j<numCards;j++)
	{
		$("#card"+j).flip({
			direction:'tb',
			onEnd:function()
			{
				$("#card"+curCard).hide();
				$("#space"+curCard).append('<canvas id="distcanv'+curCard+'"></canvas>');
				$("#distcanv"+curCard).css({"width":"190","background-color":"white","height":"90"});
				cardList[curCard].setDist(graphTypes[curCard]+1,curCard, masterParms);
				curCard++;
			}
		})
		window.setTimeout(function(){
			$("#distcanv"+(curCard-numCards)).flip({
				direction:'tb',
				onEnd:function()
				{
					$("#card"+(curCard-numCards-numCards)).show();
					$("#distcanv"+(curCard-numCards-numCards)).remove();
					curCard++;
				}
			})
			curCard++;
		},2000);
	}
	swapsLeft=1;
 	window.setTimeout(function(){
		intervalKey=window.setInterval(function(){
		var c1=Math.floor(Math.random()*numCards);
		var c2;
		do{c2=Math.floor(Math.random()*numCards)}while(c2==c1)
		if(c1>c2)
		{
			var tempc=c1;
			c1=c2;
			c2=tempc
		}
		swapCards("#space"+c1,"#space"+c2,(c1*(190+40)),(c2*(190+40)));
		},1000/gameSpeed+120);
	},3200);

	roundOn=true;
}

//ends current round
function endRound()
{
	currRound++;
	roundOn=false;
	smartTime=0;
	$("#facecard").flip({
		direction:'bt',
		onEnd:function(){
			$("#backimage").show();
			$("#distcanv").remove();

		}
	});
	if(hideCards)
	flipDown();
	reconcileBoard();
	if(answerFound)
	{
		weightedAverage+=smartTime;
		weightedAverage/=2;
	}
	if(smartAI)
	{
		startTimes[enemyDiff]+=(weightedAverage-startTimes[enemyDiff]+smartAdd[enemyDiff])*smartMult[enemyDiff];
		if(startTimes[enemyDiff]<0)
			startTimes[enemyDiff]=.05;
		if(startTimes[enemyDiff]>1)
			startTimes[enemyDiff]=.95;
	}
	if(currRound<numGraphs)
		window.setTimeout(function(){startRound()},1500);
	else
	{
		window.setTimeout(function()
		{
			$("#game").empty();
			$("#yourscore").html(p1score);
			$("#hisscore").html(p2score);
			if(p1score>p2score)
				$("#finalmess").html('Congratulations, you win!');
			else if(p2score>p1score)
				$("#finalmess").html('You lose. Better luck next time!');
			else
				$("#finalmess").html("It's a tie!");
			$('#results-modal').modal('show');

		},1000);
	}
}

//determines scores and performs board cleanup
function reconcileBoard()
{
	for(var i=0;i<2;i++)
	{
		numRight[i]=0;
		numWrong[i]=0;
	}
	for(var i=0;i<numCards;i++)
	{
		if(cardList[i].controller!=0)
		{
			if(chosenGraph[i]==roundCard[currRound-1])
			{
				numRight[(cardList[i].controller==1)?0:1]++;
				if(cardList[i].controller==1)
				{
					if(answerFound)
					{
						smartTime+=answerTimes[i];
						smartTime/=2;
					}
					else
					{
						smartTime+=answerTimes[i];
						answerFound=true;
					}
				}
			}
			else
				numWrong[(cardList[i].controller==1)?0:1]++;
		}
	}
	p1bonus*=(numRight[0]>0)?numRight[0]:1;
	p2bonus*=(numRight[1]>0)?numRight[1]:1;
	if(numWrong[0]>0)
		p1bonus=1;
	if(numWrong[1]>0)
		p2bonus=1;
	p1score+=(numRight[0]-numWrong[0])*p1bonus;
	p2score+=(numRight[1]-numWrong[1])*p2bonus;
	$("#scores").html('P1 Score: '+p1score+' P2 Score: '+p2score+'
P1 Combo Multiplier: x'+p1bonus+' P2 Combo Multiplier: x'+p2bonus+"");
	for(var i=0;i<numCards;i++)
	{
		cardList[i].deselect();
	}
}

//flips down correct cards
function flipDown()
{
	var curDown=0,nextFlip=0;
	for(var j=0;j<numCards;j++)
	{
		if(chosenGraph[j]==roundCard[currRound-1])
		{
			downCards[curDown]=j;
			var color;
			if(cardList[j].controller==1)
			{
				downColor[curDown]="green";
			}
			else if(cardList[j].controller==-1)
			{
				downColor[curDown]="red";
			}
			else
			{
				downColor[curDown]="black";
			}
			curDown++;
			$("#card"+j).flip({
				direction:'tb',
				onEnd:function(){
				var flipDex=downCards[nextFlip];
				nextFlip++;
					$("#card"+flipDex).hide();
					$("#space"+flipDex).append('');
					$("#color"+flipDex).css({"width":"190","height":"90", "float":"left","border-style":"solid","border-width":"5px","border-color":"rgb(194, 194, 208)"});
				}
			});
		}
	}
};

//creates gameboard using recieved parameters;
function setBoard()
{
	$("#facecard").html("Let's play a game!");
	$("#facecard").css({"position":"relative","top":"350px","height":"200px","width":"500px", "background-color":"rgb(50,200,60)", "text-align":"center", "line-height":"200px", "font-family":"Verdana","font-size":"2.5em", "color":"white"})
	$("#board").css({"position":"relative", "top":"110px","width":((190*(numCards)+50*(numCards-1))+"px"),"z-index":"0","height":(110)+"px","background-color":"rgb(255, 255, 255)"});
	for(var j=0;j<numCards;j++)
	{
		cardList[j].placeCard();
	}
}

function getGraphs()
{
	graphTypes=new Array();
	graphChosen=new Array();
	for(var j=0;j<numGraphs;j++)
	{
		graphChosen[j]=false;
	}
	for(var j=0;j<numCards;j++)
	{
		var k;

		do
		{
			k=Math.floor(Math.random()*numGraphs);
		}while (graphChosen[k]);
		graphChosen[k]=true;
		graphTypes[j]=k;
	}
}

//total time:1000/speed
function animateAround(name,radius,startX, startY, dir, theta, speed)
{
	theta+=.01;
	var nextX=(Math.cos(theta*Math.PI+Math.PI)+1)*radius*dir+startX;
	var nextY=(-1)*Math.sin(theta*Math.PI+Math.PI)*100*dir+startY;
	$(name).css({"left":nextX+"px"});
	$(name).css({"top":nextY+"px"});
	if(theta<1)
	{
		window.setTimeout(function(){animateAround(name, radius, startX, startY, dir, theta, speed)}, 10/speed)
	}
}
function swapCards(card1, card2, card1x, card2x)
{console.log(card1+" "+card2);
	animateAround(card1, (card2x-card1x)/2, card1x, 210, 1, 0,gameSpeed)
	animateAround(card2, (card2x-card1x)/2, card2x, 210, -1, 0,gameSpeed)
	swapsLeft--;
	if(swapsLeft<1)
		window.clearInterval(intervalKey)
	window.setTimeout(function(){
		var temp=card1;
		var temp2=card2;
		$(card1).attr('id',"temp")
		$(card2).attr('id',"HHH")
		$("#temp").attr('id',temp2)
	},1000/gameSpeed+70)
}
<commit_msg>Bug Fix, Comments<commit_after>//bools
var simpleGame

//integers
var numCards, gameSpeed, roundsLeft, p1score, numGraphs, curCard, swapsLeft;

//arrays
var graphTypes, graphChosen, cardList, masterParms, distCard;

var distributions, intervalKey;

//jquery calls
$(document).ready(function() {

	$('#startup-modal').modal('show');

	$('#startup-modal').on('hidden.bs.modal', function (e) {
		boardSetup();
	});
	$(document).on('mouseenter', ".boardcard", function()
	{
		cardList[Number(this.id.substring(4,this.id.length))].highlight();
	});
	$(document).on('mouseleave', ".boardcard", function()
	{
		cardList[Number(this.id.substring(4,this.id.length))].unhighlight();
	});
	$(document).on('click', ".boardcard", function()
	{
		if(roundOn)
		{
			answerTimes[Number(this.id.substring(4,this.id.length))]=1-cardList[Number(this.id.substring(4,this.id.length))].p1select();
		}
	});
});

//sets up board for a new game
function boardSetup()
{
	numCards=Number($('input[name="numcards"]:checked').val());
	gameSpeed=Number($('input[name="gamespeed"]:checked').val());
	roundsLeft=Number($('input[name="gamelength"]:checked').val());
	cardList=new Array();
	masterParms=new Array();
	for(var j=0;j<31;j++)
	{
		masterParms[j]=getParms(j+1);
	}

	//checks for simplified or general veresion
	if($('input[name="gametype"]:checked').val()==1)
		simpleGame=false;
	else
		simpleGame=true;

	//determines list of selectable graphs
	if(simpleGame)
		numGraphs=22;
	else
		numGraphs=31;

	p1score=0;

	for(var j=0;j<numCards;j++)
	{
		cardList[j]=new monteClass(j);
	}

	//wipes instructions and creates board
	setBoard();
/* 	$("#scores").html('P1 Score: '+p1score+' P2 Score: '+p2score+'
P1 Combo Multiplier: x'+p1bonus+' P2 Combo Multiplier: x'+p2bonus+""); */

	window.setTimeout(function(){startRound()},2000);
}

//starts next round
function startRound()
{
	getGraphs();
	distCard=new Array()
	curCard=0;

	//shows identity of each card, then hides again
	for(var j=0;j<numCards;j++)
	{
		$("#card"+j).flip({
			direction:'tb',
			onEnd:function()
			{
				$("#card"+curCard).hide();
				$("#space"+curCard).append('<canvas id="distcanv'+curCard+'"></canvas>');
				$("#distcanv"+curCard).css({"width":"190","background-color":"white","height":"90"});
				cardList[curCard].setDist(graphTypes[curCard]+1,curCard, masterParms);
				curCard++;
			}
		})
		window.setTimeout(function(){
			$("#distcanv"+(curCard-numCards)).flip({
				direction:'tb',
				onEnd:function()
				{
					$("#card"+(curCard-numCards-numCards)).show();
					$("#distcanv"+(curCard-numCards-numCards)).remove();
					curCard++;
				}
			})
			curCard++;
		},2000);
	}
	swapsLeft=5;
 	window.setTimeout(function(){
		intervalKey=window.setInterval(function(){

		//select cards to be swapped
		var c1=Math.floor(Math.random()*numCards);
		var c2;

		//check to make sure 2 different cards are selected
		do{c2=Math.floor(Math.random()*numCards)}while(c2==c1)

		//sort cards in ascending order
		if(c1>c2)
		{
			var tempc=c1;
			c1=c2;
			c2=tempc
		}

		//swap cards
		swapCards("#space"+c1,"#space"+c2,(c1*(190+40)),(c2*(190+40)));
		},1000/gameSpeed+320);
	},3200);

	roundOn=true;
}

//ends current round
function endRound()
{
	currRound++;
	roundOn=false;
	smartTime=0;
	$("#facecard").flip({
		direction:'bt',
		onEnd:function(){
			$("#backimage").show();
			$("#distcanv").remove();

		}
	});
	if(hideCards)
	flipDown();
	reconcileBoard();
	if(answerFound)
	{
		weightedAverage+=smartTime;
		weightedAverage/=2;
	}
	if(smartAI)
	{
		startTimes[enemyDiff]+=(weightedAverage-startTimes[enemyDiff]+smartAdd[enemyDiff])*smartMult[enemyDiff];
		if(startTimes[enemyDiff]<0)
			startTimes[enemyDiff]=.05;
		if(startTimes[enemyDiff]>1)
			startTimes[enemyDiff]=.95;
	}
	if(currRound<numGraphs)
		window.setTimeout(function(){startRound()},1500);
	else
	{
		window.setTimeout(function()
		{
			$("#game").empty();
			$("#yourscore").html(p1score);
			$("#hisscore").html(p2score);
			if(p1score>p2score)
				$("#finalmess").html('Congratulations, you win!');
			else if(p2score>p1score)
				$("#finalmess").html('You lose. Better luck next time!');
			else
				$("#finalmess").html("It's a tie!");
			$('#results-modal').modal('show');

		},1000);
	}
}

//determines scores and performs board cleanup
function reconcileBoard()
{
	for(var i=0;i<2;i++)
	{
		numRight[i]=0;
		numWrong[i]=0;
	}
	for(var i=0;i<numCards;i++)
	{
		if(cardList[i].controller!=0)
		{
			if(chosenGraph[i]==roundCard[currRound-1])
			{
				numRight[(cardList[i].controller==1)?0:1]++;
				if(cardList[i].controller==1)
				{
					if(answerFound)
					{
						smartTime+=answerTimes[i];
						smartTime/=2;
					}
					else
					{
						smartTime+=answerTimes[i];
						answerFound=true;
					}
				}
			}
			else
				numWrong[(cardList[i].controller==1)?0:1]++;
		}
	}
	p1bonus*=(numRight[0]>0)?numRight[0]:1;
	p2bonus*=(numRight[1]>0)?numRight[1]:1;
	if(numWrong[0]>0)
		p1bonus=1;
	if(numWrong[1]>0)
		p2bonus=1;
	p1score+=(numRight[0]-numWrong[0])*p1bonus;
	p2score+=(numRight[1]-numWrong[1])*p2bonus;
	$("#scores").html('P1 Score: '+p1score+' P2 Score: '+p2score+'
P1 Combo Multiplier: x'+p1bonus+' P2 Combo Multiplier: x'+p2bonus+"");
	for(var i=0;i<numCards;i++)
	{
		cardList[i].deselect();
	}
}

//flips down correct cards
function flipDown()
{
	var curDown=0,nextFlip=0;
	for(var j=0;j<numCards;j++)
	{
		if(chosenGraph[j]==roundCard[currRound-1])
		{
			downCards[curDown]=j;
			var color;
			if(cardList[j].controller==1)
			{
				downColor[curDown]="green";
			}
			else if(cardList[j].controller==-1)
			{
				downColor[curDown]="red";
			}
			else
			{
				downColor[curDown]="black";
			}
			curDown++;
			$("#card"+j).flip({
				direction:'tb',
				onEnd:function(){
				var flipDex=downCards[nextFlip];
				nextFlip++;
					$("#card"+flipDex).hide();
					$("#space"+flipDex).append('');
					$("#color"+flipDex).css({"width":"190","height":"90", "float":"left","border-style":"solid","border-width":"5px","border-color":"rgb(194, 194, 208)"});
				}
			});
		}
	}
};

//creates gameboard using recieved parameters;
function setBoard()
{
	$("#facecard").html("Let's play a game!");
	$("#facecard").css({"position":"relative","top":"350px","height":"200px","width":"500px", "background-color":"rgb(50,200,60)", "text-align":"center", "line-height":"200px", "font-family":"Verdana","font-size":"2.5em", "color":"white"})
	$("#board").css({"position":"relative", "top":"110px","width":((190*(numCards)+50*(numCards-1))+"px"),"z-index":"0","height":(110)+"px","background-color":"rgb(255, 255, 255)"});
	for(var j=0;j<numCards;j++)
	{
		cardList[j].placeCard();
	}
}

//obtains random graph types for each card on board
function getGraphs()
{
	graphTypes=new Array();
	graphChosen=new Array();
	for(var j=0;j<numGraphs;j++)
	{
		graphChosen[j]=false;
	}
	for(var j=0;j<numCards;j++)
	{
		var k;

		do
		{
			k=Math.floor(Math.random()*numGraphs);
		}while (graphChosen[k]);
		graphChosen[k]=true;
		graphTypes[j]=k;
	}
}

//function to animate any HTML object in an elliptical path
//total time:1000/speed
function animateAround(name,radius,startX, startY, dir, theta, speed)
{
	theta+=.01;
	var nextX=(Math.cos(theta*Math.PI+Math.PI)+1)*radius*dir+startX;
	var nextY=(-1)*Math.sin(theta*Math.PI+Math.PI)*100*dir+startY;
	$(name).css({"left":nextX+"px"});
	$(name).css({"top":nextY+"px"});
	if(theta<1)
	{
		window.setTimeout(function(){animateAround(name, radius, startX, startY, dir, theta, speed)}, 10/speed)
	}
}

//function to swap 2 cards
function swapCards(card1, card2, card1x, card2x)
{console.log(card1+" "+card2);
	animateAround(card1, (card2x-card1x)/2, card1x, 210, 1, 0,gameSpeed)
	animateAround(card2, (card2x-card1x)/2, card2x, 210, -1, 0,gameSpeed)
	swapsLeft--;
	if(swapsLeft<1)
	{
		window.clearInterval(intervalKey)
	}
	window.setTimeout(function(){console.log("namechange!!!!!!!!!!!!"+card1+" "+card2);
		var temp=card1;
		var temp2=card2;
		$(card1).attr('id',"temp")
		$(card2).attr('id',card1.substring(1))
		$("#temp").attr('id',card2.substring(1))
	},1000/gameSpeed+220)
}
<|endoftext|>


<commit_before>//Creates special single image webpage that is tinted black with a given image in the center of the webpage
//To exit the display click anywhere not on the image itself
function imgAppearOpen(imgSrc) {

//Create Fixed Wrapper Div
	jQuery('<div/>', {
		id: 'imgAppear_wrapper',
		css: {
			width: '100%',
			height: '100%',
			position: 'fixed',
			'z-index' : 2,
			top:0,
			left: 0
		}
	}).appendTo('body');

//Creates Shaded Div that tints whole page black
	jQuery('<div/>', {
		id: 'imgAppear_shade',
		css: {
			background: 'black',
			opacity: 0.8,
			width: '100%',
			height: '100%',
			position: 'fixed',
			top: 0,
			left: 0,
			display: 'none',
			'z-index' : 1
			},
			click: function(){
				imgAppearClose();
			}
	}).appendTo('#imgAppear_wrapper').fadeIn('slow', function() {});

//Create image object from href source
var t = new Image();
t.src = $(imgSrc).attr("href");

//Get the Width and Height of the Browser
var wrapWidth = $('#imgAppear_wrapper').width();
var wrapHeight = $('#imgAppear_wrapper').height();

//Calculate the top and bottom height margins, and check if the image has greather width or height than browser
//Purpose of + 10 is so the close img does not get cut off
var marginHeight;
var maxWidth;
var maxHeight;

if (wrapHeight > t.height + 10)
{
	marginHeight = (wrapHeight - t.height)/2;
	maxHeight = t.height + 10;
}
else
{
	marginHeight = 0;
	maxHeight = wrapHeight
}

if (wrapWidth > t.width + 10)
{
	maxWidth = t.width + 10;
}
else
{
	maxWidth = wrapWidth ;
}

//Make sure image loads first
t.onload = function(){
	//Div that holds the image to be displayed
		jQuery('<div/>', {
			id: 'imgAppear_img',
			css: {
				position: 'relative',
				overflow: 'auto',
				width:maxWidth,
				height: maxHeight,
				margin: '0 auto',
				'margin-top': marginHeight,
				'z-index' : 3
			}
		}).appendTo('#imgAppear_wrapper');

		//Main image to be displayed
		jQuery('<img/>', {
			id: 'imgAppear_img_img',
			src: $(imgSrc).attr("href"),
			css: {
				position: 'relative',
				top: 5,
				display : 'none',
				'z-index' : 2
			}
		}).appendTo('#imgAppear_img').fadeIn('slow', function() {});

		//Close Button Image
		jQuery('<img/>', {
			id: 'imgAppear_close_img',
			src: 'imgAppear/close.png',
			css: {
				position: 'absolute',
				left: t.width,
				top: 5,
				'margin-left' : '-8px',
				'margin-top' :'-4px',
				display : 'none',
				cursor: 'pointer',
				'z-index' : 2
			},
			click: function(){
				imgAppearClose();
			}
		}).appendTo('#imgAppear_img').fadeIn('slow', function() {});
	};
	return false;
}

//Removes all created divs and images from HTML
function imgAppearClose() {

	$("#imgAppear_wrapper").fadeOut("slow", function () {	$("#imgAppear_wrapper").remove(); });
	return true;
}
<commit_msg>Trying to optimize onload speed<commit_after>//Creates special single image webpage that is tinted black with a given image in the center of the webpage
//To exit the display click anywhere not on the image itself
function imgAppearOpen(imgSrc) {

//Create image object from href source
var t = new Image();
t.src = $(imgSrc).attr("href");

//Create Fixed Wrapper Div
	jQuery('<div/>', {
		id: 'imgAppear_wrapper',
		css: {
			width: '100%',
			height: '100%',
			position: 'fixed',
			'z-index' : 2,
			top:0,
			left: 0
		}
	}).appendTo('body');

//Creates Shaded Div that tints whole page black
	jQuery('<div/>', {
		id: 'imgAppear_shade',
		css: {
			background: 'black',
			opacity: 0.8,
			width: '100%',
			height: '100%',
			position: 'fixed',
			top: 0,
			left: 0,
			display: 'none',
			'z-index' : 1
			},
			click: function(){
				imgAppearClose();
			}
	}).appendTo('#imgAppear_wrapper').fadeIn('slow', function() {});

//Get the Width and Height of the Browser
var wrapWidth = $('#imgAppear_wrapper').width();
var wrapHeight = $('#imgAppear_wrapper').height();

//Calculate the top and bottom height margins, and check if the image has greather width or height than browser
//Purpose of + 10 is so the close img does not get cut off
var marginHeight;
var maxWidth;
var maxHeight;

if (wrapHeight > t.height + 10)
{
	marginHeight = (wrapHeight - t.height)/2;
	maxHeight = t.height + 10;
}
else
{
	marginHeight = 0;
	maxHeight = wrapHeight
}

if (wrapWidth > t.width + 10)
{
	maxWidth = t.width + 10;
}
else
{
	maxWidth = wrapWidth ;
}

//Make sure image loads first
t.onload = function(){
	//Div that holds the image to be displayed
		jQuery('<div/>', {
			id: 'imgAppear_img',
			css: {
				position: 'relative',
				overflow: 'auto',
				width:maxWidth,
				height: maxHeight,
				margin: '0 auto',
				'margin-top': marginHeight,
				'z-index' : 3
			}
		}).appendTo('#imgAppear_wrapper');

		//Main image to be displayed
		jQuery('<img/>', {
			id: 'imgAppear_img_img',
			src: $(imgSrc).attr("href"),
			css: {
				position: 'relative',
				top: 5,
				display : 'none',
				'z-index' : 2
			}
		}).appendTo('#imgAppear_img').fadeIn('slow', function() {});

		//Close Button Image
		jQuery('<img/>', {
			id: 'imgAppear_close_img',
			src: 'imgAppear/close.png',
			css: {
				position: 'absolute',
				left: t.width,
				top: 5,
				'margin-left' : '-8px',
				'margin-top' :'-4px',
				display : 'none',
				cursor: 'pointer',
				'z-index' : 2
			},
			click: function(){
				imgAppearClose();
			}
		}).appendTo('#imgAppear_img').fadeIn('slow', function() {});
	};
	return false;
}

//Removes all created divs and images from HTML
function imgAppearClose() {

	$("#imgAppear_wrapper").fadeOut("slow", function () {	$("#imgAppear_wrapper").remove(); });
	return true;
}
<|endoftext|>


<commit_before>var settings = require('../core/settings');
var THREE = require('three');
var shaderParse = require('../helpers/shaderParse');
var glslify = require('glslify');
var simulator = require('./simulator');
var lights = require('./lights');
var floor = require('./floor');
var postprocessing = require('./postprocessing');
var math = require('../utils/math');

var undef;

var mesh = exports.mesh = undef;
exports.init = init;
exports.resize = resize;
exports.preRender = preRender;
exports.update = update;

var _renderer;
var _camera;
var _scene;
var _particleGeometry;

var _quadScene;
var _quadCamera;
var _shadowMatrial;

var _particles;
var _particlesMaterial;
var _particlesScene;
var _depthRenderTarget;
var _additiveRenderTarget;

var _blurHMaterial;
var _blurVMaterial;
var _blurRenderTarget;

var _resolution;
var _width;
var _height;

var TEXTURE_WIDTH = settings.simulatorTextureWidth;
var TEXTURE_HEIGHT = settings.simulatorTextureHeight;
var AMOUNT = TEXTURE_WIDTH * TEXTURE_HEIGHT;

function init(renderer, camera, scene) {

    _quadCamera = new THREE.Camera();
    _quadCamera.position.z = 1;
    _particlesScene = new THREE.Scene();
    _quadScene = new THREE.Scene();
    _camera = camera;
    _scene = scene;
    _renderer = renderer;
    _resolution = new THREE.Vector2();

    _initGeometry();
    _initDepthRenderTarget();
    _initAdditiveRenderTarget();
    _initBlurRenderTarget();

    _particles = new THREE.Points(_particleGeometry, _additiveRenderTarget.material);
    _particles.frustumCulled = false;

    var geomtry =  new THREE.PlaneBufferGeometry( 2, 2 );
    var uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib.ambient, THREE.UniformsLib.lights]);
    uniforms.uTime = {type: 't', value: 0};
    uniforms.uDepth = {type: 't', value: _depthRenderTarget};
    uniforms.uAdditive = {type: 't', value: _additiveRenderTarget};
    // uniforms.uSphereMap = {type: 't', value: new THREE.Texture(settings.sphereMap)};
    uniforms.uResolution = {type: 'v2', value: _resolution};
    uniforms.uCameraInverse = {type: 'm4', value: _camera.matrixWorld};
    uniforms.uCameraRotationInverse = {type: 'm4', value: new THREE.Matrix4()};
    uniforms.uProjectMatrix = {type: 'm4', value: _camera.projectionMatrix};
    uniforms.uProjectMatrixInverse = {type: 'm4', value: new THREE.Matrix4()};
    uniforms.uFogColor = {type: 'c', value: new THREE.Color()};
    uniforms.uColor1 = {type: 'c', value: new THREE.Color()};
    uniforms.uColor2 = {type: 'c', value: new THREE.Color()};
    uniforms.uLightPosition = {type: 'v3', value: lights.mesh.position};

    _particlesMaterial = new THREE.ShaderMaterial({
        uniforms: uniforms,
        transparent: true,
        depthWrite: false,
        vertexShader: shaderParse(glslify('../glsl/particles.vert')),
        fragmentShader: shaderParse(glslify('../glsl/particles.frag'))
    });

    // _particlesMaterial.uniforms.uSphereMap.value.anisotropy = 16;
    // _particlesMaterial.uniforms.uSphereMap.value.needsUpdate = true;
    // _particlesMaterial.uniforms.uSphereMap.value.flipY = false;
    mesh = exports.mesh = new THREE.Mesh(geomtry, _particlesMaterial);
    _quadScene.add(mesh);

    _shadowMatrial = new THREE.ShaderMaterial( {
        uniforms: {
            uTexturePosition: {type: 't', value: null},
            uParticleSize: { type: 'f', value: 1 }
        },
        vertexShader: shaderParse(glslify('../glsl/shadow.vert')),
        fragmentShader: shaderParse(glslify('../glsl/shadow.frag')),
        blending: THREE.NoBlending,
        depthTest: true,
        depthWrite: true
    });
    _particles.castShadow = true;
    _particles.customDepthMaterial = _shadowMatrial;

}

function _initGeometry() {

    var position = new Float32Array(AMOUNT * 3);
    var i3;
    var baseSize = settings.particleSize;
    for(var i = 0; i < AMOUNT; i++ ) {
        i3 = i * 3;
        position[i3 + 0] = (i % TEXTURE_WIDTH) / TEXTURE_WIDTH;
        position[i3 + 1] = ~~(i / TEXTURE_WIDTH) / TEXTURE_HEIGHT;
        position[i3 + 2] = (20000 + Math.pow(Math.random(), 5) * 24000) / baseSize; // size
    }
    _particleGeometry = new THREE.BufferGeometry();
    _particleGeometry.addAttribute( 'position', new THREE.BufferAttribute( position, 3 ));

}

function _initDepthRenderTarget() {
    var material = new THREE.ShaderMaterial({
        uniforms: {
            uTexturePosition: { type: 't', value: null },
            uParticleSize: { type: 'f', value: 1 }
        },
        vertexShader: shaderParse(glslify('../glsl/particlesDepth.vert')),
        fragmentShader: shaderParse(glslify('../glsl/particlesDepth.frag')),
        blending: THREE.NoBlending
    });

    _depthRenderTarget = new THREE.WebGLRenderTarget(1, 1, {
        minFilter: THREE.NearestFilter,
        magFilter: THREE.NearestFilter,
        type: THREE.FloatType,
        format: THREE.RGBAFormat,
        stencilBuffer: false,
        transparent: true
    });
    _depthRenderTarget.material = material;
}

function _initAdditiveRenderTarget() {
    var material = new THREE.ShaderMaterial({
        uniforms: {
            uTexturePosition: {type: 't', value: null},
            uDepth: {type: 't', value: _depthRenderTarget},
            uResolution: {type: 'v2', value: _resolution},
            uParticleSize: { type: 'f', value: 1 }
        },
        vertexShader: shaderParse(glslify('../glsl/particlesAdditive.vert')),
        fragmentShader: shaderParse(glslify('../glsl/particlesAdditive.frag')),

        blending : THREE.CustomBlending,
        blendEquation : THREE.AddEquation,
        blendSrc : THREE.OneFactor,
        blendDst : THREE.OneFactor ,
        // blendEquationAlpha : THREE.MinEquation,
        blendEquationAlpha : THREE.AddEquation,
        blendSrcAlpha : THREE.OneFactor,
        blendDstAlpha : THREE.OneFactor,
        transparent: true
    });

    _additiveRenderTarget = new THREE.WebGLRenderTarget(1, 1, {
        minFilter: THREE.NearestFilter,
        magFilter: THREE.NearestFilter,
        format: THREE.RGBAFormat,
        type: THREE.FloatType,
        depthWrite: false,
        depthBuffer: false,
        stencilBuffer: false
    });
    _additiveRenderTarget.material = material;
}

function _initBlurRenderTarget() {

    _blurHMaterial = new THREE.ShaderMaterial({
        uniforms: {
            tDiffuse : {type: 't', value: _additiveRenderTarget},
            uResolution : {type: 'v2', value: _resolution},
            uOffset : {type: 'f', value: 0}
        },
        vertexShader: shaderParse(glslify('../glsl/blur.vert')),
        fragmentShader: shaderParse(glslify('../glsl/blurH.frag')),
        transparent: true,
        blending: THREE.NoBlending
    });

    _blurRenderTarget = new THREE.WebGLRenderTarget(1, 1, {
        minFilter: THREE.NearestFilter,
        magFilter: THREE.NearestFilter,
        format: THREE.RGBAFormat,
        type: THREE.FloatType,
        stencilBuffer: false
    });

    _blurVMaterial = new THREE.ShaderMaterial({
        uniforms: {
            tDiffuse : {type: 't', value: _blurRenderTarget},
            uResolution : {type: 'v2', value: _resolution},
            uOffset : {type: 'f', value: 0}
        },
        vertexShader: shaderParse(glslify('../glsl/blur.vert')),
        fragmentShader: shaderParse(glslify('../glsl/blurV.frag')),
        transparent: true,
        blending: THREE.NoBlending
    });

}

function resize(width, height) {
    _width = width;
    _height = height;
    _resolution.set(width, height);
    _depthRenderTarget.setSize(width, height);
    _additiveRenderTarget.setSize(width, height);
    _blurRenderTarget.setSize(width, height);
}

function preRender() {

    _particlesScene.add(_particles);
    var autoClearColor = _renderer.autoClearColor;
    var clearColor = _renderer.getClearColor().getHex();
    var clearAlpha = _renderer.getClearAlpha();

    _renderer.setClearColor(0, 0);
    _renderer.clearTarget(_depthRenderTarget, true, true, true);
    _particles.material = _depthRenderTarget.material;
    _depthRenderTarget.material.uniforms.uTexturePosition.value = simulator.positionRenderTarget;
    _depthRenderTarget.material.uniforms.uParticleSize.value = settings.particleSize;
    _renderer.render( _particlesScene, _camera, _depthRenderTarget );

    _renderer.setClearColor(0, 0);
    _renderer.clearTarget(_additiveRenderTarget, true, true, true);

    _particles.material = _additiveRenderTarget.material;
    _additiveRenderTarget.material.uniforms.uTexturePosition.value = simulator.positionRenderTarget;
    _additiveRenderTarget.material.uniforms.uParticleSize.value = settings.particleSize;
    _renderer.render( _particlesScene, _camera, _additiveRenderTarget );

    var blurRadius = settings.blur;

    if(blurRadius) {
        _blurHMaterial.uniforms.uOffset.value = blurRadius / _width;
        _blurVMaterial.uniforms.uOffset.value = blurRadius / _height;

        _renderer.clearTarget(_blurRenderTarget, true, true, true);
        mesh.material = _blurHMaterial;
        _renderer.render( _quadScene, _quadCamera, _blurRenderTarget );

        _renderer.clearTarget(_additiveRenderTarget, true, true, true);
        mesh.material = _blurVMaterial;
        _renderer.render( _quadScene, _quadCamera, _additiveRenderTarget );
        mesh.material = _particlesMaterial;
    }

    _renderer.setClearColor(clearColor, clearAlpha);
    _renderer.autoClearColor = autoClearColor;
    _renderer.setViewport(0, 0, _width, _height);

    _particles.material = settings.ignoredMaterial;
    _shadowMatrial.uniforms.uTexturePosition.value = simulator.positionRenderTarget;
    _shadowMatrial.uniforms.uParticleSize.value = settings.particleSize;
    _scene.add(_particles);
}

function update(renderTarget, dt) {
    var autoClearColor = _renderer.autoClearColor;
    var clearColor = _renderer.getClearColor().getHex();
    var clearAlpha = _renderer.getClearAlpha();
    _renderer.autoClearColor = false;

    _particlesMaterial.uniforms.uColor1.value.setStyle(settings.color1);
    _particlesMaterial.uniforms.uColor2.value.setStyle(settings.color2);

    _particlesMaterial.uniforms.spotShadowMap.value = [lights.spot.shadow.map];
    _particlesMaterial.uniforms.spotShadowMatrix.value = [lights.spot.shadow.matrix];

    _particlesMaterial.uniforms.uCameraRotationInverse.value.extractRotation(_camera.matrixWorld);
    _particlesMaterial.uniforms.uProjectMatrixInverse.value.getInverse(_camera.projectionMatrix);

    _renderer.render( _quadScene, _quadCamera, renderTarget );

    _renderer.setClearColor(clearColor, clearAlpha);
    _renderer.autoClearColor = autoClearColor;

}
<commit_msg>clean up and fix<commit_after>var settings = require('../core/settings');
var THREE = require('three');
var shaderParse = require('../helpers/shaderParse');
var glslify = require('glslify');
var simulator = require('./simulator');
var lights = require('./lights');
var floor = require('./floor');
var postprocessing = require('./postprocessing');
var math = require('../utils/math');

var undef;

var mesh = exports.mesh = undef;
exports.init = init;
exports.resize = resize;
exports.preRender = preRender;
exports.update = update;

var _renderer;
var _camera;
var _scene;
var _particleGeometry;

var _quadScene;
var _quadCamera;
var _shadowMatrial;

var _particles;
var _particlesMaterial;
var _particlesScene;
var _depthRenderTarget;
var _additiveRenderTarget;

var _blurHMaterial;
var _blurVMaterial;
var _blurRenderTarget;

var _resolution;
var _width;
var _height;

var TEXTURE_WIDTH = settings.simulatorTextureWidth;
var TEXTURE_HEIGHT = settings.simulatorTextureHeight;
var AMOUNT = TEXTURE_WIDTH * TEXTURE_HEIGHT;

function init(renderer, camera, scene) {

    _quadCamera = new THREE.Camera();
    _quadCamera.position.z = 1;
    _particlesScene = new THREE.Scene();
    _quadScene = new THREE.Scene();
    _camera = camera;
    _scene = scene;
    _renderer = renderer;
    _resolution = new THREE.Vector2();

    _initGeometry();
    _initDepthRenderTarget();
    _initAdditiveRenderTarget();
    _initBlurRenderTarget();

    _particles = new THREE.Points(_particleGeometry, _additiveRenderTarget.material);
    _particles.frustumCulled = false;

    var geomtry =  new THREE.PlaneBufferGeometry( 2, 2 );
    var uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib.ambient, THREE.UniformsLib.lights]);
    uniforms.uDepth = {type: 't', value: _depthRenderTarget};
    uniforms.uAdditive = {type: 't', value: _additiveRenderTarget};
    uniforms.uResolution = {type: 'v2', value: _resolution};
    uniforms.uCameraInverse = {type: 'm4', value: _camera.matrixWorld};
    uniforms.uCameraRotationInverse = {type: 'm4', value: new THREE.Matrix4()};
    uniforms.uProjectMatrix = {type: 'm4', value: _camera.projectionMatrix};
    uniforms.uProjectMatrixInverse = {type: 'm4', value: new THREE.Matrix4()};
    uniforms.uFogColor = {type: 'c', value: new THREE.Color()};
    uniforms.uColor1 = {type: 'c', value: new THREE.Color()};
    uniforms.uColor2 = {type: 'c', value: new THREE.Color()};
    uniforms.uLightPosition = {type: 'v3', value: lights.mesh.position};

    _particlesMaterial = new THREE.ShaderMaterial({
        uniforms: uniforms,
        transparent: true,
        depthWrite: false,
        vertexShader: shaderParse(glslify('../glsl/particles.vert')),
        fragmentShader: shaderParse(glslify('../glsl/particles.frag'))
    });
    mesh = exports.mesh = new THREE.Mesh(geomtry, _particlesMaterial);
    _quadScene.add(mesh);

    _shadowMatrial = new THREE.ShaderMaterial( {
        uniforms: {
            uTexturePosition: {type: 't', value: null},
            uParticleSize: { type: 'f', value: 1 }
        },
        vertexShader: shaderParse(glslify('../glsl/shadow.vert')),
        fragmentShader: shaderParse(glslify('../glsl/shadow.frag')),
        blending: THREE.NoBlending,
        depthTest: true,
        depthWrite: true
    });
    _particles.castShadow = true;
    _particles.customDepthMaterial = _shadowMatrial;

}

function _initGeometry() {

    var position = new Float32Array(AMOUNT * 3);
    var i3;
    var baseSize = settings.particleSize;
    for(var i = 0; i < AMOUNT; i++ ) {
        i3 = i * 3;
        position[i3 + 0] = (i % TEXTURE_WIDTH) / TEXTURE_WIDTH;
        position[i3 + 1] = ~~(i / TEXTURE_WIDTH) / TEXTURE_HEIGHT;
        position[i3 + 2] = (20000 + Math.pow(Math.random(), 5) * 24000) / baseSize; // size
    }
    _particleGeometry = new THREE.BufferGeometry();
    _particleGeometry.addAttribute( 'position', new THREE.BufferAttribute( position, 3 ));

}

function _initDepthRenderTarget() {
    var material = new THREE.ShaderMaterial({
        uniforms: {
            uTexturePosition: { type: 't', value: null },
            uParticleSize: { type: 'f', value: 1 }
        },
        vertexShader: shaderParse(glslify('../glsl/particlesDepth.vert')),
        fragmentShader: shaderParse(glslify('../glsl/particlesDepth.frag')),
        blending: THREE.NoBlending
    });

    _depthRenderTarget = new THREE.WebGLRenderTarget(1, 1, {
        minFilter: THREE.NearestFilter,
        magFilter: THREE.NearestFilter,
        type: THREE.FloatType,
        format: THREE.RGBAFormat,
        stencilBuffer: false,
        transparent: true
    });
    _depthRenderTarget.material = material;
}

function _initAdditiveRenderTarget() {
    var material = new THREE.ShaderMaterial({
        uniforms: {
            uTexturePosition: {type: 't', value: null},
            uDepth: {type: 't', value: _depthRenderTarget},
            uResolution: {type: 'v2', value: _resolution},
            uParticleSize: { type: 'f', value: 1 }
        },
        vertexShader: shaderParse(glslify('../glsl/particlesAdditive.vert')),
        fragmentShader: shaderParse(glslify('../glsl/particlesAdditive.frag')),

        blending : THREE.CustomBlending,
        blendEquation : THREE.AddEquation,
        blendSrc : THREE.OneFactor,
        blendDst : THREE.OneFactor ,
        // blendEquationAlpha : THREE.MinEquation,
        blendEquationAlpha : THREE.AddEquation,
        blendSrcAlpha : THREE.OneFactor,
        blendDstAlpha : THREE.OneFactor,
        transparent: true
    });

    _additiveRenderTarget = new THREE.WebGLRenderTarget(1, 1, {
        minFilter: THREE.NearestFilter,
        magFilter: THREE.NearestFilter,
        format: THREE.RGBAFormat,
        type: THREE.FloatType,
        depthWrite: false,
        depthBuffer: false,
        stencilBuffer: false
    });
    _additiveRenderTarget.material = material;
}

function _initBlurRenderTarget() {

    _blurHMaterial = new THREE.ShaderMaterial({
        uniforms: {
            tDiffuse : {type: 't', value: _additiveRenderTarget},
            uResolution : {type: 'v2', value: _resolution},
            uOffset : {type: 'f', value: 0}
        },
        vertexShader: shaderParse(glslify('../glsl/blur.vert')),
        fragmentShader: shaderParse(glslify('../glsl/blurH.frag')),
        transparent: true,
        blending: THREE.NoBlending
    });

    _blurRenderTarget = new THREE.WebGLRenderTarget(1, 1, {
        minFilter: THREE.NearestFilter,
        magFilter: THREE.NearestFilter,
        format: THREE.RGBAFormat,
        type: THREE.FloatType,
        stencilBuffer: false
    });

    _blurVMaterial = new THREE.ShaderMaterial({
        uniforms: {
            tDiffuse : {type: 't', value: _blurRenderTarget},
            uResolution : {type: 'v2', value: _resolution},
            uOffset : {type: 'f', value: 0}
        },
        vertexShader: shaderParse(glslify('../glsl/blur.vert')),
        fragmentShader: shaderParse(glslify('../glsl/blurV.frag')),
        transparent: true,
        blending: THREE.NoBlending
    });

}

function resize(width, height) {
    _width = width;
    _height = height;
    _resolution.set(width, height);
    _depthRenderTarget.setSize(width, height);
    _additiveRenderTarget.setSize(width, height);
    _blurRenderTarget.setSize(width, height);
}

function preRender() {

    _particlesScene.add(_particles);
    var autoClearColor = _renderer.autoClearColor;
    var clearColor = _renderer.getClearColor().getHex();
    var clearAlpha = _renderer.getClearAlpha();

    _renderer.setClearColor(0, 0);
    _renderer.clearTarget(_depthRenderTarget, true, true, true);
    _particles.material = _depthRenderTarget.material;
    _depthRenderTarget.material.uniforms.uTexturePosition.value = simulator.positionRenderTarget;
    _depthRenderTarget.material.uniforms.uParticleSize.value = settings.particleSize;
    _renderer.render( _particlesScene, _camera, _depthRenderTarget );

    _renderer.setClearColor(0, 0);
    _renderer.clearTarget(_additiveRenderTarget, true, true, true);

    _particles.material = _additiveRenderTarget.material;
    _additiveRenderTarget.material.uniforms.uTexturePosition.value = simulator.positionRenderTarget;
    _additiveRenderTarget.material.uniforms.uParticleSize.value = settings.particleSize;
    _renderer.render( _particlesScene, _camera, _additiveRenderTarget );

    var blurRadius = settings.blur;

    if(blurRadius) {
        _blurHMaterial.uniforms.uOffset.value = blurRadius / _width;
        _blurVMaterial.uniforms.uOffset.value = blurRadius / _height;

        _renderer.clearTarget(_blurRenderTarget, true, true, true);
        mesh.material = _blurHMaterial;
        _renderer.render( _quadScene, _quadCamera, _blurRenderTarget );

        _renderer.clearTarget(_additiveRenderTarget, true, true, true);
        mesh.material = _blurVMaterial;
        _renderer.render( _quadScene, _quadCamera, _additiveRenderTarget );
        mesh.material = _particlesMaterial;
    }

    _renderer.setClearColor(clearColor, clearAlpha);
    _renderer.autoClearColor = autoClearColor;
    _renderer.setViewport(0, 0, _width, _height);

    _particles.material = settings.ignoredMaterial;
    _shadowMatrial.uniforms.uTexturePosition.value = simulator.positionRenderTarget;
    _shadowMatrial.uniforms.uParticleSize.value = settings.particleSize;
    _scene.add(_particles);
}

function update(renderTarget, dt) {
    var autoClearColor = _renderer.autoClearColor;
    var clearColor = _renderer.getClearColor().getHex();
    var clearAlpha = _renderer.getClearAlpha();
    _renderer.autoClearColor = false;

    _particlesMaterial.uniforms.uColor1.value.setStyle(settings.color1);
    _particlesMaterial.uniforms.uColor2.value.setStyle(settings.color2);

    _particlesMaterial.uniforms.spotShadowMap.value = [lights.spot.shadow.map];
    _particlesMaterial.uniforms.spotShadowMatrix.value = [lights.spot.shadow.matrix];

    _particlesMaterial.uniforms.uCameraRotationInverse.value.extractRotation(_camera.matrixWorld);
    _particlesMaterial.uniforms.uProjectMatrixInverse.value.getInverse(_camera.projectionMatrix);

    _renderer.render( _quadScene, _quadCamera, renderTarget );

    _renderer.setClearColor(clearColor, clearAlpha);
    _renderer.autoClearColor = autoClearColor;

}
<|endoftext|>


<commit_before>const labs = require('../../../../../../services/labs');
const MEMBER_TAG = '#members';

// Checks if request should hide memnbers only content
function hideMembersOnlyContent(attrs, frame) {
    let hasMemberTag = false;
    if (labs.isSet('members') && !frame.original.context.member && attrs.tags) {
        hasMemberTag = attrs.tags.find((tag) => {
            return (tag.name === MEMBER_TAG);
        });
    }
    return hasMemberTag;
}

const forPost = (attrs, frame) => {
    const hideFormatsData = hideMembersOnlyContent(attrs, frame);
    if (hideFormatsData) {
        ['plaintext', 'html'].forEach((field) => {
            attrs[field] = '';
        });
    }
    if (labs.isSet('members')) {
        // CASE: Members always adds tags, remove if the user didn't originally ask for them
        const origQuery = frame.original.query || {};
        if (!origQuery.include || !origQuery.include.includes('tags')) {
            delete attrs.tags;
        }
    }

    return attrs;
};

module.exports.forPost = forPost;
<commit_msg>Checked options.include when filtering tags (#10163)<commit_after>const labs = require('../../../../../../services/labs');
const MEMBER_TAG = '#members';

// Checks if request should hide memnbers only content
function hideMembersOnlyContent(attrs, frame) {
    let hasMemberTag = false;
    if (labs.isSet('members') && !frame.original.context.member && attrs.tags) {
        hasMemberTag = attrs.tags.find((tag) => {
            return (tag.name === MEMBER_TAG);
        });
    }
    return hasMemberTag;
}

const forPost = (attrs, frame) => {
    const hideFormatsData = hideMembersOnlyContent(attrs, frame);
    if (hideFormatsData) {
        ['plaintext', 'html'].forEach((field) => {
            attrs[field] = '';
        });
    }
    if (labs.isSet('members')) {
        // CASE: Members always adds tags, remove if the user didn't originally ask for them
        const origQueryOrOptions = frame.original.query || frame.original.options || {};
        const origInclude = origQueryOrOptions.include;

        if (!origInclude || !origInclude.includes('tags')) {
            delete attrs.tags;
        }
    }

    return attrs;
};

module.exports.forPost = forPost;
<|endoftext|>


<commit_before>/*!
 * Cluster - reload
 * Copyright (c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var fs = require('fs')
  , basename = require('path').basename
  , extname = require('path').extname;

/**
 * Restart the server the given js `files` have changed.
 * `files` may be several directories, filenames, etc,
 * defaulting to the server's root directory.
 *
 * Options:
 *
 *   - `signal` Signal to send, defaults to __SIGTERM__
 *   - `interval` Watcher interval, defaulting to `100`
 *   - `extensions` File extensions to watch, defaults to ['.js']
 *
 * Examples:
 *
 *     cluster(server)
 *       .use(cluster.reload())
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload('lib'))
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload(['lib', 'tests', 'index.js']))
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload('lib', { signal: 'SIGQUIT', interval: 60000 }))
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload('lib', { extensions: ['.js', '.coffee'] }))
 *       .listen(3000);
 *
 * Ignore Directories:
 *
 *  By default `reload()` will ignore the following directories:
 *
 *   - node_modules
 *   - support
 *   - examples
 *   - test
 *   - bin
 *
 *  Alter with `reload.ignoreDirectories`
 *
 *      cluster.reload.ignoreDirectories.push('src');
 *
 * @param {String|Array} files
 * @param {Options} options
 * @return {Function}
 * @api public
 */

exports = module.exports = function(files, options){
  options = options || {};

  // defaults
  var sig = options.sig || 'SIGTERM'
    , interval = options.interval || 100
    , extensions = options.extensions || ['.js'];

  return function(master){
    var restarting;

    if (!files) files = master.dir;
    if (!Array.isArray(files)) files = [files];
    files.forEach(traverse);

    // traverse file if it is a directory
    // otherwise setup the watcher
    function traverse(file) {
      file = master.resolve(file);
      fs.stat(file, function(err, stat){
        if (!err) {
          if (stat.isDirectory()) {
            if (~exports.ignoreDirectories.indexOf(basename(file))) return;
            fs.readdir(file, function(err, files){
              files.map(function(f){
                return file + '/' + f;
              }).forEach(traverse);
            });
          } else {
            watch(file);
          }
        }
      });
    }

    // watch file for changes
    function watch(file) {
      if (!~extensions.indexOf(extname(file))) return;
      fs.watchFile(file, { interval: interval }, function(curr, prev){
        if (restarting) return;
        if (curr.mtime > prev.mtime) {
          console.log('  \033[36mchanged\033[0m \033[90m- %s\033[0m', file);
          master.restart(sig);
        }
      });
    }

    master.on('restarting', function(){
      restarting = true;
    });
  }
};

/**
 * Directories to ignore.
 */

exports.ignoreDirectories = ['node_modules', 'support', 'test', 'bin'];<commit_msg>Fixed typo in `reload()` plugin causing the `signal` option to fail. Closes #131<commit_after>/*!
 * Cluster - reload
 * Copyright (c) 2011 LearnBoost <dev@learnboost.com>
 * MIT Licensed
 */

/**
 * Module dependencies.
 */

var fs = require('fs')
  , basename = require('path').basename
  , extname = require('path').extname;

/**
 * Restart the server the given js `files` have changed.
 * `files` may be several directories, filenames, etc,
 * defaulting to the server's root directory.
 *
 * Options:
 *
 *   - `signal` Signal to send, defaults to __SIGTERM__
 *   - `interval` Watcher interval, defaulting to `100`
 *   - `extensions` File extensions to watch, defaults to ['.js']
 *
 * Examples:
 *
 *     cluster(server)
 *       .use(cluster.reload())
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload('lib'))
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload(['lib', 'tests', 'index.js']))
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload('lib', { signal: 'SIGQUIT', interval: 60000 }))
 *       .listen(3000);
 *
 *     cluster(server)
 *       .use(cluster.reload('lib', { extensions: ['.js', '.coffee'] }))
 *       .listen(3000);
 *
 * Ignore Directories:
 *
 *  By default `reload()` will ignore the following directories:
 *
 *   - node_modules
 *   - support
 *   - examples
 *   - test
 *   - bin
 *
 *  Alter with `reload.ignoreDirectories`
 *
 *      cluster.reload.ignoreDirectories.push('src');
 *
 * @param {String|Array} files
 * @param {Options} options
 * @return {Function}
 * @api public
 */

exports = module.exports = function(files, options){
  options = options || {};

  // defaults
  var sig = options.signal || 'SIGTERM'
    , interval = options.interval || 100
    , extensions = options.extensions || ['.js'];

  return function(master){
    var restarting;

    if (!files) files = master.dir;
    if (!Array.isArray(files)) files = [files];
    files.forEach(traverse);

    // traverse file if it is a directory
    // otherwise setup the watcher
    function traverse(file) {
      file = master.resolve(file);
      fs.stat(file, function(err, stat){
        if (!err) {
          if (stat.isDirectory()) {
            if (~exports.ignoreDirectories.indexOf(basename(file))) return;
            fs.readdir(file, function(err, files){
              files.map(function(f){
                return file + '/' + f;
              }).forEach(traverse);
            });
          } else {
            watch(file);
          }
        }
      });
    }

    // watch file for changes
    function watch(file) {
      if (!~extensions.indexOf(extname(file))) return;
      fs.watchFile(file, { interval: interval }, function(curr, prev){
        if (restarting) return;
        if (curr.mtime > prev.mtime) {
          console.log('  \033[36mchanged\033[0m \033[90m- %s\033[0m', file);
          master.restart(sig);
        }
      });
    }

    master.on('restarting', function(){
      restarting = true;
    });
  }
};

/**
 * Directories to ignore.
 */

exports.ignoreDirectories = ['node_modules', 'support', 'test', 'bin'];<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Alasdair Mercer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

'use strict';

const EOL = require('os').EOL;

const Style = require('./Style');

/**
 * TODO: Document
 */
class JsonStyle extends Style {

  /**
   * @override
   * @inheritDoc
   */
  apply(options) {
    let count = 0;
    const outputStream = options.outputStream;
    const pathLength = options.pathLength;
    const pretty = options.pretty;

    pathLength.on('check', () => outputStream.write('['));
    pathLength.on('result', (event) => {
      if (count) {
        outputStream.write(',');
      }
      if (pretty) {
        outputStream.write(EOL);
      }

      count++;

      if (pretty) {
        outputStream.write(`  ${JSON.stringify(event, null, 2).replace(/\n/gm, '\n  ')}`);
      } else {
        outputStream.write(JSON.stringify(event));
      }
    });
    pathLength.on('end', () => {
      if (count && pretty) {
        outputStream.write(EOL);
      }

      outputStream.write(`]${EOL}`);
    });
  }

  /**
   * @override
   * @inheritDoc
   */
  getName() {
    return 'json';
  }

}

Style.register(JsonStyle);

module.exports = JsonStyle;
<commit_msg>added JSDoc to JsonStyle<commit_after>/*
 * Copyright (C) 2017 Alasdair Mercer
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

'use strict';

const EOL = require('os').EOL;

const Style = require('./Style');

/**
 * An implementation of {@link Style} that outputs the results as a JSON array containing elements the following form:
 *
 *

 * {"directory":DIRECTORY_BOOLEAN,"length":LENGTH_NUMBER,"path":"PATH_STRING"}
 *

 *
 * When the pretty option is enabled, the JSON is indented and spans multiple lines.
 */
class JsonStyle extends Style {

  /**
   * @override
   * @inheritDoc
   */
  apply(options) {
    let count = 0;
    const outputStream = options.outputStream;
    const pathLength = options.pathLength;
    const pretty = options.pretty;

    pathLength.on('check', () => outputStream.write('['));
    pathLength.on('result', (event) => {
      if (count) {
        outputStream.write(',');
      }
      if (pretty) {
        outputStream.write(EOL);
      }

      count++;

      if (pretty) {
        outputStream.write(`  ${JSON.stringify(event, null, 2).replace(/\n/gm, '\n  ')}`);
      } else {
        outputStream.write(JSON.stringify(event));
      }
    });
    pathLength.on('end', () => {
      if (count && pretty) {
        outputStream.write(EOL);
      }

      outputStream.write(`]${EOL}`);
    });
  }

  /**
   * @override
   * @inheritDoc
   */
  getName() {
    return 'json';
  }

}

Style.register(JsonStyle);

module.exports = JsonStyle;
<|endoftext|>