<commit_before>var headers = { 'Content-Type': 'application/json' };

server = Bones.Server.extend({});

var options = {
    type: '.js',
    wrapper: Bones.utils.wrapClientFile,
    sort: Bones.utils.sortByLoadOrder
};

// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.assets = {
    vendor: new mirror([
        require.resolve('bones/assets/jquery'),
        require.resolve('underscore'),
        require.resolve('backbone')
    ], { type: '.js' }),
    core: new mirror([
        require.resolve('bones/shared/utils'),
        require.resolve('bones/client/utils'),
        require.resolve('bones/shared/backbone'),
        require.resolve('bones/client/backbone')
    ], { type: '.js' }),
    models: new mirror([], options),
    views: new mirror([], options),
    controllers: new mirror([], options),
    templates: new mirror([], options)
};

// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.assets.all = new mirror([
    server.prototype.assets.vendor,
    server.prototype.assets.core,
    server.prototype.assets.controllers,
    server.prototype.assets.models,
    server.prototype.assets.views,
    server.prototype.assets.templates
], { type: '.js' });

// Stores models, views served by this server.
// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.models = {};
server.prototype.views = {};

// Stores instances of controllers registered with this server.
// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.controllers = {};

server.prototype.initialize = function(app) {
    this.registerComponents(app);
    this.initializeAssets(app);
    this.initializeModels(app);
};

server.prototype.registerComponents = function(app) {
    var components = ['controllers', 'models', 'views', 'templates'];
    components.forEach(function(kind) {
        for (var name in app[kind]) {
            app[kind][name].register(this);
        }
    }, this);
};

server.prototype.initializeAssets = function(app) {
    this.get('/assets/bones/vendor.js', this.assets.vendor);
    this.get('/assets/bones/core.js', this.assets.core);
    this.get('/assets/bones/controllers.js', this.assets.controllers);
    this.get('/assets/bones/models.js', this.assets.models);
    this.get('/assets/bones/views.js', this.assets.views);
    this.get('/assets/bones/templates.js', this.assets.templates);

    this.get('/assets/bones/all.js', this.assets.all);
};

server.prototype.initializeModels = function(app) {
    this.models = app.models;
    _.bindAll(this, 'loadModel', 'getModel', 'saveModel', 'delModel', 'loadCollection');
    this.get('/api/:model/:id', this.loadModel, this.getModel);
    this.post('/api/:model', this.loadModel, this.saveModel);
    this.put('/api/:model/:id', this.loadModel, this.saveModel);
    this.del('/api/:model/:id', this.loadModel, this.delModel);
    this.get('/api/:collection', this.loadCollection.bind(this));
};

server.prototype.loadCollection = function(req, res, next) {
    var name = Bones.utils.pluralize(req.params.collection);
    if (name in this.models) {
        // Pass any querystring paramaters to the collection.
        req.collection = new this.models[name]([], req.query);
        req.collection.fetch({
            success: function(collection, resp) {
                res.send(collection, headers);
            },
            error: function(collection, err) {
                err = err instanceof Object ? err.toString() : err;
                next(new Error.HTTP(err, 500));
            }
        });
    } else {
        next();
    }
};

server.prototype.loadModel = function(req, res, next) {
    var name = req.params.model;
    if (name in this.models) {
        // Pass any querystring paramaters to the model.
        req.model = new this.models[name]({ id: req.params.id }, req.query);
    }
    next();
};

server.prototype.getModel = function(req, res, next) {
    if (!req.model) return next();
    req.model.fetch({
        success: function(model, resp) {
            res.send(model, headers);
        },
        error: function(model, err) {
            err = err instanceof Object ? err.toString() : err;
            next(new Error.HTTP(err, 404));
        }
    });
};

server.prototype.saveModel = function(req, res, next) {
    if (!req.model) return next();
    req.model.save(req.body, {
        success: function(model, resp) {
            res.send({}, headers);
        },
        error: function(model, err) {
            err = err instanceof Object ? err.toString() : err;
            next(new Error.HTTP(err, 409));
        }
    });
};

server.prototype.delModel = function(req, res, next) {
    if (!req.model) return next();
    req.model.destroy({
        success: function(model, resp) {
            res.send({}, headers);
        },
        error: function(model, err) {
            err = err instanceof Object ? err.toString() : err;
            next(new Error.HTTP(err, 409));
        }
    });
};
<commit_msg>Revert "don't send model when saving"<commit_after>var headers = { 'Content-Type': 'application/json' };

server = Bones.Server.extend({});

var options = {
    type: '.js',
    wrapper: Bones.utils.wrapClientFile,
    sort: Bones.utils.sortByLoadOrder
};

// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.assets = {
    vendor: new mirror([
        require.resolve('bones/assets/jquery'),
        require.resolve('underscore'),
        require.resolve('backbone')
    ], { type: '.js' }),
    core: new mirror([
        require.resolve('bones/shared/utils'),
        require.resolve('bones/client/utils'),
        require.resolve('bones/shared/backbone'),
        require.resolve('bones/client/backbone')
    ], { type: '.js' }),
    models: new mirror([], options),
    views: new mirror([], options),
    controllers: new mirror([], options),
    templates: new mirror([], options)
};

// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.assets.all = new mirror([
    server.prototype.assets.vendor,
    server.prototype.assets.core,
    server.prototype.assets.controllers,
    server.prototype.assets.models,
    server.prototype.assets.views,
    server.prototype.assets.templates
], { type: '.js' });

// Stores models, views served by this server.
// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.models = {};
server.prototype.views = {};

// Stores instances of controllers registered with this server.
// TODO for Bones 1.4: This should be moved to the initialize method!
server.prototype.controllers = {};

server.prototype.initialize = function(app) {
    this.registerComponents(app);
    this.initializeAssets(app);
    this.initializeModels(app);
};

server.prototype.registerComponents = function(app) {
    var components = ['controllers', 'models', 'views', 'templates'];
    components.forEach(function(kind) {
        for (var name in app[kind]) {
            app[kind][name].register(this);
        }
    }, this);
};

server.prototype.initializeAssets = function(app) {
    this.get('/assets/bones/vendor.js', this.assets.vendor);
    this.get('/assets/bones/core.js', this.assets.core);
    this.get('/assets/bones/controllers.js', this.assets.controllers);
    this.get('/assets/bones/models.js', this.assets.models);
    this.get('/assets/bones/views.js', this.assets.views);
    this.get('/assets/bones/templates.js', this.assets.templates);

    this.get('/assets/bones/all.js', this.assets.all);
};

server.prototype.initializeModels = function(app) {
    this.models = app.models;
    _.bindAll(this, 'loadModel', 'getModel', 'saveModel', 'delModel', 'loadCollection');
    this.get('/api/:model/:id', this.loadModel, this.getModel);
    this.post('/api/:model', this.loadModel, this.saveModel);
    this.put('/api/:model/:id', this.loadModel, this.saveModel);
    this.del('/api/:model/:id', this.loadModel, this.delModel);
    this.get('/api/:collection', this.loadCollection.bind(this));
};

server.prototype.loadCollection = function(req, res, next) {
    var name = Bones.utils.pluralize(req.params.collection);
    if (name in this.models) {
        // Pass any querystring paramaters to the collection.
        req.collection = new this.models[name]([], req.query);
        req.collection.fetch({
            success: function(collection, resp) {
                res.send(collection, headers);
            },
            error: function(collection, err) {
                err = err instanceof Object ? err.toString() : err;
                next(new Error.HTTP(err, 500));
            }
        });
    } else {
        next();
    }
};

server.prototype.loadModel = function(req, res, next) {
    var name = req.params.model;
    if (name in this.models) {
        // Pass any querystring paramaters to the model.
        req.model = new this.models[name]({ id: req.params.id }, req.query);
    }
    next();
};

server.prototype.getModel = function(req, res, next) {
    if (!req.model) return next();
    req.model.fetch({
        success: function(model, resp) {
            res.send(model, headers);
        },
        error: function(model, err) {
            err = err instanceof Object ? err.toString() : err;
            next(new Error.HTTP(err, 404));
        }
    });
};

server.prototype.saveModel = function(req, res, next) {
    if (!req.model) return next();
    req.model.save(req.body, {
        success: function(model, resp) {
            res.send(model, headers);
        },
        error: function(model, err) {
            err = err instanceof Object ? err.toString() : err;
            next(new Error.HTTP(err, 409));
        }
    });
};

server.prototype.delModel = function(req, res, next) {
    if (!req.model) return next();
    req.model.destroy({
        success: function(model, resp) {
            res.send({}, headers);
        },
        error: function(model, err) {
            err = err instanceof Object ? err.toString() : err;
            next(new Error.HTTP(err, 409));
        }
    });
};
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
 * Copyright (c) 2012, Thomas Tanghus <thomas@tanghus.net>
 * This file is licensed under the Affero General Public License version 3 or later.
 * See the COPYING-README file.
 */

