<commit_before>(function () {
    'use strict';
    var throbber,
        start_editing,
        stop_editing,
        set_album,
        change_album,
        submit_tag,
        remove_tag,
        add_tag;

    start_editing = function (event, display_element, edit_element, on_success) {
        var $edit,
            $form,
            attribute,
            $this = $(this);

        attribute = $this.data('attribute');
        $form = $('<form class="navbar-form">');
        $edit = $("<" + edit_element + ' class="form-control">');
        $edit.val($this.text().trim());
        $edit.blur(function (event) {
            _.bind(stop_editing, $form,
                    event, attribute, display_element, edit_element, on_success)();
        });
        $form.submit(function (event) {
            event.preventDefault();
            _.bind(stop_editing, $form,
                    event, attribute, display_element, edit_element, on_success)();
        });
        $form.append($edit);
        $this.parent().append($form);
        $this.remove();
        $edit.focus();
        $edit.select();
    };

    stop_editing = function (event,
            attribute,
            display_element,
            edit_element,
            on_success) {
        var $display,
            $parent,
            text,
            $throbber = throbber(),
            post_data = {},
            $this = $(this);

        $parent = $this.parent();
        text = $this.children().val().trim();
        $display = $("<" + display_element + "/>").text(text);
        $display.data('attribute', attribute);
        $display.click(function(event) {
            _.bind(start_editing, $display,
                    event, display_element, edit_element)();
        });
        $parent.append($throbber);
        $this.remove();
        post_data[attribute] = text;
        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {attributes: JSON.stringify(post_data)},
            success: function(data, status, jqXHR) {
                $throbber.remove();
                $parent.append($display);
                if (typeof on_success !== 'undefined') {
                    on_success(text);
                }
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    set_album = function(event, albums) {
        var $parent,
            $form,
            $select,
            $blank_option,
            $new_album_link,
            $this = $(this);

        $parent = $this.parent();
        if (typeof albums === 'undefined') {
            albums = {};
            _.each($parent.find('.data'), function(element) {
                var $element = $(element);
                albums[$element.data('id')] = $element.data('name');
            });
        }

        $form = $('<form class="navbar-form">');
        $select = $('<select class="form-control name="album">');
        $form.append($select);
        $blank_option = $('<option>(no album)</option>');
        $blank_option.val('');
        $select.append($blank_option);
        _.each(_.keys(albums), function(album_id) {
            var $option;
            $option = $('<option>');
            $option.text(albums[album_id]);
            $option.val(album_id);
            if (album_id === window.album_id) {
                $option.attr('selected', 'selected');
            }
            $select.append($option);
        });
        $select.change(function(event) {
            _.bind(change_album, $select, event, albums)();
        });

        $parent.text('');
        $parent.append($form);

        $new_album_link = $('create a new album');
        $parent.append(' or ');
        $parent.append($new_album_link);
    };

    change_album = function(event, albums) {
        var $parent,
            post_data = {},
            $throbber = throbber(),
            $this = $(this);

        $parent = $this.parent();
        post_data.album_id = $this.val();
        $this.remove();
        $parent.append($throbber);

        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {attributes: JSON.stringify(post_data)},
            success: function(data, status, jqXHR) {
                var $set_album,
                    $selected,
                    $link;
                if ($this.val() !== '') {
                    $selected = $this.find('option:selected');
                    $link = $('');
                    $link.attr('href', '/album/' + $this.val());
                    $link.text($selected.text());
                    $throbber.remove();
                    $parent.text("This image appears in the album '");
                    $parent.append($link);
                    $parent.append("'. ");
                } else {
                    $parent.text("This image has no album. ");
                }

                $set_album = $('');
                $set_album.text('(click to set album)');
                $set_album.click(function(event) {
                    _.bind(set_album, $set_album, event, albums)();
                });
                $parent.append($set_album);

                window.album_id = $this.val();
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    add_tag = function(event) {
        var $form,
            $edit,
            $this = $(this);
        $form = $('<form class="navbar-form">');
        $edit = $('<input class="form-control">');
        $form.append($edit);
        $this.text('');
        $this.append($form);
        $edit.focus();
        $edit.blur(function(event) {
            _.bind(submit_tag, $this, event)();
        });
        $form.submit(function(event) {
            event.preventDefault();
            _.bind(submit_tag, $this, event)();
        });
    };

    submit_tag = function(event) {
        var tag_name,
            $throbber = throbber(),
            $this = $(this);

        tag_name = $this.find('input').val();
        $this.append($throbber);
        $this.find('form').remove();
        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {add_tag: tag_name},
            success: function(data, status, jqXHR) {
                var $add_new,
                    $remove,
                    $span,
                    $link;
                $throbber.remove();
                $link = $('');
                $link.attr('href', '/find?tags=' + tag_name);
                $link.text(tag_name);
                $span = $('');
                $span.append($link);

                $this.append($span);

                $remove = $('');
                $remove.attr('href', '#');
                $remove.text('x');
                $remove.click(remove_tag);

                $this.append(' [');
                $this.append($remove);
                $this.append(']');

                $add_new = $('
');
                $add_new.text('(click to add a tag)');
                $add_new.click(add_tag);
                $this.parent().append($add_new);
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    remove_tag = function(event) {
        var tag_name,
            $parent,
            $throbber = throbber(),
            $this = $(this);
        event.preventDefault();

        $parent = $this.parent();
        tag_name = $parent.find('span').text();
        $parent.text('');
        $parent.append($throbber);
        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {remove_tag: tag_name},
            success: function(data, status, jqXHR) {
                $parent.remove();
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    throbber = function() {
        return $("").attr('src', '/public/img/ajax-loader.gif');
    };

    $(function() {
        if (window.logged_in) {
            $('div.page-head h2').click(function(event) {
                var on_success;
                on_success = function(text) {
                    $('title').text(text + ' - Catsnap');
                };
                _.bind(start_editing, this, event, 'h2', 'input', on_success)();
            });
            $('#description span').click(function(event) {
                _.bind(start_editing, this, event, 'span', 'textarea')();
            });
            $('#set-album').click(set_album);
            $('#add-tag').click(add_tag);
            $('.remove-tag').click(remove_tag);
        }
    });
})();
<commit_msg>Fix a missing double-quote<commit_after>(function () {
    'use strict';
    var throbber,
        start_editing,
        stop_editing,
        set_album,
        change_album,
        submit_tag,
        remove_tag,
        add_tag;

    start_editing = function (event, display_element, edit_element, on_success) {
        var $edit,
            $form,
            attribute,
            $this = $(this);

        attribute = $this.data('attribute');
        $form = $('<form class="navbar-form">');
        $edit = $("<" + edit_element + ' class="form-control">');
        $edit.val($this.text().trim());
        $edit.blur(function (event) {
            _.bind(stop_editing, $form,
                    event, attribute, display_element, edit_element, on_success)();
        });
        $form.submit(function (event) {
            event.preventDefault();
            _.bind(stop_editing, $form,
                    event, attribute, display_element, edit_element, on_success)();
        });
        $form.append($edit);
        $this.parent().append($form);
        $this.remove();
        $edit.focus();
        $edit.select();
    };

    stop_editing = function (event,
            attribute,
            display_element,
            edit_element,
            on_success) {
        var $display,
            $parent,
            text,
            $throbber = throbber(),
            post_data = {},
            $this = $(this);

        $parent = $this.parent();
        text = $this.children().val().trim();
        $display = $("<" + display_element + "/>").text(text);
        $display.data('attribute', attribute);
        $display.click(function(event) {
            _.bind(start_editing, $display,
                    event, display_element, edit_element)();
        });
        $parent.append($throbber);
        $this.remove();
        post_data[attribute] = text;
        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {attributes: JSON.stringify(post_data)},
            success: function(data, status, jqXHR) {
                $throbber.remove();
                $parent.append($display);
                if (typeof on_success !== 'undefined') {
                    on_success(text);
                }
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    set_album = function(event, albums) {
        var $parent,
            $form,
            $select,
            $blank_option,
            $new_album_link,
            $this = $(this);

        $parent = $this.parent();
        if (typeof albums === 'undefined') {
            albums = {};
            _.each($parent.find('.data'), function(element) {
                var $element = $(element);
                albums[$element.data('id')] = $element.data('name');
            });
        }

        $form = $('<form class="navbar-form">');
        $select = $('<select class="form-control" name="album">');
        $form.append($select);
        $blank_option = $('<option>(no album)</option>');
        $blank_option.val('');
        $select.append($blank_option);
        _.each(_.keys(albums), function(album_id) {
            var $option;
            $option = $('<option>');
            $option.text(albums[album_id]);
            $option.val(album_id);
            if (album_id === window.album_id) {
                $option.attr('selected', 'selected');
            }
            $select.append($option);
        });
        $select.change(function(event) {
            _.bind(change_album, $select, event, albums)();
        });

        $parent.text('');
        $parent.append($form);

        $new_album_link = $('create a new album');
        $parent.append(' or ');
        $parent.append($new_album_link);
    };

    change_album = function(event, albums) {
        var $parent,
            post_data = {},
            $throbber = throbber(),
            $this = $(this);

        $parent = $this.parent();
        post_data.album_id = $this.val();
        $this.remove();
        $parent.append($throbber);

        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {attributes: JSON.stringify(post_data)},
            success: function(data, status, jqXHR) {
                var $set_album,
                    $selected,
                    $link;
                if ($this.val() !== '') {
                    $selected = $this.find('option:selected');
                    $link = $('');
                    $link.attr('href', '/album/' + $this.val());
                    $link.text($selected.text());
                    $throbber.remove();
                    $parent.text("This image appears in the album '");
                    $parent.append($link);
                    $parent.append("'. ");
                } else {
                    $parent.text("This image has no album. ");
                }

                $set_album = $('');
                $set_album.text('(click to set album)');
                $set_album.click(function(event) {
                    _.bind(set_album, $set_album, event, albums)();
                });
                $parent.append($set_album);

                window.album_id = $this.val();
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    add_tag = function(event) {
        var $form,
            $edit,
            $this = $(this);
        $form = $('<form class="navbar-form">');
        $edit = $('<input class="form-control">');
        $form.append($edit);
        $this.text('');
        $this.append($form);
        $edit.focus();
        $edit.blur(function(event) {
            _.bind(submit_tag, $this, event)();
        });
        $form.submit(function(event) {
            event.preventDefault();
            _.bind(submit_tag, $this, event)();
        });
    };

    submit_tag = function(event) {
        var tag_name,
            $throbber = throbber(),
            $this = $(this);

        tag_name = $this.find('input').val();
        $this.append($throbber);
        $this.find('form').remove();
        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {add_tag: tag_name},
            success: function(data, status, jqXHR) {
                var $add_new,
                    $remove,
                    $span,
                    $link;
                $throbber.remove();
                $link = $('');
                $link.attr('href', '/find?tags=' + tag_name);
                $link.text(tag_name);
                $span = $('');
                $span.append($link);

                $this.append($span);

                $remove = $('');
                $remove.attr('href', '#');
                $remove.text('x');
                $remove.click(remove_tag);

                $this.append(' [');
                $this.append($remove);
                $this.append(']');

                $add_new = $('
');
                $add_new.text('(click to add a tag)');
                $add_new.click(add_tag);
                $this.parent().append($add_new);
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    remove_tag = function(event) {
        var tag_name,
            $parent,
            $throbber = throbber(),
            $this = $(this);
        event.preventDefault();

        $parent = $this.parent();
        tag_name = $parent.find('span').text();
        $parent.text('');
        $parent.append($throbber);
        $.ajax('/image/' + window.image_id + '.json', {
            type: "PATCH",
            data: {remove_tag: tag_name},
            success: function(data, status, jqXHR) {
                $parent.remove();
            },
            error: function(jqXHR, status, errorThrown) {
                $throbber.remove();
                alert(errorThrown);
            }
        });
    };

    throbber = function() {
        return $("").attr('src', '/public/img/ajax-loader.gif');
    };

    $(function() {
        if (window.logged_in) {
            $('div.page-head h2').click(function(event) {
                var on_success;
                on_success = function(text) {
                    $('title').text(text + ' - Catsnap');
                };
                _.bind(start_editing, this, event, 'h2', 'input', on_success)();
            });
            $('#description span').click(function(event) {
                _.bind(start_editing, this, event, 'span', 'textarea')();
            });
            $('#set-album').click(set_album);
            $('#add-tag').click(add_tag);
            $('.remove-tag').click(remove_tag);
        }
    });
})();
<|endoftext|>


<commit_before>'use strict';
var fs = require("fs");
var async = require("async");
var request = require("request");
var hostModel = require("../../models/host.js");
const utils = require("../../utils/utils.js");

function checkReturnError(soajs, mainCb, data, cb) {
	utils.checkErrorReturn(soajs, mainCb, data, cb);
}

var BL = {
	model: null,

	"list": function (config, soajs, cbMain) {
		hostModel.getEnvironment(soajs, BL.model, soajs.inputmaskData.env, function (err, envRecord) {
			checkReturnError(soajs, cbMain, { config: config, error: err || !envRecord, code: 600 }, function () {
				hostModel.getHosts(soajs, BL.model, envRecord.code, function (err, hosts) {
					checkReturnError(soajs, cbMain, { config: config, error: err, code: 600 }, function () {
						return cbMain(null, {
							'hosts': hosts,
							'deployer': envRecord.deployer,
							'profile': envRecord.profile
						});
					});
				});
			});
		});
	},

	/*
	 * This function will return all the environments where a service is deployed.
	 * it takes the service name and renders an object having the following form :
	 * "env_code: apiPrefix.domain"
	 * @ param serviceName
	 * @ param getHostEnv
	 * @ param response
	 */
	"listHostEnv": function (config, soajs, deployer, helpers, cbMain) {
		if (process.env.SOAJS_DEPLOY_HA) {
			BL.listHAhostEnv(config, soajs, deployer, helpers, cbMain);
		}
		else {
			hostModel.getHostEnv(soajs, BL.model, function (error, envs) {
				checkReturnError(soajs, cbMain, { config: config, error: error, code: 600 }, function () {
					checkReturnError(soajs, cbMain, {
						config: config,
						error: envs.length === 0,
						code: 621
					}, function () {
						async.map(envs, function (oneEnv, callback) {
							var opts = {
								"collection": "environment",
								"conditions": {
									"code": oneEnv.toUpperCase(),
									"$or": [
										{
											"sensitive": { "$exists": false }
										},
										{
											"sensitive": false
										}
									]
								}
							};
							BL.model.findEntry(soajs, opts, function (error, environment) {
								if (error) {
									return callback(error);
								}
								if (environment) {
									return callback(null, oneEnv.toUpperCase());
								}

								return callback(null, null);
							});
						}, function (error, envsList) {

							for (var i = envsList.length - 1; i >= 0; i--) {
								if (!envsList[i]) {
									envsList.splice(i, 1);
								}
							}

							hostModel.getEnvInfo(soajs, BL.model, { envList: envsList }, function (error, result) {
								checkReturnError(soajs, cbMain, {
									config: config,
									error: error,
									code: 600
								}, function () {
									var response = {};
									result.forEach(function (oneEnvRec) {
										if (!response[oneEnvRec.code.toLowerCase()]) {
											response[oneEnvRec.code.toLowerCase()] = {};
										}
										if(oneEnvRec.domain === ''){
											output[oneEnvRec.code.toLowerCase()]['domain'] = oneEnvRec.deployer.manual.nodes;
										}
										else {
											response[oneEnvRec.code.toLowerCase()]['domain'] = oneEnvRec.apiPrefix + "." + oneEnvRec.domain;
										}
									});
									//grab the list of tenant that have ext key in requested env and return tenant code, package nad key as part of response
									helpers.getTenants(soajs, response, BL.model, function (error) {
										checkReturnError(soajs, cbMain, { config: config, error: error }, function () {
											return cbMain(null, response);
										});
									});
								});
							});
						});
					});
				});
			});
		}
	},

	"listHAhostEnv": function (config, soajs, deployer, helpers, cbMain) {
		var output = {};

		//fetch the non sensitive environments only
		var opts = {
			"collection": "environment",
			"conditions": {
				"$or": [
					{
						"sensitive": { "$exists": false }
					},
					{
						"sensitive": false
					},
					{
						"sensitive": null
					}
				]
			}
		};
		BL.model.findEntries(soajs, opts, function (error, environments) {
			checkReturnError(soajs, cbMain, { config: config, error: error, code: 600 }, function () {
				if (!environments || environments.length === 0) {
					return cbMain(null, output);
				}

				async.each(environments, function (oneEnv, mCb) {
					//NOTE: need to get registry for environment, deployer depends on registry not environment record
					//NOTE: can't get registries without listing environments, no other way to get the list of available registries
					var options = helpers.buildDeployerOptions(oneEnv, soajs, BL.model);
					checkReturnError(soajs, cbMain, { config: config, error: !options, code: 825 }, function () {
						options.params = {
							env: oneEnv.code.toLowerCase()
						};
						let port;
						deployer.listServices(options, function (error, services) {
							checkReturnError(soajs, cbMain, { config: config, error: error }, function () {
								//loop in services and see if you find the one you want only
								for (var i = 0; i < services.length; i++) {
									var oneService = services[i];
									if (soajs.inputmaskData.service === oneService.labels["soajs.service.name"]) {
										if (!output[oneEnv.code.toLowerCase()]) {
											output[oneEnv.code.toLowerCase()] = {};
										}

										oneService.ports.forEach(function (onePort) {
											if (onePort.published) {
												port = onePort.published;
											}
										});

										if(oneEnv.domain === ''){
											let deployerInfo = oneEnv.deployer.selected.split(".");
											if(deployerInfo[1] === 'docker' && deployerInfo[2] === 'local'){
												output[oneEnv.code.toLowerCase()]['domain'] = "localhost";
											}
											else{
												if(oneEnv.deployer[deployerInfo[0]][deployerInfo[1]][deployerInfo[2]]){
													if(oneEnv.deployer[deployerInfo[0]][deployerInfo[1]][deployerInfo[2]].nodes && oneEnv.deployer[deployerInfo[0]][deployerInfo[1]][deployerInfo[2]].nodes !== ''){
														output[oneEnv.code.toLowerCase()]['domain'] = oneEnv.nodes;
													}
												}
											}
										}
										else{
											output[oneEnv.code.toLowerCase()]['domain'] = oneEnv.apiPrefix + "." + oneEnv.domain;
										}
										break;
									}
								}

								if(!port){
									services.forEach(function (oneService) {
										if (output[oneEnv.code.toLowerCase()] && oneService.labels['soajs.service.name'] === 'controller' && oneService.labels['soajs.env.code'] === oneEnv.code.toLowerCase()) {
											//todo: map domain to inner property
											oneService.ports.forEach(function (onePort) {
												if (onePort.published) {
													port = onePort.published;
												}
											});
										}
									});

									if(!port){
										if(process.env.SOAJS_SAAS && oneEnv.deployer && oneEnv.deployer.selected === 'container.kubernetes.remote'){
											if(oneEnv.deployer.container && oneEnv.deployer.container.kubernetes && oneEnv.deployer.container.kubernetes.remote && oneEnv.deployer.container.kubernetes.remote.nginxDeployType === 'LoadBalancer'){
												port = 80;
											}
										}
										else{
											services.forEach(function (oneService) {
												if (output[oneEnv.code.toLowerCase()] && oneService.labels['soajs.service.group'] === 'soajs-nginx' && oneService.labels['soajs.env.code'] === oneEnv.code.toLowerCase()) {
													//todo: map domain to inner property
													oneService.ports.forEach(function (onePort) {
														if (onePort.published) {
															port = onePort.published;
														}
													});
												}
											});
										}
									}
								}

								if(output[oneEnv.code.toLowerCase()]){
									output[oneEnv.code.toLowerCase()]['domain'] += ":" + port;
								}
								return mCb(null, true);
							});
						});
					});
				}, function (error) {
					checkReturnError(soajs, cbMain, { config: config, error: error, code: 600 }, function () {
						//grab the list of tenant that have ext key in requested env and return tenant code, package nad key as part of response
						helpers.getTenants(soajs, output, BL.model, function (error) {
							checkReturnError(soajs, cbMain, { config: config, error: error }, function () {
								return cbMain(null, output);
							});
						});
					});
				});
			});
		});
	},

	"awareness": function (config, soajs, cbMain) {
		hostModel.getEnvironment(soajs, BL.model, soajs.inputmaskData.env, function (err, envRecord) {
			checkReturnError(soajs, cbMain, { config: config, error: err || !envRecord, code: 600 }, function () {
				hostModel.getControllers(soajs, BL.model, envRecord.code, function (err, controllers) {
					checkReturnError(soajs, cbMain, { config: config, error: err, code: 600 }, function () {
						return cbMain(null, controllers);
					});
				});
			});
		});
	}
};

module.exports = {
	"init": function (modelName, cb) {
		var modelPath;

		if (!modelName) {
			return cb(new Error("No Model Requested!"));
		}

		modelPath = __dirname + "/../../models/" + modelName + ".js";
		return requireModel(modelPath, cb);

		/**
		 * checks if model file exists, requires it and returns it.
		 * @param filePath
		 * @param cb
		 */
		function requireModel(filePath, cb) {
			//check if file exist. if not return error
			fs.exists(filePath, function (exists) {
				if (!exists) {
					return cb(new Error("Requested Model Not Found!"));
				}

				BL.model = require(filePath);
				return cb(null, BL);
			});
		}
	}
};
<commit_msg>port is located in env record when using kubernetes and loadbalancer nginx deployment.<commit_after>'use strict';
var fs = require("fs");
var async = require("async");
var request = require("request");
var hostModel = require("../../models/host.js");
const utils = require("../../utils/utils.js");

function checkReturnError(soajs, mainCb, data, cb) {
	utils.checkErrorReturn(soajs, mainCb, data, cb);
}

var BL = {
	model: null,

	"list": function (config, soajs, cbMain) {
		hostModel.getEnvironment(soajs, BL.model, soajs.inputmaskData.env, function (err, envRecord) {
			checkReturnError(soajs, cbMain, { config: config, error: err || !envRecord, code: 600 }, function () {
				hostModel.getHosts(soajs, BL.model, envRecord.code, function (err, hosts) {
					checkReturnError(soajs, cbMain, { config: config, error: err, code: 600 }, function () {
						return cbMain(null, {
							'hosts': hosts,
							'deployer': envRecord.deployer,
							'profile': envRecord.profile
						});
					});
				});
			});
		});
	},

	/*
	 * This function will return all the environments where a service is deployed.
	 * it takes the service name and renders an object having the following form :
	 * "env_code: apiPrefix.domain"
	 * @ param serviceName
	 * @ param getHostEnv
	 * @ param response
	 */
	"listHostEnv": function (config, soajs, deployer, helpers, cbMain) {
		if (process.env.SOAJS_DEPLOY_HA) {
			BL.listHAhostEnv(config, soajs, deployer, helpers, cbMain);
		}
		else {
			hostModel.getHostEnv(soajs, BL.model, function (error, envs) {
				checkReturnError(soajs, cbMain, { config: config, error: error, code: 600 }, function () {
					checkReturnError(soajs, cbMain, {
						config: config,
						error: envs.length === 0,
						code: 621
					}, function () {
						async.map(envs, function (oneEnv, callback) {
							var opts = {
								"collection": "environment",
								"conditions": {
									"code": oneEnv.toUpperCase(),
									"$or": [
										{
											"sensitive": { "$exists": false }
										},
										{
											"sensitive": false
										}
									]
								}
							};
							BL.model.findEntry(soajs, opts, function (error, environment) {
								if (error) {
									return callback(error);
								}
								if (environment) {
									return callback(null, oneEnv.toUpperCase());
								}

								return callback(null, null);
							});
						}, function (error, envsList) {

							for (var i = envsList.length - 1; i >= 0; i--) {
								if (!envsList[i]) {
									envsList.splice(i, 1);
								}
							}

							hostModel.getEnvInfo(soajs, BL.model, { envList: envsList }, function (error, result) {
								checkReturnError(soajs, cbMain, {
									config: config,
									error: error,
									code: 600
								}, function () {
									var response = {};
									result.forEach(function (oneEnvRec) {
										if (!response[oneEnvRec.code.toLowerCase()]) {
											response[oneEnvRec.code.toLowerCase()] = {};
										}
										if(oneEnvRec.domain === ''){
											output[oneEnvRec.code.toLowerCase()]['domain'] = oneEnvRec.deployer.manual.nodes;
										}
										else {
											response[oneEnvRec.code.toLowerCase()]['domain'] = oneEnvRec.apiPrefix + "." + oneEnvRec.domain;
										}
									});
									//grab the list of tenant that have ext key in requested env and return tenant code, package nad key as part of response
									helpers.getTenants(soajs, response, BL.model, function (error) {
										checkReturnError(soajs, cbMain, { config: config, error: error }, function () {
											return cbMain(null, response);
										});
									});
								});
							});
						});
					});
				});
			});
		}
	},

	"listHAhostEnv": function (config, soajs, deployer, helpers, cbMain) {
		var output = {};

		//fetch the non sensitive environments only
		var opts = {
			"collection": "environment",
			"conditions": {
				"$or": [
					{
						"sensitive": { "$exists": false }
					},
					{
						"sensitive": false
					},
					{
						"sensitive": null
					}
				]
			}
		};
		BL.model.findEntries(soajs, opts, function (error, environments) {
			checkReturnError(soajs, cbMain, { config: config, error: error, code: 600 }, function () {
				if (!environments || environments.length === 0) {
					return cbMain(null, output);
				}

				async.each(environments, function (oneEnv, mCb) {
					//NOTE: need to get registry for environment, deployer depends on registry not environment record
					//NOTE: can't get registries without listing environments, no other way to get the list of available registries
					var options = helpers.buildDeployerOptions(oneEnv, soajs, BL.model);
					checkReturnError(soajs, cbMain, { config: config, error: !options, code: 825 }, function () {
						options.params = {
							env: oneEnv.code.toLowerCase()
						};
						let port;
						deployer.listServices(options, function (error, services) {
							checkReturnError(soajs, cbMain, { config: config, error: error }, function () {
								//loop in services and see if you find the one you want only
								for (var i = 0; i < services.length; i++) {
									var oneService = services[i];
									if (soajs.inputmaskData.service === oneService.labels["soajs.service.name"]) {
										if (!output[oneEnv.code.toLowerCase()]) {
											output[oneEnv.code.toLowerCase()] = {};
										}

										oneService.ports.forEach(function (onePort) {
											if (onePort.published) {
												port = onePort.published;
											}
										});

										if(oneEnv.domain === ''){
											let deployerInfo = oneEnv.deployer.selected.split(".");
											if(deployerInfo[1] === 'docker' && deployerInfo[2] === 'local'){
												output[oneEnv.code.toLowerCase()]['domain'] = "localhost";
											}
											else{
												if(oneEnv.deployer[deployerInfo[0]][deployerInfo[1]][deployerInfo[2]]){
													if(oneEnv.deployer[deployerInfo[0]][deployerInfo[1]][deployerInfo[2]].nodes && oneEnv.deployer[deployerInfo[0]][deployerInfo[1]][deployerInfo[2]].nodes !== ''){
														output[oneEnv.code.toLowerCase()]['domain'] = oneEnv.nodes;
													}
												}
											}
										}
										else{
											output[oneEnv.code.toLowerCase()]['domain'] = oneEnv.apiPrefix + "." + oneEnv.domain;
										}
										break;
									}
								}

								if(!port){
									services.forEach(function (oneService) {
										if (output[oneEnv.code.toLowerCase()] && oneService.labels['soajs.service.name'] === 'controller' && oneService.labels['soajs.env.code'] === oneEnv.code.toLowerCase()) {
											//todo: map domain to inner property
											oneService.ports.forEach(function (onePort) {
												if (onePort.published) {
													port = onePort.published;
												}
											});
										}
									});

									if(!port){
										if(process.env.SOAJS_SAAS && oneEnv.deployer && oneEnv.deployer.selected === 'container.kubernetes.remote'){
											if(oneEnv.deployer.container && oneEnv.deployer.container.kubernetes && oneEnv.deployer.container.kubernetes.remote && oneEnv.deployer.container.kubernetes.remote.nginxDeployType === 'LoadBalancer'){
												port = oneEnv.port;
											}
										}
										else{
											services.forEach(function (oneService) {
												if (output[oneEnv.code.toLowerCase()] && oneService.labels['soajs.service.group'] === 'soajs-nginx' && oneService.labels['soajs.env.code'] === oneEnv.code.toLowerCase()) {
													//todo: map domain to inner property
													oneService.ports.forEach(function (onePort) {
														if (onePort.published) {
															port = onePort.published;
														}
													});
												}
											});
										}
									}
								}

								if(output[oneEnv.code.toLowerCase()]){
									output[oneEnv.code.toLowerCase()]['domain'] += ":" + port;
								}
								return mCb(null, true);
							});
						});
					});
				}, function (error) {
					checkReturnError(soajs, cbMain, { config: config, error: error, code: 600 }, function () {
						//grab the list of tenant that have ext key in requested env and return tenant code, package nad key as part of response
						helpers.getTenants(soajs, output, BL.model, function (error) {
							checkReturnError(soajs, cbMain, { config: config, error: error }, function () {
								return cbMain(null, output);
							});
						});
					});
				});
			});
		});
	},

	"awareness": function (config, soajs, cbMain) {
		hostModel.getEnvironment(soajs, BL.model, soajs.inputmaskData.env, function (err, envRecord) {
			checkReturnError(soajs, cbMain, { config: config, error: err || !envRecord, code: 600 }, function () {
				hostModel.getControllers(soajs, BL.model, envRecord.code, function (err, controllers) {
					checkReturnError(soajs, cbMain, { config: config, error: err, code: 600 }, function () {
						return cbMain(null, controllers);
					});
				});
			});
		});
	}
};

module.exports = {
	"init": function (modelName, cb) {
		var modelPath;

		if (!modelName) {
			return cb(new Error("No Model Requested!"));
		}

		modelPath = __dirname + "/../../models/" + modelName + ".js";
		return requireModel(modelPath, cb);

		/**
		 * checks if model file exists, requires it and returns it.
		 * @param filePath
		 * @param cb
		 */
		function requireModel(filePath, cb) {
			//check if file exist. if not return error
			fs.exists(filePath, function (exists) {
				if (!exists) {
					return cb(new Error("Requested Model Not Found!"));
				}

				BL.model = require(filePath);
				return cb(null, BL);
			});
		}
	}
};
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
//  Copyright (C) 2014  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// Utilities
//============================================================================
IPython.namespace('IPython.security');

IPython.security = (function (IPython) {
    "use strict";

    var utils = IPython.utils;

    var noop = function (x) { return x; };

    var sanitize = function (html, log) {
        // sanitize HTML
        // returns a struct of
        // {
        //   src: original_html,
        //   sanitized: the_sanitized_html,
        //   safe: bool // false if the sanitizer made any changes
        // }
        var result = {
            src : html,
            safe : true
        };
        var record_messages = function (msg, opts) {
            console.log("HTML Sanitizer", msg, opts);
            result.safe = false;
        };
        result.sanitized = window.html_sanitize(html, noop, noop, record_messages);
        return result;
    };

    var sanitize_html = function (html) {
        // shorthand for str-to-str conversion, dropping the struct
        return sanitize(html).sanitized;
    };

    var is_safe = function (html) {
        // just return bool for whether an HTML string is safe
        return sanitize(html).safe;
    };

    return {
        is_safe: is_safe,
        sanitize: sanitize,
        sanitize_html: sanitize_html
    };

}(IPython));

<commit_msg>add cmp_tree, in case caja log can't be trusted<commit_after>//----------------------------------------------------------------------------
//  Copyright (C) 2014  The IPython Development Team
//
//  Distributed under the terms of the BSD License.  The full license is in
//  the file COPYING, distributed as part of this software.
//----------------------------------------------------------------------------

//============================================================================
// Utilities
//============================================================================
IPython.namespace('IPython.security');

IPython.security = (function (IPython) {
    "use strict";

    var utils = IPython.utils;

    var noop = function (x) { return x; };

    var cmp_tree = function (a, b) {
        // compare two HTML trees
        // only checks the tag structure is preserved,
        // not any attributes or contents
        if (a.length !== b.length) {
            return false;
        }

        for (var i = a.length - 1; i >= 0; i--) {
            if (a[i].tagName && b[i].tagName && a[i].tagName.toLowerCase() != b[i].tagName.toLowerCase()) {
                return false;
            }
        }
        var ac = a.children();
        var bc = b.children();
        if (ac.length === 0 && bc.length === 0) {
            return true;
        }
        return cmp_tree(ac, bc);
    };

    var sanitize = function (html, log) {
        // sanitize HTML
        // returns a struct of
        // {
        //   src: original_html,
        //   sanitized: the_sanitized_html,
        //   safe: bool // false if the sanitizer made any changes
        // }
        var result = {
            src : html,
            safe : true
        };
        var record_messages = function (msg, opts) {
            console.log("HTML Sanitizer", msg, opts);
            result.safe = false;
        };
        result.sanitized = window.html_sanitize(html, noop, noop, record_messages);
        // caja can strip whole elements without logging,
        // so double-check that node structure didn't change
        if (result.safe) {
            result.safe = cmp_tree($(result.sanitized), $(result.src));
        }
        return result;
    };

    var sanitize_html = function (html) {
        // shorthand for str-to-str conversion, dropping the struct
        return sanitize(html).sanitized;
    };

    var is_safe = function (html) {
        // just return bool for whether an HTML string is safe
        return sanitize(html).safe;
    };

    return {
        is_safe: is_safe,
        sanitize: sanitize,
        sanitize_html: sanitize_html
    };

}(IPython));

<|endoftext|>


<commit_before>'use strict';

require('../stanza/roster');

module.exports = function (client) {

    client.on('iq:set:roster', function (iq) {
        var allowed = {};
        allowed[''] = true;
        allowed[client.jid.bare] = true;
        allowed[client.jid.domain] = true;

        if (!allowed[iq.from.full]) {
            return client.sendIq(iq.errorReply({
                error: {
                    type: 'cancel',
                    condition: 'service-unavailable'
                }
            }));
        }

        client.emit('roster:update', iq);
        client.sendIq({
            id: iq.id,
            type: 'result'
        });
    });

    client.getRoster = function (cb) {
        var self = this;
        cb = cb || function () {};

        return client.sendIq({
            type: 'get',
            roster: {
                ver: self.config.rosterVer
            }
        }).then(function (resp) {
            var ver = resp.roster.ver;
            if (ver) {
                self.config.rosterVer = ver;
                self.emit('roster:ver', ver);
            }
            return resp;
        }).nodeify(cb);
    };

    client.updateRosterItem = function (item, cb) {
        return client.sendIq({
            type: 'set',
            roster: {
                items: [item]
            }
        }, cb);
    };

    client.removeRosterItem = function (jid, cb) {
        return client.updateRosterItem({jid: jid, subscription: 'remove'}, cb);
    };

    client.subscribe = function (jid) {
        client.sendPresence({type: 'subscribe', to: jid});
    };

    client.unsubscribe = function (jid) {
        client.sendPresence({type: 'unsubscribe', to: jid});
    };

    client.acceptSubscription = function (jid) {
        client.sendPresence({type: 'subscribed', to: jid});
    };

    client.denySubscription = function (jid) {
        client.sendPresence({type: 'unsubscribed', to: jid});
    };
};
<commit_msg>Empty iq roster result<commit_after>'use strict';

require('../stanza/roster');

module.exports = function (client) {

    client.on('iq:set:roster', function (iq) {
        var allowed = {};
        allowed[''] = true;
        allowed[client.jid.bare] = true;
        allowed[client.jid.domain] = true;

        if (!allowed[iq.from.full]) {
            return client.sendIq(iq.errorReply({
                error: {
                    type: 'cancel',
                    condition: 'service-unavailable'
                }
            }));
        }

        client.emit('roster:update', iq);
        client.sendIq({
            id: iq.id,
            type: 'result'
        });
    });

    client.getRoster = function (cb) {
        var self = this;
        cb = cb || function () {};

        return client.sendIq({
            type: 'get',
            roster: {
                ver: self.config.rosterVer
            }
        }).then(function (resp) {
            if (resp.roster) {
                var ver = resp.roster.ver;
                if (ver) {
                    self.config.rosterVer = ver;
                    self.emit('roster:ver', ver);
                }
            }
            return resp;
        }).nodeify(cb);
    };

    client.updateRosterItem = function (item, cb) {
        return client.sendIq({
            type: 'set',
            roster: {
                items: [item]
            }
        }, cb);
    };

    client.removeRosterItem = function (jid, cb) {
        return client.updateRosterItem({jid: jid, subscription: 'remove'}, cb);
    };

    client.subscribe = function (jid) {
        client.sendPresence({type: 'subscribe', to: jid});
    };

    client.unsubscribe = function (jid) {
        client.sendPresence({type: 'unsubscribe', to: jid});
    };

    client.acceptSubscription = function (jid) {
        client.sendPresence({type: 'subscribed', to: jid});
    };

    client.denySubscription = function (jid) {
        client.sendPresence({type: 'unsubscribed', to: jid});
    };
};
<|endoftext|>


<commit_before>var fs = require('fs'),
    util = require('util'),
    union = require('union'),
    ecstatic = require('ecstatic');

var HTTPServer = exports.HTTPServer = function (options) {
  options = options || {};

  if (options.root) {
    this.root = options.root;
  }
  else {
    try {
      fs.lstatSync('./public');
      this.root = './public';
    }
    catch (err) {
      this.root = './';
    }
  }

  if (options.headers) {
    this.headers = options.headers;
  }

  this.cache = options.cache || 3600; // in seconds.
  this.autoIndex = options.autoIndex !== false;
  this.server = union.createServer({
    before: [
      ecstatic(this.root, {
        autoIndex: this.autoIndex,
        cache: this.cache
      })
    ],
    headers: this.headers || {};
  });
};

HTTPServer.prototype.listen = function () {
  this.server.listen.apply(this.server, arguments);
};

HTTPServer.prototype.close = function () {
  return this.server.close();
};

exports.createServer = function (options) {
  return new HTTPServer(options);
};
<commit_msg>[fix] semicolon crazy fix<commit_after>var fs = require('fs'),
    util = require('util'),
    union = require('union'),
    ecstatic = require('ecstatic');

var HTTPServer = exports.HTTPServer = function (options) {
  options = options || {};

  if (options.root) {
    this.root = options.root;
  }
  else {
    try {
      fs.lstatSync('./public');
      this.root = './public';
    }
    catch (err) {
      this.root = './';
    }
  }

  if (options.headers) {
    this.headers = options.headers;
  }

  this.cache = options.cache || 3600; // in seconds.
  this.autoIndex = options.autoIndex !== false;
  this.server = union.createServer({
    before: [
      ecstatic(this.root, {
        autoIndex: this.autoIndex,
        cache: this.cache
      })
    ],
    headers: this.headers || {}
  });
};

HTTPServer.prototype.listen = function () {
  this.server.listen.apply(this.server, arguments);
};

HTTPServer.prototype.close = function () {
  return this.server.close();
};

exports.createServer = function (options) {
  return new HTTPServer(options);
};
<|endoftext|>


<commit_before>const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
const logger = require('../logger').policy;
const schemas = require('../schemas');

const register = (policy) => {
  const { name, schema } = policy;
  const action = policy.policy;

  const validate = schemas.register('policy', name, schema);

  policy.policy = (params, ...args) => {
    const validationResult = validate(params);
    if (validationResult.isValid) {
      return action(params, ...args);
    } else {
      logger.error(`Policy ${chalk.default.red.bold(name)} params validation failed: ${validationResult.error}`);
      throw new Error(`POLICY_PARAMS_VALIDATION_FAILED`);
    }
  };

  policies[name] = policy;
};

const resolve = (policyName) => {
  const policy = policies[policyName];

  if (!policy) {
    logger.error(`Could not find policy ${policyName}, Please make sure the plugins providing such policy
     is correctly configured in system.config file.`);
    throw new Error('POLICY_NOT_FOUND');
  }

  return policy;
};

const policies = {};

schemas.register('internal', 'baseAuth', {
  $id: 'http://express-gateway.io/schemas/base/auth.json',
  type: 'object',
  properties: {
    passThrough: {
      type: 'boolean',
      default: false,
      description: 'Specify whether continue with pipeline processing in case the authentication fails'
    }
  },
  required: ['passThrough']
});

const policyNames = fs
  .readdirSync(path.resolve(__dirname))
  .filter(dir => fs.lstatSync(path.resolve(__dirname, dir)).isDirectory());

policyNames.forEach((name) => {
  const policy = require(path.resolve(__dirname, name));
  policies[name] = Object.assign(policy, { name });
  register(policy);
});

module.exports = { register, resolve };
<commit_msg>Expose loaded policies<commit_after>const fs = require('fs');
const chalk = require('chalk');
const path = require('path');
const logger = require('../logger').policy;
const schemas = require('../schemas');

const register = (policy) => {
  const { name, schema } = policy;
  const action = policy.policy;

  const validate = schemas.register('policy', name, schema);

  policy.policy = (params, ...args) => {
    const validationResult = validate(params);
    if (validationResult.isValid) {
      return action(params, ...args);
    } else {
      logger.error(`Policy ${chalk.default.red.bold(name)} params validation failed: ${validationResult.error}`);
      throw new Error(`POLICY_PARAMS_VALIDATION_FAILED`);
    }
  };

  policies[name] = policy;
};

const resolve = (policyName) => {
  const policy = policies[policyName];

  if (!policy) {
    logger.error(`Could not find policy ${policyName}, Please make sure the plugins providing such policy
     is correctly configured in system.config file.`);
    throw new Error('POLICY_NOT_FOUND');
  }

  return policy;
};

const policies = {};

schemas.register('internal', 'baseAuth', {
  $id: 'http://express-gateway.io/schemas/base/auth.json',
  type: 'object',
  properties: {
    passThrough: {
      type: 'boolean',
      default: false,
      description: 'Specify whether continue with pipeline processing in case the authentication fails'
    }
  },
  required: ['passThrough']
});

const policyNames = fs
  .readdirSync(path.resolve(__dirname))
  .filter(dir => fs.lstatSync(path.resolve(__dirname, dir)).isDirectory());

policyNames.forEach((name) => {
  const policy = require(path.resolve(__dirname, name));
  policies[name] = Object.assign(policy, { name });
  register(policy);
});

module.exports = { register, resolve, policies };
<|endoftext|>


<commit_before>// Copyright (c) 2011, Centrum Cyfrowe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Centrum Cyfrowe nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

var _gui = (function () {

// P U B L I C   I N T E R F A C E
    var that = {};

    that.init_gui = function () {
        $('#table-tab').click( function () {
            $('#table-container').show();
            $('#download-container').hide();
            $('#permalink-container').hide();

            $('#tabs')
                .find('div')
                .removeClass('active')
                .addClass('inactive');

            $(this)
                .addClass('active')
                .removeClass('inactive');
        });
        $('#download-tab').click( function () {
            var html = [];

            $('.snapshot').each( function () {
                var id = $(this).attr('id').split('-');
                var group = id[1];
                var sheet = id[2];
                var name = $(this).attr('title');

                html.push( '
' );
                html.push( '' );
                html.push( '<input type="checkbox" ');
                html.push( 'id="', ( group + '-' + sheet ));
                html.push( '" />	' );
                html.push( '' );
                html.push( '<input type="radio" name="scope-', group, '-', sheet );
                html.push( '" value="sheet" checked />' )
                html.push( '	' );
                html.push( '	' );
                html.push( '' );
                if( sheet === '0' ) {
                    html.push( '<input type="radio" name="scope-', group, '-', sheet );
                    html.push( '" value="full" />' )
                }
                html.push( '	' );
                html.push( '' );
                html.push( sheet === '0' ? name : ( ' > ' + name ));
                html.push( '	' );
                html.push( '
' );
            });

            $('.radio > input').attr( 'disabled', 'true' );
            $('#download-table > tbody').append( html.join('') );

            $('#table-container').hide();
            $('#download-container').show();
            $('#permalink-container').hide();

            $('#tabs')
                .find('div')
                .removeClass('active')
                .addClass('inactive');

            $(this)
                .addClass('active')
                .removeClass('inactive');
        });
        $('#permalink-tab').click( function () {
            $('#table-container').hide();
            $('#download-container').hide();
            $('#permalink-container').show();

            $('#tabs')
                .find('div')
                .removeClass('active')
                .addClass('inactive');

            $(this)
                .addClass('active')
                .removeClass('inactive');
        });
        $('#download-button').click( _download.current_sheet );

        $('#download-container').find('.radio > input').attr( 'disabled', 'true' );
        $('#download-container').find('.check > input').change( function () {
            var radios = $('#download-container').find('.radio > input');
            if( $(this).attr('checked') ) {
                radios.removeAttr( 'disabled' );
            }
            else {
                radios.attr( 'disabled', 'true' );
            }
        });
        _tools.prepare_tools();

        // arm open/close button and hide it!
        $('#open-close-choose-panel')
            .click( function () {
                // if choose panel is open
                if( $('#choose-panel:visible').length > 0 ) {
                    hide_choose_panel();
                }
                else {
                    show_choose_panel();
                }
            });

        // arm back-to-datasets button
        $('#back-to-datasets')
            .hover(
                function () {
                    $(this)
                        .attr( 'src', '/site_media/img/datasets_over.png' )
                        .css('cursor', 'pointer');
                },
                function () {
                    $(this).attr( 'src', '/site_media/img/datasets.png' );
                }
            )
            .click( function () {
                $('#info-title')
                    .html('Dostępne kolekcje');
                $('#info-text')
                    .html('Wybierz jedną z dostępnych kolekcji danych.');

                $(this)
                    .hide();
                $('#choose-perspectives')
                    .hide();
                $('#choose-datasets')
                    .show();

                // clear the perspectives list
                $('#choose-perspectives')
                    .html('');
            });

        init_choose_panel();
    };

    // used once when some perspective is chosen for the very first time
    that.init_app = function ( collection_name ) {
        $('#open-close-choose-panel')
            .show();

        that.create_sheet_tab({
            // TODO move name from func arg to store!!
            name: collection_name,
            group_nr: _store.active_group_index(),
            sheet_nr: _store.active_sheet_index()
        });

        $('#application').show();
        that.make_zebra();
        hide_choose_panel();
    }

    that.create_sheet_tab = function ( args ) {
        var html = [];

        var group_nr = args.group_nr || _store.active_group_index();
        var sheet_nr = args.sheet_nr || _store.active_sheet_index();
        var sheet_name = args.name || "Arkusz " + group_nr + '-' + sheet_nr;
        var filtered_sheet = args.filtered_sheet;

        var group_changed = _store.active_group_index() !== group_nr;
        var sheet_changed = _store.active_sheet_index() !== sheet_nr;
        var new_tab;

        html.push( '
' );
        html.push( sheet_name.length > 13 ?
                   sheet_name.slice( 0, 10 ) + '...' :
                   sheet_name );
        html.push( '
' );

        new_tab = $( html.join('') );

        $('.snapshot').removeClass('active');
        new_tab
            .addClass( 'active' )
            .click( function () {
                var id_elements = $(this).attr('id').split('-');
                var group_nr = id_elements[1];
                var sheet_nr = id_elements[2];

                $('.snapshot').removeClass('active');
                $(this).addClass('active');

                _store.active_group( group_nr );
                _store.active_sheet( sheet_nr );

                _table.clean_table();
                _table.init_table();
            });

        if( sheet_nr === 0 ) {
            new_tab.insertBefore( '#save-snapshot' );
        }
        else {
            new_tab.insertAfter( '#snap-'+group_nr+'-'+(sheet_nr-1));
        }

        if( $('.snapshot').length == 10 ) {
            $('#save-snapshot' ).hide();
        }

        _store.active_sheet( sheet_nr );
        _store.active_group( group_nr );

        _table.clean_table();
        _table.init_table( filtered_sheet );
    };

    that.make_zebra = function () {
        $('tbody > tr').not(':hidden').each( function ( i ) {
            if( i % 2 === 0 ) {
                $(this).removeClass( 'odd' );

                $(this).addClass( 'even' );
            }
            else {
                $(this).removeClass( 'even' );
                $(this).addClass( 'odd' );
            }
        });
    };

    that.highlight_node = function () {
        var a_root = $('tr[data-selected="true"]');
        // next a-level node
        var a_root_index = parseInt( a_root.attr( 'data-index' ), 10 );
        var next = $('tr[data-index='+ (a_root_index + 1) +']');

        if( a_root.length === 0 ) {
            // nothing found - nothing to do
            return;
        }
        else {
            // jquery returns a list of objects even for single entity
            a_root = a_root[0];
        }

        a_root
            .siblings()
//            .not(':hidden')
            .addClass('dim');

        // make a-root background black
        $('tr.root').removeClass('root');
        a_root.addClass('root');

        // highlight the subtree
        _utils.with_subtree( a_root.attr('id'), function () {
            // uses 'this' instead of '$(this)' for fun.call reason
            this.removeClass( 'dim' );
        });

        // add the bottom border
        $('.next').removeClass('next');
        next.addClass('next');

//        that.make_zebra();
    }

    return that;

// P R I V A T E   I N T E R F A C E
    function show_choose_panel() {
        $('#choose-panel')
            .slideDown( 400 );

        $('#application')
            .animate({ opacity: 0.25 }, 300 );

        $('#open-close-choose-panel')
            .html('zwiń');
    }

    function hide_choose_panel() {
        $('#choose-panel')
            .slideUp( 400 );

        $('#application')
            .animate({ opacity: 1 }, 300 );

        $('#open-close-choose-panel')
            .html('zmień dane');
    };

    function init_choose_panel() {
        var i;
        var html = [];
        var datasets = _store.meta_datasets();
        var len = datasets.length;
        var mid = len % 2 === 0 ? Math.floor( len / 2 )-1 : Math.floor( len / 2 );

        html.push( '
' );
        for( i = 0; i < len; i += 1 ) {
            html.push( '
' );
            html.push( '
' );
            html.push( datasets[i]['name'] );
            html.push( '
' );
            html.push( '
' );
            html.push( datasets[i]['description'] );
            html.push( '
' );
            html.push( '
Zobacz dane
' );
            html.push( '
' );

            if( i === mid ) {
                html.push( '

' );
            }
        }
        html.push( '
' );
        $('#choose-datasets')
            .append( $( html.join('') ))
            .find( '.position' )
            .find( '.more' )
            .click( function () {
                var dataset_id = $(this).parent().attr( 'data-set-id' );

                create_perspectives_panel( dataset_id );

                $('#choose-datasets')
                    .hide();
            });
    };

    function create_perspectives_panel( dataset_id ) {
        var i, j;
        var html = [];
        var perspectives = _store.meta_perspectives( dataset_id );
        var len = perspectives.length;
        var mid = len % 2 === 0 ? Math.floor( len / 2 )-1 : Math.floor( len / 2 );
        var issues;
        var name;

        html.push( '
' );
        for( i = 0; i < len; i += 1 ) {
            issues = perspectives[i]['issues'];

            html.push( '
' );
            html.push( '
' );
            html.push( perspectives[i]['name'] );
            html.push( '
' );
            html.push( '
' );
            html.push( perspectives[i]['description'] );
            html.push( '
' );
            // iterates in revers order because of CSS "float: right"
            for( j = issues.length-1; j >= 0; j -= 1 ) {
                html.push( '
' );
                html.push( issues[j] );
                html.push( '
' );
            }
            html.push( '
Zobacz dane:
' );
            html.push( '
' );

            if( i === mid ) {
                html.push( '

' );
            }
        }
        html.push( '
' );

        $('#info-title')
            // TODO interface this call!!!
            .html( _store.meta_datasets()[ dataset_id ]['name'] );
        $('#info-text')
            .html('Wybierz jedno z wydań danych.');

        $('#back-to-datasets')
            .show();

        $('#choose-perspectives')
            .append( $( html.join('') ))
            .show()
            .find( '.position' )
            .find( '.more' )
            .click( function () {
                var col_id = {
                    dataset: $(this).parent().attr( 'data-set-id' ),
                    perspective: $(this).parent().attr( 'data-per-id' ),
                    issue: $(this).attr( 'data-issue' )
                };

                // if new group is created, get data and show table
                if( _store.create_new_group( col_id ) ) {
                    // get top-level data from db
                    _db.get_init_data();
                }
                else {
                    // go back to application with focus on requested sheet
                    hide_choose_panel();
                }
            });
    };

})();
<commit_msg>Download table checkboxes active<commit_after>// Copyright (c) 2011, Centrum Cyfrowe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Centrum Cyfrowe nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

var _gui = (function () {

// P U B L I C   I N T E R F A C E
    var that = {};

    that.init_gui = function () {
        $('#table-tab').click( function () {
            $('#table-container').show();
            $('#download-container').hide();
            $('#permalink-container').hide();

            $('#tabs')
                .find('div')
                .removeClass('active')
                .addClass('inactive');

            $(this)
                .addClass('active')
                .removeClass('inactive');
        });
        $('#download-tab').click( function () {
            var html = [];

            $('.snapshot').each( function () {
                var id = $(this).attr('id').split('-');
                var group = id[1];
                var sheet = id[2];
                var name = $(this).attr('title');

                html.push( '
' );
                html.push( '' );
                html.push( '<input type="checkbox" ');
                html.push( 'id="', ( group + '-' + sheet ));
                html.push( '" />	' );
                html.push( '' );
                html.push( '<input type="radio" name="scope-', group, '-', sheet );
                html.push( '" value="sheet" checked />' )
                html.push( '	' );
                html.push( '	' );
                html.push( '' );
                if( sheet === '0' ) {
                    html.push( '<input type="radio" name="scope-', group, '-', sheet );
                    html.push( '" value="full" />' )
                }
                html.push( '	' );
                html.push( '' );
                html.push( sheet === '0' ? name : ( ' > ' + name ));
                html.push( '	' );
                html.push( '
' );
            });
            $('#download-table > tbody').append( html.join('') );

            $('#download-table .radio > input').attr( 'disabled', 'true' );
            $('#download-table .checkbox > input' ).change( function () {
                if( $(this).attr('checked') ) {
                    $(this).parent().find('.radio > input').removeAttr('disabled');
                }
                else {
                    $(this).parent().find('.radio > input').attr('disabled', 'true');
                }
            });

            $('#table-container').hide();
            $('#download-container').show();
            $('#permalink-container').hide();

            $('#tabs')
                .find('div')
                .removeClass('active')
                .addClass('inactive');

            $(this)
                .addClass('active')
                .removeClass('inactive');
        });
        $('#permalink-tab').click( function () {
            $('#table-container').hide();
            $('#download-container').hide();
            $('#permalink-container').show();

            $('#tabs')
                .find('div')
                .removeClass('active')
                .addClass('inactive');

            $(this)
                .addClass('active')
                .removeClass('inactive');
        });
        $('#download-button').click( _download.current_sheet );

        $('#download-container').find('.radio > input').attr( 'disabled', 'true' );
        $('#download-container').find('.check > input').change( function () {
            var radios = $('#download-container').find('.radio > input');
            if( $(this).attr('checked') ) {
                radios.removeAttr( 'disabled' );
            }
            else {
                radios.attr( 'disabled', 'true' );
            }
        });
        _tools.prepare_tools();

        // arm open/close button and hide it!
        $('#open-close-choose-panel')
            .click( function () {
                // if choose panel is open
                if( $('#choose-panel:visible').length > 0 ) {
                    hide_choose_panel();
                }
                else {
                    show_choose_panel();
                }
            });

        // arm back-to-datasets button
        $('#back-to-datasets')
            .hover(
                function () {
                    $(this)
                        .attr( 'src', '/site_media/img/datasets_over.png' )
                        .css('cursor', 'pointer');
                },
                function () {
                    $(this).attr( 'src', '/site_media/img/datasets.png' );
                }
            )
            .click( function () {
                $('#info-title')
                    .html('Dostępne kolekcje');
                $('#info-text')
                    .html('Wybierz jedną z dostępnych kolekcji danych.');

                $(this)
                    .hide();
                $('#choose-perspectives')
                    .hide();
                $('#choose-datasets')
                    .show();

                // clear the perspectives list
                $('#choose-perspectives')
                    .html('');
            });

        init_choose_panel();
    };

    // used once when some perspective is chosen for the very first time
    that.init_app = function ( collection_name ) {
        $('#open-close-choose-panel')
            .show();

        that.create_sheet_tab({
            // TODO move name from func arg to store!!
            name: collection_name,
            group_nr: _store.active_group_index(),
            sheet_nr: _store.active_sheet_index()
        });

        $('#application').show();
        that.make_zebra();
        hide_choose_panel();
    }

    that.create_sheet_tab = function ( args ) {
        var html = [];

        var group_nr = args.group_nr || _store.active_group_index();
        var sheet_nr = args.sheet_nr || _store.active_sheet_index();
        var sheet_name = args.name || "Arkusz " + group_nr + '-' + sheet_nr;
        var filtered_sheet = args.filtered_sheet;

        var group_changed = _store.active_group_index() !== group_nr;
        var sheet_changed = _store.active_sheet_index() !== sheet_nr;
        var new_tab;

        html.push( '
' );
        html.push( sheet_name.length > 13 ?
                   sheet_name.slice( 0, 10 ) + '...' :
                   sheet_name );
        html.push( '
' );

        new_tab = $( html.join('') );

        $('.snapshot').removeClass('active');
        new_tab
            .addClass( 'active' )
            .click( function () {
                var id_elements = $(this).attr('id').split('-');
                var group_nr = id_elements[1];
                var sheet_nr = id_elements[2];

                $('.snapshot').removeClass('active');
                $(this).addClass('active');

                _store.active_group( group_nr );
                _store.active_sheet( sheet_nr );

                _table.clean_table();
                _table.init_table();
            });

        if( sheet_nr === 0 ) {
            new_tab.insertBefore( '#save-snapshot' );
        }
        else {
            new_tab.insertAfter( '#snap-'+group_nr+'-'+(sheet_nr-1));
        }

        if( $('.snapshot').length == 10 ) {
            $('#save-snapshot' ).hide();
        }

        _store.active_sheet( sheet_nr );
        _store.active_group( group_nr );

        _table.clean_table();
        _table.init_table( filtered_sheet );
    };

    that.make_zebra = function () {
        $('tbody > tr').not(':hidden').each( function ( i ) {
            if( i % 2 === 0 ) {
                $(this).removeClass( 'odd' );

                $(this).addClass( 'even' );
            }
            else {
                $(this).removeClass( 'even' );
                $(this).addClass( 'odd' );
            }
        });
    };

    that.highlight_node = function () {
        var a_root = $('tr[data-selected="true"]');
        // next a-level node
        var a_root_index = parseInt( a_root.attr( 'data-index' ), 10 );
        var next = $('tr[data-index='+ (a_root_index + 1) +']');

        if( a_root.length === 0 ) {
            // nothing found - nothing to do
            return;
        }
        else {
            // jquery returns a list of objects even for single entity
            a_root = a_root[0];
        }

        a_root
            .siblings()
//            .not(':hidden')
            .addClass('dim');

        // make a-root background black
        $('tr.root').removeClass('root');
        a_root.addClass('root');

        // highlight the subtree
        _utils.with_subtree( a_root.attr('id'), function () {
            // uses 'this' instead of '$(this)' for fun.call reason
            this.removeClass( 'dim' );
        });

        // add the bottom border
        $('.next').removeClass('next');
        next.addClass('next');

//        that.make_zebra();
    }

    return that;

// P R I V A T E   I N T E R F A C E
    function show_choose_panel() {
        $('#choose-panel')
            .slideDown( 400 );

        $('#application')
            .animate({ opacity: 0.25 }, 300 );

        $('#open-close-choose-panel')
            .html('zwiń');
    }

    function hide_choose_panel() {
        $('#choose-panel')
            .slideUp( 400 );

        $('#application')
            .animate({ opacity: 1 }, 300 );

        $('#open-close-choose-panel')
            .html('zmień dane');
    };

    function init_choose_panel() {
        var i;
        var html = [];
        var datasets = _store.meta_datasets();
        var len = datasets.length;
        var mid = len % 2 === 0 ? Math.floor( len / 2 )-1 : Math.floor( len / 2 );

        html.push( '
' );
        for( i = 0; i < len; i += 1 ) {
            html.push( '
' );
            html.push( '
' );
            html.push( datasets[i]['name'] );
            html.push( '
' );
            html.push( '
' );
            html.push( datasets[i]['description'] );
            html.push( '
' );
            html.push( '
Zobacz dane
' );
            html.push( '
' );

            if( i === mid ) {
                html.push( '

' );
            }
        }
        html.push( '
' );
        $('#choose-datasets')
            .append( $( html.join('') ))
            .find( '.position' )
            .find( '.more' )
            .click( function () {
                var dataset_id = $(this).parent().attr( 'data-set-id' );

                create_perspectives_panel( dataset_id );

                $('#choose-datasets')
                    .hide();
            });
    };

    function create_perspectives_panel( dataset_id ) {
        var i, j;
        var html = [];
        var perspectives = _store.meta_perspectives( dataset_id );
        var len = perspectives.length;
        var mid = len % 2 === 0 ? Math.floor( len / 2 )-1 : Math.floor( len / 2 );
        var issues;
        var name;

        html.push( '
' );
        for( i = 0; i < len; i += 1 ) {
            issues = perspectives[i]['issues'];

            html.push( '
' );
            html.push( '
' );
            html.push( perspectives[i]['name'] );
            html.push( '
' );
            html.push( '
' );
            html.push( perspectives[i]['description'] );
            html.push( '
' );
            // iterates in revers order because of CSS "float: right"
            for( j = issues.length-1; j >= 0; j -= 1 ) {
                html.push( '
' );
                html.push( issues[j] );
                html.push( '
' );
            }
            html.push( '
Zobacz dane:
' );
            html.push( '
' );

            if( i === mid ) {
                html.push( '

' );
            }
        }
        html.push( '
' );

        $('#info-title')
            // TODO interface this call!!!
            .html( _store.meta_datasets()[ dataset_id ]['name'] );
        $('#info-text')
            .html('Wybierz jedno z wydań danych.');

        $('#back-to-datasets')
            .show();

        $('#choose-perspectives')
            .append( $( html.join('') ))
            .show()
            .find( '.position' )
            .find( '.more' )
            .click( function () {
                var col_id = {
                    dataset: $(this).parent().attr( 'data-set-id' ),
                    perspective: $(this).parent().attr( 'data-per-id' ),
                    issue: $(this).attr( 'data-issue' )
                };

                // if new group is created, get data and show table
                if( _store.create_new_group( col_id ) ) {
                    // get top-level data from db
                    _db.get_init_data();
                }
                else {
                    // go back to application with focus on requested sheet
                    hide_choose_panel();
                }
            });
    };

})();
<|endoftext|>


<commit_before>Meteor.subscribe('users');
Meteor.subscribe('tags');
Meteor.subscribe('elements');

Users = new Meteor.Collection('users');
Tags = new Meteor.Collection('tags');
Elements = new Meteor.Collection('elements');<commit_msg>Geolocation initial code<commit_after>Meteor.subscribe('users');
Meteor.subscribe('tags');
Meteor.subscribe('elements');

Users = new Meteor.Collection('users');
Tags = new Meteor.Collection('tags');
Elements = new Meteor.Collection('elements');

function showError(error) {
  switch(error.code) {
    case error.PERMISSION_DENIED:
      alert("Permesso negato")
      break;
    case error.POSITION_UNAVAILABLE:
      alert("Informazione non disponibile");
      break;
    case error.TIMEOUT:
      alert("Timeout");
      break;
    case error.UNKNOWN_ERROR:
      alert("Impossibile localizzarti");
      break;
  }
}

function sendLocation(position) {
  Elements.insert({
    latitude:position.latitude,
    longitude:position.longitude,
    accuracy:position.accuracy,
  });
}

if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(sendLocation, showError);
} else {
    alert("Il tuo browser non supporta la geolocalizzazione");
}<|endoftext|>


<commit_before>(function() {
    /**
     * iframeの子側のスクリプト
     * iframeのIDを受信した後、iframeのコンテンツ内の高さを送信する
     * @constructor
     */
    var FrameSender = function() {
        var self = this;
        this._receiveHandler = function(e) {
            self.receive(e.data);
        };
        window.addEventListener('message', this._receiveHandler);
    };
    FrameSender.prototype = {
        /**
         * messageを受信した時の処理
         * @param data
         */
        receive: function(data) {
            var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
            if (typeof target != "undefined" && document.body.scrollHeight) {
                target.postMessage({
                    id: data.id,
                    height: document.body.scrollHeight
                },'*');
            }
        },
        send: function() {
            if(!window.frameElement) return;
            var id = window.frameElement.id;
            if (!id) return;
            this.receive({id:id});
        }
    };
    window.FrameSender = new FrameSender();
})();<commit_msg>可変リサイズが正しく動作しない不具合の<commit_after>(function() {
    /**
     * iframeの子側のスクリプト
     * iframeのIDを受信した後、iframeのコンテンツ内の高さを送信する
     * @constructor
     */
    var FrameSender = function() {
        var self = this;
        this._receiveHandler = function(e) {
            self.receive(e.data);
        };
        window.addEventListener('message', this._receiveHandler);
    };
    FrameSender.prototype = {
        /**
         * messageを受信した時の処理
         * @param data
         */
        receive: function(data) {
            var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);
            if (typeof target != "undefined" && document.body.offsetHeight) {
                target.postMessage({
                    id: data.id,
                    height: document.body.offsetHeight
                },'*');
            }
        },
        send: function() {
            if(!window.frameElement) return;
            var id = window.frameElement.id;
            if (!id) return;
            this.receive({id:id});
        }
    };
    window.FrameSender = new FrameSender();
})();<|endoftext|>


<commit_before>'use strict';

module.exports = function HandleUsingProcess(grunt, options, commands, callback) {

    var fs = require('fs');
    var version = grunt.file.readJSON('./package.json').version;
    var projectPkg = grunt.file.readJSON('package.json');
    var spawn = require('child_process').spawn;
    var _ = require('underscore');
    var commondir = require('commondir');

    var WIN32_BIN_PATH = 'node_modules\\.bin\\cucumber-js.cmd';
    var UNIX_BIN_PATH = 'node_modules/cucumber/bin/cucumber.js';

    var buffer = [];
    var cucumber;
    var binPath = '';

    if (process.platform === 'win32') {
        binPath = WIN32_BIN_PATH;
    } else {
        binPath = UNIX_BIN_PATH;
    }

    if (!grunt.file.exists(binPath)) {
        grunt.log.error('cucumberjs binary not found at path ' + binPath + '\n NOTE: You cannot install grunt-cucumberjs without bin links on windows');
        return callback(false);
    }

    cucumber = spawn(binPath, commands);

    cucumber.stdout.on('data', function(data) {
        if (options.format === 'html') {
            if (options.debug) {
                process.stdout.write(data);
            }
            buffer.push(data);
        } else {
            grunt.log.write(data);
        }
    });

    cucumber.stderr.on('data', function(data) {
        if (options.debug) {
            process.stdout.write(data);
        }
        var stderr = new Buffer(data);
        grunt.log.error(stderr.toString());
    });

    cucumber.on('close', function(code) {
        if (options.format === 'html') {
            var featureJsonOutput;

            var output = Buffer.concat(buffer).toString();

            var featureStartIndex = output.search(/\[\s*{\s*\"id\"/g);

            var logOutput = output.substring(0, featureStartIndex - 1);

            var featureOutput = output.substring(featureStartIndex);

            try {
                //console.log('#####JSON output', featureOutput);
                featureJsonOutput = JSON.parse(featureOutput);
            } catch (e) {
                grunt.log.error('Unable to parse cucumberjs output into json.');

                return callback(false);
            }

            generateReport(featureJsonOutput, logOutput);
        }

        return callback(code);
    });

    /**
     * Adds passed/failed properties on features/scenarios
     *
     * @param {object} suite The test suite object
     */
    var setStats = function(suite) {
        var features = suite.features;
        var rootDir = commondir(_.pluck(features, 'uri'));
        var scrshotDir;
        if (options.output.lastIndexOf('/') > -1) {
            scrshotDir = options.output.substring(0, options.output.lastIndexOf('/')) + '/screenshot/';
        } else {
            scrshotDir = 'screenshot/';
        }
        features.forEach(function(feature) {
            feature.passed = 0;
            feature.failed = 0;
            feature.relativeFolder = feature.uri.slice(rootDir.length);

            if (!feature.elements) {
                return;
            }

            feature.elements.forEach(function(element) {
                element.passed = 0;
                element.failed = 0;
                element.notdefined = 0;
                element.skipped = 0;

                element.steps.forEach(function(step) {
                    if (step.embeddings !== undefined) {
                        var Base64 = require('js-base64').Base64;
                        step.embeddings.forEach(function (embedding) {
                            if (embedding.mime_type === "text/plain") {
                                if (!step.text) {
                                    step.text = Base64.decode(embedding.data)
                                } else {
                                    step.text = step.text.concat('
' + Base64.decode(embedding.data));
                        }
                            }else {
                                var stepData = step.embeddings[0],
                                    name = step.name && step.name.split(' ').join('_') || step.keyword.trim();
                                if (!fs.existsSync(scrshotDir)) {
                                    fs.mkdirSync(scrshotDir);
                                }
                                name = name + Math.round(Math.random() * 10000) + '.png'; //randomize the file name
                                var filename = scrshotDir + name;
                                fs.writeFile(filename, new Buffer(embedding.data, 'base64'), function (err) {
                                    if (err) {
                                        console.error('Error saving screenshot ' + filename); //asynchronously save screenshot
                                    }
                                });
                                step.image = 'screenshot/' + name;
                            }
                        });
                    }

                    if (!step.result) {
                        return 0;
                    }
                    if (step.result.status === 'passed') {
                        return element.passed++;
                    }
                    if (step.result.status === 'failed') {
                        return element.failed++;
                    }
                    if (step.result.status === 'undefined') {
                        return element.notdefined++;
                    }

                    element.skipped++;
                });

                if (element.failed > 0) {
                    return feature.failed++;
                }
                if (element.passed > 0) {
                    return feature.passed++;
                }
            });

            if (feature.failed > 0) {
                return suite.failed++;
            }
            if (feature.passed > 0) {
                return suite.passed++;
            }
        });

        suite.features = features;

        return suite;
    };

    /**
     * Returns the path of a template
     *
     * @param {string} name The template name
     */
    var getPath = function(name) {
        var path = 'node_modules/grunt-cucumberjs/templates/' + options.theme + '/' + name;
        // return the users custom template if it has been defined
        if (grunt.file.exists(options.templateDir + '/' + name)) {
            path = options.templateDir + '/' + name;
        }

        return path;
    };

    /**
     * Generate html report
     *
     * @param {object} featureOutput Features result object
     * @param {string} logOutput Contains any console statements captured during the test run
     */
    var generateReport = function(featureOutput, logOutput) {
        var suite = {
            name: projectPkg.name,
            features: featureOutput,
            passed: 0,
            failed: 0,
            logOutput: logOutput
        };

        suite = setStats(suite);

        if (options.saveJson) {
            grunt.file.write(options.output + '.json', JSON.stringify(featureOutput, null, '\t'));
        }
        grunt.file.write(
            options.output,
            _.template(grunt.file.read(getPath('index.tmpl')))({
                suite: suite,
                version: version,
                time: new Date(),
                features: _.template(grunt.file.read(getPath('features.tmpl')))({
                    suite: suite,
                    _: _
                }),
                styles: grunt.file.read(getPath('style.css')),
                script: grunt.file.read(getPath('script.js'))
            })
        );

        grunt.log.writeln('Generated ' + options.output + ' successfully.');
    };

};
<commit_msg>use parallel-cucumber bin for parallel executions<commit_after>'use strict';

module.exports = function HandleUsingProcess(grunt, options, commands, callback) {

    var fs = require('fs');
    var version = grunt.file.readJSON('./package.json').version;
    var projectPkg = grunt.file.readJSON('package.json');
    var spawn = require('child_process').spawn;
    var _ = require('underscore');
    var commondir = require('commondir');

    var WIN32_BIN_PATH,
		UNIX_BIN_PATH;

	if (options.executeParallel) {
		UNIX_BIN_PATH = 'node_modules/parallel-cucumber/bin/parallel-cucumber-js';
		WIN32_BIN_PATH = 'node_modules\\parallel-cucumber\\bin\\parallel-cucumber-js';
	} else {
		WIN32_BIN_PATH = 'node_modules\\.bin\\cucumber-js.cmd';
		UNIX_BIN_PATH = 'node_modules/cucumber/bin/cucumber.js';
	}

    var buffer = [];
    var cucumber;
    var binPath = '';

    if (process.platform === 'win32') {
        binPath = WIN32_BIN_PATH;
    } else {
        binPath = UNIX_BIN_PATH;
    }

    if (!grunt.file.exists(binPath)) {
		if(options.executeParallel) {
			grunt.log.error('parallel-cucumber-js binary not found at path ' + binPath + '\n NOTE: You cannot install grunt-cucumberjs without bin links on windows');
		} else {
			grunt.log.error('cucumberjs binary not found at path ' + binPath + '\n NOTE: You cannot install grunt-cucumberjs without bin links on windows');
		}
        return callback(false);
    }

    cucumber = spawn(binPath, commands);

    cucumber.stdout.on('data', function(data) {
        if (options.format === 'html') {
            if (options.debug) {
                process.stdout.write(data);
            }
            buffer.push(data);
        } else {
            grunt.log.write(data);
        }
    });

    cucumber.stderr.on('data', function(data) {
        if (options.debug) {
            process.stdout.write(data);
        }
        var stderr = new Buffer(data);
        grunt.log.error(stderr.toString());
    });

    cucumber.on('close', function(code) {
        if (options.format === 'html') {

			var featureJsonOutput,
				featureOutput;

			if (options.executeParallel) {
				featureOutput = JSON.stringify(require('jsonfile').readFileSync(options.output + '.json'));
			} else {
				var output = Buffer.concat(buffer).toString();

				var featureStartIndex = output.search(/\[\s*{\s*\"id\"/g);

				var logOutput = output.substring(0, featureStartIndex - 1);

				featureOutput = output.substring(featureStartIndex);
			}

            try {
				featureJsonOutput = JSON.parse(featureOutput);
            } catch (e) {
                grunt.log.error('Unable to parse cucumberjs output into json.');

                return callback(false);
            }

            generateReport(featureJsonOutput, logOutput);
        }

        return callback(code);
    });

    /**
     * Adds passed/failed properties on features/scenarios
     *
     * @param {object} suite The test suite object
     */
    var setStats = function(suite) {
        var features = suite.features;
        var rootDir = commondir(_.pluck(features, 'uri'));
        var scrshotDir;
        if (options.output.lastIndexOf('/') > -1) {
            scrshotDir = options.output.substring(0, options.output.lastIndexOf('/')) + '/screenshot/';
        } else {
            scrshotDir = 'screenshot/';
        }
        features.forEach(function(feature) {
            feature.passed = 0;
            feature.failed = 0;
            feature.relativeFolder = feature.uri.slice(rootDir.length);

            if (!feature.elements) {
                return;
            }

            feature.elements.forEach(function(element) {
                element.passed = 0;
                element.failed = 0;
                element.notdefined = 0;
                element.skipped = 0;

                element.steps.forEach(function(step) {
                    if (step.embeddings !== undefined) {
                        var Base64 = require('js-base64').Base64;
                        step.embeddings.forEach(function (embedding) {
                            if (embedding.mime_type === "text/plain") {
                                if (!step.text) {
                                    step.text = Base64.decode(embedding.data)
                                } else {
                                    step.text = step.text.concat('
' + Base64.decode(embedding.data));
                        }
                            }else {
                                var stepData = step.embeddings[0],
                                    name = step.name && step.name.split(' ').join('_') || step.keyword.trim();
                                if (!fs.existsSync(scrshotDir)) {
                                    fs.mkdirSync(scrshotDir);
                                }
                                name = name + Math.round(Math.random() * 10000) + '.png'; //randomize the file name
                                var filename = scrshotDir + name;
                                fs.writeFile(filename, new Buffer(embedding.data, 'base64'), function (err) {
                                    if (err) {
                                        console.error('Error saving screenshot ' + filename); //asynchronously save screenshot
                                    }
                                });
                                step.image = 'screenshot/' + name;
                            }
                        });
                    }

                    if (!step.result) {
                        return 0;
                    }
                    if (step.result.status === 'passed') {
                        return element.passed++;
                    }
                    if (step.result.status === 'failed') {
                        return element.failed++;
                    }
                    if (step.result.status === 'undefined') {
                        return element.notdefined++;
                    }

                    element.skipped++;
                });

                if (element.failed > 0) {
                    return feature.failed++;
                }
                if (element.passed > 0) {
                    return feature.passed++;
                }
            });

            if (feature.failed > 0) {
                return suite.failed++;
            }
            if (feature.passed > 0) {
                return suite.passed++;
            }
        });

        suite.features = features;

        return suite;
    };

    /**
     * Returns the path of a template
     *
     * @param {string} name The template name
     */
    var getPath = function(name) {
        var path = 'node_modules/grunt-cucumberjs/templates/' + options.theme + '/' + name;
        // return the users custom template if it has been defined
        if (grunt.file.exists(options.templateDir + '/' + name)) {
            path = options.templateDir + '/' + name;
        }

        return path;
    };

    /**
     * Generate html report
     *
     * @param {object} featureOutput Features result object
     * @param {string} logOutput Contains any console statements captured during the test run
     */
    var generateReport = function(featureOutput, logOutput) {
        var suite = {
            name: projectPkg.name,
            features: featureOutput,
            passed: 0,
            failed: 0,
            logOutput: logOutput
        };

        suite = setStats(suite);

        if (options.saveJson) {
            grunt.file.write(options.output + '.json', JSON.stringify(featureOutput, null, '\t'));
        }
        grunt.file.write(
            options.output,
            _.template(grunt.file.read(getPath('index.tmpl')))({
                suite: suite,
                version: version,
                time: new Date(),
                features: _.template(grunt.file.read(getPath('features.tmpl')))({
                    suite: suite,
                    _: _
                }),
                styles: grunt.file.read(getPath('style.css')),
                script: grunt.file.read(getPath('script.js'))
            })
        );

        grunt.log.writeln('Generated ' + options.output + ' successfully.');
    };

};
<|endoftext|>