<commit_before>/*
 * AjaxStream JQuery JavaScript Library v1.0.0
 *
 * Requires JQuery 1.11.2 or higher
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Shane Tindle
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

$.ajaxStream =
(function($) {
	// js GUID
	function _g(n) {
		var _r = "";

		if (typeof n != "number")
			n = 5;

        function _s() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }

		for (var i = 0; i < n.length; i++)
			_r += _s() + "_";

        return _r;
    }

	// unique ids
	var _i = {
		o: _g(), // <form/>
		r: _g(), // <iframe/>
		i: _g() // <input type="file"/>
	};

	// form builder
	function makeForm(p) {
		// id unique to the page
		var i = _g(1) + new Date().getTime();
		var f = {
			o: _i.o + i
		};

		// return object
		return $("<form/>")
			.attr("method", "POST")
			.attr("name", f.o)
			.attr("id", f.o)
			.attr("enctype", "multipart/form-data")
			.css({
				position: "absolute",
				top: "-1200px",
				left: "-1200px"
			})
			.appendTo("body");
	}

	// frame builder
	function makeFrame() {
		// id unique to the page
		var i = _g(1) + new Date().getTime();
		var f = {
			r: _i.r + i
		};

		// return object
		return $("<iframe/>")
			.attr("id", f.r)
			.attr("name", f.r)
			.css({
				position: "absolute",
				top: -9999,
				left: -9999
			})
			.attr("src", "about:blank")
			.appendTo("body");
	}

	// input builder
	function makeInput(n, v) {
		return $("<input/>")
			.attr("name", n)
			.val(v);
	}

	// response handler
	function response(timeout, done, xhtml, frame, form, p) {
		var status;

		try {
			if (frame[0].contentWindow) {
                xhtml.responseText =
                    frame.contents().find("body").length > 0 ?
                    (
                        frame.contents().find("body").find("pre").length > 0 ?
                        frame.contents().find("body").find("pre").html() :
                        frame.contents().find("body").html()
                    ) :
                    (
                        frame[0].contentWindow.document.body ?
                        (
                            frame[0].contentWindow.document.body.getElementByName("pre") ?
                            frame[0].contentWindow.document.body.getElementByName("pre").innerHTML :
                            frame[0].contentWindow.document.body.innerHTML
                        ) :
                        frame[0].contentWindow.document.body.innerHTML
                    );
                xhtml.responseXML = frame[0].contentWindow.document.XMLDocument ? frame[0].contentWindow.document.XMLDocument : frame[0].contentWindow.document;
            }
		} catch (e) {
			// handle the error...
			if (p.debug)
				console.log("contentWindow not appended: " + e);
		}

		try {
			if (frame[0].contentDocument) {
                xhtml.responseText = frame[0].contentDocument.document.body ? frame[0].contentDocument.document.body.innerHTML : null;
                xhtml.responseXML = frame[0].contentDocument.document.XMLDocument ? frame[0].contentDocument.document.XMLDocument : frame[0].contentDocument.document;
            }
		} catch (e) {
			// handle the error...
			if (p.debug)
				console.log("contentWindow not appended: " + e);
		}

		if (xhtml || timeout === "timeout") {
            done = true;

            try {
                status = timeout !== "timeout" ? "success" : "error";

                if (status !== "error") {
					p.dataType = p.dataType.toLowerCase();
					if (p.dataType !== "file") {
						var data = p.dataType === "xml" ? xhtml.responseXML : xhtml.responseText;

						if (p.dataType === "script")
							$.globalEval(data);

						if (p.dataType === "json")
							data = $.parseJSON(data);
					} else {
						if (typeof p.success === typeof Function)
							p.success(null, status);
					}

					if (p.global)
						$.event.trigger("ajaxSuccess", [xhtml]);
                } else {
                    // handle the error...
                    if (p.debug)
						console.log("Executing ajaxError");

                    if (typeof p.error === typeof Function)
						p.error(xhtml, status, "ajax failure on ie");

                    if (p.global)
						$.event.trigger("ajaxError", [xhtml]);
                }
                //if (param.global) $.event.trigger("ajaxComplete", [xhtml]);
            } catch (e) {
                // handle the error...
                if (p.debug) console.log("unexpected error: " + e);
                try {
                    // retry code
                    if (typeof p.error === typeof Function)
						p.error(xhtml, status, "ajax failure on ie");
                } catch (ee) {
					/* nothing left to do */
					throw;
				}
            }

            // request complete
            if (p.global)
				$.event.trigger("ajaxComplete", [xhtml]);

            // handle the global ajax counter
            if (p.global && ! --$.active)
				$.event.trigger("ajaxStop");

            // process it
            if (typeof p.complete === typeof Function)
				p.complete(xhtml, status);

            frame.unbind();

            try {
                frame.remove();
            } catch (e) {
                // handle the error...
                if (p.debug)
					console.log("failed to remove frame");
            }
            try {
                form.remove();
            } catch (e) {
                // handle the error...
                if (p.debug)
					console.log("failed to remove form");
            }
			delete xhtml;
            //xhtml = null;
        }
	}

	function real(p) {
		var d = new FormData();
		var url = typeof p.url === "string" ? p.url : "";

		// extract files from tag
		if (p.files instanceof Array && p.files.length > 0) {
			try {
				var name;
				var obj;
				for (var i = 0; i < p.files.length; i++) {
					obj = $(p.files[i]);
					name = obj.attr("name");
					if (name === "")
						name = "file";
					$.each(obj[0].files, function(ii, file) {
						d.append(name, file);
					});
				}
			} catch (e) {
				// error in extracting files
				if (p.debug)
					console.log("failed to add extracted files");
			}
		}

		// server is responsible for decoding json string name
		// only allow POST

		$.each(p.data, function(name, obj) {
			d.append(name, JSON.stringify(p.data));
		});

		// send data
		$.ajax({
			url: url,
			data: d,
			dataType: p.dataType,
			cache: false,
			contentType: false,
			processData: false,
			async: true,
			type: "POST",
			success: function(data, textStatus) {
				if (typeof p.success === typeof Function)
					p.success(data, textStatus);
			},
			error: function(jqXHR, textStatus, errorThrown) {
				if (typeof p.error === typeof Function)
					p.error(jqXHR, textStatus, errorThrown);
			},
			complete: function(jqXHR, textStatus) {
				if (typeof p.complete === typeof Function)
					p.complete(jqXHR, textStatus);
			}
		});
	}

	function fake(p) {
		var p = $.extend({},
			$.ajaxSettings,
			p);

		var processForm = makeForm(p),
			processIFrame = makeFrame(),
			processId = "streamfile_" + _g(2) + new Date().getTime();

		if (p.files instanceof Array && p.files.length > 0) {
			try {
				var c = 0;
				for (var i = 0; i < p.files.length; i++) {
					var origobj = $(p.files[i]);
					var clone = origobj.clone();
					origobj.attr("id", _i.i + processId + c++);
					origobj.before(clone);
					origobj.appendTo(processForm);
				}
			} catch (e) {
				// error in extracting files
				if (p.debug)
					console.log("failed to add extracted files");
			}
		}

		// server is responsible for decoding json string name
		// only allow POST

		$.each(p.data, function(name, obj) {
			processForm.append(makeInput(name, JSON.stringify(obj));
		});

		// look for new requests
		if (p.global && !$.active++) $.event.trigger("ajaxStart");

		var done = false;

		// build request
		var xhtml = {};
		if (p.global) $.event.trigger("ajaxSend", [xhtml]);

		if (p.timeout > 0)
			setTimeout(function () {
				if (!done)
					response("timeout", done, xhtml, processIFrame, processForm, p);
			}, p.timeout);

		try {
			processForm.attr("action", p.url);
			processForm.attr("method", "POST");
			processForm.attr("target", processIFrame.attr("id"));

			if (p.debug)
				console.log(processIFrame.attr("id"));

			processForm.attr("encoding", "multipart/form-data");
			processForm.attr("enctype", "multipart/form-data");
			processForm.submit();

		} catch (e) {
			// handle the error...
			if (p.debug)
				console.log("error in submitting");
		}

		processIFrame.load(function () {
			done = true;
			response("success", done, xhtml, processIFrame, processForm, p);
		});
	}

	function main(p) {
		var p = $.extend({}, {
			url: "", // URL to submit data to
			data: {}, // object to encode - first layer keys will be part of multipart form
			dataType: "json", // server response expected
			files: [], // files to send to the server (must be array of valid <input/>)
			timeout: -1, // max request time
			success: function(data, textStatus) {}, // success promise
			error: function (jqXHR, textStatus, errorThrown) {}, // error promise
			complete: function (jqXHR, textStatus) {} // completion promise
		}, p);

		var isReal = false;

		try {
			// is new FormData supported?
			var t = new FormData();
			isReal = true;
		} catch (e) {
			isReal = false;
		}

		if (p.dataType === "file") {
			// this is a download request
			fake(p);
			return;
		}

		if (isReal) {
			real(p);
		} else {
			fake(p);
		}

		return;
	}

	return main;
})($);
<commit_msg>Update ajaxstream.jquery-1.0.0.js<commit_after>/*
 * AjaxStream JQuery JavaScript Library v1.0.0
 *
 * Requires JQuery 1.11.2 or higher
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Shane Tindle
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

$.ajaxStream =
(function($) {
	// js GUID
	function _s() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }

	function _g(n) {
		var _r = "";

		if (typeof n != "number")
			n = 5;

		for (var i = 0; i < n.length; i++)
			_r += _s() + "_";

        	return _r;
    	}

	// unique ids
	var _i = {
		o: _g(), // <form/>
		r: _g(), // <iframe/>
		i: _g() // <input type="file"/>
	};

	// form builder
	function makeForm(p) {
		// id unique to the page
		var i = _g(1) + new Date().getTime();
		var f = {
			o: _i.o + i
		};

		// return object
		return $("<form/>")
			.attr("method", "POST")
			.attr("name", f.o)
			.attr("id", f.o)
			.attr("enctype", "multipart/form-data")
			.css({
				position: "absolute",
				top: "-1200px",
				left: "-1200px"
			})
			.appendTo("body");
	}

	// frame builder
	function makeFrame() {
		// id unique to the page
		var i = _g(1) + new Date().getTime();
		var f = {
			r: _i.r + i
		};

		// return object
		return $("<iframe/>")
			.attr("id", f.r)
			.attr("name", f.r)
			.css({
				position: "absolute",
				top: -9999,
				left: -9999
			})
			.attr("src", "about:blank")
			.appendTo("body");
	}

	// input builder
	function makeInput(n, v) {
		return $("<input/>")
			.attr("name", n)
			.val(v);
	}

	// response handler
	function response(timeout, done, xhtml, frame, form, p) {
		var status;

		try {
			if (frame[0].contentWindow) {
	                	xhtml.responseText =
	                    	frame.contents().find("body").length > 0 ?
	                    	(
	                        	frame.contents().find("body").find("pre").length > 0 ?
	                        	frame.contents().find("body").find("pre").html() :
	                        	frame.contents().find("body").html()
	                    	) :
	                    	(
	                        	frame[0].contentWindow.document.body ?
	                        	(
	                            		frame[0].contentWindow.document.body.getElementByName("pre") ?
	                            		frame[0].contentWindow.document.body.getElementByName("pre").innerHTML :
	                            		frame[0].contentWindow.document.body.innerHTML
	                        	) :
	                        	frame[0].contentWindow.document.body.innerHTML
	                    	);
	                	xhtml.responseXML = frame[0].contentWindow.document.XMLDocument ? frame[0].contentWindow.document.XMLDocument : frame[0].contentWindow.document;
            		}
		} catch (e) {
			// handle the error...
			if (p.debug)
				console.log("contentWindow not appended: " + e);
		}

		try {
			if (frame[0].contentDocument) {
                		xhtml.responseText = frame[0].contentDocument.document.body ? frame[0].contentDocument.document.body.innerHTML : null;
                		xhtml.responseXML = frame[0].contentDocument.document.XMLDocument ? frame[0].contentDocument.document.XMLDocument : frame[0].contentDocument.document;
            		}
		} catch (e) {
			// handle the error...
			if (p.debug)
				console.log("contentWindow not appended: " + e);
		}

		if (xhtml || timeout === "timeout") {
            		done = true;

            		try {
                		status = timeout !== "timeout" ? "success" : "error";

                		if (status !== "error") {
					p.dataType = p.dataType.toLowerCase();
					if (p.dataType !== "file") {
						var data = p.dataType === "xml" ? xhtml.responseXML : xhtml.responseText;

						if (p.dataType === "script")
							$.globalEval(data);

						if (p.dataType === "json")
							data = $.parseJSON(data);
					} else {
						if (typeof p.success === typeof Function)
							p.success(null, status);
					}

					if (p.global)
						$.event.trigger("ajaxSuccess", [xhtml]);
                		} else {
                    			// handle the error...
                    			if (p.debug)
						console.log("Executing ajaxError");

                    			if (typeof p.error === typeof Function)
						p.error(xhtml, status, "ajax failure on ie");

                    			if (p.global)
						$.event.trigger("ajaxError", [xhtml]);
                		}
                		//if (param.global) $.event.trigger("ajaxComplete", [xhtml]);
            		} catch (e) {
                		// handle the error...
                		if (p.debug) console.log("unexpected error: " + e);
                		try {
                			// retry code
                    			if (typeof p.error === typeof Function)
						p.error(xhtml, status, "ajax failure on ie");
                		} catch (ee) {
					/* nothing left to do */
					throw;
				}
            		}

            		// request complete
            		if (p.global)
				$.event.trigger("ajaxComplete", [xhtml]);

            		// handle the global ajax counter
            		if (p.global && ! --$.active)
				$.event.trigger("ajaxStop");

            		// process it
            		if (typeof p.complete === typeof Function)
				p.complete(xhtml, status);

            		frame.unbind();

            		try {
                		frame.remove();
            		} catch (e) {
                		// handle the error...
                		if (p.debug)
					console.log("failed to remove frame");
            		}

            		try {
                		form.remove();
            		} catch (e) {
                		// handle the error...
                		if (p.debug)
					console.log("failed to remove form");
            		}
			delete xhtml;
            		//xhtml = null;
        	}
	}

	function real(p) {
		var d = new FormData();
		var url = typeof p.url === "string" ? p.url : "";

		// extract files from tag
		if (p.files instanceof Array && p.files.length > 0) {
			try {
				var name;
				var obj;
				for (var i = 0; i < p.files.length; i++) {
					obj = $(p.files[i]);
					name = obj.attr("name");
					if (name === "")
						name = "file";
					$.each(obj[0].files, function(ii, file) {
						d.append(name, file);
					});
				}
			} catch (e) {
				// error in extracting files
				if (p.debug)
					console.log("failed to add extracted files");
			}
		}

		// server is responsible for decoding json string name
		// only allow POST

		$.each(p.data, function(name, obj) {
			d.append(name, JSON.stringify(p.data));
		});

		// send data
		$.ajax({
			url: url,
			data: d,
			dataType: p.dataType,
			cache: false,
			contentType: false,
			processData: false,
			async: true,
			type: "POST",
			success: function(data, textStatus) {
				if (typeof p.success === typeof Function)
					p.success(data, textStatus);
			},
			error: function(jqXHR, textStatus, errorThrown) {
				if (typeof p.error === typeof Function)
					p.error(jqXHR, textStatus, errorThrown);
			},
			complete: function(jqXHR, textStatus) {
				if (typeof p.complete === typeof Function)
					p.complete(jqXHR, textStatus);
			}
		});
	}

	function fake(p) {
		var p = $.extend({},
			$.ajaxSettings,
			p);

		var processForm = makeForm(p),
			processIFrame = makeFrame(),
			processId = "streamfile_" + _g(2) + new Date().getTime();

		if (p.files instanceof Array && p.files.length > 0) {
			try {
				var c = 0;
				var origobj;
				var clone;
				for (var i = 0; i < p.files.length; i++) {
					origobj = $(p.files[i]);
					clone = origobj.clone();
					origobj.attr("id", _i.i + processId + c++);
					origobj.before(clone);
					origobj.appendTo(processForm);
				}
			} catch (e) {
				// error in extracting files
				if (p.debug)
					console.log("failed to add extracted files");
			}
		}

		// server is responsible for decoding json string name
		// only allow POST

		$.each(p.data, function(name, obj) {
			processForm.append(makeInput(name, JSON.stringify(obj));
		});

		// look for new requests
		if (p.global && !$.active++)
			$.event.trigger("ajaxStart");

		var done = false;

		// build request
		var xhtml = {};
		if (p.global)
			$.event.trigger("ajaxSend", [xhtml]);

		if (p.timeout > 0)
			setTimeout(function () {
				if (!done)
					response("timeout", done, xhtml, processIFrame, processForm, p);
			}, p.timeout);

		try {
			processForm.attr("action", p.url);
			processForm.attr("method", "POST");
			processForm.attr("target", processIFrame.attr("id"));

			if (p.debug)
				console.log(processIFrame.attr("id"));

			processForm.attr("encoding", "multipart/form-data");
			processForm.attr("enctype", "multipart/form-data");
			processForm.submit();

		} catch (e) {
			// handle the error...
			if (p.debug)
				console.log("error in submitting");
		}

		processIFrame.load(function () {
			done = true;
			response("success", done, xhtml, processIFrame, processForm, p);
		});
	}

	function main(p) {
		var p = $.extend({}, {
			url: "", // URL to submit data to
			data: {}, // object to encode - first layer keys will be part of multipart form
			dataType: "json", // server response expected
			files: [], // files to send to the server (must be array of valid <input/>)
			timeout: -1, // max request time
			success: function(data, textStatus) {}, // success promise
			error: function (jqXHR, textStatus, errorThrown) {}, // error promise
			complete: function (jqXHR, textStatus) {} // completion promise
		}, p);

		var isReal = false;

		try {
			// is new FormData supported?
			var t = new FormData();
			isReal = true;
		} catch (e) {
			isReal = false;
		}

		if (p.dataType === "file") {
			// this is a download request
			fake(p);
			return;
		}

		if (isReal) {
			real(p);
		} else {
			fake(p);
		}

		return;
	}

	return main;
})($);
<|endoftext|>


