<commit_before>/** @babel */

/** @jsx etch.dom */

import etch from "etch";

export default class FileTree {

	constructor({files = [], showCheckboxes = true, tabIndexStart = 1, treeView = true} = {}) {
		this.state = {
			fileList: this.convertFiles(files, treeView),
			showCheckboxes,
			tabIndexStart,
		};

		etch.initialize(this);
	}

	convertFiles(files, treeView) {

		if (!treeView) {
			return files.reduce((obj, file) => {
				obj[file.file] = {
					checked: true,
					indeterminate: false,
					file,
					parent: null,
				};

				return obj;
			}, {});
		}

		files.sort((a, b) => {
			// sort dirs first
			const aPaths = a.file.split("/");
			const bPaths = b.file.split("/");
			const len = Math.min(aPaths.length, bPaths.length);
			for (let i = 0; i < len; i++) {
				const comp = aPaths[i].localeCompare(bPaths[i]);
				if (comp !== 0) {
					return comp;
				}
			}
			return bPaths.length - aPaths.length;
		});

		const treeFiles = {};

		// FIXME: file and folder with same path?
		//        ["a/b/c.js", "a/b/c.js/d.js"]
		//        Should be rare but could happen.

		for (const f of files) {
			const paths = f.file.split("/");
			let parent = null;
			let currentLevel = treeFiles;
			for (let i = 0; i < paths.length; i++) {
				const isFile = (i === paths.length - 1);
				const p = paths[i] + (isFile ? "" : "/");
				if (!currentLevel[p]) {
					if (isFile) {
						currentLevel[p] = {
							checked: true,
							indeterminate: false,
							file: f,
							parent,
						};
					} else {
						currentLevel[p] = {
							checked: true,
							indeterminate: false,
							collapsed: false,
							files: {},
							parent,
						};
					}
				}
				parent = currentLevel[p];
				currentLevel = currentLevel[p].files;
			}
		}

		const combineEmptyFolders = (filesObj) => {
			const namesToCheck = Object.keys(filesObj);

			for (let i = 0; i < namesToCheck.length; i++) {
				const name = namesToCheck[i];
				const obj = filesObj[name];
				if (!obj.files) {
					continue;
				}
				const list = Object.keys(obj.files);
				if (list.length === 1) {
					const newName = `${name}${list[0]}`;
					filesObj[newName] = obj.files[list[0]];
					delete filesObj[name];
					namesToCheck.push(newName);
				} else {
					obj.files = combineEmptyFolders(obj.files);
				}
			}

			return filesObj;
		};

		return combineEmptyFolders(treeFiles);
	}

	update(props) {
		if (props) {
			this.setState(props);
		}

		return etch.update(this);
	}

	setState(state) {
		this.state = {...this.state, ...state};
	}

	destroy() {
		return etch.destroy(this);
	}

	checkboxChange(obj) {
		const changeChildren = (files, checked) => {
			if (!files) {
				return;
			}

			for (const name in files) {
				files[name].indeterminate = false;
				files[name].checked = checked;
				if (files[name].files) {
					changeChildren(files[name].files, checked);
				}
			}
		};

		const changeParent = (parent, checked) => {
			if (!parent) {
				return;
			}

			let hasChecked = false;
			let hasUnchecked = false;
			let hasIndeterminate = false;

			for (const name in parent.files) {
				if (parent.files[name].checked) {
					hasChecked = true;
					if (hasUnchecked) {
						break;
					}
				} else {
					hasUnchecked = true;
					if (hasChecked) {
						break;
					}
				}
				if (parent.files[name].indeterminate) {
					hasIndeterminate = true;
					break;
				}
			}

			parent.checked = hasChecked && !(hasIndeterminate || hasUnchecked);
			parent.indeterminate = hasIndeterminate || (hasChecked && hasUnchecked);

			return changeParent(parent.parent, checked);
		};

		return ({target: {checked}}) => {
			obj.indeterminate = false;
			obj.checked = checked;
			changeChildren(obj.files, checked);
			changeParent(obj.parent, checked);

			this.update();
		};
	}

	dirClick(obj) {
		return () => {
			obj.collapsed = !obj.collapsed;
			this.update();
		};
	}

	getSelectedFiles() {

		const checkedFiles = (files) => {
			let arr = [];

			for (const name in files) {
				const obj = files[name];
				if (obj.file) {
					if (obj.checked) {
						arr.push(obj.file.file);
					}
				} else {
					arr = [...arr, ...checkedFiles(obj.files)];
				}
			}

			return arr;
		};

		return checkedFiles(this.state.fileList);
	}

	render() {
		let tabIndex = this.state.tabIndexStart;
		const renderItems = (files) => {
			return Object.keys(files).map(name => {
				const obj = files[name];

				let checkbox = "";
				if (this.state.showCheckboxes) {
					checkbox = (
						<input className="native-key-bindings input-checkbox" type="checkbox" tabIndex={tabIndex++}
							checked={obj.checked} indeterminate={obj.indeterminate} onchange={this.checkboxChange(obj)}/>
					);
				}

				const classes = [];
				if (!obj.checked && !obj.indeterminate) {
					classes.push("unchecked");
				}
				let li;
				if (obj.file) {
					classes.push("file");
					if (obj.file.added) {
						classes.push("added");
					}
					if (obj.file.untracked) {
						classes.push("untracked");
					}
					if (obj.file.deleted) {
						classes.push("deleted");
					}
					if (obj.file.changed) {
						classes.push("changed");
					}
					li = (

								{checkbox}
								{name}

					);
				} else {
					classes.push("dir");
					if (obj.collapsed) {
						classes.push("collapsed");
					}
					li = (

								{checkbox}
								<span className={`icon ${obj.collapsed ? "icon-chevron-right" : "icon-chevron-down"}`} onclick={this.dirClick(obj)}>
									{name}

								{renderItems(obj.files)}

					);
				}

				return li;
			});
		};

		return (

					{renderItems(this.state.fileList)}

		);
	}
}
<commit_msg>add title<commit_after>/** @babel */

/** @jsx etch.dom */

import etch from "etch";

export default class FileTree {

	constructor({files = [], showCheckboxes = true, tabIndexStart = 1, treeView = true} = {}) {
		this.state = {
			fileList: this.convertFiles(files, treeView),
			showCheckboxes,
			tabIndexStart,
		};

		etch.initialize(this);
	}

	convertFiles(files, treeView) {

		if (!treeView) {
			return files.reduce((obj, file) => {
				obj[file.file] = {
					checked: true,
					indeterminate: false,
					file,
					parent: null,
				};

				return obj;
			}, {});
		}

		files.sort((a, b) => {
			// sort dirs first
			const aPaths = a.file.split("/");
			const bPaths = b.file.split("/");
			const len = Math.min(aPaths.length, bPaths.length);
			for (let i = 0; i < len; i++) {
				const comp = aPaths[i].localeCompare(bPaths[i]);
				if (comp !== 0) {
					return comp;
				}
			}
			return bPaths.length - aPaths.length;
		});

		const treeFiles = {};

		// FIXME: file and folder with same path?
		//        ["a/b/c.js", "a/b/c.js/d.js"]
		//        Should be rare but could happen.

		for (const f of files) {
			const paths = f.file.split("/");
			let parent = null;
			let currentLevel = treeFiles;
			for (let i = 0; i < paths.length; i++) {
				const isFile = (i === paths.length - 1);
				const p = paths[i] + (isFile ? "" : "/");
				if (!currentLevel[p]) {
					if (isFile) {
						currentLevel[p] = {
							checked: true,
							indeterminate: false,
							file: f,
							parent,
						};
					} else {
						currentLevel[p] = {
							checked: true,
							indeterminate: false,
							collapsed: false,
							files: {},
							parent,
						};
					}
				}
				parent = currentLevel[p];
				currentLevel = currentLevel[p].files;
			}
		}

		const combineEmptyFolders = (filesObj) => {
			const namesToCheck = Object.keys(filesObj);

			for (let i = 0; i < namesToCheck.length; i++) {
				const name = namesToCheck[i];
				const obj = filesObj[name];
				if (!obj.files) {
					continue;
				}
				const list = Object.keys(obj.files);
				if (list.length === 1) {
					const newName = `${name}${list[0]}`;
					filesObj[newName] = obj.files[list[0]];
					delete filesObj[name];
					namesToCheck.push(newName);
				} else {
					obj.files = combineEmptyFolders(obj.files);
				}
			}

			return filesObj;
		};

		return combineEmptyFolders(treeFiles);
	}

	update(props) {
		if (props) {
			this.setState(props);
		}

		return etch.update(this);
	}

	setState(state) {
		this.state = {...this.state, ...state};
	}

	destroy() {
		return etch.destroy(this);
	}

