<commit_before>var _ = require('../util')
var config = require('../config')
var templateParser = require('../parsers/template')

/**
 * Process an element or a DocumentFragment based on a
 * instance option object. This allows us to transclude
 * a template node/fragment before the instance is created,
 * so the processed fragment can then be cloned and reused
 * in v-repeat.
 *
 * @param {Element} el
 * @param {Object} options
 * @return {Element|DocumentFragment}
 */

exports.transclude = function (el, options) {
  // extract container attributes to pass them down
  // to compiler, because they need to be compiled in
  // parent scope. we are mutating the options object here
  // assuming the same object will be used for compile
  // right after this.
  if (options) {
    options._containerAttrs = extractAttrs(el)
  }
  // for template tags, what we want is its content as
  // a documentFragment (for block instances)
  if (_.isTemplate(el)) {
    el = templateParser.parse(el)
  }
  if (options) {
    if (options._asComponent && !options.template) {
      options.template = '<content></content>'
    }
    if (options.template) {
      options._content = _.extractContent(el)
      el = transcludeTemplate(el, options)
    }
  }
  if (el instanceof DocumentFragment) {
    // anchors for block instance
    // passing in `persist: true` to avoid them being
    // discarded by IE during template cloning
    _.prepend(_.createAnchor('v-start', true), el)
    el.appendChild(_.createAnchor('v-end', true))
  }
  return el
}

/**
 * Process the template option.
 * If the replace option is true this will swap the $el.
 *
 * @param {Element} el
 * @param {Object} options
 * @return {Element|DocumentFragment}
 */

function transcludeTemplate (el, options) {
  var template = options.template
  var frag = templateParser.parse(template, true)
  if (!frag) {
    _.warn('Invalid template option: ' + template)
  } else {
    var replacer = frag.firstChild
    var tag = replacer.tagName && replacer.tagName.toLowerCase()
    if (options.replace) {
      if (
        // multi-children template
        frag.childNodes.length > 1 ||
        // non-element template
        replacer.nodeType !== 1 ||
        // when root node is <component>, is an element
        // directive, or has v-repeat, the instance could
        // end up having multiple top-level nodes, thus
        // becoming a block instance.
        tag === 'component' ||
        _.resolveAsset(options, 'elementDirectives', tag) ||
        replacer.hasAttribute(config.prefix + 'repeat')
      ) {
        return frag
      } else {
        options._replacerAttrs = extractAttrs(replacer)
        mergeAttrs(el, replacer)
        return replacer
      }
    } else {
      el.appendChild(frag)
      return el
    }
  }
}

/**
 * Helper to extract a component container's attribute names
 * into a map.
 *
 * @param {Element} el
 * @return {Object}
 */

function extractAttrs (el) {
  if (el.nodeType === 1 && el.hasAttributes()) {
    var attrs = el.attributes
    var res = {}
    var i = attrs.length
    while (i--) {
      res[attrs[i].name] = attrs[i].value
    }
    return res
  }
}

/**
 * Merge the attributes of two elements, and make sure
 * the class names are merged properly.
 *
 * @param {Element} from
 * @param {Element} to
 */

function mergeAttrs (from, to) {
  var attrs = from.attributes
  var i = attrs.length
  var name, value
  while (i--) {
    name = attrs[i].name
    value = attrs[i].value
    if (!to.hasAttribute(name)) {
      to.setAttribute(name, value)
    } else if (name === 'class') {
      to.className = to.className + ' ' + value
    }
  }
}
<commit_msg>add warning when mounting instance to <body> with template<commit_after>var _ = require('../util')
var config = require('../config')
var templateParser = require('../parsers/template')

/**
 * Process an element or a DocumentFragment based on a
 * instance option object. This allows us to transclude
 * a template node/fragment before the instance is created,
 * so the processed fragment can then be cloned and reused
 * in v-repeat.
 *
 * @param {Element} el
 * @param {Object} options
 * @return {Element|DocumentFragment}
 */

exports.transclude = function (el, options) {
  // extract container attributes to pass them down
  // to compiler, because they need to be compiled in
  // parent scope. we are mutating the options object here
  // assuming the same object will be used for compile
  // right after this.
  if (options) {
    options._containerAttrs = extractAttrs(el)
  }
  // for template tags, what we want is its content as
  // a documentFragment (for block instances)
  if (_.isTemplate(el)) {
    el = templateParser.parse(el)
  }
  if (options) {
    if (options._asComponent && !options.template) {
      options.template = '<content></content>'
    }
    if (options.template) {
      options._content = _.extractContent(el)
      el = transcludeTemplate(el, options)
    }
  }
  if (el instanceof DocumentFragment) {
    // anchors for block instance
    // passing in `persist: true` to avoid them being
    // discarded by IE during template cloning
    _.prepend(_.createAnchor('v-start', true), el)
    el.appendChild(_.createAnchor('v-end', true))
  }
  return el
}

/**
 * Process the template option.
 * If the replace option is true this will swap the $el.
 *
 * @param {Element} el
 * @param {Object} options
 * @return {Element|DocumentFragment}
 */

function transcludeTemplate (el, options) {
  var template = options.template
  var frag = templateParser.parse(template, true)
  if (!frag) {
    _.warn('Invalid template option: ' + template)
  } else {
    var replacer = frag.firstChild
    var tag = replacer.tagName && replacer.tagName.toLowerCase()
    if (options.replace) {
      /* istanbul ignore if */
      if (el === document.body) {
        _.warn(
          'You are mounting an instance with a template to ' +
          '<body>. This will replace <body> entirely. You ' +
          'should probably use `replace: false` here.'
        )
      }
      if (
        // multi-children template
        frag.childNodes.length > 1 ||
        // non-element template
        replacer.nodeType !== 1 ||
        // when root node is <component>, is an element
        // directive, or has v-repeat, the instance could
        // end up having multiple top-level nodes, thus
        // becoming a block instance.
        tag === 'component' ||
        _.resolveAsset(options, 'elementDirectives', tag) ||
        replacer.hasAttribute(config.prefix + 'repeat')
      ) {
        return frag
      } else {
        options._replacerAttrs = extractAttrs(replacer)
        mergeAttrs(el, replacer)
        return replacer
      }
    } else {
      el.appendChild(frag)
      return el
    }
  }
}

/**
 * Helper to extract a component container's attribute names
 * into a map.
 *
 * @param {Element} el
 * @return {Object}
 */

function extractAttrs (el) {
  if (el.nodeType === 1 && el.hasAttributes()) {
    var attrs = el.attributes
    var res = {}
    var i = attrs.length
    while (i--) {
      res[attrs[i].name] = attrs[i].value
    }
    return res
  }
}

/**
 * Merge the attributes of two elements, and make sure
 * the class names are merged properly.
 *
 * @param {Element} from
 * @param {Element} to
 */

function mergeAttrs (from, to) {
  var attrs = from.attributes
  var i = attrs.length
  var name, value
  while (i--) {
    name = attrs[i].name
    value = attrs[i].value
    if (!to.hasAttribute(name)) {
      to.setAttribute(name, value)
    } else if (name === 'class') {
      to.className = to.className + ' ' + value
    }
  }
}
<|endoftext|>


<commit_before>if (process.env.NODE_ENV != "production") {
	require('dotenv').config();
}

if (!process.env.SLACK_BOT_API_TOKEN) {
	console.log("*******************************************************************");
	console.log("process.env.SLACK_BOT_API_TOKEN not found!");
	console.log("run this script with a token like this:");
	console.log("SLACK_BOT_API_TOKEN=your-slack-bot-api-token-here nodemon dennis.js");
	console.log("or place SLACK_BOT_API_TOKEN=your-slack-bot-api-token-here in .env");
	console.log("*******************************************************************");
	throw "process.env.SLACK_BOT_API_TOKEN not found"
}

var app = require('express')();

var botkit = require('botkit');
var controller = botkit.slackbot();
var bot = controller.spawn({
	token: process.env.SLACK_BOT_API_TOKEN
})

randomMapGenerator = require("./mapGenerator.js")
mapPrinter = require("./mapPrinter.js")

games = {}

bot.startRTM(function(err, bot, payload) {
	if (err) {
		throw new Error('Could not connect to Slack');
	} else {
		console.log("connected to slack");
	}
});

controller.hears(["new game"], "direct_message", function(bot, message) {
	if ((message.user in games) && (games[message.user].gameActive == true)) {
		bot.startPrivateConversation(message, function(err, convo) {
			convo.say("you already have a game started!")
			convo.ask("would you like to start a new one?", [{
				pattern: bot.utterances.yes,
				callback: function(response, convo) {
					convo.say("Starting new game...")
					games[message.user] = {
						gameActive: true,
						map: randomMapGenerator()
					}
					convo.say("Welcome to the great and terrible dungeon of Yendor! The dungeon keeper, Rodney, has imprisoned your best friend, Dennis, in the depths below.")
					convo.say("Good luck!")
					convo.say("_type `help` to learn about commands._")
					convo.next()
				}
			}, {
				default: true,
				callback: function(response, convo) {
					convo.next()
				}
			}])

		})
	} else {
		bot.reply(message, "Starting new game...")
		games[message.user] = {
			gameActive: true,
			map: randomMapGenerator()
		}
		bot.reply(message, "Welcome to the great and terrible dungeon of Yendor! The dungeon keeper, Rodney, has imprisoned your best friend, Dennis, in the depths below.")
		bot.reply(message, "Good luck!")
		bot.reply(message, "_type `help` to learn about commands._")
	}
})

controller.hears(['map'], "direct_message", function(bot, message) {
	if (message.user in games) {
		bot.reply(message, mapPrinter(games[message.user].map))
	} else {
		bot.reply(message, "you don't have a new game started! Start one with `new game`")
	}
})

controller.hears(['.*'], "direct_message", function(bot, message) {
	bot.reply(message, "I didn't quite understand that. Type `help` to get some commands that you can use.")
})

app.get("*", function (req, res) {
	res.sendStatus(200)
})

app.listen(process.env.PORT || 3000)
<commit_msg>using persistent storage<commit_after>if (process.env.NODE_ENV != "production") {
	require('dotenv').config();
}

if (!process.env.SLACK_BOT_API_TOKEN) {
	console.log("*******************************************************************");
	console.log("process.env.SLACK_BOT_API_TOKEN not found!");
	console.log("run this script with a token like this:");
	console.log("SLACK_BOT_API_TOKEN=your-slack-bot-api-token-here nodemon dennis.js");
	console.log("or place SLACK_BOT_API_TOKEN=your-slack-bot-api-token-here in .env");
	console.log("*******************************************************************");
	throw "process.env.SLACK_BOT_API_TOKEN not found"
}

var app = require('express')();
var redisStorage = require('botkit-storage-redis')({
	url: process.env.REDIS_URL
})
var botkit = require('botkit');
var controller = botkit.slackbot({
	storage: redisStorage
});
var bot = controller.spawn({
	token: process.env.SLACK_BOT_API_TOKEN
})

randomMapGenerator = require("./mapGenerator.js")
mapPrinter = require("./mapPrinter.js")

games = {}

bot.startRTM(function(err, bot, payload) {
	if (err) {
		throw new Error('Could not connect to Slack');
	} else {
		console.log("connected to slack");
	}
});

