<commit_before>const io = require("socket.io-client");
const Promise = require("es6-promise").Promise;

class Socket {
	constructor(server, padId) {
		this._init(server, padId);
	}

	_init(server, padId) {
		// Needs to be in a separate method so that we can merge this class with a scope object in the frontend.

		this.server = server;
		this.padId = padId;

		this.socket = io.connect(server, { 'force new connection': true });

		this.padData = null;
		this.readonly = null;
		this.writable = null;
		this.markers = { };
		this.lines = { };
		this.views = { };
		this.types = { };
		this.history = { };
		this.route = null;

		this._listeners = [ ];

		for(let i in this._handlers) {
			this.on(i, this._handlers[i].bind(this));
		}

		setTimeout(() => {
			this._simulateEvent("loadStart");
		}, 0);
		let firstConnectHandler = () => {
			this.removeListener("connect", firstConnectHandler);
			this._simulateEvent("loadEnd");
		};
		this.on("connect", firstConnectHandler);
	}

	on(eventName, fn) {
		if(typeof this._listeners[eventName] != "object") {
			this._listeners[eventName] = [ ];
			this.socket.on(eventName, this._simulateEvent.bind(this, eventName));
		}

		this._listeners[eventName].push(fn);
    }

	removeListener(eventName, fn) {
		if(typeof this._listeners[eventName] == "object") {
			this._listeners[eventName] = this._listeners[eventName].filter((listener) => (listener !== fn));
		}
	}

	_emit(eventName, data) {
		return new Promise((resolve, reject) => {
			this._simulateEvent("loadStart");

			this.socket.emit(eventName, data, (err, data) => {
				this._simulateEvent("loadEnd");

				if(err)
					reject(err);
				else
					resolve(data);
			});
		});
	}

	setPadId(padId) {
		if(this.padId != null)
			throw new Error("Pad ID already set.");

		return this._setPadId(padId);
	}

	updateBbox(bbox) {
		this.bbox = bbox;
		return this._emit("updateBbox", bbox).then((obj) => {
			this._receiveMultiple(obj);
		});
	}

	createPad(data) {
		return this._emit("createPad", data).then((obj) => {
			this.readonly = false;
			this.writable = 2;

			this._receiveMultiple(obj);
		});
	}

	editPad(data) {
		return this._emit("editPad", data);
	}

	listenToHistory() {
		return this._emit("listenToHistory").then((obj) => {
			this._listeningToHistory = true;
			this._receiveMultiple(obj);
		});
	}

	stopListeningToHistory() {
		this._listeningToHistory = false;
		return this._emit("stopListeningToHistory");
	}

	revertHistoryEntry(data) {
		return this._emit("revertHistoryEntry", data).then((obj) => {
			this.history = { };
			this._receiveMultiple(obj);
		});
	}

	addMarker(data) {
		return this._emit("addMarker", data);
	}

	editMarker(data) {
		return this._emit("editMarker", data);
	}

	deleteMarker(data) {
		return this._emit("deleteMarker", data);
	}

	getLineTemplate(data) {
		return this._emit("getLineTemplate", data);
	}

	addLine(data) {
		return this._emit("addLine", data);
	}

	editLine(data) {
		return this._emit("editLine", data);
	}

	deleteLine(data) {
		return this._emit("deleteLine", data);
	}

	exportLine(data) {
		return this._emit("exportLine", data);
	}

	find(data) {
		return this._emit("find", data);
	}

	getRoute(data) {
		return this._emit("getRoute", data);
	}