OC.Settings = OC.Settings || {};
OC.Settings.Apps = OC.Settings.Apps || {
	loadApp:function(app) {
		var page = $('#app-content');
		page.find('p.license').show();
		page.find('span.name').text(app.name);
		page.find('small.externalapp').text(app.internallabel);
		if (app.version) {
			page.find('span.version').text(app.version);
		} else {
			page.find('span.version').text('');
		}
		page.find('span.score').html(app.score);
		page.find('p.description').text(app.description);
		page.find('img.preview').attr('src', app.preview);
		if (app.preview && app.preview.length) {
			page.find('img.preview').show();
		} else {
			page.find('img.preview').hide();
		}
		page.find('small.externalapp').attr('style', 'visibility:visible');
		page.find('span.author').text(app.author);

		// FIXME licenses of downloaded apps go into app.licence, licenses of not-downloaded apps into app.license
		var appLicense = '';
		if (typeof(app.licence) !== 'undefined') {
			appLicense = app.licence;
		} else if (typeof(app.license) !== 'undefined') {
			appLicense = app.license;
		}
		page.find('span.licence').text(appLicense);

		var userDocumentation = false;
		var adminDocumentation = false;
		if (typeof(app.documentation) !== 'undefined') {
			if (typeof(app.documentation.user) !== 'undefined') {
				userDocumentation = true;
				page.find('span.userDocumentation').html("" + t('settings', 'User Documentation') + "");
				page.find('p.documentation').show();
			}
			if (typeof(app.documentation.admin) !== 'undefined') {
				adminDocumentation = true;
				page.find('span.adminDocumentation').html("" + t('settings', 'Admin Documentation') + "");
				page.find('p.documentation').show();
			}

			if(userDocumentation && adminDocumentation) {
				page.find('span.userDocumentation').after(', ');
			}
		}

		if (typeof(app.website) !== 'undefined') {
			page.find('p.website').show();
			page.find('a#websitelink').attr('href', app.website);
		}

		if (app.update !== false) {
			page.find('input.update').show();
			page.find('input.update').data('appid', app.id);
			page.find('input.update').attr('value',t('settings', 'Update to {appversion}', {appversion:app.update}));
		} else {
			page.find('input.update').hide();
		}

		page.find('input.enable').show();
		page.find('input.enable').val((app.active) ? t('settings', 'Disable') : t('settings', 'Enable'));
		page.find('input.enable').data('appid', app.id);
		page.find('input.enable').data('active', app.active);
		if (app.internal === false) {
			page.find('span.score').show();
			page.find('p.appstore').show();
			page.find('a#appstorelink').attr('href', 'http://apps.owncloud.com/content/show.php?content=' + app.id);
			page.find('small.externalapp').hide();
		} else {
			page.find('p.appslink').hide();
			page.find('span.score').hide();
		}
		if (typeof($('#app-navigation ul li[data-id="'+app.id+'"]').data('errormsg')) !== "undefined") {
			page.find(".warning").show();
			page.find(".warning").text($('#app-navigation ul li[data-id="'+app.id+'"]').data('errormsg'));
		} else {
			page.find(".warning").hide();
		}

		page.find("div.multiselect").parent().remove();
		if(OC.Settings.Apps.isType(app, 'filesystem') || OC.Settings.Apps.isType(app, 'prelogin') ||
			OC.Settings.Apps.isType(app, 'authentication') || OC.Settings.Apps.isType(app, 'logging')) {
			page.find("#groups_enable").hide();
			page.find("label[for='groups_enable']").hide();
			page.find("#groups_enable").attr('checked', null);
		} else {
			$('#group_select > option').each(function (i, el) {
				if (app.groups.length === 0 || app.groups.indexOf(el.value) >= 0) {
					$(el).attr('selected', 'selected');
				} else {
					$(el).attr('selected', null);
				}
			});
			if (app.active) {
				if (app.groups.length) {
					$('#group_select').multiSelect();
					page.find("#groups_enable").attr('checked','checked');
				} else {
					page.find("#groups_enable").attr('checked', null);
				}
				page.find("#groups_enable").show();
				page.find("label[for='groups_enable']").show();
			} else {
				page.find("#groups_enable").hide();
				page.find("label[for='groups_enable']").hide();
			}
		}
	},
	enableApp:function(appid, active, element, groups) {
		groups = groups || [];
		var appitem=$('#app-navigation ul li[data-id="'+appid+'"]');
		element.val(t('settings','Please wait....'));
		if(active && !groups.length) {
			$.post(OC.filePath('settings','ajax','disableapp.php'),{appid:appid},function(result) {
				if(!result || result.status !== 'success') {
					if (result.data && result.data.message) {
						OC.Settings.Apps.showErrorMessage(result.data.message);
						appitem.data('errormsg', result.data.message);
					} else {
						OC.Settings.Apps.showErrorMessage(t('settings', 'Error while disabling app'));
						appitem.data('errormsg', t('settings', 'Error while disabling app'));
					}
					element.val(t('settings','Disable'));
					appitem.addClass('appwarning');
				}
				else {
					appitem.data('active',false);
					appitem.data('groups', '');
					element.data('active',false);
					OC.Settings.Apps.removeNavigation(appid);
					appitem.removeClass('active');
					element.val(t('settings','Enable'));
					element.parent().find("#groups_enable").hide();
					element.parent().find("label[for='groups_enable']").hide();
				}
			},'json');
		} else {
			$.post(OC.filePath('settings','ajax','enableapp.php'),{appid: appid, groups: groups},function(result) {
				if(!result || result.status !== 'success') {
					if (result.data && result.data.message) {
						OC.Settings.Apps.showErrorMessage(result.data.message);
						appitem.data('errormsg', result.data.message);
					} else {
						OC.Settings.Apps.showErrorMessage(t('settings', 'Error while enabling app'));
						appitem.data('errormsg', t('settings', 'Error while disabling app'));
					}
					element.val(t('settings','Enable'));
					appitem.addClass('appwarning');
				} else {
					OC.Settings.Apps.addNavigation(appid);
					appitem.data('active',true);
					element.data('active',true);
					appitem.addClass('active');
					element.val(t('settings','Disable'));
					element.parent().find("#groups_enable").show();
					element.parent().find("label[for='groups_enable']").show();
					if (groups) {
						appitem.data('groups', JSON.stringify(groups));
					} else {
						appitem.data('groups', '');
					}
				}
			},'json')
			.fail(function() {
				OC.Settings.Apps.showErrorMessage(t('settings', 'Error while enabling app'));
				appitem.data('errormsg', t('settings', 'Error while enabling app'));
				appitem.data('active',false);
				appitem.addClass('appwarning');
				OC.Settings.Apps.removeNavigation(appid);
				element.val(t('settings','Enable'));
			});
		}
	},
	updateApp:function(appid, element) {
		element.val(t('settings','Updating....'));
		$.post(OC.filePath('settings','ajax','updateapp.php'),{appid:appid},function(result) {
			if(!result || result.status !== 'success') {
				OC.Settings.Apps.showErrorMessage(t('settings','Error while updating app'),t('settings','Error'));
				element.val(t('settings','Update'));
			}
			else {
				element.val(t('settings','Updated'));
				element.hide();
			}
		},'json');
	},

	insertApp:function(appdata) {
		var applist = $('#app-navigation ul li');
		var app =
				$('
'
				+ ''
				+ appdata.name+'3rd party
');
		app.data('app', appdata);
		var added = false;
		applist.each(function() {
			if(!parseInt($(this).data('installed')) && $(this).find('a').text().toLowerCase() > appdata.name.toLowerCase()) {
				$(this).before(app);
				added = true;
				return false; // dang, remember this to get out of loop
			}
		});
		if(!added) {
			applist.last().after(app);
		}
		return app;
	},
	removeNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navIds=response.nav_ids;
				for(var i=0; i< navIds.length; i++){
					$('#apps .wrapper').children('li[data-id="'+navIds[i]+'"]').remove();
				}
			}
		});
	},
	addNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navEntries=response.nav_entries;
				for(var i=0; i< navEntries.length; i++){
					var entry = navEntries[i];
					var container = $('#apps .wrapper');

					if(container.children('li[data-id="'+entry.id+'"]').length === 0){
						var li=$('

');
						li.attr('data-id', entry.id);
						var img= $('').attr({ src: entry.icon});
						var a=$('').attr('href', entry.href);
						var filename=$('');
						filename.text(entry.name);
						a.prepend(filename);
						a.prepend(img);
						li.append(a);

						// append the new app as last item in the list
						// (.push is from sticky footer)
						$('#apps .wrapper .push').before(li);

						// scroll the app navigation down
						// so the newly added app is seen
						$('#navigation').animate({
							scrollTop: $('#navigation').height()
						}, 'slow');

						// draw attention to the newly added app entry
						// by flashing it twice
						container.children('li[data-id="' + entry.id + '"]')
							.animate({opacity: 0.3})
							.animate({opacity: 1})
							.animate({opacity: 0.3})
							.animate({opacity: 1});

						if (!SVGSupport() && entry.icon.match(/\.svg$/i)) {
							$(img).addClass('svg');
							replaceSVG();
						}
					}
				}
			}
		});
	},
	showErrorMessage: function(message) {
		$('.appinfo .warning').show();
		$('.appinfo .warning').text(message);
	},
	isType: function(app, type){
		return app.types && app.types.indexOf(type) !== -1;
	}
};