	checkboxChange(obj) {
		const changeChildren = (files, checked) => {
			if (!files) {
				return;
			}

			for (const name in files) {
				files[name].indeterminate = false;
				files[name].checked = checked;
				if (files[name].files) {
					changeChildren(files[name].files, checked);
				}
			}
		};

		const changeParent = (parent, checked) => {
			if (!parent) {
				return;
			}

			let hasChecked = false;
			let hasUnchecked = false;
			let hasIndeterminate = false;

			for (const name in parent.files) {
				if (parent.files[name].checked) {
					hasChecked = true;
					if (hasUnchecked) {
						break;
					}
				} else {
					hasUnchecked = true;
					if (hasChecked) {
						break;
					}
				}
				if (parent.files[name].indeterminate) {
					hasIndeterminate = true;
					break;
				}
			}

			parent.checked = hasChecked && !(hasIndeterminate || hasUnchecked);
			parent.indeterminate = hasIndeterminate || (hasChecked && hasUnchecked);

			return changeParent(parent.parent, checked);
		};

		return ({target: {checked}}) => {
			obj.indeterminate = false;
			obj.checked = checked;
			changeChildren(obj.files, checked);
			changeParent(obj.parent, checked);

			this.update();
		};
	}

	dirClick(obj) {
		return () => {
			obj.collapsed = !obj.collapsed;
			this.update();
		};
	}

	getSelectedFiles() {

		const checkedFiles = (files) => {
			let arr = [];

			for (const name in files) {
				const obj = files[name];
				if (obj.file) {
					if (obj.checked) {
						arr.push(obj.file.file);
					}
				} else {
					arr = [...arr, ...checkedFiles(obj.files)];
				}
			}

			return arr;
		};

		return checkedFiles(this.state.fileList);
	}

	render() {
		let tabIndex = this.state.tabIndexStart;
		const renderItems = (files) => {
			return Object.keys(files).map(name => {
				const obj = files[name];

				let checkbox = "";
				if (this.state.showCheckboxes) {
					checkbox = (
						<input className="native-key-bindings input-checkbox" type="checkbox" tabIndex={tabIndex++}
							checked={obj.checked} indeterminate={obj.indeterminate} onchange={this.checkboxChange(obj)}/>
					);
				}

				const classes = [];
				if (!obj.checked && !obj.indeterminate) {
					classes.push("unchecked");
				}
				let li;
				if (obj.file) {
					classes.push("file");
					if (obj.file.added) {
						classes.push("added");
					}
					if (obj.file.untracked) {
						classes.push("untracked");
					}
					if (obj.file.deleted) {
						classes.push("deleted");
					}
					if (obj.file.changed) {
						classes.push("changed");
					}
					li = (

								{checkbox}
								{name}

					);
				} else {
					classes.push("dir");
					if (obj.collapsed) {
						classes.push("collapsed");
					}
					li = (

								{checkbox}
								<span className={`icon ${obj.collapsed ? "icon-chevron-right" : "icon-chevron-down"}`} onclick={this.dirClick(obj)}>
									{name}

								{renderItems(obj.files)}

					);
				}

				return li;
			});
		};

		return (

					{renderItems(this.state.fileList)}

		);
	}
}
<|endoftext|>


<commit_before>var   express     = require('express')
    , grainstore  = require('grainstore')
    , RenderCache = require('./render_cache')
    , _           = require('underscore')
    , Step        = require('step');

module.exports = function(opts){
    var opts = opts || {};

    // initialize core mml_store
    var mml_store  = new grainstore.MMLStore(opts.redis, opts.grainstore);

    // initialize render cache 60 seconds TTL
    var render_cache = new RenderCache(60000, mml_store);

    // optional log format
    var log_format = opts.hasOwnProperty('log_format') ? opts.log_format
      : '[:req[X-Real-IP] > :req[Host] @ :date] \033[90m:method\033[0m \033[36m:url\033[0m \033[90m:status :response-time ms -> :res[Content-Type]\033[0m';

    // initialize express server
    var app = express.createServer();
    app.enable('jsonp callback');
    app.use(express.bodyParser());
    if ( log_format ) {
      app.use(express.logger({
          // Allowing for unbuffered logging is mainly
          // used to avoid hanging during unit testing.
          // TODO: provide an explicit teardown function instead,
          //       releasing any event handler or timer set by
          //       this component.
          buffer: !opts.unbuffered_logging,
          format: log_format
      }));
    }

    //TODO: extract server config to a function
    // take in base url and base req2params from opts or throw exception
    if (!_.isString(opts.base_url) || !_.isFunction(opts.req2params)) throw new Error("Must initialise Windshaft with a base URL and req2params function");

    // Extend windshaft with all the elements of the options object
    _.extend(app, opts);

    // set default before/after filters if not set in opts object
    // filters can be used for custom authentication, caching, logging etc
    _.defaults(app, {
        // called pre tile render right at the start of the call
        beforeTileRender: function(req, res, callback) {
            callback(null);
        },
        // called immediately after the tile render. Called with tile output
        afterTileRender: function(req, res, tile, headers, callback) {
            callback(null, tile, headers);
        },
        // called after a map style is changed or deleted
        afterStateChange: function(req, data, callback) {
            callback(null, data);
        }
    });

    // Support both express-2.5 and express-3.0
    if ( express.version.split('.')[0] >= 3 ) {
        app.sendWithHeaders = function(res, what, status, headers) {
            res.set(headers);
            res.send(what, status);
        }
    } else {
        app.sendWithHeaders = function(res, what, status, headers) {
            res.send(what, headers, status);
        }
    }

    /*
    * Routing from here
    */

    // simple testable route
    app.get('/', function(req, res){
        res.send("JOHN RAMBO");
    });

    // Retrieve the Carto style for a given map.
    // Returns styles stored in grainstore for a given params combination
    // Returns default if no style stored
    app.get(app.base_url + '/style', function(req, res){
        var mml_builder;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err, data){
                if (err) throw err;

                mml_builder = mml_store.mml_builder(req.params);
                mml_builder.getStyle(this);
            },
            function(err, data){
                if (err){
                    res.send({error: err.message}, 500);
                } else {
                    res.send({style: data.style}, 200);
                }
            }
        );
    });

    // Set new map style
    // Requires a 'style' parameter containing carto (mapbox.com/carto)
    //
    // 1. If carto is invalid, respond with error messages + status
    // 2. If carto is valid, save it, reset the render pool and return 200
    //
    // Triggers state change filter
    app.post(app.base_url + '/style', function(req, res){
        var mml_builder;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err, data){
                if (err) throw err;
                if (_.isUndefined(req.body) || _.isUndefined(req.body.style)) {
                    res.send({error: 'must send style information'}, 400);
                } else {
                    mml_builder = mml_store.mml_builder(req.params);
                    mml_builder.setStyle(req.body.style, this);
                }
            },
            function(err, data) {
                if (err) throw err;
                var param = req.params;
                app.afterStateChange(req, data, this);
            },
            function(err, data){
                if (err){
                    res.send(err.message.split('\n'), 500);
                } else {
                    render_cache.reset(req);
                    res.send(200);
                }
            }
        );
    });

    // Delete Map Style
    // Triggers state change filter
    app.delete(app.base_url + '/style', function(req, res){
        var mml_builder;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err, data){
                if (err) throw err;
                mml_builder = mml_store.mml_builder(req.params);
                mml_builder.delStyle(this);
            },
            function(err, data) {
                if (err) throw err;
                app.afterStateChange(req, data, this);
            },
            function(err, data){
                if (err){
                    res.send(err.message, 500);
                } else {
                    render_cache.reset(req);
                    res.send(200);
                }
            }
        );
    });

    // Gets a tile for a given set of tile ZXY coords. (OSM style)
    // Call with .png for images, or .grid.json for UTFGrid tiles
    //
    // query string arguments:
    //
    // * sql - use SQL to filter displayed results or perform operations pre-render
    // * style - assign a per tile style using carto
    // * interactivity - specify which columns to represent in the UTFGrid
    // * cache_buster - specify to ensure a new renderer is used
    // * geom_type - specify default style to use if no style present
    //
    // Triggers beforeTileRender and afterTileRender render filters
    app.get(app.base_url + '/:z/:x/:y.*', function(req, res){

        // Enable CORS access by web browsers if set
        if(opts.enable_cors){
            res.header("Access-Control-Allow-Origin", "*");
            res.header("Access-Control-Allow-Headers", "X-Requested-With");
        }

        // strip format from end of url and attach to params
        req.params.format = req.params['0'];
        delete req.params['0'];

        // Wrap SQL requests in mapnik format if sent
        if(req.query.sql && req.query.sql !== '') {
            req.query.sql = "(" + req.query.sql + ") as cdbq";
        }

        var renderer;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err) {
                if (err) throw err;
                app.beforeTileRender(req, res, this);
            },
            function(err, data){
                if (err) throw err;
                render_cache.getRenderer(req, this);
            },
            function(err, r) {
                renderer = r;
                if (err) throw err;
                var my_func = (req.params.format === 'grid.json') ? 'getGrid' : 'getTile';
                renderer[my_func].call(renderer, req.params.z, req.params.x, req.params.y, this);
            },
            function(err, tile, headers) {
                if (err) throw err;
                app.afterTileRender(req, res, tile, headers, this);
            },
            function(err, tile, headers) {
                if ( renderer ) renderer.release();
                if (err) {
                    console.log("[TILE RENDER ERROR]\n" + err);
                    res.send(err.message, 500);
                } else {
                    app.sendWithHeaders(res, tile, 200, headers);
                }
            }
        );
    });

    return app;
};
<commit_msg>Expose setStyle and delStyle methods<commit_after>var   express     = require('express')
    , grainstore  = require('grainstore')
    , RenderCache = require('./render_cache')
    , _           = require('underscore')
    , Step        = require('step');

