<commit_before>import React from 'react';
import Countdown from './countdown/countdown';
import firebase from 'firebase';
import { Link } from 'react-router';

class Quiz extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			hasQuizStarted: false,
			questionsWithShuffledAnswers: [],
      currentQuestion: 0,
      initialCountdownTime: 20,
      remainingTime: 20,
      hasUserAnswered: false,
      hasAnsweredCorrectly: false,
      correctAnswer: null,
      pointsThisQuestion: 0,
      timePerQuestion: {},
      totalScoreForQuiz: 0,
      perfectScoreForQuiz: 0
    }
    this.shuffleAnswers = this.shuffleAnswers.bind(this);
    this.startQuiz = this.startQuiz.bind(this);
    this.updateTimer = this.updateTimer.bind(this);
    this.checkCorrectness = this.checkCorrectness.bind(this);
    this.calculateScore = this.calculateScore.bind(this);
    this.advanceQuiz = this.advanceQuiz.bind(this);
	}

	componentWillReceiveProps(nextProps) {
		if (nextProps.questions) {
			this.shuffleAnswers(nextProps.questions);
		}
	}

	prepareForQuiz() {
		return (

Ready to start the quiz?

				<button className="btn" onClick={ () => this.startQuiz() }>Click here!</button>

		)
	}

	displayQuiz() {
		const { questionsWithShuffledAnswers,
						currentQuestion,
						remainingTime,
						hasUserAnswered,
						timePerQuestion,
						pointsThisQuestion,
						hasAnsweredCorrectly,
						totalScoreForQuiz } = this.state;

		if (questionsWithShuffledAnswers.length < 1) {
			return (
Quiz is loading...
)

		} else if ( questionsWithShuffledAnswers.length < (currentQuestion + 1) ) {
			return (

Your final score is { totalScoreForQuiz }

						<Link to="/">Return to all Quizzes</Link>

				)

		} else {
			return (questionsWithShuffledAnswers.map((question, i) => {

				return (

 { question.text }

						{ question.answers.map( (answer, index) => (
							<button key={index}
											value={answer}
											disabled={ hasUserAnswered }
											className={answer + " btn answer-btn"}
											onClick={ (evt) => this.checkCorrectness(evt.target.value, currentQuestion) } >
								{ answer }
							</button>
						) ) }

						{ hasUserAnswered === true ?

									{ hasAnsweredCorrectly === true ?

You answered the question correctly, you get {pointsThisQuestion} points
 :

You answered the question incorrectly. You get 0 new points...
 }

Your score is { totalScoreForQuiz }

									<button onClick={(evt) => this.advanceQuiz(evt.target.value, currentQuestion)}>Next Question</button>

							: null }

				)}
			))
		}
	}

	render() {
		const { hasQuizStarted,
						hasUserAnswered,
						currentQuestion,
						questionsWithShuffledAnswers,
						remainingTime,
						timePerQuestion } = this.state;

		// before the quiz starts, display a welcome screen and ask the user for action to start the quiz
		return (

				{ hasQuizStarted ? this.displayQuiz() : this.prepareForQuiz() }

				{ hasUserAnswered || !hasQuizStarted ?
					(

) :
					(<Countdown currentQuestion={ currentQuestion }
									 		amountOfQuestions= { questionsWithShuffledAnswers.length }
									 		remainingTime={ remainingTime }
									 		updateTimer={ this.updateTimer }
									 		checkCorrectness={ this.checkCorrectness }
									 		timePerQuestion={ timePerQuestion }/>) }

		)
	}

	shuffleAnswers(questions) {
		const length = questions.length;
		// putting all the answers together in order to shuffle them
		let questionsWithShuffledAnswers = [];

		// the if statement part is necessary so that when component first mounts, the code does not break
		if (length < 1) {
			return;
		} else {
			// loop through all the questions and shuffle the answers
			for (let i = 0; i < length; i++) {
				let shuffledAnswers = [];
				let currentQuestion = questions[i].text;
				let currentSetOfAnswers = questions[i].answers;

				// push all the current answers into shuffledAnswers array
				currentSetOfAnswers.incorrect.map((incorrectAnswer) => shuffledAnswers.push(incorrectAnswer));
				shuffledAnswers.push(currentSetOfAnswers.correct);

				// shuffle shuffledAnswers array
				let currentIndex = shuffledAnswers.length;
				let temporaryValue;
				let randomIndex;

				// While there remain elements to shuffle...
				while (0 !== currentIndex) {

					// Pick a remaining element...
					randomIndex = Math.floor(Math.random() * currentIndex);
					currentIndex -= 1;

					// And swap it with the current element.
					temporaryValue = shuffledAnswers[currentIndex];
					shuffledAnswers[currentIndex] = shuffledAnswers[randomIndex];
					shuffledAnswers[randomIndex] = temporaryValue;
				}

				// push an object containing the shuffledAnswers & the question into the questionsWithShuffledAnswers array
				questionsWithShuffledAnswers.push({
					text: currentQuestion,
					answers: shuffledAnswers
				});
			}

			// update questionsWithShuffledAnswers and reset the countdown to initial time
			this.setState({
				questionsWithShuffledAnswers: questionsWithShuffledAnswers,
				remainingTime: this.state.initialCountdownTime
			})
		}
	}

	startQuiz() {
		this.setState({
			hasQuizStarted: true
		});
	}

	checkCorrectness(answer, index) {
		const { timePerQuestion, currentQuestion, remainingTime } = this.state;
		let correctAnswer = this.props.questions[index].answers.correct;

		this.displayCorrectAnswer(correctAnswer);

		// if the correct answer is chosen, pair the remaining time
		// and the question index in an object and add it to timePerQuestion object
		if (answer === correctAnswer) {
			timePerQuestion[index] = remainingTime;
			this.setState({
				timePerQuestion: timePerQuestion,
				hasAnsweredCorrectly: true
			});
			this.calculateScore(timePerQuestion);

		} else {
		// else if the wrong answer is chosen, pair 0 with the question index
		// and add it to timePerQuestion object
			timePerQuestion[index] = 0;
			this.setState({
				timePerQuestion: timePerQuestion
			});
			this.calculateScore(timePerQuestion);
		}
	}

	updateTimer(newTime) {
		this.setState({
			remainingTime: newTime
		});
	}

	componentDidUpdate() {
		// if the quiz is over checks whether userHighestScore passed as props is higher than
		// the new total score, if it isn't or that userHighestScore is 0, updates firebase with userHighestScore
		if (this.state.currentQuestion === this.state.questionsWithShuffledAnswers.length &&
				this.state.questionsWithShuffledAnswers.length > 0) {
			if (this.state.totalScoreForQuiz > this.props.userHighestScore || this.props.userHighestScore === 0) {
				this.props.setUserHighestScore(this.state.totalScoreForQuiz);
				this.props.setPerfectScore(this.state.perfectScoreForQuiz);
			}
		}
	}

	calculateScore(allPoints){
		allPoints = Object.values(allPoints);
		allPoints = allPoints.map(Number);
		const pointsLength = allPoints.length;

		let streakArray = [];

		allPoints = allPoints.map((num, i) => {
			if (num === 0) {
				streakArray = [];
			} else {

				if (streakArray.length == 0 ) { // there is no streak so stays
					streakArray.push(num);

				} else if (streakArray.length !== 0){ // streak so multiply
					streakArray.push(num);
					let newMultiplier = ((streakArray.length * 2) / 10) + 1;
					num = (num * newMultiplier);

				}
				let perfectNum;

				if (i === 0) {
					perfectNum = 20;
				} else {
					perfectNum = (((pointsLength - 1) * 2) / 10) + 1;
					perfectNum = (20 * perfectNum);
				}
				this.setState({
					perfectScoreForQuiz: perfectNum,
				});
			}
			return Math.round(num);
		});

		const result = allPoints.reduce((a, b) => a + b, 0);
		const pointsThisQuestion = allPoints[allPoints.length-1];
		// console.log(allPoints + ' add up to the all points ' + result);

		this.setState({
			totalScoreForQuiz: result,
			pointsThisQuestion: pointsThisQuestion
		});
	}

	displayCorrectAnswer(correctAnswer){
		this.setState({
			hasUserAnswered: true,
			correctAnswer: correctAnswer
		});
	}

	advanceQuiz(index, currentQuestion){
		// move advancing quiz by updating state here so it can be called when appropriate
		this.setState({
			currentQuestion: (currentQuestion + 1),
			remainingTime: this.state.initialCountdownTime,
			hasUserAnswered: false
		})
	}
}

export default Quiz;<commit_msg>chore: polish little bits of css for ooh la la factor<commit_after>import React from 'react';
import Countdown from './countdown/countdown';
import firebase from 'firebase';
import { Link } from 'react-router';