$(document).ready(function(){
	$('#app-navigation ul li').each(function(index,li){
		var app = OC.get('appData_'+$(li).data('id'));
		if (app) {
			app.groups= $(li).data('groups') || [];
		}
		$(li).data('app',app);
		$(this).find('span.hidden').remove();
	});
	$('#app-navigation ul li').keydown(function(event) {
		if (event.which === 13 || event.which === 32) {
			$(event.target).click();
		}
		return false;
	});

	$(document).on('click', '#app-navigation', function(event){
		var tgt = $(event.target);
		if (tgt.is('li') || tgt.is('a')) {
			var item = tgt.is('li') ? $(tgt) : $(tgt).parent();
			var app = item.data('app');
			OC.Settings.Apps.loadApp(app);
			$('#app-navigation .selected').removeClass('selected');
			item.addClass('selected');
		}
		return false;
	});
	$('#app-content input.enable').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		var active=$(this).data('active');
		if(appid) {
			OC.Settings.Apps.enableApp(appid, active, element);
		}
	});
	$('#app-content input.update').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		if(appid) {
			OC.Settings.Apps.updateApp(appid, element);
		}
	});

	$('#group_select').change(function() {
		var element = $('#app-content input.enable');
		var groups = $(this).val();
		var appid = element.data('appid');
		if (appid) {
			OC.Settings.Apps.enableApp(appid, false, element, groups);
		}
	});

	if(appid) {
		var item = $('#app-navigation ul li[data-id="'+appid+'"]');
		if(item) {
			item.trigger('click');
			item.addClass('active');
			$('#app-navigation').animate({scrollTop: $(item).offset().top-70}, 'slow','swing');
		}
	}

	$("#groups_enable").change(function() {
		if (this.checked) {
			$("div.multiselect").parent().remove();
			$('#group_select').multiSelect();
		} else {
			$('#group_select').hide().val(null);
			$("div.multiselect").parent().remove();
		}

		$('#group_select').change();
	});
});
<commit_msg>Dont show group settings for login, filesystem, etc apps after enabling them<commit_after>/**
 * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
 * Copyright (c) 2012, Thomas Tanghus <thomas@tanghus.net>
 * This file is licensed under the Affero General Public License version 3 or later.
 * See the COPYING-README file.
 */

OC.Settings = OC.Settings || {};
OC.Settings.Apps = OC.Settings.Apps || {
	loadApp:function(app) {
		var page = $('#app-content');
		page.find('p.license').show();
		page.find('span.name').text(app.name);
		page.find('small.externalapp').text(app.internallabel);
		if (app.version) {
			page.find('span.version').text(app.version);
		} else {
			page.find('span.version').text('');
		}
		page.find('span.score').html(app.score);
		page.find('p.description').text(app.description);
		page.find('img.preview').attr('src', app.preview);
		if (app.preview && app.preview.length) {
			page.find('img.preview').show();
		} else {
			page.find('img.preview').hide();
		}
		page.find('small.externalapp').attr('style', 'visibility:visible');
		page.find('span.author').text(app.author);

		// FIXME licenses of downloaded apps go into app.licence, licenses of not-downloaded apps into app.license
		var appLicense = '';
		if (typeof(app.licence) !== 'undefined') {
			appLicense = app.licence;
		} else if (typeof(app.license) !== 'undefined') {
			appLicense = app.license;
		}
		page.find('span.licence').text(appLicense);

		var userDocumentation = false;
		var adminDocumentation = false;
		if (typeof(app.documentation) !== 'undefined') {
			if (typeof(app.documentation.user) !== 'undefined') {
				userDocumentation = true;
				page.find('span.userDocumentation').html("" + t('settings', 'User Documentation') + "");
				page.find('p.documentation').show();
			}
			if (typeof(app.documentation.admin) !== 'undefined') {
				adminDocumentation = true;
				page.find('span.adminDocumentation').html("" + t('settings', 'Admin Documentation') + "");
				page.find('p.documentation').show();
			}

			if(userDocumentation && adminDocumentation) {
				page.find('span.userDocumentation').after(', ');
			}
		}

		if (typeof(app.website) !== 'undefined') {
			page.find('p.website').show();
			page.find('a#websitelink').attr('href', app.website);
		}

		if (app.update !== false) {
			page.find('input.update').show();
			page.find('input.update').data('appid', app.id);
			page.find('input.update').attr('value',t('settings', 'Update to {appversion}', {appversion:app.update}));
		} else {
			page.find('input.update').hide();
		}

		page.find('input.enable').show();
		page.find('input.enable').val((app.active) ? t('settings', 'Disable') : t('settings', 'Enable'));
		page.find('input.enable').data('appid', app.id);
		page.find('input.enable').data('active', app.active);
		if (app.internal === false) {
			page.find('span.score').show();
			page.find('p.appstore').show();
			page.find('a#appstorelink').attr('href', 'http://apps.owncloud.com/content/show.php?content=' + app.id);
			page.find('small.externalapp').hide();
		} else {
			page.find('p.appslink').hide();
			page.find('span.score').hide();
		}
		if (typeof($('#app-navigation ul li[data-id="'+app.id+'"]').data('errormsg')) !== "undefined") {
			page.find(".warning").show();
			page.find(".warning").text($('#app-navigation ul li[data-id="'+app.id+'"]').data('errormsg'));
		} else {
			page.find(".warning").hide();
		}

		page.find("div.multiselect").parent().remove();
		if(OC.Settings.Apps.isType(app, 'filesystem') || OC.Settings.Apps.isType(app, 'prelogin') ||
			OC.Settings.Apps.isType(app, 'authentication') || OC.Settings.Apps.isType(app, 'logging')) {
			page.find("#groups_enable").hide();
			page.find("label[for='groups_enable']").hide();
			page.find("#groups_enable").attr('checked', null);
		} else {
			$('#group_select > option').each(function (i, el) {
				if (app.groups.length === 0 || app.groups.indexOf(el.value) >= 0) {
					$(el).attr('selected', 'selected');
				} else {
					$(el).attr('selected', null);
				}
			});
			if (app.active) {
				if (app.groups.length) {
					$('#group_select').multiSelect();
					page.find("#groups_enable").attr('checked','checked');
				} else {
					page.find("#groups_enable").attr('checked', null);
				}
				page.find("#groups_enable").show();
				page.find("label[for='groups_enable']").show();
			} else {
				page.find("#groups_enable").hide();
				page.find("label[for='groups_enable']").hide();
			}
		}
	},
	enableApp:function(appid, active, element, groups) {
		groups = groups || [];
		var appitem=$('#app-navigation ul li[data-id="'+appid+'"]');
		element.val(t('settings','Please wait....'));
		if(active && !groups.length) {
			$.post(OC.filePath('settings','ajax','disableapp.php'),{appid:appid},function(result) {
				if(!result || result.status !== 'success') {
					if (result.data && result.data.message) {
						OC.Settings.Apps.showErrorMessage(result.data.message);
						appitem.data('errormsg', result.data.message);
					} else {
						OC.Settings.Apps.showErrorMessage(t('settings', 'Error while disabling app'));
						appitem.data('errormsg', t('settings', 'Error while disabling app'));
					}
					element.val(t('settings','Disable'));
					appitem.addClass('appwarning');
				}
				else {
					appitem.data('active',false);
					appitem.data('groups', '');
					element.data('active',false);
					OC.Settings.Apps.removeNavigation(appid);
					appitem.removeClass('active');
					element.val(t('settings','Enable'));
					element.parent().find("#groups_enable").hide();
					element.parent().find("label[for='groups_enable']").hide();
					var app = OC.get('appData_' + appid);
					app.active = false;
				}
			},'json');
		} else {
			$.post(OC.filePath('settings','ajax','enableapp.php'),{appid: appid, groups: groups},function(result) {
				if(!result || result.status !== 'success') {
					if (result.data && result.data.message) {
						OC.Settings.Apps.showErrorMessage(result.data.message);
						appitem.data('errormsg', result.data.message);
					} else {
						OC.Settings.Apps.showErrorMessage(t('settings', 'Error while enabling app'));
						appitem.data('errormsg', t('settings', 'Error while disabling app'));
					}
					element.val(t('settings','Enable'));
					appitem.addClass('appwarning');
				} else {
					OC.Settings.Apps.addNavigation(appid);
					appitem.data('active',true);
					element.data('active',true);
					appitem.addClass('active');
					element.val(t('settings','Disable'));
					var app = OC.get('appData_' + appid);
					app.active = true;
					if (OC.Settings.Apps.isType(app, 'filesystem') || OC.Settings.Apps.isType(app, 'prelogin') ||
						OC.Settings.Apps.isType(app, 'authentication') || OC.Settings.Apps.isType(app, 'logging')) {
						element.parent().find("#groups_enable").hide();
						element.parent().find("label[for='groups_enable']").hide();
					} else {
						element.parent().find("#groups_enable").show();
						element.parent().find("label[for='groups_enable']").show();
						if (groups) {
							appitem.data('groups', JSON.stringify(groups));
						} else {
							appitem.data('groups', '');
						}
					}
				}
			},'json')
			.fail(function() {
				OC.Settings.Apps.showErrorMessage(t('settings', 'Error while enabling app'));
				appitem.data('errormsg', t('settings', 'Error while enabling app'));
				appitem.data('active',false);
				appitem.addClass('appwarning');
				OC.Settings.Apps.removeNavigation(appid);
				element.val(t('settings','Enable'));
			});
		}
	},
	updateApp:function(appid, element) {
		element.val(t('settings','Updating....'));
		$.post(OC.filePath('settings','ajax','updateapp.php'),{appid:appid},function(result) {
			if(!result || result.status !== 'success') {
				OC.Settings.Apps.showErrorMessage(t('settings','Error while updating app'),t('settings','Error'));
				element.val(t('settings','Update'));
			}
			else {
				element.val(t('settings','Updated'));
				element.hide();
			}
		},'json');
	},

	insertApp:function(appdata) {
		var applist = $('#app-navigation ul li');
		var app =
				$('
'
				+ ''
				+ appdata.name+'3rd party
');
		app.data('app', appdata);
		var added = false;
		applist.each(function() {
			if(!parseInt($(this).data('installed')) && $(this).find('a').text().toLowerCase() > appdata.name.toLowerCase()) {
				$(this).before(app);
				added = true;
				return false; // dang, remember this to get out of loop
			}
		});
		if(!added) {
			applist.last().after(app);
		}
		return app;
	},
	removeNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navIds=response.nav_ids;
				for(var i=0; i< navIds.length; i++){
					$('#apps .wrapper').children('li[data-id="'+navIds[i]+'"]').remove();
				}
			}
		});
	},
	addNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navEntries=response.nav_entries;
				for(var i=0; i< navEntries.length; i++){
					var entry = navEntries[i];
					var container = $('#apps .wrapper');

					if(container.children('li[data-id="'+entry.id+'"]').length === 0){
						var li=$('

');
						li.attr('data-id', entry.id);
						var img= $('').attr({ src: entry.icon});
						var a=$('').attr('href', entry.href);
						var filename=$('');
						filename.text(entry.name);
						a.prepend(filename);
						a.prepend(img);
						li.append(a);

						// append the new app as last item in the list
						// (.push is from sticky footer)
						$('#apps .wrapper .push').before(li);

						// scroll the app navigation down
						// so the newly added app is seen
						$('#navigation').animate({
							scrollTop: $('#navigation').height()
						}, 'slow');

						// draw attention to the newly added app entry
						// by flashing it twice
						container.children('li[data-id="' + entry.id + '"]')
							.animate({opacity: 0.3})
							.animate({opacity: 1})
							.animate({opacity: 0.3})
							.animate({opacity: 1});

						if (!SVGSupport() && entry.icon.match(/\.svg$/i)) {
							$(img).addClass('svg');
							replaceSVG();
						}
					}
				}
			}
		});
	},
	showErrorMessage: function(message) {
		$('.appinfo .warning').show();
		$('.appinfo .warning').text(message);
	},
	isType: function(app, type){
		return app.types && app.types.indexOf(type) !== -1;
	}
};

