<commit_before>var CHAR_MAX_LENGTH = 30;

// customized from RelatedObjectLoopups.js
function showRelatedObjectLookupPopup(triggeringLink) {
    var name = triggeringLink.id.replace(/^lookup_/, '');
    name = id_to_windowname(name);
    var href;
    if (triggeringLink.href.search(/\?/) >= 0) {
        href = triggeringLink.href + '&pop=1';
    } else {
        href = triggeringLink.href + '?pop=1';
    }
    //grappelli custom
    var win = window.open(href, name, 'height=500,width=980,resizable=yes,scrollbars=yes');
    // end
    win.focus();
    return false;
}

// customized from RelatedObjectLoopups.js
function dismissRelatedLookupPopup(win, chosenId) {
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
        elem.value += ',' + chosenId;
    } else {
        document.getElementById(name).value = chosenId;
    }
    //grappelli custom
    document.getElementById(name).focus();
    // end
    win.close();
}

// customized from RelatedObjectLoopups.js
function showAddAnotherPopup(triggeringLink) {
    var name = triggeringLink.id.replace(/^add_/, '');
    name = id_to_windowname(name);
    href = triggeringLink.href;
    if (href.indexOf('?') == -1) {
        href += '?_popup=1';
    } else {
        href  += '&_popup=1';
    }
    var win = window.open(href, name, 'height=500,width=1000,resizable=yes,scrollbars=yes');
    win.focus();
    return false;
}

// customized from RelatedObjectLoopups.js
// grappelli custom:
//  - trigger elem.click() to show submit/cancle footer in change_list;
function dismissAddAnotherPopup(win, newId, newRepr) {
    // newId and newRepr are expected to have previously been escaped by
    // django.utils.html.escape.
    newId = html_unescape(newId);
    newRepr = html_unescape(newRepr);
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem) {
        if (elem.nodeName == 'SELECT') {
            var o = new Option(newRepr, newId);
            elem.options[elem.options.length] = o;
            o.selected = true;
        } else if (elem.nodeName == 'INPUT') {
            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
                elem.value += ',' + newId;
            } else {
                elem.value = newId;
            }
        // NOTE: via http://code.djangoproject.com/attachment/ticket/10191/RelatedObjectLookups-updated.js.patch
        // check if the className contains radiolist - if it's HORIZONTAL, then it won't match if we compare explicitly
        } else if (elem.className.indexOf('radiolist') > -1) {
            var cnt = elem.getElementsByTagName('li').length;
            var idName = elem.id+'_'+cnt;
            var newLi = document.createElement('li');
            var newLabel = document.createElement('label');
            var newText = document.createTextNode(' '+newRepr);
            try {
                // IE doesn't support settings name, type, or class by setAttribute
                var newInput = document.createElement('<input type=\'radio\' name=\''+name.slice(3)+'\' checked=\'checked\' class=\''+elem.className+'\' />');
            } catch(err) {
                var newInput = document.createElement('input');
                newInput.setAttribute('class', elem.className);
                newInput.setAttribute('type', 'radio');
                newInput.setAttribute('name', name.slice(3));
            }
            newLabel.setAttribute('for', idName);
            newInput.setAttribute('id', idName);
            newInput.setAttribute('value', newId);
            newInput.setAttribute('checked', 'checked');
            newLabel.appendChild(newInput);
            // check if the content being added is a tag - useful for image lists
            if (newRepr.charAt(0) == '<' && newRepr.charAt(newRepr.length-1) == '>') {
                newLabel.innerHTML += newRepr;
            }
            else {
                newLabel.appendChild(newText);
            }
            newLi.appendChild(newLabel);
            elem.appendChild(newLi);
        }
    } else {
        var toId = name + "_to";
        elem = document.getElementById(toId);
        var o = new Option(newRepr, newId);
        SelectBox.add_to_cache(toId, o);
        SelectBox.redisplay(toId);
    }
    //grappelli custom
    if (elem.click) {
        elem.click();
    }
    // end
    win.close();
}

(function($) {
    function RelatedLookup(obj) {
        // check if val isn't empty string or the same value as before
        if (obj.val() == obj.data('old_val')) return;
        obj.data('old_val', obj.val());

        var link = obj.next();
        var text = obj.next().next();
        var app_label = link.attr('href').split('/')[2];
        var model_name= link.attr('href').split('/')[3];

        if (obj.val() == "") {
            text.text('');
            return;
        }

        text.text('loading ...');

        // get object
        $.get('/grappelli/lookup/related/', {
            object_id: obj.val(),
            app_label: app_label,
            model_name: model_name
        }, function(data) {
            var item = data;
            text.text('');
            if (item) {
                if (item.length > CHAR_MAX_LENGTH) {
                    text.text(decodeURI(item.substr(0, CHAR_MAX_LENGTH) + " ..."));
                } else {
                    text.text(decodeURI(item));
                }

            }
        });
    }

    function M2MLookup(obj) {
        // check if val isn't empty string or the same value as before
        if (obj.val() == obj.data('old_val')) return;
        obj.data('old_val', obj.val());

        var link = obj.next();
        var text = obj.next().next();
        var app_label = link.attr('href').split('/')[2];
        var model_name= link.attr('href').split('/')[3];

        if (obj.val() == "") {
            text.text('');
            return;
        }

        text.text('loading ...');

        // get object
        $.get('/grappelli/lookup/m2m/', {
            object_id: obj.val(),
            app_label: app_label,
            model_name: model_name
        }, function(data) {
            var item = data;
            text.text('');
            if (item) {
                if (item.length > CHAR_MAX_LENGTH) {
                    text.text(decodeURI(item.substr(0, CHAR_MAX_LENGTH) + " ..."));
                } else {
                    text.text(decodeURI(item));
                }
            }
        });
    }

    function GenericLookup(obj) {
        // check if val isn't empty string or the same value as before
        if (obj.val() == obj.data('old_val')) return;
        obj.data('old_val', obj.val());

        var link = obj.next();
        var text = obj.next().next();
        var app_label = link.attr('href').split('/')[2];
        var model_name= link.attr('href').split('/')[3];

        text.text('loading ...');

        // get object
        $.get('/grappelli/lookup/related/', {object_id: obj.val(), app_label: app_label, model_name: model_name}, function(data) {
            var item = data;
            text.text('');
            if (item) {
                if (item.length > CHAR_MAX_LENGTH) {
                    text.text(decodeURI(item.substr(0, CHAR_MAX_LENGTH) + " ..."));
                } else {
                    text.text(decodeURI(item));
                }
            }
        });
    }

    function RelatedHandler(obj) {
        // related lookup handler
        obj.bind("change focus keyup blur", function() {
            RelatedLookup($(this));
        });
    }

    function M2MHandler(obj) {
        // related lookup handler
        obj.bind("change focus keyup blur", function() {
            M2MLookup($(this));
        });
    }

    function InitObjectID(obj) {
        obj.each(function() {
            var ct = $(this).closest('div[class*="object_id"]').prev().find(':input[name*="content_type"]').val();
            if (ct) {
                var lookupLink = $('  ');
                lookupLink.attr('id', 'lookup_'+this.id);
                lookupLink.attr('href', ADMIN_URL + MODEL_URL_ARRAY[ct] + '/?t=id');
                lookupLink.attr('onClick', 'return showRelatedObjectLookupPopup(this);');
                var lookupText = ' ';
                $(this).after(lookupText).after(lookupLink);
                if ($(this).val() != "") {
                    lookupText = GenericLookup($(this));
                }
            }
        });
    }

    function InitContentType(obj) {
        obj.bind("change", function() {
            var node = $(this).closest('div[class*="content_type"]').next(),
                lookupLink = node.find('a.related-lookup'),
                obj_id = next.find('input[name*="object_id"]'),
                href = ADMIN_URL + MODEL_URL_ARRAY[$(this).val()] + "/?t=id";

            if ($(this).val()) {
                if (lookupLink.attr('href')) {
                    lookupLink.attr('href', href);
                } else {
                    lookupLink = $('  ');
                    lookupLink.attr('id', 'lookup_'+obj_id.attr('id'));
                    lookupLink.attr('href', ADMIN_URL + MODEL_URL_ARRAY[$(this).val()] + '/?t=id');
                    lookupLink.attr('onClick', 'return showRelatedObjectLookupPopup(this);');
                    var lookupText = ' ';
                    obj_id.after(lookupText).after(lookupLink);
                }
            } else {
                obj_id.val('');
                lookupLink.remove();
                node.find('strong').remove();
            }
        });
    }

    function GenericHandler(obj) {
        // related lookup handler
        obj.bind("change focus keyup", function() {
            GenericLookup($(this));
        });
    }
    $(document).ready(function() {
        // change related-lookups in order to get the right URL.
        $('a.related-lookup').each(function() {
           href = $(this).attr('href').replace('../../../', ADMIN_URL);
           $(this).attr('href', href);
        });

        // related lookup setup
        $("input.vForeignKeyRawIdAdminField").each(function() {
            // insert empty text-elements after all empty foreignkeys
            if ($(this).val() == "") {
                $(this).next().after(' ');
            }
        });

        // m2m lookup setup
        $("input.vManyToManyRawIdAdminField").each(function() {
            // insert empty text-elements after all m2m fields
            $(this).next().after('  ');
            M2MLookup($(this));
        });

        RelatedHandler($("input.vForeignKeyRawIdAdminField"));
        M2MHandler($("input.vManyToManyRawIdAdminField"));

        InitObjectID($('input[name*="object_id"]'));
        InitContentType($(':input[name*="content_type"]'));
        GenericHandler($('input[name*="object_id"]'));
    });
})(django.jQuery);
<commit_msg>fixed wrong href's for GenericObjects<commit_after>var CHAR_MAX_LENGTH = 30;

// customized from RelatedObjectLoopups.js
function showRelatedObjectLookupPopup(triggeringLink) {
    var name = triggeringLink.id.replace(/^lookup_/, '');
    name = id_to_windowname(name);
    var href;
    if (triggeringLink.href.search(/\?/) >= 0) {
        href = triggeringLink.href + '&pop=1';
    } else {
        href = triggeringLink.href + '?pop=1';
    }
    //grappelli custom
    var win = window.open(href, name, 'height=500,width=980,resizable=yes,scrollbars=yes');
    // end
    win.focus();
    return false;
}

// customized from RelatedObjectLoopups.js
function dismissRelatedLookupPopup(win, chosenId) {
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
        elem.value += ',' + chosenId;
    } else {
        document.getElementById(name).value = chosenId;
    }
    //grappelli custom
    document.getElementById(name).focus();
    // end
    win.close();
}