class Quiz extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			hasQuizStarted: false,
			questionsWithShuffledAnswers: [],
      currentQuestion: 0,
      initialCountdownTime: 20,
      remainingTime: 20,
      hasUserAnswered: false,
      hasAnsweredCorrectly: false,
      correctAnswer: null,
      pointsThisQuestion: 0,
      timePerQuestion: {},
      totalScoreForQuiz: 0,
      perfectScoreForQuiz: 0
    }
    this.shuffleAnswers = this.shuffleAnswers.bind(this);
    this.startQuiz = this.startQuiz.bind(this);
    this.updateTimer = this.updateTimer.bind(this);
    this.checkCorrectness = this.checkCorrectness.bind(this);
    this.calculateScore = this.calculateScore.bind(this);
    this.advanceQuiz = this.advanceQuiz.bind(this);
	}

	componentWillReceiveProps(nextProps) {
		if (nextProps.questions) {
			this.shuffleAnswers(nextProps.questions);
		}
	}

	prepareForQuiz() {
		return (

Ready to start the quiz?

				<button className="btn" onClick={ () => this.startQuiz() }>Click here!</button>

		)
	}

	displayQuiz() {
		const { questionsWithShuffledAnswers,
						currentQuestion,
						remainingTime,
						hasUserAnswered,
						timePerQuestion,
						pointsThisQuestion,
						hasAnsweredCorrectly,
						totalScoreForQuiz } = this.state;

		if (questionsWithShuffledAnswers.length < 1) {
			return (
Quiz is loading...
)

		} else if ( questionsWithShuffledAnswers.length < (currentQuestion + 1) ) {
			return (

Your final score is { totalScoreForQuiz }

						<Link to="/">Return to all Quizzes</Link>

				)

		} else {
			return (questionsWithShuffledAnswers.map((question, i) => {

				return (

 { question.text }

						{ question.answers.map( (answer, index) => (
							<button key={index}
											value={answer}
											disabled={ hasUserAnswered }
											className={answer + " btn answer-btn"}
											onClick={ (evt) => this.checkCorrectness(evt.target.value, currentQuestion) } >
								{ answer }
							</button>
						) ) }

						{ hasUserAnswered === true ?

									{ hasAnsweredCorrectly === true ?

You answered the question correctly, you get {pointsThisQuestion} points
 :

You answered the question incorrectly. You get 0 new points...
 }

Your score is { totalScoreForQuiz }

									<button onClick={(evt) => this.advanceQuiz(evt.target.value, currentQuestion)}>Next Question</button>

							: null }

				)}
			))
		}
	}

	render() {
		const { hasQuizStarted,
						hasUserAnswered,
						currentQuestion,
						questionsWithShuffledAnswers,
						remainingTime,
						timePerQuestion } = this.state;

		// before the quiz starts, display a welcome screen and ask the user for action to start the quiz
		return (

				{ hasQuizStarted ? this.displayQuiz() : this.prepareForQuiz() }

				{ hasUserAnswered || !hasQuizStarted ?
					(

) :
					(<Countdown currentQuestion={ currentQuestion }
									 		amountOfQuestions= { questionsWithShuffledAnswers.length }
									 		remainingTime={ remainingTime }
									 		updateTimer={ this.updateTimer }
									 		checkCorrectness={ this.checkCorrectness }
									 		timePerQuestion={ timePerQuestion }/>) }

		)
	}

	shuffleAnswers(questions) {
		const length = questions.length;
		// putting all the answers together in order to shuffle them
		let questionsWithShuffledAnswers = [];

		// the if statement part is necessary so that when component first mounts, the code does not break
		if (length < 1) {
			return;
		} else {
			// loop through all the questions and shuffle the answers
			for (let i = 0; i < length; i++) {
				let shuffledAnswers = [];
				let currentQuestion = questions[i].text;
				let currentSetOfAnswers = questions[i].answers;

				// push all the current answers into shuffledAnswers array
				currentSetOfAnswers.incorrect.map((incorrectAnswer) => shuffledAnswers.push(incorrectAnswer));
				shuffledAnswers.push(currentSetOfAnswers.correct);

				// shuffle shuffledAnswers array
				let currentIndex = shuffledAnswers.length;
				let temporaryValue;
				let randomIndex;

				// While there remain elements to shuffle...
				while (0 !== currentIndex) {

					// Pick a remaining element...
					randomIndex = Math.floor(Math.random() * currentIndex);
					currentIndex -= 1;

					// And swap it with the current element.
					temporaryValue = shuffledAnswers[currentIndex];
					shuffledAnswers[currentIndex] = shuffledAnswers[randomIndex];
					shuffledAnswers[randomIndex] = temporaryValue;
				}

				// push an object containing the shuffledAnswers & the question into the questionsWithShuffledAnswers array
				questionsWithShuffledAnswers.push({
					text: currentQuestion,
					answers: shuffledAnswers
				});
			}

			// update questionsWithShuffledAnswers and reset the countdown to initial time
			this.setState({
				questionsWithShuffledAnswers: questionsWithShuffledAnswers,
				remainingTime: this.state.initialCountdownTime
			})
		}
	}

	startQuiz() {
		this.setState({
			hasQuizStarted: true
		});
	}

	checkCorrectness(answer, index) {
		const { timePerQuestion, currentQuestion, remainingTime } = this.state;
		let correctAnswer = this.props.questions[index].answers.correct;

		this.displayCorrectAnswer(correctAnswer);

		// if the correct answer is chosen, pair the remaining time
		// and the question index in an object and add it to timePerQuestion object
		if (answer === correctAnswer) {
			timePerQuestion[index] = remainingTime;
			this.setState({
				timePerQuestion: timePerQuestion,
				hasAnsweredCorrectly: true
			});
			this.calculateScore(timePerQuestion);

		} else {
		// else if the wrong answer is chosen, pair 0 with the question index
		// and add it to timePerQuestion object
			timePerQuestion[index] = 0;
			this.setState({
				timePerQuestion: timePerQuestion
			});
			this.calculateScore(timePerQuestion);
		}
	}

	updateTimer(newTime) {
		this.setState({
			remainingTime: newTime
		});
	}

	componentDidUpdate() {
		// if the quiz is over checks whether userHighestScore passed as props is higher than
		// the new total score, if it isn't or that userHighestScore is 0, updates firebase with userHighestScore
		if (this.state.currentQuestion === this.state.questionsWithShuffledAnswers.length &&
				this.state.questionsWithShuffledAnswers.length > 0) {
			if (this.state.totalScoreForQuiz > this.props.userHighestScore || this.props.userHighestScore === 0) {
				this.props.setUserHighestScore(this.state.totalScoreForQuiz);
				this.props.setPerfectScore(this.state.perfectScoreForQuiz);
			}
		}
	}

	calculateScore(allPoints){
		allPoints = Object.values(allPoints);
		allPoints = allPoints.map(Number);
		const pointsLength = allPoints.length;

		let streakArray = [];

		allPoints = allPoints.map((num, i) => {
			if (num === 0) {
				streakArray = [];
			} else {

				if (streakArray.length == 0 ) { // there is no streak so stays
					streakArray.push(num);

				} else if (streakArray.length !== 0){ // streak so multiply
					streakArray.push(num);
					let newMultiplier = ((streakArray.length * 2) / 10) + 1;
					num = (num * newMultiplier);

				}
				let perfectNum;

				if (i === 0) {
					perfectNum = 20;
				} else {
					perfectNum = (((pointsLength - 1) * 2) / 10) + 1;
					perfectNum = (20 * perfectNum);
				}
				this.setState({
					perfectScoreForQuiz: perfectNum,
				});
			}
			return Math.round(num);
		});

		const result = allPoints.reduce((a, b) => a + b, 0);
		const pointsThisQuestion = allPoints[allPoints.length-1];
		// console.log(allPoints + ' add up to the all points ' + result);

		this.setState({
			totalScoreForQuiz: result,
			pointsThisQuestion: pointsThisQuestion
		});
	}

	displayCorrectAnswer(correctAnswer){
		this.setState({
			hasUserAnswered: true,
			correctAnswer: correctAnswer
		});
	}

	advanceQuiz(index, currentQuestion){
		// move advancing quiz by updating state here so it can be called when appropriate
		this.setState({
			currentQuestion: (currentQuestion + 1),
			remainingTime: this.state.initialCountdownTime,
			hasUserAnswered: false
		})
	}
}

export default Quiz;<|endoftext|>


<commit_before>var fs = require('fs'),
    events = require('events'),
    buffer = require('buffer'),
    http = require('http'),
    url = require('url'),
    path = require('path');

this.version = [0, 6, 0];

var mime = require('./node-static/mime');
var util = require('./node-static/util');

var serverInfo = 'node-static/' + this.version.join('.');

// In-memory file store
this.store = {};
this.indexStore = {};

this.Server = function (root, options) {
    if (root && (typeof(root) === 'object')) { options = root, root = null }

    this.root    = path.resolve(root || '.');
    this.options = options || {};
    this.cache   = 3600;

    this.defaultHeaders  = {};
    this.options.headers = this.options.headers || {};

    if ('cache' in this.options) {
        if (typeof(this.options.cache) === 'number') {
            this.cache = this.options.cache;
        } else if (! this.options.cache) {
            this.cache = false;
        }
    }

    if (this.cache !== false) {
        this.defaultHeaders['Cache-Control'] = 'max-age=' + this.cache;
    }
    this.defaultHeaders['Server'] = serverInfo;

    for (var k in this.defaultHeaders) {
        this.options.headers[k] = this.options.headers[k] ||
                                  this.defaultHeaders[k];
    }
};

this.Server.prototype.serveDir = function (pathname, req, res, finish) {
    var htmlIndex = path.join(pathname, 'index.html'),
        that = this;

    fs.stat(htmlIndex, function (e, stat) {
        if (!e) {
            that.respond(null, 200, {}, [htmlIndex], stat, req, res, finish);
        } else {
            if (pathname in exports.store) {
                streamFiles(exports.indexStore[pathname].files);
            } else {
                // Stream a directory of files as a single file.
                fs.readFile(path.join(pathname, 'index.json'), function (e, contents) {
                    if (e) { return finish(404, {}) }
                    var index = JSON.parse(contents);
                    exports.indexStore[pathname] = index;
                    streamFiles(index.files);
                });
            }
        }
    });
    function streamFiles(files) {
        util.mstat(pathname, files, function (e, stat) {
            that.respond(pathname, 200, {}, files, stat, req, res, finish);
        });
    }
};
this.Server.prototype.serveFile = function (pathname, status, headers, req, res) {
    var that = this;
    var promise = new(events.EventEmitter);

    pathname = this.resolve(pathname);

    fs.stat(pathname, function (e, stat) {
        if (e) {
            return promise.emit('error', e);
        }
        that.respond(null, status, headers, [pathname], stat, req, res, function (status, headers) {
            that.finish(status, headers, req, res, promise);
        });
    });
    return promise;
};
this.Server.prototype.finish = function (status, headers, req, res, promise, callback) {
    var result = {
        status:  status,
        headers: headers,
        message: http.STATUS_CODES[status]
    };

    headers['Server'] = serverInfo;

    if (!status || status >= 400) {
        if (callback) {
            callback(result);
        } else {
            if (promise.listeners('error').length > 0) {
                promise.emit('error', result);
            }
            res.writeHead(status, headers);
            res.end();
        }
    } else {
        // Don't end the request here, if we're streaming;
        // it's taken care of in `prototype.stream`.
        if (status !== 200 || req.method !== 'GET') {
            res.writeHead(status, headers);
            res.end();
        }
        callback && callback(null, result);
        promise.emit('success', result);
    }
};

this.Server.prototype.servePath = function (pathname, status, headers, req, res, finish) {
    var that = this,
        promise = new(events.EventEmitter);

    pathname = this.resolve(pathname);

    // Only allow GET and HEAD requests
    if (req.method !== 'GET' && req.method !== 'HEAD') {
        finish(405, { 'Allow': 'GET, HEAD' });
        return promise;
    }

    // Make sure we're not trying to access a
    // file outside of the root.
    if (pathname.indexOf(that.root) === 0) {
        fs.stat(pathname, function (e, stat) {
            if (e) {
                finish(404, {});
            } else if (stat.isFile()) {      // Stream a single file.
                that.respond(null, status, headers, [pathname], stat, req, res, finish);
            } else if (stat.isDirectory()) { // Stream a directory of files.
                that.serveDir(pathname, req, res, finish);
            } else {
                finish(400, {});
            }
        });
    } else {
        // Forbidden
        finish(403, {});
    }
    return promise;
};
this.Server.prototype.resolve = function (pathname) {
    return path.resolve(path.join(this.root, pathname));
};
this.Server.prototype.serve = function (req, res, callback) {
    var that = this,
        promise = new(events.EventEmitter);

    var pathname = decodeURI(url.parse(req.url).pathname);

    var finish = function (status, headers) {
        that.finish(status, headers, req, res, promise, callback);
    };

    process.nextTick(function () {
        that.servePath(pathname, 200, {}, req, res, finish).on('success', function (result) {
            promise.emit('success', result);
        }).on('error', function (err) {
            promise.emit('error');
        });
    });
    if (! callback) { return promise }
};

