<commit_before>"use strict";

function AnimationTab(parent, closeable, container, index)
{
	TabElement.call(this, parent, closeable, container, index, "Animation", Editor.filePath + "icons/misc/animation.png");

	var self = this;

	this.obj = null;
	this.mixer = null;

	this.zoom = 50.0; //Pixels/sec
	this.timelineHeight = 20;

	//Bar
	this.bar = document.createElement("div");
	this.bar.style.backgroundColor = Editor.theme.barColor;
	this.bar.style.overflow = "visible";
	this.bar.style.position = "absolute";
	this.bar.style.width = "100%";
	this.bar.style.height = "20px";
	this.element.appendChild(this.bar);

	//Timeline zone
	this.timeline = document.createElement("div");
	this.timeline.style.overflow = "auto";
	this.timeline.style.position = "absolute";
	this.timeline.style.top = "20px";
	this.timeline.style.width = "100%";
	this.element.appendChild(this.timeline);

	//Animation
	this.animationButton = new Button(this.bar);
	this.animationButton.position.set(0, 0);
	this.animationButton.size.set(100, 20);
	this.animationButton.setText("Create Animation")
	this.animationButton.updateInterface();
	this.animationButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				console.log(object.animations);
				alert("This object is already animated");
			}
			else
			{
				alert("Added animation array");
				object.animations = [];
			}

			self.obj = object;
		}
	});

	//Create clip
	this.clipButton = new Button(this.bar);
	this.clipButton.position.set(100, 0);
	this.clipButton.size.set(100, 20);
	this.clipButton.setText("Create Clip")
	this.clipButton.updateInterface();
	this.clipButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				//VectorKeyframeTrack
				//BooleanKeyframeTrack
				//ColorKeyframeTrack
				//NumberKeyframeTrack
				//QuaternionKeyframeTrack
				//StringKeyframeTrack

				var clip = new THREE.AnimationClip("Animation", 5, []);

				var position = new VectorKeyframeTrack(".position", [1, 2, 2.5, 3, 4.5], [0,0,0, 1,1,1, 2,1,2, 2,2,2, 0,0,0]);
				position.setInterpolation(THREE.InterpolateSmooth); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(position);

				var scale = new VectorKeyframeTrack(".scale", [0, 1, 2, 3], [1,1,1, 2,2,2, 0.5,0.5,0.5, 1,1,1]);
				scale.setInterpolation(THREE.InterpolateLinear); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(scale);

				object.animations.push(clip);

				alert("Added clip");
			}
		}
		else
		{
			alert("Object not found!");
		}
	});

	//Update
	this.updateButton = new Button(this.bar);
	this.updateButton.position.set(200, 0);
	this.updateButton.size.set(100, 20);
	this.updateButton.setText("Update")
	this.updateButton.updateInterface();
	this.updateButton.setCallback(function()
	{
		update();
	});

	this.play = new Button(this.bar);
	this.play.position.set(300, 0);
	this.play.size.set(100, 20);
	this.play.setText("Play")
	this.play.updateInterface();
	this.play.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];
			console.log(object);
			self.mixer = new THREE.AnimationMixer(object);

			for(var i = 0; i < object.animations.length; i++)
			{
				var action = self.mixer.clipAction(object.animations[i]);
				action.setLoop(THREE.LoopRepeat); //LoopOnce || LoopRepeat || LoopPingPong
				action.play();
			}

			var clock = new THREE.Clock();
			clock.start();

			var loop = function()
			{
				if(self.mixer !== null)
				{
					self.mixer.update(clock.getDelta());
					requestAnimationFrame(loop);
				}
			};
			loop();
		}
		else
		{
			alert("Object not found!");
		}
	});

	this.stop = new Button(this.bar);
	this.stop.position.set(400, 0);
	this.stop.size.set(100, 20);
	this.stop.setText("Stop")
	this.stop.updateInterface();
	this.stop.setCallback(function()
	{
		self.mixer.stopAllAction();
		self.mixer = null;
	});

	this.zoomSlider = new Slider(this.bar);
	this.zoomSlider.size.set(100, 20);
	this.zoomSlider.position.set(500, 0);
	this.zoomSlider.setStep(10);
	this.zoomSlider.setRange(50, 1000);
	this.zoomSlider.updateInterface();
	this.zoomSlider.setOnChange(function()
	{
		self.zoom = self.zoomSlider.getValue();
		update();
	});

	function update()
	{
		if(Editor.selectedObjects.length > 0 && Editor.selectedObjects[0].animations !== undefined)
		{
			self.clearTimeline();

			var object = Editor.selectedObjects[0];
			var animations = object.animations;

			for(var i = 0; i < animations.length; i++)
			{
				var tracks = animations[i].tracks;

				var animation = document.createElement("div");
				animation.style.width = (self.zoom * animations[i].duration) + "px";
				animation.style.height = (self.timelineHeight * tracks.length) + "px";
				self.timeline.appendChild(animation);

				for(var j = 0; j < tracks.length; j++)
				{
					var times = tracks[j].times;

					var track = document.createElement("div");
					track.style.height = self.timelineHeight + "px";
					track.style.width = (self.zoom * (times[times.length - 1] - times[0])) + "px";
					animation.appendChild(track);

					for(var k = 0; k < times.length - 1; k++)
					{
						var key = document.createElement("div");
						key.style.position = "absolute";
						key.style.backgroundColor = MathUtils.randomColor();
						key.style.height = self.timelineHeight + "px";
						key.style.left = (self.zoom * times[k]) + "px";
						key.style.width = (self.zoom * (times[k + 1] - times[k])) + "px";
						track.appendChild(key);
					}
				}
			}

			self.updateInterface();
		}
	};
}

AnimationTab.prototype = Object.create(TabElement.prototype);

//Clean timeline
AnimationTab.prototype.clearTimeline = function()
{
	this.element.removeChild(this.timeline);

	this.timeline = document.createElement("div");
	this.timeline.style.overflow = "auto";
	this.timeline.style.position = "absolute";
	this.timeline.style.top = "20px";
	this.timeline.style.width = "100%";
	this.element.appendChild(this.timeline);

	this.seek = document.createElement("div");
	this.seek.style.backgroundColor = "#FFFFFF";
	this.seek.style.zIndex = "100";
	this.seek.style.width = "3px";
	this.seek.style.height = "100%";
	this.seek.style.overflow = "hidden";
	this.seek.style.top = "0px";
	this.seek.style.left = "40px";
	this.seek.style.position = "absolute";
	this.seek.style.cursor = "e-resize";

	this.timeline.appendChild(this.seek);
};

//Update interface
AnimationTab.prototype.updateInterface = function()
{
	if(this.visible)
	{
		this.element.style.display = "block";
		this.element.style.top = this.position.y + "px";
		this.element.style.left = this.position.x + "px";
		this.element.style.width = this.size.x + "px";
		this.element.style.height = this.size.y + "px";

		this.timeline.style.height = (this.size.y - 20) + "px";
	}
	else
	{
		this.element.style.display = "none";
	}
};

<commit_msg>Seekbar update<commit_after>"use strict";

