<commit_before>// function definitions

var fadeTime = 10;
function openMenu(menu) {
	menu.fadeIn(fadeTime);
	menu.css('top', $('.toolbar table').height());
	if (menu.offset().left + menu.width() > $(window).width()) {
		menu.css('left', $(window).width()- (menu.offset().left + menu.width()));
	}
}

function closeMenu(menu) {
	menu.fadeOut(fadeTime);
}

function startTime() {
	var today = new Date();
	var month = fixMonth(today.getMonth());
	var date = today.getDate();
	var h = fixHours(today.getHours());
	var m = fixMinutes(today.getMinutes());
	var amPm = getAmPm(today.getHours());

	$('.toolbar #clock').html(month + ' ' + date + ', ' + h + ':' + m + ' ' + amPm);
	var previousTime = today;
	var currentTime;
	window.setInterval( function() {
		currentTime = new Date();
		tickTime(previousTime, currentTime);
		previousTime = currentTime;
	}, 1000); // call every second
}

function tickTime(previousTime, currentTime) { // called every second
	if (previousTime.getMinutes() != currentTime.getMinutes()) {
		var minutes = fixMinutes(currentTime.getMinutes());
		if (previousTime.getHours() == currentTime.getHours()) {
			var oldTime = $('.toolbar #clock').html().split(':');
			var oldAmPM = oldTime[1].split(' ')[1];
			$('.toolbar #clock').html(oldTime[0] + ':' + minutes + ' ' + oldAmPM);
		} else {
			// update hours too
			var hours = fixHours(currentTime.getHours());
			var amPm = getAmPm(currentTime.getHours());
			if (previousTime.getDate() == currentTime.getDate()) {
				var oldTime = $('.toolbar #clock').html().split(', ');
				$('.toolbar #clock').html(oldTime[0] + hours + ':' + minutes + ' ' + amPM);
			} else {
				var date = currentTime.getDate();
				if (previousTime.getMonth() == currentTime.getMonth()) {
					var oldTime = $('.toolbar #clock').html().split(' ');
					$('.toolbar #clock').html(oldTime[0] + ' ' + date + hours + ':' + minutes + ' ' + amPM);
				} else {
					var month = fixMonth(currentTime.getMonth());
					$('.toolbar #clock').html(month + ' ' + date + hours + ':' + minutes + ' ' + amPM);
					createCalendar();
				}
			}
		}
	}
}

function fixMonth(month) {
	switch(month) {
		case 0:
			month = 'January';
			break;
		case 1:
			month = 'February';
			break;
		case 2:
			month = 'March';
			break;
		case 3:
			month = 'April';
			break;
		case 4:
			month = 'May';
			break;
		case 5:
			month = 'June';
			break;
		case 6:
			month = 'July';
			break;
		case 7:
			month = 'August';
			break;
		case 8:
			month = 'September';
			break;
		case 9:
			month = 'October';
			break;
		case 10:
			month = 'November';
			break;
		case 11:
			month = 'December';
			break;
		default:
			month = 'Caturday';
			break;
	}
	return month;
}

function getAmPm(h) {
	if (h >= 12) {
		return 'PM';
	} else {
		return 'AM';
	}
}

function fixHours(h) {
	if (h > 12) {
		return h - 12;
	} else if (h == 0) {
		return 12;
	} else {
		return h;
	}
}

function fixMinutes(i) {
    if (i < 10) {i = '0' + i};  // add zero in front of numbers < 10
    return i;
}

function createCalendar() {
	var today = new Date();
	var date = today.getDate();
	var month = today.getMonth() % 13; // there are thirteen moths flying around in the HackNC year.
	var year = today.getFullYear();
	var beginningOfMonth = new Date(year, month, 1, 0, 0, 0, 0);
	var daysInMonth = 0;
	switch (month) {
		case 0:
			month = 'January';
			daysInMonth = 31;
			break;
		case 1:
			month = 'February';
			daysInMonth = (year % 4 == 0 && year % 400 != 0) ? 29 : 28;
			break;
		case 2:
			month = 'March';
			daysInMonth = 31;
			break;
		case 3:
			month = 'April';
			daysInMonth = 30;
			break;
		case 4:
			month = 'May';
			daysInMonth = 31;
			break;
		case 5:
			month = 'June';
			daysInMonth = 30;
			break;
		case 6:
			month = 'July';
			daysInMonth = 31;
			break;
		case 7:
			month = 'August';
			daysInMonth = 31;
			break;
		case 8:
			month = 'September';
			daysInMonth = 30;
			break;
		case 9:
			month = 'October';
			daysInMonth = 31;
			break;
		case 10:
			month = 'November';
			daysInMonth = 30;
			break;
		case 11:
			month = 'December';
			daysInMonth = 31;
			break;
		default:
			month = 'Caturday';
			daysInMonth = 666;
			break;
	}
	var startDay = beginningOfMonth.getDay();
	var i = 1 - startDay;

	var table = '';
	table += '
';
	table += '
' + month + '
';
	table += '

';
	table += '
Sun	Mon	Tue	Wed	Thu	Fri	Sat
';
	for (var week = 0; week < 6; week++) {
		if (i > daysInMonth) {
			break;
		}
		table += '
'
		for (var day = 0; day < 7; day++) {
			if (date == i) {
				table += '';
			} else {
				table += '';
			}
			if (i > 0 && i <= daysInMonth) {
				table += '' + i + '';
			}
			table += '	'
			i++;
		}
		table += '
'
	}
	$('.toolbar #clock + ul.submenu').html(table);
}

var numberOfBatteryImageFrames = 38;
var arbitraryDate = new Date(2014, 6, 6, 6, 6, 6, 6);
var today;
var HackNC = new Date(2014, 9, 25, 11, 0, 0, 0);
function getChargeLevel() {
	today = new Date();
	var percentCharged;
	if (HackNC < today) {
		percentCharged = 1;
	} else {
		percentCharged = (today - arbitraryDate) / (HackNC - arbitraryDate);
	}
	return cachedChargeLevel = Math.floor(percentCharged * numberOfBatteryImageFrames);
}

function doChargeUp() {
	var maxCharge = getChargeLevel();
	var imgs = [];
	for (var i=0; i <= maxCharge; i++) {
		imgs[i] = new Image();
		imgs[i].src = './images/toolbar/battery_' + i + '.png';
	}
	var i = 0;
	window.setInterval(function() {
		if (i <= maxCharge) {
			$('.toolbar #battery img').attr('src', imgs[i++].src);
		}
	}, 250);
}