<commit_before>import TwoVector from '../../serialize/TwoVector';
let differenceVector = new TwoVector();

// The collision detection of SimplePhysicsEngine is a brute-force approach
export default class CollisionDetection {

    constructor(options) {
        this.options = Object.assign({ COLLISION_DISTANCE: 28 }, options);
        this.collisionPairs = {};
    }

    init(options) {
        this.gameEngine = options.gameEngine;
    }

    // check if pair (id1, id2) have collided
    checkPair(id1, id2) {
        let objects = this.gameEngine.world.objects;
        let o1 = objects[id1];
        let o2 = objects[id2];

        // make sure that objects actually exist. might have been destroyed
        if (!o1 || !o2) return;
        let pairId = [id1, id2].join(',');
        differenceVector.copy(o1.position).subtract(o2.position);

        if (differenceVector.length() < this.options.COLLISION_DISTANCE) {
            if (!(pairId in this.collisionPairs)) {
                this.collisionPairs[pairId] = true;
                this.gameEngine.emit('collisionStart', { o1, o2 });
            } else {
                this.gameEngine.emit('collisionStay', { o1, o2 });
            }
        } else if (pairId in this.collisionPairs) {
            this.gameEngine.emit('collisionStop', { o1, o2 });
            delete this.collisionPairs[pairId];
        }
    }

    // detect by checking all pairs
    detect() {
        let objects = this.gameEngine.world.objects;
        for (let k1 of Object.keys(objects))
            for (let k2 of Object.keys(objects))
                if (k2 > k1) this.checkPair(k1, k2);
    }

}
<commit_msg>fix memory leak code which occurs when collisionPairs's object was removed from gameworld<commit_after>import TwoVector from '../../serialize/TwoVector';
let differenceVector = new TwoVector();