function AnimationTab(parent, closeable, container, index)
{
	TabElement.call(this, parent, closeable, container, index, "Animation", Editor.filePath + "icons/misc/animation.png");

	var self = this;

	this.obj = null;
	this.mixer = null;

	this.zoom = 50.0; //Pixels/sec
	this.timelineHeight = 20;

	//Bar
	this.bar = document.createElement("div");
	this.bar.style.backgroundColor = Editor.theme.barColor;
	this.bar.style.overflow = "visible";
	this.bar.style.position = "absolute";
	this.bar.style.width = "100%";
	this.bar.style.height = "20px";
	this.element.appendChild(this.bar);

	//Timeline
	this.createTimeline();

	//Animation
	this.animationButton = new Button(this.bar);
	this.animationButton.position.set(0, 0);
	this.animationButton.size.set(100, 20);
	this.animationButton.setText("Create Animation")
	this.animationButton.updateInterface();
	this.animationButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				console.log(object.animations);
				alert("This object is already animated");
			}
			else
			{
				alert("Added animation array");
				object.animations = [];
			}

			self.obj = object;
		}
	});

	//Create clip
	this.clipButton = new Button(this.bar);
	this.clipButton.position.set(100, 0);
	this.clipButton.size.set(100, 20);
	this.clipButton.setText("Create Clip")
	this.clipButton.updateInterface();
	this.clipButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				//VectorKeyframeTrack
				//BooleanKeyframeTrack
				//ColorKeyframeTrack
				//NumberKeyframeTrack
				//QuaternionKeyframeTrack
				//StringKeyframeTrack

				var clip = new THREE.AnimationClip("Animation", 5, []);

				var position = new VectorKeyframeTrack(".position", [1, 2, 2.5, 3, 4.5], [0,0,0, 1,1,1, 2,1,2, 2,2,2, 0,0,0]);
				position.setInterpolation(THREE.InterpolateSmooth); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(position);

				var scale = new VectorKeyframeTrack(".scale", [0, 1, 2, 3], [1,1,1, 2,2,2, 0.5,0.5,0.5, 1,1,1]);
				scale.setInterpolation(THREE.InterpolateLinear); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(scale);

				object.animations.push(clip);

				alert("Added clip");
			}
		}
		else
		{
			alert("Object not found!");
		}
	});

	//Update
	this.updateButton = new Button(this.bar);
	this.updateButton.position.set(200, 0);
	this.updateButton.size.set(100, 20);
	this.updateButton.setText("Update")
	this.updateButton.updateInterface();
	this.updateButton.setCallback(function()
	{
		update();
	});

	this.play = new Button(this.bar);
	this.play.position.set(300, 0);
	this.play.size.set(100, 20);
	this.play.setText("Play")
	this.play.updateInterface();
	this.play.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];
			console.log(object);
			self.mixer = new THREE.AnimationMixer(object);

			for(var i = 0; i < object.animations.length; i++)
			{
				var action = self.mixer.clipAction(object.animations[i]);
				action.setLoop(THREE.LoopRepeat); //LoopOnce || LoopRepeat || LoopPingPong
				action.play();
			}

			var clock = new THREE.Clock();
			clock.start();

			var loop = function()
			{
				if(self.mixer !== null)
				{
					self.mixer.update(clock.getDelta());
					requestAnimationFrame(loop);
				}
			};
			loop();
		}
		else
		{
			alert("Object not found!");
		}
	});

	this.stop = new Button(this.bar);
	this.stop.position.set(400, 0);
	this.stop.size.set(100, 20);
	this.stop.setText("Stop")
	this.stop.updateInterface();
	this.stop.setCallback(function()
	{
		self.mixer.stopAllAction();
		self.mixer = null;
	});

	this.zoomSlider = new Slider(this.bar);
	this.zoomSlider.size.set(100, 20);
	this.zoomSlider.position.set(500, 0);
	this.zoomSlider.setStep(10);
	this.zoomSlider.setRange(50, 1000);
	this.zoomSlider.updateInterface();
	this.zoomSlider.setOnChange(function()
	{
		self.zoom = self.zoomSlider.getValue();
		update();
	});

	function update()
	{
		if(Editor.selectedObjects.length > 0 && Editor.selectedObjects[0].animations !== undefined)
		{
			self.createTimeline();

			var object = Editor.selectedObjects[0];
			var animations = object.animations;

			for(var i = 0; i < animations.length; i++)
			{
				var tracks = animations[i].tracks;

				var animation = document.createElement("div");
				animation.style.width = (self.zoom * animations[i].duration) + "px";
				animation.style.height = (self.timelineHeight * tracks.length) + "px";
				self.animation.appendChild(animation);

				for(var j = 0; j < tracks.length; j++)
				{
					var times = tracks[j].times;

					var track = document.createElement("div");
					track.style.height = self.timelineHeight + "px";
					track.style.width = (self.zoom * (times[times.length - 1] - times[0])) + "px";
					animation.appendChild(track);

					for(var k = 0; k < times.length - 1; k++)
					{
						var key = document.createElement("div");
						key.style.position = "absolute";
						key.style.backgroundColor = MathUtils.randomColor();
						key.style.height = self.timelineHeight + "px";
						key.style.left = (self.zoom * times[k]) + "px";
						key.style.width = (self.zoom * (times[k + 1] - times[k])) + "px";
						track.appendChild(key);
					}
				}
			}

			self.updateInterface();
		}
	};
}

AnimationTab.prototype = Object.create(TabElement.prototype);

AnimationTab.prototype.update = function()
{
	if(this.mixer !== null)
	{
		this.seek.style.left = (this.mixer._actions[0].time * this.zoom) + "px";
	}
};

//Create timeline
AnimationTab.prototype.createTimeline = function()
{
	if(this.timeline !== undefined)
	{
		this.timeline.removeChild(this.animation);
	}
	else
	{
		this.timeline = document.createElement("div");
		this.timeline.style.overflow = "visible";
		this.timeline.style.position = "absolute";
		this.timeline.style.top = "20px";
		this.timeline.style.width = "100%";
		this.element.appendChild(this.timeline);

		this.seek = document.createElement("div");
		this.seek.style.backgroundColor = "#FFFFFF";
		this.seek.style.zIndex = "100";
		this.seek.style.width = "3px";
		this.seek.style.height = "100%";
		this.seek.style.overflow = "hidden";
		this.seek.style.top = "0px";
		this.seek.style.left = "0px";
		this.seek.style.position = "absolute";
		this.seek.style.cursor = "e-resize";
		this.timeline.appendChild(this.seek);
	}

	this.animation = document.createElement("div");
	this.animation.style.overflow = "auto";
	this.animation.style.position = "absolute";
	this.animation.style.height = "100%";
	this.animation.style.width = "100%";
	this.timeline.appendChild(this.animation);
};

//Update interface
AnimationTab.prototype.updateInterface = function()
{
	if(this.visible)
	{
		this.element.style.display = "block";
		this.element.style.top = this.position.y + "px";
		this.element.style.left = this.position.x + "px";
		this.element.style.width = this.size.x + "px";
		this.element.style.height = this.size.y + "px";

		this.timeline.style.height = (this.size.y - 20) + "px";
	}
	else
	{
		this.element.style.display = "none";
	}
};

<|endoftext|>


<commit_before>// @ngInject
export default class CostPlanningFormatter {
  constructor($filter) {
    this.$filter = $filter;
  }

  formatFlavor(flavor) {
    return `${flavor.name} (${this.$filter('formatFlavor')(flavor)})`;
  }

  formatPreset(preset) {
    return `${preset.category} / ${preset.variant}`;
  }

  formatPlan(item) {
    const price = this.$filter('defaultCurrency')(item.price);
    const preset = this.formatPreset(item.preset);
    const flavor = this.formatFlavor(item.size);
    return `${preset} — ${flavor} — ${price}`;
  }

  formatPresets(plan) {
    return plan.optimized_presets.map(this.formatPlan.bind(this)).join('
');
  }
}
<commit_msg>Render preset name [WAL-638]<commit_after>// @ngInject
export default class CostPlanningFormatter {
  constructor($filter) {
    this.$filter = $filter;
  }

  formatFlavor(flavor) {
    return `${flavor.name} (${this.$filter('formatFlavor')(flavor)})`;
  }

  formatPreset(preset) {
    return `${preset.category} / ${preset.variant} ${preset.name}`;
  }

  formatPlan(item) {
    const price = this.$filter('defaultCurrency')(item.price);
    const preset = this.formatPreset(item.preset);
    const flavor = this.formatFlavor(item.size);
    return `${preset} — ${flavor} — ${price}`;
  }