// customized from RelatedObjectLoopups.js
function showAddAnotherPopup(triggeringLink) {
    var name = triggeringLink.id.replace(/^add_/, '');
    name = id_to_windowname(name);
    href = triggeringLink.href;
    if (href.indexOf('?') == -1) {
        href += '?_popup=1';
    } else {
        href  += '&_popup=1';
    }
    var win = window.open(href, name, 'height=500,width=1000,resizable=yes,scrollbars=yes');
    win.focus();
    return false;
}

// customized from RelatedObjectLoopups.js
// grappelli custom:
//  - trigger elem.click() to show submit/cancle footer in change_list;
function dismissAddAnotherPopup(win, newId, newRepr) {
    // newId and newRepr are expected to have previously been escaped by
    // django.utils.html.escape.
    newId = html_unescape(newId);
    newRepr = html_unescape(newRepr);
    var name = windowname_to_id(win.name);
    var elem = document.getElementById(name);
    if (elem) {
        if (elem.nodeName == 'SELECT') {
            var o = new Option(newRepr, newId);
            elem.options[elem.options.length] = o;
            o.selected = true;
        } else if (elem.nodeName == 'INPUT') {
            if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
                elem.value += ',' + newId;
            } else {
                elem.value = newId;
            }
        // NOTE: via http://code.djangoproject.com/attachment/ticket/10191/RelatedObjectLookups-updated.js.patch
        // check if the className contains radiolist - if it's HORIZONTAL, then it won't match if we compare explicitly
        } else if (elem.className.indexOf('radiolist') > -1) {
            var cnt = elem.getElementsByTagName('li').length;
            var idName = elem.id+'_'+cnt;
            var newLi = document.createElement('li');
            var newLabel = document.createElement('label');
            var newText = document.createTextNode(' '+newRepr);
            try {
                // IE doesn't support settings name, type, or class by setAttribute
                var newInput = document.createElement('<input type=\'radio\' name=\''+name.slice(3)+'\' checked=\'checked\' class=\''+elem.className+'\' />');
            } catch(err) {
                var newInput = document.createElement('input');
                newInput.setAttribute('class', elem.className);
                newInput.setAttribute('type', 'radio');
                newInput.setAttribute('name', name.slice(3));
            }
            newLabel.setAttribute('for', idName);
            newInput.setAttribute('id', idName);
            newInput.setAttribute('value', newId);
            newInput.setAttribute('checked', 'checked');
            newLabel.appendChild(newInput);
            // check if the content being added is a tag - useful for image lists
            if (newRepr.charAt(0) == '<' && newRepr.charAt(newRepr.length-1) == '>') {
                newLabel.innerHTML += newRepr;
            }
            else {
                newLabel.appendChild(newText);
            }
            newLi.appendChild(newLabel);
            elem.appendChild(newLi);
        }
    } else {
        var toId = name + "_to";
        elem = document.getElementById(toId);
        var o = new Option(newRepr, newId);
        SelectBox.add_to_cache(toId, o);
        SelectBox.redisplay(toId);
    }
    //grappelli custom
    if (elem.click) {
        elem.click();
    }
    // end
    win.close();
}

(function($) {
    function RelatedLookup(obj) {
        // check if val isn't empty string or the same value as before
        if (obj.val() == obj.data('old_val')) return;
        obj.data('old_val', obj.val());

        var link = obj.next();
        var text = obj.next().next();
        var app_label = link.attr('href').split('/')[2];
        var model_name= link.attr('href').split('/')[3];

        if (obj.val() == "") {
            text.text('');
            return;
        }

        text.text('loading ...');

        // get object
        $.get('/grappelli/lookup/related/', {
            object_id: obj.val(),
            app_label: app_label,
            model_name: model_name
        }, function(data) {
            var item = data;
            text.text('');
            if (item) {
                if (item.length > CHAR_MAX_LENGTH) {
                    text.text(decodeURI(item.substr(0, CHAR_MAX_LENGTH) + " ..."));
                } else {
                    text.text(decodeURI(item));
                }

            }
        });
    }

    function M2MLookup(obj) {
        // check if val isn't empty string or the same value as before
        if (obj.val() == obj.data('old_val')) return;
        obj.data('old_val', obj.val());

        var link = obj.next();
        var text = obj.next().next();
        var app_label = link.attr('href').split('/')[2];
        var model_name= link.attr('href').split('/')[3];

        if (obj.val() == "") {
            text.text('');
            return;
        }

        text.text('loading ...');

        // get object
        $.get('/grappelli/lookup/m2m/', {
            object_id: obj.val(),
            app_label: app_label,
            model_name: model_name
        }, function(data) {
            var item = data;
            text.text('');
            if (item) {
                if (item.length > CHAR_MAX_LENGTH) {
                    text.text(decodeURI(item.substr(0, CHAR_MAX_LENGTH) + " ..."));
                } else {
                    text.text(decodeURI(item));
                }
            }
        });
    }

    function GenericLookup(obj) {
        // check if val isn't empty string or the same value as before
        if (obj.val() == obj.data('old_val')) return;
        obj.data('old_val', obj.val());

        var link = obj.next();
        var text = obj.next().next();
        var app_label = link.attr('href').split('/')[2];
        var model_name= link.attr('href').split('/')[3];

        text.text('loading ...');

        // get object
        $.get('/grappelli/lookup/related/', {object_id: obj.val(), app_label: app_label, model_name: model_name}, function(data) {
            var item = data;
            text.text('');
            if (item) {
                if (item.length > CHAR_MAX_LENGTH) {
                    text.text(decodeURI(item.substr(0, CHAR_MAX_LENGTH) + " ..."));
                } else {
                    text.text(decodeURI(item));
                }
            }
        });
    }

    function RelatedHandler(obj) {
        // related lookup handler
        obj.bind("change focus keyup blur", function() {
            RelatedLookup($(this));
        });
    }

    function M2MHandler(obj) {
        // related lookup handler
        obj.bind("change focus keyup blur", function() {
            M2MLookup($(this));
        });
    }

    function InitObjectID(obj) {
        obj.each(function() {
            var ct = $(this).closest('div[class*="object_id"]').prev().find(':input[name*="content_type"]').val();
            if (ct) {
                var lookupLink = $('  ');
                lookupLink.attr('id', 'lookup_'+this.id);
                lookupLink.attr('href', ADMIN_URL + MODEL_URL_ARRAY[ct].app + "/" + MODEL_URL_ARRAY[ct].model + '/?t=id');
                lookupLink.attr('onClick', 'return showRelatedObjectLookupPopup(this);');
                var lookupText = ' ';
                $(this).after(lookupText).after(lookupLink);
                if ($(this).val() != "") {
                    lookupText = GenericLookup($(this));
                }
            }
        });
    }

    function InitContentType(obj) {
        obj.bind("change", function() {
            var node = $(this).closest('div[class*="content_type"]').next(),
                lookupLink = node.find('a.related-lookup'),
                obj_id = next.find('input[name*="object_id"]'),
                href = ADMIN_URL + MODEL_URL_ARRAY[$(this).val()] + "/?t=id";

            if ($(this).val()) {
                if (lookupLink.attr('href')) {
                    lookupLink.attr('href', href);
                } else {
                    lookupLink = $('  ');
                    lookupLink.attr('id', 'lookup_' + obj_id.attr('id'));
                    lookupLink.attr('href', ADMIN_URL + MODEL_URL_ARRAY[$(this).val()] + '/?t=id');
                    lookupLink.attr('onClick', 'return showRelatedObjectLookupPopup(this);');
                    var lookupText = ' ';
                    obj_id.after(lookupText).after(lookupLink);
                }
            } else {
                obj_id.val('');
                lookupLink.remove();
                node.find('strong').remove();
            }
        });
    }

    function GenericHandler(obj) {
        // related lookup handler
        obj.bind("change focus keyup", function() {
            GenericLookup($(this));
        });
    }
    $(document).ready(function() {
        // change related-lookups in order to get the right URL.
        $('a.related-lookup').each(function() {
           href = $(this).attr('href').replace('../../../', ADMIN_URL);
           $(this).attr('href', href);
        });

        // related lookup setup
        $("input.vForeignKeyRawIdAdminField").each(function() {
            // insert empty text-elements after all empty foreignkeys
            if ($(this).val() == "") {
                $(this).next().after(' ');
            }
        });

        // m2m lookup setup
        $("input.vManyToManyRawIdAdminField").each(function() {
            // insert empty text-elements after all m2m fields
            $(this).next().after('  ');
            M2MLookup($(this));
        });

        RelatedHandler($("input.vForeignKeyRawIdAdminField"));
        M2MHandler($("input.vManyToManyRawIdAdminField"));

        InitObjectID($('input[name*="object_id"]'));
        InitContentType($(':input[name*="content_type"]'));
        GenericHandler($('input[name*="object_id"]'));
    });
})(django.jQuery);
<|endoftext|>