function setBatteryMenuText() {
	var maxCharge = getChargeLevel();
	$('.toolbar #battery ul.submenu').append('
' +
		Math.floor((today.getTime() - arbitraryDate.getTime()) / (HackNC.getTime() - arbitraryDate.getTime()) * 100000) / 1000 + '% charged
');
}

// code to run

startTime();
createCalendar();
doChargeUp();
setBatteryMenuText();
if (getChargeLevel() != numberOfBatteryImageFrames) {
	window.setInterval(function() {
			doChargeUp();
		}, 10000);
}
//display notification center when icon is clicked
var isNotificationCenterVisible = false;
$('.toolbar #notificationCenter').click( function() {
	if (isNotificationCenterVisible) {
		$('.toolbar .notificationCenter').animate({ right: -250 },'slow', function() {
			$(this).hide();
		});
	}
	else {
		$('.notificationCenter').css('top', $('.toolbar table').height());
		$('.notificationCenter').show().animate({ right: 0 },'slow');

	}
	isNotificationCenterVisible = !isNotificationCenterVisible;
});

//////////////////// Toolbar javascript ///////////////////

// Menubar clicks
var lastOpen;
$('.toolbar ul.topmenu > li > a').click(function() {
	var button = $(this).parent();
	var menu = $(this).next('ul.submenu');
	if(!menu.length) {
		return;
	}
	if (lastOpen) {
		// if a menu is open
		if (lastOpen.hasClass('open') && button.hasClass('open')) {
			// if this is the same menu that was just opened, close it
			closeMenu(menu);
			button.removeClass('open');
			lastOpen = null;
		} else {
			// if this is a different menu than what is already open, close the old and open this
			closeMenu(lastOpen.find('ul.submenu'));
			lastOpen.removeClass('open');
			openMenu(menu);
			button.addClass('open');
			lastOpen = button;
		}
	} else {
		// else no menu is open, open the menu that was clicked
		openMenu(menu);
		button.addClass('open');
		lastOpen = button;
	}
	return false;
});

// Menubar hover.  Hover is enabled after a menu button is clicked.
$('.toolbar ul.topmenu > li').hover(
	// on mouse enter
	function() {
		var button = $(this);
		var menu = $(this).find('ul.submenu');
		if (!menu.length) {
			return;
		}
		if (lastOpen && !button.hasClass('open')) {
			// if a menu is open but it's not this menu, open this and close the old
			closeMenu(lastOpen.find('ul.submenu'));
			lastOpen.removeClass('open');
			openMenu(menu);
			button.addClass('open');
			lastOpen = button;
		}
	},
	// on mouse exit
	function() {
		// do nothing
	});

// Submenu clicks
$('.toolbar ul.topmenu > li').each(function() {
	var button = $(this);
	var menu = button.find('ul.submenu');
	if (!menu.length) {
		return;
	}
	$(this).find('ul.submenu > li > a').click(function() {
		menu.fadeOut(fadeTime);
		button.removeClass('open');
		lastOpen = null;
		if($(this).children('a').hasClass('external')) {
			return true;
		} else {
			return false;
		}
	});
});

// Submenu hover/highlight
$('.toolbar ul.submenu li a').hover(function() {
	$(this).parent().addClass('open');
}, function() {
	$(this).parent().removeClass('open');
});

// Calendar highlight
$('.toolbar .calendar td a').hover(function() {
	$(this).parent().addClass('open');
}, function() {
	$(this).parent().removeClass('open');
});

// Submenu closes on page click
$('.everything:not(.toolbar)').click(function() {
	if (lastOpen) {
		// if a menu is open and the click is not on a new menu
		closeMenu(lastOpen.find('ul.submenu'));
		lastOpen.removeClass('open');
		lastOpen = null;
	}
});

// power button
var poweredOn = true;
var animatingNow = false;
$(function() {
	$('.power').click(function() {
		if (!animatingNow) {
			animatingNow = true;
			if (poweredOn) {
				poweredOn = false;
				$('.everything').fadeOut(400, function() {
					$('.standby').fadeIn();
					animatingNow = false;
				});
			} else {
				$('.standby').fadeOut(200, function() {
					$('.everything').fadeIn();
					poweredOn = true;
					animatingNow = false;
				});
			}
		}
	})
});<commit_msg>clock fixes<commit_after>// function definitions

var fadeTime = 10;
function openMenu(menu) {
	menu.fadeIn(fadeTime);
	menu.css('top', $('.toolbar table').height());
	if (menu.offset().left + menu.width() > $(window).width()) {
		menu.css('left', $(window).width()- (menu.offset().left + menu.width()));
	}
}

function closeMenu(menu) {
	menu.fadeOut(fadeTime);
}

function startTime() {
	var today = new Date();
	var month = fixMonth(today.getMonth());
	var date = today.getDate();
	var h = fixHours(today.getHours());
	var m = fixMinutes(today.getMinutes());
	var amPm = getAmPm(today.getHours());

	$('.toolbar #clock').html(month + ' ' + date + ', ' + h + ':' + m + ' ' + amPm);
	var previousTime = today;
	var currentTime;
	window.setInterval( function() {
		currentTime = new Date();
		tickTime(previousTime, currentTime);
		previousTime = currentTime;
	}, 1000); // call every second
}

function tickTime(previousTime, currentTime) { // called every second
	if (previousTime.getMinutes() != currentTime.getMinutes()) {
		var minutes = fixMinutes(currentTime.getMinutes());
		if (previousTime.getHours() == currentTime.getHours()) {
			var oldTime = $('.toolbar #clock').html().split(':');
			var oldAmPM = oldTime[1].split(' ')[1];
			$('.toolbar #clock').html(oldTime[0] + ':' + minutes + ' ' + oldAmPM);
		} else {
			// update hours too
			var hours = fixHours(currentTime.getHours());
			var amPm = getAmPm(currentTime.getHours());
			if (previousTime.getDate() == currentTime.getDate()) {
				var oldTime = $('.toolbar #clock').html().split(', ');
				$('.toolbar #clock').html(oldTime[0] + ', ' + hours + ':' + minutes + ' ' + amPm);
			} else {
				var date = currentTime.getDate();
				if (previousTime.getMonth() == currentTime.getMonth()) {
					var oldTime = $('.toolbar #clock').html().split(' ');
					$('.toolbar #clock').html(oldTime[0] + ' ' + date + ', ' + hours + ':' + minutes + ' ' + amPm);
				} else {
					var month = fixMonth(currentTime.getMonth());
					$('.toolbar #clock').html(month + ' ' + date + ', ' + hours + ':' + minutes + ' ' + amPm);
					createCalendar();
				}
			}
		}
	}
}

function fixMonth(month) {
	switch(month) {
		case 0:
			month = 'January';
			break;
		case 1:
			month = 'February';
			break;
		case 2:
			month = 'March';
			break;
		case 3:
			month = 'April';
			break;
		case 4:
			month = 'May';
			break;
		case 5:
			month = 'June';
			break;
		case 6:
			month = 'July';
			break;
		case 7:
			month = 'August';
			break;
		case 8:
			month = 'September';
			break;
		case 9:
			month = 'October';
			break;
		case 10:
			month = 'November';
			break;
		case 11:
			month = 'December';
			break;
		default:
			month = 'Caturday';
			break;
	}
	return month;
}

function getAmPm(h) {
	if (h >= 12) {
		return 'PM';
	} else {
		return 'AM';
	}
}

function fixHours(h) {
	if (h > 12) {
		return h - 12;
	} else if (h == 0) {
		return 12;
	} else {
		return h;
	}
}

function fixMinutes(i) {
    if (i < 10) {i = '0' + i};  // add zero in front of numbers < 10
    return i;
}

function createCalendar() {
	var today = new Date();
	var date = today.getDate();
	var month = today.getMonth() % 13; // there are thirteen moths flying around in the HackNC year.
	var year = today.getFullYear();
	var beginningOfMonth = new Date(year, month, 1, 0, 0, 0, 0);
	var daysInMonth = 0;
	switch (month) {
		case 0:
			month = 'January';
			daysInMonth = 31;
			break;
		case 1:
			month = 'February';
			daysInMonth = (year % 4 == 0 && year % 400 != 0) ? 29 : 28;
			break;
		case 2:
			month = 'March';
			daysInMonth = 31;
			break;
		case 3:
			month = 'April';
			daysInMonth = 30;
			break;
		case 4:
			month = 'May';
			daysInMonth = 31;
			break;
		case 5:
			month = 'June';
			daysInMonth = 30;
			break;
		case 6:
			month = 'July';
			daysInMonth = 31;
			break;
		case 7:
			month = 'August';
			daysInMonth = 31;
			break;
		case 8:
			month = 'September';
			daysInMonth = 30;
			break;
		case 9:
			month = 'October';
			daysInMonth = 31;
			break;
		case 10:
			month = 'November';
			daysInMonth = 30;
			break;
		case 11:
			month = 'December';
			daysInMonth = 31;
			break;
		default:
			month = 'Caturday';
			daysInMonth = 666;
			break;
	}
	var startDay = beginningOfMonth.getDay();
	var i = 1 - startDay;

	var table = '';
	table += '
';
	table += '
' + month + '
';
	table += '

';
	table += '
Sun	Mon	Tue	Wed	Thu	Fri	Sat
';
	for (var week = 0; week < 6; week++) {
		if (i > daysInMonth) {
			break;
		}
		table += '
'
		for (var day = 0; day < 7; day++) {
			if (date == i) {
				table += '';
			} else {
				table += '';
			}
			if (i > 0 && i <= daysInMonth) {
				table += '' + i + '';
			}
			table += '	'
			i++;
		}
		table += '
'
	}
	$('.toolbar #clock + ul.submenu').html(table);
}

var numberOfBatteryImageFrames = 38;
var arbitraryDate = new Date(2014, 6, 6, 6, 6, 6, 6);
var today;
var HackNC = new Date(2014, 9, 25, 11, 0, 0, 0);
function getChargeLevel() {
	today = new Date();
	var percentCharged;
	if (HackNC < today) {
		percentCharged = 1;
	} else {
		percentCharged = (today - arbitraryDate) / (HackNC - arbitraryDate);
	}
	return cachedChargeLevel = Math.floor(percentCharged * numberOfBatteryImageFrames);
}

function doChargeUp() {
	var maxCharge = getChargeLevel();
	var imgs = [];
	for (var i=0; i <= maxCharge; i++) {
		imgs[i] = new Image();
		imgs[i].src = './images/toolbar/battery_' + i + '.png';
	}
	var i = 0;
	window.setInterval(function() {
		if (i <= maxCharge) {
			$('.toolbar #battery img').attr('src', imgs[i++].src);
		}
	}, 250);
}

function setBatteryMenuText() {
	var maxCharge = getChargeLevel();
	$('.toolbar #battery ul.submenu').append('
' +
		Math.floor((today.getTime() - arbitraryDate.getTime()) / (HackNC.getTime() - arbitraryDate.getTime()) * 100000) / 1000 + '% charged
');
}

// code to run

startTime();
createCalendar();
doChargeUp();
setBatteryMenuText();
if (getChargeLevel() != numberOfBatteryImageFrames) {
	window.setInterval(function() {
			doChargeUp();
		}, 10000);
}
//display notification center when icon is clicked
var isNotificationCenterVisible = false;
$('.toolbar #notificationCenter').click( function() {
	if (isNotificationCenterVisible) {
		$('.toolbar .notificationCenter').animate({ right: -250 },'slow', function() {
			$(this).hide();
		});
	}
	else {
		$('.notificationCenter').css('top', $('.toolbar table').height());
		$('.notificationCenter').show().animate({ right: 0 },'slow');

	}
	isNotificationCenterVisible = !isNotificationCenterVisible;
});

//////////////////// Toolbar javascript ///////////////////

// Menubar clicks
var lastOpen;
$('.toolbar ul.topmenu > li > a').click(function() {
	var button = $(this).parent();
	var menu = $(this).next('ul.submenu');
	if(!menu.length) {
		return;
	}
	if (lastOpen) {
		// if a menu is open
		if (lastOpen.hasClass('open') && button.hasClass('open')) {
			// if this is the same menu that was just opened, close it
			closeMenu(menu);
			button.removeClass('open');
			lastOpen = null;
		} else {
			// if this is a different menu than what is already open, close the old and open this
			closeMenu(lastOpen.find('ul.submenu'));
			lastOpen.removeClass('open');
			openMenu(menu);
			button.addClass('open');
			lastOpen = button;
		}
	} else {
		// else no menu is open, open the menu that was clicked
		openMenu(menu);
		button.addClass('open');
		lastOpen = button;
	}
	return false;
});

// Menubar hover.  Hover is enabled after a menu button is clicked.
$('.toolbar ul.topmenu > li').hover(
	// on mouse enter
	function() {
		var button = $(this);
		var menu = $(this).find('ul.submenu');
		if (!menu.length) {
			return;
		}
		if (lastOpen && !button.hasClass('open')) {
			// if a menu is open but it's not this menu, open this and close the old
			closeMenu(lastOpen.find('ul.submenu'));
			lastOpen.removeClass('open');
			openMenu(menu);
			button.addClass('open');
			lastOpen = button;
		}
	},
	// on mouse exit
	function() {
		// do nothing
	});

// Submenu clicks
$('.toolbar ul.topmenu > li').each(function() {
	var button = $(this);
	var menu = button.find('ul.submenu');
	if (!menu.length) {
		return;
	}
	$(this).find('ul.submenu > li > a').click(function() {
		menu.fadeOut(fadeTime);
		button.removeClass('open');
		lastOpen = null;
		if($(this).children('a').hasClass('external')) {
			return true;
		} else {
			return false;
		}
	});
});

// Submenu hover/highlight
$('.toolbar ul.submenu li a').hover(function() {
	$(this).parent().addClass('open');
}, function() {
	$(this).parent().removeClass('open');
});

// Calendar highlight
$('.toolbar .calendar td a').hover(function() {
	$(this).parent().addClass('open');
}, function() {
	$(this).parent().removeClass('open');
});

// Submenu closes on page click
$('.everything:not(.toolbar)').click(function() {
	if (lastOpen) {
		// if a menu is open and the click is not on a new menu
		closeMenu(lastOpen.find('ul.submenu'));
		lastOpen.removeClass('open');
		lastOpen = null;
	}
});

// power button
var poweredOn = true;
var animatingNow = false;
$(function() {
	$('.power').click(function() {
		if (!animatingNow) {
			animatingNow = true;
			if (poweredOn) {
				poweredOn = false;
				$('.everything').fadeOut(400, function() {
					$('.standby').fadeIn();
					animatingNow = false;
				});
			} else {
				$('.standby').fadeOut(200, function() {
					$('.everything').fadeIn();
					poweredOn = true;
					animatingNow = false;
				});
			}
		}
	})
});<|endoftext|>


<commit_before>(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        define(['knockout','lodash'], factory);
    } else {
        factory(ko,_);
    }
})(function (ko, _) {
    function isLodash(lodashCalls) {
        return lodashCalls && typeof lodashCalls == 'object' && !_.isArray(lodashCalls) && hasOwnProperty.call(lodashCalls, '__wrapped__')
    };

    function kodashWrapper(obs) {
        this.__observable__ = obs;
        this.__funcs__ = [];
    };
    kodashWrapper['fn'] = kodashWrapper['prototype'];
    var kodashPushFunction = function (wrapper, loFunc, args) {
        wrapper.__funcs__.push({
            loFunc: loFunc,
            args: args,
            comp: null,
            rewrap: false
        });
    };
    var unwrapArgs = function (args) {
        var observableflag = false;
        argArr=[];
        _(args).reverse().each(function (item, index) {
            var arg=item;
            if (ko.isObservable(arg)) {
                arg = ko.utils.unwrapObservable(arg)
            }
            argArr.push(arg)
        });
        return argArr;
    };
    var hasObservableArgs = function (args) {
        var argRev = [];
        return _(args).any(function (item) {
            return ko.isObservable(item)
        });
    };
    _.mixin(kodashWrapper.prototype, _(_.prototype).keys().object().mapValues(function (val, key) {
        return function () {
            var wrapper = new kodashWrapper(this.__observable__)
            wrapper.__funcs__ = wrapper.__funcs__.concat(this.__funcs__);
            kodashPushFunction(wrapper, key, arguments);
            return wrapper;
        }
    }).value());

    var rewrap=function(){
            lastFunc = _.last(this.__funcs__);
            if(lastFunc){
                lastFunc["rewrap"]=true;
            }
            return this;
        };
    var mutap = function () {
            if (ko.isWriteableObservable(this.__observable__)) {
                var loVal = this.wrappedValueOf();
                this.__funcs__ = [];
                this.__observable__((loVal).valueOf());
            }
            return this.__observable__;
        };
    var wrappedValueOf = function () {
            var lofuncs=_(this.__funcs__);
            var lastLofuncs=lofuncs.last(function(item){ return !item.comp });
            var length = -lastLofuncs.value().length;
            length = length? length: this.__funcs__.length;
            lastComp = lofuncs.slice(0,length).last();
            if(lastComp){
                var lodashCalls = _(lastComp.comp.peek());
                lastLofuncs =lastLofuncs.rest()
            }
            else{
                var lodashCalls = _(ko.unwrap(this.__observable__));
                lastLofuncs= lofuncs;
            }

            lastLofuncs.each(function (func) {
                args = unwrapArgs(func['args'])
                if (isLodash(lodashCalls)) {
                    lodashCalls = lodashCalls[func['loFunc']].apply(lodashCalls, args);
                }
            });
            return lodashCalls
        };
    var valueOf = function () {
            return this.wrappedValueOf().valueOf();
        };
    var observe = function () {
            var result = [];
            _(this.__funcs__).each(function (item, index) {
                var lastgroup = result.length ? _.last(result).group : 0;
                var group = hasObservableArgs(item.args) ? lastgroup + 1 : lastgroup;
                result.push({
                    group: group,
                    func: item
                });
            });

            var computed = baseObservable = this.__observable__;
            _(result).groupBy('group').each(function (group) {
                computed = createComputedGroup(group, computed, baseObservable);
            });
            return createUnwrappedComputed(computed);
        }
    _.mixin(kodashWrapper.prototype, {
        _: rewrap,
        rewrap: rewrap,
        mutap: mutap,
        wrappedValueOf: wrappedValueOf,
        wrappedValue: wrappedValueOf,
        valueOf: valueOf,
        value: valueOf,
        observe: observe,
        observeValueOf: observe
    });
    function createUnwrappedComputed(observable){
        if(isLodash(observable.peek()))
            return ko.computed(function(){return observable().valueOf()})
        else
            return observable;
    }
    function createComputedGroup(group, observable, baseObservable) {
        var funcs = _(group).pluck('func')
        var last =funcs.last();
        if(last.comp){
            return last.comp
        }
        return last.comp = ko.computed(function () {
            var lodashCalls = ko.unwrap(observable);
            lodashCalls= (observable === baseObservable)? _(lodashCalls) : lodashCalls
            _(funcs).each(function (func) {
                if (isLodash(lodashCalls)) {
                    var args = unwrapArgs(func['args'])
                    lodashCalls = lodashCalls[func['loFunc']].apply(lodashCalls, args);
                    lodashCalls = func.rewrap? _(lodashCalls) : lodashCalls;
                }
            });
            return lodashCalls;
        })
    };
    ko.observable['fn']['_'] = ko.observable['fn']['kodash'] = function () {
        return new kodashWrapper(this)
    }
});<commit_msg>Changed mutap to mutate<commit_after>(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        define(['knockout','lodash'], factory);
    } else {
        factory(ko,_);
    }
})(function (ko, _) {
    function isLodash(lodashCalls) {
        return lodashCalls && typeof lodashCalls == 'object' && !_.isArray(lodashCalls) && hasOwnProperty.call(lodashCalls, '__wrapped__')
    };

    function kodashWrapper(obs) {
        this.__observable__ = obs;
        this.__funcs__ = [];
    };
    kodashWrapper['fn'] = kodashWrapper['prototype'];
    var kodashPushFunction = function (wrapper, loFunc, args) {
        wrapper.__funcs__.push({
            loFunc: loFunc,
            args: args,
            comp: null,
            rewrap: false
        });
    };
    var unwrapArgs = function (args) {
        var observableflag = false;
        argArr=[];
        _(args).reverse().each(function (item, index) {
            var arg=item;
            if (ko.isObservable(arg)) {
                arg = ko.utils.unwrapObservable(arg)
            }
            argArr.push(arg)
        });
        return argArr;
    };
    var hasObservableArgs = function (args) {
        var argRev = [];
        return _(args).any(function (item) {
            return ko.isObservable(item)
        });
    };
    _.mixin(kodashWrapper.prototype, _(_.prototype).keys().object().mapValues(function (val, key) {
        return function () {
            var wrapper = new kodashWrapper(this.__observable__)
            wrapper.__funcs__ = wrapper.__funcs__.concat(this.__funcs__);
            kodashPushFunction(wrapper, key, arguments);
            return wrapper;
        }
    }).value());

    var rewrap=function(){
            lastFunc = _.last(this.__funcs__);
            if(lastFunc){
                lastFunc["rewrap"]=true;
            }
            return this;
        };
    var mutate = function () {
            if (ko.isWriteableObservable(this.__observable__)) {
                var loVal = this.wrappedValueOf();
                this.__funcs__ = [];
                this.__observable__((loVal).valueOf());
            }
            return this.__observable__;
        };
    var wrappedValueOf = function () {
            var lofuncs=_(this.__funcs__);
            var lastLofuncs=lofuncs.last(function(item){ return !item.comp });
            var length = -lastLofuncs.value().length;
            length = length? length: this.__funcs__.length;
            lastComp = lofuncs.slice(0,length).last();
            if(lastComp){
                var lodashCalls = _(lastComp.comp.peek());
                lastLofuncs =lastLofuncs.rest()
            }
            else{
                var lodashCalls = _(ko.unwrap(this.__observable__));
                lastLofuncs= lofuncs;
            }

            lastLofuncs.each(function (func) {
                args = unwrapArgs(func['args'])
                if (isLodash(lodashCalls)) {
                    lodashCalls = lodashCalls[func['loFunc']].apply(lodashCalls, args);
                }
            });
            return lodashCalls
        };
    var valueOf = function () {
            return this.wrappedValueOf().valueOf();
        };
    var observe = function () {
            var result = [];
            _(this.__funcs__).each(function (item, index) {
                var lastgroup = result.length ? _.last(result).group : 0;
                var group = hasObservableArgs(item.args) ? lastgroup + 1 : lastgroup;
                result.push({
                    group: group,
                    func: item
                });
            });

            var computed = baseObservable = this.__observable__;
            _(result).groupBy('group').each(function (group) {
                computed = createComputedGroup(group, computed, baseObservable);
            });
            return createUnwrappedComputed(computed);
        }
    _.mixin(kodashWrapper.prototype, {
        _: rewrap,
        rewrap: rewrap,
        mutate: mutate,
        wrappedValueOf: wrappedValueOf,
        wrappedValue: wrappedValueOf,
        valueOf: valueOf,
        value: valueOf,
        observe: observe,
        observeValueOf: observe
    });
    function createUnwrappedComputed(observable){
        if(isLodash(observable.peek()))
            return ko.computed(function(){return observable().valueOf()})
        else
            return observable;
    }
    function createComputedGroup(group, observable, baseObservable) {
        var funcs = _(group).pluck('func')
        var last =funcs.last();
        if(last.comp){
            return last.comp
        }
        return last.comp = ko.computed(function () {
            var lodashCalls = ko.unwrap(observable);
            lodashCalls= (observable === baseObservable)? _(lodashCalls) : lodashCalls
            _(funcs).each(function (func) {
                if (isLodash(lodashCalls)) {
                    var args = unwrapArgs(func['args'])
                    lodashCalls = lodashCalls[func['loFunc']].apply(lodashCalls, args);
                    lodashCalls = func.rewrap? _(lodashCalls) : lodashCalls;
                }
            });
            return lodashCalls;
        })
    };
    ko.observable['fn']['_'] = ko.observable['fn']['kodash'] = function () {
        return new kodashWrapper(this)
    }
});<|endoftext|>