$(document).ready(function(){
	$('#app-navigation ul li').each(function(index,li){
		var app = OC.get('appData_'+$(li).data('id'));
		if (app) {
			app.groups= $(li).data('groups') || [];
		}
		$(li).data('app',app);
		$(this).find('span.hidden').remove();
	});
	$('#app-navigation ul li').keydown(function(event) {
		if (event.which === 13 || event.which === 32) {
			$(event.target).click();
		}
		return false;
	});

	$(document).on('click', '#app-navigation', function(event){
		var tgt = $(event.target);
		if (tgt.is('li') || tgt.is('a')) {
			var item = tgt.is('li') ? $(tgt) : $(tgt).parent();
			var app = item.data('app');
			OC.Settings.Apps.loadApp(app);
			$('#app-navigation .selected').removeClass('selected');
			item.addClass('selected');
		}
		return false;
	});
	$('#app-content input.enable').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		var active=$(this).data('active');
		if(appid) {
			OC.Settings.Apps.enableApp(appid, active, element);
		}
	});
	$('#app-content input.update').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		if(appid) {
			OC.Settings.Apps.updateApp(appid, element);
		}
	});

	$('#group_select').change(function() {
		var element = $('#app-content input.enable');
		var groups = $(this).val();
		var appid = element.data('appid');
		if (appid) {
			OC.Settings.Apps.enableApp(appid, false, element, groups);
		}
	});

	if(appid) {
		var item = $('#app-navigation ul li[data-id="'+appid+'"]');
		if(item) {
			item.trigger('click');
			item.addClass('active');
			$('#app-navigation').animate({scrollTop: $(item).offset().top-70}, 'slow','swing');
		}
	}

	$("#groups_enable").change(function() {
		if (this.checked) {
			$("div.multiselect").parent().remove();
			$('#group_select').multiSelect();
		} else {
			$('#group_select').hide().val(null);
			$("div.multiselect").parent().remove();
		}

		$('#group_select').change();
	});
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
 * Copyright (c) 2012, Thomas Tanghus <thomas@tanghus.net>
 * This file is licensed under the Affero General Public License version 3 or later.
 * See the COPYING-README file.
 */

OC.Settings = OC.Settings || {};
OC.Settings.Apps = OC.Settings.Apps || {
	loadApp:function(app) {
		var page = $('#rightcontent');
		page.find('p.license').show();
		page.find('span.name').text(app.name);
		page.find('small.externalapp').text(app.internallabel);
		if (app.version) {
			page.find('span.version').text(app.version);
		} else {
			page.find('span.version').text('');
		}
		page.find('span.score').html(app.score);
		page.find('p.description').text(app.description);
		page.find('img.preview').attr('src', app.preview);
		if (app.preview && app.preview.length) {
			page.find('img.preview').show();
		} else {
			page.find('img.preview').hide();
		}
		page.find('small.externalapp').attr('style', 'visibility:visible');
		page.find('span.author').text(app.author);
		page.find('span.licence').text(app.licence);

		if (app.update != false) {
			page.find('input.update').show();
			page.find('input.update').data('appid', app.id);
			page.find('input.update').attr('value',t('settings', 'Update to {appversion}', {appversion:app.update}));
		} else {
			page.find('input.update').hide();
		}

		page.find('input.enable').show();
		page.find('input.enable').val((app.active) ? t('settings', 'Disable') : t('settings', 'Enable'));
		page.find('input.enable').data('appid', app.id);
		page.find('input.enable').data('active', app.active);
		if (app.internal == false) {
			page.find('span.score').show();
			page.find('p.appslink').show();
			page.find('a').attr('href', 'http://apps.owncloud.com/content/show.php?content=' + app.id);
			page.find('small.externalapp').hide();
		} else {
			page.find('p.appslink').hide();
			page.find('span.score').hide();
		}
	},
	enableApp:function(appid, active, element) {
		console.log('enableApp:', appid, active, element);
		var appitem=$('#leftcontent li[data-id="'+appid+'"]');
		appData = appitem.data('app');
		appData.active = !active;
		appitem.data('app', appData);
		element.val(t('settings','Please wait....'));
		if(active) {
			$.post(OC.filePath('settings','ajax','disableapp.php'),{appid:appid},function(result) {
				if(!result || result.status!='success') {
					OC.dialogs.alert('Error while disabling app', t('core', 'Error'));
				}
				else {
					element.data('active',false);
					OC.Settings.Apps.removeNavigation(appid);
					element.val(t('settings','Enable'));
				}
			},'json');
			$('#leftcontent li[data-id="'+appid+'"]').removeClass('active');
		} else {
			$.post(OC.filePath('settings','ajax','enableapp.php'),{appid:appid},function(result) {
				if(!result || result.status!='success') {
					OC.dialogs.alert('Error while enabling app', t('core', 'Error'));
				}
				else {
					OC.Settings.Apps.addNavigation(appid);
					element.data('active',true);
					element.val(t('settings','Disable'));
				}
			},'json')
			.fail(function() {
				OC.dialogs.alert('Error while enabling app', t('core', 'Error'));
				element.data('active',false);
				OC.Settings.Apps.removeNavigation(appid);
				element.val(t('settings','Enable'));
			});
			$('#leftcontent li[data-id="'+appid+'"]').addClass('active');
		}
	},
	updateApp:function(appid, element) {
		console.log('updateApp:', appid, element);
		element.val(t('settings','Updating....'));
		$.post(OC.filePath('settings','ajax','updateapp.php'),{appid:appid},function(result) {
			if(!result || result.status!='success') {
				OC.dialogs.alert(t('settings','Error while updating app'),t('settings','Error'));
			}
			else {
				element.val(t('settings','Updated'));
				element.hide();
			}
		},'json');
	},

	insertApp:function(appdata) {
		var applist = $('#leftcontent li');
		var app =
				$('
'
				+ ''
				+ appdata.name+'3rd party
');
		app.data('app', appdata);
		var added = false;
		applist.each(function() {
			if(!parseInt($(this).data('installed')) && $(this).find('a').text().toLowerCase() > appdata.name.toLowerCase()) {
				$(this).before(app);
				added = true;
				return false; // dang, remember this to get out of loop
			}
		});
		if(!added) {
			applist.last().after(app);
		}
		return app;
	},
	removeNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navIds=response.nav_ids;
				for(var i=0; i< navIds.length; i++){
					$('#apps').children('li[data-id="'+navIds[i]+'"]').remove();
				}
			}
		});
	},
	addNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navEntries=response.nav_entries;
				for(var i=0; i< navEntries.length; i++){
					var entry = navEntries[i];
					var container = $('#apps');

					if(container.children('li[data-id="'+entry.id+'"]').length === 0){
						var li=$('

');
						li.attr('data-id', entry.id);
						var img= $('').attr({ src: entry.icon});
						var a=$('').attr('href', entry.href);
						var filename=$('');
						filename.text(entry.name);
						a.prepend(filename);
						a.prepend(img);
						li.append(a);
						container.append(li);
						if (entry.icon.match(/\.svg$/i)) {
							$(img).addClass('svg');
							replaceSVG();
						}
					}
				}
			}
		});
	}
};