this.Server.prototype.respond = function (pathname, status, _headers, files, stat, req, res, finish) {
    var mtime   = Date.parse(stat.mtime),
        key     = pathname || files[0],
        headers = {};

    // Copy default headers
    for (var k in this.options.headers) {  headers[k] = this.options.headers[k] }

    headers['ETag']          = JSON.stringify([stat.ino, stat.size, mtime].join('-'));
    headers['Date']          = new(Date)().toUTCString();
    headers['Last-Modified'] = new(Date)(stat.mtime).toUTCString();

    // Conditional GET
    // If the "If-Modified-Since" or "If-None-Match" headers
    // match the conditions, send a 304 Not Modified.
    if (req.headers['if-none-match'] === headers['ETag'] ||
        Date.parse(req.headers['if-modified-since']) >= mtime) {
        finish(304, headers);
    } else if (req.method === 'HEAD') {
        finish(200, headers);
    } else {
        var fileExtension = path.extname(files[0]).slice(1).toLowerCase();
        headers['Content-Length'] = stat.size;
        headers['Content-Type']   = mime.contentTypes[fileExtension] ||
                                   'application/octet-stream';

        for (var k in _headers) { headers[k] = _headers[k] }

        res.writeHead(status, headers);

        // If the file was cached and it's not older
        // than what's on disk, serve the cached version.
        if (this.cache && (key in exports.store) &&
            exports.store[key].stat.mtime >= stat.mtime) {
            res.end(exports.store[key].buffer);
            finish(status, headers);
        } else {
            this.stream(pathname, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) {
                if (e) { return finish(500, {}) }
                exports.store[key] = {
                    stat:      stat,
                    buffer:    buffer,
                    timestamp: Date.now()
                };
                finish(status, headers);
            });
        }
    }
};

this.Server.prototype.stream = function (pathname, files, buffer, res, callback) {
    (function streamFile(files, offset) {
        var file = files.shift();

        if (file) {
            file = file[0] === '/' ? file : path.join(pathname || '.', file);

            // Stream the file to the client
            fs.createReadStream(file, {
                flags: 'r',
                mode: 0666
            }).on('data', function (chunk) {
                chunk.copy(buffer, offset);
                offset += chunk.length;
            }).on('close', function () {
                streamFile(files, offset);
            }).on('error', function (err) {
                callback(err);
                console.error(err);
            }).pipe(res, { end: false });
        } else {
            res.end();
            callback(null, buffer, offset);
        }
    })(files.slice(0), 0);
};
<commit_msg>HEAD requests should have the same headers as GET.<commit_after>var fs = require('fs'),
    events = require('events'),
    buffer = require('buffer'),
    http = require('http'),
    url = require('url'),
    path = require('path');

this.version = [0, 6, 0];

var mime = require('./node-static/mime');
var util = require('./node-static/util');

var serverInfo = 'node-static/' + this.version.join('.');

// In-memory file store
this.store = {};
this.indexStore = {};

this.Server = function (root, options) {
    if (root && (typeof(root) === 'object')) { options = root, root = null }

    this.root    = path.resolve(root || '.');
    this.options = options || {};
    this.cache   = 3600;

    this.defaultHeaders  = {};
    this.options.headers = this.options.headers || {};

    if ('cache' in this.options) {
        if (typeof(this.options.cache) === 'number') {
            this.cache = this.options.cache;
        } else if (! this.options.cache) {
            this.cache = false;
        }
    }

    if (this.cache !== false) {
        this.defaultHeaders['Cache-Control'] = 'max-age=' + this.cache;
    }
    this.defaultHeaders['Server'] = serverInfo;

    for (var k in this.defaultHeaders) {
        this.options.headers[k] = this.options.headers[k] ||
                                  this.defaultHeaders[k];
    }
};

this.Server.prototype.serveDir = function (pathname, req, res, finish) {
    var htmlIndex = path.join(pathname, 'index.html'),
        that = this;

    fs.stat(htmlIndex, function (e, stat) {
        if (!e) {
            that.respond(null, 200, {}, [htmlIndex], stat, req, res, finish);
        } else {
            if (pathname in exports.store) {
                streamFiles(exports.indexStore[pathname].files);
            } else {
                // Stream a directory of files as a single file.
                fs.readFile(path.join(pathname, 'index.json'), function (e, contents) {
                    if (e) { return finish(404, {}) }
                    var index = JSON.parse(contents);
                    exports.indexStore[pathname] = index;
                    streamFiles(index.files);
                });
            }
        }
    });
    function streamFiles(files) {
        util.mstat(pathname, files, function (e, stat) {
            that.respond(pathname, 200, {}, files, stat, req, res, finish);
        });
    }
};
this.Server.prototype.serveFile = function (pathname, status, headers, req, res) {
    var that = this;
    var promise = new(events.EventEmitter);

    pathname = this.resolve(pathname);

    fs.stat(pathname, function (e, stat) {
        if (e) {
            return promise.emit('error', e);
        }
        that.respond(null, status, headers, [pathname], stat, req, res, function (status, headers) {
            that.finish(status, headers, req, res, promise);
        });
    });
    return promise;
};
this.Server.prototype.finish = function (status, headers, req, res, promise, callback) {
    var result = {
        status:  status,
        headers: headers,
        message: http.STATUS_CODES[status]
    };

    headers['Server'] = serverInfo;

    if (!status || status >= 400) {
        if (callback) {
            callback(result);
        } else {
            if (promise.listeners('error').length > 0) {
                promise.emit('error', result);
            }
            res.writeHead(status, headers);
            res.end();
        }
    } else {
        // Don't end the request here, if we're streaming;
        // it's taken care of in `prototype.stream`.
        if (status !== 200 || req.method !== 'GET') {
            res.writeHead(status, headers);
            res.end();
        }
        callback && callback(null, result);
        promise.emit('success', result);
    }
};

this.Server.prototype.servePath = function (pathname, status, headers, req, res, finish) {
    var that = this,
        promise = new(events.EventEmitter);

    pathname = this.resolve(pathname);

    // Only allow GET and HEAD requests
    if (req.method !== 'GET' && req.method !== 'HEAD') {
        finish(405, { 'Allow': 'GET, HEAD' });
        return promise;
    }

    // Make sure we're not trying to access a
    // file outside of the root.
    if (pathname.indexOf(that.root) === 0) {
        fs.stat(pathname, function (e, stat) {
            if (e) {
                finish(404, {});
            } else if (stat.isFile()) {      // Stream a single file.
                that.respond(null, status, headers, [pathname], stat, req, res, finish);
            } else if (stat.isDirectory()) { // Stream a directory of files.
                that.serveDir(pathname, req, res, finish);
            } else {
                finish(400, {});
            }
        });
    } else {
        // Forbidden
        finish(403, {});
    }
    return promise;
};
this.Server.prototype.resolve = function (pathname) {
    return path.resolve(path.join(this.root, pathname));
};
this.Server.prototype.serve = function (req, res, callback) {
    var that = this,
        promise = new(events.EventEmitter);

    var pathname = decodeURI(url.parse(req.url).pathname);

    var finish = function (status, headers) {
        that.finish(status, headers, req, res, promise, callback);
    };

    process.nextTick(function () {
        that.servePath(pathname, 200, {}, req, res, finish).on('success', function (result) {
            promise.emit('success', result);
        }).on('error', function (err) {
            promise.emit('error');
        });
    });
    if (! callback) { return promise }
};

this.Server.prototype.respond = function (pathname, status, _headers, files, stat, req, res, finish) {
    var mtime   = Date.parse(stat.mtime),
        key     = pathname || files[0],
        headers = {};

    // Copy default headers
    for (var k in this.options.headers) {  headers[k] = this.options.headers[k] }

    headers['ETag']          = JSON.stringify([stat.ino, stat.size, mtime].join('-'));
    headers['Date']          = new(Date)().toUTCString();
    headers['Last-Modified'] = new(Date)(stat.mtime).toUTCString();

    // Conditional GET
    // If the "If-Modified-Since" or "If-None-Match" headers
    // match the conditions, send a 304 Not Modified.
    if (req.headers['if-none-match'] === headers['ETag'] ||
        Date.parse(req.headers['if-modified-since']) >= mtime) {
        finish(304, headers);
    } else {
        var fileExtension = path.extname(files[0]).slice(1).toLowerCase();
        headers['Content-Length'] = stat.size;
        headers['Content-Type']   = mime.contentTypes[fileExtension] ||
                                   'application/octet-stream';

        for (var k in _headers) { headers[k] = _headers[k] }

        res.writeHead(status, headers);

        if (req.method === 'HEAD') {
            finish(200, headers);
            return;
        }

        // If the file was cached and it's not older
        // than what's on disk, serve the cached version.
        if (this.cache && (key in exports.store) &&
            exports.store[key].stat.mtime >= stat.mtime) {
            res.end(exports.store[key].buffer);
            finish(status, headers);
        } else {
            this.stream(pathname, files, new(buffer.Buffer)(stat.size), res, function (e, buffer) {
                if (e) { return finish(500, {}) }
                exports.store[key] = {
                    stat:      stat,
                    buffer:    buffer,
                    timestamp: Date.now()
                };
                finish(status, headers);
            });
        }
    }
};

this.Server.prototype.stream = function (pathname, files, buffer, res, callback) {
    (function streamFile(files, offset) {
        var file = files.shift();

        if (file) {
            file = file[0] === '/' ? file : path.join(pathname || '.', file);

            // Stream the file to the client
            fs.createReadStream(file, {
                flags: 'r',
                mode: 0666
            }).on('data', function (chunk) {
                chunk.copy(buffer, offset);
                offset += chunk.length;
            }).on('close', function () {
                streamFile(files, offset);
            }).on('error', function (err) {
                callback(err);
                console.error(err);
            }).pipe(res, { end: false });
        } else {
            res.end();
            callback(null, buffer, offset);
        }
    })(files.slice(0), 0);
};
<|endoftext|>


<commit_before><commit_msg>Update 11 Automatically Rejoin Audience Memebers.js<commit_after><|endoftext|>


<commit_before>'use strict';

var _        = require('lodash');
var Node     = require(__dirname);
var ParameterNode = require(__dirname + '/parameter');