<commit_before>var isNode = typeof module != 'undefined' && module.exports;

/**
 * Expects a Fabric.js Canvas
 */
function ImageMarkupBuilder(canvas) {
   if (isNode) {
      var FS = require('fs');
      var Fabric = require('fabric').fabric;
   } else {
      var Fabric = fabric;
   }

   var colorValues = {
      'red': 'rgb(193,40,11)',
      'orange': 'rgb(355,144,36)',
      'yellow': 'rgb(243,224,14)',
      'green': 'rgb(22,220,129)',
      'blue': 'rgb(35,67,232)',
      'violet': 'rgb(220,84,183)',
      'black': 'rgb(0,0,0)'
   };

   var imageOffset;
   var resizeRatio = 1;

   var markupObjects = new Array();

   function clone(obj) {
      var newobj = {};
      for (property in obj) {
         if (typeof obj[property] == 'object') {
            newobj[property] = clone(property);
         } else {
            newobj[property] = obj[property];
         }
      }
      return newobj;
   }

   /**
    * Cycles through an object and changes all numeric fields to ints
    * where necessary. 'context' is used for exception reporting and can be
    * left unset upon invocation.
    */
   function cleanJSON(json, context) {
      if (!context)
         context = "root";

      for (property in json) {
         if (typeof(json[property]) == 'object') {
            cleanJSON(json[property], context + '.' + property);
         }
         else if (property == 'x' || property == 'y' ||
          property == 'width' || property == 'height' ||
          property == 'radius') {
            if (typeof(json[property]) == 'string') {
             json[property] = parseInt(json[property]);
               if (isNaN(json[property])) {
                  var msg = "In '" + context + "': property '" + property +
                   "' is not a number.";
                  throw msg;
               }
            }
         }
      }
   }

   function applyBackground(json, canvas, callback) {
      if (!json['sourceFile']) {
         if (!json['finalDimensions']) {
            var msg = "Need source file or final dimensions to create canvas";
            throw Exception(msg);
         }

         //Apply markup to blank canvas
         applyMarkup(json, canvas, callback);
      } else {
         if (isNode) {
            FS.readFile(json['sourceFile'], function (err, blob) {
               if (err) throw err;

               var dimensions = json['dimensions'];
               var finalDimensions = json['finalDimensions'];
               img = {
                  'width': dimensions['width'],
                  'height': dimensions['height'],
                  'src':blob
               };

               Fabric.Image.fromObject(img, function(fimg) {
                  top = img.height/2 - imageOffset['y'];
                  if (top % 1 != 0) {
                     top -= 0.5;
                  }
                  left = img.width / 2 - imageOffset['x'];
                  if (left % 1 != 0) {
                     left -= 0.5;
                  }

                  canvas.add(fimg.set('top', top).set('left', left));

                  applyMarkup(json, canvas, callback);
               });
            });
         } else {
            throw Exception('Source files not supported on frontend');
         }
      }
   }

   function applyMarkup(json, canvas, callback) {
      for (instruction in json['instructions']) {
         switch (instruction) {
            case 'draw':
               json['instructions']['draw'].forEach(function (e) {
               for (shapeName in e) {
                  shape = e[shapeName];
                  shape['shapeName'] = shapeName;

                  switch (shapeName) {
                     case 'rectangle':
                        drawRectangle(json['finalDimensions']['width'],
                         canvas, shape, imageOffset);
                        break;
                     case 'circle':
                        drawCircle(json['finalDimensions']['width'], canvas,
                         shape, imageOffset);
                        break;
                     default:
                        console.error('Unsupported Shape: ' + shapeName);
                  }
               }
            });
            break;
            case 'crop':
               //もう処理していたから無視する
               break;
            default:
               console.error('Unsupported Instruction: ' + instruction);
         }
      }

      if (isNode) {
         writeCanvas(json, canvas, callback);
      } else {
         callback(canvas);
      }
   }

   function writeCanvas(json, canvas, callback) {
      canvas.renderAll();
      var outstream = FS.createWriteStream(json['destinationFile']),
      stream = canvas.createJPEGStream({
         quality: 93
      });

      stream.on('data', function(chunk) {
         outstream.write(chunk);
      });
      stream.on('end', function () {
         callback(canvas);
      });
   }

   function drawRectangle(finalWidth, canvas, shape, imageOffset) {
      shape['stroke'] = Math.max(Math.round(finalWidth / 300 * 2), 2);
      whiteStroke = 2;

      var rect = {
         shapeName: shape['shapeName'],
         left: shape['from']['x']-imageOffset['x'],
         top: shape['from']['y']-imageOffset['y'],
         width: shape['size']['width'],
         height: shape['size']['height'],
         rx: 1,
         ry: 1,
         strokeWidth: shape['stroke'],
         stroke: colorValues[shape['color']],
         fill: 'transparent'
      }

      //Fabric調整
      rect['top'] = rect['top'] + rect['height'] / 2
       + rect['strokeWidth'] / 2;
      rect['top'] *= resizeRatio;
      rect['left'] = rect['left'] + rect['width'] / 2
       + rect['strokeWidth'] / 2;
      rect['left'] *= resizeRatio;
      rect['width'] *= resizeRatio;
      rect['height'] *= resizeRatio;

      var rectBorder = clone(rect);
      rectBorder['width'] = rectBorder['width'] + rect['strokeWidth']
       + whiteStroke;
      rectBorder['height'] = rectBorder['height'] + rect['strokeWidth']
       + whiteStroke;
      rectBorder['rx'] = rect['strokeWidth'] - whiteStroke;
      rectBorder['ry'] = rect['strokeWidth'] - whiteStroke;
      rectBorder['strokeWidth'] = whiteStroke;
      rectBorder['stroke'] = 'white';

      var rectInline = clone(rect);
      rectInline['width'] = rectInline['width'] - rect['strokeWidth']
       + whiteStroke;
      rectInline['height'] = rectInline['height'] - rect['strokeWidth']
       + whiteStroke;
      rectInline['rx'] = Math.max(shape['stroke'] - rectBorder['rx'],4);
      rectInline['ry'] = Math.max(shape['stroke'] - rectBorder['ry'],4);
      rectInline['strokeWidth'] = whiteStroke;
      rectInline['stroke'] = 'white';

      if (isNode && shadows == true) {
         drawShadow(canvas, rect, shadowStep);
      }

      var fabricRect = new Fabric.Rect(rect),
      fabricBorder = new Fabric.Rect(rectBorder),
      fabricInline = new Fabric.Rect(rectInline);

      fabricRect.lockUniScaling = fabricBorder.lockUniScaling =
         fabricInline.lockUniScaling = true;

      var group = new Fabric.Group([fabricRect, fabricBorder, fabricInline],
       {left: rect['left'], top: rect['top']});

      group.shapeName = 'Rectangle';

      markupObjects.push(group);
      canvas.add(group);
   }

   function drawCircle(finalWidth, canvas, shape, imageOffset) {
      shape['stroke'] = Math.max(Math.round(finalWidth / 300 * 2), 2);
      whiteStroke = 2;

      var circle = {
         shapeName: shape['shapeName'],
         left: shape['from']['x']-imageOffset['x'],
         top: shape['from']['y']-imageOffset['y'],
         radius: shape['radius'],
         strokeWidth: shape['stroke'],
         stroke: colorValues[shape['color']],
         fill: 'transparent'
      };
      circle.left *= resizeRatio;
      circle.top *= resizeRatio;
      circle.radius *= resizeRatio;

      var circleBorder = clone(circle);
      circleBorder['radius'] = circle['radius'] + circle['strokeWidth'] / 2;
      circleBorder['strokeWidth'] = whiteStroke;
      circleBorder['stroke'] = 'white';

      var circleInline = clone(circleBorder);
      circleInline['radius'] = circle['radius'] - circle['strokeWidth'] / 2;

      if (isNode && shadows == true) {
         drawShadow(canvas, circle, shadowStep);
      }

      var fabricCircle = new Fabric.Circle(circle),
      fabricBorder = new Fabric.Circle(circleBorder),
      fabricInline = new Fabric.Circle(circleInline);

      fabricCircle.lockRotation = fabricBorder.lockRotation =
         fabricInline.lockRotation = true;
      fabricCircle.lockUniScaling = fabricBorder.lockUniScaling =
         fabricInline.lockUniScaling = true;

      var group = new Fabric.Group([fabricCircle, fabricBorder, fabricInline],
       {left: fabricCircle['left'], top: fabricCircle['top']});

      group.shapeName = 'Circle';

      markupObjects.push(group);
      canvas.add(group);
   }

   /**
    * Draw a fuzzy shadow for the shape given.
    * Take care to draw the shadow before the shape.
    */
   function drawShadow(canvas, shape, step) {
      if (step < 1) {
         step = 1;
      }
      var shadow = Cloner.clone(shape);
      if (step > shadow['strokeWidth']) {
         step = shadow['strokeWidth'];
      }

      var offsetX = 8;
      var offsetY = offsetX;

      var shadow = Cloner.clone(shape);
      shadow['left'] += offsetX;
      shadow['top'] += offsetY;
      shadow['rx'] = 5;
      shadow['ry'] = 5;
      shadow['stroke'] = 'rgba(0,0,0,0.5)';
      shadow['strokeWidth'] = shadow['strokeWidth'] / step;
      var stepWidth = shadow['strokeWidth'];

      //Empirically-derived pixel tweaks to line up shadow sizes with their
      //parents. TODO: Base these numbers on something real.
      var circleTweak = 0.6875;
      var rectangleTweak = 1.3125;

      //Adjust shadow outlines to outer edge, to work towards inside later.
      switch (shape['shapeName']) {
         case 'circle':
            shadow['radius'] += shape['strokeWidth'] * circleTweak;
            shadow['strokeWidth'] *= 2;
            break;
         case 'rectangle':
            shadow['width'] += shape['strokeWidth'] * rectangleTweak;
            shadow['height'] += shape['strokeWidth'] * rectangleTweak;
            shadow['strokeWidth'] *= 2;
            break;
         default:
            console.error('実装されていない機能：' + shape['shapeName']);
            return;
      }

      var alpha;
      for (var i = 0; i < step; ++i) {
         if (i < (step / 2)) {
            alpha = (((i + 1) * 2) / (step));
         }
         else if (i == step / 2) {
            //Math ain't working to my likings
            alpha = 1;
         }
         else {
            alpha = (((step - (i + 1)) * 2) / (step));
         }

         shadow['stroke'] = 'rgba(0,0,0,' + alpha + ')';

         switch (shape['shapeName']) {
            case 'circle':
               canvas.add(new Fabric.Circle(shadow));
               shadow['radius'] = shadow['radius'] - stepWidth * 2 * 0.8;
               break;
            case 'rectangle':
               canvas.add(new Fabric.Rect(shadow));
               shadow['width'] = shadow['width'] - stepWidth * 4 * 0.8;
               shadow['height'] = shadow['height'] - stepWidth * 4 * 0.8;
               break;
            default:
               console.error('実装されてない機能：' + shape['shapeName']);
               return;
         }
      }
   }

   return {
      processJSON: function processJSON(json, callback) {
         //Make sure not to render every addition on server end
         canvas.renderOnAddition = !isNode;

         cleanJSON(json);

         var imagePath = json['sourceFile'];

         var crop = json['instructions']['crop'];
         imageOffset = (typeof crop != "undefined") ?
            {'x':crop['from']['x'],
               'y':crop['from']['y']} :
                  {'x':0,'y':0};

               if (json['previewInstructions']) {
                  imageOffset.x = json.previewInstructions.left;
                  imageOffset.y = json.previewInstructions.top;
                  resizeRatio = 1 / json.previewInstructions.ratio;
               }

               applyBackground(json, canvas, callback);
      },

      getMarkupObjects: function getMarkupObjects(callback) {
         return markupObjects;
      }
   };
}