// The collision detection of SimplePhysicsEngine is a brute-force approach
export default class CollisionDetection {

    constructor(options) {
        this.options = Object.assign({ COLLISION_DISTANCE: 28 }, options);
        this.collisionPairs = {};
        this.visitHash = Math.floor(Math.random()*10000);
    }

    init(options) {
        this.gameEngine = options.gameEngine;
    }

    // check if pair (id1, id2) have collided
    checkPair(id1, id2) {
        let objects = this.gameEngine.world.objects;
        let o1 = objects[id1];
        let o2 = objects[id2];

        // make sure that objects actually exist. might have been destroyed
        if (!o1 || !o2) return;
        let pairId = [id1, id2].join(',');
        differenceVector.copy(o1.position).subtract(o2.position);

        if (differenceVector.length() < this.options.COLLISION_DISTANCE) {
            if (!(pairId in this.collisionPairs)) {
                this.collisionPairs[pairId] = {collision: true, visit:this.visitHash};
                this.gameEngine.emit('collisionStart', { o1, o2 });
            }else{
                this.collisionPairs[pairId].visit = this.visitHash;
                this.gameEngine.emit('collisionStay', { o1, o2 });
            }
        } else if (pairId in this.collisionPairs) {
            this.gameEngine.emit('collisionStop', { o1, o2 });
            delete this.collisionPairs[pairId];
        }
    }

    // detect by checking all pairs
    detect() {
        this.visitHash = Math.floor(Math.random()*10000);

        let objects = this.gameEngine.world.objects;
        for (let k1 of Object.keys(objects))
            for (let k2 of Object.keys(objects))
                if (k2 > k1) this.checkPair(k1, k2);

        //Delete non visited pairs
        for (let pair in this.collisionPairs) {
            if(this.collisionPairs[pair].visit !== this.visitHash)
                delete this.collisionPairs[pair];
        }
    }

}
<|endoftext|>


<commit_before>define(['bluebird', 'kb_lib/html'], function (Promise, html) {
    'use strict';

    const t = html.tag,
        div = t('div');

    function factory(config) {
        var hostNode,
            runtime = config.runtime;

        // var tabsControl = document.querySelector(selector);

        var tabSet;
        var currentTab;

        // var tabsOrder = arg.order;
        // var tabsDefinition = arg.tabs;

        var tabsId = html.genId();
        var tabsMap = config.tabs.reduce(function (accum, tab) {
            if (tab) {
                accum[tab.name] = tab;
            }
            return accum;
        }, {});

        //     function render() {
        //         var html = '<div class="flex-tabs" id="' + myId + '">' +
        //                    ''

        //         tabsOrder.map(function (tabName) {
        //             var tab = tabsDefinition[tabName];

        //         }
        // }

        function render() {
            var style = {};
            if (config.style) {
                style = config.style;
            }
            hostNode.innerHTML = div(
                {
                    class: 'flex-tabs',
                    id: tabsId,
                    style: style
                },
                [
                    div(
                        {
                            class: '-tabs'
                        },
                        config.tabs.map(function (tab) {
                            return div(
                                {
                                    class: '-tab',
                                    dataTab: tab.name
                                },
                                div(
                                    {
                                        class: '-label'
                                    },
                                    tab.label
                                )
                            );
                        }).concat([div(
                            {
                                class: '-tab-rest'
                            }
                        )])
                    ),
                    div(
                        {
                            class: '-panels'
                        },
                        config.tabs.map(function (tab) {
                            return div({
                                class: '-panel',
                                dataTabPanel: tab.name
                            });
                        })
                    )
                ]
            );
            tabSet = hostNode.querySelector('.-tabs');
        }

        function deactivateCurrentTab() {
            if (!currentTab) {
                return;
            }
            var tab = hostNode.querySelector('[data-tab="' + currentTab + '"]');
            var panel = hostNode.querySelector('[data-tab-panel="' + currentTab + '"]');
            tab.classList.add('-inactive');
            panel.classList.add('-inactive');
            tab.classList.remove('-active');
            panel.classList.remove('-active');
        }

        var currentTabWidget;

        function unloadCurrentTab() {
            return Promise.try(function () {
                if (!currentTabWidget) {
                    return null;
                }
                return currentTabWidget.stop().then(function () {
                    return currentTabWidget.detach();
                });
            });
        }

        function loadTab(tabName) {
            const panel = tabsMap[tabName].panel;
            if (panel.factory) {
                currentTabWidget = panel.factory.make({
                    runtime
                });
            } else if (panel.class) {
                currentTabWidget = new panel.class({
                    runtime
                });
            } else {
                throw new Error('No panel factory or class');
            }

            var tabNode = hostNode.querySelector('[data-tab-panel="' + tabName + '"]');
            return currentTabWidget.attach(tabNode).then(function () {
                return currentTabWidget.start();
            });
        }

        function activateTab(tabName) {
            currentTab = tabName;
            var tab = hostNode.querySelector('[data-tab="' + currentTab + '"]');
            var panel = hostNode.querySelector('[data-tab-panel="' + currentTab + '"]');
            return unloadCurrentTab()
                .then(function () {
                    tab.classList.remove('-inactive');
                    panel.classList.remove('-inactive');
                    return loadTab(tabName);
                })
                .then(function () {
                    tab.classList.add('-active');
                    panel.classList.add('-active');
                })
                .catch(function (err) {
                    console.error('ERROR', err);
                });
        }

        // Service API

        function attach(node) {
            return Promise.try(function () {
                hostNode = node;
                // More bare to the metal...
                render();
            });
        }

        function start() {
            return Promise.try(function () {
                var tabs = Array.prototype.slice.call(tabSet.querySelectorAll('[data-tab]'));
                // var tabPanels = Array.prototype.slice.call(tabSet.querySelectorAll('[data-tab-panel]'));
                tabs.forEach(function (tab) {
                    var tabName = tab.getAttribute('data-tab');
                    var tabPanel = hostNode.querySelector('[data-tab-panel="' + tabName + '"]');
                    tab.classList.add(tabName === currentTab ? '-active' : '-inactive');
                    tabPanel.classList.add(tabName === currentTab ? '-active' : '-inactive');
                    tab.addEventListener('click', function () {
                        deactivateCurrentTab();
                        activateTab(tabName);
                    });
                });
                if (config.initialTab) {
                    return activateTab(config.initialTab);
                }
            });
        }

        function run({ tab }) {
            deactivateCurrentTab();
            return activateTab(tab);
        }

        function stop() {
            return Promise.try(function () {
                if (!currentTabWidget) {
                    return null;
                }
                return currentTabWidget.stop();
            });
        }

        function detach() {
            return Promise.try(function () {
                if (!currentTabWidget) {
                    return null;
                }
                return currentTabWidget.detach();
            }).then(() => {
                if (hostNode) {
                    hostNode.innerHTML = '';
                }
                return null;
            });
        }

        return {
            attach,
            start,
            run,
            stop,
            detach
        };
    }

    return {
        make: function (config) {
            return factory(config);
        }
    };
});
<commit_msg>clean up code<commit_after>define(['bluebird', 'kb_lib/html'], function (Promise, html) {
    'use strict';

    const t = html.tag,
        div = t('div');

    function make(config) {
        let hostNode;
        const runtime = config.runtime;

        let tabSet;
        let currentTab;

        const tabsId = html.genId();
        const tabsMap = config.tabs.reduce(function (accum, tab) {
            if (tab) {
                accum[tab.name] = tab;
            }
            return accum;
        }, {});

        function render() {
            const style = config.style ? config.style : {};

            hostNode.innerHTML = div(
                {
                    class: 'flex-tabs',
                    id: tabsId,
                    style: style
                },
                [
                    div(
                        {
                            class: '-tabs'
                        },
                        config.tabs.map(function (tab) {
                            return div(
                                {
                                    class: '-tab',
                                    dataTab: tab.name
                                },
                                div(
                                    {
                                        class: '-label'
                                    },
                                    tab.label
                                )
                            );
                        }).concat([div(
                            {
                                class: '-tab-rest'
                            }
                        )])
                    ),
                    div(
                        {
                            class: '-panels'
                        },
                        config.tabs.map(function (tab) {
                            return div({
                                class: '-panel',
                                dataTabPanel: tab.name
                            });
                        })
                    )
                ]
            );
            tabSet = hostNode.querySelector('.-tabs');
        }

        function deactivateCurrentTab() {
            if (!currentTab) {
                return;
            }
            const tab = hostNode.querySelector('[data-tab="' + currentTab + '"]');
            const panel = hostNode.querySelector('[data-tab-panel="' + currentTab + '"]');
            tab.classList.add('-inactive');
            panel.classList.add('-inactive');
            tab.classList.remove('-active');
            panel.classList.remove('-active');
        }

        let currentTabWidget;

        function unloadCurrentTab() {
            return Promise.try(function () {
                if (!currentTabWidget) {
                    return null;
                }
                return currentTabWidget.stop().then(function () {
                    return currentTabWidget.detach();
                });
            });
        }

        function loadTab(tabName) {
            const panel = tabsMap[tabName].panel;
            if (panel.factory) {
                currentTabWidget = panel.factory.make({
                    runtime
                });
            } else if (panel.class) {
                currentTabWidget = new panel.class({
                    runtime
                });
            } else {
                throw new Error('No panel factory or class');
            }

            const tabNode = hostNode.querySelector(`[data-tab-panel="${tabName}"]`);
            return currentTabWidget.attach(tabNode).then(function () {
                return currentTabWidget.start();
            });
        }

        function activateTab(tabName) {
            currentTab = tabName;
            const tab = hostNode.querySelector(`[data-tab="${currentTab}"]`);
            const panel = hostNode.querySelector(`[data-tab-panel="${currentTab}"]`);
            return unloadCurrentTab()
                .then(function () {
                    tab.classList.remove('-inactive');
                    panel.classList.remove('-inactive');
                    return loadTab(tabName);
                })
                .then(function () {
                    tab.classList.add('-active');
                    panel.classList.add('-active');
                })
                .catch(function (err) {
                    console.error('ERROR', err);
                });
        }

        // Service API

        function attach(node) {
            return Promise.try(function () {
                hostNode = node;
                render();
            });
        }

        function start() {
            return Promise.try(function () {
                const tabs = Array.prototype.slice.call(tabSet.querySelectorAll('[data-tab]'));
                tabs.forEach((tab) => {
                    const tabName = tab.getAttribute('data-tab');
                    const tabPanel = hostNode.querySelector(`[data-tab-panel="${tabName}"]`);
                    tab.classList.add(tabName === currentTab ? '-active' : '-inactive');
                    tabPanel.classList.add(tabName === currentTab ? '-active' : '-inactive');
                    tab.addEventListener('click', function () {
                        deactivateCurrentTab();
                        activateTab(tabName);
                    });
                });
                if (config.initialTab) {
                    return activateTab(config.initialTab);
                }
            });
        }

        function run({ tab }) {
            deactivateCurrentTab();
            return activateTab(tab);
        }

        function stop() {
            return Promise.try(function () {
                if (!currentTabWidget) {
                    return null;
                }
                return currentTabWidget.stop();
            });
        }

        function detach() {
            return Promise.try(function () {
                if (!currentTabWidget) {
                    return null;
                }
                return currentTabWidget.detach();
            }).then(() => {
                if (hostNode) {
                    hostNode.innerHTML = '';
                }
                return null;
            });
        }

        return {
            attach,
            start,
            run,
            stop,
            detach
        };
    }

    return {
        make
    };
});
<|endoftext|>