  formatPresets(plan) {
    return plan.optimized_presets.map(this.formatPlan.bind(this)).join('
');
  }
}
<|endoftext|>


<commit_before>// Vererbung wird ben�tigt
// Funktionen wie underscore implementieren? -> Modularity.isFunction(func(){})?

/**
 * @author Christoph Grundmann
 * @class ModularityCore
 */
var ModularityCore = (function () {
    var extensions = {};
    var core = {};

    /**
     * @callback extensionDefinition
     * @param {Extension} extension - The newly created instance of the extension
     * @param {string} extension.name - The name of the extension
     * @param {...Extension} imports - Each imported extension
     */

    /**
     * Registers a new framework extension
     * @param {string} name - The name of the new extension
     * @param {string} [inherits = Extension] - The name of the extension to inherit from
     * @param {string[]} [imports = []] - All names of extensions which should be imported
     * @param {extensionDefinition} extension - The definition of the extension
     */
    core.extend = function (name, inherits = "Extension", imports = [], extension = null) {
        if (!ModularityCore.utils.isFunction(extension)) {
            throw new Error("Extension with name <" + name + "> must be a function, but is of type <" + typeof extension + ">");
        } else if (ModularityCore.utils.isFunction(extensions[name])) {
            throw new Error("Extension with name <" + name + "> already exists. Please use another name or check whether this extension is already added.");
        } else {
            extensions[name] = extension;
        }
    };

    /**
     * Registers a new application module
     * @param name
     * @param inherits
     * @param requires
     * @param module
     */
    core.module = function (name, inherits, requires, module) {

    };

    function inherits(module, baseModule) {
    }

    return core;
})();

/**
 * Collection of utilities used for type checking
 * @namespace
 */
ModularityCore.utils = (function () {
    var utils = {};

    /**
     * Checks whether the given value is a function
     * @param {*} value - The value to test
     * @returns {boolean} Returns true if the given value is a function, otherwise it returns false
     */
    utils.isFunction = function (value) {
        return utils.isObject(value) && Object.prototype.toString.call(value) == '[object Function]';
    };

    utils.isString = function (value) {
        return typeof value == 'string' || (isObjectLike(value) && String.prototype.toString.call(value) == '[object String]');
    };

    utils.isObject = function (value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    };

    /**
     * Checks if `value` is object-like.
     *
     * @private
     * @param {*} value The value to check.
     * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
     */
    function isObjectLike(value) {
        return !!value && typeof value == 'object';
    }

    return utils;
})();

// 1. Module registrieren, unabh�ngig von Abh�ngigkeiten
// 2. Alle Module initialisieren, Abh�ngigkeiten vermeiden!
// 3. Nutzerdefinierte init() aufrufen

/**
 * @class Extension
 */
ModularityCore.extend("Extension", function (extention) {

    /**
     * Gets the name of the extension
     * @returns {string} The name of the extension
     */
    extention.getExtensionName = function () {
        return extention.name;
    };
});

ModularityCore.extend("Gallery", ["Navigator", ""], function (gallery, navigator) {

});<commit_msg>[updated] comments<commit_after>// Vererbung wird ben�tigt
// Funktionen wie underscore implementieren? -> Modularity.isFunction(func(){})?

/**
 * @author Christoph Grundmann
 * @namespace ModularityCore
 */
var ModularityCore = (function () {
    var extensions = {};
    var core = {};

    /**
     * @callback extensionDefinition
     * @param {Extension} extension - The newly created instance of the extension
     * @param {string} extension.name - The name of the extension
     * @param {...Extension} imports - Each imported extension
     */

    /**
     * Registers a new framework extension
     * @function extend
     * @param {string} name - The name of the new extension
     * @param {string} [inherits = Extension] - The name of the extension to inherit from
     * @param {string[]} [imports = []] - All names of extensions which should be imported
     * @param {extensionDefinition} extension - The definition of the extension
     */
    core.extend = function (name, inherits = "Extension", imports = [], extension = null) {
        if (!ModularityCore.type.isFunction(extension)) {
            throw new Error("Extension with name <" + name + "> must be a function, but is of type <" + typeof extension + ">");
        } else if (ModularityCore.type.isFunction(extensions[name])) {
            throw new Error("Extension with name <" + name + "> already exists. Please use another name or check whether this extension is already added.");
        } else {
            extensions[name] = extension;
        }
    };

    /**
     * Registers a new application module
     * @function module
     * @param name
     * @param inherits
     * @param requires
     * @param module
     */
    core.module = function (name, inherits, requires, module) {

    };

    function inherits(module, baseModule) {
    }

    return core;
})();

/**
 * Collection of utilities used for type checking
 * These utilities are inspired by lodash {@link https://lodash.com/}
 * @namespace
 */
ModularityCore.type = (function () {
    var utils = {};

    /**
     * Checks whether the given value is a function
     * @function isFunction
     * @param {*} value - The value to check
     * @returns {boolean} Returns true if the given value is a function, otherwise false
     */
    utils.isFunction = function (value) {
        return utils.isObject(value) && Object.prototype.toString.call(value) == '[object Function]';
    };

    /**
     * Checks whether the given value is a string
     * @function isString
     * @param {*} value - The value to check
     * @returns {boolean} Returns true if the given value is a string, otherwise false
     */
    utils.isString = function (value) {
        return typeof value == 'string' || (isObjectLike(value) && String.prototype.toString.call(value) == '[object String]');
    };

    /**
     * Checks whether the given value is an object
     * @function isObject
     * @param {*} value - The value to check
     * @returns {boolean} Returns true if the given value is an object, otherwise false
     */
    utils.isObject = function (value) {
        var type = typeof value;
        return !!value && (type == 'object' || type == 'function');
    };

    /**
     * Checks whether the given value is object-like
     * @function isObjectLike
     * @private
     * @param {*} value - The value to check
     * @returns {boolean} Returns true if the given value is object-like, otherwise false
     */
    function isObjectLike(value) {
        return !!value && typeof value == 'object';
    }

    return utils;
})();

// 1. Module registrieren, unabh�ngig von Abh�ngigkeiten
// 2. Alle Module initialisieren, Abh�ngigkeiten vermeiden!
// 3. Nutzerdefinierte init() aufrufen

/**
 * @class Extension
 */
ModularityCore.extend("Extension", function (extention) {

    /**
     * Gets the name of the extension
     * @returns {string} The name of the extension
     */
    extention.getExtensionName = function () {
        return extention.name;
    };
});

ModularityCore.extend("Gallery", ["Navigator", ""], function (gallery, navigator) {

});<|endoftext|>


<commit_before>webSocket = {
    name: "webSocketDataPanel",
    panelHTML: function(uniqueParentElementID) {
        var html = '';
        return html;
    },
    panelAdminHTML: function(uniqueParentElementID) {
        var loc = window.location;
        var url = '';
        if (loc.protocol === "https:"){
            url = 'wss://';
        } else if (loc.protocol === "file:"){
            url = 'ws://localhost:8888'
        } else {
            url = 'ws://';
        }
        url += loc.host + ':8888/ws';
        var html = '';
        html += '\
            <input type="text" class="wsurl" id="';
        html += uniqueParentElementID;
        html += '-wsurl" value="' + url + '"/>\
            <button class="button" type="button" onclick="webSocket.panelConnect(this)">\
                Connect\
            </button>\
        ';
        return html;
    },
    /*
    panelContextMenu: {
    },
    topMenuItems : {
    },
    */

    linkDataKeys: [
        'wsurl',
        'stringData',
        'binaryData',
        'jsonData'
    ],

    getPanelData: function(parentElement, key){
      if (key == 'wsurl'){
         var ta = $(parentElement).find('.wsurl');
         return ta.val();
      } else if (key == 'stringData') {
         var datakey = parentElement.find('.wsurl').attr('id')
         return divIDE.panelJSData[datakey].stringData;
      } else if (key == 'jsonData') {
         var datakey = parentElement.find('.wsurl').attr('id')
         return divIDE.panelJSData[datakey].jsonData;
      } else if (key == 'binaryData') {
         var datakey = parentElement.find('.wsurl').attr('id')
         return divIDE.panelJSData[datakey].binaryData;
      }
    },

    setPanelData: function(parentElement, data, key) {
      if (key == 'wsurl'){
         var ta = $(parentElement).find('.wsurl');
         ta.val(data);
         webSocket.panelConnect(parentElement);
      } else if (key == 'stringData') {
         var datakey = parentElement.find('.wsurl').attr('id');
         try {
            return divIDE.panelJSData[datakey].ws.send(data);
         } catch(e) {
            return '';
         }
      } else if (key == 'jsonData') {
         var datakey = parentElement.find('.wsurl').attr('id');
         try {
            return divIDE.panelJSData[datakey].ws.send(data);
         } catch(e) {
            return '';
         }
      } else if (key == 'binaryData') {
         var datakey = parentElement.find('.wsurl').attr('id');
         try {
            return divIDE.panelJSData[datakey].ws.send(data);
         } catch(e) {
             return '';
         }
      }

    },

    panelConnect: function(elem){
        var parentElement = divIDE.getCtxTarget(elem);
        var elem = $(parentElement).find('.wsurl');
        var datakey = elem.attr('id');
        var url = elem.val();
        divIDE.panelJSData[datakey] = {
            stringData: '',
            binaryData: '',
            ws: new WebSocket(url),
        }
        divIDE.panelJSData[datakey].ws.binaryType = 'arraybuffer';
        divIDE.panelJSData[datakey].ws.onmessage = function (e) {
            if (typeof e.data == 'string'){
                try {
                    divIDE.panelJSData[datakey].jsonData = JSON.parse(e.data);
                    divIDE.onLinkDataChange($(parentElement).parent('div'), 'jsonData');
                } catch(e) {
                    divIDE.panelJSData[datakey].stringData = e.data;
                    divIDE.onLinkDataChange($(parentElement).parent('div'), 'stringData');
                }
            } else {
                divIDE.panelJSData[datakey].binaryData = e.data;
                divIDE.onLinkDataChange($(parentElement).parent('div'), 'binaryData');
            }
        }
    }
}

divIDE.registerPanel(webSocket);<commit_msg>Adding AutoURL to websocket panel.<commit_after>webSocket = {
    name: "webSocketDataPanel",
    panelHTML: function(uniqueParentElementID) {
        var html = '';
        return html;
    },

    autoUrl: function(){
        var loc = window.location;
        var url = '';
        if (loc.protocol === "https:"){
            url = 'wss://';
        } else if (loc.protocol === "file:"){
            url = 'ws://localhost:8888'
        } else {
            url = 'ws://';
        }
        url += loc.host + '/ws';
        return url;
    },

    panelAdminHTML: function(uniqueParentElementID) {
        var html = '';
        html += '\
            <input type="text" class="wsurl" id="';
        html += uniqueParentElementID;
        html += '-wsurl" value="' + webSocket.autoUrl + '"/>\
            <button class="button" type="button" onclick="webSocket.panelConnect(this)">\
                Connect\
            </button>\
        ';
        return html;
    },
    /*
    panelContextMenu: {
    },
    topMenuItems : {
    },
    */

    linkDataKeys: [
        'wsurl',
        'stringData',
        'binaryData',
        'jsonData'
    ],

    getPanelData: function(parentElement, key){
      if (key == 'wsurl'){
         var ta = $(parentElement).find('.wsurl');
         return ta.val();
      } else if (key == 'stringData') {
         var datakey = parentElement.find('.wsurl').attr('id')
         return divIDE.panelJSData[datakey].stringData;
      } else if (key == 'jsonData') {
         var datakey = parentElement.find('.wsurl').attr('id')
         return divIDE.panelJSData[datakey].jsonData;
      } else if (key == 'binaryData') {
         var datakey = parentElement.find('.wsurl').attr('id')
         return divIDE.panelJSData[datakey].binaryData;
      }
    },

    setPanelData: function(parentElement, data, key) {
      if (key == 'wsurl'){
         if (data === 'auto'){
             data = webSocket.autoUrl();
         }
         var ta = $(parentElement).find('.wsurl');
         ta.val(data);
         webSocket.panelConnect(parentElement);
      } else if (key == 'stringData') {
         var datakey = parentElement.find('.wsurl').attr('id');
         try {
            return divIDE.panelJSData[datakey].ws.send(data);
         } catch(e) {
            return '';
         }
      } else if (key == 'jsonData') {
         var datakey = parentElement.find('.wsurl').attr('id');
         try {
            return divIDE.panelJSData[datakey].ws.send(data);
         } catch(e) {
            return '';
         }
      } else if (key == 'binaryData') {
         var datakey = parentElement.find('.wsurl').attr('id');
         try {
            return divIDE.panelJSData[datakey].ws.send(data);
         } catch(e) {
             return '';
         }
      }

    },

    panelConnect: function(elem){
        var parentElement = divIDE.getCtxTarget(elem);
        var elem = $(parentElement).find('.wsurl');
        var datakey = elem.attr('id');
        var url = elem.val();
        divIDE.panelJSData[datakey] = {
            stringData: '',
            binaryData: '',
            ws: new WebSocket(url),
        }
        divIDE.panelJSData[datakey].ws.binaryType = 'arraybuffer';
        divIDE.panelJSData[datakey].ws.onmessage = function (e) {
            if (typeof e.data == 'string'){
                try {
                    divIDE.panelJSData[datakey].jsonData = JSON.parse(e.data);
                    divIDE.onLinkDataChange($(parentElement).parent('div'), 'jsonData');
                } catch(e) {
                    divIDE.panelJSData[datakey].stringData = e.data;
                    divIDE.onLinkDataChange($(parentElement).parent('div'), 'stringData');
                }
            } else {
                divIDE.panelJSData[datakey].binaryData = e.data;
                divIDE.onLinkDataChange($(parentElement).parent('div'), 'binaryData');
            }
        }
    }
}

divIDE.registerPanel(webSocket);<|endoftext|>


<commit_before>"use strict";

function AnimationTab(parent, closeable, container, index)
{
	TabElement.call(this, parent, closeable, container, index, "Animation", Editor.filePath + "icons/misc/animation.png");

	var self = this;

 	this.obj = null;

 	//Scale in pixels per second
 	this.scale = 20.0;

 	//Playback
 	this.mixer = null;
 	this.time = 0.0;
 	this.playing = false;

	//Bar
	this.bar = document.createElement("div");
	this.bar.style.backgroundColor = Editor.theme.barColor;
	this.bar.style.overflow = "visible";
	this.bar.style.position = "absolute";
	this.bar.style.width = "100%";
	this.bar.style.height = "20px";
	this.element.appendChild(this.bar);

	//Timeline zone
	this.timeline = document.createElement("div");
	this.timeline.style.overflow = "auto";
	this.timeline.style.position = "absolute";
	this.timeline.style.top = "20px";
	this.timeline.style.width = "100%";
	this.element.appendChild(this.timeline);

	//Animation
	this.animationButton = new Button(this.bar);
	this.animationButton.position.set(0, 0);
	this.animationButton.size.set(100, 20);
	this.animationButton.setText("Read Animations")
	this.animationButton.updateInterface();
	this.animationButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				console.log(object.animations);
				alert("This object is already animated");
			}
			else
			{
				alert("Added animation array");
				object.animations = [];
			}