module.exports = function(opts){
    var opts = opts || {};

    // initialize core mml_store
    var mml_store  = new grainstore.MMLStore(opts.redis, opts.grainstore);

    // initialize render cache 60 seconds TTL
    var render_cache = new RenderCache(60000, mml_store);

    // optional log format
    var log_format = opts.hasOwnProperty('log_format') ? opts.log_format
      : '[:req[X-Real-IP] > :req[Host] @ :date] \033[90m:method\033[0m \033[36m:url\033[0m \033[90m:status :response-time ms -> :res[Content-Type]\033[0m';

    // initialize express server
    var app = express.createServer();
    app.enable('jsonp callback');
    app.use(express.bodyParser());
    if ( log_format ) {
      app.use(express.logger({
          // Allowing for unbuffered logging is mainly
          // used to avoid hanging during unit testing.
          // TODO: provide an explicit teardown function instead,
          //       releasing any event handler or timer set by
          //       this component.
          buffer: !opts.unbuffered_logging,
          format: log_format
      }));
    }

    //TODO: extract server config to a function
    // take in base url and base req2params from opts or throw exception
    if (!_.isString(opts.base_url) || !_.isFunction(opts.req2params)) throw new Error("Must initialise Windshaft with a base URL and req2params function");

    // Extend windshaft with all the elements of the options object
    _.extend(app, opts);

    // set default before/after filters if not set in opts object
    // filters can be used for custom authentication, caching, logging etc
    _.defaults(app, {
        // called pre tile render right at the start of the call
        beforeTileRender: function(req, res, callback) {
            callback(null);
        },
        // called immediately after the tile render. Called with tile output
        afterTileRender: function(req, res, tile, headers, callback) {
            callback(null, tile, headers);
        },
        // called after a map style is changed or deleted
        afterStateChange: function(req, data, callback) {
            callback(null, data);
        },
        // Set new map style
        // Requires a 'style' parameter containing carto (mapbox.com/carto)
        //
        // @param callback function(err, data) where data has currently NO meaning
        //
        setStyle: function(params, style, callback) {
            var mml_builder = mml_store.mml_builder(params);
            mml_builder.setStyle(style, callback);
        },
        // Delete a map style
        //
        // @param callback function(err, data) where data has currently NO meaning
        //
        delStyle: function(params, callback) {
            var mml_builder = mml_store.mml_builder(params);
            mml_builder.delStyle(callback);
        }
    });

    // Support both express-2.5 and express-3.0
    if ( express.version.split('.')[0] >= 3 ) {
        app.sendWithHeaders = function(res, what, status, headers) {
            res.set(headers);
            res.send(what, status);
        }
    } else {
        app.sendWithHeaders = function(res, what, status, headers) {
            res.send(what, headers, status);
        }
    }

    /*
    * Routing from here
    */

    // simple testable route
    app.get('/', function(req, res){
        res.send("JOHN RAMBO");
    });

    // Retrieve the Carto style for a given map.
    // Returns styles stored in grainstore for a given params combination
    // Returns default if no style stored
    app.get(app.base_url + '/style', function(req, res){
        var mml_builder;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err, data){
                if (err) throw err;

                mml_builder = mml_store.mml_builder(req.params);
                mml_builder.getStyle(this);
            },
            function(err, data){
                if (err){
                    res.send({error: err.message}, 500);
                } else {
                    res.send({style: data.style}, 200);
                }
            }
        );
    });

    // Set new map style
    // Requires a 'style' parameter containing carto (mapbox.com/carto)
    //
    // 1. If carto is invalid, respond with error messages + status
    // 2. If carto is valid, save it, reset the render pool and return 200
    //
    // Triggers state change filter
    app.post(app.base_url + '/style', function(req, res){
        var mml_builder;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err, data){
                if (err) throw err;
                if (_.isUndefined(req.body) || _.isUndefined(req.body.style)) {
                    res.send({error: 'must send style information'}, 400);
                } else {
                    app.setStyle(req.params, req.body.style, this);
                }
            },
            function(err, data) {
                if (err) throw err;
                var param = req.params;
                app.afterStateChange(req, data, this);
            },
            function(err, data){
                if (err){
                    res.send(err.message.split('\n'), 500);
                } else {
                    render_cache.reset(req);
                    res.send(200);
                }
            }
        );
    });

    // Delete Map Style
    // Triggers state change filter
    app.delete(app.base_url + '/style', function(req, res){
        var mml_builder;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err, data){
                if (err) throw err;
                app.delStyle(req.params, this);
            },
            function(err, data) {
                if (err) throw err;
                app.afterStateChange(req, data, this);
            },
            function(err, data){
                if (err){
                    res.send(err.message, 500);
                } else {
                    render_cache.reset(req);
                    res.send(200);
                }
            }
        );
    });

    // Gets a tile for a given set of tile ZXY coords. (OSM style)
    // Call with .png for images, or .grid.json for UTFGrid tiles
    //
    // query string arguments:
    //
    // * sql - use SQL to filter displayed results or perform operations pre-render
    // * style - assign a per tile style using carto
    // * interactivity - specify which columns to represent in the UTFGrid
    // * cache_buster - specify to ensure a new renderer is used
    // * geom_type - specify default style to use if no style present
    //
    // Triggers beforeTileRender and afterTileRender render filters
    app.get(app.base_url + '/:z/:x/:y.*', function(req, res){

        // Enable CORS access by web browsers if set
        if(opts.enable_cors){
            res.header("Access-Control-Allow-Origin", "*");
            res.header("Access-Control-Allow-Headers", "X-Requested-With");
        }

        // strip format from end of url and attach to params
        req.params.format = req.params['0'];
        delete req.params['0'];

        // Wrap SQL requests in mapnik format if sent
        if(req.query.sql && req.query.sql !== '') {
            req.query.sql = "(" + req.query.sql + ") as cdbq";
        }

        var renderer;

        Step(
            function(){
                app.req2params(req, this);
            },
            function(err) {
                if (err) throw err;
                app.beforeTileRender(req, res, this);
            },
            function(err, data){
                if (err) throw err;
                render_cache.getRenderer(req, this);
            },
            function(err, r) {
                renderer = r;
                if (err) throw err;
                var my_func = (req.params.format === 'grid.json') ? 'getGrid' : 'getTile';
                renderer[my_func].call(renderer, req.params.z, req.params.x, req.params.y, this);
            },
            function(err, tile, headers) {
                if (err) throw err;
                app.afterTileRender(req, res, tile, headers, this);
            },
            function(err, tile, headers) {
                if ( renderer ) renderer.release();
                if (err) {
                    console.log("[TILE RENDER ERROR]\n" + err);
                    res.send(err.message, 500);
                } else {
                    app.sendWithHeaders(res, tile, 200, headers);
                }
            }
        );
    });

    return app;
};
<|endoftext|>


<commit_before>var React = require('react');
var ReactDOM = require('react-dom');
var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName');
var merge = require('./utils/merge');