$(document).ready(function(){
	$('#leftcontent li').each(function(index,li){
		var app = OC.get('appData_'+$(li).data('id'));
		$(li).data('app',app);
		$(this).find('span.hidden').remove();
	});
	$('#leftcontent li').keydown(function(event) {
		if (event.which == 13 || event.which == 32) {
			$(event.target).click();
		}
		return false;
	});

	$(document).on('click', '#leftcontent', function(event){
		var tgt = $(event.target);
		if (tgt.is('li') || tgt.is('a')) {
			var item = tgt.is('li') ? $(tgt) : $(tgt).parent();
			var app = item.data('app');
			OC.Settings.Apps.loadApp(app);
		}
		return false;
	});
	$('#rightcontent input.enable').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		var active=$(this).data('active');
		if(appid) {
			OC.Settings.Apps.enableApp(appid, active, element);
		}
	});
	$('#rightcontent input.update').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		if(appid) {
			OC.Settings.Apps.updateApp(appid, element);
		}
	});

	if(appid) {
		var item = $('#leftcontent li[data-id="'+appid+'"]');
		if(item) {
			item.trigger('click');
			item.addClass('active');
			$('#leftcontent').animate({scrollTop: $(item).offset().top-70}, 'slow','swing');
		}
	}
});
<commit_msg>Use svg to png fallback on demand only<commit_after>/**
 * Copyright (c) 2011, Robin Appelman <icewind1991@gmail.com>
 * Copyright (c) 2012, Thomas Tanghus <thomas@tanghus.net>
 * This file is licensed under the Affero General Public License version 3 or later.
 * See the COPYING-README file.
 */

OC.Settings = OC.Settings || {};
OC.Settings.Apps = OC.Settings.Apps || {
	loadApp:function(app) {
		var page = $('#rightcontent');
		page.find('p.license').show();
		page.find('span.name').text(app.name);
		page.find('small.externalapp').text(app.internallabel);
		if (app.version) {
			page.find('span.version').text(app.version);
		} else {
			page.find('span.version').text('');
		}
		page.find('span.score').html(app.score);
		page.find('p.description').text(app.description);
		page.find('img.preview').attr('src', app.preview);
		if (app.preview && app.preview.length) {
			page.find('img.preview').show();
		} else {
			page.find('img.preview').hide();
		}
		page.find('small.externalapp').attr('style', 'visibility:visible');
		page.find('span.author').text(app.author);
		page.find('span.licence').text(app.licence);

		if (app.update != false) {
			page.find('input.update').show();
			page.find('input.update').data('appid', app.id);
			page.find('input.update').attr('value',t('settings', 'Update to {appversion}', {appversion:app.update}));
		} else {
			page.find('input.update').hide();
		}

		page.find('input.enable').show();
		page.find('input.enable').val((app.active) ? t('settings', 'Disable') : t('settings', 'Enable'));
		page.find('input.enable').data('appid', app.id);
		page.find('input.enable').data('active', app.active);
		if (app.internal == false) {
			page.find('span.score').show();
			page.find('p.appslink').show();
			page.find('a').attr('href', 'http://apps.owncloud.com/content/show.php?content=' + app.id);
			page.find('small.externalapp').hide();
		} else {
			page.find('p.appslink').hide();
			page.find('span.score').hide();
		}
	},
	enableApp:function(appid, active, element) {
		console.log('enableApp:', appid, active, element);
		var appitem=$('#leftcontent li[data-id="'+appid+'"]');
		appData = appitem.data('app');
		appData.active = !active;
		appitem.data('app', appData);
		element.val(t('settings','Please wait....'));
		if(active) {
			$.post(OC.filePath('settings','ajax','disableapp.php'),{appid:appid},function(result) {
				if(!result || result.status!='success') {
					OC.dialogs.alert('Error while disabling app', t('core', 'Error'));
				}
				else {
					element.data('active',false);
					OC.Settings.Apps.removeNavigation(appid);
					element.val(t('settings','Enable'));
				}
			},'json');
			$('#leftcontent li[data-id="'+appid+'"]').removeClass('active');
		} else {
			$.post(OC.filePath('settings','ajax','enableapp.php'),{appid:appid},function(result) {
				if(!result || result.status!='success') {
					OC.dialogs.alert('Error while enabling app', t('core', 'Error'));
				}
				else {
					OC.Settings.Apps.addNavigation(appid);
					element.data('active',true);
					element.val(t('settings','Disable'));
				}
			},'json')
			.fail(function() {
				OC.dialogs.alert('Error while enabling app', t('core', 'Error'));
				element.data('active',false);
				OC.Settings.Apps.removeNavigation(appid);
				element.val(t('settings','Enable'));
			});
			$('#leftcontent li[data-id="'+appid+'"]').addClass('active');
		}
	},
	updateApp:function(appid, element) {
		console.log('updateApp:', appid, element);
		element.val(t('settings','Updating....'));
		$.post(OC.filePath('settings','ajax','updateapp.php'),{appid:appid},function(result) {
			if(!result || result.status!='success') {
				OC.dialogs.alert(t('settings','Error while updating app'),t('settings','Error'));
			}
			else {
				element.val(t('settings','Updated'));
				element.hide();
			}
		},'json');
	},

	insertApp:function(appdata) {
		var applist = $('#leftcontent li');
		var app =
				$('
'
				+ ''
				+ appdata.name+'3rd party
');
		app.data('app', appdata);
		var added = false;
		applist.each(function() {
			if(!parseInt($(this).data('installed')) && $(this).find('a').text().toLowerCase() > appdata.name.toLowerCase()) {
				$(this).before(app);
				added = true;
				return false; // dang, remember this to get out of loop
			}
		});
		if(!added) {
			applist.last().after(app);
		}
		return app;
	},
	removeNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navIds=response.nav_ids;
				for(var i=0; i< navIds.length; i++){
					$('#apps').children('li[data-id="'+navIds[i]+'"]').remove();
				}
			}
		});
	},
	addNavigation: function(appid){
		$.getJSON(OC.filePath('settings', 'ajax', 'navigationdetect.php'), {app: appid}).done(function(response){
			if(response.status === 'success'){
				var navEntries=response.nav_entries;
				for(var i=0; i< navEntries.length; i++){
					var entry = navEntries[i];
					var container = $('#apps');

					if(container.children('li[data-id="'+entry.id+'"]').length === 0){
						var li=$('

');
						li.attr('data-id', entry.id);
						var img= $('').attr({ src: entry.icon});
						var a=$('').attr('href', entry.href);
						var filename=$('');
						filename.text(entry.name);
						a.prepend(filename);
						a.prepend(img);
						li.append(a);
						container.append(li);
						if (!SVGSupport() && entry.icon.match(/\.svg$/i)) {
							$(img).addClass('svg');
							replaceSVG();
						}
					}
				}
			}
		});
	}
};