<commit_before>define([
	'jquery',
	'knockout',

	'Utils',
], function($, ko, Utils){

	function Entity(data){

		//Init
		var self = this;
		data = data || {};

		this.init = function(data){

			self.nextRoundAction = ko.observable(undefined);
			self.nextRoundActionType = ko.observable(undefined);

			self.maxHp = ko.observable(data.maxHp || 5);
			self.hp = ko.observable(data.hp || 5);
			self.armor = ko.observable(data.armor || 0);
			self.speed = ko.observable(data.speed || 1);
			self.minDmg = ko.observable(data.minDmg || 1);
			self.maxDmg = ko.observable(data.maxDmg || 2);

			self.activeEffects = ko.observable({

			});

			self.passiveEffects = ko.observableArray(data.passiveEffects || []);

			self.isDead = ko.computed(function(){
				return self.hp() < 1;
			});

		}

		this.attacks = {

			basic : {
				numAttacks : 1,
				chanceToHit : 1,
				chanceToCrit : 0,
				dmgModifier : 1,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 0
			},
			flurry : {
				numAttacks : 3,
				chanceToHit : 1,
				chanceToCrit : 0,
				dmgModifier : 0.3,
				onHitEffect : function(hitData){

				},
				onMissEffect : {

				},
				baseCooldown : 2
			},
			/*flurry_improved : {
				numAttacks : 3,
				chanceToHit : 0.3,
				chanceToCrit : 0,
				dmgModifier : 2.0,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 0
			},*/
			mighty : {
				numAttacks : 1,
				chanceToHit : 0.5,
				chanceToCrit : 0,
				dmgModifier : 3.0,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 2
			},
			stun : {
				numAttacks : 1,
				chanceToHit : 0.5,
				chanceToCrit : 0,
				dmgModifier : 0.5,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 3
			}

		}

		this.calculateActualDmg = function(dmg){

			var coefficientOfDmgToTake,
				dmgTaken;

			//What % of our AC is the DMG?
			var percentOfArmorDmgIs = Math.round((dmg / self.armor()) * 100);

			if( percentOfArmorDmgIs < 100 ){

				if( percentOfArmorDmgIs <= 25 ){
					coefficientOfDmgToTake = 0;
				}else{
					coefficientOfDmgToTake = (50 - (((100 - percentOfArmorDmgIs) * 0.66))) / 100;
				}

			}else if( percentOfArmorDmgIs > 100 ){

				if(percentOfArmorDmgIs >= 200){
					coefficientOfDmgToTake = 1;
				}else{
					coefficientOfDmgToTake = 1 + (((100 - percentOfArmorDmgIs) * 0.5) / 100)
				}

			}else {
				coefficientOfDmgToTake = 0.5;
			}

			dmgTaken = Math.round(dmg * coefficientOfDmgToTake);

			return dmgTaken;
		}

		this.takeCombatAction = function(action, target, game){

			var actionType = action.actionType;

			if(actionType == 'attack'){

				var attackName = action.actionName;

				self.makeAttack(attackName, target, game);

			}else if(actionType == 'ability'){

				//Figure this out later

			}else if(actionType == 'item'){

				//Figure this out later too!

			}

		}

		this.makeAttack = function(attackName, target, game){

			var numAttacks = 1;
			var chanceToHit = 1.0;
			var chanceToCrit = 0.0;
			var dmgModifier = 1.0;

			//We'll definitely have to implement usage of base entity stats here

			/*
			Flurry of Blows: 3x attacks, 30% chance to hit, 200% of normal dmg, 3 rd cooldown
Mighty Strike: 1x attack, 50% chance to hit, 300% of normal dmg, 2 rd cooldown
Gut Punch: 1x attack, 50% chance to hit, 50% of normal dmg, stuns for two rounds (effective immediately if applicable), 2 rd cooldown
			*/

			if(attackName == 'flurry'){
				numAttacks = 3;
				chanceToHit = 0.3;
				dmgModifier = 2.0;
			}else if(attackName == 'mighty'){
				chanceToHit = 0.5;
				dmgModifier = 3.0;
			}else if(attackName == 'stun'){
				chanceToHit = 0.5;
				dmgModifier = 0.5;
			}

			for(var i = 1; i <= numAttacks; i++){

				var attackResults = Array();
				var hitRoll = Utils.doRand(1, 101);
				var didHit = (hitRoll <= (chanceToHit * 100)) ? true : false ;
				var dmgDealt = 0;
				var hitType = "hit";

				if(didHit){
					var critRoll = Utils.doRand(1, 101);
					var didCrit = (critRoll <= (chanceToCrit * 100)) ? true : false ;

					if(didCrit){
						dmgDealt = self.maxDmg();
						hitType = "crit";
					}else{
						dmgDealt = Utils.doRand( self.minDmg(), (self.maxDmg() + 1) );
					}

					//Yes, we're making assumptions for now
					dmgDealt += self.hasWeapon() ? self.getEquippedWeapon().extraDamage() : 0 ;

					dmgDealt = dmgDealt * dmgModifier;

				}else{
					hitType = "miss";
				}

				var actualDmg = target.calculateActualDmg(dmgDealt);

				attackResults = {
					attemptedDmg : dmgDealt,
					actualDmg : actualDmg,
					hitType : hitType,
					attackType : attackName,
				};

				target.takeDmg(actualDmg);

				//Register the attack
				game.registerAttack(self, target, attackResults);
			}

		}

		this.takeDmg = function(dmg){
			self.hp( self.hp() - dmg );
			return self.hp();
		}

		this.hasArmor = function(){
			return false;
		}

		this.hasWeapon = function(){
			return false;
		}

		this.getEquippedWeapon = function(){
			return false;
		}

		self.init(data);
	}

	Entity.prototype.constructor = Entity;

	return Entity;

});
<commit_msg>Started implementing concept of attacks having on hit/on miss effects<commit_after>define([
	'jquery',
	'knockout',

	'Utils',
], function($, ko, Utils){

	function Entity(data){

		//Init
		var self = this;
		data = data || {};

		this.init = function(data){

			self.nextRoundAction = ko.observable(undefined);
			self.nextRoundActionType = ko.observable(undefined);

			self.maxHp = ko.observable(data.maxHp || 5);
			self.hp = ko.observable(data.hp || 5);
			self.armor = ko.observable(data.armor || 0);
			self.speed = ko.observable(data.speed || 1);
			self.minDmg = ko.observable(data.minDmg || 1);
			self.maxDmg = ko.observable(data.maxDmg || 2);

			self.activeEffects = ko.observable({

			});

			self.passiveEffects = ko.observableArray(data.passiveEffects || []);

			self.isDead = ko.computed(function(){
				return self.hp() < 1;
			});

		}

		this.attacks = {

			basic : {
				numAttacks : 1,
				chanceToHit : 1,
				chanceToCrit : 0,
				dmgModifier : 1,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 0
			},
			flurry : {
				numAttacks : 3,
				chanceToHit : 1,
				chanceToCrit : 0,
				dmgModifier : 0.3,
				onHitEffect : function(hitData){

				},
				onMissEffect : {

				},
				baseCooldown : 2
			},
			/*flurry_improved : {
				numAttacks : 3,
				chanceToHit : 0.3,
				chanceToCrit : 0,
				dmgModifier : 2.0,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 0
			},*/
			mighty : {
				numAttacks : 1,
				chanceToHit : 0.5,
				chanceToCrit : 0,
				dmgModifier : 3.0,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 2
			},
			stun : {
				numAttacks : 1,
				chanceToHit : 0.5,
				chanceToCrit : 0,
				dmgModifier : 0.5,
				onHitEffect : {

				},
				onMissEffect : {

				},
				baseCooldown : 3
			}

		}

		this.calculateActualDmg = function(dmg){

			var coefficientOfDmgToTake,
				dmgTaken;

			//What % of our AC is the DMG?
			var percentOfArmorDmgIs = Math.round((dmg / self.armor()) * 100);

			if( percentOfArmorDmgIs < 100 ){

				if( percentOfArmorDmgIs <= 25 ){
					coefficientOfDmgToTake = 0;
				}else{
					coefficientOfDmgToTake = (50 - (((100 - percentOfArmorDmgIs) * 0.66))) / 100;
				}

			}else if( percentOfArmorDmgIs > 100 ){

				if(percentOfArmorDmgIs >= 200){
					coefficientOfDmgToTake = 1;
				}else{
					coefficientOfDmgToTake = 1 + (((100 - percentOfArmorDmgIs) * 0.5) / 100)
				}

			}else {
				coefficientOfDmgToTake = 0.5;
			}

			dmgTaken = Math.round(dmg * coefficientOfDmgToTake);

			return dmgTaken;
		}

		this.takeCombatAction = function(action, target, game){

			var actionType = action.actionType;

			if(actionType == 'attack'){

				var attackName = action.actionName;

				self.makeAttack(attackName, target, game);

			}else if(actionType == 'ability'){

				//Figure this out later

			}else if(actionType == 'item'){

				//Figure this out later too!

			}

		}

		this.makeAttack = function(attackName, target, game){

			var attackData = this.attacks[attackName];

			var numAttacks = attackData.numAttacks;
			var chanceToHit = attackData.chanceToHit;
			var chanceToCrit = attackData.chanceToCrit;
			var dmgModifier = attackData.dmgModifier;
			var onHitEffect = attackData.onHitEffect;
			var onMissEffect = attackData.onMissEffect;
			var baseCooldown = attackData.baseCooldown;

			for(var i = 1; i <= numAttacks; i++){

				var attackResults = Array();
				var hitRoll = Utils.doRand(1, 101);
				var didHit = (hitRoll <= (chanceToHit * 100)) ? true : false ;
				var hitType = "hit";
				var dmgObject = {
					dmgDealt : 0,
					didCrit : 0,
					dmgModifier : dmgModifier
				}

				if(didHit){
					var critRoll = Utils.doRand(1, 101);
					var didCrit = (critRoll <= (chanceToCrit * 100)) ? true : false ;

					if(didCrit){
						dmgObject.dmgDealt = self.maxDmg();
						hitType = "crit";
					}else{
						dmgObject.dmgDealt = Utils.doRand( self.minDmg(), (self.maxDmg() + 1) );
					}

					//Yes, we're making assumptions for now
					dmgObject.dmgDealt += self.hasWeapon() ? self.getEquippedWeapon().extraDamage() : 0 ;

					dmgObject.dmgDealt = dmgObject.dmgDealt * dmgObject.dmgModifier;

				}else{
					hitType = "miss";
				}

				var actualDmg = target.calculateActualDmg(dmgObject.dmgDealt);

				attackResults = {
					attemptedDmg : dmgObject.dmgDealt,
					actualDmg : actualDmg,
					hitType : hitType,
					attackType : attackName,
				};

				target.takeDmg(actualDmg);

				//Register the attack
				game.registerAttack(self, target, attackResults);
			}

		}

		this.takeDmg = function(dmg){
			self.hp( self.hp() - dmg );
			return self.hp();
		}

		this.hasArmor = function(){
			return false;
		}

		this.hasWeapon = function(){
			return false;
		}

		this.getEquippedWeapon = function(){
			return false;
		}

		self.init(data);
	}

	Entity.prototype.constructor = Entity;

	return Entity;

});
<|endoftext|>


<commit_before>var exporter = require('../lib/ghost-export'),
    fs = require('fs');

describe('export', function() {

  describe('with invalid arguments', function() {
    it('requires a source', function() {
      function testFunction() {
        exporter.export({ destination: 'output' });
      }

      expect(testFunction).toThrow();
    });

    it('requires a destination', function() {
      function testFunction() {
        exporter.export({ source: 'fixtures/ghost' });
      }
      expect(testFunction).toThrow();
    });
  });

  describe('with standard arguments', function() {
    fs.mkdirSync('output');

    exporter.export({
      source: 'fixtures/ghost',
      destination: 'output'
    });

    var output = fs.readdirSync('output');

    it('writes markdown files', function() {
      expect(output).toEqual(['a-test-post.md', 'welcome-to-ghost.md']);
    });

    it('uses content from the specified Ghost app', function() {
      var actual = fs.readFileSync('output/welcome-to-ghost.md', 'utf8'),
          expected = fs.readFileSync('fixtures/expected/default/welcome-to-ghost.md', 'utf8');

      expect(actual).toEqual(expected);
    });

  });

  if (fs.existsSync('output')) {
    fs.rmdirSync('output');
  }

});
<commit_msg>Flow control in spec<commit_after>var exporter = require('../lib/ghost-export'),
    fs = require('fs'),
    path = require('path');