<commit_before>'use strict';

var path = require('path'),
    dirAssets = path.join(__dirname, '..'),
    dirStyles = path.join(dirAssets, 'styles'),
    dirScripts = path.join(dirAssets, 'scripts'),
    dirVendors = path.join(dirAssets, 'vendors'),
    dirScriptsAppFile = path.join(dirScripts, 'src', 'app.js'),
    dirScriptsVendorFiles = [
        path.join(dirVendors, 'bower', 'jquery', 'dist', 'jquery.min.js'),
        path.join(dirVendors, 'bower', 'bootstrap', 'dist', 'js', 'bootstrap.min.js')
    ];

module.exports = {
    assets: {
        dir: dirAssets
    },
    styles: {
        dir: dirStyles,
        src: {
            dir: path.join(dirStyles, 'src'),
            file: path.join(dirStyles, 'src', 'app.less'),
            files: path.join(dirStyles, 'src', '**/*')
        },
        dist: {
            dir: path.join(dirStyles, 'dist'),
            file: path.join(dirStyles, 'dist', 'app.css'),
            files: path.join(dirStyles, 'dist', '**/*'),
            blessed: {
                dir: path.join(dirStyles, 'dist', 'blessed'),
                files: path.join(dirStyles, 'dist', 'blessed', '**/*.css')
            }
        }
    },
    scripts: {
        dir: dirScripts,
        src: {
            app: {
                file: dirScriptsAppFile
            },
            pages: {},
            vendors: {
                files: dirScriptsVendorFiles
            },
            shared: dirScriptsVendorFiles.concat(dirScriptsAppFile)
        },
        dist: {
            dir: path.join(dirScripts, 'dist'),
            files: path.join(dirScripts, 'dist', '**/*')
        }
    },
    vendors: {
        dir: dirVendors,
        styles: {
            files: path.join(dirVendors, '**/*.@(less|css)')
        }
    }
};
<commit_msg>[GULP] Updated "config.paths.js" to use uncompressed JS files from vendors.<commit_after>'use strict';

var path = require('path'),
    dirAssets = path.join(__dirname, '..'),
    dirStyles = path.join(dirAssets, 'styles'),
    dirScripts = path.join(dirAssets, 'scripts'),
    dirVendors = path.join(dirAssets, 'vendors'),
    dirScriptsAppFile = path.join(dirScripts, 'src', 'app.js'),
    dirScriptsVendorFiles = [
        path.join(dirVendors, 'bower', 'jquery', 'dist', 'jquery.js'),
        path.join(dirVendors, 'bower', 'bootstrap', 'dist', 'js', 'bootstrap.js')
    ];

module.exports = {
    assets: {
        dir: dirAssets
    },
    styles: {
        dir: dirStyles,
        src: {
            dir: path.join(dirStyles, 'src'),
            file: path.join(dirStyles, 'src', 'app.less'),
            files: path.join(dirStyles, 'src', '**/*')
        },
        dist: {
            dir: path.join(dirStyles, 'dist'),
            file: path.join(dirStyles, 'dist', 'app.css'),
            files: path.join(dirStyles, 'dist', '**/*'),
            blessed: {
                dir: path.join(dirStyles, 'dist', 'blessed'),
                files: path.join(dirStyles, 'dist', 'blessed', '**/*.css')
            }
        }
    },
    scripts: {
        dir: dirScripts,
        src: {
            app: {
                file: dirScriptsAppFile
            },
            pages: {},
            vendors: {
                files: dirScriptsVendorFiles
            },
            shared: dirScriptsVendorFiles.concat(dirScriptsAppFile)
        },
        dist: {
            dir: path.join(dirScripts, 'dist'),
            files: path.join(dirScripts, 'dist', '**/*')
        }
    },
    vendors: {
        dir: dirVendors,
        styles: {
            files: path.join(dirVendors, '**/*.@(less|css)')
        }
    }
};
<|endoftext|>


<commit_before>import FileListView from '../components/filelist.js'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { setPath, downloadFile, showDeleteDialog } from '../actions/files.js'

const mapStateToProps = (state) => ({
	files: state.files.get('workingDirectoryFiles'),
	searchResults: state.files.get('searchResults'),
	path: state.files.get('path'),
	showSearchField: state.files.get('showSearchField'),
})
const mapDispatchToProps = (dispatch) => ({
	actions: bindActionCreators({ setPath, downloadFile, showDeleteDialog }, dispatch),
})

const FileList = connect(mapStateToProps, mapDispatchToProps)(FileListView)
export default FileList
<commit_msg>add rename dialog to filelist container<commit_after>import FileListView from '../components/filelist.js'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { setPath, downloadFile, showDeleteDialog, showRenameDialog } from '../actions/files.js'

const mapStateToProps = (state) => ({
	files: state.files.get('workingDirectoryFiles'),
	searchResults: state.files.get('searchResults'),
	path: state.files.get('path'),
	showSearchField: state.files.get('showSearchField'),
})
const mapDispatchToProps = (dispatch) => ({
	actions: bindActionCreators({ setPath, showRenameDialog, downloadFile, showDeleteDialog }, dispatch),
})

const FileList = connect(mapStateToProps, mapDispatchToProps)(FileListView)
export default FileList
<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

/**
 * OData-based DataBinding Utility Class
 *
 * @namespace
 * @name sap.ui.model.odata
 * @public
 */