$(document).ready(function(){
	$('#leftcontent li').each(function(index,li){
		var app = OC.get('appData_'+$(li).data('id'));
		$(li).data('app',app);
		$(this).find('span.hidden').remove();
	});
	$('#leftcontent li').keydown(function(event) {
		if (event.which == 13 || event.which == 32) {
			$(event.target).click();
		}
		return false;
	});

	$(document).on('click', '#leftcontent', function(event){
		var tgt = $(event.target);
		if (tgt.is('li') || tgt.is('a')) {
			var item = tgt.is('li') ? $(tgt) : $(tgt).parent();
			var app = item.data('app');
			OC.Settings.Apps.loadApp(app);
		}
		return false;
	});
	$('#rightcontent input.enable').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		var active=$(this).data('active');
		if(appid) {
			OC.Settings.Apps.enableApp(appid, active, element);
		}
	});
	$('#rightcontent input.update').click(function(){
		var element = $(this);
		var appid=$(this).data('appid');
		if(appid) {
			OC.Settings.Apps.updateApp(appid, element);
		}
	});

	if(appid) {
		var item = $('#leftcontent li[data-id="'+appid+'"]');
		if(item) {
			item.trigger('click');
			item.addClass('active');
			$('#leftcontent').animate({scrollTop: $(item).offset().top-70}, 'slow','swing');
		}
	}
});
<|endoftext|>


<commit_before>// @flow
import logger from '../logger'
import * as RS from 'redux-saga'
import * as Effects from 'redux-saga/effects'
import {convertToError} from '../util/errors'
import * as ConfigGen from '../actions/config-gen'
import type {TypedState} from '../constants/reducer'
import type {TypedActions} from '../actions/typed-actions-gen'
import put from './typed-put'

export type SagaGenerator<Yield, Actions> = Generator<Yield, void, Actions>

function safeTakeEvery(
  pattern: RS.Pattern,
  worker: Function
): RS.ForkEffect<null, Function, $ReadOnlyArray<any>> {
  const safeTakeEveryWorker = function* safeTakeEveryWorker(action: TypedActions): RS.Saga<void> {
    try {
      yield Effects.call(worker, action)
    } catch (error) {
      // Convert to global error so we don't kill the takeEvery loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('safeTakeEvery cancelled')
      }
    }
  }

  return Effects.takeEvery(pattern, safeTakeEveryWorker)
}

// Useful in safeTakeEveryPure when you have an array of effects you want to run in order
function* sequentially(effects: Array<any>): Generator<any, Array<any>, any> {
  const results = []
  for (let i = 0; i < effects.length; i++) {
    results.push(yield effects[i])
  }
  return results
}

// Helper that expects a function which returns a promise that resolves to a put
function actionToPromise<A>(
  pattern: RS.Pattern,
  f: (state: TypedState, action: A) => null | false | void | Promise<TypedActions | null | false | void>
) {
  return Effects.takeEvery(pattern, function* actionToPromiseHelper(action: A): RS.Saga<void> {
    try {
      const state: TypedState = yield Effects.select()
      const toPut = yield Effects.call(f, state, action)
      if (toPut) {
        yield Effects.put(toPut)
      }
    } catch (error) {
      // Convert to global error so we don't kill the takeEvery loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('actionToPromise cancelled')
      }
    }
  })
}

// like safeTakeEveryPure but simpler, only 2 params and gives you a state first
function actionToAction<A, E>(pattern: RS.Pattern, f: (state: TypedState, action: A) => E) {
  return Effects.takeEvery(pattern, function* actionToActionHelper(action: A): Generator<any, void, any> {
    try {
      const state: TypedState = yield Effects.select()
      yield f(state, action)
    } catch (error) {
      // Convert to global error so we don't kill the takeEvery loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('actionToAction cancelled')
      }
    }
  })
}

// Like safeTakeEvery but the worker is pure (not a generator) optionally pass in a third argument
// Which is a selector function that will select some state and pass it to pureWorker
// whatever purework returns will be yielded on.
// i.e. it can return put(someAction). That effectively transforms the input action into another action
// It can also return all([put(action1), put(action2)]) to dispatch multiple actions
function safeTakeEveryPure<A, R, FinalEffect, FinalErrorEffect>(
  pattern: RS.Pattern,
  pureWorker: ((action: A, state: TypedState) => any) | ((action: A) => any),
  actionCreatorsWithResult?: ?(result: R, action: A, updatedState: TypedState) => FinalEffect,
  actionCreatorsWithError?: ?(result: R, action: A) => FinalErrorEffect
) {
  return safeTakeEvery(pattern, function* safeTakeEveryPureWorker(action: A) {
    // If the pureWorker fn takes two arguments, let's pass the state
    try {
      let result
      if (pureWorker.length === 2) {
        const state: TypedState = yield Effects.select()
        // $FlowIssue - doesn't understand checking for arity
        result = yield pureWorker(action, state)
      } else {
        // $FlowIssue - doesn't understand checking for arity
        result = yield pureWorker(action)
      }

      if (actionCreatorsWithResult) {
        if (actionCreatorsWithResult.length === 3) {
          // add a way to get the updated state
          const state: TypedState = yield Effects.select()
          yield actionCreatorsWithResult(result, action, state)
        } else {
          // $FlowIssue we pass undefined if they don't use it
          yield actionCreatorsWithResult(result, action, undefined)
        }
      }
    } catch (e) {
      if (actionCreatorsWithError) {
        yield actionCreatorsWithError(e, action)
      } else {
        yield Effects.put(
          ConfigGen.createGlobalError({
            globalError: convertToError(e),
          })
        )
      }
    }
  })
}
// Similar to safeTakeEveryPure
function safeTakeLatestPure<A, R, FinalEffect, FinalErrorEffect>(
  pattern: RS.Pattern,
  pureWorker: ((action: A, state: TypedState) => any) | ((action: A) => any),
  actionCreatorsWithResult?: (result: R, action: A) => FinalEffect,
  actionCreatorsWithError?: (result: R, action: A) => FinalErrorEffect
) {
  const safeTakeLatestPureWorker = function* safeTakeLatestPureWorker(action: A) {
    // If the pureWorker fn takes two arguments, let's pass the state
    try {
      let result
      if (pureWorker.length === 2) {
        const state: TypedState = yield Effects.select(s => s)
        // $FlowIssue - doesn't understand checking for arity
        result = yield pureWorker(action, state)
      } else {
        // $FlowIssue - doesn't understand checking for arity
        result = yield pureWorker(action)
      }

      if (actionCreatorsWithResult) {
        // $FlowIssue confused
        yield actionCreatorsWithResult(result, action)
      }
    } catch (e) {
      if (actionCreatorsWithError) {
        // $FlowIssue confused
        yield actionCreatorsWithError(e, action)
      } else {
        yield Effects.put(
          ConfigGen.createGlobalError({
            globalError: convertToError(e),
          })
        )
      }
    } finally {
      if (actionCreatorsWithError) {
        if (yield Effects.cancelled()) {
          // $FlowIssue confused
          yield actionCreatorsWithError(new Error('Canceled'), action)
        }
      }
    }
  }
  // $FlowIssue confused
  return Effects.takeLatest(pattern, safeTakeLatestPureWorker)
}

function _safeTakeLatestWithCatch(
  pattern: RS.Pattern,
  catchHandler: Function,
  worker: Function | Generator<any, void, any>,
  ...args: Array<any>
) {
  const safeTakeLatestWithCatchWorker = function* safeTakeLatestWithCatchWorker(...args) {
    try {
      yield Effects.call(worker, ...args)
    } catch (error) {
      // Convert to global error so we don't kill the takeLatest loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
      yield Effects.call(catchHandler, error)
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('safeTakeLatestWithCatch cancelled')
      }
    }
  }

  // $FlowIssue confused
  return Effects.takeLatest(pattern, safeTakeLatestWithCatchWorker, ...args)
}

// Likely avoid using this. Saga canceling is tricky
function safeTakeLatest(
  pattern: RS.Pattern,
  worker: Function | Generator<any, void, any>,
  ...args: Array<any>
) {
  return _safeTakeLatestWithCatch(pattern, () => {}, worker, ...args)
}

export type {Effect, PutEffect, Channel} from 'redux-saga'
export {buffers, channel, delay, eventChannel} from 'redux-saga'
export {
  all,
  call,
  cancel,
  cancelled,
  fork,
  join,
  race,
  select,
  spawn,
  take,
  takeEvery,
  takeLatest,
  throttle,
} from 'redux-saga/effects'