controller.hears(["new game"], "direct_message", function(bot, message) {
	controller.storage.users.get(message.user, function(err, user_game) {
		if (user_game.gameActive == true) {
			bot.startPrivateConversation(message, function(err, convo) {
				convo.say("you already have a game started!")
				convo.ask("would you like to start a new one?", [{
					pattern: bot.utterances.yes,
					callback: function(response, convo) {
						convo.say("Starting new game...")
						controller.storage.users.save({
							id: message.user,
							gameActive: true,
							map: randomMapGenerator()
						}, function(err) {
							if (err) {
								convo.say(message, "error starting game!")
							} else {
								convo.say("Welcome to the great and terrible dungeon of Yendor! The dungeon keeper, Rodney, has imprisoned your best friend, Dennis, in the depths below.")
								convo.say("Good luck!")
								convo.say("_type `help` to learn about commands._")
								convo.next()
							}
						})

					}
				}, {
					default: true,
					callback: function(response, convo) {
						convo.next()
					}
				}])

			})
		} else {
			bot.reply(message, "Starting new game...")
			controller.storage.users.save({
				id: message.user,
				gameActive: true,
				map: randomMapGenerator()
			}, function(err) {
				if (err) {
					bot.reply(message, "error starting game!")
				} else {
					bot.reply(message, "Welcome to the great and terrible dungeon of Yendor! The dungeon keeper, Rodney, has imprisoned your best friend, Dennis, in the depths below.")
					bot.reply(message, "Good luck!")
					bot.reply(message, "_type `help` to learn about commands._")
				}
			})
		}
	})
})

controller.hears(['map'], "direct_message", function(bot, message) {
	if (message.user in games) {
		bot.reply(message, mapPrinter(games[message.user].map))
	} else {
		bot.reply(message, "you don't have a new game started! Start one with `new game`")
	}
})

controller.hears(['.*'], "direct_message", function(bot, message) {
	bot.reply(message, "I didn't quite understand that. Type `help` to get some commands that you can use.")
})

app.get("*", function(req, res) {
	res.sendStatus(200)
})

app.listen(process.env.PORT || 3000)
<|endoftext|>


<commit_before>// Pay - deploy.js

// Deploy Pay to the server

'use strict';<commit_msg>Remove js deploy<commit_after><|endoftext|>


<commit_before>'use strict'
require('shelljs/make')
const
    DEST = '/opt/theatersoft',
    DEST_CONFIG_THEATERSOFT = `${DEST}/.config/theatersoft`,
    fs = require('fs'),
    pkg = require('./package.json'),
    hostname = require('os').hostname(),
    isRoot = host => host === hostname,
    execo = c => exec(c, {silent: true}).stdout.trim(),
    write = (file, text) => fs.writeFileSync(file, text, 'utf-8'),
    writeJson = (file, json) => fs.writeFileSync(file, JSON.stringify(json, null, '  '), 'utf-8'),
    log = console.log,
    exists = f => {try {fs.accessSync(f); return true} catch (e) {return false}}

if (!exists('config.json')) {
    log('Creating config.json')
    exec(`sed 's/{{HOSTNAME}}/${hostname}/' config.json.template > config.json`)
}

const
    cfg = require('./config.json'),
    {hosts = []} = cfg

const targets = {
    config () {
        log('target config')
        exec(`mkdir -p deploy`)
        const
            find = module => execo(`${module === '@theatersoft/server' ? ''
                : 'npm explore @theatersoft/server '}npm explore ${module} pwd`),
            pack = path => pkg.theatersoft.pack
                ? execo(`cd deploy; npm pack ${path}`)
                : require(`${path}/package.json`).version,
            server = {
                "@theatersoft/server": pack(find('@theatersoft/server')),
                "@theatersoft/bus": pack(find('@theatersoft/bus'))
            },
            client = {
                "@theatersoft/client": pack(find('@theatersoft/client'))
            }

        hosts.forEach(({name, services = []}) => {
            log(`\n${name}`)

            targets.package(name, services.reduce((o, {module}) => {
                const path = find(module)
                o[module] = pack(path)
                return o
            }, Object.assign({}, server, isRoot(name) && client)))

            targets.env(name)
        })

        Object.assign(pkg.scripts, hosts.reduce((o, {name}) => {
            o[`deploy-${name}`] = `node deploy deploy -- ${name}`
            return o
        }, {}))
        writeJson('package.json', pkg)
    },

    package (host, dependencies) {
        log(dependencies)
        exec(`mkdir -p deploy/${host}`)
        const link = Object.keys(dependencies).map(d => `npm link ${d}`).join('; ')
        const start = `${pkg.deployScripts.start}${isRoot(host) ? '' : '-child'}`
        writeJson(`deploy/${host}/package.json`, Object.assign({}, pkg, {
            dependencies,
            devDependencies: undefined,
            scripts: Object.assign({}, pkg.deployScripts, {link}, {start}),
            deployScripts: undefined,
            theatersoft: undefined
        }))
    },

    env (host) {
        if (exists(`deploy/${host}/.bus`)) return
        // Create bus env
        process.env.XDG_CONFIG_HOME = `${DEST}/.config`
        const
            {createSession} = require('@theatersoft/server'),
            auth = createSession(host, undefined, '@theatersoft/home')
        if (host === hostname) {
            write(`deploy/${host}/.root`, `PORT=443\n`)
            write(`deploy/${host}/.bus`, `BUS=wss://localhost\nAUTH=${auth}\n`)
        } else {
            write(`deploy/${host}/.bus`, `BUS=wss://${hostname}.local\nAUTH=${auth}\n`)
        }
    },

    deploy (host) {
        if (!host) return hosts.forEach(({name}) => targets.deploy(name))
        if (Array.isArray(host)) host = host[0]
        log('target deploy', host)
        if (isRoot(host)) {
            // Install packages
            exec(`cp -v $(ls deploy/*.tgz) deploy/${host}/package.json COPYRIGHT LICENSE ${DEST}`)
            exec(`cp -v deploy/${host}/.bus deploy/${host}/.root ${DEST}/.config/theatersoft`)
            log(`start npm install`)
            exec(`cd ${DEST}; npm install`)
            log(`done npm install`)

            // Symlink config.json
            exec(`ln -sfvt ${DEST}/.config/theatersoft \$(pwd)/config.json`)

            // Create server TLS certificate
        } else {
            const
                ssh = c => exec(`ssh ${host}.local "${c}"`),
                scp = (s, d) => exec(`scp ${s} ${host}.local:${d || ''}`)
            ssh(`sudo mkdir -p ${DEST}`)
            ssh(`sudo chown $USER ${DEST}`)
            scp(`$(ls deploy/*.tgz) deploy/${host}/package.json COPYRIGHT LICENSE`, DEST)
            scp(`deploy/${host}/.bus`, `${DEST}/.config/theatersoft`)
            log(`start npm install`)
            ssh(`cd ${DEST}; npm install`)
            log(`done npm install`)
        }
    }
}
Object.assign(target, targets)
<commit_msg>refactor<commit_after>'use strict'
require('shelljs/make')
const
    DEST = '/opt/theatersoft',
    DEST_CONFIG_THEATERSOFT = `${DEST}/.config/theatersoft`,
    fs = require('fs'),
    pkg = require('./package.json'),
    hostname = require('os').hostname(),
    isRoot = host => host === hostname,
    execo = c => exec(c, {silent: true}).stdout.trim(),
    write = (file, text) => fs.writeFileSync(file, text, 'utf-8'),
    writeJson = (file, json) => fs.writeFileSync(file, JSON.stringify(json, null, '  '), 'utf-8'),
    log = console.log,
    exists = f => {
        try {
            fs.accessSync(f);
            return true
        } catch (e) {return false}
    },
    cfg = (!exists('config.json') && exec(`sed 's/{{HOSTNAME}}/${hostname}/' config.json.template > config.json`), require('./config.json')),
    {hosts = []} = cfg

function hostPackage (host, dependencies) {
    log(`${host}\n`, dependencies)
    exec(`mkdir -p deploy/${host}`)
    const link = Object.keys(dependencies).map(d => `npm link ${d}`).join('; ')
    const start = `${pkg.deployScripts.start}${isRoot(host) ? '' : '-child'}`
    writeJson(`deploy/${host}/package.json`, Object.assign({}, pkg, {
        dependencies,
        devDependencies: undefined,
        scripts: Object.assign({}, pkg.deployScripts, {link}, {start}),
        deployScripts: undefined,
        theatersoft: undefined
    }))
}

function hostEnv (host) {
    if (exists(`deploy/${host}/.bus`)) return
    // Create bus env
    process.env.XDG_CONFIG_HOME = `${DEST}/.config`
    const
        {createSession} = require('@theatersoft/server'),
        auth = createSession(host, undefined, '@theatersoft/home')
    if (host === hostname) {
        write(`deploy/${host}/.root`, `PORT=443\n`)
        write(`deploy/${host}/.bus`, `BUS=wss://localhost\nAUTH=${auth}\n`)
    } else {
        write(`deploy/${host}/.bus`, `BUS=wss://${hostname}.local\nAUTH=${auth}\n`)
    }
}

const targets = {
    config () {
        log('target config')
        exec(`mkdir -p deploy`)
        const
            find = module => execo(`${module === '@theatersoft/server' ? ''
                : 'npm explore @theatersoft/server '}npm explore ${module} pwd`),
            pack = path => pkg.theatersoft.pack
                ? execo(`cd deploy; npm pack ${path}`)
                : require(`${path}/package.json`).version,
            server = {
                "@theatersoft/server": pack(find('@theatersoft/server')),
                "@theatersoft/bus": pack(find('@theatersoft/bus'))
            },
            client = {
                "@theatersoft/client": pack(find('@theatersoft/client'))
            }
        hosts.forEach(({name, services = []}) => {
            hostPackage(name, services.reduce(
                (o, {module}) =>
                    (o[module] = pack(find(module)), o),
                Object.assign({}, server, isRoot(name) && client)
            ))
            hostEnv(name)
        })

        Object.assign(pkg.scripts, hosts.reduce((o, {name}) =>
            (o[`deploy-${name}`] = `node deploy deploy -- ${name}`, o), {})
        )
        writeJson('package.json', pkg)
    },

    deploy (host) {
        if (!host) return hosts.forEach(({name}) => targets.deploy(name))
        if (Array.isArray(host)) host = host[0]
        log('target deploy', host)
        if (isRoot(host)) {
            // Install packages
            exec(`cp -v $(ls deploy/*.tgz) deploy/${host}/package.json COPYRIGHT LICENSE ${DEST}`)
            exec(`cp -v deploy/${host}/.bus deploy/${host}/.root ${DEST}/.config/theatersoft`)
            log(`start npm install`)
            exec(`cd ${DEST}; npm install`)
            log(`done npm install`)

            // Symlink config.json
            exec(`ln -sfvt ${DEST}/.config/theatersoft \$(pwd)/config.json`)

            // Create server TLS certificate
        } else {
            const
                ssh = c => exec(`ssh ${host}.local "${c}"`),
                scp = (s, d) => exec(`scp ${s} ${host}.local:${d || ''}`)
            ssh(`sudo mkdir -p ${DEST}`)
            ssh(`sudo chown $USER ${DEST}`)
            scp(`$(ls deploy/*.tgz) deploy/${host}/package.json COPYRIGHT LICENSE`, DEST)
            scp(`deploy/${host}/.bus`, `${DEST}/.config/theatersoft`)
            log(`start npm install`)
            ssh(`cd ${DEST}; npm install`)
            log(`done npm install`)
        }
    }
}
Object.assign(target, targets)
<|endoftext|>