var TransitionContainer = React.createClass({
  displayName: 'TransitionContainer',

  propTypes: {
    children: React.PropTypes.any,
    childrenAppearStyle: React.PropTypes.object,
    childrenBaseStyle: React.PropTypes.object,
    childrenEnterStyle: React.PropTypes.object,
    childrenLeaveStyle: React.PropTypes.object,
    id: React.PropTypes.oneOfType(
      [React.PropTypes.string, React.PropTypes.number]
    ),
    onChildAppeared: React.PropTypes.func,
    onChildEntered: React.PropTypes.func,
    onChildLeft: React.PropTypes.func,
    onChildStartAppear: React.PropTypes.func,
    onChildStartEnter: React.PropTypes.func,
    onChildStartLeave: React.PropTypes.func,
  },

  componentWillMount: function () {
    this._callbackTimeout = null;
  },

  componentDidMount: function () {
    var node = ReactDOM.findDOMNode(this);
    if (!node) return;

    node.setAttribute('style', this._computeNewStyle());

    // Flush styles
    this.flush = node.offsetWidth;
  },

  componentWillUnmount: function () {
    clearTimeout(this._callbackTimeout);
  },

  componentWillAppear: function (callback) {
    this._transition(callback, 'appear');

    if (this.props.onChildStartAppear) {
      this.props.onChildStartAppear(this.props.id);
    }
  },

  componentDidAppear: function () {
    if (this.props.onChildAppeared) {
      this.props.onChildAppeared(this.props.id);
    }

    this._appeared = true;
  },

  componentWillEnter: function (callback) {
    this._transition(callback, 'enter');

    if (this.props.onChildStartEnter) {
      this.props.onChildStartEnter(this.props.id);
    }
  },

  componentDidEnter: function () {
    if (this.props.onChildEntered) {
      this.props.onChildEntered(this.props.id);
    }
  },

  componentWillLeave: function (callback) {
    this._transition(callback, 'leave');

    if (this.props.onChildStartLeave) {
      this.props.onChildStartLeave(this.props.id);
    }
  },

  componentDidLeave: function () {
    if (this.props.onChildLeft) this.props.onChildLeft(this.props.id);
  },

  _getTransitionProperties: function (computedStyle) {
    var properties = {};

    properties.transitionDuration = computedStyle.transitionDuration ||
      computedStyle.WebkitTransitionDuration ||
      computedStyle.MozTransitionDuration ||
      computedStyle.msTransitionDuration;

    properties.transitionDelay = computedStyle.transitionDelay ||
      computedStyle.WebkitTransitionDelay ||
      computedStyle.MozTransitionDelay ||
      computedStyle.msTransitionDelay;

    properties.transitionProperty = computedStyle.transitionProperty ||
      computedStyle.WebkitTransitionProperty ||
      computedStyle.msTransitionProperty ||
      computedStyle.MozTransitionProperty;

    return properties;
  },

  // Specs: https://www.w3.org/TR/css3-transitions/
  // A lot of assumptions could be made here, like that probably the duration
  // and delay lists are already truncated by the size of the property list
  // or that values will be returned by window.getComputedStyle in seconds,
  // but I prefer to make this function less vulnerable to changes.
  _getTransitionMaximumTime: function (property, duration, delay) {
    var durationArray = duration.split(',');
    var delayArray = delay.split(',');
    var propertyArray = property.split(',');
    var longestTime = 0;
    var re = /([0-9]*\.?[0-9]+)(m?s)/;
    var durationFactor;
    var delayFactor;
    var durationGroups;
    var delayGroups;

    for (var i = 0; i < propertyArray.length; i++) {
      durationGroups = (durationArray[i] || '0s').match(re);
      if (durationGroups[2] === 's') durationFactor = 1000;
      else durationFactor = 1;

      delayGroups = (delayArray[i] || '0s').match(re);
      if (delayGroups[2] === 's') delayFactor = 1000;
      else delayFactor = 1;

      longestTime = Math.max(
        parseFloat(
          (durationGroups[1] * durationFactor) + (delayGroups[1] * delayFactor)
        ),
        longestTime
      );
    }

    return longestTime;
  },

  _computeNewStyle: function (phase) {
    var currentStyle;
    if (phase === 'appear') currentStyle = this.props.childrenAppearStyle;
    else if (phase === 'enter') currentStyle = this.props.childrenEnterStyle;
    else if (phase === 'leave') currentStyle = this.props.childrenLeaveStyle;
    else currentStyle = this.props.childrenBaseStyle;

    var mergedStyle = phase
      ? merge(this.props.childrenBaseStyle, currentStyle)
      : currentStyle;

    var styleStr = '';
    Object.keys(mergedStyle).forEach(function (key) {
      styleStr += hyphenateStyleName(key) + ':' + mergedStyle[key] + ';';
    });

    return styleStr;
  },

  _registerCallbackTimeout: function (callback, maxTransitionTime) {
    this._callbackTimeout = setTimeout(function () {
      callback();
    }, maxTransitionTime);
  },

  _transition: function (callback, phase) {
    if ((phase === 'appear' && !this.props.childrenAppearStyle) ||
        (phase === 'enter' && !this.props.childrenEnterStyle) ||
        (phase === 'leave' && !this.props.childrenLeaveStyle)) {
      callback();
    }
    else {
      this._executeTransition.call(this, callback, phase);
    }
  },

  _executeTransition: function (callback, phase) {
    this._lastCallback = callback;

    var node = ReactDOM.findDOMNode(this);
    if (!node) return;

    node.setAttribute('style', this._computeNewStyle(phase));

    // Flush styles
    this.flush = node.offsetWidth;

    node.removeEventListener('transitionend', this._lastCallback);
    node.addEventListener('transitionend', callback);
  },

  render: function () {
    return React.Children.only(this.props.children);
  },

});

module.exports = TransitionContainer;<commit_msg>Remove functions that were used to calculate the transition time<commit_after>var React = require('react');
var ReactDOM = require('react-dom');
var hyphenateStyleName = require('fbjs/lib/hyphenateStyleName');
var merge = require('./utils/merge');

var TransitionContainer = React.createClass({
  displayName: 'TransitionContainer',

  propTypes: {
    children: React.PropTypes.any,
    childrenAppearStyle: React.PropTypes.object,
    childrenBaseStyle: React.PropTypes.object,
    childrenEnterStyle: React.PropTypes.object,
    childrenLeaveStyle: React.PropTypes.object,
    id: React.PropTypes.oneOfType(
      [React.PropTypes.string, React.PropTypes.number]
    ),
    onChildAppeared: React.PropTypes.func,
    onChildEntered: React.PropTypes.func,
    onChildLeft: React.PropTypes.func,
    onChildStartAppear: React.PropTypes.func,
    onChildStartEnter: React.PropTypes.func,
    onChildStartLeave: React.PropTypes.func,
  },

  componentWillMount: function () {
    this._callbackTimeout = null;
  },

  componentDidMount: function () {
    var node = ReactDOM.findDOMNode(this);
    if (!node) return;

    node.setAttribute('style', this._computeNewStyle());

    // Flush styles
    this.flush = node.offsetWidth;
  },

  componentWillUnmount: function () {
    clearTimeout(this._callbackTimeout);
  },

  componentWillAppear: function (callback) {
    this._transition(callback, 'appear');

    if (this.props.onChildStartAppear) {
      this.props.onChildStartAppear(this.props.id);
    }
  },

  componentDidAppear: function () {
    if (this.props.onChildAppeared) {
      this.props.onChildAppeared(this.props.id);
    }

    this._appeared = true;
  },

  componentWillEnter: function (callback) {
    this._transition(callback, 'enter');

    if (this.props.onChildStartEnter) {
      this.props.onChildStartEnter(this.props.id);
    }
  },

  componentDidEnter: function () {
    if (this.props.onChildEntered) {
      this.props.onChildEntered(this.props.id);
    }
  },

  componentWillLeave: function (callback) {
    this._transition(callback, 'leave');

    if (this.props.onChildStartLeave) {
      this.props.onChildStartLeave(this.props.id);
    }
  },

  componentDidLeave: function () {
    if (this.props.onChildLeft) this.props.onChildLeft(this.props.id);
  },

  _computeNewStyle: function (phase) {
    var currentStyle;
    if (phase === 'appear') currentStyle = this.props.childrenAppearStyle;
    else if (phase === 'enter') currentStyle = this.props.childrenEnterStyle;
    else if (phase === 'leave') currentStyle = this.props.childrenLeaveStyle;
    else currentStyle = this.props.childrenBaseStyle;

    var mergedStyle = phase
      ? merge(this.props.childrenBaseStyle, currentStyle)
      : currentStyle;

    var styleStr = '';
    Object.keys(mergedStyle).forEach(function (key) {
      styleStr += hyphenateStyleName(key) + ':' + mergedStyle[key] + ';';
    });

    return styleStr;
  },

  _transition: function (callback, phase) {
    if ((phase === 'appear' && !this.props.childrenAppearStyle) ||
        (phase === 'enter' && !this.props.childrenEnterStyle) ||
        (phase === 'leave' && !this.props.childrenLeaveStyle)) {
      callback();
    }
    else {
      this._executeTransition.call(this, callback, phase);
    }
  },

  _executeTransition: function (callback, phase) {
    this._lastCallback = callback;

    var node = ReactDOM.findDOMNode(this);
    if (!node) return;

    node.setAttribute('style', this._computeNewStyle(phase));

    // Flush styles
    this.flush = node.offsetWidth;

    node.removeEventListener('transitionend', this._lastCallback);
    node.addEventListener('transitionend', callback);
  },

  render: function () {
    return React.Children.only(this.props.children);
  },

});

module.exports = TransitionContainer;<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { connect } from 'react-redux'
import { withNavigation } from 'react-navigation'
import ParkingCard from './ParkingCard'

export class ParkingCardContainer extends React.Component {
	gotoParkingSpotType = (navigation) => {
		navigation.navigate('ParkingSpotType')
	}

	render() {
		const { navigation } = this.props
		return (
			<ParkingCard
				gotoParkingSpotType={() => this.gotoParkingSpotType(navigation)}
			/>
		)
	}
}

const mapStateToProps = state => ({ parkingData: state.parking.data })
const ActualParkingCard = connect(mapStateToProps)(withNavigation(ParkingCardContainer))
export default ActualParkingCard
<commit_msg>Small change in syntax<commit_after>import React, { Component } from 'react'
import { connect } from 'react-redux'
import { withNavigation } from 'react-navigation'
import ParkingCard from './ParkingCard'

export class ParkingCardContainer extends Component {
	gotoParkingSpotType = (navigation) => {
		navigation.navigate('ParkingSpotType')
	}

	render() {
		const { navigation } = this.props
		return (
			<ParkingCard
				gotoParkingSpotType={() => this.gotoParkingSpotType(navigation)}
			/>
		)
	}
}

const mapStateToProps = state => ({ parkingData: state.parking.data })
const ActualParkingCard = connect(mapStateToProps)(withNavigation(ParkingCardContainer))
export default ActualParkingCard
<|endoftext|>


<commit_before>var http = require12345('http');

var server = http123421.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World\n");
});

server.listen(8000);

console.log("Server is running at http://127.0.0.1:8000/");
<commit_msg>Update app.js<commit_after>var http = require12345('http');

var server = http12we3421.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World\n");
});

server.listen(8000);

console.log("Server is running at http://127.0.0.1:8000/");
<|endoftext|>


<commit_before>// Load the http module to create an http server.
var http = require('http');

// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World I'm changed\n");
});

// Listen on port 8000, IP defaults to "0.0.0.0"
server.listen(8000);

// Put a friendly message on the terminal
console.log("Server is running at http://127.0.0.1:8000/");
<commit_msg>Update app.js<commit_after>// Load the http module to create an http server.
var http = require123('http');