	setRoute(data) {
		return this._emit("setRoute", data).then((route) => {
			if(route) { // If unset, a newer submitted route has returned in the meantime
				this.route = route;
				this.route.trackPoints = this._mergeTrackPoints({}, route.trackPoints);
			}

			return this.route;<commit_msg>Fetch route elevation profile on reconnect<commit_after>const io = require("socket.io-client");
const Promise = require("es6-promise").Promise;

class Socket {
	constructor(server, padId) {
		this._init(server, padId);
	}

	_init(server, padId) {
		// Needs to be in a separate method so that we can merge this class with a scope object in the frontend.

		this.server = server;
		this.padId = padId;

		this.socket = io.connect(server, { 'force new connection': true });

		this.padData = null;
		this.readonly = null;
		this.writable = null;
		this.markers = { };
		this.lines = { };
		this.views = { };
		this.types = { };
		this.history = { };
		this.route = null;

		this._listeners = [ ];

		for(let i in this._handlers) {
			this.on(i, this._handlers[i].bind(this));
		}

		setTimeout(() => {
			this._simulateEvent("loadStart");
		}, 0);
		let firstConnectHandler = () => {
			this.removeListener("connect", firstConnectHandler);
			this._simulateEvent("loadEnd");
		};
		this.on("connect", firstConnectHandler);
	}

	on(eventName, fn) {
		if(typeof this._listeners[eventName] != "object") {
			this._listeners[eventName] = [ ];
			this.socket.on(eventName, this._simulateEvent.bind(this, eventName));
		}

		this._listeners[eventName].push(fn);
    }

	removeListener(eventName, fn) {
		if(typeof this._listeners[eventName] == "object") {
			this._listeners[eventName] = this._listeners[eventName].filter((listener) => (listener !== fn));
		}
	}

	_emit(eventName, data) {
		return new Promise((resolve, reject) => {
			this._simulateEvent("loadStart");

			this.socket.emit(eventName, data, (err, data) => {
				this._simulateEvent("loadEnd");

				if(err)
					reject(err);
				else
					resolve(data);
			});
		});
	}

	setPadId(padId) {
		if(this.padId != null)
			throw new Error("Pad ID already set.");

		return this._setPadId(padId);
	}

	updateBbox(bbox) {
		this.bbox = bbox;
		return this._emit("updateBbox", bbox).then((obj) => {
			this._receiveMultiple(obj);
		});
	}

	createPad(data) {
		return this._emit("createPad", data).then((obj) => {
			this.readonly = false;
			this.writable = 2;

			this._receiveMultiple(obj);
		});
	}

	editPad(data) {
		return this._emit("editPad", data);
	}

	listenToHistory() {
		return this._emit("listenToHistory").then((obj) => {
			this._listeningToHistory = true;
			this._receiveMultiple(obj);
		});
	}

	stopListeningToHistory() {
		this._listeningToHistory = false;
		return this._emit("stopListeningToHistory");
	}

	revertHistoryEntry(data) {
		return this._emit("revertHistoryEntry", data).then((obj) => {
			this.history = { };
			this._receiveMultiple(obj);
		});
	}

	addMarker(data) {
		return this._emit("addMarker", data);
	}

	editMarker(data) {
		return this._emit("editMarker", data);
	}

	deleteMarker(data) {
		return this._emit("deleteMarker", data);
	}

	getLineTemplate(data) {
		return this._emit("getLineTemplate", data);
	}

	addLine(data) {
		return this._emit("addLine", data);
	}

	editLine(data) {
		return this._emit("editLine", data);
	}

	deleteLine(data) {
		return this._emit("deleteLine", data);
	}

	exportLine(data) {
		return this._emit("exportLine", data);
	}

	find(data) {
		return this._emit("find", data);
	}

	getRoute(data) {
		return this._emit("getRoute", data);
	}

	setRoute(data) {
		return this._emit("setRoute", data).then((route) => {
			if(route) { // If unset, a newer submitted route has returned in the meantime
				this.route = route;
				this.route.elevation = data.elevation; // For reconnect
				this.route.trackPoints = this._mergeTrackPoints({}, route.trackPoints);
			}

			return this.route;
{'fraction_non_alphanumeric': 0.1655703289013296, 'fraction_numerical': 0.0008397480755773268, 'mean_word_length': 3.838185511171293, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6670308', 'n_tokens_mistral': 2785, 'n_tokens_neox': 2453, 'n_words': 450}