var binaryMethod = function(operator) {
  return function(val) {
    var node = new BinaryNode({
      left: this.toNode(),
      operator: operator
    });
    if (Array.isArray(val)) {
      node.right = val.map(function (v) {
        return v.toNode ? v.toNode() : new ParameterNode(v);
      });
    }
    else {
      node.right = val.toNode ? val.toNode() : new ParameterNode(val);
    }
    return node;
  };
};

// Value expressions can be composed to form new binary expressions.
// valueExpressionMixin is in this file because it depends upon
// BinaryNode, while BinaryNode depends upon valueExpressionMixin.
var ValueExpressionMixin = {
  or       : binaryMethod('OR'),
  and      : binaryMethod('AND'),
  equals   : binaryMethod('='),
  equal    : binaryMethod('='),
  notEquals: binaryMethod('<>'),
  notEqual : binaryMethod('<>'),
  gt       : binaryMethod('>'),
  gte      : binaryMethod('>='),
  lt       : binaryMethod('<'),
  lte      : binaryMethod('<='),
  add      : binaryMethod('+'),
  subtract : binaryMethod('-'),
  multiply : binaryMethod('*'),
  divide   : binaryMethod('/'),
  modulo   : binaryMethod('%'),
  like     : binaryMethod('LIKE'),
  notLike  : binaryMethod('NOT LIKE'),
  in       : binaryMethod('IN'),
  notIn    : binaryMethod('NOT IN')
};

var BinaryNode = Node.define(_.extend({
  type: 'BINARY',
  constructor: function(config) {
    Node.call(this);
    this.left = config.left;
    this.operator = config.operator;
    this.right = config.right;
  },
}, valueExpressionMixin));

module.exports = {
  BinaryNode : BinaryNode,
  ValueExpressionMixin: ValueExpressionMixin
}
<commit_msg>Fix up errors caught by jshint<commit_after>'use strict';

var _        = require('lodash');
var Node     = require(__dirname);
var ParameterNode = require(__dirname + '/parameter');

var binaryMethod = function(operator) {
  return function(val) {
    var node = new BinaryNode({
      left: this.toNode(),
      operator: operator
    });
    if (Array.isArray(val)) {
      node.right = val.map(function (v) {
        return v.toNode ? v.toNode() : new ParameterNode(v);
      });
    }
    else {
      node.right = val.toNode ? val.toNode() : new ParameterNode(val);
    }
    return node;
  };
};

// Value expressions can be composed to form new binary expressions.
// ValueExpressionMixin is in this file because it depends upon
// BinaryNode, while BinaryNode depends upon ValueExpressionMixin.
var ValueExpressionMixin = {
  or       : binaryMethod('OR'),
  and      : binaryMethod('AND'),
  equals   : binaryMethod('='),
  equal    : binaryMethod('='),
  notEquals: binaryMethod('<>'),
  notEqual : binaryMethod('<>'),
  gt       : binaryMethod('>'),
  gte      : binaryMethod('>='),
  lt       : binaryMethod('<'),
  lte      : binaryMethod('<='),
  add      : binaryMethod('+'),
  subtract : binaryMethod('-'),
  multiply : binaryMethod('*'),
  divide   : binaryMethod('/'),
  modulo   : binaryMethod('%'),
  like     : binaryMethod('LIKE'),
  notLike  : binaryMethod('NOT LIKE'),
  in       : binaryMethod('IN'),
  notIn    : binaryMethod('NOT IN')
};

var BinaryNode = Node.define(_.extend({
  type: 'BINARY',
  constructor: function(config) {
    Node.call(this);
    this.left = config.left;
    this.operator = config.operator;
    this.right = config.right;
  },
}, ValueExpressionMixin));

module.exports = {
  BinaryNode : BinaryNode,
  ValueExpressionMixin: ValueExpressionMixin
};
<|endoftext|>


<commit_before>(function(root) { "use strict";

// Import
// ========

var _,
   util;

if (typeof exports !== 'undefined') {
  _    = require('underscore');
  util   = require('../util/util');
} else {
  _ = root._;
  util = root.Substance.util;
}

var COMPOUND = "compound";

var Compound = function(ops) {
  this.type = COMPOUND;
  this.ops = ops;
};

Compound.__prototype__ = function() {

  this.clone = function() {
    var ops = [];
    for (var idx = 0; idx < this.ops.length; idx++) {
      ops.push(util.clone(this.ops[idx]));
    }
    return new Compound(ops);
  };

  this.apply = function(obj) {
    for (var idx = 0; idx < this.ops.length; idx++) {
      obj = this.ops[idx].apply(obj);
    }
    return obj;
  };

  this.invert = function() {
    var ops = [];
    for (var idx = 0; idx < this.ops.length; idx++) {
      // reverse the order of the inverted atomic commands
      ops.unshift(this.ops[idx].invert());
    }

    return new Compound(ops);
  };

  this.toJSON = function() {
    return {
      type: COMPOUND,
      ops: this.ops
    };
  };

};
Compound.prototype = new Compound.__prototype__();

Compound.TYPE = COMPOUND;

// Transforms a compound and another given change inplace.
// --------
//

var compound_transform = function(a, b, first, check, transform0) {
  var idx;

  if (b.type === COMPOUND) {
    for (idx = 0; idx < b.ops.length; idx++) {
      compound_transform(a, b.ops[idx], first, check, transform0);
    }
  }

  else {
    for (idx = 0; idx < a.ops.length; idx++) {
      var _a, _b;
      if (first) {
        _a = a.ops[idx];
        _b = b;
      } else {
        _a = b;
        _b = a.ops[idx];
      }
      transform0(_a, _b, {inplace: true, check: check});
    }
  }
};

// A helper to create a transform method that supports Compounds.
// --------
//

Compound.createTransform = function(primitive_transform) {
  return function(a, b, options) {
    options = options || {};
    if(a.type === COMPOUND || b.type === COMPOUND) {
      if (!options.inplace) {
        a = util.clone(a);
        b = util.clone(b);
      }
      if (a.type === COMPOUND) {
        compound_transform(a, b, true, options.check, primitive_transform);
      } else if (b.type === COMPOUND) {
        compound_transform(b, a, false, options.check, primitive_transform);
      }
      return [a, b];
    } else {
      return primitive_transform(a, b, options);
    }

  };
};

// Export
// ========

if (typeof exports !== 'undefined') {
  module.exports = Compound;
} else {
  root.Substance.Chronicle.ot = root.Substance.Chronicle.ot || {};
  root.Substance.Chronicle.ot.Compound = Compound;
}

})(this);
<commit_msg>Allow to provide an alias for Compounds.<commit_after>(function(root) { "use strict";

// Import
// ========

var _,
   util;

if (typeof exports !== 'undefined') {
  _    = require('underscore');
  util   = require('../util/util');
} else {
  _ = root._;
  util = root.Substance.util;
}

var COMPOUND = "compound";

var Compound = function(ops) {
  this.type = COMPOUND;
  this.ops = ops;
  this.alias = undefined;
};

Compound.__prototype__ = function() {

  this.clone = function() {
    var ops = [];
    for (var idx = 0; idx < this.ops.length; idx++) {
      ops.push(util.clone(this.ops[idx]));
    }
    return new Compound(ops);
  };

  this.apply = function(obj) {
    for (var idx = 0; idx < this.ops.length; idx++) {
      obj = this.ops[idx].apply(obj);
    }
    return obj;
  };

  this.invert = function() {
    var ops = [];
    for (var idx = 0; idx < this.ops.length; idx++) {
      // reverse the order of the inverted atomic commands
      ops.unshift(this.ops[idx].invert());
    }

    return new Compound(ops);
  };

  this.toJSON = function() {
    var result = {
      type: COMPOUND,
      ops: this.ops,
    };
    if (this.alias) result.alias = this.alias;
    return result;
  };

};
Compound.prototype = new Compound.__prototype__();

Compound.TYPE = COMPOUND;

// Transforms a compound and another given change inplace.
// --------
//

var compound_transform = function(a, b, first, check, transform0) {
  var idx;

  if (b.type === COMPOUND) {
    for (idx = 0; idx < b.ops.length; idx++) {
      compound_transform(a, b.ops[idx], first, check, transform0);
    }
  }

  else {
    for (idx = 0; idx < a.ops.length; idx++) {
      var _a, _b;
      if (first) {
        _a = a.ops[idx];
        _b = b;
      } else {
        _a = b;
        _b = a.ops[idx];
      }
      transform0(_a, _b, {inplace: true, check: check});
    }
  }
};

// A helper to create a transform method that supports Compounds.
// --------
//

Compound.createTransform = function(primitive_transform) {
  return function(a, b, options) {
    options = options || {};
    if(a.type === COMPOUND || b.type === COMPOUND) {
      if (!options.inplace) {
        a = util.clone(a);
        b = util.clone(b);
      }
      if (a.type === COMPOUND) {
        compound_transform(a, b, true, options.check, primitive_transform);
      } else if (b.type === COMPOUND) {
        compound_transform(b, a, false, options.check, primitive_transform);
      }
      return [a, b];
    } else {
      return primitive_transform(a, b, options);
    }

  };
};

// Export
// ========

if (typeof exports !== 'undefined') {
  module.exports = Compound;
} else {
  root.Substance.Chronicle.ot = root.Substance.Chronicle.ot || {};
  root.Substance.Chronicle.ot.Compound = Compound;
}

})(this);
<|endoftext|>


<commit_before>
var path = require('path');

var browserify = require('browserify');
var titaniumResolve = require('titanium-resolve');
var when = require('when');
var nodefn = require('when/node/function');

var fs = require('./util/fs');

var GLOBAL_VARS = require('./globals');
var PRELUDE_PATH = path.resolve(__dirname, 'util', '_prelude.js');
var PRELUDE_SRC = require('fs').readFileSync(PRELUDE_PATH, 'utf8');

module.exports = pack;

function getPackage(entryfile) {
  return fs.isFile(entryfile).then(function (isFile) {
    if (isFile) return entryfile;
    else return path.resolve(entryfile, 'package.json');
  })
  .then(function (entry) {
    return fs
    .readFile(entry, 'utf8')
    .then(JSON.parse)
    .then(function (pkg) {
      return {
        path: entry,
        pkg: pkg
      };
    });
  });
}

function addDeps(to, deps) {
  if (Array.isArray(deps)) {
    deps.forEach(function (dep) {
      to.push(dep);
    });
  }
  else if (typeof deps === 'string') {
    to.push(deps);
  }
  else if (deps) {
    addDeps(to, Object.keys(deps));
  }
}

// cfg = {
//   noDependencies // do not pack dependencies with it
//   useTitaniumPlatformResolve // TODO
//   debug // build source maps
// }