<commit_before>import React from 'react';
import { StyleSheet, Text,Button,Dimensions, View,ScrollView,StatusBar,Image } from 'react-native';
import LineChart from './ui/LineChart';
import mockData from './../assets/mockData';
import * as exchangeActions from './../actions/exchange'
import * as public_dataActions from './../actions/public_data'
import {connect} from 'react-redux'
import DropDown from './ui/DropDown';
import TouchableIcon from './ui/TouchableIcon';
import CandleChart from './ui/CandleChart';
import wsBitfinex from './../services/webSocket';
import MultiSlider from '@ptomasroos/react-native-multi-slider';

class Exchange extends React.Component{
  constructor(props){
    console.log("Exchange");
    super(props)
    this.state={sampleRatio:1};
    this.showHourly=this.showHourly.bind(this);
    this.showInMinuites=this.showInMinuites.bind(this);
    this.showlast100days=this.showlast100days.bind(this);
    this.symbolPairs=[
      {key:'BTC:USD'},
      {key:'BTC:ETH'},
      {key:'ETH:USD'},
    ];
  }
  componentDidMount() {
    const {dispatch}=this.props;
    dispatch(public_dataActions.fetchOhlcv());
  }
  componentWillReceiveProps(nextProps){
      if(nextProps.exchange.symbol1==this.props.exchange.symbol1&&nextProps.exchange.symbol2==this.props.exchange.symbol2){
        return
      }
      const {dispatch}=this.props;
      dispatch(public_dataActions.fetchOhlcv());
  }

  showHourly(){
    const {dispatch}=this.props;
    const action=exchangeActions.setTimeType('data1h');
    dispatch(action);
  }
  showInMinuites(){
    const {dispatch,exchange}=this.props;
    const action=exchangeActions.setTimeType('data1m');
    dispatch(action);
  }
  showlast100days(){
    console.log("in days");
    const {dispatch}=this.props;
    const action=exchangeActions.setTimeType('data1d');
    dispatch(action);
  }
  static navigationOptions={
    title:"Exchange",
    drawerLabel: 'Home',
    tabBarLabel: 'Exchange',
  }
  render(){
    const tabBarHeight=60,statusBarHeight=20;
    const {timeType}=this.props.exchange;
    const ohlcv=this.props.ohlcv;
    //console.log(timeType);
    const scrollStyle={height:Dimensions.get('window').height-statusBarHeight-tabBarHeight-(50)}
    return(
      <View>
        <DropDown data={this.symbolPairs}></DropDown>
        <ScrollView>
          <View style={{flex:1}}>
          <LineChart data={ohlcv} timeType={timeType}  width={Dimensions.get('screen').width} height={Dimensions.get('screen').height*2/5}  sampleRatio={1} ></LineChart>
          <Button
              onPress={this.showInMinuites}
              title="Minute"
              color="#841584"
              >
              </Button>
            <Button
              onPress={this.showHourly}
              title="Hours"
              color="#841584"
              >
              </Button>
            <Button
              onPress={this.showlast100days}
              title="Days"
              color="#841584"
              >
            </Button>
            <MultiSlider
              selectedStyle={{
                backgroundColor: 'gold',
              }}
              unselectedStyle={{
                backgroundColor: 'silver',
              }}
              values={[5,10]}
              containerStyle={{
                height:200,
                marginTop:30,
                marginBottom:20,
              }}
              container={{
                height:80,
              }}
              enabledTwo={true}
              markerContainer={{
                height:80,
              }}
              markerStyle={{
                height:30,
                marginTop:10,
                width:30,
                borderRadius:30,
              }}
              pressedMarkerStyle={{
                height:38,
                width:38,
                borderRadius:40,
              }}
              trackStyle={{
                height:10,
                backgroundColor: 'red',
              }}
              min={0}
              max={20}
              touchDimensions={{
                height: 80,
                width: 80,
                borderRadius: 20,
                slipDisplacement: 40,
              }}
              sliderLength={Dimensions.get('screen').width}
            />
          </View>

        </ScrollView>
      </View>
    )
  }
}

const mapStateToProps = state => ({
  exchange: state.exchange,
  bitfinex:state.bitfinex,
  ohlcv:state.public_data.ohlcv,
});
/* const function mapDispatchToProps(dispatch) {
   return bindActionCreators({reducer},dispatch)
 }
*/
export default connect(mapStateToProps)(Exchange);
<commit_msg>added 3 Touchable icons in exchange<commit_after>import React from 'react';
import { StyleSheet, Text,Button,Dimensions, View,ScrollView,StatusBar,Image } from 'react-native';
import LineChart from './ui/LineChart';
import mockData from './../assets/mockData';
import * as exchangeActions from './../actions/exchange'
import * as public_dataActions from './../actions/public_data'
import {connect} from 'react-redux'
import DropDown from './ui/DropDown';
import TouchableIcon from './ui/TouchableIcon';
import CandleChart from './ui/CandleChart';
import wsBitfinex from './../services/webSocket';
import MultiSlider from '@ptomasroos/react-native-multi-slider';

class Exchange extends React.Component{
  constructor(props){
    console.log("Exchange");
    super(props)
    this.state={sampleRatio:1};
    this.showHourly=this.showHourly.bind(this);
    this.showInMinuites=this.showInMinuites.bind(this);
    this.showlast100days=this.showlast100days.bind(this);
    this.symbolPairs=[
      {key:'BTC:USD'},
      {key:'BTC:ETH'},
      {key:'ETH:USD'},
    ];
  }
  componentDidMount() {
    const {dispatch}=this.props;
    dispatch(public_dataActions.fetchOhlcv());
  }
  componentWillReceiveProps(nextProps){
      if(nextProps.exchange.symbol1==this.props.exchange.symbol1&&nextProps.exchange.symbol2==this.props.exchange.symbol2){
        return
      }
      const {dispatch}=this.props;
      dispatch(public_dataActions.fetchOhlcv());
  }

  showHourly(){
    const {dispatch}=this.props;
    const action=exchangeActions.setTimeType('data1h');
    dispatch(action);
  }
  showInMinuites(){
    const {dispatch,exchange}=this.props;
    const action=exchangeActions.setTimeType('data1m');
    dispatch(action);
  }
  showlast100days(){
    console.log("in days");
    const {dispatch}=this.props;
    const action=exchangeActions.setTimeType('data1d');
    dispatch(action);
  }
  static navigationOptions={
    title:"Exchange",
    drawerLabel: 'Home',
    tabBarLabel: 'Exchange',
  }
  render(){
    const tabBarHeight=60,statusBarHeight=20;
    const {timeType}=this.props.exchange;
    const ohlcv=this.props.ohlcv;
    //console.log(timeType);
    const scrollStyle={height:Dimensions.get('window').height-statusBarHeight-tabBarHeight-(50)}
    return(
      <View>
        <DropDown data={this.symbolPairs}></DropDown>
        <ScrollView>
          <View style={{flex:1}}>
          <LineChart data={ohlcv} timeType={timeType}  width={Dimensions.get('screen').width} height={Dimensions.get('screen').height*2/5}  sampleRatio={1} ></LineChart>
          <View style={{flexDirection:'row',marginTop:20,justifyContent:'space-around'}}>
            <TouchableIcon name={'data1m'} onPress={()=>this.showInMinuites()} active={timeType} source='minutes' ></TouchableIcon>
            <TouchableIcon name={'data1h'} onPress={()=>this.showHourly()} active={timeType} source='hours' ></TouchableIcon>
            <TouchableIcon name={'data1d'} onPress={()=>this.showlast100days()} active={timeType} source='calendar' ></TouchableIcon>
          </View>
            <MultiSlider
              selectedStyle={{
                backgroundColor: 'gold',
              }}
              unselectedStyle={{
                backgroundColor: 'silver',
              }}
              values={[5,10]}
              containerStyle={{
                height:200,
                marginTop:30,
                marginBottom:20,
              }}
              container={{
                height:80,
              }}
              enabledTwo={true}
              markerContainer={{
                height:80,
              }}
              markerStyle={{
                height:30,
                marginTop:10,
                width:30,
                borderRadius:30,
              }}
              pressedMarkerStyle={{
                height:38,
                width:38,
                borderRadius:40,
              }}
              trackStyle={{
                height:10,
                backgroundColor: 'red',
              }}
              min={0}
              max={20}
              touchDimensions={{
                height: 80,
                width: 80,
                borderRadius: 20,
                slipDisplacement: 40,
              }}
              sliderLength={Dimensions.get('screen').width}
            />
          </View>

        </ScrollView>
      </View>
    )
  }
}

const mapStateToProps = state => ({
  exchange: state.exchange,
  bitfinex:state.bitfinex,
  ohlcv:state.public_data.ohlcv,
});
/* const function mapDispatchToProps(dispatch) {
   return bindActionCreators({reducer},dispatch)
 }
*/
export default connect(mapStateToProps)(Exchange);
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------*\
 |  Precache.js                                                              |
 |                                                                           |
 |  Copyright © 2017-2020, Rajiv Bakulesh Shah, original author.             |
 |                                                                           |
 |      This program is free software: you can redistribute it and/or modify |
 |      it under the terms of the GNU General Public License as published by |
 |      the Free Software Foundation, either version 3 of the License, or    |
 |      (at your option) any later version.                                  |
 |                                                                           |
 |      This program is distributed in the hope that it will be useful, but  |
 |      WITHOUT ANY WARRANTY; without even the implied warranty of           |
 |      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
 |      General Public License for more details.                             |
 |                                                                           |
 |      You should have received a copy of the GNU General Public License    |
 |      along with this program.  If not, see:                               |
 |          <http://www.gnu.org/licenses/>                                   |
\*---------------------------------------------------------------------------*/

import { useEffect } from 'react';

const querystring = require('querystring');

const getQueries = () => {
  fetch(`${process.env.REACT_APP_API}/v1/queries`)
    .then((response) => response.json())
    .then((data) => cacheQueries(data.queries))
    .catch(console.log);
};

const cacheQueries = (queries) => {
  if (queries.length) {
    const query = queries.shift();
    const urlQueryString = querystring.stringify({ q: query });
    fetch(`${process.env.REACT_APP_API}/v1/songs/search?${urlQueryString}`)
      .catch(console.log)
      .finally(() => cacheQueries(queries));
  }
};

function Precache() {
  useEffect(getQueries);

  return null;
};

export default Precache;
<commit_msg>Prefer named functions over arrow functions<commit_after>/*---------------------------------------------------------------------------*\
 |  Precache.js                                                              |
 |                                                                           |
 |  Copyright © 2017-2020, Rajiv Bakulesh Shah, original author.             |
 |                                                                           |
 |      This program is free software: you can redistribute it and/or modify |
 |      it under the terms of the GNU General Public License as published by |
 |      the Free Software Foundation, either version 3 of the License, or    |
 |      (at your option) any later version.                                  |
 |                                                                           |
 |      This program is distributed in the hope that it will be useful, but  |
 |      WITHOUT ANY WARRANTY; without even the implied warranty of           |
 |      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
 |      General Public License for more details.                             |
 |                                                                           |
 |      You should have received a copy of the GNU General Public License    |
 |      along with this program.  If not, see:                               |
 |          <http://www.gnu.org/licenses/>                                   |
\*---------------------------------------------------------------------------*/