// Provides class sap.ui.model.odata.ODataUtils
sap.ui.define(['jquery.sap.global', './Filter', 'sap/ui/model/Sorter', 'sap/ui/model/Filter', 'sap/ui/core/format/DateFormat'],
	function(jQuery, ODataFilter, Sorter, Filter, DateFormat) {
	"use strict";

	// Static class
	var ODataUtils = function() {};

	/**
	 * Create URL parameters for sorting
	 * @name sap.ui.model.odata.ODataUtils#createSortParams
	 * @param {array} aSorters an array of sap.ui.model.Sorter
	 * @return {string} the URL encoded sorter parameters
	 * @private
	 * @function
	 */
	ODataUtils.createSortParams = function(aSorters) {
		var sSortParam;
		if (!aSorters || aSorters.length == 0) {
			return;
		}
		sSortParam = "$orderby=";
		for (var i = 0; i < aSorters.length; i++) {
			var oSorter = aSorters[i];
			if (oSorter instanceof Sorter) {
				sSortParam += oSorter.sPath;
				sSortParam += oSorter.bDescending ? "%20desc" : "%20asc";
				sSortParam += ",";
			}
		}
		//remove trailing comma
		sSortParam = sSortParam.slice(0, -1);
		return sSortParam;
	};

	/**
	 * Creates URL parameters strings for filtering.
	 * The Parameter string is prepended with the "$filter=" system query option to form
	 * a valid URL part for OData Request.
	 * @see ODataUtils._createFilterParams
	 * @see {array} aFilters an array of sap.ui.model.Filter
	 * @param {object} oEntityType the entity metadata object
	 * @return {string} the URL encoded filter parameters
	 * @name sap.ui.model.odata.ODataUtils#createFilterParams
	 * @private
	 * @function
	 */
	ODataUtils.createFilterParams = function(aFilters, oMetadata, oEntityType) {
		if (!aFilters || aFilters.length == 0) {
			return;
		}
		return "$filter=" + this._createFilterParams(aFilters, oMetadata, oEntityType);
	};

	/**
	 * Creates a string of logically (or/and) linked filter options,
	 * which will be used as URL query parameters for filtering.
	 * @param {array} aFilters an array of sap.ui.model.Filter
	 * @param {object} oEntityType the entity metadata object
	 * @return {string} the URL encoded filter parameters
	 * @name sap.ui.model.odata.ODataUtils#createFilterParams
	 * @private
	 * @function
	 */
	ODataUtils._createFilterParams = function(aFilters, oMetadata, oEntityType) {
		var sFilterParam;
		if (!aFilters || aFilters.length == 0) {
			return;
		}
		var oFilterGroups = {},
			iFilterGroupLength = 0,
			aFilterGroup,
			sFilterParam = "",
			iFilterGroupCount = 0,
			that = this;
		//group filters by path
		jQuery.each(aFilters, function(j, oFilter) {
			if (oFilter.sPath) {
				aFilterGroup = oFilterGroups[oFilter.sPath];
				if (!aFilterGroup) {
					aFilterGroup = oFilterGroups[oFilter.sPath] = [];
					iFilterGroupLength++;
				}
			} else {
				aFilterGroup = oFilterGroups["__multiFilter"];
				if (!aFilterGroup) {
					aFilterGroup = oFilterGroups["__multiFilter"] = [];
					iFilterGroupLength++;
				}
			}
			aFilterGroup.push(oFilter);
		});
		jQuery.each(oFilterGroups, function(sPath, aFilterGroup) {
			if (aFilterGroup.length > 1) {
				sFilterParam += '(';
			}
			jQuery.each(aFilterGroup, function(i,oFilter) {
				if (oFilter instanceof ODataFilter) {
					if (oFilter.aValues.length > 1) {
						sFilterParam += '(';
					}
					jQuery.each(oFilter.aValues, function(i, oFilterSegment) {
						if (i > 0) {
							if (oFilter.bAND) {
								sFilterParam += "%20and%20";
							} else {
								sFilterParam += "%20or%20";
							}
						}
						sFilterParam = that._createFilterSegment(oFilter.sPath, oMetadata, oEntityType, oFilterSegment.operator, oFilterSegment.value1, oFilterSegment.value2, sFilterParam);
					});
					if (oFilter.aValues.length > 1) {
						sFilterParam += ')';
					}
				} else if (oFilter._bMultiFilter) {
					sFilterParam += that._resolveMultiFilter(oFilter, oMetadata, oEntityType);
				} else {
					sFilterParam = that._createFilterSegment(oFilter.sPath, oMetadata, oEntityType, oFilter.sOperator, oFilter.oValue1, oFilter.oValue2, sFilterParam);
				}
				if (i < aFilterGroup.length - 1) {
					sFilterParam += "%20or%20";
				}
			});
			if (aFilterGroup.length > 1) {
				sFilterParam += ')';
			}
			if (iFilterGroupCount < iFilterGroupLength - 1) {
				sFilterParam += "%20and%20";
			}
			iFilterGroupCount++;
		});
		return sFilterParam;
	};

	/**
	 * Converts a string or object-map with URL Parameters into an array.
	 * If vParams is an object map, it will be also encoded properly.
	 *
	 * @private
	 * @param {string|object|array} vParams
	 * @name sap.ui.model.odata.ODataUtils#_createUrlParamsArray
	 * @function
	 */
	ODataUtils._createUrlParamsArray = function(vParams) {
		var aUrlParams, sType = jQuery.type(vParams);
		if (sType === "array") {
			return vParams;
		}

		aUrlParams = [];
		if (sType === "object") {
			aUrlParams.push(this._encodeURLParameters(vParams));
		} else if (sType === "string") {
			aUrlParams.push(vParams);
		}

		return aUrlParams;
	};

	/**
	 * Encode a map of parameters into a combined URL parameter string
	 *
	 * @param {map} mParams The map of parameters to encode
	 * @returns {string} sUrlParams The URL encoded parameters
	 * @private
	 */
	ODataUtils._encodeURLParameters = function(mParams) {
		if (!mParams) {
			return "";
		}
		var aUrlParams = [];
		jQuery.each(mParams, function (sName, oValue) {
			if (jQuery.type(oValue) === "string") {
				oValue = encodeURIComponent(oValue);
			}
			sName = jQuery.sap.startsWith(sName,'$') ? sName : encodeURIComponent(sName);
			aUrlParams.push(sName + "=" + oValue);
		});
		return aUrlParams.join("&");
	};

	/**
	 * convert multi filter to filter string
	 *
	 * @private
	 * @name sap.ui.model.odata.ODataUtils#_resolveMultiFilter
	 * @function
	 */
	ODataUtils._resolveMultiFilter = function(oMultiFilter, oMetadata, oEntityType){
		var that = this,
			aFilters = oMultiFilter.aFilters,
			sFilterParam = "";

		if (aFilters) {
			sFilterParam += "(";
			jQuery.each(aFilters, function(i, oFilter) {
				if (oFilter._bMultiFilter) {
					sFilterParam += that._resolveMultiFilter(oFilter, oMetadata, oEntityType);
				} else if (oFilter.sPath) {
					sFilterParam += that._createFilterSegment(oFilter.sPath, oMetadata, oEntityType, oFilter.sOperator, oFilter.oValue1, oFilter.oValue2, "");
				}
				if (i < (aFilters.length - 1)) {
					if (oMultiFilter.bAnd) {
						sFilterParam += "%20and%20";
					} else {
						sFilterParam += "%20or%20";
					}
				}
			});
			sFilterParam += ")";
		}

		return sFilterParam;
	};

	/**
	 * Create a single filter segment of the OData filter parameters
	 *
	 * @private
	 * @name sap.ui.model.odata.ODataUtils#_createFilterSegment
	 * @function
	 */
	ODataUtils._createFilterSegment = function(sPath, oMetadata, oEntityType, sOperator, oValue1, oValue2, sFilterParam) {

		var oPropertyMetadata, sType;
		if (oEntityType) {
			oPropertyMetadata = oMetadata._getPropertyMetadata(oEntityType, sPath);
			sType = oPropertyMetadata && oPropertyMetadata.type;
			jQuery.sap.assert(oPropertyMetadata, "PropertyType for property " + sPath + " of EntityType " + oEntityType.name + " not found!");
		}

		if (sType) {
			oValue1 = this.formatValue(oValue1, sType);
			oValue2 = (oValue2 != null) ? this.formatValue(oValue2, sType) : null;
		} else {
			jQuery.sap.assert(null, "Type for filter property could not be found in metadata!");
		}

		if (oValue1) {
			oValue1 = jQuery.sap.encodeURL(String(oValue1));
		}
		if (oValue2) {
			oValue2 = jQuery.sap.encodeURL(String(oValue2));
		}

		// TODO embed 2nd value
		switch (sOperator) {
			case "EQ":
			case "NE":
			case "GT":
			case "GE":
			case "LT":
			case "LE":
				sFilterParam += sPath + "%20" + sOperator.toLowerCase() + "%20" + oValue1;
				break;
			case "BT":
				sFilterParam += "(" + sPath + "%20ge%20" + oValue1 + "%20and%20" + sPath + "%20le%20" + oValue2 + ")";
				break;
			case "Contains":
				sFilterParam += "substringof(" + oValue1 + "," + sPath + ")";
				break;
			case "StartsWith":
				sFilterParam += "startswith(" + sPath + "," + oValue1 + ")";
				break;
			case "EndsWith":
				sFilterParam += "endswith(" + sPath + "," + oValue1 + ")";
				break;
			default:
				sFilterParam += "true";
		}
		return sFilterParam;
	};

	/**
	 * Format a JavaScript value according to the given EDM type
	 * http://www.odata.org/documentation/overview#AbstractTypeSystem
	 *
	 * @param {any} vValue the value to format
	 * @param {string} sType the EDM type (e.g. Edm.Decimal)
	 * @return {string} the formatted value
	 * @name sap.ui.model.odata.ODataUtils#formatValue
	 * @public
	 * @function
	 */
	ODataUtils.formatValue = function(vValue, sType) {
		// Lazy creation of format objects
		if (!this.oDateTimeFormat) {
			this.oDateTimeFormat = DateFormat.getDateInstance({
				pattern: "'datetime'''yyyy-MM-dd'T'HH:mm:ss''"
			});
			this.oDateTimeOffsetFormat = DateFormat.getDateInstance({
				pattern: "'datetimeoffset'''yyyy-MM-dd'T'HH:mm:ss'Z'''"
			});
			this.oTimeFormat = DateFormat.getTimeInstance({
				pattern: "'time'''HH:mm:ss''"
			});
		}

		// null values should return the null literal
		if (vValue === null || vValue === undefined) {
			return "null";
		}

		// Format according to the given type
		var sValue;
		switch (sType) {
			case "Edm.String":
				// quote
				sValue = "'" + String(vValue).replace(/'/g, "''") + "'";
				break;
			case "Edm.Time":
				sValue = "time'" + vValue + "'";
				break;
			case "Edm.DateTime":
				sValue = this.oDateTimeFormat.format(new Date(vValue), true);
				break;
			case "Edm.DateTimeOffset":
				sValue = this.oDateTimeOffsetFormat.format(new Date(vValue), true);
				break;
			case "Edm.Guid":
				sValue = "guid'" + vValue + "'";
				break;
			case "Edm.Decimal":
				sValue = vValue + "M";
				break;
			case "Edm.Int64":
				sValue = vValue + "L";
				break;
			case "Edm.Single":
				sValue = vValue + "f";
				break;
			case "Edm.Binary":
				sValue = "binary'" + vValue + "'";
				break;
			default:
				sValue = new String(vValue);
				break;
		}
		return sValue;
	};

	return ODataUtils;

}, /* bExport= */ true);

<commit_msg>[FIX] ODataModel: Don't create empty query string<commit_after>/*!
 * ${copyright}
 */

/**
 * OData-based DataBinding Utility Class
 *
 * @namespace
 * @name sap.ui.model.odata
 * @public
 */

// Provides class sap.ui.model.odata.ODataUtils
sap.ui.define(['jquery.sap.global', './Filter', 'sap/ui/model/Sorter', 'sap/ui/model/Filter', 'sap/ui/core/format/DateFormat'],
	function(jQuery, ODataFilter, Sorter, Filter, DateFormat) {
	"use strict";

	// Static class
	var ODataUtils = function() {};

	/**
	 * Create URL parameters for sorting
	 * @name sap.ui.model.odata.ODataUtils#createSortParams
	 * @param {array} aSorters an array of sap.ui.model.Sorter
	 * @return {string} the URL encoded sorter parameters
	 * @private
	 * @function
	 */
	ODataUtils.createSortParams = function(aSorters) {
		var sSortParam;
		if (!aSorters || aSorters.length == 0) {
			return;
		}
		sSortParam = "$orderby=";
		for (var i = 0; i < aSorters.length; i++) {
			var oSorter = aSorters[i];
			if (oSorter instanceof Sorter) {
				sSortParam += oSorter.sPath;
				sSortParam += oSorter.bDescending ? "%20desc" : "%20asc";
				sSortParam += ",";
			}
		}
		//remove trailing comma
		sSortParam = sSortParam.slice(0, -1);
		return sSortParam;
	};

	/**
	 * Creates URL parameters strings for filtering.
	 * The Parameter string is prepended with the "$filter=" system query option to form
	 * a valid URL part for OData Request.
	 * @see ODataUtils._createFilterParams
	 * @see {array} aFilters an array of sap.ui.model.Filter
	 * @param {object} oEntityType the entity metadata object
	 * @return {string} the URL encoded filter parameters
	 * @name sap.ui.model.odata.ODataUtils#createFilterParams
	 * @private
	 * @function
	 */
	ODataUtils.createFilterParams = function(aFilters, oMetadata, oEntityType) {
		if (!aFilters || aFilters.length == 0) {
			return;
		}
		return "$filter=" + this._createFilterParams(aFilters, oMetadata, oEntityType);
	};

	/**
	 * Creates a string of logically (or/and) linked filter options,
	 * which will be used as URL query parameters for filtering.
	 * @param {array} aFilters an array of sap.ui.model.Filter
	 * @param {object} oEntityType the entity metadata object
	 * @return {string} the URL encoded filter parameters
	 * @name sap.ui.model.odata.ODataUtils#createFilterParams
	 * @private
	 * @function
	 */
	ODataUtils._createFilterParams = function(aFilters, oMetadata, oEntityType) {
		var sFilterParam;
		if (!aFilters || aFilters.length == 0) {
			return;
		}
		var oFilterGroups = {},
			iFilterGroupLength = 0,
			aFilterGroup,
			sFilterParam = "",
			iFilterGroupCount = 0,
			that = this;
		//group filters by path
		jQuery.each(aFilters, function(j, oFilter) {
			if (oFilter.sPath) {
				aFilterGroup = oFilterGroups[oFilter.sPath];
				if (!aFilterGroup) {
					aFilterGroup = oFilterGroups[oFilter.sPath] = [];
					iFilterGroupLength++;
				}
			} else {
				aFilterGroup = oFilterGroups["__multiFilter"];
				if (!aFilterGroup) {
					aFilterGroup = oFilterGroups["__multiFilter"] = [];
					iFilterGroupLength++;
				}
			}
			aFilterGroup.push(oFilter);
		});
		jQuery.each(oFilterGroups, function(sPath, aFilterGroup) {
			if (aFilterGroup.length > 1) {
				sFilterParam += '(';
			}
			jQuery.each(aFilterGroup, function(i,oFilter) {
				if (oFilter instanceof ODataFilter) {
					if (oFilter.aValues.length > 1) {
						sFilterParam += '(';
					}
					jQuery.each(oFilter.aValues, function(i, oFilterSegment) {
						if (i > 0) {
							if (oFilter.bAND) {
								sFilterParam += "%20and%20";
							} else {
								sFilterParam += "%20or%20";
							}
						}
						sFilterParam = that._createFilterSegment(oFilter.sPath, oMetadata, oEntityType, oFilterSegment.operator, oFilterSegment.value1, oFilterSegment.value2, sFilterParam);
					});
					if (oFilter.aValues.length > 1) {
						sFilterParam += ')';
					}
				} else if (oFilter._bMultiFilter) {
					sFilterParam += that._resolveMultiFilter(oFilter, oMetadata, oEntityType);
				} else {
					sFilterParam = that._createFilterSegment(oFilter.sPath, oMetadata, oEntityType, oFilter.sOperator, oFilter.oValue1, oFilter.oValue2, sFilterParam);
				}
				if (i < aFilterGroup.length - 1) {
					sFilterParam += "%20or%20";
				}
			});
			if (aFilterGroup.length > 1) {
				sFilterParam += ')';
			}
			if (iFilterGroupCount < iFilterGroupLength - 1) {
				sFilterParam += "%20and%20";
			}
			iFilterGroupCount++;
		});
		return sFilterParam;
	};

	/**
	 * Converts a string or object-map with URL Parameters into an array.
	 * If vParams is an object map, it will be also encoded properly.
	 *
	 * @private
	 * @param {string|object|array} vParams
	 * @name sap.ui.model.odata.ODataUtils#_createUrlParamsArray
	 * @function
	 */
	ODataUtils._createUrlParamsArray = function(vParams) {
		var aUrlParams, sType = jQuery.type(vParams), sParams;
		if (sType === "array") {
			return vParams;
		}

		aUrlParams = [];
		if (sType === "object") {
			sParams = this._encodeURLParameters(vParams);
			if (sParams) {
				aUrlParams.push(sParams);
			}
		} else if (sType === "string") {
			if (vParams) {
				aUrlParams.push(vParams);
			}
		}

		return aUrlParams;
	};

	/**
	 * Encode a map of parameters into a combined URL parameter string
	 *
	 * @param {map} mParams The map of parameters to encode
	 * @returns {string} sUrlParams The URL encoded parameters
	 * @private
	 */
	ODataUtils._encodeURLParameters = function(mParams) {
		if (!mParams) {
			return "";
		}
		var aUrlParams = [];
		jQuery.each(mParams, function (sName, oValue) {
			if (jQuery.type(oValue) === "string") {
				oValue = encodeURIComponent(oValue);
			}
			sName = jQuery.sap.startsWith(sName,'$') ? sName : encodeURIComponent(sName);
			aUrlParams.push(sName + "=" + oValue);
		});
		return aUrlParams.join("&");
	};

	/**
	 * convert multi filter to filter string
	 *
	 * @private
	 * @name sap.ui.model.odata.ODataUtils#_resolveMultiFilter
	 * @function
	 */
	ODataUtils._resolveMultiFilter = function(oMultiFilter, oMetadata, oEntityType){
		var that = this,
			aFilters = oMultiFilter.aFilters,
			sFilterParam = "";

		if (aFilters) {
			sFilterParam += "(";
			jQuery.each(aFilters, function(i, oFilter) {
				if (oFilter._bMultiFilter) {
					sFilterParam += that._resolveMultiFilter(oFilter, oMetadata, oEntityType);
				} else if (oFilter.sPath) {
					sFilterParam += that._createFilterSegment(oFilter.sPath, oMetadata, oEntityType, oFilter.sOperator, oFilter.oValue1, oFilter.oValue2, "");
				}
				if (i < (aFilters.length - 1)) {
					if (oMultiFilter.bAnd) {
						sFilterParam += "%20and%20";
					} else {
						sFilterParam += "%20or%20";
					}
				}
			});
			sFilterParam += ")";
		}

		return sFilterParam;
	};

	/**
	 * Create a single filter segment of the OData filter parameters
	 *
	 * @private
	 * @name sap.ui.model.odata.ODataUtils#_createFilterSegment
	 * @function
	 */
	ODataUtils._createFilterSegment = function(sPath, oMetadata, oEntityType, sOperator, oValue1, oValue2, sFilterParam) {

		var oPropertyMetadata, sType;
		if (oEntityType) {
			oPropertyMetadata = oMetadata._getPropertyMetadata(oEntityType, sPath);
			sType = oPropertyMetadata && oPropertyMetadata.type;
			jQuery.sap.assert(oPropertyMetadata, "PropertyType for property " + sPath + " of EntityType " + oEntityType.name + " not found!");
		}

		if (sType) {
			oValue1 = this.formatValue(oValue1, sType);
			oValue2 = (oValue2 != null) ? this.formatValue(oValue2, sType) : null;
		} else {
			jQuery.sap.assert(null, "Type for filter property could not be found in metadata!");
		}

		if (oValue1) {
			oValue1 = jQuery.sap.encodeURL(String(oValue1));
		}
		if (oValue2) {
			oValue2 = jQuery.sap.encodeURL(String(oValue2));
		}

		// TODO embed 2nd value
		switch (sOperator) {
			case "EQ":
			case "NE":
			case "GT":
			case "GE":
			case "LT":
			case "LE":
				sFilterParam += sPath + "%20" + sOperator.toLowerCase() + "%20" + oValue1;
				break;
			case "BT":
				sFilterParam += "(" + sPath + "%20ge%20" + oValue1 + "%20and%20" + sPath + "%20le%20" + oValue2 + ")";
				break;
			case "Contains":
				sFilterParam += "substringof(" + oValue1 + "," + sPath + ")";
				break;
			case "StartsWith":
				sFilterParam += "startswith(" + sPath + "," + oValue1 + ")";
				break;
			case "EndsWith":
				sFilterParam += "endswith(" + sPath + "," + oValue1 + ")";
				break;
			default:
				sFilterParam += "true";
		}
		return sFilterParam;
	};

	/**
	 * Format a JavaScript value according to the given EDM type
	 * http://www.odata.org/documentation/overview#AbstractTypeSystem
	 *
	 * @param {any} vValue the value to format
	 * @param {string} sType the EDM type (e.g. Edm.Decimal)
	 * @return {string} the formatted value
	 * @name sap.ui.model.odata.ODataUtils#formatValue
	 * @public
	 * @function
	 */
	ODataUtils.formatValue = function(vValue, sType) {
		// Lazy creation of format objects
		if (!this.oDateTimeFormat) {
			this.oDateTimeFormat = DateFormat.getDateInstance({
				pattern: "'datetime'''yyyy-MM-dd'T'HH:mm:ss''"
			});
			this.oDateTimeOffsetFormat = DateFormat.getDateInstance({
				pattern: "'datetimeoffset'''yyyy-MM-dd'T'HH:mm:ss'Z'''"
			});
			this.oTimeFormat = DateFormat.getTimeInstance({
				pattern: "'time'''HH:mm:ss''"
			});
		}

		// null values should return the null literal
		if (vValue === null || vValue === undefined) {
			return "null";
		}

		// Format according to the given type
		var sValue;
		switch (sType) {
			case "Edm.String":
				// quote
				sValue = "'" + String(vValue).replace(/'/g, "''") + "'";
				break;
			case "Edm.Time":
				sValue = "time'" + vValue + "'";
				break;
			case "Edm.DateTime":
				sValue = this.oDateTimeFormat.format(new Date(vValue), true);
				break;
			case "Edm.DateTimeOffset":
				sValue = this.oDateTimeOffsetFormat.format(new Date(vValue), true);
				break;
			case "Edm.Guid":
				sValue = "guid'" + vValue + "'";
				break;
			case "Edm.Decimal":
				sValue = vValue + "M";
				break;
			case "Edm.Int64":
				sValue = vValue + "L";
				break;
			case "Edm.Single":
				sValue = vValue + "f";
				break;
			case "Edm.Binary":
				sValue = "binary'" + vValue + "'";
				break;
			default:
				sValue = new String(vValue);
				break;
		}
		return sValue;
	};

	return ODataUtils;

}, /* bExport= */ true);
<|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function () {

  'use strict';

  /**
   * @ngdoc service
   * @name stock-orderable-group.orderableGroupService
   *
   * @description
   * Responsible for managing orderable groups.
   */
  angular
    .module('stock-orderable-group')
    .service('orderableGroupService', service);

  service.$inject = ['messageService'];

  function service(messageService) {
    var noLotDefined = {lotCode: messageService.get('orderableGroupService.noLotDefined')};

    this.lotsOf = lotsOf;
    this.determineLotMessage = determineLotMessage;
    this.areOrderablesUseVvm = areOrderablesUseVvm;
    this.groupByOrderableId = groupByOrderableId;
    this.findByLotInOrderableGroup = findByLotInOrderableGroup;

    function groupByOrderableId (items) {
      return _.chain(items)
        .groupBy(function (item) {
          return item.orderable.id;
        }).values().value();
    }

    function findByLotInOrderableGroup (orderableGroup, selectedLot) {
      var selectedItem = _.chain(orderableGroup)
        .find(function (groupItem) {
          var selectedNoLot = !groupItem.lot && (!selectedLot || selectedLot == noLotDefined);
          var lotMatch = groupItem.lot && groupItem.lot === selectedLot;
          return selectedNoLot || lotMatch;
        }).value();

      if (selectedItem) {
        determineLotMessage(selectedItem, orderableGroup);
      }
      return selectedItem;
    }

    function lotsOf(orderableGroup) {
      var lots = _.chain(orderableGroup).pluck('lot').compact().value();

      var someHasLot = lots.length > 0;
      var someHasNoLot = _.any(orderableGroup, function (item) {
        return item.lot == null;
      });

      if (someHasLot && someHasNoLot) {
        lots.unshift(noLotDefined);//add no lot defined as an option
      }
      return lots;
    }

    function determineLotMessage(selectedItem, orderableGroup) {
      if (!selectedItem.lot) {
        var messageKey = lotsOf(orderableGroup).length > 0 ? 'noLotDefined' : 'productHasNoLots';
        selectedItem.displayLotMessage = messageService.get('orderableGroupService.' + messageKey);
      } else {
        selectedItem.displayLotMessage = selectedItem.lot.lotCode;
      }
    }

    /**
     * @ngdoc method
     * @methodOf stock-orderable-group.orderableGroupService
     * @name areOrderablesUseVvm
     *
     * @description
     * Determines if any orderable in orderable groups use VVM.
     *
     * @param {Array} orderableGroups   filtered groups
     * @return {boolean}                true if any orderable has useVVM property 'true'
     */
    function areOrderablesUseVvm(orderableGroups) {
        var groupsWithVVM = orderableGroups.filter(filterOrderablesThatUseVvm);
        return groupsWithVVM.length > 0;
    }

    function filterOrderablesThatUseVvm (group) {
        var extraData = group[0].orderable.extraData;
        return extraData !== null && extraData !== undefined && extraData.useVVM === 'true';
    }

  }

})();
<commit_msg>OLMIS-3027: add javadocs to orderable group service<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function () {

    'use strict';

    /**
     * @ngdoc service
     * @name stock-orderable-group.orderableGroupService
     *
     * @description
     * Responsible for managing orderable groups.
     */
    angular
        .module('stock-orderable-group')
        .service('orderableGroupService', service);

    service.$inject = ['messageService'];

    function service(messageService) {
        var noLotDefined = {lotCode: messageService.get('orderableGroupService.noLotDefined')};

        this.lotsOf = lotsOf;
        this.determineLotMessage = determineLotMessage;
        this.groupByOrderableId = groupByOrderableId;
        this.findByLotInOrderableGroup = findByLotInOrderableGroup;
        this.areOrderablesUseVvm = areOrderablesUseVvm;

        /**
         * @ngdoc method
         * @methodOf stock-orderable-group.orderableGroupService
         * @name lotsOf
         *
         * @description
         * Extract lots from orderable group. Adds no lot defined as an option when some group
         * has no lot
         *
         * @param {Object} orderableGroup   orderable group
         * @return {Array}                  array with lots
         */
        function lotsOf (orderableGroup) {
            var lots = _.chain(orderableGroup).pluck('lot').compact().value();

            var someHasLot = lots.length > 0;
            var someHasNoLot = _.any(orderableGroup, function (item) {
                return item.lot == null;
            });

            if (someHasLot && someHasNoLot) {
                lots.unshift(noLotDefined);//add no lot defined as an option
            }
            return lots;
        }

        /**
         * @ngdoc method
         * @methodOf stock-orderable-group.orderableGroupService
         * @name determineLotMessage
         *
         * @description
         * Determines lot message based on a lot and an orderable group.
         *
         * @param {Object} orderableGroup   orderable group
         * @param {Object} selectedItem     product with lot property. Property displayLotMessage
         *                                  will be assigned to id.
         */
        function determineLotMessage (selectedItem, orderableGroup) {
            if (!selectedItem.lot) {
                var messageKey = lotsOf(orderableGroup).length > 0 ? 'noLotDefined' : 'productHasNoLots';
                selectedItem.displayLotMessage = messageService.get('orderableGroupService.' + messageKey);
            } else {
                selectedItem.displayLotMessage = selectedItem.lot.lotCode;
            }
        }

        /**
         * @ngdoc method
         * @methodOf stock-orderable-group.orderableGroupService
         * @name groupByOrderableId
         *
         * @description
         * Groups product items by orderable id.
         *
         * @param {Array} items             product items to be grouped
         * @return {Array}                  items grouped by orderable id.
         */
        function groupByOrderableId (items) {
            return _.chain(items)
                .groupBy(function (item) {
                    return item.orderable.id;
                }).values().value();
        }

        /**
         * @ngdoc method
         * @methodOf stock-orderable-group.orderableGroupService
         * @name areOrderablesUseVvm
         *
         * @description
         * Find product in orderable group based on lot.
         *
         * @param {Object} orderableGroup   orderable group
         * @param {Object} selectedLot      selected lot
         * @return {Object}                 found product
         */
        function findByLotInOrderableGroup (orderableGroup, selectedLot) {
            var selectedItem = _.chain(orderableGroup)
                .find(function (groupItem) {
                    var selectedNoLot = !groupItem.lot && (!selectedLot || selectedLot == noLotDefined);
                    var lotMatch = groupItem.lot && groupItem.lot === selectedLot;
                    return selectedNoLot || lotMatch;
                }).value();

            if (selectedItem) {
                determineLotMessage(selectedItem, orderableGroup);
            }
            return selectedItem;
        }

        /**
         * @ngdoc method
         * @methodOf stock-orderable-group.orderableGroupService
         * @name areOrderablesUseVvm
         *
         * @description
         * Determines if any orderable in orderable groups use VVM.
         *
         * @param {Array} orderableGroups   filtered groups
         * @return {boolean}                true if any orderable has useVVM property 'true'
         */
        function areOrderablesUseVvm(orderableGroups) {
            var groupsWithVVM = orderableGroups.filter(filterOrderablesThatUseVvm);
            return groupsWithVVM.length > 0;
        }

        function filterOrderablesThatUseVvm (group) {
            var extraData = group[0].orderable.extraData;
            return extraData !== null && extraData !== undefined && extraData.useVVM === 'true';
        }

    }

})();
<|endoftext|>