// Configure our HTTP server to respond with Hello World to all requests.
var server = http.createServer(function (request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.end("Hello World I'm changed\n");
});

// Listen on port 8000, IP defaults to "0.0.0.0"
server.listen(8000);

// Put a friendly message on the terminal
console.log("Server is running at http://127.0.0.1:8000/");
<|endoftext|>


<commit_before>var CU = require('../compilerUtils'),
	U = require('../../../utils'),
	styler = require('../styler'),
	CONST = require('../../../common/constants'),
	_ = require('../../../lib/alloy/underscore')._;

var NAME_ERROR = 'Alloy.Abstract.ItemTemplate must have a "name" attribute';

exports.parse = function(node, state) {
	return require('./base').parse(node, state, parse);
};

function parse(node, state, args) {
	var code = '';

	// make sure we have a name
	var name = node.getAttribute('name');
	if (!name) {
		U.dieWithNode(node, NAME_ERROR);
	}
	node.removeAttribute('name');

	// make symbol a local variable if necessary
	if (state.local) {
		args.symbol = CU.generateUniqueId();
	}

	// apply usual style properties
	var argsObject = {
		properties: styler.generateStyleParams(
			state.styles,
			args.classes,
			args.id,
			CU.getNodeFullname(node),
			_.defaults(state.extraStyle || {}, args.createArgs || {}),
			state
		)
	};

	// add in any events on the ItemTemplate
	if (args.events && args.events.length > 0) {
		argsObject.events = '{' + _.reduce(args.events, function(memo,o) {
			return memo + o.name + ':' + o.value + ',';
		}, '') + '}';
	}

	// process children and add them to childTemplates
	var children = U.XML.getElementsFromNodes(node.childNodes);
	var childTemplates;
	if (children.length > 0) {
		childTemplates = CU.generateUniqueId();
		code += 'var ' + childTemplates + '=[];';

		_.each(children, function(child) {
			code += CU.generateNodeExtended(child, state, {
				parent: {},
				local: true,
				isViewTemplate: true,
				post: function(node, state, args) {
					return childTemplates + '.push(' + state.item.symbol + ');';
				}
			});
		});

		argsObject.childTemplates = childTemplates;
	}

	// Generate runtime code
	code += (state.local ? 'var ' : '') + args.symbol + " = {";
	code += _.reduce(argsObject, function(memo,v,k) {
		return memo + k + ':' + v + ',';
	}, '');
	code += '};';

	code += (state.templateObject || CONST.ITEM_TEMPLATE_VAR);
	code +=	'["' + name + '"]=' + args.symbol + ';';

	// Update the parsing state
	return {
		parent: {},
		local: state.local || false,
		model: state.model || undefined,
		condition: state.condition || undefined,
		styles: state.styles,
		code: code
	};
}<commit_msg>[ALOY-611] Give explicit message stating that ListView can only use Titanium APIs as template elements<commit_after>var CU = require('../compilerUtils'),
	U = require('../../../utils'),
	styler = require('../styler'),
	CONST = require('../../../common/constants'),
	_ = require('../../../lib/alloy/underscore')._;

var NAME_ERROR = 'Alloy.Abstract.ItemTemplate must have a "name" attribute';

exports.parse = function(node, state) {
	return require('./base').parse(node, state, parse);
};

function parse(node, state, args) {
	var code = '';

	// make sure we have a name
	var name = node.getAttribute('name');
	if (!name) {
		U.dieWithNode(node, NAME_ERROR);
	}
	node.removeAttribute('name');

	// make symbol a local variable if necessary
	if (state.local) {
		args.symbol = CU.generateUniqueId();
	}

	// apply usual style properties
	var argsObject = {
		properties: styler.generateStyleParams(
			state.styles,
			args.classes,
			args.id,
			CU.getNodeFullname(node),
			_.defaults(state.extraStyle || {}, args.createArgs || {}),
			state
		)
	};

	// add in any events on the ItemTemplate
	if (args.events && args.events.length > 0) {
		argsObject.events = '{' + _.reduce(args.events, function(memo,o) {
			return memo + o.name + ':' + o.value + ',';
		}, '') + '}';
	}

	// process children and add them to childTemplates
	var children = U.XML.getElementsFromNodes(node.childNodes);
	var childTemplates;
	if (children.length > 0) {
		childTemplates = CU.generateUniqueId();
		code += 'var ' + childTemplates + '=[];';

		_.each(children, function(child) {
			if (child.nodeName === 'Require' || child.nodeName === 'Widget') {
				U.dieWithNode(child, [
					'<ItemTemplate> cannot contain <Require> or <Widget> elements.',
					'ListView currently only supports Titanium API elements:',
					'  examples: <Label>, <Button>, <ImageView>, etc...',
					'Please reference the ListView guide at docs.appcelerator.com for more details.'
				]);
			}

			code += CU.generateNodeExtended(child, state, {
				parent: {},
				local: true,
				isViewTemplate: true,
				post: function(node, state, args) {
					return childTemplates + '.push(' + state.item.symbol + ');';
				}
			});
		});

		argsObject.childTemplates = childTemplates;
	}

	// Generate runtime code
	code += (state.local ? 'var ' : '') + args.symbol + " = {";
	code += _.reduce(argsObject, function(memo,v,k) {
		return memo + k + ':' + v + ',';
	}, '');
	code += '};';

	code += (state.templateObject || CONST.ITEM_TEMPLATE_VAR);
	code +=	'["' + name + '"]=' + args.symbol + ';';

	// Update the parsing state
	return {
		parent: {},
		local: state.local || false,
		model: state.model || undefined,
		condition: state.condition || undefined,
		styles: state.styles,
		code: code
	};
}<|endoftext|>


<commit_before>/**
 * @fileoverview MediaHandler
 */

/* MediaHandler
 * @class PeerConnection helper Class.
 * @param {SIP.Session} session
 * @param {Object} [options]
 * @param {SIP.WebRTC.MediaStreamManager} [options.mediaStreamManager]
 *        The MediaStreamManager to acquire/release streams from/to.
 *        If not provided, a default MediaStreamManager will be used.
 */