import { useEffect } from 'react';

const querystring = require('querystring');

function getQueries() {
  fetch(`${process.env.REACT_APP_API}/v1/queries`)
    .then((response) => response.json())
    .then((data) => cacheQueries(data.queries))
    .catch(console.log);
}

function cacheQueries(queries) {
  if (queries.length) {
    const query = queries.shift();
    const urlQueryString = querystring.stringify({ q: query });
    fetch(`${process.env.REACT_APP_API}/v1/songs/search?${urlQueryString}`)
      .catch(console.log)
      .finally(() => cacheQueries(queries));
  }
}

function Precache() {
  useEffect(getQueries);

  return null;
};

export default Precache;
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'react-apollo'
import Votes from './Votes'
import { flyingHearts, DEFAULT_PROFILE_PIC, ALERT_DEFAULT } from '../utils/helpers'
import TimeAgo from 'react-timeago'
import TweetParser from './TweetParser'
import Alert from 'react-s-alert'

import ModeratorOptions from './ModeratorOptions'

import CREATE_VOTE_MUTATION from '../graphql/Vote.mutation.gql'

class Question extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
      votes: this.props.question._votesMeta.count,
      isTheAuthor: this.isTheAuthor(this.props.auth.userId),
    }
    this.props.auth.on('user-id-updated', this.updateState.bind(this))
  }

  updateState(userId) {
    this.setState({
      isTheAuthor: this.isTheAuthor(userId),
    })
  }

  isTheAuthor(userId) {
    let questionUserId

    if (this.props.question && this.props.question.user) {
      questionUserId = this.props.question.user.id
    }
    return (userId === questionUserId)
  }

  componentDidMount() {
    // not working for now
    // window.scroll({ top: this.elem.scrollHeight, left: 0, behavior: 'smooth' })
  }

  componentWillReceiveProps(nextProps) {
    // re-render only when votes have changed
    if (nextProps.question && this.props.question) {
      let newVotes = nextProps.question._votesMeta.count
      let currentVotes = this.props.question._votesMeta.count

      if (newVotes !== currentVotes) {
        this.setState({
          votes: newVotes,
        })
      }
    }
  }

  componentWillUnmount() {
    this.props.auth.removeListener('user-id-updated', this.updateState.bind(this))
  }

  formatter(value, unit, suffix, date, defaultFormatter) {
    if (unit === 'second' && value < 60) {
      return 'just now'
    }
    return defaultFormatter(value, unit, suffix, date)
  }

  onSubmit() {
    this.setState({
      votes: this.state.votes+1,
      isTheAuthor: this.isTheAuthor(this.props.auth.userId),
    })
    this.props
      .vote(this.props.question.id)
      .catch(e => {
        if (e.graphQLErrors) {
          e.graphQLErrors.forEach(error => {
            switch (error.code) {
              case 3023:
                break
              default:
                console.error(error)
            }
          }, this)
        }
      })
    flyingHearts('.flying-hearts')
  }

  flagUser(question) {
    this.props.flag(question.id, question.flagged).then(() => {
      this.props.flagUser(question.user.id, question.user.flagged)
    })
  }
  flagQuestion(question) {
    this.props.flag(question.id, question.flagged)
  }

  roles() {
    if (this.props.auth.role && this.props.auth.role!=='User') {
      return (

          <button className='btn btn-primary' onClick={() => this.flagUser(this.props.question)}>
            Flag User
          </button>
          <button className='btn btn-primary' onClick={() => this.flagQuestion(this.props.question)}>
            Flag Question
          </button>

      )
    }
  }

  render() {
    // hide flagged questions from users
    if (this.props.question.flagged && (this.props.auth.role==='User' || !this.props.auth.role)) {
      return null
    }
    return (

 (this.elem = elem)}>

              <TweetParser parseUsers={false} parseUrls={false} hashtagClass={'twitter'} userClass={'twitter'} >{this.props.question.body}</TweetParser>

            <Votes votes={this.state.votes} />

by {this.props.question.user? this.props.question.user.username : '@happylama'}
                , <TimeAgo date={this.props.question.createdAt} formatter={this.formatter} />

              <button className='btn btn-circle'
                onClick={e => this.onSubmit()} disabled={this.state.isTheAuthor}>

              </button>

        <ModeratorOptions
          question={this.props.question}
          role={this.props.auth.role} />

    )
  }
}

const withVote = graphql(CREATE_VOTE_MUTATION,
  {
    props: ({ mutate }) => ({
      vote(id) {
        return mutate({
          variables: { question: id },
        }).catch(error => {
          Alert.error(error.message, ALERT_DEFAULT)
        })
      },
    }),
  },
)

Question.propTypes = {
  question: PropTypes.object.isRequired,
  auth: PropTypes.object.isRequired,
}

export default withVote(Question)
<commit_msg>Disable voting button for flagged questions<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import { graphql } from 'react-apollo'
import Votes from './Votes'
import { flyingHearts, DEFAULT_PROFILE_PIC, ALERT_DEFAULT } from '../utils/helpers'
import TimeAgo from 'react-timeago'
import TweetParser from './TweetParser'
import Alert from 'react-s-alert'

import ModeratorOptions from './ModeratorOptions'

import CREATE_VOTE_MUTATION from '../graphql/Vote.mutation.gql'

class Question extends React.Component {

  constructor(props) {
    super(props)
    this.state = {
      votes: this.props.question._votesMeta.count,
      isTheAuthor: this.isTheAuthor(this.props.auth.userId),
    }
    this.props.auth.on('user-id-updated', this.updateState.bind(this))
  }

  updateState(userId) {
    this.setState({
      isTheAuthor: this.isTheAuthor(userId),
    })
  }

  isTheAuthor(userId) {
    let questionUserId

    if (this.props.question && this.props.question.user) {
      questionUserId = this.props.question.user.id
    }
    return (userId === questionUserId)
  }

  componentDidMount() {
    // not working for now
    // window.scroll({ top: this.elem.scrollHeight, left: 0, behavior: 'smooth' })
  }

  componentWillReceiveProps(nextProps) {
    // re-render only when votes have changed
    if (nextProps.question && this.props.question) {
      let newVotes = nextProps.question._votesMeta.count
      let currentVotes = this.props.question._votesMeta.count

      if (newVotes !== currentVotes) {
        this.setState({
          votes: newVotes,
        })
      }
    }
  }

  componentWillUnmount() {
    this.props.auth.removeListener('user-id-updated', this.updateState.bind(this))
  }

  formatter(value, unit, suffix, date, defaultFormatter) {
    if (unit === 'second' && value < 60) {
      return 'just now'
    }
    return defaultFormatter(value, unit, suffix, date)
  }

  onSubmit() {
    this.setState({
      votes: this.state.votes+1,
      isTheAuthor: this.isTheAuthor(this.props.auth.userId),
    })
    this.props
      .vote(this.props.question.id)
      .catch(e => {
        if (e.graphQLErrors) {
          e.graphQLErrors.forEach(error => {
            switch (error.code) {
              case 3023:
                break
              default:
                console.error(error)
            }
          }, this)
        }
      })
    flyingHearts('.flying-hearts')
  }

  flagUser(question) {
    this.props.flag(question.id, question.flagged).then(() => {
      this.props.flagUser(question.user.id, question.user.flagged)
    })
  }
  flagQuestion(question) {
    this.props.flag(question.id, question.flagged)
  }

  render() {
    // hide flagged questions from users
    if (this.props.question.flagged && (this.props.auth.role==='User' || !this.props.auth.role)) {
      return null
    }
    return (

 (this.elem = elem)}>

              <TweetParser parseUsers={false} parseUrls={false} hashtagClass={'twitter'} userClass={'twitter'} >{this.props.question.body}</TweetParser>

            <Votes votes={this.state.votes} />

by {this.props.question.user? this.props.question.user.username : '@happylama'}
                , <TimeAgo date={this.props.question.createdAt} formatter={this.formatter} />

              <button className='btn btn-circle'
                onClick={e => this.onSubmit()} disabled={this.state.isTheAuthor || this.props.question.flagged}>

              </button>

        <ModeratorOptions
          question={this.props.question}
          role={this.props.auth.role} />

    )
  }
}

const withVote = graphql(CREATE_VOTE_MUTATION,
  {
    props: ({ mutate }) => ({
      vote(id) {
        return mutate({
          variables: { question: id },
        }).catch(error => {
          Alert.error(error.message, ALERT_DEFAULT)
        })
      },
    }),
  },
)

Question.propTypes = {
  question: PropTypes.object.isRequired,
  auth: PropTypes.object.isRequired,
}

export default withVote(Question)
<|endoftext|>


<commit_before>import React from 'react'
import Todo from './Todo'

export default class TodoList extends React.Component {

  _filterTodos = todo => (
    this.props.filter === 'SHOW_ALL' ||
    this.props.filter === 'SHOW_ACTIVE' && !todo.complete ||
    this.props.filter === 'SHOW_COMPLETED' && todo.complete
  )

  renderTodos () {
    return this.props.todos
      .filter(this._filterTodos)
      .reverse()
      .map(todo =>
        <Todo
          key={todo.id}
          todo={todo}
          toggleTodo={this.props.toggleTodo}
        />
      )
  }

  render () {
    return (

        {this.renderTodos()}

    )
  }
}
<commit_msg>Remove className<commit_after>import React from 'react'
import Todo from './Todo'

export default class TodoList extends React.Component {

  _filterTodos = todo => (
    this.props.filter === 'SHOW_ALL' ||
    this.props.filter === 'SHOW_ACTIVE' && !todo.complete ||
    this.props.filter === 'SHOW_COMPLETED' && todo.complete
  )

  renderTodos () {
    return this.props.todos
      .filter(this._filterTodos)
      .reverse()
      .map(todo =>
        <Todo
          key={todo.id}
          todo={todo}
          toggleTodo={this.props.toggleTodo}
        />
      )
  }