export {
  put,
  safeTakeEvery,
  safeTakeEveryPure,
  actionToPromise,
  actionToAction,
  safeTakeLatest,
  safeTakeLatestPure,
  sequentially,
}
<commit_msg>WIP (#13679)<commit_after>// @flow
import logger from '../logger'
import * as RS from 'redux-saga'
import * as Effects from 'redux-saga/effects'
import {convertToError} from '../util/errors'
import * as ConfigGen from '../actions/config-gen'
import type {TypedState} from '../constants/reducer'
import type {TypedActions} from '../actions/typed-actions-gen'
import put from './typed-put'

export type SagaGenerator<Yield, Actions> = Generator<Yield, void, Actions>

function safeTakeEvery(
  pattern: RS.Pattern,
  worker: Function
): RS.ForkEffect<null, Function, $ReadOnlyArray<any>> {
  const safeTakeEveryWorker = function* safeTakeEveryWorker(action: TypedActions): RS.Saga<void> {
    try {
      yield Effects.call(worker, action)
    } catch (error) {
      // Convert to global error so we don't kill the takeEvery loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('safeTakeEvery cancelled')
      }
    }
  }

  return Effects.takeEvery(pattern, safeTakeEveryWorker)
}

// Useful in safeTakeEveryPure when you have an array of effects you want to run in order
function* sequentially(effects: Array<any>): Generator<any, Array<any>, any> {
  const results = []
  for (let i = 0; i < effects.length; i++) {
    results.push(yield effects[i])
  }
  return results
}

// Helper that expects a function which returns a promise that resolves to a put
function actionToPromise<A>(
  pattern: RS.Pattern,
  f: (state: TypedState, action: A) => null | false | void | Promise<TypedActions | null | false | void>
) {
  return Effects.takeEvery(pattern, function* actionToPromiseHelper(action: A): RS.Saga<void> {
    try {
      const state: TypedState = yield Effects.select()
      const toPut = yield Effects.call(f, state, action)
      if (toPut) {
        yield Effects.put(toPut)
      }
    } catch (error) {
      // Convert to global error so we don't kill the takeEvery loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('actionToPromise cancelled')
      }
    }
  })
}

// like safeTakeEveryPure but simpler, only 2 params and gives you a state first
function actionToAction<A, E>(pattern: RS.Pattern, f: (state: TypedState, action: A) => E) {
  return Effects.takeEvery(pattern, function* actionToActionHelper(action: A): Generator<any, void, any> {
    try {
      const state: TypedState = yield Effects.select()
      yield f(state, action)
    } catch (error) {
      // Convert to global error so we don't kill the takeEvery loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('actionToAction cancelled')
      }
    }
  })
}

// Like safeTakeEvery but the worker is pure (not a generator) optionally pass in a third argument
// Which is a selector function that will select some state and pass it to pureWorker
// whatever purework returns will be yielded on.
// i.e. it can return put(someAction). That effectively transforms the input action into another action
// It can also return all([put(action1), put(action2)]) to dispatch multiple actions
function safeTakeEveryPure<A, R, FinalEffect, FinalErrorEffect>(
  pattern: RS.Pattern,
  pureWorker: (action: A, state: TypedState) => any,
  actionCreatorsWithResult?: ?(result: R, action: A, updatedState: TypedState) => FinalEffect,
  actionCreatorsWithError?: ?(result: R, action: A) => FinalErrorEffect
) {
  return safeTakeEvery(pattern, function* safeTakeEveryPureWorker(action: A) {
    // If the pureWorker fn takes two arguments, let's pass the state
    try {
      const state: TypedState = yield Effects.select()
      const result = yield pureWorker(action, state)

      if (actionCreatorsWithResult) {
        if (actionCreatorsWithResult.length === 3) {
          // add a way to get the updated state
          const state: TypedState = yield Effects.select()
          yield actionCreatorsWithResult(result, action, state)
        } else {
          // $FlowIssue we pass undefined if they don't use it
          yield actionCreatorsWithResult(result, action, undefined)
        }
      }
    } catch (e) {
      if (actionCreatorsWithError) {
        yield actionCreatorsWithError(e, action)
      } else {
        yield Effects.put(
          ConfigGen.createGlobalError({
            globalError: convertToError(e),
          })
        )
      }
    }
  })
}
// Similar to safeTakeEveryPure
function safeTakeLatestPure<A, R, FinalEffect, FinalErrorEffect>(
  pattern: RS.Pattern,
  pureWorker: ((action: A, state: TypedState) => any) | ((action: A) => any),
  actionCreatorsWithResult?: (result: R, action: A) => FinalEffect,
  actionCreatorsWithError?: (result: R, action: A) => FinalErrorEffect
) {
  const safeTakeLatestPureWorker = function* safeTakeLatestPureWorker(action: A) {
    // If the pureWorker fn takes two arguments, let's pass the state
    try {
      let result
      if (pureWorker.length === 2) {
        const state: TypedState = yield Effects.select(s => s)
        // $FlowIssue - doesn't understand checking for arity
        result = yield pureWorker(action, state)
      } else {
        // $FlowIssue - doesn't understand checking for arity
        result = yield pureWorker(action)
      }

      if (actionCreatorsWithResult) {
        // $FlowIssue confused
        yield actionCreatorsWithResult(result, action)
      }
    } catch (e) {
      if (actionCreatorsWithError) {
        // $FlowIssue confused
        yield actionCreatorsWithError(e, action)
      } else {
        yield Effects.put(
          ConfigGen.createGlobalError({
            globalError: convertToError(e),
          })
        )
      }
    } finally {
      if (actionCreatorsWithError) {
        if (yield Effects.cancelled()) {
          // $FlowIssue confused
          yield actionCreatorsWithError(new Error('Canceled'), action)
        }
      }
    }
  }
  // $FlowIssue confused
  return Effects.takeLatest(pattern, safeTakeLatestPureWorker)
}

function _safeTakeLatestWithCatch(
  pattern: RS.Pattern,
  catchHandler: Function,
  worker: Function | Generator<any, void, any>,
  ...args: Array<any>
) {
  const safeTakeLatestWithCatchWorker = function* safeTakeLatestWithCatchWorker(...args) {
    try {
      yield Effects.call(worker, ...args)
    } catch (error) {
      // Convert to global error so we don't kill the takeLatest loop
      yield Effects.put(
        ConfigGen.createGlobalError({
          globalError: convertToError(error),
        })
      )
      yield Effects.call(catchHandler, error)
    } finally {
      if (yield Effects.cancelled()) {
        logger.info('safeTakeLatestWithCatch cancelled')
      }
    }
  }

  // $FlowIssue confused
  return Effects.takeLatest(pattern, safeTakeLatestWithCatchWorker, ...args)
}

// Likely avoid using this. Saga canceling is tricky
function safeTakeLatest(
  pattern: RS.Pattern,
  worker: Function | Generator<any, void, any>,
  ...args: Array<any>
) {
  return _safeTakeLatestWithCatch(pattern, () => {}, worker, ...args)
}

export type {Effect, PutEffect, Channel} from 'redux-saga'
export {buffers, channel, delay, eventChannel} from 'redux-saga'
export {
  all,
  call,
  cancel,
  cancelled,
  fork,
  join,
  race,
  select,
  spawn,
  take,
  takeEvery,
  takeLatest,
  throttle,
} from 'redux-saga/effects'

export {
  put,
  safeTakeEvery,
  safeTakeEveryPure,
  actionToPromise,
  actionToAction,
  safeTakeLatest,
  safeTakeLatestPure,
  sequentially,
}
<|endoftext|>


<commit_before>

console.log("nav js loaded");

// $(window).scroll(function() {
//   if ($(document).scrollTop() > 50) {
//     $('.navbar').addClass('shrink');
//    $('img#nav-logo').animate({width: "15px"}, 200, function(){});
//    console.log("ran shrink");
// //$('img#nav-logo').animate({"width": "20px"}, 5000, "linear");

//   } else if($(document).scrollTop() < 50){
//     $('.navbar').removeClass('shrink');
//    $('img#nav-logo').animate({width: "100px"}, 200, function(){});
//    console.log("ran expand");

//   // $('img#nav-logo').animate({"width": "100px"}, 5000, "linear");

//   }
// });

$(document).ready(function(){

collapsedBar = false;

 if(window.pageYOffset > 15 && !collapsedBar){  // collapsed size
          collapsedBar = true;
          //collapse bar

          $('img#nav-logo').animate({width: "20px"},300,function(){});

         // document.getElementById('span1').innerHTML='some value...';

        }

        else if(window.pageYOffset == 0){ //full size
          collapsedBar = false;

         $('img#nav-logo').animate({width: "100px"},300,function(){});

        }

});

// just changed again

   <commit_msg>changing<commit_after>

console.log("nav js loaded");