if (isNode)
   module.exports = ImageMarkupBuilder;
else
   var createImageFromMarkup = ImageMarkupBuilder;
<commit_msg>Add preview size functionality<commit_after>var isNode = typeof module != 'undefined' && module.exports;

/**
 * Expects a Fabric.js Canvas
 */
function ImageMarkupBuilder(canvas) {
   if (isNode) {
      var FS = require('fs');
      var Fabric = require('fabric').fabric;
   } else {
      var Fabric = fabric;
   }

   var colorValues = {
      'red': 'rgb(193,40,11)',
      'orange': 'rgb(355,144,36)',
      'yellow': 'rgb(243,224,14)',
      'green': 'rgb(22,220,129)',
      'blue': 'rgb(35,67,232)',
      'violet': 'rgb(220,84,183)',
      'black': 'rgb(0,0,0)'
   };

   var imageOffset;
   var resizeRatio = 1;

   var markupObjects = new Array();

   var crop = null;

   function clone(obj) {
      var newobj = {};
      for (property in obj) {
         if (typeof obj[property] == 'object') {
            newobj[property] = clone(property);
         } else {
            newobj[property] = obj[property];
         }
      }
      return newobj;
   }

   /**
    * Cycles through an object and changes all numeric fields to ints
    * where necessary. 'context' is used for exception reporting and can be
    * left unset upon invocation.
    */
   function cleanJSON(json, context) {
      if (!context)
         context = "root";

      for (property in json) {
         if (typeof(json[property]) == 'object') {
            cleanJSON(json[property], context + '.' + property);
         }
         else if (property == 'x' || property == 'y' ||
          property == 'width' || property == 'height' ||
          property == 'radius') {
            if (typeof(json[property]) == 'string') {
             json[property] = parseInt(json[property]);
               if (isNaN(json[property])) {
                  var msg = "In '" + context + "': property '" + property +
                   "' is not a number.";
                  throw msg;
               }
            }
         }
      }
   }

   function applyBackground(json, canvas, callback) {
      if (!json['sourceFile']) {
         if (!json['finalDimensions']) {
            var msg = "Need source file or final dimensions to create canvas";
            throw Exception(msg);
         }

         //Apply markup to blank canvas
         applyMarkup(json, canvas, callback);
      } else {
         if (isNode) {
            FS.readFile(json['sourceFile'], function (err, blob) {
               if (err) throw err;

               var dimensions = json['dimensions'];
               var finalDimensions = json['finalDimensions'];
               img = {
                  'width': dimensions['width'],
                  'height': dimensions['height'],
                  'src':blob
               };

               Fabric.Image.fromObject(img, function(fimg) {
                  top = img.height/2 - imageOffset['y'];
                  if (top % 1 != 0) {
                     top -= 0.5;
                  }
                  left = img.width / 2 - imageOffset['x'];
                  if (left % 1 != 0) {
                     left -= 0.5;
                  }

                  canvas.add(fimg.set('top', top).set('left', left));

                  applyMarkup(json, canvas, callback);
               });
            });
         } else {
            throw Exception('Source files not supported on frontend');
         }
      }
   }

   function applyMarkup(json, canvas, callback) {
      for (instruction in json['instructions']) {
         switch (instruction) {
            case 'draw':
               json['instructions']['draw'].forEach(function (e) {
               for (shapeName in e) {
                  shape = e[shapeName];
                  shape['shapeName'] = shapeName;

                  switch (shapeName) {
                     case 'rectangle':
                        drawRectangle(json['finalDimensions']['width'],
                         canvas, shape, imageOffset);
                        break;
                     case 'circle':
                        drawCircle(json['finalDimensions']['width'], canvas,
                         shape, imageOffset);
                        break;
                     default:
                        console.error('Unsupported Shape: ' + shapeName);
                  }
               }
            });
            break;
            case 'crop':
               //This should already be taken care of in the canvas size
               break;
            default:
               console.error('Unsupported Instruction: ' + instruction);
         }
      }

      if (isNode) {
         writeCanvas(json, canvas, callback);
      } else {
         callback(canvas);
      }
   }

   function writeCanvas(json, canvas, callback) {
      canvas.renderAll();
      var outstream = FS.createWriteStream(json['destinationFile']),
      stream = canvas.createJPEGStream({
         quality: 93
      });

      stream.on('data', function(chunk) {
         outstream.write(chunk);
      });
      stream.on('end', function () {
         callback(canvas);
      });
   }

   function drawRectangle(finalWidth, canvas, shape, imageOffset) {
      shape['stroke'] = Math.max(Math.round(finalWidth / 300 * 2), 2);
      whiteStroke = 2;

      var rect = {
         shapeName: shape['shapeName'],
         left: shape['from']['x']-imageOffset['x'],
         top: shape['from']['y']-imageOffset['y'],
         width: shape['size']['width'],
         height: shape['size']['height'],
         rx: 1,
         ry: 1,
         strokeWidth: shape['stroke'],
         stroke: colorValues[shape['color']],
         fill: 'transparent'
      }

      //Fabric調整
      rect['top'] = rect['top'] + rect['height'] / 2
       + rect['strokeWidth'] / 2;
      rect['top'] *= resizeRatio;
      rect['left'] = rect['left'] + rect['width'] / 2
       + rect['strokeWidth'] / 2;
      rect['left'] *= resizeRatio;
      rect['width'] *= resizeRatio;
      rect['height'] *= resizeRatio;

      rect.shapeFunction = "shape";

      var rectBorder = clone(rect);
      rectBorder['width'] = rectBorder['width'] + rect['strokeWidth']
       + whiteStroke;
      rectBorder['height'] = rectBorder['height'] + rect['strokeWidth']
       + whiteStroke;
      rectBorder['rx'] = rect['strokeWidth'] - whiteStroke;
      rectBorder['ry'] = rect['strokeWidth'] - whiteStroke;
      rectBorder['strokeWidth'] = whiteStroke;
      rectBorder['stroke'] = 'white';

      rectBorder.shapeFunction = "border";

      var rectInline = clone(rect);
      rectInline['width'] = rectInline['width'] - rect['strokeWidth']
       + whiteStroke;
      rectInline['height'] = rectInline['height'] - rect['strokeWidth']
       + whiteStroke;
      rectInline['rx'] = Math.max(shape['stroke'] - rectBorder['rx'],4);
      rectInline['ry'] = Math.max(shape['stroke'] - rectBorder['ry'],4);
      rectInline['strokeWidth'] = whiteStroke;
      rectInline['stroke'] = 'white';

      rectInline.shapeFunction = "inline";

      if (isNode && shadows == true) {
         drawShadow(canvas, rect, shadowStep);
      }

      var fabricRect = new Fabric.Rect(rect),
      fabricBorder = new Fabric.Rect(rectBorder),
      fabricInline = new Fabric.Rect(rectInline);

      var group = new Fabric.Group([fabricRect, fabricBorder, fabricInline],
       {left: rect['left'], top: rect['top']});

      group.shapeName = 'rectangle';

      group.lockRotation = true;
      group.lockUniScaling = true;

      markupObjects.push(group);
      canvas.add(group);
   }

   function drawCircle(finalWidth, canvas, shape, imageOffset) {
      shape['stroke'] = Math.max(Math.round(finalWidth / 300 * 2), 2);
      whiteStroke = 2;

      var circle = {
         shapeName: shape['shapeName'],
         left: shape['from']['x']-imageOffset['x'],
         top: shape['from']['y']-imageOffset['y'],
         radius: shape['radius'],
         strokeWidth: shape['stroke'],
         stroke: colorValues[shape['color']],
         fill: 'transparent'
      };
      circle.left *= resizeRatio;
      circle.top *= resizeRatio;
      circle.radius *= resizeRatio;
      circle.shapeFunction = 'shape';

      var circleBorder = clone(circle);
      circleBorder['radius'] = circle['radius'] + circle['strokeWidth'] / 2;
      circleBorder['strokeWidth'] = whiteStroke;
      circleBorder['stroke'] = 'white';
      circleBorder.shapeFunction = 'border';

      var circleInline = clone(circleBorder);
      circleInline['radius'] = circle['radius'] - circle['strokeWidth'] / 2;
      circleInline.shapeFunction = 'inline';

      if (isNode && shadows == true) {
         drawShadow(canvas, circle, shadowStep);
      }

      var fabricCircle = new Fabric.Circle(circle),
      fabricBorder = new Fabric.Circle(circleBorder),
      fabricInline = new Fabric.Circle(circleInline);

      var group = new Fabric.Group([fabricCircle, fabricBorder, fabricInline],
       {left: fabricCircle['left'], top: fabricCircle['top']});

      group.shapeName = 'circle';

      group.lockRotation = true;
      group.lockUniScaling = true;

      markupObjects.push(group);
      canvas.add(group);
   }

   /**
    * Draw a fuzzy shadow for the shape given.
    * Take care to draw the shadow before the shape.
    */
   function drawShadow(canvas, shape, step) {
      if (step < 1) {
         step = 1;
      }
      var shadow = Cloner.clone(shape);
      if (step > shadow['strokeWidth']) {
         step = shadow['strokeWidth'];
      }

      var offsetX = 8;
      var offsetY = offsetX;

      var shadow = Cloner.clone(shape);
      shadow['left'] += offsetX;
      shadow['top'] += offsetY;
      shadow['rx'] = 5;
      shadow['ry'] = 5;
      shadow['stroke'] = 'rgba(0,0,0,0.5)';
      shadow['strokeWidth'] = shadow['strokeWidth'] / step;
      var stepWidth = shadow['strokeWidth'];

      //Empirically-derived pixel tweaks to line up shadow sizes with their
      //parents. TODO: Base these numbers on something real.
      var circleTweak = 0.6875;
      var rectangleTweak = 1.3125;

      //Adjust shadow outlines to outer edge, to work towards inside later.
      switch (shape['shapeName']) {
         case 'circle':
            shadow['radius'] += shape['strokeWidth'] * circleTweak;
            shadow['strokeWidth'] *= 2;
            break;
         case 'rectangle':
            shadow['width'] += shape['strokeWidth'] * rectangleTweak;
            shadow['height'] += shape['strokeWidth'] * rectangleTweak;
            shadow['strokeWidth'] *= 2;
            break;
         default:
            console.error('実装されていない機能：' + shape['shapeName']);
            return;
      }

      var alpha;
      for (var i = 0; i < step; ++i) {
         if (i < (step / 2)) {
            alpha = (((i + 1) * 2) / (step));
         }
         else if (i == step / 2) {
            //Math ain't working to my likings
            alpha = 1;
         }
         else {
            alpha = (((step - (i + 1)) * 2) / (step));
         }

         shadow['stroke'] = 'rgba(0,0,0,' + alpha + ')';

         switch (shape['shapeName']) {
            case 'circle':
               canvas.add(new Fabric.Circle(shadow));
               shadow['radius'] = shadow['radius'] - stepWidth * 2 * 0.8;
               break;
            case 'rectangle':
               canvas.add(new Fabric.Rect(shadow));
               shadow['width'] = shadow['width'] - stepWidth * 4 * 0.8;
               shadow['height'] = shadow['height'] - stepWidth * 4 * 0.8;
               break;
            default:
               console.error('実装されてない機能：' + shape['shapeName']);
               return;
         }
      }
   }

   return {
      processJSON: function processJSON(json, callback) {
         //Make sure not to render every addition on server end
         canvas.renderOnAddition = !isNode;

         cleanJSON(json);

         var imagePath = json['sourceFile'];

         crop = json['instructions']['crop'];
         imageOffset = (typeof crop != "undefined") ?
            {
               'x': crop['from']['x'],
               'y': crop['from']['y']
            } : {'x': 0,'y': 0};

            if (json['previewInstructions']) {
               imageOffset.x = json.previewInstructions.left;
               imageOffset.y = json.previewInstructions.top;
               resizeRatio = 1 / json.previewInstructions.ratio;
            }

            applyBackground(json, canvas, callback);
      },

      getMarkupObjects: function getMarkupObjects(callback) {
         return markupObjects;
      },

      getMarkupString: function getMarkupString() {
         /**
          * Translate RGB value to applicable color string. Unknown
          * RGB values will will become black and a console.error message
          * will be written.
          */
         function translateRGBtoColorString(rgb) {
            for (colorString in colorValues) {
               if (rgb == colorValues[colorString]) {
                  return colorString;
               }
            }
            console.error("No mapping from RGB to Color String Found: " + rgb);
            return 'black';
         }

         var markupString = ";"

         if (typeof crop != "undefined") {
            markupString += "crop," + crop.from.x + "x" +
             crop.from.y + "," + crop.size.width + "x" +
             crop.size.height + ";";
         }

         for (var i = 0; i < markupObjects.length; ++i) {
            var group = markupObjects[i];

            switch (group.shapeName) {
               case 'circle':
                  var circle = group.objects[0]; //main shape
                  var outline = group.objects[1];
                  var from = {
                     'x': Math.round((group.left - (outline.width - circle.width) / 2)
                      / resizeRatio),
                     'y': Math.round((group.top - (outline.height - circle.height) / 2)
                      / resizeRatio)
                  };
                  var radius = Math.round((circle.width / 2) / resizeRatio);
                  var color = translateRGBtoColorString(circle.stroke);

                  markupString += "circle," + from.x + "x" + from.y + ","
                   + radius + "," + color + ";";
                  break;
               case 'rectangle':
                  var rectangle = group.objects[0]; //main shape
                  var from = {
                     'x': Math.round((group.left - rectangle.width / 2)
                      / resizeRatio),
                     'y': Math.round((group.top - rectangle.height / 2)
                      / resizeRatio)
                  };
                  var size = {
                     'width': Math.round(rectangle.width / resizeRatio),
                     'height': Math.round(rectangle.height / resizeRatio)
                  };

                  markupString += "rectangle," + from.x + "x" + from.y + ","
                   + size.width + "x" + size.height + ";";
                  break;
            }
         }

         return markupString;
      }
   };
}