  render () {
    return (

        {this.renderTodos()}

    )
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, Matt Godbolt
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const chai = require('chai'),
    FakeCompiler = require('../../lib/compilers/fake-for-test'),
    CompilationEnvironment = require('../../lib/compilation-env'),
    chaiAsPromised = require("chai-as-promised"),
    parsers = require('../../lib/compilers/argument-parsers'),
    CompilerArguments = require('../../lib/compiler-arguments'),
    properties = require('../../lib/properties');
chai.use(chaiAsPromised);
const should = chai.should();

const languages = {
    'c++': {id: 'c++'}
};

const compilerProps = new properties.CompilerProps(languages, properties.fakeProps({}));

function makeCompiler(stdout, stderr, code) {
    if (code === undefined) code = 0;
    const env = new CompilationEnvironment(compilerProps);
    const compiler = new FakeCompiler({lang: languages['c++'].id, remote: true}, env);
    compiler.exec = () => Promise.resolve({code: code, stdout: stdout || "", stderr: stderr || ""});
    compiler.possibleArguments = new CompilerArguments("g82");
    return compiler;
}

describe('option parser', () => {
    it('should do nothing for the base parser', () => {
        const compiler = makeCompiler();
        return parsers.Base.parse(compiler).should.deep.equals(compiler);
    });
    it('should handle empty options', () => {
        return parsers.Base.getOptions(makeCompiler()).should.eventually.deep.equals({});
    });
    it('should parse single-dash options', () => {
        return parsers.Base.getOptions(makeCompiler("-foo\n")).should.eventually.deep.equals({'-foo': {"description": "", "timesused": 0}});
    });
    it('should parse double-dash options', () => {
        return parsers.Base.getOptions(makeCompiler("--foo\n")).should.eventually.deep.equals({'--foo': {"description": "", "timesused": 0}});
    });
    it('should parse stderr options', () => {
        return parsers.Base.getOptions(makeCompiler("", "--bar=monkey\n")).should.eventually.deep.equals({'--bar=monkey': {"description": "", "timesused": 0}});
    });
    it('handles non-option text', () => {
        return parsers.Base.getOptions(makeCompiler("-foo=123\nthis is a fish\n-badger=123")).should.eventually.deep.equals(
            {'-foo=123': {"description": "this is a fish", "timesused": 0}, '-badger=123': {"description": "", "timesused": 0}});
    });
    it('should ignore if errors occur', () => {
        return parsers.Base.getOptions(makeCompiler("--foo\n", "--bar\n", 1)).should.eventually.deep.equals({});
    });
});

describe('gcc parser', () => {
    it('should handle empty options', () => {
        return parsers.GCC.parse(makeCompiler()).should.eventually.satisfy(result => {
            return Promise.all([
                should.not.equal(result.compiler.supportsGccDump, true),
                result.compiler.options.should.equals('')
            ]);
        });
    });
    it('should handle options', () => {
        return parsers.GCC.parse(makeCompiler("-masm=intel\n-fdiagnostics-color=[blah]\n-fdump-tree-all"))
            .should.eventually.satisfy(result => {
                return Promise.all([
                    result.compiler.supportsGccDump.should.equals(true),
                    result.compiler.supportsIntel.should.equals(true),
                    result.compiler.intelAsm.should.equals('-masm=intel'),
                    result.compiler.options.should.equals('-fdiagnostics-color=always')
                ]);
            });
    });
    it('should handle undefined options', () => {
        return parsers.GCC.parse(makeCompiler("-fdiagnostics-color=[blah]")).should.eventually.satisfy(result => {
            return Promise.all([
                result.compiler.options.should.equals('-fdiagnostics-color=always')
            ]);
        });
    });
});

describe('clang parser', () => {
    it('should handle empty options', () => {
        return parsers.Clang.parse(makeCompiler()).should.eventually.satisfy(result => {
            return Promise.all([
                result.compiler.options.should.equals('')
            ]);
        });
    });
    it('should handle options', () => {
        return parsers.Clang.parse(makeCompiler("-fsave-optimization-record\n-fcolor-diagnostics"))
            .should.eventually.satisfy(result => {
                return Promise.all([
                    result.compiler.supportsOptOutput.should.equals(true),
                    result.compiler.optArg.should.equals('-fsave-optimization-record'),
                    result.compiler.options.should.equals('-fcolor-diagnostics')
                ]);
            });
    });
    it("should add '-fno-crash-diagnostics' and '-fcolor-diagnostics' when supported", () => {
        const compiler = new FakeCompiler({});
        compiler.possibleArguments = new CompilerArguments("fake");
        compiler.exec = () => Promise.resolve({
          code: 0,
          stdout: "-O3\n-fno-crash-diagnostics\n-Wall\n",
          stderr: ""
        });

        return parsers.Clang.parse(compiler)
            .should.eventually.satisfy(result => {
                return Promise.all([
                    result.compiler.options.includes("-fno-crash-diagnostics").should.be.true,
                    result.compiler.options.includes("-fcolor-diagnostics").should.be.false,
                    result.compiler.options.includes("-Wall").should.be.false,
                ]);
            });
    });
});

describe('popular compiler arguments', () => {
    let compiler = makeCompiler("-fsave-optimization-record\n-x\n-g\n-fcolor-diagnostics\n-O<number> optimization level\n-std=<c++11,c++14,c++17z>")

    it('should return 5 arguments', () => {
        return parsers.Clang.parse(compiler).then(compiler => {
            return compiler.should.satisfy(compiler => {
                return Promise.all([
                    compiler.possibleArguments.getPopularArguments().should.deep.equal({
                        "-O<number>": {description: "optimization level", timesused: 0},
                        "-fcolor-diagnostics": {"description": "", "timesused": 0},
                        "-fsave-optimization-record": {"description": "", "timesused": 0},
                        "-g": {"description": "", "timesused": 0},
                        "-x": {"description": "", "timesused": 0}
                    })
                ]);
            });
        })
    });

    it('should return arguments except the ones excluded', () => {
        return parsers.Clang.parse(compiler).then(compiler => {
            return compiler.should.satisfy(compiler => {
                return Promise.all([
                    compiler.possibleArguments.getPopularArguments(["-O3", "--hello"]).should.deep.equal({
                        "-fcolor-diagnostics": {"description": "", "timesused": 0},
                        "-fsave-optimization-record": {"description": "", "timesused": 0},
                        "-g": {"description": "", "timesused": 0},
                        "-x": {"description": "", "timesused": 0},
                        "-std=<c++11,c++14,c++17z>": {"description": "", "timesused": 0}
                    })
                ]);
            });
        })
    });

    it('should be able to exclude special params with assignments', () => {
        return parsers.Clang.parse(compiler).then(compiler => {
            return compiler.should.satisfy(compiler => {
                return Promise.all([
                    compiler.possibleArguments.getPopularArguments(["-std=c++14", "-g", "--hello"]).should.deep.equal({
                        "-O<number>": {description: "optimization level", timesused: 0},
                        "-fcolor-diagnostics": {"description": "", "timesused": 0},
                        "-fsave-optimization-record": {"description": "", "timesused": 0},
                        "-x": {"description": "", "timesused": 0}
                    })
                ]);
            });
        })
    });
});
<commit_msg>oops, extending the existing test instead<commit_after>// Copyright (c) 2017, Matt Godbolt
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

const chai = require('chai'),
    FakeCompiler = require('../../lib/compilers/fake-for-test'),
    CompilationEnvironment = require('../../lib/compilation-env'),
    chaiAsPromised = require("chai-as-promised"),
    parsers = require('../../lib/compilers/argument-parsers'),
    CompilerArguments = require('../../lib/compiler-arguments'),
    properties = require('../../lib/properties');
chai.use(chaiAsPromised);
const should = chai.should();

const languages = {
    'c++': {id: 'c++'}
};

const compilerProps = new properties.CompilerProps(languages, properties.fakeProps({}));

function makeCompiler(stdout, stderr, code) {
    if (code === undefined) code = 0;
    const env = new CompilationEnvironment(compilerProps);
    const compiler = new FakeCompiler({lang: languages['c++'].id, remote: true}, env);
    compiler.exec = () => Promise.resolve({code: code, stdout: stdout || "", stderr: stderr || ""});
    compiler.possibleArguments = new CompilerArguments("g82");
    return compiler;
}

describe('option parser', () => {
    it('should do nothing for the base parser', () => {
        const compiler = makeCompiler();
        return parsers.Base.parse(compiler).should.deep.equals(compiler);
    });
    it('should handle empty options', () => {
        return parsers.Base.getOptions(makeCompiler()).should.eventually.deep.equals({});
    });
    it('should parse single-dash options', () => {
        return parsers.Base.getOptions(makeCompiler("-foo\n")).should.eventually.deep.equals({'-foo': {"description": "", "timesused": 0}});
    });
    it('should parse double-dash options', () => {
        return parsers.Base.getOptions(makeCompiler("--foo\n")).should.eventually.deep.equals({'--foo': {"description": "", "timesused": 0}});
    });
    it('should parse stderr options', () => {
        return parsers.Base.getOptions(makeCompiler("", "--bar=monkey\n")).should.eventually.deep.equals({'--bar=monkey': {"description": "", "timesused": 0}});
    });
    it('handles non-option text', () => {
        return parsers.Base.getOptions(makeCompiler("-foo=123\nthis is a fish\n-badger=123")).should.eventually.deep.equals(
            {'-foo=123': {"description": "this is a fish", "timesused": 0}, '-badger=123': {"description": "", "timesused": 0}});
    });
    it('should ignore if errors occur', () => {
        return parsers.Base.getOptions(makeCompiler("--foo\n", "--bar\n", 1)).should.eventually.deep.equals({});
    });
});

describe('gcc parser', () => {
    it('should handle empty options', () => {
        return parsers.GCC.parse(makeCompiler()).should.eventually.satisfy(result => {
            return Promise.all([
                should.not.equal(result.compiler.supportsGccDump, true),
                result.compiler.options.should.equals('')
            ]);
        });
    });
    it('should handle options', () => {
        return parsers.GCC.parse(makeCompiler("-masm=intel\n-fdiagnostics-color=[blah]\n-fdump-tree-all"))
            .should.eventually.satisfy(result => {
                return Promise.all([
                    result.compiler.supportsGccDump.should.equals(true),
                    result.compiler.supportsIntel.should.equals(true),
                    result.compiler.intelAsm.should.equals('-masm=intel'),
                    result.compiler.options.should.equals('-fdiagnostics-color=always')
                ]);
            });
    });
    it('should handle undefined options', () => {
        return parsers.GCC.parse(makeCompiler("-fdiagnostics-color=[blah]")).should.eventually.satisfy(result => {
            return Promise.all([
                result.compiler.options.should.equals('-fdiagnostics-color=always')
            ]);
        });
    });
});

describe('clang parser', () => {
    it('should handle empty options', () => {
        return parsers.Clang.parse(makeCompiler()).should.eventually.satisfy(result => {
            return Promise.all([
                result.compiler.options.should.equals('')
            ]);
        });
    });
    it('should handle options', () => {
        return parsers.Clang.parse(makeCompiler("-fno-crash-diagnostics\n-fsave-optimization-record\n-fcolor-diagnostics"))
            .should.eventually.satisfy(result => {
                return Promise.all([
                    result.compiler.supportsOptOutput.should.equals(true),
                    result.compiler.optArg.should.equals('-fsave-optimization-record'),

                    result.compiler.options.should.include("-fcolor-diagnostics"),
                    result.compiler.options.should.include("-fno-crash-diagnostics"),
                    result.compiler.options.should.not.include("-fsave-optimization-record"),
                ]);
            });
    });
});

describe('popular compiler arguments', () => {
    let compiler = makeCompiler("-fsave-optimization-record\n-x\n-g\n-fcolor-diagnostics\n-O<number> optimization level\n-std=<c++11,c++14,c++17z>")

    it('should return 5 arguments', () => {
        return parsers.Clang.parse(compiler).then(compiler => {
            return compiler.should.satisfy(compiler => {
                return Promise.all([
                    compiler.possibleArguments.getPopularArguments().should.deep.equal({
                        "-O<number>": {description: "optimization level", timesused: 0},
                        "-fcolor-diagnostics": {"description": "", "timesused": 0},
                        "-fsave-optimization-record": {"description": "", "timesused": 0},
                        "-g": {"description": "", "timesused": 0},
                        "-x": {"description": "", "timesused": 0}
                    })
                ]);
            });
        })
    });

    it('should return arguments except the ones excluded', () => {
        return parsers.Clang.parse(compiler).then(compiler => {
            return compiler.should.satisfy(compiler => {
                return Promise.all([
                    compiler.possibleArguments.getPopularArguments(["-O3", "--hello"]).should.deep.equal({
                        "-fcolor-diagnostics": {"description": "", "timesused": 0},
                        "-fsave-optimization-record": {"description": "", "timesused": 0},
                        "-g": {"description": "", "timesused": 0},
                        "-x": {"description": "", "timesused": 0},
                        "-std=<c++11,c++14,c++17z>": {"description": "", "timesused": 0}
                    })
                ]);
            });
        })
    });

    it('should be able to exclude special params with assignments', () => {
        return parsers.Clang.parse(compiler).then(compiler => {
            return compiler.should.satisfy(compiler => {
                return Promise.all([
                    compiler.possibleArguments.getPopularArguments(["-std=c++14", "-g", "--hello"]).should.deep.equal({
                        "-O<number>": {description: "optimization level", timesused: 0},
                        "-fcolor-diagnostics": {"description": "", "timesused": 0},
                        "-fsave-optimization-record": {"description": "", "timesused": 0},
                        "-x": {"description": "", "timesused": 0}
                    })
                ]);
            });
        })
    });
});
<|endoftext|>


<commit_before><commit_msg>sphere is working<commit_after><|endoftext|>


<commit_before>'use strict';

var sinon = require('sinon');
var should = require('should');
var StatusController = require('../lib/status');

describe('Status', function() {
  describe('/status', function() {
    var info = {
      version: 110000,
      protocolversion: 70002,
      blocks: 548645,
      timeoffset: 0,
      connections: 8,
      difficulty: 21546.906405522557,
      testnet: true,
      relayfee: 1000,
      errors: ''
    };

    var outSetInfo = {
      height: 151,
      bestblock: '20b6cc0600037171b8bb634bbd04ea754945be44db8d9199b74798f1abdb382d',
      transactions: 151,
      txouts: 151,
      bytes_serialized: 10431,
      hash_serialized: 'c165d5dcb22a897745ee2ee274b47133b995bbcf8dd4a7572fedad87541c7df8',
      total_amount: 750000000000
    };

    var node = {
      services: {
        bitcoind: {
          getInfo: sinon.stub().returns(info),
          getBestBlockHash: sinon.stub().returns(outSetInfo.bestblock)
        },
        db: {
          tip: {
            hash: outSetInfo.bestblock
          }
        }
      }
    };

    var status = new StatusController(node);

    it('getInfo', function(done) {
      var req = {
        query: {}
      };
      var res = {
        jsonp: function(data) {
          should.exist(data.info.version);
          should.exist(data.info.protocolversion);
          should.exist(data.info.blocks);
          should.exist(data.info.timeoffset);
          should.exist(data.info.connections);
          should.exist(data.info.difficulty);
          should.exist(data.info.testnet);
          should.exist(data.info.relayfee);
          done();
        }
      };

      status.show(req, res);
    });

    it('getDifficulty', function(done) {
      var req = {
        query: {
          q: 'getDifficulty'
        }
      };
      var res = {
        jsonp: function(data) {
          data.difficulty.should.equal(info.difficulty);
          done();
        }
      };

      status.show(req, res);
    });

    it('getBestBlockHash', function(done) {
      var req = {
        query: {
          q: 'getBestBlockHash'
        }
      };
      var res = {
        jsonp: function(data) {
          data.bestblockhash.should.equal(outSetInfo.bestblock);
          done();
        }
      };
      status.show(req, res);
    });

    it('getLastBlockHash', function(done) {
      var req = {
        query: {
          q: 'getLastBlockHash'
        }
      };
      var res = {
        jsonp: function(data) {
          data.syncTipHash.should.equal(outSetInfo.bestblock);
          data.lastblockhash.should.equal(outSetInfo.bestblock);
          done();
        }
      };
      status.show(req, res);
    });

  });

  describe('/sync', function() {
    it('should have correct data', function(done) {
      var node = {
        services: {
          db: {
            tip: {
              __height: 500000
            }
          },
          bitcoind: {
            height: 500000,
            isSynced: sinon.stub().returns(true),
            syncPercentage: sinon.stub().returns(99.99)
          }
        }
      };

      var expected = {
        status: 'finished',
        blockChainHeight: 500000,
        syncPercentage: 100,
        height: 500000,
        error: null,
        type: 'bitcore node'
      };

      var status = new StatusController(node);

      var req = {};
      var res = {
        jsonp: function(data) {
          should(data).eql(expected);
          done();
        }
      };
      status.sync(req, res);
    });
  });

  describe('/peer', function() {
    it('should have correct data', function(done) {
      var node = {};

      var expected = {
        connected: true,
        host: '127.0.0.1',
        port: null
      };

      var req = {};
      var res = {
        jsonp: function(data) {
          should(data).eql(expected);
          done();
        }
      };

      var status = new StatusController(node);

      status.peer(req, res);
    });
  });

  describe('/version', function() {
    it('should have correct data', function(done) {
      var node = {};
      var expected = {
        version: '0.3.0'
      };

      var req = {};
      var res = {
        jsonp: function(data) {
          should(data).eql(expected);
          done();
        }
      };

      var status = new StatusController(node);
      status.version(req, res);
    });
  });
});
<commit_msg>Fix test to pull version from package.json<commit_after>'use strict';

var sinon = require('sinon');
var should = require('should');
var StatusController = require('../lib/status');

describe('Status', function() {
  describe('/status', function() {
    var info = {
      version: 110000,
      protocolversion: 70002,
      blocks: 548645,
      timeoffset: 0,
      connections: 8,
      difficulty: 21546.906405522557,
      testnet: true,
      relayfee: 1000,
      errors: ''
    };

    var outSetInfo = {
      height: 151,
      bestblock: '20b6cc0600037171b8bb634bbd04ea754945be44db8d9199b74798f1abdb382d',
      transactions: 151,
      txouts: 151,
      bytes_serialized: 10431,
      hash_serialized: 'c165d5dcb22a897745ee2ee274b47133b995bbcf8dd4a7572fedad87541c7df8',
      total_amount: 750000000000
    };

    var node = {
      services: {
        bitcoind: {
          getInfo: sinon.stub().returns(info),
          getBestBlockHash: sinon.stub().returns(outSetInfo.bestblock)
        },
        db: {
          tip: {
            hash: outSetInfo.bestblock
          }
        }
      }
    };

    var status = new StatusController(node);

    it('getInfo', function(done) {
      var req = {
        query: {}
      };
      var res = {
        jsonp: function(data) {
          should.exist(data.info.version);
          should.exist(data.info.protocolversion);
          should.exist(data.info.blocks);
          should.exist(data.info.timeoffset);
          should.exist(data.info.connections);
          should.exist(data.info.difficulty);
          should.exist(data.info.testnet);
          should.exist(data.info.relayfee);
          done();
        }
      };

      status.show(req, res);
    });

    it('getDifficulty', function(done) {
      var req = {
        query: {
          q: 'getDifficulty'
        }
      };
      var res = {
        jsonp: function(data) {
          data.difficulty.should.equal(info.difficulty);
          done();
        }
      };

      status.show(req, res);
    });

    it('getBestBlockHash', function(done) {
      var req = {
        query: {
          q: 'getBestBlockHash'
        }
      };
      var res = {
        jsonp: function(data) {
          data.bestblockhash.should.equal(outSetInfo.bestblock);
          done();
        }
      };
      status.show(req, res);
    });

    it('getLastBlockHash', function(done) {
      var req = {
        query: {
          q: 'getLastBlockHash'
        }
      };
      var res = {
        jsonp: function(data) {
          data.syncTipHash.should.equal(outSetInfo.bestblock);
          data.lastblockhash.should.equal(outSetInfo.bestblock);
          done();
        }
      };
      status.show(req, res);
    });

  });

  describe('/sync', function() {
    it('should have correct data', function(done) {
      var node = {
        services: {
          db: {
            tip: {
              __height: 500000
            }
          },
          bitcoind: {
            height: 500000,
            isSynced: sinon.stub().returns(true),
            syncPercentage: sinon.stub().returns(99.99)
          }
        }
      };

      var expected = {
        status: 'finished',
        blockChainHeight: 500000,
        syncPercentage: 100,
        height: 500000,
        error: null,
        type: 'bitcore node'
      };

      var status = new StatusController(node);

      var req = {};
      var res = {
        jsonp: function(data) {
          should(data).eql(expected);
          done();
        }
      };
      status.sync(req, res);
    });
  });

  describe('/peer', function() {
    it('should have correct data', function(done) {
      var node = {};

      var expected = {
        connected: true,
        host: '127.0.0.1',
        port: null
      };

      var req = {};
      var res = {
        jsonp: function(data) {
          should(data).eql(expected);
          done();
        }
      };

      var status = new StatusController(node);

      status.peer(req, res);
    });
  });

  describe('/version', function() {
    it('should have correct data', function(done) {
      var node = {};
      var expected = {
        version: require('../package.json').version
      };

      var req = {};
      var res = {
        jsonp: function(data) {
          should(data).eql(expected);
          done();
        }
      };

      var status = new StatusController(node);
      status.version(req, res);
    });
  });
});
<|endoftext|>


<commit_before>/**
 * @author Benjamin Hollis
 *
 * This component provides a stream converter that can translate from JSON to HTML.
 * It is compatible with Firefox 3 and up, since it uses many components that are new
 * to Firefox 3.
 */

// Save some tedious typing
const Ci = Components.interfaces;
const Cc = Components.classes;

// Import XPCOMUtils to help set up our JSONView XPCOM component (new to FF3)
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

/*
 * The JSONFormatter helper object. This contains two major functions, jsonToHTML and errorPage,
 * each of which returns an HTML document.
 */
function JSONFormatter() {
}
JSONFormatter.prototype = {
  htmlEncode: function (t) {
    return t != null ? t.toString().replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">") : '';
  },

  // Completely escape strings, taking care to return common escape codes to their short forms
  jsString: function(s) {
    // the JSON serializer escapes everything to the long-form \uXXXX
    // escape code. This is a map of characters to return to the short-escaped
    // form after escaping.
    var has = {
      '\b': 'b',
      '\f': 'f',
      '\r': 'r',
      '\n': 'n',
      '\t': 't'
    }, ws;
    for (ws in has) {
      if (-1 === s.indexOf(ws)) {
        delete has[ws];
      }
    }

    s = JSON.stringify(s).slice(1, -1);

    for (ws in has) {
      s = s.replace(new RegExp('\\\\u000' + (ws.charCodeAt().toString(16)), 'ig'),
                    '\\' + has[ws]);
    }

    return this.htmlEncode(s);
  },

  decorateWithSpan: function (value, className) {
    return '' + this.htmlEncode(value) + '';
  },

  // Convert a basic JSON datatype (number, string, boolean, null, object, array) into an HTML fragment.
  valueToHTML: function(value) {
    var valueType = typeof value;

    var output = "";
    if (value == null) {
      output += this.decorateWithSpan('null', 'null');
    }
    else if (value && value.constructor == Array) {
      output += this.arrayToHTML(value);
    }
    else if (valueType == 'object') {
      output += this.objectToHTML(value);
    }
    else if (valueType == 'number') {
      output += this.decorateWithSpan(value, 'num');
    }
    else if (valueType == 'string') {
      if (/^(http|https):\/\/[^\s]+$/i.test(value)) {
        output += '' + this.jsString(value) + '';
      } else {
        output += '"' + this.jsString(value) + '"';
      }
    }
    else if (valueType == 'boolean') {
      output += this.decorateWithSpan(value, 'bool');
    }

    return output;
  },

  // Convert an array into an HTML fragment
  arrayToHTML: function(json) {
    var output = '[
';
    var hasContents = false;
    for ( var prop in json ) {
      hasContents = true;
      output += '
';
      output += this.valueToHTML(json[prop]);
      output += '
';
    }
    output += '
]';

    if ( ! hasContents ) {
      output = "[ ]";
    }

    return output;
  },