			self.obj = object;
		}
	});

	this.clipButton = new Button(this.bar);
	this.clipButton.position.set(100, 0);
	this.clipButton.size.set(100, 20);
	this.clipButton.setText("Create Clip")
	this.clipButton.updateInterface();
	this.clipButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				//VectorKeyframeTrack -> Vector3
				//BooleanKeyframeTrack
				//ColorKeyframeTrack
				//NumberKeyframeTrack
				//QuaternionKeyframeTrack
				//StringKeyframeTrack

				var clip = new THREE.AnimationClip("Animation", 3, []);

				var position = new VectorKeyframeTrack(".position", [0, 1, 2, 3], [0,0,0, 0,2,0, 2,1,2, 0,0,0]);
				position.setInterpolation(THREE.InterpolateSmooth); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(position);

				clip.tracks.push(new VectorKeyframeTrack(".rotation", [0, 1, 2], [0,0,0, 0,1.57,0, 0,0,0]));
				object.animations.push(clip);

				alert("Added clip");
			}
		}
	});

	//Update
	this.updateButton = new Button(this.bar);
	this.updateButton.position.set(200, 0);
	this.updateButton.size.set(100, 20);
	this.updateButton.setText("Update")
	this.updateButton.updateInterface();
	this.updateButton.setCallback(function()
	{
		if(self.obj !== null)
		{
			self.clearTimeline();

			var animations = self.obj.animations;

			for(var i = 0; i < animations.length; i++)
			{
				var container = document.createElement("div");
				container.style.backgroundColor = "#FF0000";
				self.timeline.appendChild(container);

				var tracks = animations[i].tracks;
				for(var j = 0; j < tracks.length; j++)
				{
					var key = document.createElement("div");
					key.style.backgroundColor = MathUtils.randomColor();
					key.style.height = "100%";
					key.style.width = (self.scale * animations[i].duration) + "px";
					container.appendChild(key);
				}
			}
		}
	});

	this.play = new Button(this.bar);
	this.play.position.set(300, 0);
	this.play.size.set(100, 20);
	this.play.setText("Play")
	this.play.updateInterface();
	this.play.setCallback(function()
	{
		self.mixer = new AnimationMixer(self.obj);

		var action = self.mixer.clipAction(self.obj.animations[0]);
		action.setLoop(THREE.LoopPingPong); //LoopOnce || LoopRepeat || LoopPingPong
		action.play();

		var clock = new THREE.Clock();
		clock.start();

		var loop = function()
		{
			if(self.playing)
			{
				self.mixer.update(clock.getDelta());
				requestAnimationFrame(loop);
			}
		};

		self.playing = true;
		loop();
	});

	this.stop = new Button(this.bar);
	this.stop.position.set(400, 0);
	this.stop.size.set(100, 20);
	this.stop.setText("Stop")
	this.stop.updateInterface();
	this.stop.setCallback(function()
	{
		self.mixer.time = 0;
		self.mixer.update(0);
		self.mixer.stopAllAction();

		self.playing = false;
	});

	/*var mixer, clock;

	function initialize()
	{
		var box = scene.getObjectByName("box");

		var position = new VectorKeyframeTrack(".position", [0, 1, 2], [0,0,0, 0,10,0, 0,0,0]);
		var color = new ColorKeyframeTrack(".material.color", [0, 1, 3], [1,0,0, 0,1,0, 0,0,1]);

		var clip = new AnimationClip("Animation", 3, [position, color]);

		mixer = new AnimationMixer(box);
		mixer.clipAction(clip).play();

		clock = new Clock();
		clock.start();
	}

	function update()
	{
		mixer.update(clock.getDelta());
	}*/
}

AnimationTab.prototype = Object.create(TabElement.prototype);

//Clean timeline
AnimationTab.prototype.clearTimeline = function()
{
	this.element.removeChild(this.timeline);

	this.timeline = document.createElement("div");
	this.timeline.style.overflow = "auto";
	this.timeline.style.position = "absolute";
	this.timeline.style.top = "20px";
	this.timeline.style.width = "100%";
	this.element.appendChild(this.timeline);
};

//Update interface
AnimationTab.prototype.updateInterface = function()
{
	if(this.visible)
	{
		this.element.style.display = "block";
		this.element.style.top = this.position.y + "px";
		this.element.style.left = this.position.x + "px";
		this.element.style.width = this.size.x + "px";
		this.element.style.height = this.size.y + "px";

		this.timeline.style.height = (this.size.y - 20) + "px";
	}
	else
	{
		this.element.style.display = "none";
	}
};

<commit_msg>Zoom<commit_after>"use strict";