<commit_before>import IdentityManager from 'service-framework/dist/IdentityManager';
import {Syncher} from 'service-framework/dist/Syncher';
import {Discovery} from 'service-framework/dist/Discovery';
import {divideURL} from '../utils/utils';
import Search from '../utils/Search';
import EventEmitter from '../utils/EventEmitter';

class UserAvailabilityObserver extends EventEmitter {

  constructor(hypertyURL, bus, configuration) {
    if (!hypertyURL) throw new Error('The hypertyURL is a needed parameter');
    if (!bus) throw new Error('The MiniBus is a needed parameter');
    if (!configuration) throw new Error('The configuration is a needed parameter ');

    super();

    let _this = this;
    _this._url = hypertyURL;
    _this._discoverUsersPromises = {}; // object with promises executed at discoverUsers function
    _this._observePromises = {}; // object with promises executed at observe function

    //let identityManager = new IdentityManager(hypertyURL, configuration.runtimeURL, bus);
    console.log('[UserAvailabilityObserver] started with hypertyURL->', hypertyURL);
    _this._domain = divideURL(hypertyURL).domain;
    _this._objectDescURL = 'hyperty-catalogue://catalogue.' + _this._domain + '/.well-known/dataschema/Context';

    _this._users2observe = [];
    _this._observers = {};

    _this._syncher = new Syncher(hypertyURL, bus, configuration);
    let discovery = new Discovery(hypertyURL, configuration.runtimeURL, bus);
    _this._discovery = discovery;

    _this._discoveries = {}; //list of discovered objects
    //_this.identityManager = identityManager;
    //_this.search = new Search(discovery, identityManager);
    window.discovery = _this._discovery;
  }