  // Convert a JSON object to an HTML fragment
  objectToHTML: function(json) {
    var output = '{
';
    var hasContents = false;
    for ( var prop in json ) {
      hasContents = true;
      output += '
';
      output += '' + this.jsString(prop) + ': '
      output += this.valueToHTML(json[prop]);
      output += '
';
    }
    output += '
}';

    if ( ! hasContents ) {
      output = "{ }";
    }

    return output;
  },

  // Convert a whole JSON value / JSONP response into a formatted HTML document
  jsonToHTML: function(json, callback, uri) {
    var output = '
' +
                 this.valueToHTML(json) +
                 '
';
    if (callback) {
      output = '
' + callback + '(
' +
               output +
               '
)
';
    }
    return this.toHTML(output, uri);
  },

  // lazy load the translations
  getStringBundle: function() {
    if (this.stringbundle) {
      return this.stringbundle;
    }

    var src = 'chrome://jsonview/locale/jsonview.properties';
    var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);

    var appLocale = localeService.getApplicationLocale();
    var stringBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
    this.stringbundle = stringBundleService.createBundle(src, appLocale);
    return this.stringbundle;
  },

  // Produce an error document for when parsing fails.
  errorPage: function(error, data, uri) {
    var stringbundle = this.getStringBundle();

    var output = '
' + stringbundle.GetStringFromName('errorParsing') + '
';
    output += '
' + stringbundle.GetStringFromName('docContents') + ':
';
    output += '
' + this.htmlEncode(data) + '
';
    return this.toHTML(output, uri + ' - Error');
  },

  // Wrap the HTML fragment in a full document. Used by jsonToHTML and errorPage.
  toHTML: function(content, title) {
    return '<!DOCTYPE html>\n' +
      '<title>' + this.htmlEncode(title) + '</title>' +
      '<link rel="stylesheet" type="text/css" href="chrome://jsonview/content/default.css">' +
      '' +
      '' +
      content +
      '';
  }
};