function AnimationTab(parent, closeable, container, index)
{
	TabElement.call(this, parent, closeable, container, index, "Animation", Editor.filePath + "icons/misc/animation.png");

	var self = this;

	this.obj = null;
	this.mixer = null;

	this.zoom = 50.0; //Pixels/sec
	this.timelineHeight = 20;

	//Bar
	this.bar = document.createElement("div");
	this.bar.style.backgroundColor = Editor.theme.barColor;
	this.bar.style.overflow = "visible";
	this.bar.style.position = "absolute";
	this.bar.style.width = "100%";
	this.bar.style.height = "20px";
	this.element.appendChild(this.bar);

	//Timeline zone
	this.timeline = document.createElement("div");
	this.timeline.style.overflow = "auto";
	this.timeline.style.position = "absolute";
	this.timeline.style.top = "20px";
	this.timeline.style.width = "100%";
	this.element.appendChild(this.timeline);

	//Animation
	this.animationButton = new Button(this.bar);
	this.animationButton.position.set(0, 0);
	this.animationButton.size.set(100, 20);
	this.animationButton.setText("Read Animations")
	this.animationButton.updateInterface();
	this.animationButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				console.log(object.animations);
				alert("This object is already animated");
			}
			else
			{
				alert("Added animation array");
				object.animations = [];
			}

			self.obj = object;
		}
	});

	this.clipButton = new Button(this.bar);
	this.clipButton.position.set(100, 0);
	this.clipButton.size.set(100, 20);
	this.clipButton.setText("Create Clip")
	this.clipButton.updateInterface();
	this.clipButton.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];

			if(object.animations !== undefined)
			{
				//VectorKeyframeTrack
				//BooleanKeyframeTrack
				//ColorKeyframeTrack
				//NumberKeyframeTrack
				//QuaternionKeyframeTrack
				//StringKeyframeTrack

				var clip = new THREE.AnimationClip("Animation", 5, []);

				var position = new VectorKeyframeTrack(".position", [1, 2, 2.5, 3, 4.5], [0,0,0, 1,1,1, 2,1,2, 2,2,2, 0,0,0]);
				position.setInterpolation(THREE.InterpolateSmooth); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(position);

				var scale = new VectorKeyframeTrack(".scale", [0, 1, 2, 3], [1,1,1, 2,2,2, 0.5,0.5,0.5, 1,1,1]);
				scale.setInterpolation(THREE.InterpolateLinear); //InterpolateLinear || InterpolateSmooth || InterpolateDiscrete
				clip.tracks.push(scale);

				object.animations.push(clip);

				alert("Added clip");
			}
		}
		else
		{
			alert("Object not found!");
		}
	});

	//Update
	this.updateButton = new Button(this.bar);
	this.updateButton.position.set(200, 0);
	this.updateButton.size.set(100, 20);
	this.updateButton.setText("Update")
	this.updateButton.updateInterface();
	this.updateButton.setCallback(function()
	{
		update();
	});

	this.play = new Button(this.bar);
	this.play.position.set(300, 0);
	this.play.size.set(100, 20);
	this.play.setText("Play")
	this.play.updateInterface();
	this.play.setCallback(function()
	{
		if(Editor.selectedObjects.length > 0)
		{
			var object = Editor.selectedObjects[0];
			console.log(object);
			self.mixer = new THREE.AnimationMixer(object);

			for(var i = 0; i < object.animations.length; i++)
			{
				var action = self.mixer.clipAction(object.animations[i]);
				action.setLoop(THREE.LoopRepeat); //LoopOnce || LoopRepeat || LoopPingPong
				action.play();
			}

			var clock = new THREE.Clock();
			clock.start();

			var loop = function()
			{
				if(self.mixer !== null)
				{
					self.mixer.update(clock.getDelta());
					requestAnimationFrame(loop);
				}
			};
			loop();
		}
		else
		{
			alert("Object not found!");
		}
	});

	this.stop = new Button(this.bar);
	this.stop.position.set(400, 0);
	this.stop.size.set(100, 20);
	this.stop.setText("Stop")
	this.stop.updateInterface();
	this.stop.setCallback(function()
	{
		self.mixer.stopAllAction();
		self.mixer = null;
	});

	this.zoomSlider = new Slider(this.bar);
	this.zoomSlider.size.set(100, 20);
	this.zoomSlider.position.set(500, 0);
	this.zoomSlider.setStep(10);
	this.zoomSlider.setRange(50, 1000);
	this.zoomSlider.updateInterface();
	this.zoomSlider.setOnChange(function()
	{
		self.zoom = self.zoomSlider.getValue();
		update();
	});

	function update()
	{
		if(Editor.selectedObjects.length > 0 && Editor.selectedObjects[0].animations !== undefined)
		{
			self.clearTimeline();

			var object = Editor.selectedObjects[0];
			var animations = object.animations;

			for(var i = 0; i < animations.length; i++)
			{
				var tracks = animations[i].tracks;

				var animation = document.createElement("div");
				animation.style.width = (self.zoom * animations[i].duration) + "px";
				animation.style.height = (self.timelineHeight * tracks.length) + "px";
				self.timeline.appendChild(animation);

				for(var j = 0; j < tracks.length; j++)
				{
					var times = tracks[j].times;

					var track = document.createElement("div");
					track.style.height = self.timelineHeight + "px";
					track.style.width = (self.zoom * (times[times.length - 1] - times[0])) + "px";
					animation.appendChild(track);

					for(var k = 0; k < times.length - 1; k++)
					{
						var key = document.createElement("div");
						key.style.position = "absolute";
						key.style.backgroundColor = MathUtils.randomColor();
						key.style.height = self.timelineHeight + "px";
						key.style.left = (self.zoom * times[k]) + "px";
						key.style.width = (self.zoom * (times[k + 1] - times[k])) + "px";
						track.appendChild(key);
					}
				}
			}

			self.updateInterface();
		}
	};
}

AnimationTab.prototype = Object.create(TabElement.prototype);

//Clean timeline
AnimationTab.prototype.clearTimeline = function()
{
	this.element.removeChild(this.timeline);

	this.timeline = document.createElement("div");
	this.timeline.style.overflow = "auto";
	this.timeline.style.position = "absolute";
	this.timeline.style.top = "20px";
	this.timeline.style.width = "100%";
	this.element.appendChild(this.timeline);
};

//Update interface
AnimationTab.prototype.updateInterface = function()
{
	if(this.visible)
	{
		this.element.style.display = "block";
		this.element.style.top = this.position.y + "px";
		this.element.style.left = this.position.x + "px";
		this.element.style.width = this.size.x + "px";
		this.element.style.height = this.size.y + "px";

		this.timeline.style.height = (this.size.y - 20) + "px";
	}
	else
	{
		this.element.style.display = "none";
	}
};

<|endoftext|>


<commit_before>(function(Queue, QueueEntry) {
  'use strict';

  function QueueManagerFactory($q, YoutubeClient, LoggerFactory) {
    var logger = LoggerFactory.logger('QueueManager');

    function serialize(queue) {
      var buffer = [];

      buffer.push((queue.name || ''));
      queue.entries.forEach(function(queueEntry) {
        buffer.push(YoutubeClient.shortName + queueEntry.video.id);
      });

      var jsonString = JSON.stringify(buffer);
      // remove useless array delimiters because we are actually not using it as an array
      return jsonString.substr(1, jsonString.length - 2);
    }

    function deserialize(input) {
      // add removed array delimiters
      var buffer;
      try {
        buffer = JSON.parse('[' + input + ']');
      } catch (e) {
        logger.debug('Unable to parse a serialized queue because of an exception %s', e);
        return $q.reject('Sorry we are unable to load your queue. Seems that the link you used is not valid.');
      }

      var queue = new Queue();
      // the first bucket is the name of the queue
      queue.name = buffer[0];

      var youtubeVideosIds = [];
      for (var idx = 1; idx < buffer.length; idx++) {
        var serializedEntry = buffer[idx];
        if (serializedEntry.indexOf(YoutubeClient.shortName) === 0) {
          youtubeVideosIds.push(serializedEntry.substring(YoutubeClient.shortName.length));
        } else {
          logger.debug('Unable to find a provider for serialized entry %s', serializedEntry);
          return $q.reject('Sorry we are unable to load your queue because of an internal error.');
        }
      }

      return YoutubeClient.listVideosByIds(youtubeVideosIds).then(function(videos) {
        videos.forEach(function(video) {
          var queueEntry = new QueueEntry();
          queueEntry.id = _.uniqueId();
          queueEntry.video = video;
          queue.entries.push(queueEntry);
        });

        return queue;
      }, function() {
        return $q.reject('Sorry we are unable to load videos from YouTube while loading your queue. May be you should try later.');
      });
    }

    // initialize queue
    var queue = new Queue();

    /**
     * @name QueueManager
     */
    var QueueManager = {
      /**
       * @returns {mt.model.Queue}
       */
      get queue() {
        return queue;
      },

      /**
       * Adds a video at the end of the queue.
       *
       * @param {mt.model.Video} video
       * @return {mt.model.QueueEntry} the newly created entry in the queue
       */
      appendVideo: function(video) {
        var queueEntry = new QueueEntry();
        queueEntry.id = _.uniqueId();
        queueEntry.video = video;
        queue.entries.push(queueEntry);
        return queueEntry;
      },

      /**
       * Removes an entry from the queue.
       *
       * @param {mt.model.QueueEntry} entry
       */
      removeEntry: function(entry) {
        var position = queue.entries.indexOf(entry);
        if (position === -1) {
          throw new Error('The given entry is not in the queue array');
        }
        queue.entries.splice(position, 1);
      },

      /**
       * Restores the queue in a pristine state.
       */
      clear: function() {
        queue.entries = [];
      },

      /**
       * Returns the closest valid (not skipped yet) entry in the queue from the given entry index included.
       *
       * @param {number} fromIndex the index in the queue to start to search from
       * @return {mt.model.QueueEntry} the next entry or null if none
       */
      closestValidEntryByIndex: function(fromIndex) {
        var validEntry = null;

        if (fromIndex !== -1) {
          while (!validEntry && fromIndex < queue.entries.length) {
            var entry = queue.entries[fromIndex];
            if (entry.skippedAtRuntime) {
              fromIndex++;
            } else {
              validEntry = entry;
            }
          }
        }

        return validEntry;
      },

      /**
       * Deserialize the queue from the given string, load the entry details from remote providers and "extends"
       * the queue with the new entries.
       *
       * @param {string} serialized
       * @return {promise}
       */
      deserialize: function(serialized) {
        return deserialize(serialized).then(function(newQueue) {
          // remove invalid entries
          newQueue.entries = newQueue.entries.filter(function(entry) {
            return entry.video.hasOwnProperty('publisherName');
          });
          // replacing the queue object prevents the Angular digest / watch mechanism to work
          // by extending the object it allows it to detect the changes
          angular.extend(queue, newQueue);
        });
      },

      /**
       * Serialize the queue.
       *
       * @returns {string} the serialized version of the queue
       */
      serialize: function() {
        return serialize(queue);
      }
    };

    return QueueManager;
  }

  angular.module('Mixtube').factory('QueueManager', QueueManagerFactory);

})(mt.model.Queue, mt.model.QueueEntry);<commit_msg>#91 Clean JS code: - cleaned queue manager<commit_after>(function(Queue, QueueEntry) {
  'use strict';

  function QueueManagerFactory($q, YoutubeClient, LoggerFactory) {

    var logger = LoggerFactory.logger('QueueManager');

    // initialize queue
    var queue = new Queue();

    function serialize() {
      var buffer = [];

      buffer.push(queue.name || '');
      queue.entries.forEach(function(queueEntry) {
        buffer.push(YoutubeClient.shortName + queueEntry.video.id);
      });

      var jsonString = JSON.stringify(buffer);
      // remove useless array delimiters because we are actually not using it as an array
      return jsonString.substr(1, jsonString.length - 2);
    }

    function deserialize(input) {
      // add removed array delimiters
      try {
        var buffer = JSON.parse('[' + input + ']');
      } catch (e) {
        logger.debug('Unable to parse a serialized queue because of an exception %s', e);
        return $q.reject('Sorry we are unable to load your queue. Seems that the link you used is not valid.');
      }

      var newQueue = new Queue();
      // the first bucket is the name of the queue
      newQueue.name = buffer[0];

      var youtubeVideosIds = [];
      for (var idx = 1; idx < buffer.length; idx++) {
        var serializedEntry = buffer[idx];
        if (serializedEntry.indexOf(YoutubeClient.shortName) === 0) {
          youtubeVideosIds.push(serializedEntry.substring(YoutubeClient.shortName.length));
        } else {
          logger.debug('Unable to find a provider for serialized entry %s', serializedEntry);
          return $q.reject('Sorry we are unable to load your queue because of an internal error.');
        }
      }

      return YoutubeClient.listVideosByIds(youtubeVideosIds)
        .then(function(videos) {
          videos.forEach(function(video) {
            var queueEntry = new QueueEntry();
            queueEntry.id = _.uniqueId();
            queueEntry.video = video;
            newQueue.entries.push(queueEntry);
          });

          // remove invalid entries
          newQueue.entries = newQueue.entries.filter(function(entry) {
            return _.has(entry.video, 'publisherName');
          });

          // replacing the queue object prevents the Angular digest / watch mechanism to work
          // by extending the object it allows it to detect the changes
          angular.extend(queue, newQueue);
        })
        .catch(function() {
          return $q.reject('Sorry we are unable to load videos from YouTube while loading your queue. ' +
          'May be you should try later.');
        });
    }

    function appendVideo(video) {
      var queueEntry = new QueueEntry();
      queueEntry.id = _.uniqueId();
      queueEntry.video = video;
      queue.entries.push(queueEntry);
      return queueEntry;
    }

    function removeEntry(entry) {
      var position = queue.entries.indexOf(entry);
      if (position === -1) {
        throw new Error('The given entry is not in the queue array');
      }
      queue.entries.splice(position, 1);
    }

    function closestValidEntryByIndex(fromIndex) {
      var validEntry = null;

      if (fromIndex !== -1) {
        while (!validEntry && fromIndex < queue.entries.length) {
          var entry = queue.entries[fromIndex];
          if (entry.skippedAtRuntime) {
            fromIndex++;
          } else {
            validEntry = entry;
          }
        }
      }

      return validEntry;
    }

    /**
     * @name QueueManager
     */
    var QueueManager = {
      /**
       * @returns {mt.model.Queue}
       */
      get queue() {
        return queue;
      },

      /**
       * Adds a video at the end of the queue.
       *
       * @param {mt.model.Video} video
       * @return {mt.model.QueueEntry} the newly created entry in the queue
       */
      appendVideo: appendVideo,

      /**
       * Removes an entry from the queue.
       *
       * @param {mt.model.QueueEntry} entry
       */
      removeEntry: removeEntry,

      /**
       * Returns the closest valid (not skipped yet) entry in the queue from the given entry index included.
       *
       * @param {number} fromIndex the index in the queue to start to search from
       * @return {mt.model.QueueEntry} the next entry or null if none
       */
      closestValidEntryByIndex: closestValidEntryByIndex,

      /**
       * Deserialize the queue from the given string, load the entry details from remote providers and "extends"
       * the queue with the new entries.
       *
       * @param {string} serialized
       * @return {promise}
       */
      deserialize: deserialize,

      /**
       * Serialize the queue.
       *
       * @returns {string} the serialized version of the queue
       */
      serialize: serialize
    };

    return QueueManager;
  }

  angular.module('Mixtube').factory('QueueManager', QueueManagerFactory);

})(mt.model.Queue, mt.model.QueueEntry);<|endoftext|>