describe('export', function() {

  describe('arguments', function() {
    it('should require a source', function() {
      function testFunction() {
        exporter.export({ destination: 'output' });
      }
      expect(testFunction).toThrow();
    });

    it('should require a destination', function() {
      function testFunction() {
        exporter.export({ source: 'fixtures/ghost' });
      }
      expect(testFunction).toThrow();
    });
  });

  describe('with standard arguments', function() {
    var filesWritten = 0;

    runs(function() {
      if (!fs.existsSync('output')) {
        fs.mkdirSync('output');
      }

      exporter.export({
        source: 'fixtures/ghost',
        destination: 'output'
      }, function(err, count) {
        filesWritten = count;
      });
    });

    waitsFor(function() {
      return (filesWritten > 0);
    });

    it('writes markdown files', function() {
      expect( fs.readdirSync('output') ).toEqual(['a-test-post.md', 'welcome-to-ghost.md']);
    });

    it('uses content from the specified Ghost app', function() {
      var actual = fs.readFileSync('output/a-test-post.md', 'utf8'),
          expected = fs.readFileSync('fixtures/expected/default/a-test-post.md', 'utf8');

      expect(actual).toEqual(expected);
    });
  });

  // teardown
  runs(function() {
    if (fs.existsSync('output')) {
      fs.readdirSync('output').forEach(function(file) {
        fs.unlink( path.join('output', file) );
      });
      fs.rmdirSync('output');
    }
  });

});
<|endoftext|>


<commit_before>import { complete, progress, upload } from '../state/files'
import { connect } from 'react-redux'
import DropWrapper from './DropWrapper'
import Dropzone from 'react-dropzone'
import React, { Component } from 'react'
import UploadIcon from '../../assets/icons/cloud_upload.svg'

class Drop extends Component {
  state = {
    fileOver: false
  }
  handleEnter = () => {
    this.setState((state) => {
      return { fileOver: true }
    })
  }
  handleLeave = () => {
    this.setState((state) => {
      return { fileOver: false }
    })
  }
  handleDrop = (acceptedFiles, rejectedFiles) => {
    // reset state of drop
    this.handleLeave()
    // add files dropped
    acceptedFiles.forEach((file) => {
      this.props.addFile(file)
    })
  }
  render() {
    return (
      <DropWrapper
        active={this.state.fileOver}
        desktopDirections="Drop PDFs to insert pages"
        mobileDirections="Select PDFs to insert pages"
      >
        <Dropzone
          accept="application/pdf"
          style={{
            top: '0',
            bottom: '0',
            width: '100%',
            height: '100%',
            position: 'absolute'
          }}
          onDrop={this.handleDrop}
          onDragEnter={this.handleEnter}
          onDragLeave={this.handleLeave}
        />
        <UploadIcon/>
      </DropWrapper>
    )
  }
}

export default connect(state => state)(Drop)
<commit_msg>Fix IE dropzone issue<commit_after>import { complete, progress, upload } from '../state/files'
import { connect } from 'react-redux'
import DropWrapper from './DropWrapper'
import Dropzone from 'react-dropzone'
import React, { Component } from 'react'
import UploadIcon from '../../assets/icons/cloud_upload.svg'

class Drop extends Component {
  state = {
    fileOver: false
  }
  handleEnter = () => {
    this.setState((state) => {
      return { fileOver: true }
    })
  }
  handleLeave = () => {
    this.setState((state) => {
      return { fileOver: false }
    })
  }
  handleDrop = (acceptedFiles, rejectedFiles) => {
    // reset state of drop
    this.handleLeave()
    // add files dropped
    acceptedFiles.forEach((file) => {
      this.props.addFile(file)
    })
  }
  render() {
    return (
      <DropWrapper
        active={this.state.fileOver}
        desktopDirections="Drop PDFs to insert pages"
        mobileDirections="Select PDFs to insert pages"
      >
        <Dropzone
          accept="application/pdf"
          style={{
            top: '0',
            bottom: '0',
            left: '0',
            right: '0',
            width: '100%',
            height: '100%',
            position: 'absolute'
          }}
          onDrop={this.handleDrop}
          onDragEnter={this.handleEnter}
          onDragLeave={this.handleLeave}
        />
        <UploadIcon/>
      </DropWrapper>
    )
  }
}

export default connect(state => state)(Drop)
<|endoftext|>


<commit_before>const fs = require('fs');
const http = require('http');
const inquirer = require('inquirer');
const urlParser = require('url');
const querystring = require('querystring');
const request = require('request');

const OAUTH_PORT = 3333;

const datafire = require('../index');
const logger = require('../lib/logger');

const QUESTION_SETS = {
  alias: [
    {name: 'alias', message: "Choose an alias for this account:"}
  ],
  basic: [
    {name: 'username', message: "username:"},
    {name: 'password', message: "password:", type: 'password'},
  ],
  apiKey: [
    {name: 'api_key', message: "api_key:"},
  ],
  oauth2: [
    {name: 'access_token', message: "access_token:"},
    {name: 'refresh_token', message: "refresh_token (optional):"},
    {name: 'client_id', message: "client_id (optional):"},
    {name: 'client_secret', message: "client_secret (optional):"},
  ],
}

let setDefaults = (questions, defaults) => {
  return questions.map(q => {
    return {
      name: q.name,
      message: q.message,
      type: q.type,
      default: defaults[q.name],
    }
  });
}

let getAccounts = (integration) => {
  let credFile = datafire.credentialsDirectory + '/' + integration + '.json';
  return fs.existsSync(credFile) ? require(credFile) : {};
}

module.exports = (args) => {
  try {
    fs.mkdirSync(datafire.credentialsDirectory);
  } catch (e) {}

  let integration = datafire.Integration.new(args.integration);
  integration.initialize(err => {
    if (err) throw err;
    let secDefs = integration.spec.securityDefinitions;
    if (!secDefs || !Object.keys(secDefs).length) {
      logger.logError("No security definitions found for " + args.integration);
      return;
    }
    let secOptions = Object.keys(secDefs).map(name => {
      return {
        name: name,
        def: secDefs[name],
      }
    });
    let accounts = getAccounts(integration.name);
    let accountToEdit = null;
    let secOption = secOptions[0];
    if (args.as) {
      accountToEdit = accounts[args.as];
      if (!accountToEdit) throw new Error("Account " + args.as + " not found");
      secOption = secOptions.filter(o => o.name === accountToEdit.securityDefinition)[0];
      if (!secOption) throw new Error("Security definition " + accountToEdit.securityDefinition + " not found");
    }
    if (args.generate_token) {
      startOAuthServer(integration, secOption.def, accounts, accountToEdit)
    } else if (secOptions.length === 1) {
      authenticate(integration, secOption, accounts, accountToEdit);
    } else if (accountToEdit) {
      authenticate(integration, secOption, accounts, accountToEdit);
    } else {
      let question = {name: 'definition', message: "This API has multiple authentication flows. Which do you want to use?", type: 'list'};
      question.choices = secOptions.map(o => ({name: o.def.type + ' (' + o.name + ')', value: o}))
      inquirer.prompt([question]).then(answer => {
        authenticate(integration, answer.definition, accounts, accountToEdit);
      })
    }
  })
}

let authenticate = (integration, secDef, accounts, accountToEdit) => {
  let questions = QUESTION_SETS[secDef.def.type];
  if (accountToEdit && secDef.def.type === 'oauth2') {
    logger.log("You can retrieve an access token here:\n" + getOAuthURL(integration, secDef.def, accountToEdit.client_id));
  }
  if (accountToEdit) questions = setDefaults(questions, accountToEdit);
  inquirer.prompt(questions).then(answers => {
    for (let k in answers) {
      if (!answers[k]) delete answers[k];
    }
    answers.securityDefinition = secDef.name;
    if (accountToEdit) {
      for (let k in answers) accountToEdit[k] = answers[k];
      saveAccounts(integration, accounts);
      return
    } else {
      inquirer.prompt(QUESTION_SETS.alias).then(aliasAnswer => {
        accounts[aliasAnswer.alias] = answers;
        saveAccounts(integration, accounts);
      })
    }
  })
}

let saveAccounts = (integration, accounts) => {
  let oldCreds = getAccounts(integration.name);
  let credFile = datafire.credentialsDirectory + '/' + integration.name + '.json';
  logger.log('Saving credentials to ' + credFile.replace(process.cwd(), '.'));
  fs.writeFileSync(credFile, JSON.stringify(accounts, null, 2));
}

let getOAuthURL = (integration, secDef, clientId) => {
  var flow = secDef.flow;
  var url = secDef.authorizationUrl;
  var scopes = [Object.keys(secDef.scopes)[0]];
  var state = Math.random();
  var redirect = 'http://localhost:' + OAUTH_PORT;
  url += '?response_type=code';// + (flow === 'implicit' ? 'token' : 'code');
  url += '&redirect_uri=' + redirect;
  url += '&client_id=' + encodeURIComponent(clientId);
  url += '&access_type=offline';
  if (scopes.length > 0) {
    url += '&scope=' + encodeURIComponent(scopes.join(' '));
  }
  url += '&state=' + encodeURIComponent(state);
  return url;
}

let startOAuthServer = (integration, secDef, accounts, accountToEdit) => {
  if (integration.name === 'gmail') {
    secDef.flow = 'code';
    secDef.tokenUrl = 'https://www.googleapis.com/oauth2/v4/token';
  }
  let server = http.createServer((req, res) => {
    let search = urlParser.parse(req.url).search || '?';
    search = search.substring(1);
    if (search) {
      search = querystring.parse(search);
      request.post({
        url: secDef.tokenUrl,
        form: {
          code: search.code,
          client_id: accountToEdit.client_id,
          client_secret: accountToEdit.client_secret,
          redirect_uri: 'http://localhost:3333',
          grant_type: 'authorization_code',
        },
        json: true,
      }, (err, resp, body) => {
        let newURL = '/#access_token=' + encodeURIComponent(body.access_token);
        newURL += '&refresh_token=' + encodeURIComponent(body.refresh_token);
        newURL += '&saved=true';
        res.writeHead(302, {
          'Location': newURL,
        });
        res.end();
        accountToEdit.access_token = body.access_token;
        accountToEdit.refresh_token = body.refresh_token;
        saveAccounts(integration, accounts);
        server.close();
      })
    } else {
      fs.readFile(__dirname + '/../www/oauth_callback.html', 'utf8', (err, data) => {
        if (err) throw err;
        res.end(data);
        server.close();
      })
    }
  }).listen(OAUTH_PORT, (err) => {
    if (err) throw err;
    let url = getOAuthURL(integration, secDef, accountToEdit.client_id);
    logger.log("Visit this url to retrieve your access and refresh tokens:")
    logger.logURL(url);
  });
}
<commit_msg>fix up oauth flows<commit_after>const fs = require('fs');
const http = require('http');
const inquirer = require('inquirer');
const urlParser = require('url');
const querystring = require('querystring');
const request = require('request');