// This component is an implementation of nsIStreamConverter that converts application/json to html
const JSONVIEW_CONVERSION =
    "?from=application/json&to=*/*";
const JSONVIEW_CONTRACT_ID =
    "@mozilla.org/streamconv;1" + JSONVIEW_CONVERSION;
const JSONVIEW_COMPONENT_ID =
    Components.ID("{64890660-53c4-11dd-ae16-0800200c9a66}");

// JSONView class constructor. Not much to see here.
function JSONView() {
  this.jsonFormatter = new JSONFormatter();
};

// This defines an object that implements our converter, and is set up to be XPCOM-ified by XPCOMUtils
JSONView.prototype = {

  // properties required for XPCOM registration:
  classDescription: "JSONView XPCOM Component",
  classID:          JSONVIEW_COMPONENT_ID,
  contractID:       JSONVIEW_CONTRACT_ID,

  _xpcom_categories: [{
    category: "@mozilla.org/streamconv;1",
    entry: JSONVIEW_CONVERSION,
    value: "JSON to HTML stream converter"
  }],

  QueryInterface: XPCOMUtils.generateQI([
      Ci.nsISupports,
      Ci.nsIStreamConverter,
      Ci.nsIStreamListener,
      Ci.nsIRequestObserver
  ]),

  // Lazy getter for the native JSON implementation, new to FF3
  getNativeJSON: function() {
    if (this.nativeJSON) {
      return this.nativeJSON;
    }
    this.nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
    return this.nativeJSON;
  },

  /*
   * This component works as such:
   * 1. asyncConvertData captures the listener
   * 2. onStartRequest fires, initializes stuff, modifies the listener to match our output type
   * 3. onDataAvailable transcodes the data into a UTF-8 string
   * 4. onStopRequest gets the collected data and converts it, spits it to the listener
   * 5. convert does nothing, it's just the synchronous version of asyncConvertData
   */

  // nsIStreamConverter::convert
  convert: function (aFromStream, aFromType, aToType, aCtxt) {
      return aFromStream;
  },

  // nsIStreamConverter::asyncConvertData
  asyncConvertData: function (aFromType, aToType, aListener, aCtxt) {
    // Store the listener passed to us
    this.listener = aListener;
  },

  // nsIStreamListener::onDataAvailable
  onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
    // From https://developer.mozilla.org/en/Reading_textual_data
    var is = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
    is.init(aInputStream, this.charset, -1, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);

    var str = {};

    // This used to read in a loop until readString returned 0, but it caused it to crash Firefox on OSX/Win32 (but not Win64)
    // It seems just reading once with -1 (default buffer size) gets the file done.
    // However, *not* reading in a loop seems to cause problems with Firebug
    // So I read in a loop, but do whatever I can to avoid infinite-looping.
    var totalBytesRead = 0;
    var bytesRead = 1; // Seed it with something positive

    while (totalBytesRead < aCount && bytesRead > 0) {
      bytesRead = is.readString(-1, str);
      totalBytesRead += bytesRead;
      this.data += str.value;
    }

  },

  // nsIRequestObserver::onStartRequest
  onStartRequest: function (aRequest, aContext) {
    this.data = '';
    this.uri = aRequest.QueryInterface(Ci.nsIChannel).URI.spec;

    // Sets the charset if it is available. (For documents loaded from the
    // filesystem, this is not set.)
    this.charset = aRequest.QueryInterface(Ci.nsIChannel).contentCharset || 'UTF-8';

    this.channel = aRequest;
    this.channel.contentType = "text/html";
    // All our data will be coerced to UTF-8
    this.channel.contentCharset = "UTF-8";

    this.listener.onStartRequest (this.channel, aContext);
  },

  // nsIRequestObserver::onStopRequest
  onStopRequest: function (aRequest, aContext, aStatusCode) {
    /*
     * This should go something like this:
     * 1. Make sure we have a unicode string.
     * 2. Convert it to a Javascript object.
     * 2.1 Removes the callback
     * 3. Convert that to HTML? Or XUL?
     * 4. Spit it back out at the listener
     */

    var converter = Components
        .classes["@mozilla.org/intl/scriptableunicodeconverter"]
        .createInstance(Ci.nsIScriptableUnicodeConverter);
    converter.charset = this.charset;
    var outputDoc = "";

    var cleanData = '',
        callback = '';

    // This regex attempts to match a JSONP structure:
    //    * Any amount of whitespace (including unicode nonbreaking spaces) between the start of the file and the callback name
    //    * Callback name (any valid JavaScript function name according to ECMA-262 Edition 3 spec)
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Open parentheses
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Either { or [, the only two valid characters to start a JSON string.
    //    * Any character, any number of times
    //    * Either } or ], the only two valid closing characters of a JSON string.
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * A closing parenthesis, an optional semicolon, and any amount of whitespace (including unicode nonbreaking spaces) until the end of the file.
    // This will miss anything that has comments, or more than one callback, or requires modification before use.
    var callback_results = /^[\s\u200B\uFEFF]*([\w$\[\]\.]+)[\s\u200B\uFEFF]*\([\s\u200B\uFEFF]*([\[{][\s\S]*[\]}])[\s\u200B\uFEFF]*\);?[\s\u200B\uFEFF]*$/.exec(this.data);
    if( callback_results && callback_results.length == 3 ){
      callback = callback_results[1];
      cleanData = callback_results[2];
    }else{
      cleanData = this.data;
    }

    try {
      var nativeJSON = this.getNativeJSON();
      var jsonObj = nativeJSON.decode(cleanData);
      outputDoc = this.jsonFormatter.jsonToHTML(jsonObj, callback, this.uri);
    }
    catch(e) {
      outputDoc = this.jsonFormatter.errorPage(e, this.data, this.uri);
    }

    // I don't really understand this part, but basically it's a way to get our UTF-8 stuff
    // spit back out as a byte stream
    // See http://www.mail-archive.com/mozilla-xpcom@mozilla.org/msg04194.html
    var storage = Cc["@mozilla.org/storagestream;1"]
    .createInstance(Ci.nsIStorageStream);

    // I have no idea what to pick for the first parameter (segments)
    storage.init(4, 0xffffffff, null);
    var out = storage.getOutputStream(0);

    var binout = Cc["@mozilla.org/binaryoutputstream;1"]
    .createInstance(Ci.nsIBinaryOutputStream);
    binout.setOutputStream(out);
    binout.writeUtf8Z(outputDoc);
    binout.close();

    // I can't explain it, but we need to trim 4 bytes off the front or else it includes random crap
    var trunc = 4;
    var instream = storage.newInputStream(trunc);

    // Pass the data to the main content listener
    this.listener.onDataAvailable(this.channel, aContext, instream, 0, storage.length - trunc);

    this.listener.onStopRequest(this.channel, aContext, aStatusCode);
  }
};

// We only have one component to register
var components = [JSONView];

// The actual hook into XPCOM
if (XPCOMUtils.generateNSGetFactory) {
  // Gecko 2 (FF4) uses a different component registration strategy and registers categories in chrome.manifest
  var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
} else {
  // Older Firefox requires manually setting up category entries
  var NSGetModule = function NSGetModule(compMgr, fileSpec){
    function postRegister(){
      var catMgr = XPCOMUtils.categoryManager;
      catMgr.addCategoryEntry('ext-to-type-mapping', 'json', 'application/json', true, true);
    }

    function preUnregister(){
      var catMgr = XPCOMUtils.categoryManager;
      catMgr.addCategoryEntry('ext-to-type-mapping', 'json', true);
    }

    return XPCOMUtils.generateModule(components, postRegister, preUnregister);
  };
}<commit_msg>Code style cleanup, remove some unused stuff, don't keep the JSON service around<commit_after>/**
 * @author Benjamin Hollis
 *
 * This component provides a stream converter that can translate from JSON to HTML.
 * It is compatible with Firefox 3 and up, since it uses many components that are new
 * to Firefox 3.
 */

// Save some tedious typing
const Ci = Components.interfaces;
const Cc = Components.classes;

// Import XPCOMUtils to help set up our JSONView XPCOM component (new to FF3)
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");

/*
 * The JSONFormatter helper object. This contains two major functions, jsonToHTML and errorPage,
 * each of which returns an HTML document.
 */
function JSONFormatter() {
}

JSONFormatter.prototype = {
  htmlEncode: function (t) {
    return t != null ? t.toString().replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">") : '';
  },

  // Completely escape strings, taking care to return common escape codes to their short forms
  jsString: function(s) {
    // the JSON serializer escapes everything to the long-form \uXXXX
    // escape code. This is a map of characters to return to the short-escaped
    // form after escaping.
    var has = {
      '\b': 'b',
      '\f': 'f',
      '\r': 'r',
      '\n': 'n',
      '\t': 't'
    }, ws;
    for (ws in has) {
      if (-1 === s.indexOf(ws)) {
        delete has[ws];
      }
    }

    s = JSON.stringify(s).slice(1, -1);

    for (ws in has) {
      s = s.replace(new RegExp('\\\\u000' + (ws.charCodeAt().toString(16)), 'ig'),
                    '\\' + has[ws]);
    }

    return this.htmlEncode(s);
  },

  decorateWithSpan: function (value, className) {
    return '' + this.htmlEncode(value) + '';
  },

  // Convert a basic JSON datatype (number, string, boolean, null, object, array) into an HTML fragment.
  valueToHTML: function(value) {
    var valueType = typeof value;

    var output = "";
    if (value == null) {
      output += this.decorateWithSpan('null', 'null');
    }
    else if (value && value.constructor == Array) {
      output += this.arrayToHTML(value);
    }
    else if (valueType == 'object') {
      output += this.objectToHTML(value);
    }
    else if (valueType == 'number') {
      output += this.decorateWithSpan(value, 'num');
    }
    else if (valueType == 'string') {
      if (/^(http|https):\/\/[^\s]+$/i.test(value)) {
        output += '' + this.jsString(value) + '';
      } else {
        output += '"' + this.jsString(value) + '"';
      }
    }
    else if (valueType == 'boolean') {
      output += this.decorateWithSpan(value, 'bool');
    }

    return output;
  },

  // Convert an array into an HTML fragment
  arrayToHTML: function(json) {
    var hasContents = false;
    var output = '';
    for ( var prop in json ) {
      hasContents = true;
      output += '
' + this.valueToHTML(json[prop]) + '
';
    }

    if ( hasContents ) {
      output = '[
' + output + '
]';
    } else {
      output = '[ ]';
    }

    return output;
  },

  // Convert a JSON object to an HTML fragment
  objectToHTML: function(json) {
    var hasContents = false;
    var output = '';
    for ( var prop in json ) {
      hasContents = true;
      output += '
' + this.jsString(prop) +
                ': ' + this.valueToHTML(json[prop]) + '
';
    }

    if ( hasContents ) {
      output = '{
' + output + '
}';
    } else {
      output = '{ }';
    }

    return output;
  },

  // Convert a whole JSON value / JSONP response into a formatted HTML document
  jsonToHTML: function(json, callback, uri) {
    var output = '
' +
                 this.valueToHTML(json) +
                 '
';
    if (callback) {
      output = '
' + callback + '(
' +
               output +
               '
)
';
    }
    return this.toHTML(output, uri);
  },

  // lazy load the translations
  getStringBundle: function() {
    if (this.stringbundle) {
      return this.stringbundle;
    }

    var src = 'chrome://jsonview/locale/jsonview.properties';
    var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci.nsILocaleService);

    var appLocale = localeService.getApplicationLocale();
    var stringBundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
    this.stringbundle = stringBundleService.createBundle(src, appLocale);
    return this.stringbundle;
  },

  // Produce an error document for when parsing fails.
  errorPage: function(error, data, uri) {
    var stringbundle = this.getStringBundle();

    var output = '
' + stringbundle.GetStringFromName('errorParsing') + '
' +
                 '
' + stringbundle.GetStringFromName('docContents') + ':
' +
                 '
' + this.htmlEncode(data) + '
';
    return this.toHTML(output, uri + ' - Error');
  },

  // Wrap the HTML fragment in a full document. Used by jsonToHTML and errorPage.
  toHTML: function(content, title) {
    return '<!DOCTYPE html>\n' +
      '<title>' + this.htmlEncode(title) + '</title>' +
      '<link rel="stylesheet" type="text/css" href="chrome://jsonview/content/default.css">' +
      '' +
      '' +
      content +
      '';
  }
};