if (isNode)
   module.exports = ImageMarkupBuilder;
else
   var createImageFromMarkup = ImageMarkupBuilder;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 * Use of this source code is governed by a BSD-style license
 * that can be found in the LICENSE file in the root of the source
 * tree.
 */

/* More information about these options at jshint.com/docs/options */

/* globals trace */
/* exported maybePreferCodec, addCodecParam */

'use strict';

// Sets |codec| as the default |type| codec if it's present.
// The format of |codec| is 'NAME/RATE', e.g. 'opus/48000'.
function maybePreferCodec(sdp, type, dir, codec) {
  var str = type + ' ' + dir + ' codec';
  if (codec === '') {
    trace('No preference on ' + str + '.');
    return sdp;
  }

  trace('Prefer ' + str + ': ' + codec);

  var sdpLines = sdp.split('\r\n');

  // Search for m line.
  var mLineIndex = findLine(sdpLines, 'm=', type);
  if (mLineIndex === null) {
    return sdp;
  }

  // If the codec is available, set it as the default in m line.
  var codecIndex = findLine(sdpLines, 'a=rtpmap', codec);
  if (codecIndex) {
    var payload = getCodecPayloadType(sdpLines[codecIndex]);
    if (payload) {
      sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], payload);
    }
  }

  sdp = sdpLines.join('\r\n');
  return sdp;
}