const OAUTH_PORT = 3333;

const datafire = require('../index');
const logger = require('../lib/logger');

const QUESTION_SETS = {
  alias: [
    {name: 'alias', message: "Choose an alias for this account:"}
  ],
  basic: [
    {name: 'username', message: "username:"},
    {name: 'password', message: "password:", type: 'password'},
  ],
  apiKey: [
    {name: 'api_key', message: "api_key:"},
  ],
  oauth_client: [
    {name: 'client_id', message: "client_id:"},
    {name: 'client_secret', message: "client_secret:"},
  ],
  oauth_tokens: [
    {name: 'access_token', message: "access_token:"},
    {name: 'refresh_token', message: "refresh_token (optional):"},
  ],
}

QUESTION_SETS.oauth2 = QUESTION_SETS.oauth_tokens.concat(QUESTION_SETS.oauth_client);

let setDefaults = (questions, defaults) => {
  return questions.map(q => {
    return {
      name: q.name,
      message: q.message,
      type: q.type,
      default: defaults[q.name],
    }
  });
}

let getAccounts = (integration) => {
  let credFile = datafire.credentialsDirectory + '/' + integration + '.json';
  return fs.existsSync(credFile) ? require(credFile) : {};
}

module.exports = (args) => {
  try {
    fs.mkdirSync(datafire.credentialsDirectory);
  } catch (e) {}

  let integration = datafire.Integration.new(args.integration);
  integration.initialize(err => {
    if (err) throw err;
    let secDefs = integration.spec.securityDefinitions;
    if (!secDefs || !Object.keys(secDefs).length) {
      logger.logError("No security definitions found for " + args.integration);
      return;
    }
    let secOptions = Object.keys(secDefs).map(name => {
      return {
        name: name,
        def: secDefs[name],
      }
    });
    let accounts = getAccounts(integration.name);
    let accountToEdit = null;
    let secOption = secOptions[0];
    if (args.as) {
      accountToEdit = accounts[args.as];
      if (!accountToEdit) throw new Error("Account " + args.as + " not found");
      secOption = secOptions.filter(o => o.name === accountToEdit.securityDefinition)[0];
      if (!secOption) throw new Error("Security definition " + accountToEdit.securityDefinition + " not found");
    }
    if (args.generate_token) {
      let clientAccount = accountToEdit;
      if (args.client) {
        clientAccount = accounts[args.client];
      }
      generateToken(integration, secOption, accounts, accountToEdit, clientAccount);
    } else if (secOptions.length === 1) {
      authenticate(integration, secOption, accounts, accountToEdit);
    } else if (accountToEdit) {
      authenticate(integration, secOption, accounts, accountToEdit);
    } else {
      let question = {name: 'definition', message: "This API has multiple authentication flows. Which do you want to use?", type: 'list'};
      question.choices = secOptions.map(o => ({name: o.def.type + ' (' + o.name + ')', value: o}))
      inquirer.prompt([question]).then(answers => {
        authenticate(integration, answers.definition, accounts, accountToEdit);
      })
    }
  })
}

let authenticate = (integration, secOption, accounts, accountToEdit) => {
  let questions = QUESTION_SETS[secOption.def.type];
  if (accountToEdit) questions = setDefaults(questions, accountToEdit);
  inquirer.prompt(questions).then(answers => {
    for (let k in answers) {
      if (!answers[k]) delete answers[k];
    }
    answers.securityDefinition = secOption.name;
    if (accountToEdit) {
      for (let k in answers) accountToEdit[k] = answers[k];
      saveAccounts(integration, accounts);
      return
    } else {
      inquirer.prompt(QUESTION_SETS.alias).then(aliasAnswer => {
        accounts[aliasAnswer.alias] = answers;
        saveAccounts(integration, accounts);
      })
    }
  })
}

let generateToken = (integration, secOption, accounts, accountToEdit, clientAccount) => {
  let questions = [];
  if (!accountToEdit) questions = questions.concat(QUESTION_SETS.alias);
  if (!clientAccount) questions = questions.concat(QUESTION_SETS.oauth_client);
  inquirer.prompt(questions).then(answers => {
    if (answers.alias) accountToEdit = accounts[answers.alias] = {};
    if (answers.client_id) accountToEdit.client_id = answers.client_id;
    if (answers.client_secret) accountToEdit.client_secret = answers.client_secret;
    if (!clientAccount) clientAccount = accountToEdit;
    accountToEdit.securityDefinition = secOption.name;
    startOAuthServer(integration, secOption.def, accounts, accountToEdit, clientAccount)
  })
}
let saveAccounts = (integration, accounts) => {
  let oldCreds = getAccounts(integration.name);
  let credFile = datafire.credentialsDirectory + '/' + integration.name + '.json';
  logger.log('Saving credentials to ' + credFile.replace(process.cwd(), '.'));
  fs.writeFileSync(credFile, JSON.stringify(accounts, null, 2));
}

let getOAuthURL = (integration, secDef, clientId, scopes) => {
  var flow = secDef.flow;
  var url = secDef.authorizationUrl;
  var state = Math.random();
  var redirect = 'http://localhost:' + OAUTH_PORT;
  url += '?response_type=' + (flow === 'implicit' ? 'token' : 'code');
  url += '&redirect_uri=' + redirect;
  url += '&client_id=' + encodeURIComponent(clientId);
  if (flow === 'accessCode') url += '&access_type=offline';
  if (scopes.length > 0) {
    url += '&scope=' + encodeURIComponent(scopes.join(' '));
  }
  url += '&state=' + encodeURIComponent(state);
  return url;
}

let startOAuthServer = (integration, secDef, accounts, accountToEdit, clientAccount) => {
  let server = http.createServer((req, res) => {
    let urlObj = urlParser.parse(req.url);
    if (urlObj.pathname !== '/') {
      res.writeHead(404);
      res.end();
      return;
    }
    let search = urlParser.parse(req.url).search || '?';
    search = search.substring(1);
    search = querystring.parse(search);
    if (search.code) {
      request.post({
        url: secDef.tokenUrl,
        form: {
          code: search.code,
          client_id: clientAccount.client_id,
          client_secret: clientAccount.client_secret,
          redirect_uri: 'http://localhost:3333',
          grant_type: 'authorization_code',
        },
        json: true,
      }, (err, resp, body) => {
        let newURL = '/?saved=true#access_token=' + encodeURIComponent(body.access_token);
        newURL += '&refresh_token=' + encodeURIComponent(body.refresh_token);
        newURL += '&saved=true';
        res.writeHead(302, {
          'Location': newURL,
        });
        res.end();
        accountToEdit.access_token = body.access_token;
        accountToEdit.refresh_token = body.refresh_token;
        saveAccounts(integration, accounts);
      })
    } else {
      fs.readFile(__dirname + '/../www/oauth_callback.html', 'utf8', (err, data) => {
        if (err) throw err;
        res.end(data);
        if (!search.saved) {
          inquirer.prompt(QUESTION_SETS.oauth_tokens).then(answers => {
            accountToEdit.access_token = answers.access_token;
            accountToEdit.refresh_token = answers.refresh_token;
            saveAccounts(integration, accounts);
            server.close();
            process.exit(0);
          })
        } else {
          server.close();
          process.exit(0);
        }
      })
    }
  }).listen(OAUTH_PORT, (err) => {
    if (err) throw err;
    let scope = Object.keys(secDef.scopes)[0];
    let url = getOAuthURL(integration, secDef, clientAccount.client_id, [scope]);
    logger.log("Visit this url to retrieve your access and refresh tokens:")
    logger.logURL(url);
  });
}
<|endoftext|>


<commit_before>/**
 * Created by denistrofimov on 26.01.16.
 */

var fs = require('fs');
var path = require('path');
var utils = require('../utils/index');
var _ = require('lodash');
var async = require('async');
var Promise = require('bluebird');
var express = require('express');

var _handler = function (controller) {
    return function (req, res, next) {
        var method = req.params['method'];
        if (!_.isFunction(controller[method])) {
            if (_.isFunction(controller['@remap']))
                controller['@remap'].apply(controller, [req, res, next]);
            else
                return next();
        }
        controller[method].apply(controller, [req, res, next]);
    }
};

var _route = function (controller, relative) {
    if (_.isString(controller['@route']))
        return controller['@route'];

    var route;
    var name = path.basename(relative, '.js');
    if (name == 'index')
        route = path.dirname(relative);
    else
        route = relative.replace(/\.[^.$]+$/, '');

    return path.join('/', route, ':method');
};

module.exports = {
    /**
     * Inject controllers
     * @param {string} directory Root directory for injection
     * @param {Core} core application core
     * @returns {Promise|bluebird}
     */
    inject: function (directory, core) {

        directory = path.normalize(directory);

        console.info('\nMount controllers from %s\n', directory);

        var tasks = utils.inspect(directory).map(function (file) {

            return function (cb) {
                var loader = require(file);

                var controller = loader(core);
                if (!_.isObject(controller))
                    return cb(new Error('Controller "' + path.basename(file, '.js') + '" must be an object'));

                var relative = path.relative(directory, file);
                var route = _route(controller, relative);
                var method = (controller['@method'] || 'all').toLowerCase();

                cb(null, {
                    route: route,
                    method: method,
                    handler: _handler(controller)
                });

                console.info('\tController "%s" has been mounted on route "%s" for %s requests', path.basename(file, '.js'), route, method);
            }
        });

        return new Promise(function (resolve, reject) {
            async.parallel(tasks, function (err, controllers) {
                if (err)
                    return reject(err);

                var route = new express.Router();

                controllers.forEach(function (controller) {
                    route[controller.method](controller.route, controller.handler);
                });

                return resolve(route);
            });
        });
    }
};<commit_msg>controller before<commit_after>/**
 * Created by denistrofimov on 26.01.16.
 */

var fs = require('fs');
var path = require('path');
var utils = require('../utils/index');
var _ = require('lodash');
var async = require('async');
var Promise = require('bluebird');
var express = require('express');

var _handler = function (controller) {
    return function (req, res, next) {
        var method = req.params['method'];
        if (!_.isFunction(controller[method])) {
            if (_.isFunction(controller['@remap']))
                controller['@remap'].apply(controller, [req, res, next]);
            else
                return next();
        }
        controller[method].apply(controller, [req, res, next]);
    }
};