<commit_before>const log = require('ringo/logging').getLogger(module.id);
const {XmlConfiguration} = org.eclipse.jetty.xml;
const {Server, HttpConfiguration, HttpConnectionFactory,
        ServerConnector, SslConnectionFactory,
        SecureRequestCustomizer, ServerConnectionStatistics} = org.eclipse.jetty.server;
const {HandlerCollection, ContextHandlerCollection} = org.eclipse.jetty.server.handler;
const {ConnectionStatistics} = org.eclipse.jetty.io;
const {HTTP_1_1} = org.eclipse.jetty.http.HttpVersion;
const {DefaultSessionIdManager} = org.eclipse.jetty.server.session;
const {SslContextFactory} = org.eclipse.jetty.util.ssl;

const objects = require("ringo/utils/objects");
const ApplicationContext = require("./context/application");
const StaticContext = require("./context/static");
const fs = require("fs");

const HttpServer = module.exports = function HttpServer(options) {
    if (!(this instanceof HttpServer)) {
        return new HttpServer(options);
    }

    const jetty = new Server();

    let xmlConfig = null;

    Object.defineProperties(this, {
        "jetty": {
            "value": jetty,
            "enumerable": true
        },
        "xmlConfig": {
            "get": function() {
                return xmlConfig;
            },
            "set": function(config) {
                if (!(config instanceof XmlConfiguration)) {
                    throw new Error("Invalid jetty xml configuration");
                }
                xmlConfig = config;
                xmlConfig.configure(jetty);
            },
            "enumerable": true
        },
        "contexts": {
            "value": {},
            "enumerable": true
        }
    });

    if (typeof(options) === "string") {
        // path to jetty xml configuration
        this.configure(options);
    } else if (typeof(options) === "object" && options.constructor === Object) {
        jetty.setStopAtShutdown(options.stopAtShutdown !== false);
        jetty.setStopTimeout(options.stopTimeout || 1000);
        jetty.setDumpAfterStart(options.dumpBeforeStart === true);
        jetty.setDumpBeforeStop(options.dumpBeforeStop === true);
    }
    return this;
};

HttpServer.prototype.toString = function() {
    return "[HttpServer]";
};

HttpServer.prototype.configure = function(xmlPath) {
    const xmlResource = getResource(xmlPath);
    if (!xmlResource.exists()) {
        throw Error('Jetty XML configuration "' + xmlResource + '" not found');
    }
    return this.xmlConfig = new XmlConfiguration(xmlResource.inputStream);
};

HttpServer.prototype.createHttpConfig = function(options) {
    options = objects.merge(options || {}, {
        "requestHeaderSize": 8129,
        "outputBufferSize": 32768,
        "responseHeaderSize": 8129,
        "secureScheme": "https"
    });
    const httpConfig = new HttpConfiguration();
    httpConfig.setRequestHeaderSize(options.requestHeaderSize);
    httpConfig.setOutputBufferSize(options.outputBufferSize);
    httpConfig.setResponseHeaderSize(options.responseHeaderSize);
    httpConfig.setSecureScheme(options.secureScheme);
    httpConfig.setSendServerVersion(options.sendServerVersion === true);
    httpConfig.setSendDateHeader(options.sendDateHeader !== false);
    return httpConfig;
};

HttpServer.prototype.createConnector = function(connectionFactory, options) {
    const connector = new ServerConnector(this.jetty, options.acceptors || -1,
            options.selectors || -1, connectionFactory);
    connector.setHost(options.host);
    connector.setPort(options.port);
    connector.setIdleTimeout(options.idleTimeout || 30000);
    connector.setSoLingerTime(options.soLingerTime || -1);
    connector.setAcceptorPriorityDelta(options.acceptorPriorityDelta || 0);
    connector.setAcceptQueueSize(options.acceptQueueSize || 0);
    if (typeof(options.name) === "string") {
        connector.setName(options.name);
    }
    return connector;
};

HttpServer.prototype.createHttpConnector = function(options) {
    options = objects.merge(options || {}, {
        "host": "0.0.0.0",
        "port": 8080
    });
    const httpConfig = this.createHttpConfig(options);
    const connectionFactory = new HttpConnectionFactory(httpConfig);
    return this.createConnector(connectionFactory, options);
};

HttpServer.prototype.createSslContextFactory = function(options) {
    options = objects.merge(options || {}, {
        "includeCipherSuites": [],
        "excludeCipherSuites": [
            "SSL_RSA_WITH_DES_CBC_SHA",
            "SSL_DHE_RSA_WITH_DES_CBC_SHA", "SSL_DHE_DSS_WITH_DES_CBC_SHA",
            "SSL_RSA_EXPORT_WITH_RC4_40_MD5",
            "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
            "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
            "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"
        ],
        "includeProtocols": ["TLSv1", "TLSv1.1", "TLSv1.2"],
        "excludeProtocols": ["SSLv3", "SSLv2Hello"]
    });
    const sslContextFactory = new SslContextFactory();
    sslContextFactory.setKeyStorePath(options.keyStore);
    sslContextFactory.setKeyStoreType(options.keyStoreType || "JKS");
    sslContextFactory.setKeyStorePassword(options.keyStorePassword);
    sslContextFactory.setKeyManagerPassword(options.keyManagerPassword);
    sslContextFactory.setTrustStorePath(options.trustStore || options.keyStore);
    sslContextFactory.setTrustStorePassword(options.trustStorePassword ||
            options.keyStorePassword);
    sslContextFactory.setIncludeCipherSuites(options.includeCipherSuites);
    sslContextFactory.setExcludeCipherSuites(options.excludeCipherSuites);
    sslContextFactory.setIncludeProtocols(options.includeProtocols);
    sslContextFactory.setExcludeProtocols(options.excludeProtocols);
    return sslContextFactory;
};