function pack(entry, cfg, callback) {
  var promise = getPackage(entry).then(function (data) {

    var entry = path.dirname(data.path);
    var pkg = data.pkg;
    var titaniumManifest = pkg.titaniumManifest || {};

    var moduleid = titaniumManifest.moduleid || pkg.name;

    var opts = pkg.titaniumifier || pkg.npmifier || pkg.browserify || {};

    opts.extensions || (opts.extensions = [ '.js', '.json' ]);
    opts.transforms || (opts.transforms = []);
    opts.ignores || (opts.ignores = []);
    opts.externals || (opts.externals = []);

    var addExternals = addDeps.bind(null, opts.externals);

    addExternals(pkg.peerDependencies);
    addExternals(pkg.nativeDependencies);

    if (cfg.noDependencies) {
      addExternals(pkg.dependencies);
      addExternals(pkg.devDependencies);
      addExternals(pkg.optionalDependencies);
    }

    opts.ignoreMissing = !!opts.ignoreMissing;

    opts.transforms = opts.transforms.map(function (tr) {
      return require(tr);
    });

    var b = browserify({
      debug: cfg.debug,
      extensions: opts.extensions,
      insertGlobalVars: GLOBAL_VARS,
      ignoreMissing: !!opts.ignoreMissing,
      standalone: moduleid,
      prelude: PRELUDE_SRC,
      preludePath: PRELUDE_PATH
    });

    b.plugin(fixResolver, {
      resolve: titaniumResolve
    });

    opts.transforms.forEach(function (transform) {
      b.transform(transform);
    });

    opts.ignores.forEach(function (ignore) {
      b.ignore(ignore);
    });

    opts.externals.forEach(function (external) {
      b.exclude(external);
    });

    if (cfg.useTitaniumPlatformResolve) {
      TODO;
      /*b.transform(titaniumPlatformResolve.createTransform({
        platforms: [ build.platformName ],
        extensions: opts.extensions
      }));*/
    }

    var entrypoint = path.resolve(entry, pkg.main || 'index.js');

    return when.promise(function (resolve, reject) {
      titaniumResolve(entrypoint, {
        paths: b._mdeps.paths,
        modules: b._mdeps.options.modules,
        filename: path.resolve(entry, 'package.json'),
        extensions: opts.extensions
      }, function (err, result) {
        if (err) return reject(err);
        resolve(result);
      });
    })
    .then(function (result) {
      b.add(result);

      return nodefn.call(b.bundle.bind(b));
    });
  });

  if (callback) {
    promise.done(callback.bind(null, null), callback.bind(null));
  }

  return promise;
}

function fixResolver(b, opts) {
  b._mdeps.resolver = (opts.resolve || b._mdeps.resolver);
}
<commit_msg>Smaller refactor<commit_after>
var path = require('path');

var browserify = require('browserify');
var titaniumResolve = require('titanium-resolve');
var when = require('when');
var nodefn = require('when/node/function');

var fs = require('./util/fs');

var GLOBAL_VARS = require('./globals');
var PRELUDE_PATH = path.resolve(__dirname, 'util', '_prelude.js');
var PRELUDE_SRC = require('fs').readFileSync(PRELUDE_PATH, 'utf8');

module.exports = pack;

function getPackage(entryfile) {
  return fs.isFile(entryfile).then(function (isFile) {
    if (isFile) return entryfile;
    else return path.resolve(entryfile, 'package.json');
  })
  .then(function (entry) {
    return fs
    .readFile(entry, 'utf8')
    .then(JSON.parse)
    .then(function (pkg) {
      return {
        path: entry,
        pkg: pkg
      };
    });
  });
}

function addDeps(to, deps) {
  if (Array.isArray(deps)) {
    deps.forEach(function (dep) {
      to.push(dep);
    });
  }
  else if (typeof deps === 'string') {
    to.push(deps);
  }
  else if (deps) {
    addDeps(to, Object.keys(deps));
  }
}

// cfg = {
//   noDependencies // do not pack dependencies with it
//   useTitaniumPlatformResolve // TODO
//   debug // build source maps
// }

function pack(entry, cfg, callback) {
  var promise = getPackage(entry).then(function (data) {

    var entry = path.dirname(data.path);
    var pkg = data.pkg;
    var titaniumManifest = pkg.titaniumManifest || {};

    var moduleid = titaniumManifest.moduleid || pkg.name;

    var opts = pkg.titaniumifier || pkg.npmifier || pkg.browserify || {};

    opts.extensions || (opts.extensions = [ '.js', '.json' ]);
    opts.transforms || (opts.transforms = []);
    opts.ignores || (opts.ignores = []);
    opts.externals || (opts.externals = []);

    var addExternals = addDeps.bind(null, opts.externals);

    addExternals(pkg.peerDependencies);
    addExternals(pkg.nativeDependencies);

    if (cfg.noDependencies) {
      addExternals(pkg.dependencies);
      addExternals(pkg.devDependencies);
      addExternals(pkg.optionalDependencies);
    }

    opts.ignoreMissing = !!opts.ignoreMissing;

    opts.transforms = opts.transforms.map(function (tr) {
      return require(tr);
    });

    var b = browserify({
      debug: cfg.debug,
      extensions: opts.extensions,
      insertGlobalVars: GLOBAL_VARS,
      ignoreMissing: !!opts.ignoreMissing,
      standalone: moduleid,
      prelude: PRELUDE_SRC,
      preludePath: PRELUDE_PATH
    });

    b.plugin(fixResolver, {
      resolve: titaniumResolve
    });

    opts.transforms.forEach(function (transform) {
      b.transform(transform);
    });

    opts.ignores.forEach(function (ignore) {
      b.ignore(ignore);
    });

    opts.externals.forEach(function (external) {
      b.exclude(external);
    });

    if (cfg.useTitaniumPlatformResolve) {
      TODO;
      /*b.transform(titaniumPlatformResolve.createTransform({
        platforms: [ build.platformName ],
        extensions: opts.extensions
      }));*/
    }

    var entrypoint = path.resolve(entry, pkg.main || 'index.js');

    return when.promise(function (resolve, reject) {
      titaniumResolve(entrypoint, {
        paths: b._mdeps.paths,
        modules: b._mdeps.options.modules,
        filename: path.resolve(entry, 'package.json'),
        extensions: opts.extensions
      }, function (err, result) {
        if (err) return reject(err);

        b.add(result);

        b.bundle(function (err, result) {
          if (err) return reject(err);
          resolve(result);
        });
      });
    });
  });

  if (callback) {
    promise.done(callback.bind(null, null), callback.bind(null));
  }

  return promise;
}

function fixResolver(b, opts) {
  b._mdeps.resolver = (opts.resolve || b._mdeps.resolver);
}
<|endoftext|>


<commit_before>'use strict';

var async = require('async');

var injectIncludes = require('./inject-includes');
var parse = require('./parse');
var readAndParse = require('./read-and-parse');
var validate = require('./validate');

module.exports = function parse(argv, spunFiles){
  return function(cb){
    async.waterfall([
      readAndParse(spunFiles, argv),
      injectIncludes,
      validate
    ], cb);
  };
};
<commit_msg>removing an unused require.<commit_after>'use strict';

var async = require('async');

var injectIncludes = require('./inject-includes');
var readAndParse = require('./read-and-parse');
var validate = require('./validate');

module.exports = function parse(argv, spunFiles){
  return function(cb){
    async.waterfall([
      readAndParse(spunFiles, argv),
      injectIncludes,
      validate
    ], cb);
  };
};
<|endoftext|>


<commit_before>// original file from https://github.com/kunklejr/node-pcap-parser
// modified to work with fritzbox eth file and return full pcapPacket
// for decoding with node_pcap