var _route = function (controller, relative) {
    if (_.isString(controller['@route']))
        return controller['@route'];

    var route;
    var name = path.basename(relative, '.js');
    if (name == 'index')
        route = path.dirname(relative);
    else
        route = relative.replace(/\.[^.$]+$/, '');

    return path.join('/', route, ':method');
};

module.exports = {
    /**
     * Inject controllers
     * @param {string} directory Root directory for injection
     * @param {Core} core application core
     * @returns {Promise|bluebird}
     */
    inject: function (directory, core) {

        directory = path.normalize(directory);

        console.info('\nMount controllers from %s\n', directory);

        var tasks = utils.inspect(directory).map(function (file) {

            return function (cb) {
                var loader = require(file);

                var controller = loader(core);
                if (!_.isObject(controller))
                    return cb(new Error('Controller "' + path.basename(file, '.js') + '" must be an object'));

                var relative = path.relative(directory, file);
                var route = _route(controller, relative);
                var method = (controller['@method'] || 'all').toLowerCase();

                cb(null, {
                    route: route,
                    method: method,
                    before: controller['@before'],
                    handler: _handler(controller)
                });

                console.info('\tController "%s" has been mounted on route "%s" for %s requests', path.basename(file, '.js'), route, method);
            }
        });

        return new Promise(function (resolve, reject) {
            async.parallel(tasks, function (err, controllers) {
                if (err)
                    return reject(err);

                var route = new express.Router();

                controllers.forEach(function (controller) {
                    if (controller.before)
                        route[controller.method](controller.route, controller.before);
                    route[controller.method](controller.route, controller.handler);
                });

                return resolve(route);
            });
        });
    }
};<|endoftext|>


<commit_before>// @ts-check

// Maintains a cache of all info.json files in /.~info.json.cache/ directory
// (Downloads only the missing info.json files)

const request = require("request-promise");
const fs = require("fs");
const path = require("path");

const INFO_JSON_CACHE_DIR = ".~info.json.cache";

/**
 * Chunking (immutable)
 *
 * @template T
 * @param arr {T[]}
 * @param size {number}
 * @return T[]
 */
const chunk = (arr, size) => {
    let copy = [...arr];
    let results = [];
    while (copy.length) results.push(copy.splice(0, size));
    return results;
};

/**
 * Convert URL to filename
 * @param url {string}
 */
const urlToFilename = url => {
    return url.replace(/[^a-z0-9.]+/gi, "_");
};

/**
 * Request URL by GET
 *
 * @param {string} url
 */
const get = url => {
    return request.get({
        headers: {
            "User-Agent": "Request",
        },
        url: url,
        json: true,
    });
};

/**
 * Main program
 *
 * @returns {Promise<{[key: string]: any}>}
 */
const getInfoJsonMap = async (clearCache = false) => {
    console.log("Downloading info.json listing from GitHub...");
    /** @type {{items: {html_url: string}[]}[]} */
    let searchResults = await Promise.all([
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=2"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=3"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=4"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=5"
        ),
    ]);

    /** @type {string[]} */
    let urls = [];

    // Get raw GitHub urls to the info.json contents
    searchResults.forEach(result => {
        urls.push(
            ...result.items.map(item =>
                // Convert html_url to raw github url for download
                item.html_url
                    .replace("https://github.com", "https://raw.githubusercontent.com")
                    .replace("/blob", "")
            )
        );
    });

    // Existing downloads
    if (!fs.existsSync(INFO_JSON_CACHE_DIR)) fs.mkdirSync(INFO_JSON_CACHE_DIR);
    let files = fs.readdirSync(INFO_JSON_CACHE_DIR);

    // Clear the cache on demand
    if (clearCache) {
        console.log("Clearing the info.json cache...");
        files.forEach(t => fs.unlinkSync(path.join(INFO_JSON_CACHE_DIR, t)));
        files = [];
    }

    /** @type {string[]} */
    let downloadedFiles = [];

    console.log("Downloading the missing files...");

    // Download urls with 10 in parallel
    for (const downloadGroup of chunk(urls, 10)) {
        // Blocks until 10 is downloaded
        await Promise.all(
            downloadGroup
                .map(t => ({
                    url: t,
                    cacheFilename: urlToFilename(t),
                }))

                // Only if cached file is missing
                .filter(f => files.indexOf(f.cacheFilename) === -1)

                // Then download and store to cache
                .map(r =>
                    get(r.url).then(infoJson => {
                        // TODO: It would be possible to validate INFO.json file here
                        fs.writeFileSync(
                            path.join(INFO_JSON_CACHE_DIR, r.cacheFilename),
                            JSON.stringify({
                                url: r.url,
                                infoJson: infoJson,
                                keymapUrl: r.url, // TODO: CONVERT TO KEYMAP URL
                            })
                        );
                        downloadedFiles.push(r.url);
                    })
                )
        );
    }
    console.log("Downloaded info.json files:", downloadedFiles.length);
    console.log("Cached info.json files:", files.length);

    // Returns the filepaths to the info.json files
    /** @type {[string, Object][]} */
    let infoJsonFiles = fs
        .readdirSync(INFO_JSON_CACHE_DIR)
        .map(cachedFilename => {
            let fileContents = fs.readFileSync(
                path.join(INFO_JSON_CACHE_DIR, cachedFilename),
                "utf8"
            );

            // Parse the info.json
            /** @type {{url: string; infoJson: any; keymapUrl: string}} */
            let parsed;
            try {
                parsed = JSON.parse(fileContents);
            } catch (e) {
                console.error("Discarding info.json file, not JSON parseable: ", cachedFilename);
                return;
            }

            // Get the keyboard unique identifier from url part keyboards/...
            let keyMatch = parsed.url.match(/keyboards\/(.*?)\/info.json/);
            if (!keyMatch) {
                console.log("Discarding info.json file, not in keyboards: ", cachedFilename);
                return;
            }

            // TODO: Validate info.json structure more thoroughly here:
            if (!parsed.infoJson.keyboard_name) {
                console.log("Discarding info.json file, no keyboard_name: ", cachedFilename);
                return;
            }

            /** @type {[string, Object]} */
            let result = [
                keyMatch[1],
                {
                    ...parsed.infoJson,
                    _defaultKeymapUrl: parsed.keymapUrl.replace(
                        "info.json",
                        "keymaps/default/keymap.c"
                    ),
                },
            ];
            return result;
        })
        .filter(t => t);

    let infoJsonMap = {};
    infoJsonFiles.sort((a, b) => (a[0] > b[0] ? 1 : a[0] === b[0] ? 0 : -1));
    infoJsonFiles.forEach(([key, infoJson]) => {
        infoJsonMap[key] = infoJson;
    });
    return infoJsonMap;
};

module.exports = {
    getInfoJsonMap: getInfoJsonMap,
};

// Ran as an individual script
if (require.main === module) {
    (async () => {
        console.log("This script downloads info.json files from QMK repository to a local cache");
        console.log("Help: Run with --clear-cache to empty the cache first (forces redownload)");
        try {
            await getInfoJsonMap(process.argv.indexOf("--clear-cache") !== -1);
        } catch (err) {
            console.error(err);
            console.error("Died with error code 1");
            process.exit(1);
        }
        console.log("Done, no errors");
    })();
}
<commit_msg>info.json inheritance (minor, not well utilized in QMK)<commit_after>// @ts-check

// Maintains a cache of all info.json files in /.~info.json.cache/ directory
// (Downloads only the missing info.json files)

const request = require("request-promise");
const fs = require("fs");
const path = require("path");

const INFO_JSON_CACHE_DIR = ".~info.json.cache";

/**
 * Chunking (immutable)
 *
 * @template T
 * @param arr {T[]}
 * @param size {number}
 * @return T[]
 */
const chunk = (arr, size) => {
    let copy = [...arr];
    let results = [];
    while (copy.length) results.push(copy.splice(0, size));
    return results;
};

/**
 * Convert URL to filename
 * @param url {string}
 */
const urlToFilename = url => {
    return url.replace(/[^a-z0-9.]+/gi, "_");
};

/**
 * Request URL by GET
 *
 * @param {string} url
 */
const get = url => {
    return request.get({
        headers: {
            "User-Agent": "Request",
        },
        url: url,
        json: true,
    });
};

/**
 * Main program
 *
 * @returns {Promise<{[key: string]: any}>}
 */