(function(SIP){

var MediaHandler = function(session, options) {
  var events = [
    'userMediaRequest',
    'userMedia',
    'userMediaFailed',
    'iceGathering',
    'iceComplete',
    'iceFailed',
    'getDescription',
    'setDescription',
    'dataChannel',
    'addStream'
  ];
  options = options || {};

  this.logger = session.ua.getLogger('sip.invitecontext.mediahandler', session.id);
  this.session = session;
  this.localMedia = null;
  this.ready = true;
  this.mediaStreamManager = options.mediaStreamManager || new SIP.WebRTC.MediaStreamManager();
  this.audioMuted = false;
  this.videoMuted = false;

  // old init() from here on
  var idx, length, server,
    self = this,
    servers = [],
    stunServers = options.stunServers || null,
    turnServers = options.turnServers || null,
    config = this.session.ua.configuration;
  this.RTCConstraints = options.RTCConstraints || {};

  if (!stunServers) {
    stunServers = config.stunServers;
  }

  if(!turnServers) {
    turnServers = config.turnServers;
  }

  /* Change 'url' to 'urls' whenever this issue is solved:
   * https://code.google.com/p/webrtc/issues/detail?id=2096
   */
  servers.push({'url': stunServers});

  length = turnServers.length;
  for (idx = 0; idx < length; idx++) {
    server = turnServers[idx];
    servers.push({
      'url': server.urls,
      'username': server.username,
      'credential': server.password
    });
  }

  this.peerConnection = new SIP.WebRTC.RTCPeerConnection({'iceServers': servers}, this.RTCConstraints);

  this.peerConnection.onaddstream = function(e) {
    self.logger.log('stream added: '+ e.stream.id);
    self.render();
    self.emit('addStream', e);
  };

  this.peerConnection.onremovestream = function(e) {
    self.logger.log('stream removed: '+ e.stream.id);
  };

  this.peerConnection.onicecandidate = function(e) {
    if (e.candidate) {
      self.logger.log('ICE candidate received: '+ e.candidate.candidate);
    } else if (self.onIceCompleted !== undefined) {
      self.onIceCompleted(this);
    }
  };

  this.peerConnection.onicegatheringstatechange = function () {
    self.logger.log('RTCIceGatheringState changed: ' + this.iceGatheringState);
    if (this.iceGatheringState === 'gathering') {
      self.emit('iceGathering', this);
    }
    if (this.iceGatheringState === 'complete' &&
        self.onIceCompleted !== undefined) {
      self.onIceCompleted(this);
    }
  };

  this.peerConnection.oniceconnectionstatechange = function() {  //need e for commented out case
    self.logger.log('ICE connection state changed to "'+ this.iceConnectionState +'"');
    //Bria state changes are always connected -> disconnected -> connected on accept, so session gets terminated
    //normal calls switch from failed to connected in some cases, so checking for failed and terminated
    /*if (this.iceConnectionState === 'failed') {
      self.session.terminate({
        cause: SIP.C.causes.RTP_TIMEOUT,
        status_code: 200,
        reason_phrase: SIP.C.causes.RTP_TIMEOUT
      });
    } else if (e.currentTarget.iceGatheringState === 'complete' && this.iceConnectionState !== 'closed') {
      self.onIceCompleted(this);
    }*/
  };

  this.peerConnection.onstatechange = function() {
    self.logger.log('PeerConnection state changed to "'+ this.readyState +'"');
  };

  this.initEvents(events);

  function selfEmit(mh, event) {
    if (mh.mediaStreamManager.on &&
        mh.mediaStreamManager.checkEvent &&
        mh.mediaStreamManager.checkEvent(event)) {
      mh.mediaStreamManager.on(event, function () {
        mh.emit.apply(mh, [event].concat(Array.prototype.slice.call(arguments)));
      });
    }
  }

  selfEmit(this, 'userMediaRequest');
  selfEmit(this, 'userMedia');
  selfEmit(this, 'userMediaFailed');
};

MediaHandler.defaultFactory = function defaultFactory (session, options) {
  return new MediaHandler(session, options);
};
MediaHandler.defaultFactory.isSupported = function () {
  return SIP.WebRTC.isSupported();
};

MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, {
// Functions the session can use
  isReady: {writable: true, value: function isReady () {
    return this.ready;
  }},

  close: {writable: true, value: function close () {
    this.logger.log('closing PeerConnection');
    // have to check signalingState since this.close() gets called multiple times
    // TODO figure out why that happens
    if(this.peerConnection && this.peerConnection.signalingState !== 'closed') {
      this.peerConnection.close();

      if(this.localMedia) {
        this.mediaStreamManager.release(this.localMedia);
      }
    }
  }},

  /**
   * @param {Function} onSuccess
   * @param {Function} onFailure
   * @param {SIP.WebRTC.MediaStream | (getUserMedia constraints)} [mediaHint]
   *        the MediaStream (or the constraints describing it) to be used for the session
   */
  getDescription: {writable: true, value: function getDescription (onSuccess, onFailure, mediaHint) {
    var self = this;
    mediaHint = mediaHint || {};
    if (mediaHint.dataChannel === true) {
      mediaHint.dataChannel = {};
    }
    this.mediaHint = mediaHint;

    /*
     * 1. acquire stream (skip if MediaStream passed in)
     * 2. addStream
     * 3. createOffer/createAnswer
     * 4. call onSuccess()
     */

    /* Last functions first, to quiet JSLint */
    function streamAdditionSucceeded() {
      if (self.hasOffer('remote')) {
        self.peerConnection.ondatachannel = function (evt) {
          self.dataChannel = evt.channel;
          self.emit('dataChannel', self.dataChannel);
        };
      } else if (mediaHint.dataChannel &&
                 self.peerConnection.createDataChannel) {
        self.dataChannel = self.peerConnection.createDataChannel(
          'sipjs',
          mediaHint.dataChannel
        );
        self.emit('dataChannel', self.dataChannel);
      }

      self.createOfferOrAnswer(onSuccess, onFailure, self.RTCConstraints);
    }

    function acquireSucceeded(stream) {
      self.logger.log('acquired local media stream');
      self.localMedia = stream;
      self.session.connecting();
      self.addStream(
        stream,
        streamAdditionSucceeded,
        onFailure,
        self.RTCConstraints
      );
    }

    if (self.localMedia) {
      self.logger.log('already have local media');
      streamAdditionSucceeded();
      return;
    }

    self.logger.log('acquiring local media');
    self.mediaStreamManager.acquire(
      acquireSucceeded,
      function acquireFailed(err) {
        self.logger.error('unable to acquire stream');
        self.logger.error(err);
        self.session.connecting();
        onFailure(err);
      },
      mediaHint
    );
  }},

  /**
  * Message reception.
  * @param {String} type
  * @param {String} sdp
  * @param {Function} onSuccess
  * @param {Function} onFailure
  */
  setDescription: {writable: true, value: function setDescription (sdp, onSuccess, onFailure) {
    var rawDescription = {
      type: this.hasOffer('local') ? 'answer' : 'offer',
      sdp: sdp
    };

    this.emit('setDescription', rawDescription);

    var description = new SIP.WebRTC.RTCSessionDescription(rawDescription);
    this.peerConnection.setRemoteDescription(description, onSuccess, onFailure);
  }},

// Functions the session can use, but only because it's convenient for the application
  isMuted: {writable: true, value: function isMuted () {
    return {
      audio: this.audioMuted,
      video: this.videoMuted
    };
  }},

  mute: {writable: true, value: function mute (options) {
    if (this.getLocalStreams().length === 0) {
      return;
    }

    options = options || {
      audio: this.getLocalStreams()[0].getAudioTracks().length > 0,
      video: this.getLocalStreams()[0].getVideoTracks().length > 0
    };

    var audioMuted = false,
        videoMuted = false;

    if (options.audio && !this.audioMuted) {
      audioMuted = true;
      this.audioMuted = true;
      this.toggleMuteAudio(true);
    }

    if (options.video && !this.videoMuted) {
      videoMuted = true;
      this.videoMuted = true;
      this.toggleMuteVideo(true);
    }

    //REVISIT
    if (audioMuted || videoMuted) {
      return {
        audio: audioMuted,
        video: videoMuted
      };
      /*this.session.onmute({
        audio: audioMuted,
        video: videoMuted
      });*/
    }
  }},

  unmute: {writable: true, value: function unmute (options) {
    if (this.getLocalStreams().length === 0) {
      return;
    }

    options = options || {
      audio: this.getLocalStreams()[0].getAudioTracks().length > 0,
      video: this.getLocalStreams()[0].getVideoTracks().length > 0
    };

    var audioUnMuted = false,
        videoUnMuted = false;

    if (options.audio && this.audioMuted) {
      audioUnMuted = true;
      this.audioMuted = false;
      this.toggleMuteAudio(false);
    }

    if (options.video && this.videoMuted) {
      videoUnMuted = true;
      this.videoMuted = false;
      this.toggleMuteVideo(false);
    }

    //REVISIT
    if (audioUnMuted || videoUnMuted) {
      return {
        audio: audioUnMuted,
        video: videoUnMuted
      };
      /*this.session.onunmute({
        audio: audioUnMuted,
        video: videoUnMuted
      });*/
    }
  }},

  hold: {writable: true, value: function hold () {
    this.toggleMuteAudio(true);
    this.toggleMuteVideo(true);
  }},

  unhold: {writable: true, value: function unhold () {
    if (!this.audioMuted) {
      this.toggleMuteAudio(false);
    }

    if (!this.videoMuted) {
      this.toggleMuteVideo(false);
    }
  }},

// Functions the application can use, but not the session
  getLocalStreams: {writable: true, value: function getLocalStreams () {
    var pc = this.peerConnection;
    if (pc && pc.signalingState === 'closed') {
      this.logger.warn('peerConnection is closed, getLocalStreams returning []');
      return [];
    }
    return (pc.getLocalStreams && pc.getLocalStreams()) ||
      pc.localStreams || [];
  }},

  getRemoteStreams: {writable: true, value: function getRemoteStreams () {
    var pc = this.peerConnection;
    if (pc && pc.signalingState === 'closed') {
      this.logger.warn('peerConnection is closed, getRemoteStreams returning []');
      return [];
    }
    return(pc.getRemoteStreams && pc.getRemoteStreams()) ||
      pc.remoteStreams || [];
  }},

  render: {writable: true, value: function render (renderHint) {
    renderHint = renderHint || (this.mediaHint && this.mediaHint.render);
    if (!renderHint) {
      return false;
    }
    var streamGetters = {
      local: 'getLocalStreams',
      remote: 'getRemoteStreams'
    };
    Object.keys(streamGetters).forEach(function (loc) {
      var streamGetter = streamGetters[loc];
      var streams = this[streamGetter]();
      if (streams.length) {
        SIP.WebRTC.MediaStreamManager.render(streams[0], renderHint[loc]);
      }
    }.bind(this));
  }},

// Internal functions
  hasOffer: {writable: true, value: function hasOffer (where) {
    var offerState = 'have-' + where + '-offer';
    return this.peerConnection.signalingState === offerState;
    // TODO consider signalingStates with 'pranswer'?
  }},

  createOfferOrAnswer: {writable: true, value: function createOfferOrAnswer (onSuccess, onFailure, constraints) {
    var self = this;
    var methodName;

    function readySuccess () {
      var sdp = self.peerConnection.localDescription.sdp;

      sdp = SIP.Hacks.Chrome.needsExplicitlyInactiveSDP(sdp);

      var sdpWrapper = {
        type: methodName === 'createOffer' ? 'offer' : 'answer',
        sdp: sdp
      };

      self.emit('getDescription', sdpWrapper);

      self.ready = true;
      onSuccess(sdp);
    }

    function onSetLocalDescriptionSuccess() {
      if (self.peerConnection.iceGatheringState === 'complete' && self.peerConnection.iceConnectionState === 'connected') {
        readySuccess();
      } else {
        self.onIceCompleted = function(pc) {
          self.logger.log('ICE Gathering Completed');
          self.onIceCompleted = undefined;
          self.emit('iceComplete', pc);
          readySuccess();
        };
      }
    }

    function methodFailed (methodName, e) {
      self.logger.error('peerConnection.' + methodName + ' failed');
      self.logger.error(e);
      self.ready = true;
      onFailure(e);
    }

    self.ready = false;

    methodName = self.hasOffer('remote') ? 'createAnswer' : 'createOffer';

    self.peerConnection[methodName](
      function(sessionDescription){
        self.peerConnection.setLocalDescription(
          sessionDescription,
          onSetLocalDescriptionSuccess,
          methodFailed.bind(null, 'setLocalDescription')
        );
      },
      methodFailed.bind(null, methodName),
      constraints
    );
  }},

  addStream: {writable: true, value: function addStream (stream, onSuccess, onFailure, constraints) {
    try {
      this.peerConnection.addStream(stream, constraints);
    } catch(e) {
      this.logger.error('error adding stream');
      this.logger.error(e);
      onFailure(e);
      return;
    }

    onSuccess();
  }},

  toggleMuteHelper: {writable: true, value: function toggleMuteHelper (trackGetter, mute) {
    this.getLocalStreams().forEach(function (stream) {
      stream[trackGetter]().forEach(function (track) {
        track.enabled = !mute;
      });
    });
  }},

  toggleMuteAudio: {writable: true, value: function toggleMuteAudio (mute) {
    this.toggleMuteHelper('getAudioTracks', mute);
  }},

  toggleMuteVideo: {writable: true, value: function toggleMuteVideo (mute) {
    this.toggleMuteHelper('getVideoTracks', mute);
  }}
});

// Return since it will be assigned to a variable.
return MediaHandler;
}(SIP));
<commit_msg>WebRTC.MediaHandler: don't pass constraints to peerConnection.addStream<commit_after>/**
 * @fileoverview MediaHandler
 */