  start() {
    let _this = this;
    console.log('[UserAvailabilityObserver.start] ');

    return new Promise((resolve, reject) => {
      _this._syncher.resumeObservers({store: true}).then((observers) => {

        let observersList = Object.keys(observers);

        if (observersList.length  > 0) {

          console.log('[UserAvailabilityObserver.start] resuming: ', observers);

          /*observersList.forEach((i)=>{
          _this._users2observe.push(new UserAvailabilityController(observers[i]));
        });*/
        _this._observers = observers;

        resolve(observers);

        // TODO: add onDisconnected to DataObjectObserver and invoke for each resumed observer
        observersList.forEach((observer) =>{
          let availability = observers[observer]

          // By default resumed availability is unavailable. It will be updated with value synchronized with reporter if connected
          availability.data.values[0].value = 'unavailable';
          availability.sync();

          //Add listener to be notified when reporter is abruptly disconnected
          availability.onDisconnected(()=>{
            console.log('[UserAvailabilityObserver.onDisconnected]: ', observers[observer]);

            availability.data.values[0].value = 'unavailable';
            // to avoid false disconnects
            availability.sync();
          });
        });

      } else {
        resolve(false);
      }

    }).catch((reason) => {
      console.info('[UserAvailabilityObserver] Resume Observer failed | ', reason);
      resolve(false);
    });
  }).catch((reason) => {
    reject('[UserAvailabilityObserver] Start failed | ', reason);
  });
}

resumeDiscoveries() {
  let _this = this;

  return new Promise((resolve, reject) => {
    _this._discovery.resumeDiscoveries().then((discoveries) => {

      console.log('[UserAvailabilityObserver._resumeDiscoveries] found: ', discoveries);

      discoveries.forEach((discovery) =>{

        if (discovery.data.resources && discovery.data.resources[0] === 'availability_context') {
          console.log('[UserAvailabilityObserver._resumeDiscoveries] resuming: ', discovery);

          if (discovery.data.status === 'live' ) {// previously discovered object is now live
            resolve([discovery.data]);
            discovery.unsubscribeLive(_this._url);
          } else {// previously discovered object is still disconnected
            discovery.onLive(_this._url,()=>{
              console.log('[UserAvailabilityObserver._resumeDiscoveries] disconnected Hyperty is back to live', discovery);
              resolve([discovery.data]);
              discovery.unsubscribeLive(_this._url);
            });
          }
        }
      });
    });
  }).catch((reason) => {
  reject('[UserAvailabilityObserver] resumeDiscoveries failed | ', reason);
});
}