const getInfoJsonMap = async (clearCache = false) => {
    console.log("Downloading info.json listing from GitHub...");
    /** @type {{items: {html_url: string}[]}[]} */
    let searchResults = await Promise.all([
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=2"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=3"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=4"
        ),
        get(
            "https://api.github.com/search/code?q=filename:info.json+repo:qmk/qmk_firmware&per_page=100&page=5"
        ),
    ]);

    /** @type {string[]} */
    let urls = [];

    // Get raw GitHub urls to the info.json contents
    searchResults.forEach(result => {
        urls.push(
            ...result.items.map(item =>
                // Convert html_url to raw github url for download
                item.html_url
                    .replace("https://github.com", "https://raw.githubusercontent.com")
                    .replace("/blob", "")
            )
        );
    });

    // Existing downloads
    if (!fs.existsSync(INFO_JSON_CACHE_DIR)) fs.mkdirSync(INFO_JSON_CACHE_DIR);
    let files = fs.readdirSync(INFO_JSON_CACHE_DIR);

    // Clear the cache on demand
    if (clearCache) {
        console.log("Clearing the info.json cache...");
        files.forEach(t => fs.unlinkSync(path.join(INFO_JSON_CACHE_DIR, t)));
        files = [];
    }

    /** @type {string[]} */
    let downloadedFiles = [];

    console.log("Downloading the missing files...");

    // Download urls with 10 in parallel
    for (const downloadGroup of chunk(urls, 10)) {
        // Blocks until 10 is downloaded
        await Promise.all(
            downloadGroup
                .map(t => ({
                    url: t,
                    cacheFilename: urlToFilename(t),
                }))

                // Only if cached file is missing
                .filter(f => files.indexOf(f.cacheFilename) === -1)

                // Then download and store to cache
                .map(r =>
                    get(r.url).then(infoJson => {
                        // TODO: It would be possible to validate INFO.json file here
                        fs.writeFileSync(
                            path.join(INFO_JSON_CACHE_DIR, r.cacheFilename),
                            JSON.stringify({
                                url: r.url,
                                infoJson: infoJson,
                                keymapUrl: r.url, // TODO: CONVERT TO KEYMAP URL
                            })
                        );
                        downloadedFiles.push(r.url);
                    })
                )
        );
    }
    console.log("Downloaded info.json files:", downloadedFiles.length);
    console.log("Cached info.json files:", files.length);

    // Returns the filepaths to the info.json files
    let infoJsonFileNames = fs.readdirSync(INFO_JSON_CACHE_DIR);
    infoJsonFileNames.sort((a, b) => {
        a = a.toLowerCase().replace(/(.+?)keyboards_/, "");
        b = b.toLowerCase().replace(/(.+?)keyboards_/, "");
        return a > b ? 1 : b > a ? -1 : 0;
    });

    // Info.json inherits in the tree, e.g. keyboards/a/info.json "inherits" to keyboards/a/b/info.json
    /** @type {{[k: string]: Object}} */
    let infoJsonInheritanceCache = {};

    /** @type {[string, Object][]} */
    let infoJsonFiles = infoJsonFileNames
        .map(cachedFilename => {
            let fileContents = fs.readFileSync(
                path.join(INFO_JSON_CACHE_DIR, cachedFilename),
                "utf8"
            );

            // Parse the info.json
            /** @type {{url: string; infoJson: any; keymapUrl: string}} */
            let parsed;
            try {
                parsed = JSON.parse(fileContents);
            } catch (e) {
                console.error("Discarding info.json file, not JSON parseable: ", cachedFilename);
                return;
            }

            // Get the keyboard unique identifier from url part keyboards/...
            let keyMatch = parsed.url.match(/keyboards\/(.*?)\/info.json/);
            if (!keyMatch) {
                console.log("Discarding info.json file, not in keyboards: ", cachedFilename);
                return;
            }
            let keyboardPath = keyMatch[1];
            let inheritFromParts = keyboardPath.split("/").slice(0, -1);
            let bits = "";
            for (const part of inheritFromParts) {
                bits += (bits != "" ? "/" : "") + part;
                if (bits in infoJsonInheritanceCache) {
                    // console.log("Inherit", bits);
                    // console.log("Pre inherit", parsed.infoJson);
                    parsed.infoJson = Object.assign(
                        {},
                        infoJsonInheritanceCache[bits],
                        parsed.infoJson
                    );
                    // console.log("After inherit", parsed.infoJson);
                }
            }

            infoJsonInheritanceCache[keyboardPath] = parsed.infoJson;

            // TODO: Validate info.json structure more thoroughly here:
            if (!parsed.infoJson.keyboard_name) {
                console.log("Discarding info.json file, no keyboard_name: ", cachedFilename);
                return;
            }

            /** @type {[string, Object]} */
            let result = [
                keyboardPath,
                {
                    ...parsed.infoJson,
                    _defaultKeymapUrl: parsed.keymapUrl.replace(
                        "info.json",
                        "keymaps/default/keymap.c"
                    ),
                },
            ];
            return result;
        })
        .filter(t => t);

    let infoJsonMap = {};
    infoJsonFiles.sort((a, b) => (a[0] > b[0] ? 1 : a[0] === b[0] ? 0 : -1));
    infoJsonFiles.forEach(([key, infoJson]) => {
        infoJsonMap[key] = infoJson;
    });
    return infoJsonMap;
};

module.exports = {
    getInfoJsonMap: getInfoJsonMap,
};

// Ran as an individual script
if (require.main === module) {
    (async () => {
        console.log("This script downloads info.json files from QMK repository to a local cache");
        console.log("Help: Run with --clear-cache to empty the cache first (forces redownload)");
        try {
            await getInfoJsonMap(process.argv.indexOf("--clear-cache") !== -1);
        } catch (err) {
            console.error(err);
            console.error("Died with error code 1");
            process.exit(1);
        }
        console.log("Done, no errors");
    })();
}
<|endoftext|>


<commit_before>import React from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import * as actions from '../../store/reducer/navigation'

export const TraderScreen = props =>
  <ProfileScreen
    additionalDetails={() => (
      <BusinessDetails/>
    )}
    dataSource={props.dataSource}
    />

const mapStateToProps = (state) => ({
  selectedBusiness: state.business.businessList.find(b => b.id === state.business.selectedBusinessId),
  dataSource: state.business.traderTransactionsDataSource
})

const mapDispatchToProps = (dispatch) =>
  bindActionCreators(actions, dispatch)

export default connect(mapStateToProps, mapDispatchToProps)(TraderScreen)
<commit_msg>remove leftover file which should have been deleted during refactor<commit_after><|endoftext|>


<commit_before>Vps.onContentReady(function()
{
    var fadeComponents = Ext.query('div.vpsFadeElements');
    Ext.each(fadeComponents, function(c) {
        var selector = Ext.query('.fadeSelector', c)[0].value;
        var config = Ext.query('.fadeConfig', c); // optional
        if (config && config[0]) {
            config = Ext.decode(config[0].value);
        } else {
            config = { };
        }
        var textSelector = Ext.query('.textSelector', c); // optional
        if (textSelector) {
            config.textSelector = textSelector[0].value;
        }

        config.selector = selector;
        config.selectorRoot = c;

        var fade = new Vps.Fade.Elements(config);
        fade.start();
    });
});

Ext.namespace("Vps.Fade");

Vps.Fade.Elements = function(cfg) {
    this.selector = cfg.selector;

    this.elementAccessLinks = false; // optional
    this.selectorRoot = document;
    this.fadeDuration = 1.5;
    this.easingFadeOut = 'easeIn';
    this.easingFadeIn = 'easeIn';
    this.fadeEvery = 7;
    this.startRandom = true;

    if (cfg.elementAccessLinks) this.elementAccessLinks = cfg.elementAccessLinks;
    if (cfg.selectorRoot) this.selectorRoot = cfg.selectorRoot;
    if (cfg.fadeDuration) this.fadeDuration = cfg.fadeDuration;
    if (cfg.easingFadeOut) this.easingFadeOut = cfg.easingFadeOut;
    if (cfg.easingFadeIn) this.easingFadeIn = cfg.easingFadeIn;
    if (cfg.fadeEvery) this.fadeEvery = cfg.fadeEvery;
    if (cfg.startRandom) this.startRandom = cfg.startRandom;

    this.fadeElements = Ext.query(this.selector, this.selectorRoot);

    if (this.startRandom) {
        this.active = Math.floor(Math.random() * this.fadeElements.length);
        if (this.active >= this.fadeElements.length) {
            this.active = this.fadeElements.length - 1;
        }

        this.next = this.active + 1;
        if (this.next >= this.fadeElements.length) {
            this.next = 0;
        }
    }

    var i = 0;
    Ext.each(this.fadeElements, function(e) {
        var ee = Ext.get(e);

        ee.addClass('vpsFadeElement');
        if (i != this.active) {
            ee.setStyle('display', 'none');
        } else {
            ee.setStyle('display', 'block');
        }
        i += 1;
    }, this);

    // wenn nur ein fade element existiert und im text element kein inhalt ist: ausblenden
    if (this.fadeElements.length == 1 && cfg.textSelector) {
        var dontShowEl = Ext.query(cfg.textSelector, this.selectorRoot);
        if (dontShowEl && dontShowEl[0]) {
            if (dontShowEl[0].innerHTML.replace(/\s/g, '') == '') {
                Ext.get(dontShowEl[0]).setDisplayed('none');
            }
        }
    }

    // create the element access link if needed
    if (this.elementAccessLinks && i >= 1) {
        this._createElementAccessLinks(this.active);
    }
};

Vps.Fade.Elements.prototype = {

    active: 0,
    next: 1,
    _firstFaded: false,
    _timeoutId: null,
    _elementAccessLinkEls: [ ],
    _playPause: 'play',
    _playPauseButton: null,

    start: function() {
        if (this.fadeElements.length <= 1) return;
        this._timeoutId = this.doFade.defer(this._getDeferTime(), this);
    },

    doFade: function() {
        if (this.fadeElements.length <= 1) return;

        var activeEl = Ext.get(this.fadeElements[this.active]);
        activeEl.fadeOut({ endOpacity: .0, easing: this.easingFadeOut, duration: this.fadeDuration, useDisplay: true });

        var nextEl = Ext.get(this.fadeElements[this.next]);
        nextEl.fadeIn({ endOpacity: 1.0, easing: this.easingFadeIn, duration: this.fadeDuration, useDisplay: true });

        if (this.elementAccessLinks) {
            if (this._elementAccessLinkEls[this.active].hasClass('elementAccessLinkActive')) {
                this._elementAccessLinkEls[this.active].removeClass('elementAccessLinkActive');
            }
            this._elementAccessLinkEls[this.next].addClass('elementAccessLinkActive');
        }

        this.active = this.next;
        this.next += 1;
        if (typeof this.fadeElements[this.next] == 'undefined') {
            this.next = 0;
        }

        this._timeoutId = this.doFade.defer(this._getDeferTime(), this);
    },

    pause: function() {
        if (this._timeoutId) window.clearTimeout(this._timeoutId);
        if (this._playPauseButton) {
            this._playPauseButton.removeClass('elementAccessPause');
            this._playPauseButton.addClass('elementAccessPlay');
        }
        this._playPause = 'pause';
    },

    play: function() {
        this.doFade();
        if (this._playPauseButton) {
            this._playPauseButton.removeClass('elementAccessPlay');
            this._playPauseButton.addClass('elementAccessPause');
        }
        this._playPause = 'play';
    },

    _getDeferTime: function() {
        if (!this._firstFaded) {
            this._firstFaded = true;
            return Math.ceil(this.fadeEvery * 1000) - Math.ceil(this.fadeDuration * 1000);
        } else {
            return Math.ceil(this.fadeEvery * 1000);
        }
    },

    _createElementAccessLinks: function(activeLinkIndex) {
        var ul = Ext.get(this.selectorRoot).createChild({ tag: 'ul', cls: 'elementAccessLinks' });

        // accessLinks and play / pause button if there are at least 2 images
        if (this.fadeElements.length >= 2) {
            var j = 0;
            Ext.each(this.fadeElements, function(e) {
                var a = ul.createChild({ tag: 'li' })
                    .createChild({
                        tag: 'a',
                        cls: 'elementAccessLink'+(activeLinkIndex==j ? ' elementAccessLinkActive' : ''),
                        html: '',
                        href: '#'
                    });
                a.on('click', function(ev, el, opt) {
                    ev.stopEvent();

                    if (this._timeoutId) {
                        window.clearTimeout(this._timeoutId);
                    }
                    this.next = opt.activateIdx;
                    this.doFade();
                    this.pause();

                }, this, { activateIdx: j });
                this._elementAccessLinkEls.push(a);
                j += 1;
            }, this);

            this._playPauseButton = ul.createChild({ tag: 'li' })
                .createChild({
                    tag: 'a',
                    cls: 'elementAccessPlayPauseButton elementAccessPause',
                    html: ' ',
                    href: '#'
                });
            this._playPauseButton.on('click', function(ev, el, opt) {
                ev.stopEvent();

                if (this._playPause == 'play') {
                    this.pause();
                } else if (this._playPause == 'pause') {
                    this.play();
                }
            }, this);
        }
    }
};
<commit_msg>Ueberpruefung bei Fading nicht ganz korrekt, gab Fehler bei Rotary-Clubseiten<commit_after>Vps.onContentReady(function()
{
    var fadeComponents = Ext.query('div.vpsFadeElements');
    Ext.each(fadeComponents, function(c) {
        var selector = Ext.query('.fadeSelector', c)[0].value;
        var config = Ext.query('.fadeConfig', c); // optional
        if (config && config[0]) {
            config = Ext.decode(config[0].value);
        } else {
            config = { };
        }
        var textSelector = Ext.query('.textSelector', c); // optional
        if (textSelector[0]) {
            config.textSelector = textSelector[0].value;
        }

        config.selector = selector;
        config.selectorRoot = c;

        var fade = new Vps.Fade.Elements(config);
        fade.start();
    });
});