/* LICENCE:
Copyright (c) 2012 Near Infinity Corporation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

var util = require('util')
var events = require('events')
var fs = require('fs')
const pcap = require('pcap')

var GLOBAL_HEADER_LENGTH = 24 // bytes
var PACKET_HEADER_LENGTH = 16 // bytes, maybe too short for eth file?

// TODO: check if input is stream
function Parser (input) {
  if (typeof (input) === 'string') {
    this.stream = fs.createReadStream(input)
  } else {
    // assume a ReadableStream
    this.stream = input
  }

  this.stream.pause()
  this.stream.on('data', onData.bind(this))
  this.stream.on('error', onError.bind(this))
  this.stream.on('end', onEnd.bind(this))

  this.buffer = null
  this.processingStep = parseGlobalHeader
  this.endianness = null
  this.magicNumber = null
  this.linkType = null

  this.determinePcapEndianess = determinePcapEndianess.bind(this)
  this.handleError = handleError.bind(this)

  process.nextTick(this.stream.resume.bind(this.stream))
}
util.inherits(Parser, events.EventEmitter)

function onError (err) {
  this.emit('error', err)
}

function onEnd () {
  this.emit('end')
}

function onData (data) {
  if (this.errored) {
    return
  }

  this.buffer = updateBuffer(this.buffer, data)

  try {
    while (this.processingStep.call(this)) {
    }
  } catch (error) {
    // console.log(error)
    // if (error.message.match(/endianness unknown/)) {
    //  this.handleError('unknown magic number: %s', this.magicNumber)
    this.handleError(error)

    // }
  }
}

function updateBuffer (buffer, data) {
  if (data === null || data === undefined) {
    return
  }

  if (buffer === null) {
    buffer = data
  } else {
    var extendedBuffer = new Buffer(buffer.length + data.length)
    buffer.copy(extendedBuffer)
    data.copy(extendedBuffer, buffer.length)
    buffer = extendedBuffer
  }
  return buffer
}

function parseGlobalHeader () {
  var buffer = this.buffer

  if (checkIfEnoughData(buffer, GLOBAL_HEADER_LENGTH) === false) {
    throw new Error('not enough data in buffer')
  }
  this.magicNumber = getMagicNumber(buffer)
  this.endianness = this.determinePcapEndianess(buffer, this.magicNumber)

  var globalHeader = getGlobalHeaderFromBuffer(buffer, this.endianness)
  this.linkType = determineLinkLayer(globalHeader.linkLayerType)
  if (this.linkType === false) {
    throw new Error('link type not supported')
  }
  if (checkIfPcapVersionIsSupported(globalHeader) === false) {
    throw new Error('file Version not supported')
  }
  this.emit('globalHeader', globalHeader)
  this.buffer = buffer.slice(GLOBAL_HEADER_LENGTH)
  this.processingStep = parsePacketHeader
  return true
}

function checkIfEnoughData (buffer, length) {
  if (buffer.length < length) {
    return false
  }
  return true
}

function getMagicNumber (buffer) {
  return buffer.toString('hex', 0, 4)
}

function determinePcapEndianess (buffer, magicNumber) {
  var endianness
  // determine pcap endianness
  // added "a1b2cd34" for fritzbox eth file
  if ((magicNumber === 'a1b2c3d4') || (magicNumber === 'a1b2cd34')) {
    endianness = 'BE'
  } else if (magicNumber === 'd4c3b2a1') {
    endianness = 'LE'
  } else {
    // this.handleError('unknown magic number: %s', magicNumber)
    // return false
    throw new Error('unknown magic number: %s', magicNumber)
  }
  return endianness
}

// function handleError (message) {
//   this.errored = true
//   this.stream.pause()
//   this.emit('error', new Error(message))
//   onEnd.call(this)
// }
function handleError (error) {
  this.errored = true
  this.stream.pause()
  this.emit('error', error)
  onEnd.call(this)
}

function getGlobalHeaderFromBuffer (buffer, endianness) {
  return {
    magicNumber: buffer['readUInt32' + endianness](0, true),
    majorVersion: buffer['readUInt16' + endianness](4, true),
    minorVersion: buffer['readUInt16' + endianness](6, true),
    gmtOffset: buffer['readInt32' + endianness](8, true),
    timestampAccuracy: buffer['readUInt32' + endianness](12, true),
    snapshotLength: buffer['readUInt32' + endianness](16, true),
    linkLayerType: buffer['readUInt32' + endianness](20, true)
  }
}

function determineLinkLayer (linkLayerType) {
  var linkType
  switch (linkLayerType) {
    case 0:
      linkType = 'LINKTYPE_NULL'
      break
    case 1:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 12:
      linkType = 'LINKTYPE_RAW'
      break
    case 113:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 127:
      linkType = 'LINKTYPE_IEEE802_11_RADIO'
      break
    default:
      console.log('pcap-parser: don\'t know how to do link_type ' + linkLayerType)
      linkType = false
  }
  return linkType
}

function checkIfPcapVersionIsSupported (globalHeader) {
  if (globalHeader.majorVersion !== 2 && globalHeader.minorVersion !== 4) {
    this.handleError('unsupported version %d.%d. pcap-parser only parses libpcap file format 2.4', globalHeader.majorVersion, globalHeader.minorVersion)
    return false
  }
}

function getRawPacketBody () {
  var buffer = this.buffer
  if (buffer.length >= this.currentPacketHeader.capturedLength) {
    this.data = buffer.slice(0, this.currentPacketHeader.capturedLength)

    this.buffer = buffer.slice(this.currentPacketHeader.capturedLength)
    this.processingStep = buildAndSendFullPackage
    return true
  }
  return false
}

function buildAndSendFullPackage () {
  var fullPacket = new pcap.PacketWithHeader(this.data, this.rawCurrentHeader, this.linkType)
  this.emit('packet', fullPacket)
  this.processingStep = parsePacketHeader
  return true
}

// TODO: find out about extra 8 byte
// -->Alexey Kuznetsov's modified "libpcap"format
// https://github.com/boundary/wireshark/blob/master/wiretap/libpcap.h
// starting at line 75
// node_pcap can decode this correctly if present as dumpfile
function parsePacketHeader () {
  var buffer = this.buffer
  // if (buffer.length >= PACKET_HEADER_LENGTH + 8) {
  if (checkIfEnoughData(buffer, PACKET_HEADER_LENGTH) === false) {
    return false
  }

  var header = getHeaderFromBuffer(buffer, this.endianness)

  this.currentPacketHeader = header
  this.emit('packetHeader', header)

  // var rawHeader = buffer.slice(0, PACKET_HEADER_LENGTH + 8)
  var rawHeader = buffer.slice(0, PACKET_HEADER_LENGTH)

  this.rawCurrentHeader = transformRawHeaderToLittleEndian(rawHeader, header)

  // this.buffer = buffer.slice(PACKET_HEADER_LENGTH + 8)
  this.buffer = buffer.slice(PACKET_HEADER_LENGTH)
  this.processingStep = getRawPacketBody
  return true
}

function getHeaderFromBuffer (buffer, endianness) {
  return {
    timestampSeconds: buffer['readUInt32' + endianness](0, true),
    timestampMicroseconds: buffer['readUInt32' + endianness](4, true),
    capturedLength: buffer['readUInt32' + endianness](8, true),
    originalLength: buffer['readUInt32' + endianness](12, true),
    item1: buffer['readUInt32' + endianness](16, true),
    item2: buffer['readUInt16' + endianness](20, true),
    item3: buffer['readUInt16' + endianness](22, true)
  }
}

function transformRawHeaderToLittleEndian (buffer, header) {
  buffer.writeUInt32LE(header.timestampSeconds, 0, true)
  buffer.writeUInt32LE(header.timestampMicroseconds, 4, true)
  buffer.writeUInt32LE(header.capturedLength, 8, true)
  buffer.writeUInt32LE(header.originalLength, 12, true)

  return buffer
}

exports.parse = function (input) {
  return new Parser(input)
}
<commit_msg>moved error handling for parsesing global header in seperate function<commit_after>// original file from https://github.com/kunklejr/node-pcap-parser
// modified to work with fritzbox eth file and return full pcapPacket
// for decoding with node_pcap

/* LICENCE:
Copyright (c) 2012 Near Infinity Corporation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

var util = require('util')
var events = require('events')
var fs = require('fs')
const pcap = require('pcap')

var GLOBAL_HEADER_LENGTH = 24 // bytes
var PACKET_HEADER_LENGTH = 16 // bytes, maybe too short for eth file?

// TODO: check if input is stream
function Parser (input) {
  if (typeof (input) === 'string') {
    this.stream = fs.createReadStream(input)
  } else {
    // assume a ReadableStream
    this.stream = input
  }

  this.stream.pause()
  this.stream.on('data', onData.bind(this))
  this.stream.on('error', onError.bind(this))
  this.stream.on('end', onEnd.bind(this))

  this.buffer = null
  this.processingStep = parseGlobalHeader
  this.endianness = null
  this.magicNumber = null
  this.linkType = null

  this.determinePcapEndianess = determinePcapEndianess.bind(this)
  this.handleError = handleError.bind(this)

  process.nextTick(this.stream.resume.bind(this.stream))
}
util.inherits(Parser, events.EventEmitter)

function onError (err) {
  this.emit('error', err)
}

function onEnd () {
  this.emit('end')
}

function onData (data) {
  if (this.errored) {
    return
  }

  this.buffer = updateBuffer(this.buffer, data)

  try {
    while (this.processingStep.call(this)) {
    }
  } catch (error) {
    // console.log(error)
    // if (error.message.match(/endianness unknown/)) {
    //  this.handleError('unknown magic number: %s', this.magicNumber)
    this.handleError(error)

    // }
  }
}

function updateBuffer (buffer, data) {
  if (data === null || data === undefined) {
    return
  }

  if (buffer === null) {
    buffer = data
  } else {
    var extendedBuffer = new Buffer(buffer.length + data.length)
    buffer.copy(extendedBuffer)
    data.copy(extendedBuffer, buffer.length)
    buffer = extendedBuffer
  }
  return buffer
}

function handleError (error) {
  var message = error.message
  if (message.match(/not enough data in buffer/)) {
    return
  }

  this.errored = true
  this.stream.pause()
  this.emit('error', error)
  onEnd.call(this)
}

function parseGlobalHeader () {
  var buffer = this.buffer

  checkIfEnoughData(buffer, GLOBAL_HEADER_LENGTH)

  this.magicNumber = getMagicNumber(buffer)
  this.endianness = this.determinePcapEndianess(buffer, this.magicNumber)

  var globalHeader = getGlobalHeaderFromBuffer(buffer, this.endianness)
  this.linkType = determineLinkLayer(globalHeader.linkLayerType)

  checkIfPcapVersionIsSupported(globalHeader)

  this.emit('globalHeader', globalHeader)
  this.buffer = buffer.slice(GLOBAL_HEADER_LENGTH)
  this.processingStep = parsePacketHeader
  return true
}

function checkIfEnoughData (buffer, length) {
  if (buffer.length < length) {
    throw new Error('not enough data in buffer')
  }
}

function getMagicNumber (buffer) {
  return buffer.toString('hex', 0, 4)
}

function determinePcapEndianess (buffer, magicNumber) {
  var endianness
  // determine pcap endianness
  // added "a1b2cd34" for fritzbox eth file
  if ((magicNumber === 'a1b2c3d4') || (magicNumber === 'a1b2cd34')) {
    endianness = 'BE'
  } else if (magicNumber === 'd4c3b2a1') {
    endianness = 'LE'
  } else {
    // this.handleError('unknown magic number: %s', magicNumber)
    // return false
    throw new Error('unknown magic number: %s', magicNumber)
  }
  return endianness
}

// function handleError (message) {
//   this.errored = true
//   this.stream.pause()
//   this.emit('error', new Error(message))
//   onEnd.call(this)
// }

function getGlobalHeaderFromBuffer (buffer, endianness) {
  return {
    magicNumber: buffer['readUInt32' + endianness](0, true),
    majorVersion: buffer['readUInt16' + endianness](4, true),
    minorVersion: buffer['readUInt16' + endianness](6, true),
    gmtOffset: buffer['readInt32' + endianness](8, true),
    timestampAccuracy: buffer['readUInt32' + endianness](12, true),
    snapshotLength: buffer['readUInt32' + endianness](16, true),
    linkLayerType: buffer['readUInt32' + endianness](20, true)
  }
}

function determineLinkLayer (linkLayerType) {
  var linkType
  switch (linkLayerType) {
    case 0:
      linkType = 'LINKTYPE_NULL'
      break
    case 1:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 12:
      linkType = 'LINKTYPE_RAW'
      break
    case 113:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 127:
      linkType = 'LINKTYPE_IEEE802_11_RADIO'
      break
    default:
      throw new Error('link_type ' + linkLayerType + ' not supported')
      // console.log('pcap-parser: don\'t know how to do link_type ' + linkLayerType)
      // linkType = false
  }
  return linkType
}

function checkIfPcapVersionIsSupported (globalHeader) {
  if (globalHeader.majorVersion !== 2 && globalHeader.minorVersion !== 4) {
    throw new Error('unsupported version %d.%d. pcap-parser only parses libpcap file format 2.4', globalHeader.majorVersion, globalHeader.minorVersion)
  }
}

function getRawPacketBody () {
  var buffer = this.buffer
  if (buffer.length >= this.currentPacketHeader.capturedLength) {
    this.data = buffer.slice(0, this.currentPacketHeader.capturedLength)

    this.buffer = buffer.slice(this.currentPacketHeader.capturedLength)
    this.processingStep = buildAndSendFullPackage
    return true
  }
  return false
}

function buildAndSendFullPackage () {
  var fullPacket = new pcap.PacketWithHeader(this.data, this.rawCurrentHeader, this.linkType)
  this.emit('packet', fullPacket)
  this.processingStep = parsePacketHeader
  return true
}

// TODO: find out about extra 8 byte
// -->Alexey Kuznetsov's modified "libpcap"format
// https://github.com/boundary/wireshark/blob/master/wiretap/libpcap.h
// starting at line 75
// node_pcap can decode this correctly if present as dumpfile
function parsePacketHeader () {
  var buffer = this.buffer
  // if (buffer.length >= PACKET_HEADER_LENGTH + 8) {
  if (checkIfEnoughData(buffer, PACKET_HEADER_LENGTH) === false) {
    return false
  }

  var header = getHeaderFromBuffer(buffer, this.endianness)

  this.currentPacketHeader = header
  this.emit('packetHeader', header)

  // var rawHeader = buffer.slice(0, PACKET_HEADER_LENGTH + 8)
  var rawHeader = buffer.slice(0, PACKET_HEADER_LENGTH)

  this.rawCurrentHeader = transformRawHeaderToLittleEndian(rawHeader, header)

  // this.buffer = buffer.slice(PACKET_HEADER_LENGTH + 8)
  this.buffer = buffer.slice(PACKET_HEADER_LENGTH)
  this.processingStep = getRawPacketBody
  return true
}

function getHeaderFromBuffer (buffer, endianness) {
  return {
    timestampSeconds: buffer['readUInt32' + endianness](0, true),
    timestampMicroseconds: buffer['readUInt32' + endianness](4, true),
    capturedLength: buffer['readUInt32' + endianness](8, true),
    originalLength: buffer['readUInt32' + endianness](12, true),
    item1: buffer['readUInt32' + endianness](16, true),
    item2: buffer['readUInt16' + endianness](20, true),
    item3: buffer['readUInt16' + endianness](22, true)
  }
}

function transformRawHeaderToLittleEndian (buffer, header) {
  buffer.writeUInt32LE(header.timestampSeconds, 0, true)
  buffer.writeUInt32LE(header.timestampMicroseconds, 4, true)
  buffer.writeUInt32LE(header.capturedLength, 8, true)
  buffer.writeUInt32LE(header.originalLength, 12, true)

  return buffer
}

exports.parse = function (input) {
  return new Parser(input)
}
<|endoftext|>


<commit_before>var util = require('util');
var events = require('events');
var fs = require('fs');

var GLOBAL_HEADER_LENGTH = 24; //bytes
var PACKET_HEADER_LENGTH = 16; //bytes

function onError(err) {
  this.emit('error', err);
}

function onEnd() {
  this.emit('end');
}

function onData(data) {
  if (this.errored) {
    return;
  }

  updateBuffer.call(this, data);
  while (this.state.call(this)) {}
}

function updateBuffer(data) {
  if (data === null || data === undefined) {
    return;
  }

  if (this.buffer === null) {
    this.buffer = data;
  } else {
    var extendedBuffer = new Buffer(this.buffer.length + data.length);
    this.buffer.copy(extendedBuffer);
    data.copy(extendedBuffer, this.buffer.length);
    this.buffer = extendedBuffer;
  }
}

function parseGlobalHeader() {
  var buffer = this.buffer;

  if (buffer.length >= GLOBAL_HEADER_LENGTH) {
    var magicNumber = buffer.toString('hex', 0, 4);

    // determine pcap endianness
    if (magicNumber == "a1b2c3d4") {
      this.endianness = "BE";
    } else if (magicNumber == "d4c3b2a1") {
      this.endianness = "LE";
    } else {
      this.errored = true;
      this.stream.pause();
      var msg = util.format('unknown magic number: %s', magicNumber);
      this.emit('error', new Error(msg));
      onEnd.call(this);
      return false;
    }

    var header = {
      magicNumber: buffer['readUInt32' + this.endianness](0, true),
      majorVersion: buffer['readUInt16' + this.endianness](4, true),
      minorVersion: buffer['readUInt16' + this.endianness](6, true),
      gmtOffset: buffer['readInt32' + this.endianness](8, true),
      timestampAccuracy: buffer['readUInt32' + this.endianness](12, true),
      snapshotLength: buffer['readUInt32' + this.endianness](16, true),
      linkLayerType: buffer['readUInt32' + this.endianness](20, true)
    };

    if (header.majorVersion != 2 && header.minorVersion != 4) {
      this.errored = true;
      this.stream.pause();
      var msg = util.format('unsupported version %d.%d. pcap-parser only parses libpcap file format 2.4', header.majorVersion, header.minorVersion);
      this.emit('error', new Error(msg));
      onEnd.call(this);
    } else {
      this.emit('globalHeader', header);
      this.buffer = buffer.slice(GLOBAL_HEADER_LENGTH);
      this.state = parsePacketHeader;
      return true;
    }
  }

  return false;
}

function parsePacketHeader() {
  var buffer = this.buffer;

  if (buffer.length >= PACKET_HEADER_LENGTH) {
    var header = {
      timestampSeconds: buffer['readUInt32' + this.endianness](0, true),
      timestampMicroseconds: buffer['readUInt32' + this.endianness](4, true),
      capturedLength: buffer['readUInt32' + this.endianness](8, true),
      originalLength: buffer['readUInt32' + this.endianness](12, true)
    };

    this.currentPacketHeader = header;
    this.emit('packetHeader', header);
    this.buffer = buffer.slice(PACKET_HEADER_LENGTH);
    this.state = parsePacketBody;
    return true;
  }

  return false;
}

function parsePacketBody() {
  var buffer = this.buffer;

  if (buffer.length >= this.currentPacketHeader.capturedLength) {
    var data = buffer.slice(0, this.currentPacketHeader.capturedLength);

    this.emit('packetData', data);
    this.emit('packet', {
      header: this.currentPacketHeader,
      data: data
    });

    this.buffer = buffer.slice(this.currentPacketHeader.capturedLength);
    this.state = parsePacketHeader;
    return true;
  }

  return false;
}

function Parser(input) {
  if (typeof(input) == 'string') {
    this.stream = fs.createReadStream(input);
  } else {
    // assume a ReadableStream
    this.stream = input;
  }

  this.stream.pause();
  this.stream.on('data', onData.bind(this));
  this.stream.on('error', onError.bind(this));
  this.stream.on('end', onEnd.bind(this));

  this.buffer = null;
  this.state = parseGlobalHeader;
  this.endianness = null;

  process.nextTick(this.stream.resume.bind(this.stream));
}
util.inherits(Parser, events.EventEmitter);

exports.parse = function (input) {
  return new Parser(input);
}
<commit_msg>fixed warnings<commit_after>var util = require('util');
var events = require('events');
var fs = require('fs');

var GLOBAL_HEADER_LENGTH = 24; //bytes
var PACKET_HEADER_LENGTH = 16; //bytes

function onError(err) {
  this.emit('error', err);
}

function onEnd() {
  this.emit('end');
}

function onData(data) {
  if (this.errored) {
    return;
  }

  updateBuffer.call(this, data);
  while (this.state.call(this)) {}
}

function updateBuffer(data) {
  if (data === null || data === undefined) {
    return;
  }

  if (this.buffer === null) {
    this.buffer = data;
  } else {
    var extendedBuffer = new Buffer(this.buffer.length + data.length);
    this.buffer.copy(extendedBuffer);
    data.copy(extendedBuffer, this.buffer.length);
    this.buffer = extendedBuffer;
  }
}

function parseGlobalHeader() {
  var buffer = this.buffer;

  if (buffer.length >= GLOBAL_HEADER_LENGTH) {
    var msg;
    var magicNumber = buffer.toString('hex', 0, 4);

    // determine pcap endianness
    if (magicNumber == "a1b2c3d4") {
      this.endianness = "BE";
    } else if (magicNumber == "d4c3b2a1") {
      this.endianness = "LE";
    } else {
      this.errored = true;
      this.stream.pause();
      msg = util.format('unknown magic number: %s', magicNumber);
      this.emit('error', new Error(msg));
      onEnd.call(this);
      return false;
    }

    var header = {
      magicNumber: buffer['readUInt32' + this.endianness](0, true),
      majorVersion: buffer['readUInt16' + this.endianness](4, true),
      minorVersion: buffer['readUInt16' + this.endianness](6, true),
      gmtOffset: buffer['readInt32' + this.endianness](8, true),
      timestampAccuracy: buffer['readUInt32' + this.endianness](12, true),
      snapshotLength: buffer['readUInt32' + this.endianness](16, true),
      linkLayerType: buffer['readUInt32' + this.endianness](20, true)
    };

    if (header.majorVersion != 2 && header.minorVersion != 4) {
      this.errored = true;
      this.stream.pause();
      msg = util.format('unsupported version %d.%d. pcap-parser only parses libpcap file format 2.4', header.majorVersion, header.minorVersion);
      this.emit('error', new Error(msg));
      onEnd.call(this);
    } else {
      this.emit('globalHeader', header);
      this.buffer = buffer.slice(GLOBAL_HEADER_LENGTH);
      this.state = parsePacketHeader;
      return true;
    }
  }

  return false;
}

function parsePacketHeader() {
  var buffer = this.buffer;

  if (buffer.length >= PACKET_HEADER_LENGTH) {
    var header = {
      timestampSeconds: buffer['readUInt32' + this.endianness](0, true),
      timestampMicroseconds: buffer['readUInt32' + this.endianness](4, true),
      capturedLength: buffer['readUInt32' + this.endianness](8, true),
      originalLength: buffer['readUInt32' + this.endianness](12, true)
    };

    this.currentPacketHeader = header;
    this.emit('packetHeader', header);
    this.buffer = buffer.slice(PACKET_HEADER_LENGTH);
    this.state = parsePacketBody;
    return true;
  }

  return false;
}

function parsePacketBody() {
  var buffer = this.buffer;

  if (buffer.length >= this.currentPacketHeader.capturedLength) {
    var data = buffer.slice(0, this.currentPacketHeader.capturedLength);

    this.emit('packetData', data);
    this.emit('packet', {
      header: this.currentPacketHeader,
      data: data
    });

    this.buffer = buffer.slice(this.currentPacketHeader.capturedLength);
    this.state = parsePacketHeader;
    return true;
  }

  return false;
}

function Parser(input) {
  if (typeof(input) == 'string') {
    this.stream = fs.createReadStream(input);
  } else {
    // assume a ReadableStream
    this.stream = input;
  }

  this.stream.pause();
  this.stream.on('data', onData.bind(this));
  this.stream.on('error', onError.bind(this));
  this.stream.on('end', onEnd.bind(this));

  this.buffer = null;
  this.state = parseGlobalHeader;
  this.endianness = null;

  process.nextTick(this.stream.resume.bind(this.stream));
}
util.inherits(Parser, events.EventEmitter);

exports.parse = function (input) {
  return new Parser(input);
};
<|endoftext|>


<commit_before>'use strict';

var denied = exports;

denied.distinct = function (self) {
  if (self._fields && Object.keys(self._fields).length > 0) {
    return 'field selection and slice'
  }

  var keys = Object.keys(denied.distinct);
  var err;

  keys.every(function (option) {
    if (self.options[option]) {
      err = option;
      return false;
    }
    return true;
  });

  return err;
};
denied.distinct.select =
denied.distinct.slice =
denied.distinct.sort =
denied.distinct.limit =
denied.distinct.skip =
denied.distinct.batchSize =
denied.distinct.comment =
denied.distinct.maxScan =
denied.distinct.snapshot =
denied.distinct.hint =
denied.distinct.tailable = true;

// aggregation integration

denied.findOneAndUpdate =
denied.findOneAndRemove = function (self) {
  var keys = Object.keys(denied.findOneAndUpdate);
  var err;

  keys.every(function (option) {
    if (self.options[option]) {
      err = option;
      return false;
    }
    return true;
  });

  return err;
}
denied.findOneAndUpdate.limit =
denied.findOneAndUpdate.skip =
denied.findOneAndUpdate.batchSize =
denied.findOneAndUpdate.maxScan =
denied.findOneAndUpdate.snapshot =
denied.findOneAndUpdate.hint =
denied.findOneAndUpdate.tailable =
denied.findOneAndUpdate.comment = true;

denied.count = function (self) {
  if (self._fields && Object.keys(self._fields).length > 0) {
    return 'field selection and slice'
  }

  var keys = Object.keys(denied.count);
  var err;

  keys.every(function (option) {
    if (self.options[option]) {
      err = option;
      return false;
    }
    return true;
  });

  return err;
}

denied.count.select =
denied.count.slice =
denied.count.sort =
denied.count.batchSize =
denied.count.comment =
denied.count.maxScan =
denied.count.snapshot =
denied.count.tailable = true;
<commit_msg>fix(permissions): dont disallow sort + select with count<commit_after>'use strict';

var denied = exports;

denied.distinct = function (self) {
  if (self._fields && Object.keys(self._fields).length > 0) {
    return 'field selection and slice'
  }

  var keys = Object.keys(denied.distinct);
  var err;

  keys.every(function (option) {
    if (self.options[option]) {
      err = option;
      return false;
    }
    return true;
  });

  return err;
};
denied.distinct.select =
denied.distinct.slice =
denied.distinct.sort =
denied.distinct.limit =
denied.distinct.skip =
denied.distinct.batchSize =
denied.distinct.comment =
denied.distinct.maxScan =
denied.distinct.snapshot =
denied.distinct.hint =
denied.distinct.tailable = true;

// aggregation integration

denied.findOneAndUpdate =
denied.findOneAndRemove = function (self) {
  var keys = Object.keys(denied.findOneAndUpdate);
  var err;

  keys.every(function (option) {
    if (self.options[option]) {
      err = option;
      return false;
    }
    return true;
  });

  return err;
}
denied.findOneAndUpdate.limit =
denied.findOneAndUpdate.skip =
denied.findOneAndUpdate.batchSize =
denied.findOneAndUpdate.maxScan =
denied.findOneAndUpdate.snapshot =
denied.findOneAndUpdate.hint =
denied.findOneAndUpdate.tailable =
denied.findOneAndUpdate.comment = true;

denied.count = function (self) {
  if (self._fields && Object.keys(self._fields).length > 0) {
    return 'field selection and slice'
  }

  var keys = Object.keys(denied.count);
  var err;

  keys.every(function (option) {
    if (self.options[option]) {
      err = option;
      return false;
    }
    return true;
  });

  return err;
}

denied.count.slice =
denied.count.batchSize =
denied.count.comment =
denied.count.maxScan =
denied.count.snapshot =
denied.count.tailable = true;
<|endoftext|>


<commit_before>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 5/9/13
 * Time: 11:48 AM
 */