// Add fmtp param to specified codec in SDP.
function addCodecParam(sdp, codec, param) {
  var sdpLines = sdp.split('\r\n');

  // Find opus payload.
  var index = findLine(sdpLines, 'a=rtpmap', codec);
  var payload;
  if (index) {
    payload = getCodecPayloadType(sdpLines[index]);
  }

  // Find the payload in fmtp line.
  var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + payload.toString());
  if (fmtpLineIndex === null) {
    return sdp;
  }

  sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; ', param);

  sdp = sdpLines.join('\r\n');
  return sdp;
}

// Find the line in sdpLines that starts with |prefix|, and, if specified,
// contains |substr| (case-insensitive search).
function findLine(sdpLines, prefix, substr) {
  return findLineInRange(sdpLines, 0, -1, prefix, substr);
}

// Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix|
// and, if specified, contains |substr| (case-insensitive search).
function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  var realEndLine = endLine !== -1 ? endLine : sdpLines.length;
  for (var i = startLine; i < realEndLine; ++i) {
    if (sdpLines[i].indexOf(prefix) === 0) {
      if (!substr ||
          sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) {
        return i;
      }
    }
  }
  return null;
}

// Gets the codec payload type from an a=rtpmap:X line.
function getCodecPayloadType(sdpLine) {
  var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');
  var result = sdpLine.match(pattern);
  return (result && result.length === 2) ? result[1] : null;
}

// Returns a new m= line with the specified codec as the first one.
function setDefaultCodec(mLine, payload) {
  var elements = mLine.split(' ');
  var newLine = [];
  var index = 0;
  for (var i = 0; i < elements.length; i++) {
    if (index === 3) { // Format of media starts from the fourth.
      newLine[index++] = payload; // Put target payload to the first.
    }
    if (elements[i] !== payload) {
      newLine[index++] = elements[i];
    }
  }
  return newLine.join(' ');
}
<commit_msg>Whitespace change to trigger correct travis run.<commit_after>/*
 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
 *
 * Use of this source code is governed by a BSD-style license
 * that can be found in the LICENSE file in the root of the source
 * tree.
 */

/* More information about these options at jshint.com/docs/options */

/* globals trace */
/* exported maybePreferCodec, addCodecParam */

'use strict';