Ext.namespace("Vps.Fade");

Vps.Fade.Elements = function(cfg) {
    this.selector = cfg.selector;

    this.elementAccessLinks = false; // optional
    this.selectorRoot = document;
    this.fadeDuration = 1.5;
    this.easingFadeOut = 'easeIn';
    this.easingFadeIn = 'easeIn';
    this.fadeEvery = 7;
    this.startRandom = true;

    if (cfg.elementAccessLinks) this.elementAccessLinks = cfg.elementAccessLinks;
    if (cfg.selectorRoot) this.selectorRoot = cfg.selectorRoot;
    if (cfg.fadeDuration) this.fadeDuration = cfg.fadeDuration;
    if (cfg.easingFadeOut) this.easingFadeOut = cfg.easingFadeOut;
    if (cfg.easingFadeIn) this.easingFadeIn = cfg.easingFadeIn;
    if (cfg.fadeEvery) this.fadeEvery = cfg.fadeEvery;
    if (cfg.startRandom) this.startRandom = cfg.startRandom;

    this.fadeElements = Ext.query(this.selector, this.selectorRoot);

    if (this.startRandom) {
        this.active = Math.floor(Math.random() * this.fadeElements.length);
        if (this.active >= this.fadeElements.length) {
            this.active = this.fadeElements.length - 1;
        }

        this.next = this.active + 1;
        if (this.next >= this.fadeElements.length) {
            this.next = 0;
        }
    }

    var i = 0;
    Ext.each(this.fadeElements, function(e) {
        var ee = Ext.get(e);

        ee.addClass('vpsFadeElement');
        if (i != this.active) {
            ee.setStyle('display', 'none');
        } else {
            ee.setStyle('display', 'block');
        }
        i += 1;
    }, this);

    // wenn nur ein fade element existiert und im text element kein inhalt ist: ausblenden
    if (this.fadeElements.length == 1 && cfg.textSelector) {
        var dontShowEl = Ext.query(cfg.textSelector, this.selectorRoot);
        if (dontShowEl && dontShowEl[0]) {
            if (dontShowEl[0].innerHTML.replace(/\s/g, '') == '') {
                Ext.get(dontShowEl[0]).setDisplayed('none');
            }
        }
    }

    // create the element access link if needed
    if (this.elementAccessLinks && i >= 1) {
        this._createElementAccessLinks(this.active);
    }
};

Vps.Fade.Elements.prototype = {

    active: 0,
    next: 1,
    _firstFaded: false,
    _timeoutId: null,
    _elementAccessLinkEls: [ ],
    _playPause: 'play',
    _playPauseButton: null,

    start: function() {
        if (this.fadeElements.length <= 1) return;
        this._timeoutId = this.doFade.defer(this._getDeferTime(), this);
    },

    doFade: function() {
        if (this.fadeElements.length <= 1) return;

        var activeEl = Ext.get(this.fadeElements[this.active]);
        activeEl.fadeOut({ endOpacity: .0, easing: this.easingFadeOut, duration: this.fadeDuration, useDisplay: true });

        var nextEl = Ext.get(this.fadeElements[this.next]);
        nextEl.fadeIn({ endOpacity: 1.0, easing: this.easingFadeIn, duration: this.fadeDuration, useDisplay: true });

        if (this.elementAccessLinks) {
            if (this._elementAccessLinkEls[this.active].hasClass('elementAccessLinkActive')) {
                this._elementAccessLinkEls[this.active].removeClass('elementAccessLinkActive');
            }
            this._elementAccessLinkEls[this.next].addClass('elementAccessLinkActive');
        }

        this.active = this.next;
        this.next += 1;
        if (typeof this.fadeElements[this.next] == 'undefined') {
            this.next = 0;
        }

        this._timeoutId = this.doFade.defer(this._getDeferTime(), this);
    },

    pause: function() {
        if (this._timeoutId) window.clearTimeout(this._timeoutId);
        if (this._playPauseButton) {
            this._playPauseButton.removeClass('elementAccessPause');
            this._playPauseButton.addClass('elementAccessPlay');
        }
        this._playPause = 'pause';
    },

    play: function() {
        this.doFade();
        if (this._playPauseButton) {
            this._playPauseButton.removeClass('elementAccessPlay');
            this._playPauseButton.addClass('elementAccessPause');
        }
        this._playPause = 'play';
    },

    _getDeferTime: function() {
        if (!this._firstFaded) {
            this._firstFaded = true;
            return Math.ceil(this.fadeEvery * 1000) - Math.ceil(this.fadeDuration * 1000);
        } else {
            return Math.ceil(this.fadeEvery * 1000);
        }
    },

    _createElementAccessLinks: function(activeLinkIndex) {
        var ul = Ext.get(this.selectorRoot).createChild({ tag: 'ul', cls: 'elementAccessLinks' });

        // accessLinks and play / pause button if there are at least 2 images
        if (this.fadeElements.length >= 2) {
            var j = 0;
            Ext.each(this.fadeElements, function(e) {
                var a = ul.createChild({ tag: 'li' })
                    .createChild({
                        tag: 'a',
                        cls: 'elementAccessLink'+(activeLinkIndex==j ? ' elementAccessLinkActive' : ''),
                        html: '',
                        href: '#'
                    });
                a.on('click', function(ev, el, opt) {
                    ev.stopEvent();

                    if (this._timeoutId) {
                        window.clearTimeout(this._timeoutId);
                    }
                    this.next = opt.activateIdx;
                    this.doFade();
                    this.pause();

                }, this, { activateIdx: j });
                this._elementAccessLinkEls.push(a);
                j += 1;
            }, this);

            this._playPauseButton = ul.createChild({ tag: 'li' })
                .createChild({
                    tag: 'a',
                    cls: 'elementAccessPlayPauseButton elementAccessPause',
                    html: ' ',
                    href: '#'
                });
            this._playPauseButton.on('click', function(ev, el, opt) {
                ev.stopEvent();

                if (this._playPause == 'play') {
                    this.pause();
                } else if (this._playPause == 'pause') {
                    this.play();
                }
            }, this);
        }
    }
};
<|endoftext|>


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

    angular
        .module('atlas')
        .component('dpDashboard', {
            templateUrl: 'modules/atlas/components/dashboard/dashboard.html',
            controller: DpDashboardController,
            controllerAs: 'vm'
        });

    DpDashboardController.$inject = ['store', 'dashboardColumns'];

    function DpDashboardController (store, dashboardColumns) {
        var vm = this;

        vm.store = store;

        store.subscribe(setLayout);
        setLayout();

        function setLayout () {
            var state = store.getState();

            vm.visibility = dashboardColumns.determineVisibility(state);

            vm.isPrintMode = state.isPrintMode;

            vm.isRightColumnScrollable = !state.map.isFullscreen &&
                (
                    vm.visibility.page ||
                    vm.visibility.detail ||
                    vm.visibility.searchResults ||
                    vm.visibility.dataSelection
                );
            vm.columnSizes = dashboardColumns.determineColumnSizes(
                vm.visibility,
                state.map.isFullscreen,
                vm.isPrintMode
            );

            // Needed for the dp-scrollable-content directive
            vm.pageName = state.page;
        }
    }
})();
<commit_msg>test for githook<commit_after>(function () {
    'use strict';

    angular
        .module('atlas')
        .component('dpDashboard', {
            templateUrl: 'modules/atlas/components/dashboard/dashboard.html',
            controller: DpDashboardController,
            controllerAs: 'vm'
        });

    DpDashboardController.$inject = ['store', 'dashboardColumns'];

    function DpDashboardController (store, dashboardColumns) {
        var vm = this;

        vm.store = store;

        store.subscribe(setLayout);
        setLayout();

        function setLayout () {
            var state = store.getState();

            vm.visibility = dashboardColumns.determineVisibility(state);

            vm.isPrintMode = state.isPrintMode;

            vm.isRightColumnScrollable = !state.map.isFullscreen &&
                (
                    vm.visibility.page ||
                    vm.visibility.detail ||
                    vm.visibility.searchResults ||
                    vm.visibility.dataSelection
                );

            vm.columnSizes = dashboardColumns.determineColumnSizes(
                vm.visibility,
                state.map.isFullscreen,
                vm.isPrintMode
            );

            // Needed for the dp-scrollable-content directive
            vm.pageName = state.page;
        }
    }
})();
<|endoftext|>


<commit_before>$(document).ready(function(){
    cek();
    $("#tombol-notifikasi").click(function(){
        tampilkan();
    });
});

function cek(){
    $.ajax({
        url: "notifikasi/hitung",
        cache: false,
        success: function(msg){
            $("#jumlah-notifikasi").html(msg);
        }
    });
    var waktu = setTimeout("cek()",3000);
}

function tampilkan(){
    $.ajax({
        url: "notifikasi/get",
        cache: false,
        success: function(msg){
            // $("#loading").hide();
            $("#konten-notifikasi").html(msg);
        }
    });
}<commit_msg>fix notifikasi<commit_after>$(document).ready(function(){
    cek();
    $("#tombol-notifikasi").click(function(){
        tampilkan();
    });
});

function cek(){
    $.ajax({
        url: window.location.origin + "/hmmmm/notifikasi/hitung",
        cache: false,
        success: function(msg){
            $("#jumlah-notifikasi").html(msg);
        }
    });
    var waktu = setTimeout("cek()",3000);
}

function tampilkan(){
    $.ajax({
        url: window.location.origin + "/hmmmm/notifikasi/get",
        cache: false,
        success: function(msg){
            // $("#loading").hide();
            $("#konten-notifikasi").html(msg);
        }
    });
}<|endoftext|>