/* MediaHandler
 * @class PeerConnection helper Class.
 * @param {SIP.Session} session
 * @param {Object} [options]
 * @param {SIP.WebRTC.MediaStreamManager} [options.mediaStreamManager]
 *        The MediaStreamManager to acquire/release streams from/to.
 *        If not provided, a default MediaStreamManager will be used.
 */
(function(SIP){

var MediaHandler = function(session, options) {
  var events = [
    'userMediaRequest',
    'userMedia',
    'userMediaFailed',
    'iceGathering',
    'iceComplete',
    'iceFailed',
    'getDescription',
    'setDescription',
    'dataChannel',
    'addStream'
  ];
  options = options || {};

  this.logger = session.ua.getLogger('sip.invitecontext.mediahandler', session.id);
  this.session = session;
  this.localMedia = null;
  this.ready = true;
  this.mediaStreamManager = options.mediaStreamManager || new SIP.WebRTC.MediaStreamManager();
  this.audioMuted = false;
  this.videoMuted = false;

  // old init() from here on
  var idx, length, server,
    self = this,
    servers = [],
    stunServers = options.stunServers || null,
    turnServers = options.turnServers || null,
    config = this.session.ua.configuration;
  this.RTCConstraints = options.RTCConstraints || {};

  if (!stunServers) {
    stunServers = config.stunServers;
  }

  if(!turnServers) {
    turnServers = config.turnServers;
  }

  /* Change 'url' to 'urls' whenever this issue is solved:
   * https://code.google.com/p/webrtc/issues/detail?id=2096
   */
  servers.push({'url': stunServers});

  length = turnServers.length;
  for (idx = 0; idx < length; idx++) {
    server = turnServers[idx];
    servers.push({
      'url': server.urls,
      'username': server.username,
      'credential': server.password
    });
  }

  this.peerConnection = new SIP.WebRTC.RTCPeerConnection({'iceServers': servers}, this.RTCConstraints);

  this.peerConnection.onaddstream = function(e) {
    self.logger.log('stream added: '+ e.stream.id);
    self.render();
    self.emit('addStream', e);
  };

  this.peerConnection.onremovestream = function(e) {
    self.logger.log('stream removed: '+ e.stream.id);
  };

  this.peerConnection.onicecandidate = function(e) {
    if (e.candidate) {
      self.logger.log('ICE candidate received: '+ e.candidate.candidate);
    } else if (self.onIceCompleted !== undefined) {
      self.onIceCompleted(this);
    }
  };

  this.peerConnection.onicegatheringstatechange = function () {
    self.logger.log('RTCIceGatheringState changed: ' + this.iceGatheringState);
    if (this.iceGatheringState === 'gathering') {
      self.emit('iceGathering', this);
    }
    if (this.iceGatheringState === 'complete' &&
        self.onIceCompleted !== undefined) {
      self.onIceCompleted(this);
    }
  };

  this.peerConnection.oniceconnectionstatechange = function() {  //need e for commented out case
    self.logger.log('ICE connection state changed to "'+ this.iceConnectionState +'"');
    //Bria state changes are always connected -> disconnected -> connected on accept, so session gets terminated
    //normal calls switch from failed to connected in some cases, so checking for failed and terminated
    /*if (this.iceConnectionState === 'failed') {
      self.session.terminate({
        cause: SIP.C.causes.RTP_TIMEOUT,
        status_code: 200,
        reason_phrase: SIP.C.causes.RTP_TIMEOUT
      });
    } else if (e.currentTarget.iceGatheringState === 'complete' && this.iceConnectionState !== 'closed') {
      self.onIceCompleted(this);
    }*/
  };

  this.peerConnection.onstatechange = function() {
    self.logger.log('PeerConnection state changed to "'+ this.readyState +'"');
  };

  this.initEvents(events);

  function selfEmit(mh, event) {
    if (mh.mediaStreamManager.on &&
        mh.mediaStreamManager.checkEvent &&
        mh.mediaStreamManager.checkEvent(event)) {
      mh.mediaStreamManager.on(event, function () {
        mh.emit.apply(mh, [event].concat(Array.prototype.slice.call(arguments)));
      });
    }
  }

  selfEmit(this, 'userMediaRequest');
  selfEmit(this, 'userMedia');
  selfEmit(this, 'userMediaFailed');
};

MediaHandler.defaultFactory = function defaultFactory (session, options) {
  return new MediaHandler(session, options);
};
MediaHandler.defaultFactory.isSupported = function () {
  return SIP.WebRTC.isSupported();
};

MediaHandler.prototype = Object.create(SIP.MediaHandler.prototype, {
// Functions the session can use
  isReady: {writable: true, value: function isReady () {
    return this.ready;
  }},

  close: {writable: true, value: function close () {
    this.logger.log('closing PeerConnection');
    // have to check signalingState since this.close() gets called multiple times
    // TODO figure out why that happens
    if(this.peerConnection && this.peerConnection.signalingState !== 'closed') {
      this.peerConnection.close();

      if(this.localMedia) {
        this.mediaStreamManager.release(this.localMedia);
      }
    }
  }},

  /**
   * @param {Function} onSuccess
   * @param {Function} onFailure
   * @param {SIP.WebRTC.MediaStream | (getUserMedia constraints)} [mediaHint]
   *        the MediaStream (or the constraints describing it) to be used for the session
   */
  getDescription: {writable: true, value: function getDescription (onSuccess, onFailure, mediaHint) {
    var self = this;
    mediaHint = mediaHint || {};
    if (mediaHint.dataChannel === true) {
      mediaHint.dataChannel = {};
    }
    this.mediaHint = mediaHint;

    /*
     * 1. acquire stream (skip if MediaStream passed in)
     * 2. addStream
     * 3. createOffer/createAnswer
     * 4. call onSuccess()
     */

    /* Last functions first, to quiet JSLint */
    function streamAdditionSucceeded() {
      if (self.hasOffer('remote')) {
        self.peerConnection.ondatachannel = function (evt) {
          self.dataChannel = evt.channel;
          self.emit('dataChannel', self.dataChannel);
        };
      } else if (mediaHint.dataChannel &&
                 self.peerConnection.createDataChannel) {
        self.dataChannel = self.peerConnection.createDataChannel(
          'sipjs',
          mediaHint.dataChannel
        );
        self.emit('dataChannel', self.dataChannel);
      }

      self.createOfferOrAnswer(onSuccess, onFailure, self.RTCConstraints);
    }

    function acquireSucceeded(stream) {
      self.logger.log('acquired local media stream');
      self.localMedia = stream;
      self.session.connecting();
      self.addStream(
        stream,
        streamAdditionSucceeded,
        onFailure
      );
    }

    if (self.localMedia) {
      self.logger.log('already have local media');
      streamAdditionSucceeded();
      return;
    }

    self.logger.log('acquiring local media');
    self.mediaStreamManager.acquire(
      acquireSucceeded,
      function acquireFailed(err) {
        self.logger.error('unable to acquire stream');
        self.logger.error(err);
        self.session.connecting();
        onFailure(err);
      },
      mediaHint
    );
  }},

  /**
  * Message reception.
  * @param {String} type
  * @param {String} sdp
  * @param {Function} onSuccess
  * @param {Function} onFailure
  */
  setDescription: {writable: true, value: function setDescription (sdp, onSuccess, onFailure) {
    var rawDescription = {
      type: this.hasOffer('local') ? 'answer' : 'offer',
      sdp: sdp
    };

    this.emit('setDescription', rawDescription);

    var description = new SIP.WebRTC.RTCSessionDescription(rawDescription);
    this.peerConnection.setRemoteDescription(description, onSuccess, onFailure);
  }},

// Functions the session can use, but only because it's convenient for the application
  isMuted: {writable: true, value: function isMuted () {
    return {
      audio: this.audioMuted,
      video: this.videoMuted
    };
  }},

  mute: {writable: true, value: function mute (options) {
    if (this.getLocalStreams().length === 0) {
      return;
    }

    options = options || {
      audio: this.getLocalStreams()[0].getAudioTracks().length > 0,
      video: this.getLocalStreams()[0].getVideoTracks().length > 0
    };

    var audioMuted = false,
        videoMuted = false;

    if (options.audio && !this.audioMuted) {
      audioMuted = true;
      this.audioMuted = true;
      this.toggleMuteAudio(true);
    }

    if (options.video && !this.videoMuted) {
      videoMuted = true;
      this.videoMuted = true;
      this.toggleMuteVideo(true);
    }

    //REVISIT
    if (audioMuted || videoMuted) {
      return {
        audio: audioMuted,
        video: videoMuted
      };
      /*this.session.onmute({
        audio: audioMuted,
        video: videoMuted
      });*/
    }
  }},

  unmute: {writable: true, value: function unmute (options) {
    if (this.getLocalStreams().length === 0) {
      return;
    }

    options = options || {
      audio: this.getLocalStreams()[0].getAudioTracks().length > 0,
      video: this.getLocalStreams()[0].getVideoTracks().length > 0
    };

    var audioUnMuted = false,
        videoUnMuted = false;

    if (options.audio && this.audioMuted) {
      audioUnMuted = true;
      this.audioMuted = false;
      this.toggleMuteAudio(false);
    }

    if (options.video && this.videoMuted) {
      videoUnMuted = true;
      this.videoMuted = false;
      this.toggleMuteVideo(false);
    }

    //REVISIT
    if (audioUnMuted || videoUnMuted) {
      return {
        audio: audioUnMuted,
        video: videoUnMuted
      };
      /*this.session.onunmute({
        audio: audioUnMuted,
        video: videoUnMuted
      });*/
    }
  }},

  hold: {writable: true, value: function hold () {
    this.toggleMuteAudio(true);
    this.toggleMuteVideo(true);
  }},

  unhold: {writable: true, value: function unhold () {
    if (!this.audioMuted) {
      this.toggleMuteAudio(false);
    }

    if (!this.videoMuted) {
      this.toggleMuteVideo(false);
    }
  }},

// Functions the application can use, but not the session
  getLocalStreams: {writable: true, value: function getLocalStreams () {
    var pc = this.peerConnection;
    if (pc && pc.signalingState === 'closed') {
      this.logger.warn('peerConnection is closed, getLocalStreams returning []');
      return [];
    }
    return (pc.getLocalStreams && pc.getLocalStreams()) ||
      pc.localStreams || [];
  }},

  getRemoteStreams: {writable: true, value: function getRemoteStreams () {
    var pc = this.peerConnection;
    if (pc && pc.signalingState === 'closed') {
      this.logger.warn('peerConnection is closed, getRemoteStreams returning []');
      return [];
    }
    return(pc.getRemoteStreams && pc.getRemoteStreams()) ||
      pc.remoteStreams || [];
  }},

  render: {writable: true, value: function render (renderHint) {
    renderHint = renderHint || (this.mediaHint && this.mediaHint.render);
    if (!renderHint) {
      return false;
    }
    var streamGetters = {
      local: 'getLocalStreams',
      remote: 'getRemoteStreams'
    };
    Object.keys(streamGetters).forEach(function (loc) {
      var streamGetter = streamGetters[loc];
      var streams = this[streamGetter]();
      if (streams.length) {
        SIP.WebRTC.MediaStreamManager.render(streams[0], renderHint[loc]);
      }
    }.bind(this));
  }},

// Internal functions
  hasOffer: {writable: true, value: function hasOffer (where) {
    var offerState = 'have-' + where + '-offer';
    return this.peerConnection.signalingState === offerState;
    // TODO consider signalingStates with 'pranswer'?
  }},

  createOfferOrAnswer: {writable: true, value: function createOfferOrAnswer (onSuccess, onFailure, constraints) {
    var self = this;
    var methodName;

    function readySuccess () {
      var sdp = self.peerConnection.localDescription.sdp;

      sdp = SIP.Hacks.Chrome.needsExplicitlyInactiveSDP(sdp);

      var sdpWrapper = {
        type: methodName === 'createOffer' ? 'offer' : 'answer',
        sdp: sdp
      };

      self.emit('getDescription', sdpWrapper);

      self.ready = true;
      onSuccess(sdp);
    }

    function onSetLocalDescriptionSuccess() {
      if (self.peerConnection.iceGatheringState === 'complete' && self.peerConnection.iceConnectionState === 'connected') {
        readySuccess();
      } else {
        self.onIceCompleted = function(pc) {
          self.logger.log('ICE Gathering Completed');
          self.onIceCompleted = undefined;
          self.emit('iceComplete', pc);
          readySuccess();
        };
      }
    }

    function methodFailed (methodName, e) {
      self.logger.error('peerConnection.' + methodName + ' failed');
      self.logger.error(e);
      self.ready = true;
      onFailure(e);
    }

    self.ready = false;

    methodName = self.hasOffer('remote') ? 'createAnswer' : 'createOffer';

    self.peerConnection[methodName](
      function(sessionDescription){
        self.peerConnection.setLocalDescription(
          sessionDescription,
          onSetLocalDescriptionSuccess,
          methodFailed.bind(null, 'setLocalDescription')
        );
      },
      methodFailed.bind(null, methodName),
      constraints
    );
  }},

  addStream: {writable: true, value: function addStream (stream, onSuccess, onFailure) {
    try {
      this.peerConnection.addStream(stream);
    } catch(e) {
      this.logger.error('error adding stream');
      this.logger.error(e);
      onFailure(e);
      return;
    }

    onSuccess();
  }},

  toggleMuteHelper: {writable: true, value: function toggleMuteHelper (trackGetter, mute) {
    this.getLocalStreams().forEach(function (stream) {
      stream[trackGetter]().forEach(function (track) {
        track.enabled = !mute;
      });
    });
  }},

  toggleMuteAudio: {writable: true, value: function toggleMuteAudio (mute) {
    this.toggleMuteHelper('getAudioTracks', mute);
  }},

  toggleMuteVideo: {writable: true, value: function toggleMuteVideo (mute) {
    this.toggleMuteHelper('getVideoTracks', mute);
  }}
});

// Return since it will be assigned to a variable.
return MediaHandler;
}(SIP));
<|endoftext|>