// Sets |codec| as the default |type| codec if it's present.
// The format of |codec| is 'NAME/RATE', e.g. 'opus/48000'.
function maybePreferCodec(sdp, type, dir, codec) {
  var str = type + ' ' + dir + ' codec';
  if (codec === '') {
    trace('No preference on ' + str + '.');
    return sdp;
  }

  trace('Prefer ' + str + ': ' + codec);

  var sdpLines = sdp.split('\r\n');

  // Search for m line.
  var mLineIndex = findLine(sdpLines, 'm=', type);
  if (mLineIndex === null) {
    return sdp;
  }

  // If the codec is available, set it as the default in m line.
  var codecIndex = findLine(sdpLines, 'a=rtpmap', codec);
  if (codecIndex) {
    var payload = getCodecPayloadType(sdpLines[codecIndex]);
    if (payload) {
      sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], payload);
    }
  }

  sdp = sdpLines.join('\r\n');
  return sdp;
}

// Add fmtp param to specified codec in SDP.
function addCodecParam(sdp, codec, param) {
  var sdpLines = sdp.split('\r\n');

  // Find opus payload.
  var index = findLine(sdpLines, 'a=rtpmap', codec);
  var payload;
  if (index) {
    payload = getCodecPayloadType(sdpLines[index]);
  }

  // Find the payload in fmtp line.
  var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + payload.toString());
  if (fmtpLineIndex === null) {
    return sdp;
  }

  sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; ', param);

  sdp = sdpLines.join('\r\n');
  return sdp;
}

// Find the line in sdpLines that starts with |prefix|, and, if specified,
// contains |substr| (case-insensitive search).
function findLine(sdpLines, prefix, substr) {
  return findLineInRange(sdpLines, 0, -1, prefix, substr);
}

// Find the line in sdpLines[startLine...endLine - 1] that starts with |prefix|
// and, if specified, contains |substr| (case-insensitive search).
function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  var realEndLine = endLine !== -1 ? endLine : sdpLines.length;
  for (var i = startLine; i < realEndLine; ++i) {
    if (sdpLines[i].indexOf(prefix) === 0) {
      if (!substr ||
          sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) {
        return i;
      }
    }
  }
  return null;
}

// Gets the codec payload type from an a=rtpmap:X line.
function getCodecPayloadType(sdpLine) {
  var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+');
  var result = sdpLine.match(pattern);
  return (result && result.length === 2) ? result[1] : null;
}

// Returns a new m= line with the specified codec as the first one.
function setDefaultCodec(mLine, payload) {
  var elements = mLine.split(' ');
  var newLine = [];
  var index = 0;
  for (var i = 0; i < elements.length; i++) {
    if (index === 3) { // Format of media starts from the fourth.
      newLine[index++] = payload; // Put target payload to the first.
    }
    if (elements[i] !== payload) {
      newLine[index++] = elements[i];
    }
  }
  return newLine.join(' ');
}

<|endoftext|>


<commit_before>(function(window,$){"use strict";
/**
 * resizeable-x
 *
 * events
 *       raxdragstart
 *       raxdragmove
 *       raxdragend
 *       raxmove
 *       raxstart
 *       raxend
 *
 *
 * @param Jquery element
 * @returns {jquery-resizeablex_L1.Resizablex}
 * @author xilei
 */
//resize handle html
var handleTpl = '

';

var resizeHandles = {
        n:function(resize){
            var resizeh = resize.h+resize.t-resize.y;
            if(resizeh<resize.options.minh){
                return ;
            }
            resize.h = resizeh;
            resize.t = resize.y;
            resize.top();
            resize.height();
        },
        e:function(resize){
            resize.w = resize.x - resize.l;
            resize.width();
        },
        s:function(resize){
            resize.h = resize.y - resize.t;
            resize.height();
        },
        w:function(resize){
            var resizew = resize.w+resize.l-resize.x;
            if(resizew < resize.options.minw){
                return ;
            }
            resize.w = resizew;
            resize.l = resize.x;
            resize.left();
            resize.width();
        },
        se:function(resize){
            this.s(resize);this.e(resize);
        },
        sw:function(resize){
            this.s(resize);this.w(resize);
        },
        ne:function(resize){
            this.n(resize);this.e(resize);
        },
        nw:function(resize){
            this.n(resize);this.w(resize);
        }
};

var _current = null;

var defaultOptions = {
    minh:10,
    minw:10,
    dragable:true
};

/**
 * resizeable manager
 * @type type
 */
var RaxMananer = {
    _items:{},

    guid:0,

    create:function(element,options){
        var id = element.attr('id') || 'rax_'+this.guid++ ;
        this._items[id] = new Resizablex(element,options);
        return this._items[id];
    },

    get:function(id){
        return this._items[id];
    },

    call:function(fn,params){
        var checked = false,id=null;
        for(id in this._items){
            if(!checked && $.type(this._items[id][fn]) != 'function'){
                break;
            }
            checked = true;
            this._items[id][fn](params);
        }
    }
};

var Resizablex = function(element,options){
         var _pos = element.position();
         this.dom = element;
         this.w = this.dom.width();
         this.h = this.dom.height();
         this.l = _pos.left;
         this.t = _pos.top;
         this.x = 0;
         this.y = 0;
         this.options = $.extend({},defaultOptions,options);
         this.direction = null;
         this.dragoffset = null;
         this.controls = {};
         this.init();
     };

    Resizablex.prototype = {

        init:function(){
            for(var direction in resizeHandles){
                this.controls[direction] = $(handleTpl.replace('{d}',direction));
                this.dom.append(this.controls[direction]);
                this.controls[direction]
                        .bind('mousedown',{direction:direction},$.proxy(this,'_mousedown'));
            }
            if(this.options.dragable){
                this.dom.bind('mousedown',$.proxy(this,'_dragmousedown'));
            }
        },

        _mousedown:function(e){
            if(this.dom.hasClass('rax-disable')){
                return true;
            }
            if(e.button===2)return false;
            e.stopPropagation();
            this.direction = e.data.direction;
            _current = this;
            this.dom.triggerHandler($.Event('raxstart',{rax:this}));
            return true;
        },

        width:function(value){
            if(value){
               this.w = value;
            }
            this.w = this.w < this.options.minw ? this.options.minw :this.w ;
            this.dom.width(this.w);
            return this;
        },
        height:function(value){
            if(value){
               this.h = value;
            }
            this.h = this.h < this.options.minh ? this.options.minh :this.h ;
            this.dom.height(this.h);
            return this;
        },

        left:function(value){
            if(value){
               this.l = value;
            }
            this.dom.css('left',this.l);
        },

        top:function(value){
            if(value){
               this.t = value;
            }
            this.dom.css('top',this.t);
        },

        limit:function(w,h){
            this.options.minw = w>0 ? w : 0;
            this.options.minh = h>0 ? h : 0;
        },

        //@todo disabled some direction  resize
        disable:function(){
            this.dom.addClass('rax-disable');
        },

        //@todo enabled some direction  resize
        enable:function(){
            this.dom.removeClass('rax-disable');
        },

        dragdisable:function(){
            this.dom.addClass('rax-drag-disable');
        },

        dragenable:function(){
           this.dom.removeClass('rax-drag-disable');
        },

        _dragmousedown:function(e){
            if(this.dom.hasClass('rax-drag-disable')){
                return true;
            }
            if(e.button===2)return false;

            e.stopPropagation();
            this.dragoffset = {
                x:e.clientX-this.l,
                y:e.clientY-this.t
            };
            _current = this;
            this.dom.triggerHandler($.Event('raxdragstart',{rax:this}));
        },

        _dragmousemove:function(e){
            this.l = e.clientX-this.dragoffset.x;
            this.t = e.clientY-this.dragoffset.y;
            this.dom.css({'left':this.l,'top':this.t});
        }
};
//less callback
$(window.document).bind('mousemove',function(e){
    if(!_current){
        return true;
    }
    e.preventDefault();
    e.stopPropagation();
    if(_current.direction){
        _current.x = e.clientX;
        _current.y = e.clientY;
        resizeHandles[_current.direction](_current);
        _current.dom.triggerHandler($.Event('raxmove',{rax:_current}));
    }else if(_current.dragoffset){
        _current._dragmousemove(e);
        _current.dom.triggerHandler($.Event('raxdragmove',{rax:_current}));
    }
}).bind('mouseup',function(e){
    if(!_current){
        return true;
    }
    e.stopPropagation();
    if(_current.direction){
        _current.dom.triggerHandler($.Event('raxend',{rax:_current}));
        _current.direction = null;
    }else if(_current.dragoffset){
        _current.dom.triggerHandler($.Event('raxdragend',{rax:_current}));
         _current.dragoffset = null;
    }
    _current = null;
});

/**
 * options object see defaultOptions
 *         string disable|enable|dragdisable|dragenable
 * @returns jquery instance
 */
$.fn.resizeablex = function(options){
    if($.type(options) == 'string' && $.inArray(options,['disable','enable','dragenable','dragdisable'])!=-1){
        RaxMananer.call(options);
    }else{
        this.each(function(){
          RaxMananer.create($(this),options);
        });
    }
    return this;
};

})(window,jQuery);

