Router.map(function () {
	this.route('frameCalendar', {
		path: '/frame/calendar',
		template: 'frameCalendar',
		layoutTemplate: 'frameCalendar',
		onAfterAction: function() {
			document.title = webpagename + ' Calendar';
		}
	});
});

Template.frameCalendar.onCreated(function() {
	var instance = this;

	// create custom property object
	instance.customProperty = function(key, name, selector) {
		return {
			key: key,
			name: name,
			selector: selector
		};
	};

	instance.eventsRendered = new ReactiveVar(false);
	instance.groupedEvents = new ReactiveVar([]);
	instance.days = new ReactiveVar([]);

	this.autorun(function() {
		var filter = Filtering(EventPredicates)
		             .read(Router.current().params.query)
		             .done();

		var filterParams = filter.toParams();
		filterParams.after = new Date();

		instance.subscribe('eventsFind', filterParams, 200);

		var events = Events.find({}, {sort: {start: 1}}).fetch();
		var groupedEvents = _.groupBy(events, function(event) {
			return moment(event.start).format('LL');
		});

		instance.groupedEvents.set(groupedEvents);
		instance.days.set(Object.keys(groupedEvents));
	});
});

Template.frameCalendar.helpers({
	'ready': function() {
		return Template.instance().subscriptionsReady();
	},

	'days': function() {
		return Template.instance().days.get();
	},

	'eventsOn': function(day) {
		var groupedEvents = Template.instance().groupedEvents.get();
		return groupedEvents[day];
	}
});

Template.frameCalendar.onRendered(function() {
	var instance = this;

	instance.autorun(function() {
		var eventsRendered = instance.eventsRendered.get();
		if (eventsRendered) {
			var query = Router.current().params.query;
			var customProperty = instance.customProperty;

			var customProperties = [
				customProperty('bgcolor', 'background-color', 'body'),
				customProperty('color', 'color', 'body'),
				customProperty('eventbg', 'background-color', '.frame-calendar-event'),
				customProperty('eventcolor', 'color', '.frame-calendar-event'),
				customProperty('linkcolor', 'color', '.frame-calendar-event a')
			];

			_.forEach(customProperties, function(property) {
				var value = query[property.key];

				if (value) {
					value = '#' + value;
					$(property.selector).css(property.name, value);
				}
			});
		}
	});
});

Template.frameCalendarEvent.events({
	'click .js-toggle-event-details': function(e, instance) {
		var jQueryTarget = $(e.currentTarget);

		jQueryTarget.toggleClass('active');
		jQueryTarget.nextAll('.frame-calendar-event-body').toggle();
		jQueryTarget.children('.frame-calendar-event-time').toggle();
	}
});

Template.frameCalendarEvent.onRendered(function() {
	var eventsRendered = this.parentInstance().eventsRendered;
	if (!eventsRendered.get()) eventsRendered.set(true);
});

@@ -304,172 +304,8 @@
 s;%0A%0A
-%09// create custom property object%0A%09instance.customProperty = function(key, name, selector) %7B%0A%09%09return %7B%0A%09%09%09key: key,%0A%09%09%09name: name,%0A%09%09%09selector: selector%0A%09%09%7D;%0A%09%7D;%0A%0A
 %09ins
@@ -1359,32 +1359,150 @@
 stance = this;%0A%0A
+%09function customProperty(key, name, selector) %7B%0A%09%09return %7B%0A%09%09%09key: key,%0A%09%09%09name: name,%0A%09%09%09selector: selector%0A%09%09%7D;%0A%09%7D%0A%0A
 %09instance.autoru
@@ -1644,58 +1644,8 @@
 ry;%0A
-%09%09%09var customProperty = instance.customProperty;%0A%0A
 %09%09%09v
@@ -1984,16 +1984,66 @@
 vent a')
+,%0A%09%09%09%09customProperty('fontsize', 'font-size', '*')
 %0A%09%09%09%5D;%0A%0A
@@ -2131,17 +2131,16 @@
 y.key%5D;%0A
-%0A
 %09%09%09%09if (
@@ -2144,20 +2144,132 @@
 f (value
+) %7B%0A%09%09%09%09%09var propertyName = property.name;%0A%0A%09%09%09%09%09// hexify color values%0A%09%09%09%09%09if (~propertyName.indexOf('color')
 ) %7B%0A
+%09
 %09%09%09%09%09val
@@ -2286,16 +2286,24 @@
  value;%0A
+%09%09%09%09%09%7D%0A%0A
 %09%09%09%09%09$(p

improve setting css values via url query