  onResumeObserver(callback) {
     let _this = this;
     _this._onResumeObserver = callback;
   }

  discoverUsers(email,domain)
  {
    let _this = this;

    let user = email + '@' + domain;

    if (!_this._discoverUsersPromises[user])
      _this._discoverUsersPromises[user] = new Promise(function(resolve,reject) {

      _this._discovery.discoverHypertiesDO(email, ['context'], ['availability_context'], domain).then(hyperties =>{
      //_this.search.users([email], [domain], ['context'], ['availability_context']).then(function(a) {
        console.log('[UserAvailabilityObserver.discoverUsers] discovery result->', hyperties);
        let discovered = [];
        let disconnected = [];
        hyperties.forEach(hyperty =>{
          _this._discoveries[hyperty.data.hypertyID] = hyperty;
          if (hyperty.data.status === 'live') {
            discovered.push(hyperty.data);
          } else {
            disconnected.push(hyperty);
            };
        });

        if (discovered.length > 0) {
          console.log('[UserAvailabilityObserver.discoverUsers] returning discovered hyperties data->', discovered);
          resolve(discovered);
        } else if (disconnected.length > 0) {
          console.log('[UserAvailabilityObserver.discoverUsers] disconnected Hyperties ', disconnected);
          //resolve([]);

          disconnected[0].onLive(_this._url,()=>{
            console.log('[UserAvailabilityObserver.discoverUsers] disconnected Hyperty is back to live', disconnected[0]);

            discovered.push(disconnected[0].data);
            resolve(discovered);
            disconnected[0].unsubscribeLive(_this._url);
          });
        }
      });
    });
    return _this._discoverUsersPromises[user];
  }

  /**
   * This function is used to start the user availability observation for a certain user availability reporter
   * @param  {DiscoveredObject} hyperty       Hyperty to be observed.
   * @return {<Promise> DataObjectObserver}      It returns as a Promise the UserAvailability Data Object Observer.
   */

  observe(hyperty)
    {
      let _this = this;
      if (!_this._observePromises[hyperty.hypertyID])
        _this._observePromises[hyperty.hypertyID] = new Promise(function(resolve,reject) {
        //check if we are already observing it
        _this._users2observe.forEach((availability) => {
          if (availability._reporter === hyperty.hypertyID) return resolve(availability);
        });

          _this._discovery.discoverDataObjectsPerReporter(hyperty.hypertyID, ['context'], ['availability_context'],  _this._domain).then(function(dataObjects) {
            console.log('[UserAvailabilityObserver.discoverAvailability] discovered user availability objects ', dataObjects);
          let last = 0;
          let url;

          dataObjects.forEach( (dataObject) => {
            if (dataObject.hasOwnProperty('lastModified') && dataObject.hasOwnProperty('url') && Date.parse(dataObject.lastModified) > last) {
              last = dataObject.lastModified;
              url = dataObject.url;
                //console.log('URL DATA Object', url);
          }
        });
        if (last != 0 && url) {
          resolve(_this._subscribeAvailability(hyperty, url));
        } else {
          reject ('[UserAvailabilityObserver.discoverAvailability] discovered DataObjecs are invalid', dataObjects);
        }
      });
    });
    return _this._observePromises[hyperty.hypertyID];
  }

  _subscribeAvailability(hyperty, url) {
    let _this = this;
    // avoid duplicated subscriptions

    return new Promise(function(resolve,reject) {
      _this._users2observe.forEach((availability) => {
        if (availability.url === url) return resolve(availability);
      });

        _this._syncher.subscribe(_this._objectDescURL, url).then((availability) => {
          console.log('[UserAvailabilityObserver.observeAvailability] observer object', availability);

          //let newUserAvailability = new UserAvailabilityController(availability, userID);

          _this._users2observe.push(availability);

          // When Object is disconnected set user availability status as unavailable
          availability.onDisconnected(()=>{
            console.log('[UserAvailabilityObserver.onDisconnected]: ', availability);

            availability.data.values[0].value = 'unavailable';
            availability.sync();
          });

          resolve(availability);
        });
      });
  }

/**
 * This function is used to stop the user availability observation for a certain user
 * @param  {string} availability       the UserAvailability Data Object Observer URL to be unobserved.
 */

  unobserve(availability)
    {
      let _this = this;

      _this._users2observe.forEach( (user, index) => {
        if (user.url === availability) {
          user.unsubscribe();
          _this._users2observe.splice(index, 1);
        }

      });
  }

}

export default function activate(hypertyURL, bus, configuration) {
  return {
    name: 'UserAvailabilityObserver',
    instance: new UserAvailabilityObserver(hypertyURL, bus, configuration)
  };
}
<commit_msg>UserAvailabilityObserver is now extending ContextObserver<commit_after>import IdentityManager from 'service-framework/dist/IdentityManager';
import {Syncher} from 'service-framework/dist/Syncher';
import {Discovery} from 'service-framework/dist/Discovery';
import {ContextObserver} from 'service-framework/dist/ContextManager';
import {divideURL} from '../utils/utils';
import Search from '../utils/Search';
import EventEmitter from '../utils/EventEmitter';

class UserAvailabilityObserver extends ContextObserver {

  constructor(hypertyURL, bus, configuration) {

    super(hypertyURL, bus, configuration, ['availability_context']);

  }

  start() {
    let resumedCallback = (availability) => {
      console.log('[UserAvailabilityObserver.onDisconnected]: ', availability);

      availability.data.values[0].value = 'unavailable';
      // to avoid false disconnects
      availability.sync();
    };

    let resumedInit = [{value: 'unavailable'}];

    return super.start(resumedInit, resumedCallback);
  }

resumeDiscoveries() {
  return super.resumeDiscoveries();

}

  onResumeObserver(callback) {
    return super.onResumeObserver(callback);
   }

  discoverUsers(email,domain)
  {
    return super.discoverUsers(email,domain);

  }

  /**
   * This function is used to start the user availability observation for a certain user availability reporter
   * @param  {DiscoveredObject} hyperty       Hyperty to be observed.
   * @return {<Promise> DataObjectObserver}      It returns as a Promise the UserAvailability Data Object Observer.
   */

  observe(hyperty)
    {
      return super.observe(hyperty);

  }

/**
 * This function is used to stop the user availability observation for a certain user
 * @param  {string} availability       the UserAvailability Data Object Observer URL to be unobserved.
 */

  unobserve(availability)
    {
      return super.unobserve(availability);

  }

}

export default function activate(hypertyURL, bus, configuration) {
  return {
    name: 'UserAvailabilityObserver',
    instance: new UserAvailabilityObserver(hypertyURL, bus, configuration)
  };
}
<|endoftext|>


<commit_before>(function(angular) {
  'use strict';

  angular
    .module('pm')
    .factory('tokenApiService', tokenApiService);

  tokenApiService.$inject = ['$http', 'settings'];

  function tokenApiService($http, settings) {
    var PATH_TO_SERVICE = settings.API.URL + 'token';

    var service = {
      generate: generate
    };

    return service;

    function generate(user) {
      var payload = user;
      return $http.post(PATH_TO_SERVICE, payload);
    }
  }
})(angular);
<commit_msg>[web] fix route genarete token.<commit_after>(function(angular) {
  'use strict';

  angular
    .module('pm')
    .factory('tokenApiService', tokenApiService);

  tokenApiService.$inject = ['$http', 'settings'];

  function tokenApiService($http, settings) {
    var PATH_TO_SERVICE = settings.API.URL + 'security/token';

    var service = {
      generate: generate
    };

    return service;

    function generate(user) {
      var payload = user;
      return $http.post(PATH_TO_SERVICE, payload);
    }
  }
})(angular);
<|endoftext|>