HttpServer.prototype.createHttpsConnector = function(options) {
    options = objects.merge(options || {}, {
        "host": "0.0.0.0",
        "port": 8443,
        "sniHostCheck": true,
        "stsMaxAgeSeconds": -1,
        "stsIncludeSubdomains": false
    });
    const sslContextFactory = this.createSslContextFactory(options);
    const sslConnectionFactory = new SslConnectionFactory(sslContextFactory,
            HTTP_1_1.toString());
    const httpsConfig = this.createHttpConfig(options);
    const customizer = new SecureRequestCustomizer();
    customizer.setSniHostCheck(options.sniHostCheck === true);
    if (!isNaN(options.stsMaxAgeSeconds)) {
        customizer.setStsMaxAge(options.stsMaxAgeSeconds);
    }
    customizer.setStsIncludeSubDomains(options.stsIncludeSubdomains === true);
    httpsConfig.addCustomizer(customizer);
    const httpConnectionFactory = new HttpConnectionFactory(httpsConfig);
    return this.createConnector([sslConnectionFactory, httpConnectionFactory], options);
};

HttpServer.prototype.createHttpListener = function(options) {
    const connector = this.createHttpConnector(options);
    this.jetty.addConnector(connector);
    return connector;
};

HttpServer.prototype.createHttpsListener = function(options) {
    const connector = this.createHttpsConnector(options);
    this.jetty.addConnector(connector);
    return connector;
};

HttpServer.prototype.getHandlerCollection = function() {
    let handlerCollection = this.jetty.getHandler();
    if (handlerCollection === null) {
        handlerCollection = new HandlerCollection();
        this.jetty.setHandler(handlerCollection);
    }
    return handlerCollection;
};

HttpServer.prototype.getContextHandlerCollection = function() {
    const handlerCollection = this.getHandlerCollection();
    let contextHandlerCollection =
            handlerCollection.getChildHandlerByClass(ContextHandlerCollection);
    if (contextHandlerCollection === null) {
        contextHandlerCollection = new ContextHandlerCollection();
        handlerCollection.addHandler(contextHandlerCollection);
    }
    return contextHandlerCollection;
};

HttpServer.prototype.addContext = function(context) {
    this.contexts[context.getKey()] = context;
    if (this.jetty.isRunning()) {
        context.contextHandler.start();
    }
    return context;
};

HttpServer.prototype.enableSessions = function(options) {
    options || (options = {});

    // if random is null, jetty will fall back to a SecureRandom in its initRandom()
    const sessionIdManager = new DefaultSessionIdManager(this.jetty, options.random || null);
    sessionIdManager.setWorkerName(options.name || "node1");
    this.jetty.setSessionIdManager(sessionIdManager);
    return sessionIdManager;
};

HttpServer.prototype.serveApplication = function(mountpoint, app, options) {
    if (typeof(mountpoint) !== "string") {
        throw new Error("Missing mountpoint argument");
    }
    options || (options = {});
    options = {
        "security": options.security !== false,
        "sessions": options.sessions !== false,
        "sessionsMaxInactiveInterval": options.sessionsMaxInactiveInterval || null,
        "cookieName": options.cookieName || null,
        "cookieDomain": options.cookieDomain || null,
        "cookiePath": options.cookiePath || null,
        "cookieMaxAge": options.cookieMaxAge || -1,
        "httpOnlyCookies": options.httpOnlyCookies !== false,
        "secureCookies": options.secureCookies === true,
        "statistics": options.statistics === true,
        "virtualHosts": options.virtualHosts
    };
    const parentContainer = this.getContextHandlerCollection();
    const context = new ApplicationContext(parentContainer, mountpoint, options);
    context.serve(app);
    return this.addContext(context);
};

HttpServer.prototype.serveStatic = function(mountpoint, directory, options) {
    if (typeof(mountpoint) !== "string") {
        throw new Error("Missing mountpoint argument");
    }
    if (typeof(directory) !== "string") {
        throw new Error("Missing directory argument");
    } else if (!fs.exists(directory) || !fs.isDirectory(directory)) {
        throw new Error("Directory '" + directory + "' doesn't exist or is not a directory");
    }
    options || (options = {});
    const initParameters = {
        "acceptRanges": options.acceptRanges === true,
        "dirAllowed": options.allowDirectoryListing === true,
        "gzip": options.gzip === true,
        "stylesheet": options.stylesheet || null,
        "etags": options.etags !== false,
        "maxCacheSize": options.maxCacheSize || 0,
        "maxCachedFileSize": options.maxCachedFileSize || 0,
        "maxCachedFiles": options.maxCachedFiles || 0,
        "cacheControl": options.cacheControl || null,
        "otherGzipFileExtensions": options.gzipExtensions || null
    };
    const parentContainer = this.getContextHandlerCollection();
    const context = new StaticContext(parentContainer, mountpoint, {
            "security": options.security === true,
            "sessions": options.sessions === true,
            "virtualHosts": options.virtualHosts
        });
    context.serve(directory, initParameters);
    return this.addContext(context);
};

HttpServer.prototype.enableConnectionStatistics = function() {
    ServerConnectionStatistics.addToAllConnectors(this.jetty);
};

HttpServer.prototype.getConnectionStatistics = function() {
    let connectors = this.jetty.getConnectors();
    return connectors.map(function(connector) {
        return {
            "name": connector.getName(),
            "host": connector.getHost(),
            "port": connector.getPort(),
            "statistics": connector.getBean(ConnectionStatistics)
        }
    });
};

HttpServer.prototype.start = function() {
    this.jetty.start();
    for each (let connector in this.jetty.getConnectors()) {
        log.info("Server on {}:{} started", connector.getHost(), connector.getPort());
    }
};

HttpServer.prototype.stop = function() {
    return this.jetty.stop();
};

HttpServer.prototype.destroy = function() {
    return this.jetty.destroy();
};

HttpServer.prototype.isRunning = function() {
    return this.jetty.isRunning();
};<commit_msg>hardened default ssl configuration<commit_after>const log = require('ringo/logging').getLogger(module.id);
const {XmlConfiguration} = org.eclipse.jetty.xml;
const {Server, HttpConfiguration, HttpConnectionFactory,
        ServerConnector, SslConnectionFactory,
        SecureRequestCustomizer, ServerConnectionStatistics} = org.eclipse.jetty.server;
const {HandlerCollection, ContextHandlerCollection} = org.eclipse.jetty.server.handler;
const {ConnectionStatistics} = org.eclipse.jetty.io;
const {HTTP_1_1} = org.eclipse.jetty.http.HttpVersion;
const {DefaultSessionIdManager} = org.eclipse.jetty.server.session;
const {SslContextFactory} = org.eclipse.jetty.util.ssl;

const objects = require("ringo/utils/objects");
const ApplicationContext = require("./context/application");
const StaticContext = require("./context/static");
const fs = require("fs");

const HttpServer = module.exports = function HttpServer(options) {
    if (!(this instanceof HttpServer)) {
        return new HttpServer(options);
    }

    const jetty = new Server();

    let xmlConfig = null;

    Object.defineProperties(this, {
        "jetty": {
            "value": jetty,
            "enumerable": true
        },
        "xmlConfig": {
            "get": function() {
                return xmlConfig;
            },
            "set": function(config) {
                if (!(config instanceof XmlConfiguration)) {
                    throw new Error("Invalid jetty xml configuration");
                }
                xmlConfig = config;
                xmlConfig.configure(jetty);
            },
            "enumerable": true
        },
        "contexts": {
            "value": {},
            "enumerable": true
        }
    });

    if (typeof(options) === "string") {
        // path to jetty xml configuration
        this.configure(options);
    } else if (typeof(options) === "object" && options.constructor === Object) {
        jetty.setStopAtShutdown(options.stopAtShutdown !== false);
        jetty.setStopTimeout(options.stopTimeout || 1000);
        jetty.setDumpAfterStart(options.dumpBeforeStart === true);
        jetty.setDumpBeforeStop(options.dumpBeforeStop === true);
    }
    return this;
};

HttpServer.prototype.toString = function() {
    return "[HttpServer]";
};

HttpServer.prototype.configure = function(xmlPath) {
    const xmlResource = getResource(xmlPath);
    if (!xmlResource.exists()) {
        throw Error('Jetty XML configuration "' + xmlResource + '" not found');
    }
    return this.xmlConfig = new XmlConfiguration(xmlResource.inputStream);
};

HttpServer.prototype.createHttpConfig = function(options) {
    options = objects.merge(options || {}, {
        "requestHeaderSize": 8129,
        "outputBufferSize": 32768,
        "responseHeaderSize": 8129,
        "secureScheme": "https"
    });
    const httpConfig = new HttpConfiguration();
    httpConfig.setRequestHeaderSize(options.requestHeaderSize);
    httpConfig.setOutputBufferSize(options.outputBufferSize);
    httpConfig.setResponseHeaderSize(options.responseHeaderSize);
    httpConfig.setSecureScheme(options.secureScheme);
    httpConfig.setSendServerVersion(options.sendServerVersion === true);
    httpConfig.setSendDateHeader(options.sendDateHeader !== false);
    return httpConfig;
};

HttpServer.prototype.createConnector = function(connectionFactory, options) {
    const connector = new ServerConnector(this.jetty, options.acceptors || -1,
            options.selectors || -1, connectionFactory);
    connector.setHost(options.host);
    connector.setPort(options.port);
    connector.setIdleTimeout(options.idleTimeout || 30000);
    connector.setSoLingerTime(options.soLingerTime || -1);
    connector.setAcceptorPriorityDelta(options.acceptorPriorityDelta || 0);
    connector.setAcceptQueueSize(options.acceptQueueSize || 0);
    if (typeof(options.name) === "string") {
        connector.setName(options.name);
    }
    return connector;
};