<commit_before>exports.run = (client, message, args) => {
  function getRandomColor() {

        let letters = '0123456789';
        let color = '';
        for (let i = 0; i < 7; i++) {
            color += letters[Math.floor(Math.random() * 10)];
        }

        return color;
    }
  const config = require("../config.json");
    const path = require('path');
    const prefixes = path.join('../prefixes.json')
    const prefix = JSON.parse(fs.readFileSync(prefixes, 'utf8'));
    const param = args.slice(1).join(' ');
    const fs = require('fs');

    if (args[0] === ' set') {
      if (!prefix[message.guild.id]) prefix = {'prefix', config.prefix};
      if (param === 'default') {
        prefix[message.guild.id].prefix = config.prefix;
        fs.writeFileSync(prefixes, JSON.stringify(data, null, 2))
        msg.reply(`wew set my prefix back to ${config.prefix}.`)
      } else {
        prefix[message.guild.id].prefix = param;
        fs.writeFileSync(prefixes, JSON.stringify(data, null, 2))
        msg.reply(`wew set my prefix to ${param}.`)
      }
    } else {
      message.channel.send({
        embed: {
            color: getRandomColor(),
            author: {
                name: "Prefix for " + message.guild.name
                icon_url: message.guild.iconURL()
            },
            description: 'huh use ' + prefix[message.guild.id].prefix + 'help for my beautiful commands wew',
            timestamp: new Date(),
            footer: {
                text: "Help requested by " + message.author.username
            }
        }
    }).catch(e => console.warn('wew tf happened here ' + e))
    }
};
<commit_msg>Update prefix.js<commit_after>exports.run = (client, message, args) => {
  function getRandomColor() {

        let letters = '0123456789';
        let color = '';
        for (let i = 0; i < 7; i++) {
            color += letters[Math.floor(Math.random() * 10)];
        }

        return color;
    }
  const config = require("../config.json");
    const path = require("path");
    const prefixes = path.join("../prefixes.json")
    const prefix = JSON.parse(fs.readFileSync(prefixes, 'utf8'));
    const param = args.slice(1).join(' ');
    const fs = require('fs');

    if (args[0] === ' set') {
      if (!prefix[message.guild.id]) prefix = {'prefix', config.prefix};
      if (param === 'default') {
        prefix[message.guild.id].prefix = config.prefix;
        fs.writeFileSync(prefixes, JSON.stringify(data, null, 2))
        msg.reply(`wew set my prefix back to ${config.prefix}.`)
      } else {
        prefix[message.guild.id].prefix = param;
        fs.writeFileSync(prefixes, JSON.stringify(data, null, 2))
        msg.reply(`wew set my prefix to ${param}.`)
      }
    } else {
      message.channel.send({
        embed: {
            color: getRandomColor(),
            author: {
                name: "Prefix for " + message.guild.name
                icon_url: message.guild.iconURL()
            },
            description: 'huh use ' + prefix[message.guild.id].prefix + 'help for my beautiful commands wew',
            timestamp: new Date(),
            footer: {
                text: "Help requested by " + message.author.username
            }
        }
    }).catch(e => console.warn('wew tf happened here ' + e))
    }
};
<|endoftext|>