<commit_msg>Do not check when call $.fn.resizeablex with string<commit_after>(function(window,$){"use strict";
/**
 * resizeable-x
 *
 * events
 *       raxdragstart
 *       raxdragmove
 *       raxdragend
 *       raxmove
 *       raxstart
 *       raxend
 *
 *
 * @param Jquery element
 * @returns {jquery-resizeablex_L1.Resizablex}
 * @author xilei
 */
//resize handle html
var handleTpl = '

';

var resizeHandles = {
        n:function(resize){
            var resizeh = resize.h+resize.t-resize.y;
            if(resizeh<resize.options.minh){
                return ;
            }
            resize.h = resizeh;
            resize.t = resize.y;
            resize.top();
            resize.height();
        },
        e:function(resize){
            resize.w = resize.x - resize.l;
            resize.width();
        },
        s:function(resize){
            resize.h = resize.y - resize.t;
            resize.height();
        },
        w:function(resize){
            var resizew = resize.w+resize.l-resize.x;
            if(resizew < resize.options.minw){
                return ;
            }
            resize.w = resizew;
            resize.l = resize.x;
            resize.left();
            resize.width();
        },
        se:function(resize){
            this.s(resize);this.e(resize);
        },
        sw:function(resize){
            this.s(resize);this.w(resize);
        },
        ne:function(resize){
            this.n(resize);this.e(resize);
        },
        nw:function(resize){
            this.n(resize);this.w(resize);
        }
};

var _current = null;

var defaultOptions = {
    minh:10,
    minw:10,
    dragable:true
};

/**
 * resizeable manager
 * @type type
 */
var RaxMananer = {
    _items:{},

    guid:0,

    create:function(element,options){
        var id = element.attr('id') || 'rax_'+this.guid++ ;
        this._items[id] = new Resizablex(element,options);
        return this._items[id];
    },

    get:function(id){
        return this._items[id];
    },

    call:function(fn,params){
        var checked = false,id=null;
        for(id in this._items){
            if(!checked && $.type(this._items[id][fn]) != 'function'){
                break;
            }
            checked = true;
            this._items[id][fn](params);
        }
    }
};

var Resizablex = function(element,options){
         var _pos = element.position();
         this.dom = element;
         this.w = this.dom.width();
         this.h = this.dom.height();
         this.l = _pos.left;
         this.t = _pos.top;
         this.x = 0;
         this.y = 0;
         this.options = $.extend({},defaultOptions,options);
         this.direction = null;
         this.dragoffset = null;
         this.controls = {};
         this.init();
     };

    Resizablex.prototype = {

        init:function(){
            for(var direction in resizeHandles){
                this.controls[direction] = $(handleTpl.replace('{d}',direction));
                this.dom.append(this.controls[direction]);
                this.controls[direction]
                        .bind('mousedown',{direction:direction},$.proxy(this,'_mousedown'));
            }
            if(this.options.dragable){
                this.dom.bind('mousedown',$.proxy(this,'_dragmousedown'));
            }
        },

        _mousedown:function(e){
            if(this.dom.hasClass('rax-disable')){
                return true;
            }
            if(e.button===2)return false;
            e.stopPropagation();
            this.direction = e.data.direction;
            _current = this;
            this.dom.triggerHandler($.Event('raxstart',{rax:this}));
            return true;
        },

        width:function(value){
            if(value){
               this.w = value;
            }
            this.w = this.w < this.options.minw ? this.options.minw :this.w ;
            this.dom.width(this.w);
            return this;
        },
        height:function(value){
            if(value){
               this.h = value;
            }
            this.h = this.h < this.options.minh ? this.options.minh :this.h ;
            this.dom.height(this.h);
            return this;
        },

        left:function(value){
            if(value){
               this.l = value;
            }
            this.dom.css('left',this.l);
        },

        top:function(value){
            if(value){
               this.t = value;
            }
            this.dom.css('top',this.t);
        },

        limit:function(w,h){
            this.options.minw = w>0 ? w : 0;
            this.options.minh = h>0 ? h : 0;
        },

        //@todo disabled some direction  resize
        disable:function(){
            this.dom.addClass('rax-disable');
        },

        //@todo enabled some direction  resize
        enable:function(){
            this.dom.removeClass('rax-disable');
        },

        dragdisable:function(){
            this.dom.addClass('rax-drag-disable');
        },

        dragenable:function(){
           this.dom.removeClass('rax-drag-disable');
        },

        _dragmousedown:function(e){
            if(this.dom.hasClass('rax-drag-disable')){
                return true;
            }
            if(e.button===2)return false;

            e.stopPropagation();
            this.dragoffset = {
                x:e.clientX-this.l,
                y:e.clientY-this.t
            };
            _current = this;
            this.dom.triggerHandler($.Event('raxdragstart',{rax:this}));
        },

        _dragmousemove:function(e){
            this.l = e.clientX-this.dragoffset.x;
            this.t = e.clientY-this.dragoffset.y;
            this.dom.css({'left':this.l,'top':this.t});
        }
};
//less callback
$(window.document).bind('mousemove',function(e){
    if(!_current){
        return true;
    }
    e.preventDefault();
    e.stopPropagation();
    if(_current.direction){
        _current.x = e.clientX;
        _current.y = e.clientY;
        resizeHandles[_current.direction](_current);
        _current.dom.triggerHandler($.Event('raxmove',{rax:_current}));
    }else if(_current.dragoffset){
        _current._dragmousemove(e);
        _current.dom.triggerHandler($.Event('raxdragmove',{rax:_current}));
    }
}).bind('mouseup',function(e){
    if(!_current){
        return true;
    }
    e.stopPropagation();
    if(_current.direction){
        _current.dom.triggerHandler($.Event('raxend',{rax:_current}));
        _current.direction = null;
    }else if(_current.dragoffset){
        _current.dom.triggerHandler($.Event('raxdragend',{rax:_current}));
         _current.dragoffset = null;
    }
    _current = null;
});

/**
 * options object see defaultOptions
 *         string disable|enable|dragdisable|dragenable
 * @returns jquery instance
 */
$.fn.resizeablex = function(options){
    if($.type(options) == 'string'){
        RaxMananer.call(options);
    }else{
        this.each(function(){
          RaxMananer.create($(this),options);
        });
    }
    return this;
};

})(window,jQuery);

<|endoftext|>


<commit_before>(function($) {
    $.fn.bookmarkletHelperArrow = function(options) {
        // defaults
        var lw = 3;
        var pos = 150;
        var color = '#ffa500'
        // optionally override defaults
        if (options !== undefined) {
            if (options.lw !== undefined)
                lw = options.lw
            if (options.pos !== undefined)
                pos = options.pos
            if (options.color !== undefined)
                color = options.color
        }

        this.click(function() {return false;})
        this.mousedown(function() {
            var move_func = function(e) {
                // drag events are a proxy for mouse events
                if (e.originalEvent !== undefined)
                    e = e.originalEvent;

                // wipe
                ctx.clearRect(0, 0, $(document).width(), $(document).height());
                if (e.clientY < h*3) return;
                // line
                ctx.beginPath();
                ctx.moveTo(e.clientX, e.clientY);
                ctx.quadraticCurveTo(pos, h*5, pos, h-1);
                ctx.stroke();
                // arrow
                ctx.moveTo(pos, 0);
                ctx.beginPath();
                ctx.lineTo(pos - w, h);
                ctx.lineTo(pos, 0);
                ctx.lineTo(pos + w, h);
                ctx.stroke();
                //ctx.closePath();
                //ctx.fill();
            }

            // create canvas for the arrow
            var canvas = $('<canvas>').css({
                position: 'fixed',
                top: 0,
                left: 0,
                'z-index': 1000,
                'pointer-events': 'none'
            }).appendTo('body').get(0);
            canvas.height = $(document).height();
            canvas.width = $(document).width();
            var ctx = canvas.getContext('2d');

            // comput style options
            var w = lw * 2;
            var h = Math.sqrt(3 * w * w)
            // set static style options
            ctx.lineWidth = lw;
            ctx.strokeStyle = color;
            ctx.fillStyle = color;

            // not anonymous so that it can be unbound
            var unbind_move = function() {
                $(window).unbind('mousemove', move_func);
                $(canvas).remove();
            };
            $(window).bind('mousemove', move_func);
            $(window).one('mouseup', unbind_move);
            // switch from move to drag
            $(window).one('dragenter', function() {
                // remove nondrag bindings
                $(window).unbind('mouseup', unbind_move);
                $(window).unbind('mousemove', move_func)
                // setup drag bindings
                $(window).bind('dragover', move_func);
                $(window).one('dragend', function() {
                    $(window).unbind('dragover', move_func);
                    $(canvas).remove();
                });
            });
        });

        return this; // for chaining
    };
})(jQuery);
<commit_msg>make zindex of arrow configurable<commit_after>(function($) {
    $.fn.bookmarkletHelperArrow = function(options) {
        // defaults
        var lw = 3;
        var pos = 150;
        var color = '#ffa500'
        var zindex = 1000;
        // optionally override defaults
        if (options !== undefined) {
            if (options.lw !== undefined)
                lw = options.lw
            if (options.pos !== undefined)
                pos = options.pos
            if (options.color !== undefined)
                color = options.color
            if (options.zindex !== undefined)
                zindex = options.zindex
        }

        this.click(function() {return false;})
        this.mousedown(function() {
            var move_func = function(e) {
                // drag events are a proxy for mouse events
                if (e.originalEvent !== undefined)
                    e = e.originalEvent;

                // wipe
                ctx.clearRect(0, 0, $(document).width(), $(document).height());
                if (e.clientY < h*3) return;
                // line
                ctx.beginPath();
                ctx.moveTo(e.clientX, e.clientY);
                ctx.quadraticCurveTo(pos, h*5, pos, h-1);
                ctx.stroke();
                // arrow
                ctx.moveTo(pos, 0);
                ctx.beginPath();
                ctx.lineTo(pos - w, h);
                ctx.lineTo(pos, 0);
                ctx.lineTo(pos + w, h);
                ctx.stroke();
                //ctx.closePath();
                //ctx.fill();
            }

            // create canvas for the arrow
            var canvas = $('<canvas>').css({
                position: 'fixed',
                top: 0,
                left: 0,
                'z-index': zindex,
                'pointer-events': 'none'
            }).appendTo('body').get(0);
            canvas.height = $(document).height();
            canvas.width = $(document).width();
            var ctx = canvas.getContext('2d');

            // comput style options
            var w = lw * 2;
            var h = Math.sqrt(3 * w * w)
            // set static style options
            ctx.lineWidth = lw;
            ctx.strokeStyle = color;
            ctx.fillStyle = color;

            // not anonymous so that it can be unbound
            var unbind_move = function() {
                $(window).unbind('mousemove', move_func);
                $(canvas).remove();
            };
            $(window).bind('mousemove', move_func);
            $(window).one('mouseup', unbind_move);
            // switch from move to drag
            $(window).one('dragenter', function() {
                // remove nondrag bindings
                $(window).unbind('mouseup', unbind_move);
                $(window).unbind('mousemove', move_func)
                // setup drag bindings
                $(window).bind('dragover', move_func);
                $(window).one('dragend', function() {
                    $(window).unbind('dragover', move_func);
                    $(canvas).remove();
                });
            });
        });

        return this; // for chaining
    };
})(jQuery);
<|endoftext|>