HttpServer.prototype.createHttpConnector = function(options) {
    options = objects.merge(options || {}, {
        "host": "0.0.0.0",
        "port": 8080
    });
    const httpConfig = this.createHttpConfig(options);
    const connectionFactory = new HttpConnectionFactory(httpConfig);
    return this.createConnector(connectionFactory, options);
};

HttpServer.prototype.createSslContextFactory = function(options) {
    options = objects.merge(options || {}, {
        "verbose": false,
        "includeCipherSuites": [],
        "excludeCipherSuites": [
            "^SSL_.*",
            "^TLS_DHE_.*",
            "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA",
            "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"
        ],
        "includeProtocols": ["TLSv1.2"]
    });
    const sslContextFactory = new SslContextFactory();
    sslContextFactory.setKeyStorePath(options.keyStore);
    sslContextFactory.setKeyStoreType(options.keyStoreType || "JKS");
    sslContextFactory.setKeyStorePassword(options.keyStorePassword);
    sslContextFactory.setKeyManagerPassword(options.keyManagerPassword);
    sslContextFactory.setTrustStorePath(options.trustStore || options.keyStore);
    sslContextFactory.setTrustStorePassword(options.trustStorePassword ||
            options.keyStorePassword);
    sslContextFactory.setIncludeCipherSuites(options.includeCipherSuites);
    sslContextFactory.setExcludeCipherSuites(options.excludeCipherSuites);
    sslContextFactory.setIncludeProtocols(options.includeProtocols);
    sslContextFactory.setExcludeProtocols(options.excludeProtocols);
    sslContextFactory.setRenegotiationAllowed(options.allowRenegotiation === true);
    if (options.verbose === true) {
        log.info(sslContextFactory.dump());
    }
    return sslContextFactory;
};

HttpServer.prototype.createHttpsConnector = function(options) {
    options = objects.merge(options || {}, {
        "host": "0.0.0.0",
        "port": 8443,
        "sniHostCheck": true,
        "stsMaxAgeSeconds": -1,
        "stsIncludeSubdomains": false
    });
    const sslContextFactory = this.createSslContextFactory(options);
    const sslConnectionFactory = new SslConnectionFactory(sslContextFactory,
            HTTP_1_1.toString());
    const httpsConfig = this.createHttpConfig(options);
    const customizer = new SecureRequestCustomizer();
    customizer.setSniHostCheck(options.sniHostCheck === true);
    if (!isNaN(options.stsMaxAgeSeconds)) {
        customizer.setStsMaxAge(options.stsMaxAgeSeconds);
    }
    customizer.setStsIncludeSubDomains(options.stsIncludeSubdomains === true);
    httpsConfig.addCustomizer(customizer);
    const httpConnectionFactory = new HttpConnectionFactory(httpsConfig);
    return this.createConnector([sslConnectionFactory, httpConnectionFactory], options);
};

HttpServer.prototype.createHttpListener = function(options) {
    const connector = this.createHttpConnector(options);
    this.jetty.addConnector(connector);
    return connector;
};

HttpServer.prototype.createHttpsListener = function(options) {
    const connector = this.createHttpsConnector(options);
    this.jetty.addConnector(connector);
    return connector;
};

HttpServer.prototype.getHandlerCollection = function() {
    let handlerCollection = this.jetty.getHandler();
    if (handlerCollection === null) {
        handlerCollection = new HandlerCollection();
        this.jetty.setHandler(handlerCollection);
    }
    return handlerCollection;
};

HttpServer.prototype.getContextHandlerCollection = function() {
    const handlerCollection = this.getHandlerCollection();
    let contextHandlerCollection =
            handlerCollection.getChildHandlerByClass(ContextHandlerCollection);
    if (contextHandlerCollection === null) {
        contextHandlerCollection = new ContextHandlerCollection();
        handlerCollection.addHandler(contextHandlerCollection);
    }
    return contextHandlerCollection;
};

HttpServer.prototype.addContext = function(context) {
    this.contexts[context.getKey()] = context;
    if (this.jetty.isRunning()) {
        context.contextHandler.start();
    }
    return context;
};

HttpServer.prototype.enableSessions = function(options) {
    options || (options = {});

    // if random is null, jetty will fall back to a SecureRandom in its initRandom()
    const sessionIdManager = new DefaultSessionIdManager(this.jetty, options.random || null);
    sessionIdManager.setWorkerName(options.name || "node1");
    this.jetty.setSessionIdManager(sessionIdManager);
    return sessionIdManager;
};

HttpServer.prototype.serveApplication = function(mountpoint, app, options) {
    if (typeof(mountpoint) !== "string") {
        throw new Error("Missing mountpoint argument");
    }
    options || (options = {});
    options = {
        "security": options.security !== false,
        "sessions": options.sessions !== false,
        "sessionsMaxInactiveInterval": options.sessionsMaxInactiveInterval || null,
        "cookieName": options.cookieName || null,
        "cookieDomain": options.cookieDomain || null,
        "cookiePath": options.cookiePath || null,
        "cookieMaxAge": options.cookieMaxAge || -1,
        "httpOnlyCookies": options.httpOnlyCookies !== false,
        "secureCookies": options.secureCookies === true,
        "statistics": options.statistics === true,
        "virtualHosts": options.virtualHosts
    };
    const parentContainer = this.getContextHandlerCollection();
    const context = new ApplicationContext(parentContainer, mountpoint, options);
    context.serve(app);
    return this.addContext(context);
};

HttpServer.prototype.serveStatic = function(mountpoint, directory, options) {
    if (typeof(mountpoint) !== "string") {
        throw new Error("Missing mountpoint argument");
    }
    if (typeof(directory) !== "string") {
        throw new Error("Missing directory argument");
    } else if (!fs.exists(directory) || !fs.isDirectory(directory)) {
        throw new Error("Directory '" + directory + "' doesn't exist or is not a directory");
    }
    options || (options = {});
    const initParameters = {
        "acceptRanges": options.acceptRanges === true,
        "dirAllowed": options.allowDirectoryListing === true,
        "gzip": options.gzip === true,
        "stylesheet": options.stylesheet || null,
        "etags": options.etags !== false,
        "maxCacheSize": options.maxCacheSize || 0,
        "maxCachedFileSize": options.maxCachedFileSize || 0,
        "maxCachedFiles": options.maxCachedFiles || 0,
        "cacheControl": options.cacheControl || null,
        "otherGzipFileExtensions": options.gzipExtensions || null
    };
    const parentContainer = this.getContextHandlerCollection();
    const context = new StaticContext(parentContainer, mountpoint, {
            "security": options.security === true,
            "sessions": options.sessions === true,
            "virtualHosts": options.virtualHosts
        });
    context.serve(directory, initParameters);
    return this.addContext(context);
};

HttpServer.prototype.enableConnectionStatistics = function() {
    ServerConnectionStatistics.addToAllConnectors(this.jetty);
};

HttpServer.prototype.getConnectionStatistics = function() {
    let connectors = this.jetty.getConnectors();
    return connectors.map(function(connector) {
        return {
            "name": connector.getName(),
            "host": connector.getHost(),
            "port": connector.getPort(),
            "statistics": connector.getBean(ConnectionStatistics)
        }
    });
};

HttpServer.prototype.start = function() {
    this.jetty.start();
    this.jetty.getConnectors().forEach(function(connector) {
        log.info("Server on {}:{} started", connector.getHost(), connector.getPort());
    });
};

HttpServer.prototype.stop = function() {
    return this.jetty.stop();
};

HttpServer.prototype.destroy = function() {
    return this.jetty.destroy();
};

HttpServer.prototype.isRunning = function() {
    return this.jetty.isRunning();
};<|endoftext|>


<commit_before>const BaseCommand = require("./BaseCommand.js");

/**
 * Command for creating entries
 * @class CreateEntryCommand
 * @augments BaseCommand
 */
class CreateEntryCommand extends BaseCommand {
    /**
     * Execute the entry creation
     * @param {ArchiveDataset} obj The archive dataset
     * @param {String} groupID The ID of the group to create within
     * @param {String} entryID The ID of the entry to create
     */
    execute(obj, groupID, entryID) {
        obj.groups = obj.groups || [];
        var entry = {
            id: entryID,
            title: ""
        };
        var group = this.searchTools.findGroupByID(obj.groups, groupID);
        if (!group) {
            throw new Error("Invalid group ID");
        }
        group.entries = group.entries || [];
        group.entries.push(entry);
    }
}

module.exports = CreateEntryCommand;
<commit_msg>Fix entry title for create-title command<commit_after>const BaseCommand = require("./BaseCommand.js");

/**
 * Command for creating entries
 * @class CreateEntryCommand
 * @augments BaseCommand
 */
class CreateEntryCommand extends BaseCommand {
    /**
     * Execute the entry creation
     * @param {ArchiveDataset} obj The archive dataset
     * @param {String} groupID The ID of the group to create within
     * @param {String} entryID The ID of the entry to create
     */
    execute(obj, groupID, entryID) {
        obj.groups = obj.groups || [];
        const entry = {
            id: entryID,
            properties: {
                title: ""
            }
        };
        const group = this.searchTools.findGroupByID(obj.groups, groupID);
        if (!group) {
            throw new Error("Invalid group ID");
        }
        group.entries = group.entries || [];
        group.entries.push(entry);
    }
}

module.exports = CreateEntryCommand;
<|endoftext|>