// $(window).scroll(function() {
//   if ($(document).scrollTop() > 50) {
//     $('.navbar').addClass('shrink');
//    $('img#nav-logo').animate({width: "15px"}, 200, function(){});
//    console.log("ran shrink");
// //$('img#nav-logo').animate({"width": "20px"}, 5000, "linear");

//   } else if($(document).scrollTop() < 50){
//     $('.navbar').removeClass('shrink');
//    $('img#nav-logo').animate({width: "100px"}, 200, function(){});
//    console.log("ran expand");

//   // $('img#nav-logo').animate({"width": "100px"}, 5000, "linear");

//   }
// });

$(document).ready(function(){

collapsedBar = false;

 if(window.pageYOffset > 15 && !collapsedBar){  // collapsed size
          collapsedBar = true;
          //collapse bar

          $('img#nav-logo').animate({width: "20px"},300,function(){});

         // document.getElementById('span1').innerHTML='some value...';

console.log("greater than 15");
        }

        else if(window.pageYOffset == 0){ //full size
          collapsedBar = false;

         $('img#nav-logo').animate({width: "100px"},300,function(){});

         console.log("zero");

        }

});

// just changed again

   <|endoftext|>


<commit_before>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	var base = grunt.option('base') || '.';

	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2016 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		qunit: {
			files: [ 'test/*.html' ]
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		sass: {
			core: {
				files: {
					'css/reveal.css': 'css/reveal.scss',
				}
			},
			themes: {
				files: [
					{
						expand: true,
						cwd: 'css/theme/source',
						src: ['*.scss'],
						dest: 'css/theme',
						ext: '.css'
					}
				]
			}
		},

		autoprefixer: {
			dist: {
				src: 'css/reveal.css'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false,
					unescape: false,
					define: false,
					exports: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: base,
					livereload: true,
					open: true
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**',
				'**.md'
			]
		},

		watch: {
			js: {
				files: [ 'Gruntfile.js', 'js/reveal.js' ],
				tasks: 'js'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'css-themes'
			},
			css: {
				files: [ 'css/reveal.scss' ],
				tasks: 'css-core'
			},
			html: {
				files: [ '*.html']
			},
			markdown: {
				files: [ '*.md' ]
			},
			options: {
				livereload: true
			}
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-autoprefixer' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'css', 'js' ] );

	// JS task
	grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] );

	// Theme CSS
	grunt.registerTask( 'css-themes', [ 'sass:themes' ] );

	// Core framework CSS
	grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] );

	// All CSS
	grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<commit_msg>Updates `Gruntfile.js` to support custom scss files.<commit_after>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	var base = grunt.option('base') || '.';

	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2016 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		qunit: {
			files: [ 'test/*.html' ]
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		sass: {
			core: {
				files: {
					'css/reveal.css': 'css/reveal.scss',
				}
			},
			custom: {
				files: {
					'css/style.css': 'css/style.scss',
				}
			},
			themes: {
				files: [
					{
						expand: true,
						cwd: 'css/theme/source',
						src: ['*.scss'],
						dest: 'css/theme',
						ext: '.css'
					}
				]
			}
		},

		autoprefixer: {
			dist: {
				src: 'css/reveal.css'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false,
					unescape: false,
					define: false,
					exports: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: base,
					livereload: true,
					open: true
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**',
				'**.md'
			]
		},

		watch: {
			js: {
				files: [ 'Gruntfile.js', 'js/reveal.js' ],
				tasks: 'js'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'css-themes'
			},
			css: {
				files: [ 'css/reveal.scss' ],
				tasks: 'css-core'
			},
			custom: {
				files: [ 'css/*.scss', '!css/reveal.scss' ],
				tasks: 'css-custom'
			},
			html: {
				files: [ '*.html']
			},
			markdown: {
				files: [ '*.md' ]
			},
			options: {
				livereload: true
			}
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-autoprefixer' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'css', 'js' ] );

	// JS task
	grunt.registerTask( 'js', [ 'jshint', 'uglify', 'qunit' ] );

	// Theme CSS
	grunt.registerTask( 'css-themes', [ 'sass:themes' ] );

	// Core framework CSS
	grunt.registerTask( 'css-core', [ 'sass:core', 'autoprefixer', 'cssmin' ] );

	// Core framework CSS
	grunt.registerTask( 'css-custom', [ 'sass:custom', 'autoprefixer' ] );

	// All CSS
	grunt.registerTask( 'css', [ 'sass', 'autoprefixer', 'cssmin' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<|endoftext|>


<commit_before>/* global module:false */
module.exports = function(grunt) {
	var port = grunt.option('port') || 8000;
	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		qunit: {
			files: [ 'test/*.html' ]
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		sass: {
			main: {
				files: {
					'css/theme/default.css': 'css/theme/source/default.scss',
					'css/theme/beige.css': 'css/theme/source/beige.scss',
					'css/theme/night.css': 'css/theme/source/night.scss',
					'css/theme/serif.css': 'css/theme/source/serif.scss',
					'css/theme/simple.css': 'css/theme/source/simple.scss',
					'css/theme/sky.css': 'css/theme/source/sky.scss',
					'css/theme/moon.css': 'css/theme/source/moon.scss',
					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
					'css/theme/blood.css': 'css/theme/source/blood.scss'
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false,
					unescape: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: '.'
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**'
			]
		},

		watch: {
			main: {
				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
				tasks: 'default'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'themes'
			}
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-contrib-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );

	// Theme task
	grunt.registerTask( 'themes', [ 'sass' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<commit_msg>Update Gruntfile.js to use VCAP_SERVICES<commit_after>/* global module:false */
module.exports = function(grunt) {
	var port = process.env.VCAP_APP_PORT || grunt.option('port') || 8000;
	// Project configuration
	grunt.initConfig({
		pkg: grunt.file.readJSON('package.json'),
		meta: {
			banner:
				'/*!\n' +
				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
				' * http://lab.hakim.se/reveal-js\n' +
				' * MIT licensed\n' +
				' *\n' +
				' * Copyright (C) 2014 Hakim El Hattab, http://hakim.se\n' +
				' */'
		},

		qunit: {
			files: [ 'test/*.html' ]
		},

		uglify: {
			options: {
				banner: '<%= meta.banner %>\n'
			},
			build: {
				src: 'js/reveal.js',
				dest: 'js/reveal.min.js'
			}
		},

		cssmin: {
			compress: {
				files: {
					'css/reveal.min.css': [ 'css/reveal.css' ]
				}
			}
		},

		sass: {
			main: {
				files: {
					'css/theme/default.css': 'css/theme/source/default.scss',
					'css/theme/beige.css': 'css/theme/source/beige.scss',
					'css/theme/night.css': 'css/theme/source/night.scss',
					'css/theme/serif.css': 'css/theme/source/serif.scss',
					'css/theme/simple.css': 'css/theme/source/simple.scss',
					'css/theme/sky.css': 'css/theme/source/sky.scss',
					'css/theme/moon.css': 'css/theme/source/moon.scss',
					'css/theme/solarized.css': 'css/theme/source/solarized.scss',
					'css/theme/blood.css': 'css/theme/source/blood.scss'
				}
			}
		},

		jshint: {
			options: {
				curly: false,
				eqeqeq: true,
				immed: true,
				latedef: true,
				newcap: true,
				noarg: true,
				sub: true,
				undef: true,
				eqnull: true,
				browser: true,
				expr: true,
				globals: {
					head: false,
					module: false,
					console: false,
					unescape: false
				}
			},
			files: [ 'Gruntfile.js', 'js/reveal.js' ]
		},

		connect: {
			server: {
				options: {
					port: port,
					base: '.'
				}
			}
		},

		zip: {
			'reveal-js-presentation.zip': [
				'index.html',
				'css/**',
				'js/**',
				'lib/**',
				'images/**',
				'plugin/**'
			]
		},

		watch: {
			main: {
				files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
				tasks: 'default'
			},
			theme: {
				files: [ 'css/theme/source/*.scss', 'css/theme/template/*.scss' ],
				tasks: 'themes'
			}
		}

	});

	// Dependencies
	grunt.loadNpmTasks( 'grunt-contrib-qunit' );
	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
	grunt.loadNpmTasks( 'grunt-contrib-watch' );
	grunt.loadNpmTasks( 'grunt-contrib-sass' );
	grunt.loadNpmTasks( 'grunt-contrib-connect' );
	grunt.loadNpmTasks( 'grunt-zip' );

	// Default task
	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify', 'qunit' ] );

	// Theme task
	grunt.registerTask( 'themes', [ 'sass' ] );

	// Package presentation to archive
	grunt.registerTask( 'package', [ 'default', 'zip' ] );

	// Serve presentation locally
	grunt.registerTask( 'serve', [ 'connect', 'watch' ] );

	// Run tests
	grunt.registerTask( 'test', [ 'jshint', 'qunit' ] );

};
<|endoftext|>