define([
    'modules/Element'
], function definePageTabsElement(BaseElement) {

    /**
     * Define PageTabs Element
     * @param view
     * @param opts
     * @returns {PageTabsElement}
     * @constructor
     * @class PageTabsElement
     * @extends BaseElement
     */
    var PageTabsElement = function PageTabsElement(view, opts) {

        this._config(view, opts, $('<ul />')).build({
            $container: opts.$container,
            destroy: true
        });

        /**
         * Define current page class name
         * @type {string}
         */
        this.current = 'current';

        this.addCSS('page.tabs', {resource: '/widgets'});

        return this;
    };

    return PageTabsElement.extend('PageTabsElement', {

        /**
         * Render Embedded content
         * @member PageTabsElement
         * @param {{}} pages
         * @param {Page} page
         */
        renderEmbeddedContent: function renderEmbeddedContent(pages, page) {

            this.empty();

            var order = 0, item,
                event, current;

            for (var index in pages) {

                if (pages.hasOwnProperty(index)) {

                    /**
                     * Get item
                     * @type {Page}
                     */
                    item = pages[index];

                    /**
                     * Define event
                     * @type {string}
                     */
                    event = item.model.getConfig('order') >= order ?
                        'append' : 'prepend';

                    order = item.model.getConfig('order');

                    /**
                     * Define current page class name
                     * @type {string}
                     */
                    current = page === item ? this.current : '';

                    this.$[event](
                        this.view.renderPageTabsItem(
                            item, current
                        )
                    );
                }
            }

            this.view.controller.clearParentThumbnail();
        }

    }, BaseElement.prototype);

});<commit_msg>cont page order<commit_after>/**
 * Created with JetBrains RubyMine.
 * User: teamco
 * Date: 5/9/13
 * Time: 11:48 AM
 */