// This component is an implementation of nsIStreamConverter that converts application/json to html
const JSONVIEW_CONVERSION =
    "?from=application/json&to=*/*";
const JSONVIEW_CONTRACT_ID =
    "@mozilla.org/streamconv;1" + JSONVIEW_CONVERSION;
const JSONVIEW_COMPONENT_ID =
    Components.ID("{64890660-53c4-11dd-ae16-0800200c9a66}");

// JSONView class constructor. Not much to see here.
function JSONView() {
  this.jsonFormatter = new JSONFormatter();
};

// This defines an object that implements our converter, and is set up to be XPCOM-ified by XPCOMUtils
JSONView.prototype = {

  // properties required for XPCOM registration:
  classDescription: "JSONView XPCOM Component",
  classID:          JSONVIEW_COMPONENT_ID,
  contractID:       JSONVIEW_CONTRACT_ID,

  _xpcom_categories: [{
    category: "@mozilla.org/streamconv;1",
    entry: JSONVIEW_CONVERSION,
    value: "JSON to HTML stream converter"
  }],

  QueryInterface: XPCOMUtils.generateQI([
      Ci.nsISupports,
      Ci.nsIStreamConverter,
      Ci.nsIStreamListener,
      Ci.nsIRequestObserver
  ]),

  /*
   * This component works as such:
   * 1. asyncConvertData captures the listener
   * 2. onStartRequest fires, initializes stuff, modifies the listener to match our output type
   * 3. onDataAvailable transcodes the data into a UTF-8 string
   * 4. onStopRequest gets the collected data and converts it, spits it to the listener
   * 5. convert does nothing, it's just the synchronous version of asyncConvertData
   */

  // nsIStreamConverter::convert
  convert: function (aFromStream, aFromType, aToType, aCtxt) {
      return aFromStream;
  },

  // nsIStreamConverter::asyncConvertData
  asyncConvertData: function (aFromType, aToType, aListener, aCtxt) {
    // Store the listener passed to us
    this.listener = aListener;
  },

  // nsIStreamListener::onDataAvailable
  onDataAvailable: function (aRequest, aContext, aInputStream, aOffset, aCount) {
    // From https://developer.mozilla.org/en/Reading_textual_data
    var is = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
    is.init(aInputStream, this.charset, -1, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);

    var str = {};

    // This used to read in a loop until readString returned 0, but it caused it to crash Firefox on OSX/Win32 (but not Win64)
    // It seems just reading once with -1 (default buffer size) gets the file done.
    // However, *not* reading in a loop seems to cause problems with Firebug
    // So I read in a loop, but do whatever I can to avoid infinite-looping.
    var totalBytesRead = 0;
    var bytesRead = 1; // Seed it with something positive

    while (totalBytesRead < aCount && bytesRead > 0) {
      bytesRead = is.readString(-1, str);
      totalBytesRead += bytesRead;
      this.data += str.value;
    }

  },

  // nsIRequestObserver::onStartRequest
  onStartRequest: function (aRequest, aContext) {
    this.data = '';
    this.uri = aRequest.QueryInterface(Ci.nsIChannel).URI.spec;

    // Sets the charset if it is available. (For documents loaded from the
    // filesystem, this is not set.)
    this.charset = aRequest.QueryInterface(Ci.nsIChannel).contentCharset || 'UTF-8';

    this.channel = aRequest;
    this.channel.contentType = "text/html";
    // All our data will be coerced to UTF-8
    this.channel.contentCharset = "UTF-8";

    this.listener.onStartRequest (this.channel, aContext);
  },

  // nsIRequestObserver::onStopRequest
  onStopRequest: function (aRequest, aContext, aStatusCode) {
    /*
     * This should go something like this:
     * 1. Make sure we have a unicode string.
     * 2. Convert it to a Javascript object.
     * 2.1 Removes the callback
     * 3. Convert that to HTML? Or XUL?
     * 4. Spit it back out at the listener
     */

    var outputDoc = '',
        cleanData = '',
        callback = '';

    // This regex attempts to match a JSONP structure:
    //    * Any amount of whitespace (including unicode nonbreaking spaces) between the start of the file and the callback name
    //    * Callback name (any valid JavaScript function name according to ECMA-262 Edition 3 spec)
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Open parentheses
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * Either { or [, the only two valid characters to start a JSON string.
    //    * Any character, any number of times
    //    * Either } or ], the only two valid closing characters of a JSON string.
    //    * Any amount of whitespace (including unicode nonbreaking spaces)
    //    * A closing parenthesis, an optional semicolon, and any amount of whitespace (including unicode nonbreaking spaces) until the end of the file.
    // This will miss anything that has comments, or more than one callback, or requires modification before use.
    var callback_results = /^[\s\u200B\uFEFF]*([\w$\[\]\.]+)[\s\u200B\uFEFF]*\([\s\u200B\uFEFF]*([\[{][\s\S]*[\]}])[\s\u200B\uFEFF]*\);?[\s\u200B\uFEFF]*$/.exec(this.data);
    if (callback_results && callback_results.length == 3) {
      callback = callback_results[1];
      cleanData = callback_results[2];
    } else {
      cleanData = this.data;
    }

    try {
      var nativeJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
      var jsonObj = nativeJSON.decode(cleanData);
      outputDoc = this.jsonFormatter.jsonToHTML(jsonObj, callback, this.uri);
    }
    catch(e) {
      outputDoc = this.jsonFormatter.errorPage(e, this.data, this.uri);
    }

    // I don't really understand this part, but basically it's a way to get our UTF-8 stuff
    // spit back out as a byte stream
    // See http://www.mail-archive.com/mozilla-xpcom@mozilla.org/msg04194.html
    var storage = Cc["@mozilla.org/storagestream;1"].createInstance(Ci.nsIStorageStream);

    // I have no idea what to pick for the first parameter (segments)
    storage.init(4, 0xffffffff, null);
    var out = storage.getOutputStream(0);

    var binout = Cc["@mozilla.org/binaryoutputstream;1"]
    .createInstance(Ci.nsIBinaryOutputStream);
    binout.setOutputStream(out);
    binout.writeUtf8Z(outputDoc);
    binout.close();

    // I can't explain it, but we need to trim 4 bytes off the front or else it includes random crap
    var trunc = 4;
    var instream = storage.newInputStream(trunc);

    // Pass the data to the main content listener
    this.listener.onDataAvailable(this.channel, aContext, instream, 0, storage.length - trunc);

    this.listener.onStopRequest(this.channel, aContext, aStatusCode);
  }
};

// We only have one component to register
var components = [JSONView];

// The actual hook into XPCOM
if (XPCOMUtils.generateNSGetFactory) {
  // Gecko 2 (FF4) uses a different component registration strategy and registers categories in chrome.manifest
  var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
} else {
  // Older Firefox requires manually setting up category entries
  var NSGetModule = function NSGetModule(compMgr, fileSpec){
    function postRegister(){
      var catMgr = XPCOMUtils.categoryManager;
      catMgr.addCategoryEntry('ext-to-type-mapping', 'json', 'application/json', true, true);
    }

    function preUnregister(){
      var catMgr = XPCOMUtils.categoryManager;
      catMgr.addCategoryEntry('ext-to-type-mapping', 'json', true);
    }

    return XPCOMUtils.generateModule(components, postRegister, preUnregister);
  };
}<|endoftext|>