define([
    'modules/Element'
], function definePageTabsElement(BaseElement) {

    /**
     * Define PageTabs Element
     * @param view
     * @param opts
     * @returns {PageTabsElement}
     * @constructor
     * @class PageTabsElement
     * @extends BaseElement
     */
    var PageTabsElement = function PageTabsElement(view, opts) {

        this._config(view, opts, $('<ul />')).build({
            $container: opts.$container,
            destroy: true
        });

        /**
         * Define current page class name
         * @type {string}
         */
        this.current = 'current';

        this.addCSS('page.tabs', {resource: '/widgets'});

        return this;
    };

    return PageTabsElement.extend('PageTabsElement', {

        /**
         * Render Embedded content
         * @member PageTabsElement
         * @param {{}} pages
         * @param {Page} page
         */
        renderEmbeddedContent: function renderEmbeddedContent(pages, page) {

            this.empty();
            this.view.controller.clearParentThumbnail();

            var order = 0, item,
                current, index,
                tabs = [];

            for (index in pages) {

                if (pages.hasOwnProperty(index)) {

                    /**
                     * Get item
                     * @type {Page}
                     */
                    item = pages[index];

                    order = item.model.getConfig('order');

                    /**
                     * Define current page class name
                     * @type {string}
                     */
                    current = page === item ? this.current : '';

                    tabs[order - 1] = this.view.renderPageTabsItem(
                        item, current
                    );
                }
            }

            this.$.append(tabs);
        }

    }, BaseElement.prototype);

});<|endoftext|>


<commit_before>/**
 * @module src/GetLanguages
 *
 * Component that display SourceDocument
 * Accepts the only authentication token in header
*/

import React, { Component } from 'react';
import './App.css';
import Header from './Header';
import Footer from './Footer';
import $ from 'jquery';

class GetLanguages extends Component {
  constructor(props) {
    super(props);

    this.state = {
      getLanguages: [],
      getVersions: []
    }
      // Upload file specific callback handlers
      this.getLanguages = this.getLanguages.bind(this);
      this.onSelect = this.onSelect.bind(this);
  }

  onSelect(e) {
    this.setState({
      [e.target.name]: e.target.value });
  }

  getLanguages(e){
    e.preventDefault();
    let accessToken = JSON.parse(window.localStorage.getItem('access_token'))
    var _this = this;
    $.ajax({
      url: "http://127.0.0.1:8000/v1/get_languages",
      contentType: "application/json; charset=utf-8",
      method : "POST",
      headers: {
                "Authorization": "bearer " + JSON.stringify(accessToken['access_token']).slice(1,-1)},
      success: function (result) {
        var getLang = JSON.parse(result);
        for (var i = 0; i < getLang.length; i++) {
        var getLang1 = getLang[i];
        _this.state.getLanguages.push(getLang1[0]+ " ")
        _this.state.getVersions.push(getLang1[1]+ " ")
        }

       _this.setState({GetLanguages: result})
      },
      error: function (error) {
        console.log("Sources Uploaded failure !!!")
      }
    });

  }

  render() {
    return(

          <form className="col-md-8 uploader" encType="multipart/form-data">

Get Languages

                <button id="button" type="button" className="btn btn-success sourcefooter" onClick={this.getLanguages}>Get Languages</button>

                        Languages
                        Versions

                    {this.state.getLanguages}
                    {this.state.getVersions}

          </form>

      );
    }
}

export default GetLanguages;
<commit_msg>Response comming successfully for Get Languages<commit_after>/**
 * @module src/GetLanguages
 *
 * Component that display SourceDocument
 * Accepts the only authentication token in header
*/

import React, { Component } from 'react';
import './App.css';
import Header from './Header';
import Footer from './Footer';
import $ from 'jquery';

class GetLanguages extends Component {
  constructor(props) {
    super(props);

    this.state = {
      getLanguages: '',
      getVersions: []
    }
      // Upload file specific callback handlers
      this.getLanguages = this.getLanguages.bind(this);
  }

  componentDidMount() {
      window.addEventListener('load', this.getLanguages);
  }

  getLanguages(e){
    e.preventDefault();
    let accessToken = JSON.parse(window.localStorage.getItem('access_token'))
    var _this = this;
    $.ajax({
      url: "http://127.0.0.1:8000/v1/get_languages",
      contentType: "application/json; charset=utf-8",
      method : "POST",
      headers: {
                "Authorization": "bearer " + JSON.stringify(accessToken['access_token']).slice(1,-1)},
      success: function (result) {
        var getLang = JSON.parse(result);
        _this.setState({getLanguages: getLang.length > 0 ? getLang : []})
        for (var i = 0; i < getLang.length; i++) {
        }
      },
      error: function (error) {
        console.log("Sources Uploaded failure !!!")
      }
    });

  }

  render() {
    let currentLanguages = this.state.getLanguages.length > 0 ?  this.state.getLanguages : [];
    return(

          <form className="col-md-8 uploader" encType="multipart/form-data">

Available Source Texts

                    Language
                    Versions

                  {currentLanguages.map(function(data, index){
                    return (
{data[0]}	{data[1]}
);
                  })}

          </form>

      );
    }
}

export default GetLanguages;
<|endoftext|>