<commit_before>angular.module('feedbackcontrol', [])
.directive('transform', function(FeedbackSignal) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var currentUrl = window.location.pathname;
                var me = $(element);
                var data = FeedbackSignal.data;

                if(currentUrl.match(/published|contacts/g)) {

                    if(me.attr('return-policy') == 1) {
                        hide_the_children(me);
                        $(".checky-box-container").show();
                    }

                    if(data.status == "feature") {
                        var state = {
                            activate: {'background-position': '-64px -31px'}
                          , deactivate_sibling: {'background-position': '-32px 0px'}
                          , activation_color: {'background-color': '#ffffe0'}
                          , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                          , state_change: '{"status": "publish", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                        }
                        published_state(me, '.publish', 'publish feedback', state);
                    }

                    if(data.status == "publish") {
                        var state = {
                            activate: {'background-position': '-32px -31px'}
                          , deactivate_sibling: {'background-position': '-64px 0px'}
                          , activation_color: {'background-color': '#fff'}
                          , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                          , state_change: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                        }
                        published_state(me, '.feature', 'feature feedback', state);
                    }

                    if(data.status == "delete" || data.status == "fileas") {
                        hide_the_children(me);
                        $(".checky-box-container").show();
                    }

                }

                if(currentUrl.match(/filed/g)) {

                    var data_status = data.status;

                    if(data_status == "publish" || data_status == "feature" || data_status == "delete") {
                        hide_the_children(me);
                        $(".checky-box-container").show();
                    }

                    if(data_status == "fileas") {
                        $(me).parents(".dashboard-feedback")
                               .children("div.feedback-contents")
                               .children(".responsive-padding")
                               .children(".feedback-details")
                               .children(".filed")
                               .html($(me).text())
                    }

                }

                hide_the_children(me);
                $(".checky-box-container").show();

                e.preventDefault();
            });
        }
    }
})
.directive('undo', function(FeedbackSignal, FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                if (FeedbackSignal.data.id instanceof Array) {
                    for(var i=0; i < FeedbackSignal.data.id.length ; i++) {
                        var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id[i] + "]");
                        feedback.show();
                        $(feedback).parents('.feedback-group').show();
                    }
                } else {
                    var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id + "]");
                    feedback.show();
                    $(feedback).parents('.feedback-group').show();

                    var checkbox = $(".feed-checkbox[value=" + FeedbackSignal.data.id + "]");

                    if(checkbox.is(":checked")) {
                        checkbox.click();
                    }
                }

                if($(".sorter-checkbox").is(":checked")) {
                    $(".sorter-checkbox").click();
                }

                if($('.feed-checkbox').is(":checked")) {
                    $('.feed-checkbox').prop("checked", false);
                }

                $(".dashboard-feedback").css({'background-color': '#FFF'});

                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('close', function(FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('feedcheckbox', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            var checkbox = $(element);

            checkbox.bind('change', function() {
                if(checkbox.is(":checked")) {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#F7F7F7'});
                } else {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#FFF'});
                }
            });

        }
    }
})
.directive('statuschange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "=feedid"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                FeedbackService.inline_change($(this).val(), scope.feedid, 'status');
            })
        }
    }
})
.directive('prioritychange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "=feedid"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                FeedbackService.inline_change($(this).val(), scope.feedid, 'priority');
            })
        }
    }
})
.directive('deleteBlock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $(this).parents('.custom-att').fadeOut(400, function() {
                     var new_uploaded_images = new Array;
                     var new_attached_link;

                     var div = $(this).parents('.uploaded-images-and-links');
                     var images = div.find('.uploaded_image');
                     var media_attachment = div.find('.attached_link');

                     var remove_image = {
                        'small_url'    :$(this).find('.small-image-url').val(),
                        'medium_url'   :$(this).find('.medium-image-url').val(),
                        'large_url'    :$(this).find('.large-image-url').val()
                     }

                    if(images.length > 0){
                        var us = images.not(":hidden");
                        for(var i=0; i < us.length; i++) {
                            new_uploaded_images.push({
                                'name': $(us[i]).find('.image-name').val()
                            });
                        }
                    }

                    if(!media_attachment.is(":hidden")) {
                        new_attached_link = {
                            title           : media_attachment.find('.link-title').val(),
                            description     : media_attachment.find('.link-description').val(),
                            image           : media_attachment.find('.link-image').val(),
                            url             : media_attachment.find('.link-url').val(),
                            video           : media_attachment.find('.link-video').val(),
                        }
                    }

                    var remaining = {
                        uploaded_images : new_uploaded_images
                      , attached_link   : new_attached_link
                    }

                    var attachment_data = {
                        feedbackId      : div.find('.attachment_feedback_id').val()
                      , attachments     : remaining
                      , remove_image    : remove_image
                    }

                    //place this in service you lazy bastard!
                    $.ajax({
                        type: "POST"
                      , url: "/inbox/update_feedback_attachment"
                      , dataType: "json"
                      , data: attachment_data
                    });
                });
                e.preventDefault();
            })
        }
    }
})
.directive('flag', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var policy = $(this).attr("return-policy");
                if(policy == 1) {
                    $(this).removeAttr("style");
                    $(this).attr("return-policy", 0);
                } else {
                    $(this).attr("style", "background-position: -194px -31px");
                    $(this).attr("return-policy", 1);
                }
                e.preventDefault();
            });
        }
    }
})

function published_state(obj, sibling_id, msg, state) {
    obj.parents('.dashboard-feedback').css(state.activation_color);
    obj.css(state.activate);
    obj.children('.action-tooltip').children('span').html("Return to Inbox");
    obj.siblings(sibling_id).css(state.deactivate_sibling);
    obj.siblings(sibling_id).children('.action-tooltip').children('span').html(msg);
    obj.siblings(sibling_id).attr('return-policy', 0);
    obj.siblings(sibling_id).attr('data-feed', state.state_change);
    obj.attr('return-policy', 1);
    obj.attr('data-feed', state.state_change_inbox);
}

function hide_the_children(obj) {
    obj.parents('.dashboard-feedback').hide();
    var child_count = obj.parents('.feedback-group').children('.dashboard-feedback:visible');
    if(child_count.length == 0) {
        obj.parents('.feedback-group').hide();
    }
}
<commit_msg>I am trying to make my way home.<commit_after>angular.module('feedbackcontrol', [])
.directive('transform', function(FeedbackSignal) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var currentUrl = window.location.pathname;
                var me = $(element);
                var data = FeedbackSignal.data;

                if(currentUrl.match(/inbox/\/all|deleted/g)) {
                    hide_the_children(me);
                    $(".checky-box-container").show();
                }

                if(currentUrl.match(/published/g)) {

                    if(me.attr('return-policy') == 1) {
                        hide_the_children(me);
                        $(".checky-box-container").show();
                    }

                    if(data.status == "feature") {
                        var state = {
                            activate: {'background-position': '-64px -31px'}
                          , deactivate_sibling: {'background-position': '-32px 0px'}
                          , activation_color: {'background-color': '#ffffe0'}
                          , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                          , state_change: '{"status": "publish", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                        }
                        published_state(me, '.publish', 'publish feedback', state);
                    }

                    if(data.status == "publish") {
                        var state = {
                            activate: {'background-position': '-32px -31px'}
                          , deactivate_sibling: {'background-position': '-64px 0px'}
                          , activation_color: {'background-color': '#fff'}
                          , state_change_inbox: '{"status": "inbox", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                          , state_change: '{"status": "feature", "id": ' + data.id + ', "catid": ' + data.catid + ', "origin": "publish"}'
                        }
                        published_state(me, '.feature', 'feature feedback', state);
                    }

                    if(data.status == "delete" || data.status == "fileas") {
                        hide_the_children(me);
                        $(".checky-box-container").show();
                    }

                }

                if(currentUrl.match(/filed/g)) {

                    var data_status = data.status;

                    if(data_status == "publish" || data_status == "feature" || data_status == "delete") {
                        hide_the_children(me);
                        $(".checky-box-container").show();
                    }

                    if(data_status == "fileas") {
                        $(me).parents(".dashboard-feedback")
                               .children("div.feedback-contents")
                               .children(".responsive-padding")
                               .children(".feedback-details")
                               .children(".filed")
                               .html($(me).text())
                    }

                }

                e.preventDefault();
            });
        }
    }
})
.directive('undo', function(FeedbackSignal, FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                if (FeedbackSignal.data.id instanceof Array) {
                    for(var i=0; i < FeedbackSignal.data.id.length ; i++) {
                        var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id[i] + "]");
                        feedback.show();
                        $(feedback).parents('.feedback-group').show();
                    }
                } else {
                    var feedback = $(".dashboard-feedback[feedback=" + FeedbackSignal.data.id + "]");
                    feedback.show();
                    $(feedback).parents('.feedback-group').show();

                    var checkbox = $(".feed-checkbox[value=" + FeedbackSignal.data.id + "]");

                    if(checkbox.is(":checked")) {
                        checkbox.click();
                    }
                }

                if($(".sorter-checkbox").is(":checked")) {
                    $(".sorter-checkbox").click();
                }

                if($('.feed-checkbox').is(":checked")) {
                    $('.feed-checkbox').prop("checked", false);
                }

                $(".dashboard-feedback").css({'background-color': '#FFF'});

                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('close', function(FeedbackControlService) {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind("click", function(e) {
                $(".checky-box-container").hide();
                FeedbackControlService.expunge();
                e.preventDefault();
            });
        }
    }
})
.directive('feedcheckbox', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            var checkbox = $(element);

            checkbox.bind('change', function() {
                if(checkbox.is(":checked")) {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#F7F7F7'});
                } else {
                    checkbox.parents('.dashboard-feedback').css({'background-color': '#FFF'});
                }
            });

        }
    }
})
.directive('statuschange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "=feedid"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                FeedbackService.inline_change($(this).val(), scope.feedid, 'status');
            })
        }
    }
})
.directive('prioritychange', function(FeedbackService) {
    return {
        restrict: 'A'
      , scope: {
            feedid: "=feedid"
        }
      , link: function(scope, element, attrs) {
            $(element).bind('change', function() {
                FeedbackService.inline_change($(this).val(), scope.feedid, 'priority');
            })
        }
    }
})
.directive('deleteBlock', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                $(this).parents('.custom-att').fadeOut(400, function() {
                     var new_uploaded_images = new Array;
                     var new_attached_link;

                     var div = $(this).parents('.uploaded-images-and-links');
                     var images = div.find('.uploaded_image');
                     var media_attachment = div.find('.attached_link');

                     var remove_image = {
                        'small_url'    :$(this).find('.small-image-url').val(),
                        'medium_url'   :$(this).find('.medium-image-url').val(),
                        'large_url'    :$(this).find('.large-image-url').val()
                     }

                    if(images.length > 0){
                        var us = images.not(":hidden");
                        for(var i=0; i < us.length; i++) {
                            new_uploaded_images.push({
                                'name': $(us[i]).find('.image-name').val()
                            });
                        }
                    }

                    if(!media_attachment.is(":hidden")) {
                        new_attached_link = {
                            title           : media_attachment.find('.link-title').val(),
                            description     : media_attachment.find('.link-description').val(),
                            image           : media_attachment.find('.link-image').val(),
                            url             : media_attachment.find('.link-url').val(),
                            video           : media_attachment.find('.link-video').val(),
                        }
                    }

                    var remaining = {
                        uploaded_images : new_uploaded_images
                      , attached_link   : new_attached_link
                    }

                    var attachment_data = {
                        feedbackId      : div.find('.attachment_feedback_id').val()
                      , attachments     : remaining
                      , remove_image    : remove_image
                    }

                    //place this in service you lazy bastard!
                    $.ajax({
                        type: "POST"
                      , url: "/inbox/update_feedback_attachment"
                      , dataType: "json"
                      , data: attachment_data
                    });
                });
                e.preventDefault();
            })
        }
    }
})
.directive('flag', function() {
    return {
        restrict: 'A'
      , link: function(scope, element, attrs) {
            $(element).bind('click', function(e) {
                var policy = $(this).attr("return-policy");
                if(policy == 1) {
                    $(this).removeAttr("style");
                    $(this).attr("return-policy", 0);
                } else {
                    $(this).attr("style", "background-position: -194px -31px");
                    $(this).attr("return-policy", 1);
                }
                e.preventDefault();
            });
        }
    }
})

function published_state(obj, sibling_id, msg, state) {
    obj.parents('.dashboard-feedback').css(state.activation_color);
    obj.css(state.activate);
    obj.children('.action-tooltip').children('span').html("Return to Inbox");
    obj.siblings(sibling_id).css(state.deactivate_sibling);
    obj.siblings(sibling_id).children('.action-tooltip').children('span').html(msg);
    obj.siblings(sibling_id).attr('return-policy', 0);
    obj.siblings(sibling_id).attr('data-feed', state.state_change);
    obj.attr('return-policy', 1);
    obj.attr('data-feed', state.state_change_inbox);
}

function hide_the_children(obj) {
    obj.parents('.dashboard-feedback').hide();
    var child_count = obj.parents('.feedback-group').children('.dashboard-feedback:visible');
    if(child_count.length == 0) {
        obj.parents('.feedback-group').hide();
    }
}
<|endoftext|>


<commit_before>/**
* @file UserBarEvents.js
* @brief Script des fonctions liées à la bar utilisateur
*/

/**
* @fn loadUserBarUsers Charge la liste des utilisateurs dans la userBar
*/
function loadUserBarUsers()
{
    // Récupère les utilisateurs
    var selects = document.getElementsByTagName('select'),
        requestedSelect;
    for (var i = 0; i < selects.length; i++)
    {
        if (selects[i].name === 'user')
        {
            // Récupère les données
            requestedSelect = selects[i];
            break;
        }
    }

    // Clone les utilisateurs
    var clone = requestedSelect.cloneNode(true);
    clone.removeChild(clone.firstElementChild);
    clone.setAttribute('id', 'selectUser');
    document.getElementById('userBar').firstElementChild.firstElementChild.appendChild(clone);

    // Ajoute l'event
    clone.addEventListener('change', function()
    {
        // Ferme les fenêtres
        triggerPM(true);
        triggerReport(true);
        triggerProfile(true);
    });
}

/**
* @fn openUserBar Ouvre la barre utilisateur
* @param bar {Object} Objet HTML de la barre
*/
function triggerUserBar(bar)
{
    // Ouvre ou ferme
    if(bar.classList.contains('userBarOpened'))
    {
        triggerPM(true);
        triggerReport(true);
        triggerProfile(true);
        bar.classList.remove('userBarOpened');
    }
    else
    {
        bar.classList.add('userBarOpened');
    }
}

/**
* @fn openPM Ouvre les messages privés
* @param close {boolean} Force la fermeture
*/
function triggerPM(close)
{
    // Récupère le bouton
    var button = document.getElementById('userBar').firstElementChild.children[1];

    // Ouvre ou ferme
    if(close || button.classList.contains('userBarButtonClicked'))
    {
        button.classList.remove('userBarButtonClicked');
        document.getElementById('userBarData').classList.remove('pageLoaded');
    }
    else
    {
        // Ferme les autres boutons
        triggerReport(true);
        triggerProfile(true);
        button.classList.add('userBarButtonClicked');

        // Affiche le logo de chargement
        var dataContainer = document.getElementById('userBarData');
        dataContainer.innerHTML = '';
        var img = document.createElement('img');
        img.src = '/images/loader.gif';
        dataContainer.appendChild(img);
        dataContainer.classList.add('pageLoaded');

        var id = document.getElementById('selectUser'),
            value = id.options[id.selectedIndex].value;

        ajax('GET', '/msgcreate.php?to=' + value, '', post_triggerPM, null, null, null);
    }
}

/**
* @fn openReport Ouvre la page de report
* @param close {boolean} Force la fermeture
*/
function triggerReport(close)
{
    // Récupère le bouton
    var button = document.getElementById('userBar').firstElementChild.children[2];

    // Ouvre ou ferme
    if(close || button.classList.contains('userBarButtonClicked'))
    {
        button.classList.remove('userBarButtonClicked');
        document.getElementById('userBarData').classList.remove('pageLoaded');
    }
    else
    {console.log('report open')
        triggerPM(true);
        triggerProfile(true);
        button.classList.add('userBarButtonClicked');
    }
}

/**
* @fn openProfile Ouvre la page de l'utilisateur
* @param close {boolean} Force la fermeture
*/
function triggerProfile(close)
{
    // Récupère le bouton
    var button = document.getElementById('userBar').firstElementChild.lastElementChild;

    // Ouvre ou ferme
    if(close || button.classList.contains('userBarButtonClicked'))
    {
        button.classList.remove('userBarButtonClicked');
        document.getElementById('userBarData').classList.remove('pageLoaded');
    }
    else
    {
        // Ferme le reste
        triggerPM(true);
        triggerReport(true);
        button.classList.add('userBarButtonClicked');

        // Affiche le logo de chargement
        var dataContainer = document.getElementById('userBarData');
        dataContainer.innerHTML = '';
        var img = document.createElement('img');
        img.src = '/images/loader.gif';
        dataContainer.appendChild(img);
        dataContainer.classList.add('pageLoaded');

        var id = document.getElementById('selectUser'),
            value = id.options[id.selectedIndex].value;

        ajax('GET', '/user/' + value, '', post_triggerProfile, null, null, null);
    }
}

/**
* @fn post_triggerPM Traite l'AJAX du message privé
*/
function post_triggerPM(HTMLString, isError)
{
    // Créé le DOM virtuel
    var PMHTML = document.createElement('html');
    PMHTML.innerHTML = HTMLString;

    // Récupère le formulaire
    var form = PMHTML.getElementsByTagName('form')[0];

    // Place le sujet
    var inputs =  form.getElementsByTagName('input');
    inputs[0].setAttribute('onkeyup', '');
    inputs[1].value = '[' + document.getElementsByTagName('i')[0].innerText + ']';

    // Pas de lien en hat de page
    form.firstElementChild.firstElementChild.firstElementChild.remove();

    // Réécrit la fonction d'envoi
    form.setAttribute('action', '#');
    form.setAttribute('onsubmit', 'return userBarSendPM(this)');

    // L'affiche
    var dataContainer = document.getElementById('userBarData');
    dataContainer.innerHTML = '';
    dataContainer.appendChild(form);
}

/**
* @fn post_triggerProfile Traite l'AJAX du profile
*/
function post_triggerProfile(HTMLString, isError)
{
    // Créé le DOM virtuel
    var profHTML = document.createElement('html');
    profHTML.innerHTML = HTMLString;

    // Récupère le tableau des données
    var tables = profHTML.getElementsByTagName('table'),
        dataTable;
    for (var i = 0; i < tables.length; i++)
    {
        if (tables[i].classList.contains('tabel') && tables[i].width === '90%' && tables[i].border === '0')
        {
            // Récupère les données
            dataTable = tables[i];
            break;
        }
    }

    var dataContainer = document.getElementById('userBarData');
    dataContainer.innerHTML = '';
    dataContainer.appendChild(dataTable);
}

/**
* @fn userBarSendPM Envoi un message privé
* @param {Object} form Noeud HTML du formulaire de mesage privé
*/
function userBarSendPM(form)
{
    // Déjà en cours d'envoi
    if(form.classList.contains('messageSent'))
    {
        return false;
    }

    // Récupère les données
    var inputs   = form.getElementsByTagName('input');
    var textarea = form.getElementsByTagName('textarea')[0];

    // Prépare les données
    var params = 'to='         + inputs[0].value +
                 '&subject='   + encodeURIComponent(inputs[1].value) +
                 '&msgtext='   + encodeURIComponent('
' + textarea.value + '
'),
        url    = '/msgsend.php',
        action = 'POST';

    // Indique que c'est en envoi
    var parent = form.classList.add('messageSent');

    // Effectue l'envoi des données
    ajax(action, url, params, post_userBarSendPM, null, null, null);

    return false;
}

/**
* @fn post_userBarSendPM Traite le retour du l'envoi du message
*/
function post_userBarSendPM(HTMLstring, isError)
{
    // On est toujours sur la page
    var form = document.getElementById('userBarData').firstElementChild;
    if(!form || form.onsubmit.toString().substr(36, 19) !== 'userBarSendPM(this)' || !form.classList.contains('messageSent'))
    {
        return;
    }

    if(isError)
    {
        form.classList.add('ajaxError');
        form.title = loc.messageSendError;
        form.classList.remove('messageSent');
        return;
    }

    // Tout va bien
    var p = document.createElement('p');
    p.classList.add('messageSentSuccess');
    p.title = loc.messageSent;

    var parent = form.parentElement;
    parent.innerHTML = '';
    parent.appendChild(p);
}
<commit_msg>Fix: user list been displayed multiple times<commit_after>/**
* @file UserBarEvents.js
* @brief Script des fonctions liées à la bar utilisateur
*/

/**
* @fn loadUserBarUsers Charge la liste des utilisateurs dans la userBar
*/
function loadUserBarUsers()
{
    // Récupère les utilisateurs
    var selects = document.getElementsByTagName('select'),
        requestedSelect;
    for (var i = 0; i < selects.length; i++)
    {
        if (selects[i].name === 'user')
        {
            // Récupère les données
            requestedSelect = selects[i];
            break;
        }
    }

    // Clone les utilisateurs
    var clone = requestedSelect.cloneNode(true);
    clone.removeChild(clone.firstElementChild);
    clone.setAttribute('id', 'selectUser');

    // Les injecte dans la barre utilisateur
    var userSpan = document.getElementById('userBar').firstElementChild.firstElementChild;
    if(userSpan.lastElementChild.tagName === 'SELECT')
    {
        userSpan.lastElementChild.remove();
    }
    userSpan.appendChild(clone);

    // Ajoute l'event
    clone.addEventListener('change', function()
    {
        // Ferme les fenêtres
        triggerPM(true);
        triggerReport(true);
        triggerProfile(true);
    });
}

/**
* @fn openUserBar Ouvre la barre utilisateur
* @param bar {Object} Objet HTML de la barre
*/
function triggerUserBar(bar)
{
    // Ouvre ou ferme
    if(bar.classList.contains('userBarOpened'))
    {
        triggerPM(true);
        triggerReport(true);
        triggerProfile(true);
        bar.classList.remove('userBarOpened');
    }
    else
    {
        bar.classList.add('userBarOpened');
    }
}

/**
* @fn openPM Ouvre les messages privés
* @param close {boolean} Force la fermeture
*/
function triggerPM(close)
{
    // Récupère le bouton
    var button = document.getElementById('userBar').firstElementChild.children[1];

    // Ouvre ou ferme
    if(close || button.classList.contains('userBarButtonClicked'))
    {
        button.classList.remove('userBarButtonClicked');
        document.getElementById('userBarData').classList.remove('pageLoaded');
    }
    else
    {
        // Ferme les autres boutons
        triggerReport(true);
        triggerProfile(true);
        button.classList.add('userBarButtonClicked');

        // Affiche le logo de chargement
        var dataContainer = document.getElementById('userBarData');
        dataContainer.innerHTML = '';
        var img = document.createElement('img');
        img.src = '/images/loader.gif';
        dataContainer.appendChild(img);
        dataContainer.classList.add('pageLoaded');

        var id = document.getElementById('selectUser'),
            value = id.options[id.selectedIndex].value;

        ajax('GET', '/msgcreate.php?to=' + value, '', post_triggerPM, null, null, null);
    }
}

/**
* @fn openReport Ouvre la page de report
* @param close {boolean} Force la fermeture
*/
function triggerReport(close)
{
    // Récupère le bouton
    var button = document.getElementById('userBar').firstElementChild.children[2];

    // Ouvre ou ferme
    if(close || button.classList.contains('userBarButtonClicked'))
    {
        button.classList.remove('userBarButtonClicked');
        document.getElementById('userBarData').classList.remove('pageLoaded');
    }
    else
    {console.log('report open')
        triggerPM(true);
        triggerProfile(true);
        button.classList.add('userBarButtonClicked');
    }
}

/**
* @fn openProfile Ouvre la page de l'utilisateur
* @param close {boolean} Force la fermeture
*/
function triggerProfile(close)
{
    // Récupère le bouton
    var button = document.getElementById('userBar').firstElementChild.lastElementChild;

    // Ouvre ou ferme
    if(close || button.classList.contains('userBarButtonClicked'))
    {
        button.classList.remove('userBarButtonClicked');
        document.getElementById('userBarData').classList.remove('pageLoaded');
    }
    else
    {
        // Ferme le reste
        triggerPM(true);
        triggerReport(true);
        button.classList.add('userBarButtonClicked');

        // Affiche le logo de chargement
        var dataContainer = document.getElementById('userBarData');
        dataContainer.innerHTML = '';
        var img = document.createElement('img');
        img.src = '/images/loader.gif';
        dataContainer.appendChild(img);
        dataContainer.classList.add('pageLoaded');

        var id = document.getElementById('selectUser'),
            value = id.options[id.selectedIndex].value;

        ajax('GET', '/user/' + value, '', post_triggerProfile, null, null, null);
    }
}

/**
* @fn post_triggerPM Traite l'AJAX du message privé
*/
function post_triggerPM(HTMLString, isError)
{
    // Créé le DOM virtuel
    var PMHTML = document.createElement('html');
    PMHTML.innerHTML = HTMLString;

    // Récupère le formulaire
    var form = PMHTML.getElementsByTagName('form')[0];

    // Place le sujet
    var inputs =  form.getElementsByTagName('input');
    inputs[0].setAttribute('onkeyup', '');
    inputs[1].value = '[' + document.getElementsByTagName('i')[0].innerText + ']';

    // Pas de lien en hat de page
    form.firstElementChild.firstElementChild.firstElementChild.remove();

    // Réécrit la fonction d'envoi
    form.setAttribute('action', '#');
    form.setAttribute('onsubmit', 'return userBarSendPM(this)');

    // L'affiche
    var dataContainer = document.getElementById('userBarData');
    dataContainer.innerHTML = '';
    dataContainer.appendChild(form);
}

/**
* @fn post_triggerProfile Traite l'AJAX du profile
*/
function post_triggerProfile(HTMLString, isError)
{
    // Créé le DOM virtuel
    var profHTML = document.createElement('html');
    profHTML.innerHTML = HTMLString;

    // Récupère le tableau des données
    var tables = profHTML.getElementsByTagName('table'),
        dataTable;
    for (var i = 0; i < tables.length; i++)
    {
        if (tables[i].classList.contains('tabel') && tables[i].width === '90%' && tables[i].border === '0')
        {
            // Récupère les données
            dataTable = tables[i];
            break;
        }
    }

    var dataContainer = document.getElementById('userBarData');
    dataContainer.innerHTML = '';
    dataContainer.appendChild(dataTable);
}

/**
* @fn userBarSendPM Envoi un message privé
* @param {Object} form Noeud HTML du formulaire de mesage privé
*/
function userBarSendPM(form)
{
    // Déjà en cours d'envoi
    if(form.classList.contains('messageSent'))
    {
        return false;
    }

    // Récupère les données
    var inputs   = form.getElementsByTagName('input');
    var textarea = form.getElementsByTagName('textarea')[0];

    // Prépare les données
    var params = 'to='         + inputs[0].value +
                 '&subject='   + encodeURIComponent(inputs[1].value) +
                 '&msgtext='   + encodeURIComponent('
' + textarea.value + '
'),
        url    = '/msgsend.php',
        action = 'POST';

    // Indique que c'est en envoi
    var parent = form.classList.add('messageSent');

    // Effectue l'envoi des données
    ajax(action, url, params, post_userBarSendPM, null, null, null);

    return false;
}

/**
* @fn post_userBarSendPM Traite le retour du l'envoi du message
*/
function post_userBarSendPM(HTMLstring, isError)
{
    // On est toujours sur la page
    var form = document.getElementById('userBarData').firstElementChild;
    if(!form || form.onsubmit.toString().substr(36, 19) !== 'userBarSendPM(this)' || !form.classList.contains('messageSent'))
    {
        return;
    }

    if(isError)
    {
        form.classList.add('ajaxError');
        form.title = loc.messageSendError;
        form.classList.remove('messageSent');
        return;
    }

    // Tout va bien
    var p = document.createElement('p');
    p.classList.add('messageSentSuccess');
    p.title = loc.messageSent;

    var parent = form.parentElement;
    parent.innerHTML = '';
    parent.appendChild(p);
}
<|endoftext|>


<commit_before>import _ from 'lodash';
import React from 'react';
import { Alert, Button, Modal } from 'react-bootstrap';

import { NoOp, Spinner } from './common';

const ErrorDisplay = ({ errors }) => {
  if (errors && _.isArray(errors) && errors.length > 0) {
    return (
      <Alert bsStyle="danger">

          { errors.map((error, index) =>
{error}
) }

      </Alert>
    );
  } else {
    return <NoOp />;
  }
};

const FormModal = ({ children, errors, title, valid, onHide = () => {}, onSubmit = () => {},
    submitting = false, submitButtonBsStyle='primary', submitButtonText = 'Submit', ...otherProps }) => (
  <Modal onHide={() => { if(!submitting) { onHide(); } }} {...otherProps}>
    <Modal.Header>
      <Modal.Title>{ title }</Modal.Title>
    </Modal.Header>

    <form onSubmit={e => { e.preventDefault(); onSubmit(); }} className='form-horizontal'>
       <Modal.Body>
        { children }
      </Modal.Body>
      <Modal.Footer>
        <ErrorDisplay errors={errors} />
        {submitting && <Spinner />} {' '}
        <Button id="confirmModal" bsStyle={submitButtonBsStyle} type="submit" disabled={!valid || submitting} accessKey="s">
          { submitButtonText }
        </Button>
        <Button id="cancelModal" className='cancel' onClick={ e => { e.preventDefault(); onHide(); }} disabled={submitting}>
          Cancel
        </Button>
      </Modal.Footer>
    </form>
  </Modal>
);

FormModal.propTypes = {
  errors: React.PropTypes.array,
  onHide: React.PropTypes.func,
  onSubmit: React.PropTypes.func,
  submitButtonText: React.PropTypes.string,
  submitting: React.PropTypes.bool,
  title: React.PropTypes.string.isRequired,
  valid: React.PropTypes.bool.isRequired
};

export default FormModal;
<commit_msg>FormModal: remove superfluous e,preventDefault<commit_after>import _ from 'lodash';
import React from 'react';
import { Alert, Button, Modal } from 'react-bootstrap';

import { NoOp, Spinner } from './common';

const ErrorDisplay = ({ errors }) => {
  if (errors && _.isArray(errors) && errors.length > 0) {
    return (
      <Alert bsStyle="danger">

          { errors.map((error, index) =>
{error}
) }

      </Alert>
    );
  } else {
    return <NoOp />;
  }
};

const FormModal = ({ children, errors, title, valid, onHide = () => {}, onSubmit = () => {},
    submitting = false, submitButtonBsStyle='primary', submitButtonText = 'Submit', ...otherProps }) => (
  <Modal onHide={() => { if(!submitting) { onHide(); } }} {...otherProps}>
    <Modal.Header>
      <Modal.Title>{ title }</Modal.Title>
    </Modal.Header>

    <form onSubmit={e => { e.preventDefault(); onSubmit(); }} className='form-horizontal'>
       <Modal.Body>
        { children }
      </Modal.Body>
      <Modal.Footer>
        <ErrorDisplay errors={errors} />
        {submitting && <Spinner />} {' '}
        <Button id="confirmModal" bsStyle={submitButtonBsStyle} type="submit" disabled={!valid || submitting} accessKey="s">
          { submitButtonText }
        </Button>
        <Button id="cancelModal" className='cancel' onClick={onHide} disabled={submitting}>
          Cancel
        </Button>
      </Modal.Footer>
    </form>
  </Modal>
);

FormModal.propTypes = {
  errors: React.PropTypes.array,
  onHide: React.PropTypes.func,
  onSubmit: React.PropTypes.func,
  submitButtonText: React.PropTypes.string,
  submitting: React.PropTypes.bool,
  title: React.PropTypes.string.isRequired,
  valid: React.PropTypes.bool.isRequired
};

export default FormModal;
<|endoftext|>


<commit_before>//Based on Main/Mana.js

import React from 'react';
import PropTypes from 'prop-types';
import ChartistGraph from 'react-chartist';
import Chartist from 'chartist';
import 'chartist-plugin-legend';

import makeWclUrl from 'common/makeWclUrl';
import SPELLS from 'common/SPELLS';

import specialEventIndicators from 'Main/Chartist/specialEventIndicators';

import 'Main/Mana.css';

import FocusComponent from './FocusComponent';
import './Focus.css';
const formatDuration = (duration) => {
  const seconds = Math.floor(duration % 60);
  return `${Math.floor(duration / 60)}:${seconds < 10 ? `0${seconds}` : seconds}`;
};

const passiveWasteThreshold = .03; // (wasted passive focus generated) / (total passive focus generated), anything higher will trigger "CAN BE IMPROVED"
//TODO: get a "real" number approved by a MMS expert

class Focus extends React.PureComponent {
  static propTypes = {
    reportCode: PropTypes.string.isRequired,
    actorId: PropTypes.number.isRequired,
    start: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
  };
  constructor() {
    super();
    this.state = {
      focusData: null,
      bossHealth: null,
    };

  }

  componentWillMount() {
    this.load(this.props.reportCode, this.props.actorId, this.props.start, this.props.end);
  }
  componentWillReceiveProps(newProps) {
    if (newProps.reportCode !== this.props.reportCode || newProps.actorId !== this.props.actorId || newProps.start !== this.props.start || newProps.end !== this.props.end) {
      this.load(newProps.reportCode, newProps.actorId, newProps.start, newProps.end);
    }
  }
  load(reportCode, actorId, start, end) {
    const focusPromise = fetch(makeWclUrl(`report/tables/resources/${reportCode}`, {
      start,
      end,
      sourceid: actorId,
      abilityid: 102,
    }))
      .then(response => response.json())
      .then((json) => {
        if (json.status === 400 || json.status === 401) {
          throw json.error;
        } else {
          this.setState({
            focusData: json,
          });
        }
      });
	const playerPromise = fetch(makeWclUrl(`report/events/${reportCode}`, { //We really just grab for player stats- I'm sure there's a better way
      start,
      end,
      actorid: actorId,
    }))
      .then(response => response.json())
      .then((json) => {
        if (json.status === 400 || json.status === 401) {
          throw json.error;
        } else {
           this.setState({
            playerData: json,
          });
        }
      });
    const bossHealthPromise = fetch(makeWclUrl(`report/tables/resources/${reportCode}`, {
      start,
      end,
      sourceclass: 'Boss',
      hostility: 1,
      abilityid: 1000,
    }))
      .then(response => response.json())
      .then((json) => {
        if (json.status === 400 || json.status === 401) {
          throw json.error;
        } else {
          this.setState({
            bossHealth: json,
          });
        }
      });

    return Promise.all([focusPromise, bossHealthPromise, playerPromise]);
  }

  render() {
    if (!this.state.focusData || !this.state.bossHealth || !this.state.playerData) {
      return (

          Loading...

      );
    }
	console.log(this.state.playerData.events);

	const focusGen = Math.round((10 + .1 * this.state.playerData.events[0].hasteRanged / 375)*100)/100; //TODO: replace constant passive FocusGen (right now we don't account for lust/hero or Trueshot
	console.log(focusGen);
    const { start, end } = this.props;
	const actorId = this.props.actorId;
	let passiveCap = 0; //counts time focus capped (in seconds)
	let lastCatch = 0; //records the timestamp of the last event

    const cappedTimer = {
      0:130,
    };
	let tst2 = 0;
	console.log("actor" + actorId);
    this.state.playerData.events.forEach((events) => {
		if (events.sourceID === actorId &&(events.type === 'cast' || events.type === 'energize') ){
			const secIntoFight = (events.timestamp - start);
			cappedTimer[secIntoFight] = events.classResources[0]['amount'];
			lastCatch = (events.timestamp - start);
		}

    });
	for (let i = 0; i < (lastCatch); i++){  //extrapolates focus given passive focus gain (TODO: Update for pulls with Volley)
		if (!cappedTimer[i]){
			if (cappedTimer[i - 1] === 130){
				cappedTimer[i] = 130;
			}
			else{
				cappedTimer[i] = cappedTimer[i-1] + focusGen/1000;
			}
		}
		if (cappedTimer[i] === 130){
			passiveCap += 1/1000;
		}
		tst2 = i;
	}
	console.log(tst2 - lastCatch);

	/* no, you aren't seeing double- this does the same thing as above, but aims to maximize range where-ever possible.
	This is the graph data- since the graph is just a general point of reference, and I only record 1 data point for
	every second, this ensures that the range of each section of the graph is accurate, at the cost of exact slope*/
	lastCatch = 0;
	const overCapBySecond = {};
    const focusBySecond = {
      0: 130,
    };
	this.state.focusData.series[0].data.forEach((item) => {
	  const secIntoFight = Math.floor((item[0] - start) / 1000);
	  if (focusBySecond[secIntoFight] && item[1] <= 65 && focusBySecond[secIntoFight] > item[1]){ //aims to get highest peak
		 focusBySecond[secIntoFight] = item[1];
	  }
	  else if (focusBySecond[secIntoFight] && item[1] > 65 &&focusBySecond[secIntoFight] < item[1]){ //aims to get lowest valley
		 focusBySecond[secIntoFight] = item[1];
	  }
	  else if (!focusBySecond[secIntoFight]){
		  focusBySecond[secIntoFight] = item[1];
	  }
	  lastCatch = Math.floor((item[0] - start) / 1000);
	  if(item[1] > 129){
	  }
	});
	for (let i = 0; i < lastCatch; i++){ //extrapolates for passive focus gain
		if (!focusBySecond[i]){
			if (focusBySecond[i - 1] > 130-focusGen){
				focusBySecond[i] = 130;
			}
			else{
				focusBySecond[i] = focusBySecond[i-1]+ focusGen;
			}
		}
		if (focusBySecond[i] > 129){
			overCapBySecond[i] = focusGen;
		}
	}

    const bosses = [];
    const deadBosses = [];
    this.state.bossHealth.series.forEach((series) => {
      const newSeries = {
        ...series,
        data: {},
      };

      series.data.forEach((item) => {
        const secIntoFight = Math.floor((item[0] - start) / 1000);

        if (deadBosses.indexOf(series.guid) === -1) {
          const health = item[1];
          newSeries.data[secIntoFight] = health;

          if (health === 0) {
            deadBosses.push(series.guid);
          }
        }
      });
      bosses.push(newSeries);
    });
    const deathsBySecond = {};
    this.state.focusData.deaths.forEach((death) => {
      const secIntoFight = Math.floor((death.timestamp - start) / 1000);

      if (death.targetIsFriendly) {
        deathsBySecond[secIntoFight] = true;
      }
    });

    const abilitiesAll = {};
    const categories = {
      generated: 'Focus Generators',
      //spent: 'Focus Spenders', //I see no reason to display focus spenders, but leaving this in if someone later wants to add them
    };

    this.state.playerData.events.forEach((event) => {
		const secIntoFight = Math.floor((event.timestamp - start) / 1000);
		if (event.type === 'energize' && ((event.ability.guid === 187675) || (event.ability.guid === 215107) || (event.ability.guid === 213363))) { //filter non-focus-generator ids
			if (!abilitiesAll[`${event.ability.guid}_gen`]) {
			  const spell = SPELLS[event.ability.guid];
			  let tempSpellID = event.ability.guid;
			  if(tempSpellID === 187675 || tempSpellID === 215107){ //the ids do not align with common/SPELLS, so I manually replace the corresponding ids
				tempSpellID = 185358;
			  }
			  else if(tempSpellID === 213363){
				tempSpellID = 2643;
			  }
			  abilitiesAll[`${event.ability.guid}_gen`] = {
				ability: {
				  category: 'Focus Generators',
				  name: (spell === undefined) ? event.ability.name : spell.name,
				  spellId: tempSpellID,
				},
				spent: 0,
				casts: 0,
				created: 0,
				wasted: 0,
			  };
			}
			abilitiesAll[`${event.ability.guid}_gen`].casts += 1;
			abilitiesAll[`${event.ability.guid}_gen`].created += event.resourceChange;
			abilitiesAll[`${event.ability.guid}_gen`].wasted += event.waste;
			if (overCapBySecond[secIntoFight]){
				overCapBySecond[secIntoFight] += event.waste;
			}
			else{
				overCapBySecond[secIntoFight] = event.waste;
			}
		  }
    });

    const abilities = Object.keys(abilitiesAll).map(key => abilitiesAll[key]);
    abilities.sort((a, b) => {
      if (a.created < b.created) {
        return 1;
      } else if (a.created === b.created) {
        return 0;
      }
      return -1;
    });

    const fightDurationSec = Math.floor((end - start) / 1000);
    const labels = [];
    for (let i = 0; i <= fightDurationSec; i += 1) {
      labels.push(i);

      focusBySecond[i] = focusBySecond[i] !== undefined ? focusBySecond[i] : null;
      overCapBySecond[i] = overCapBySecond[i] !== undefined ? overCapBySecond[i] : null;
      bosses.forEach((series) => {
        series.data[i] = series.data[i] !== undefined ? series.data[i] : null;
      });
      deathsBySecond[i] = deathsBySecond[i] !== undefined ? deathsBySecond[i] : undefined;
    }
	console.log(passiveCap);
	const wastedFocus = Math.round(passiveCap * focusGen);
	console.log("fight" + fightDurationSec);
	const totalFocus = Math.floor(fightDurationSec * focusGen);
	let passiveRating = "";
	if ( passiveCap / totalFocus > passiveWasteThreshold){
		passiveRating = "CAN BE IMPROVED";
	}
	else{
	}
	console.log(passiveCap / totalFocus);
	const totalWasted = [totalFocus,wastedFocus,passiveRating];

    const chartData = {
      labels,
      series: [
        ...bosses.map((series, index) => ({
          className: `boss-health boss-${index} boss-${series.guid}`,
          name: `${series.name} Health`,
          data: Object.keys(series.data).map(key => series.data[key]),
        })),
        {
          className: 'pain',
          name: 'Focus',
          data: Object.keys(focusBySecond).map(key => focusBySecond[key] / 1),
        },
        {
          className: 'wasted',
          name: 'Focus wasted',
          data: Object.keys(overCapBySecond).map(key => overCapBySecond[key]),
        },
      ],
    };
    let step = 0;

    return (

        <ChartistGraph
          data={chartData}
          options={{
            low: 0,
            high: 125,
            showArea: true,
            showPoint: false,
            fullWidth: true,
            height: '300px',
            lineSmooth: Chartist.Interpolation.simple({
              fillHoles: true,
            }),
            axisX: {
              labelInterpolationFnc: function skipLabels(seconds) {
                if (seconds < ((step - 1) * 30)) {
                  step = 0;
                }
                if (step === 0 || seconds >= (step * 30)) {
                  step += 1;
                  return formatDuration(seconds);
                }
                return null;
              },
              offset: 20,
            },
            axisY: {
              onlyInteger: true,
              offset: 35,
              labelInterpolationFnc: function skipLabels(percentage) {
                return `${percentage}`;
              },
            },
            plugins: [
              Chartist.plugins.legend({
                classNames: [
                  ...bosses.map((series, index) => `boss-health boss-${index} boss-${series.guid}`),
                  'pain',
                  'wasted',
                ],
              }),
              specialEventIndicators({
                series: ['death'],
              }),
            ],
          }}
          type="Line"
        />
        <FocusComponent
          abilities={abilities}
          categories={categories}
		  passive = {(totalWasted)}
        />

    );
  }
}

export default Focus;
<commit_msg>Full graphical + numeric focus statistics implemented<commit_after>//Based on Main/Mana.js and Parser/VengeanceDemonHunter/Modules/PainChart

import React from 'react';
import PropTypes from 'prop-types';
import ChartistGraph from 'react-chartist';
import Chartist from 'chartist';
import 'chartist-plugin-legend';

import makeWclUrl from 'common/makeWclUrl';
import SPELLS from 'common/SPELLS';

import specialEventIndicators from 'Main/Chartist/specialEventIndicators';

import 'Main/Mana.css';

import FocusComponent from './FocusComponent';
import './Focus.css';
const formatDuration = (duration) => {
  const seconds = Math.floor(duration % 60);
  return `${Math.floor(duration / 60)}:${seconds < 10 ? `0${seconds}` : seconds}`;
};

const passiveWasteThreshold = .03; // (wasted passive focus generated) / (total passive focus generated), anything higher will trigger "CAN BE IMPROVED"
//TODO: get a "real" number approved by a MMS expert

class Focus extends React.PureComponent {
  static propTypes = {
    reportCode: PropTypes.string.isRequired,
    actorId: PropTypes.number.isRequired,
    start: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
  };
  constructor() {
    super();
    this.state = {
      focusData: null,
      bossHealth: null,
    };

  }

  componentWillMount() {
    this.load(this.props.reportCode, this.props.actorId, this.props.start, this.props.end);
  }
  componentWillReceiveProps(newProps) {
    if (newProps.reportCode !== this.props.reportCode || newProps.actorId !== this.props.actorId || newProps.start !== this.props.start || newProps.end !== this.props.end) {
      this.load(newProps.reportCode, newProps.actorId, newProps.start, newProps.end);
    }
  }
  load(reportCode, actorId, start, end) {
    const focusPromise = fetch(makeWclUrl(`report/tables/resources/${reportCode}`, {
      start,
      end,
      sourceid: actorId,
      abilityid: 102,
    }))
      .then(response => response.json())
      .then((json) => {
        if (json.status === 400 || json.status === 401) {
          throw json.error;
        } else {
          this.setState({
            focusData: json,
          });
        }
      });
	const playerPromise = fetch(makeWclUrl(`report/events/${reportCode}`, { //We really just grab for player stats- I'm sure there's a better way
      start,
      end,
      actorid: actorId,
    }))
      .then(response => response.json())
      .then((json) => {
        if (json.status === 400 || json.status === 401) {
          throw json.error;
        } else {
           this.setState({
            playerData: json,
          });
        }
      });
    const bossHealthPromise = fetch(makeWclUrl(`report/tables/resources/${reportCode}`, {
      start,
      end,
      sourceclass: 'Boss',
      hostility: 1,
      abilityid: 1000,
    }))
      .then(response => response.json())
      .then((json) => {
        if (json.status === 400 || json.status === 401) {
          throw json.error;
        } else {
          this.setState({
            bossHealth: json,
          });
        }
      });

    return Promise.all([focusPromise, bossHealthPromise, playerPromise]);
  }

  render() {
    if (!this.state.focusData || !this.state.bossHealth || !this.state.playerData) {
      return (

          Loading...

      );
    }
	console.log(this.state.playerData.events);

	const focusGen = Math.round((10 + .1 * this.state.playerData.events[0].hasteRanged / 375)*100)/100; //TODO: replace constant passive FocusGen (right now we don't account for lust/hero or Trueshot
	console.log(focusGen);
    const { start, end } = this.props;
	const actorId = this.props.actorId;
	let passiveCap = 0; //counts time focus capped (in seconds)
	let lastCatch = 0; //records the timestamp of the last event

    const cappedTimer = {
      0:130,
    };
	let tst2 = 0;
	console.log("actor" + actorId);
    this.state.playerData.events.forEach((events) => {
		if (events.sourceID === actorId &&(events.type === 'cast' || events.type === 'energize') ){
			const secIntoFight = (events.timestamp - start);
			cappedTimer[secIntoFight] = events.classResources[0]['amount'];
			lastCatch = (events.timestamp - start);
		}

    });
	for (let i = 0; i < (lastCatch); i++){  //extrapolates focus given passive focus gain (TODO: Update for pulls with Volley)
		if (!cappedTimer[i]){
			if (cappedTimer[i - 1] === 130){
				cappedTimer[i] = 130;
			}
			else{
				cappedTimer[i] = cappedTimer[i-1] + focusGen/1000;
			}
		}
		if (cappedTimer[i] === 130){
			passiveCap += 1/1000;
		}
		tst2 = i;
	}
	console.log(tst2 - lastCatch);

	/* no, you aren't seeing double- this does the same thing as above, but aims to maximize range where-ever possible.
	This is the graph data- since the graph is just a general point of reference, and I only record 1 data point for
	every second, this ensures that the range of each section of the graph is accurate, at the cost of exact slope*/
	lastCatch = 0;
	const overCapBySecond = {};
    const focusBySecond = {
      0: 130,
    };
	this.state.focusData.series[0].data.forEach((item) => {
	  const secIntoFight = Math.floor((item[0] - start) / 1000);
	  if (focusBySecond[secIntoFight] && item[1] <= 65 && focusBySecond[secIntoFight] > item[1]){ //aims to get highest peak
		 focusBySecond[secIntoFight] = item[1];
	  }
	  else if (focusBySecond[secIntoFight] && item[1] > 65 &&focusBySecond[secIntoFight] < item[1]){ //aims to get lowest valley
		 focusBySecond[secIntoFight] = item[1];
	  }
	  else if (!focusBySecond[secIntoFight]){
		  focusBySecond[secIntoFight] = item[1];
	  }
	  lastCatch = Math.floor((item[0] - start) / 1000);
	  if(item[1] > 129){
	  }
	});
	for (let i = 0; i < lastCatch; i++){ //extrapolates for passive focus gain
		if (!focusBySecond[i]){
			if (focusBySecond[i - 1] > 130-focusGen){
				focusBySecond[i] = 130;
			}
			else{
				focusBySecond[i] = focusBySecond[i-1]+ focusGen;
			}
		}
		if (focusBySecond[i] > 129){
			overCapBySecond[i] = focusGen;
		}
	}

    const bosses = [];
    const deadBosses = [];
    this.state.bossHealth.series.forEach((series) => {
      const newSeries = {
        ...series,
        data: {},
      };

      series.data.forEach((item) => {
        const secIntoFight = Math.floor((item[0] - start) / 1000);

        if (deadBosses.indexOf(series.guid) === -1) {
          const health = item[1];
          newSeries.data[secIntoFight] = health;

          if (health === 0) {
            deadBosses.push(series.guid);
          }
        }
      });
      bosses.push(newSeries);
    });
    const deathsBySecond = {};
    this.state.focusData.deaths.forEach((death) => {
      const secIntoFight = Math.floor((death.timestamp - start) / 1000);

      if (death.targetIsFriendly) {
        deathsBySecond[secIntoFight] = true;
      }
    });

    const abilitiesAll = {};
    const categories = {
      generated: 'Focus Generators',
      //spent: 'Focus Spenders', //I see no reason to display focus spenders, but leaving this in if someone later wants to add them
    };

    this.state.playerData.events.forEach((event) => {
		const secIntoFight = Math.floor((event.timestamp - start) / 1000);
		if (event.type === 'energize' && ((event.ability.guid === 187675) || (event.ability.guid === 215107) || (event.ability.guid === 213363))) { //filter non-focus-generator ids
			if (!abilitiesAll[`${event.ability.guid}_gen`]) {
			  const spell = SPELLS[event.ability.guid];
			  let tempSpellID = event.ability.guid;
			  if(tempSpellID === 187675 || tempSpellID === 215107){ //the ids do not align with common/SPELLS, so I manually replace the corresponding ids
				tempSpellID = 185358;
			  }
			  else if(tempSpellID === 213363){
				tempSpellID = 2643;
			  }
			  abilitiesAll[`${event.ability.guid}_gen`] = {
				ability: {
				  category: 'Focus Generators',
				  name: (spell === undefined) ? event.ability.name : spell.name,
				  spellId: tempSpellID,
				},
				spent: 0,
				casts: 0,
				created: 0,
				wasted: 0,
			  };
			}
			abilitiesAll[`${event.ability.guid}_gen`].casts += 1;
			abilitiesAll[`${event.ability.guid}_gen`].created += event.resourceChange;
			abilitiesAll[`${event.ability.guid}_gen`].wasted += event.waste;
			if (overCapBySecond[secIntoFight]){
				overCapBySecond[secIntoFight] += event.waste;
			}
			else{
				overCapBySecond[secIntoFight] = event.waste;
			}
		  }
    });

    const abilities = Object.keys(abilitiesAll).map(key => abilitiesAll[key]);
    abilities.sort((a, b) => {
      if (a.created < b.created) {
        return 1;
      } else if (a.created === b.created) {
        return 0;
      }
      return -1;
    });

    const fightDurationSec = Math.floor((end - start) / 1000);
    const labels = [];
    for (let i = 0; i <= fightDurationSec; i += 1) {
      labels.push(i);

      focusBySecond[i] = focusBySecond[i] !== undefined ? focusBySecond[i] : null;
      overCapBySecond[i] = overCapBySecond[i] !== undefined ? overCapBySecond[i] : null;
      bosses.forEach((series) => {
        series.data[i] = series.data[i] !== undefined ? series.data[i] : null;
      });
      deathsBySecond[i] = deathsBySecond[i] !== undefined ? deathsBySecond[i] : undefined;
    }
	console.log(passiveCap);
	const wastedFocus = Math.round(passiveCap * focusGen);
	console.log("fight" + fightDurationSec);
	const totalFocus = Math.floor(fightDurationSec * focusGen);
	let passiveRating = "";
	if ( passiveCap / totalFocus > passiveWasteThreshold){
		passiveRating = "CAN BE IMPROVED";
	}
	else{
	}
	console.log(passiveCap / totalFocus);
	const totalWasted = [totalFocus,wastedFocus,passiveRating];

    const chartData = {
      labels,
      series: [
        ...bosses.map((series, index) => ({
          className: `boss-health boss-${index} boss-${series.guid}`,
          name: `${series.name} Health`,
          data: Object.keys(series.data).map(key => series.data[key]),
        })),
        {
          className: 'pain',
          name: 'Focus',
          data: Object.keys(focusBySecond).map(key => focusBySecond[key] / 1),
        },
        {
          className: 'wasted',
          name: 'Focus wasted',
          data: Object.keys(overCapBySecond).map(key => overCapBySecond[key]),
        },
      ],
    };
    let step = 0;

    return (

        <ChartistGraph
          data={chartData}
          options={{
            low: 0,
            high: 125,
            showArea: true,
            showPoint: false,
            fullWidth: true,
            height: '300px',
            lineSmooth: Chartist.Interpolation.simple({
              fillHoles: true,
            }),
            axisX: {
              labelInterpolationFnc: function skipLabels(seconds) {
                if (seconds < ((step - 1) * 30)) {
                  step = 0;
                }
                if (step === 0 || seconds >= (step * 30)) {
                  step += 1;
                  return formatDuration(seconds);
                }
                return null;
              },
              offset: 20,
            },
            axisY: {
              onlyInteger: true,
              offset: 35,
              labelInterpolationFnc: function skipLabels(percentage) {
                return `${percentage}`;
              },
            },
            plugins: [
              Chartist.plugins.legend({
                classNames: [
                  ...bosses.map((series, index) => `boss-health boss-${index} boss-${series.guid}`),
                  'pain',
                  'wasted',
                ],
              }),
              specialEventIndicators({
                series: ['death'],
              }),
            ],
          }}
          type="Line"
        />
        <FocusComponent
          abilities={abilities}
          categories={categories}
		  passive = {(totalWasted)}
        />

    );
  }
}

export default Focus;
<|endoftext|>


<commit_before>// CLIENT

Object._ = function(){}

var shoe = require('shoe')
, MuxDemux = require('mux-demux')
, bricoleur = require('./_brico')
, host = docuement.URL.split('//')[1].split('/')[0]
, tmp_id = null
, id = null

var brico = new bricoleur({scope:'client'})

var bus = shoe('/bus')

bus.on('connect', function () {
  tmp_id = new Date().getTime(
  bus.write(JSON.stringify({tmp_id:tmp_id, host:host})

})

bus.on('data', function (json) {
  var data = JSON.parse(json)

  if (typeof data === 'object') console.dir(data)

  if (data[tmp_id]) {
    console.dir(data[tmp_id])
    id = data[tmp_id]
  }

  if (data.id === id) { // handle data -- pass to brico
  }
})

setTimeout(function () {
  console.log('sending to ... '+id)
  bus.write(JSON.stringify({id:id, params:['test',2,'r']}))
}, 900)
<commit_msg>replace document.URL with window.location.host in clnt<commit_after>// CLIENT

Object._ = function(){}

var shoe = require('shoe')
, MuxDemux = require('mux-demux')
, bricoleur = require('./_brico')
, host = window.location.host
, tmp_id = null
, id = null

var brico = new bricoleur({scope:'client'})

var bus = shoe('/bus')

bus.on('connect', function () {
  tmp_id = new Date().getTime(
  bus.write(JSON.stringify({tmp_id:tmp_id, host:host})

})

bus.on('data', function (json) {
  var data = JSON.parse(json)

  if (typeof data === 'object') console.dir(data)

  if (data[tmp_id]) {
    console.dir(data[tmp_id])
    id = data[tmp_id]
  }

  if (data.id === id) { // handle data -- pass to brico
  }
})

setTimeout(function () {
  console.log('sending to ... '+id)
  bus.write(JSON.stringify({id:id, params:['test',2,'r']}))
}, 900)
<|endoftext|>


<commit_before>require('../../modules/es.reflect.delete-property');

module.exports = require('../../internals/path').Reflect.deleteProperty;
<commit_msg>fix re-export in one entry<commit_after>module.exports = require('../../es/reflect/delete-property');
<|endoftext|>


<commit_before>// Generated by CoffeeScript 1.7.1
(function() {
  $(function() {
    $("section.feedback .trigger").click(function() {
      $(this).hide();
      $("section.feedback form").slideDown(100);
      return $('html, body').animate({
        scrollTop: $("section.feedback").offset().top - 45
      }, 100);
    });
    $("section.contact-us .write-to-us").click(function(event) {
      event.preventDefault();
      $(this).hide();
      $("section.contact-us form").slideDown(100);
      return $('html, body').animate({
        scrollTop: $("section.contact-us form").offset().top - 35
      }, 100);
    });
    $("section.feedback form, section.contact-us form").submit(function(event) {
      event.preventDefault();
      if (window.confirm('Vill du se design av svarstexter till användaren?')) {
        return document.location = 'http://malmostad.github.io/wag/messages/';
      }
    });
    return $("article.body-copy form").submit(function(event) {
      event.preventDefault();
      if (window.confirm('Vill du se design av valideringsmeddelanden?')) {
        return document.location = 'http://malmostad.github.io/wag/forms/#form-validation';
      }
    });
  });

}).call(this);
<commit_msg>Vertical media query to prevent hover effect for touch<commit_after>// Generated by CoffeeScript 1.7.0
(function() {
  $(function() {
    $("section.feedback .trigger").click(function() {
      $(this).hide();
      $("section.feedback form").slideDown(100);
      return $('html, body').animate({
        scrollTop: $("section.feedback").offset().top - 45
      }, 100);
    });
    $("section.contact-us .write-to-us").click(function(event) {
      event.preventDefault();
      $(this).hide();
      $("section.contact-us form").slideDown(100);
      return $('html, body').animate({
        scrollTop: $("section.contact-us form").offset().top - 35
      }, 100);
    });
    $("section.feedback form, section.contact-us form").submit(function(event) {
      event.preventDefault();
      if (window.confirm('Vill du se design av svarstexter till användaren?')) {
        return document.location = 'http://malmostad.github.io/wag/messages/';
      }
    });
    return $("article.body-copy form").submit(function(event) {
      event.preventDefault();
      if (window.confirm('Vill du se design av valideringsmeddelanden?')) {
        return document.location = 'http://malmostad.github.io/wag/forms/#form-validation';
      }
    });
  });

}).call(this);
<|endoftext|>


<commit_before>/*
---

description: Implements Upload functionality into the FileManager based on [FancyUpload](http://digitarald.de)

authors: Christoph Pojer (@cpojer)

license: MIT-style license.

requires: [Core/*]

provides: Filemanager.Uploader

...
*/

FileManager.implement({

	options: {
		resizeImages: true,
		upload: true,
		uploadAuthData: {}            // deprecated; use FileManager.propagateData instead!
	},

	hooks: {
		show: {
			upload: function() {
				this.startUpload();
			}
		},

		cleanup: {
			upload: function(){
				if (!this.options.upload || !this.upload) return;

				if (this.upload.uploader) this.upload.uploader.set('opacity', 0).dispose();
			}
		}
	},

	_lastFileUploaded: null,  // name of the last successfully uploaded file; will be preselected in the list view

	onDialogOpenWhenUpload: function(){
		if (this.swf && this.swf.box) this.swf.box.setStyle('visibility', 'hidden');
	},

	onDialogCloseWhenUpload: function(){
		if (this.swf && this.swf.box) this.swf.box.setStyle('visibility', 'visible');
	},

	startUpload: function(){

		if (!this.options.upload || this.swf) return;

		var self = this;
		this.upload = {
			button: this.addMenuButton('upload').inject(this.menu, 'bottom').addEvents({
				click: function(){
					return false;
				},
				mouseenter: function(){
					this.addClass('hover');
				},
				mouseleave: function(){
					this.removeClass('hover');
					this.blur();
				},
				mousedown: function(){
					this.focus();
				}
			}),
			list: new Element('ul', {'class': 'filemanager-uploader-list'}),
			uploader: new Element('div', {opacity: 0, 'class': 'filemanager-uploader-area'}).adopt(
				new Element('h2', {text: this.language.upload}),
				new Element('div', {'class': 'filemanager-uploader'})
			)
		};
		this.upload.uploader.getElement('div').adopt(this.upload.list);

		if (this.options.resizeImages){
			var resizer = new Element('div', {'class': 'checkbox'}),
				check = (function(){
			this.toggleClass('checkboxChecked');
		}).bind(resizer);
			check();
			this.upload.label = new Element('label').adopt(
				resizer, new Element('span', {text: this.language.resizeImages})
			).addEvent('click', check).inject(this.menu);
		}

		var File = new Class({

			Extends: Swiff.Uploader.File,

			initialize: function(base, data){

				this.parent(base, data);

				//if (typeof console !== 'undefined' && console.log) console.log('Uploader: setOptions');
				this.setOptions({
					//data: Object.merge({}, base.options.data, self.options.uploadAuthData),
					url: self.options.url + (self.options.url.indexOf('?') == -1 ? '?' : '&') + Object.toQueryString(Object.merge({}, (self.options.propagateType == 'GET' ? self.options.propagateData : {}), {
						event: 'upload',
						directory: self.Directory,
						filter: self.options.filter,
						resize: self.options.resizeImages && resizer.hasClass('checkboxChecked') ? 1 : 0
					}))
				});
			},

			render: function(){
				if (this.invalid){
					var message = self.language.uploader.unknown, sub = {
						name: this.name,
						size: Swiff.Uploader.formatUnit(this.size, 'b')
					};

					if (self.language.uploader[this.validationError])
						message = self.language.uploader[this.validationError];

					if (this.validationError == 'sizeLimitMin')
						sub.size_min = Swiff.Uploader.formatUnit(this.base.options.fileSizeMin, 'b');
					else if (this.validationError == 'sizeLimitMax')
						sub.size_max = Swiff.Uploader.formatUnit(this.base.options.fileSizeMax, 'b');

					this.showError(message.substitute(sub, /\\?\$\{([^{}]+)\}/g));
					return this;
				}

				this.addEvents({
					open: this.onOpen,
					remove: this.onRemove,
					requeue: this.onRequeue,
					progress: this.onProgress,
					stop: this.onStop,
					complete: this.onComplete
				});

				this.ui = {};
				this.ui.icon = new Asset.image(self.assetBasePath+'Images/Icons/' + this.extension + '.png', {
					'class': 'icon',
					onerror: function(){ new Asset.image(self.assetBasePath + 'Images/Icons/default.png').replaces(this); }
				});
				this.ui.element = new Element('li', {'class': 'file', id: 'file-' + this.id});
				this.ui.title = new Element('span', {'class': 'file-title', text: this.name});
				this.ui.size = new Element('span', {'class': 'file-size', text: Swiff.Uploader.formatUnit(this.size, 'b')});

				var file = this;
				this.ui.cancel = new Asset.image(self.assetBasePath+'Images/cancel.png', {'class': 'file-cancel', title: self.language.cancel}).addEvent('click', function(){
					file.remove();
					self.tips.hide();
					self.tips.detach(this);
				});
				self.tips.attach(this.ui.cancel);

				var progress = new Element('img', {'class': 'file-progress', src: self.assetBasePath+'Images/bar.gif'});

				this.ui.element.adopt(
					this.ui.cancel,
					progress,
					this.ui.icon,
					this.ui.title,
					this.ui.size
				).inject(self.upload.list).highlight();

				this.ui.progress = new Fx.ProgressBar(progress).set(0);

				this.base.reposition();

				return this.parent();
			},

			onOpen: function(){
				this.ui.element.addClass('file-running');
			},

			onRemove: function(){
				this.ui = this.ui.element.destroy();
			},

			onProgress: function(){
				this.ui.progress.start(this.progress.percentLoaded);
			},

			onStop: function(){
				this.remove();
			},

			onComplete: function(file_obj)
			{
				var response = null;
				var failure = true;

				this.ui.progress = this.ui.progress.cancel().element.destroy();
				this.ui.cancel = this.ui.cancel.destroy();

				try
				{
					response = JSON.decode(this.response.text);
				}
				catch(e)
				{
					if (typeof console !== 'undefined' && console.log) console.log(this.response);
				}

				if (typeof response === 'undefined' || response == null)
				{
					self.showError(self.language.uploader.mod_security);
				}
				else if (!response.status)
				{
					self.showError(('' + response.error).substitute(self.language, /\\?\$\{([^{}]+)\}/g));
				}
				else
				{
					failure = false;
				}

				this.ui.element.set('tween', {duration: 2000}).highlight(!failure ? '#e6efc2' : '#f0c2c2');
				(function(){
					this.ui.element.setStyle('overflow', 'hidden').morph({
						opacity: 0,
						height: 0
					}).get('morph').chain(function(){
						this.element.destroy();
						if (!self.upload.list.getElements('li').length)
						{
							self.upload.uploader.fade(0).get('tween').chain(function(){
								self.upload.uploader.setStyle('display', 'none');
							});
						}
					});
				}).delay(!failure ? 1000 : 5000, this);

				// don't wait for the cute delays to start updating the directory view!
				self.onShow = true;
				self.load(self.Directory, self._lastFileUploaded);
				// self.fillInfo();
			}
		});

		this.getFileTypes = function() {
			var fileTypes = {};
			if (this.options.filter == 'image')
				fileTypes = {'Images (*.jpg, *.gif, *.png)': '*.jpg; *.jpeg; *.bmp; *.gif; *.png'};
			if (this.options.filter == 'video')
				fileTypes = {'Videos (*.avi, *.flv, *.mov, *.mpeg, *.mpg, *.wmv, *.mp4)': '*.avi; *.flv; *.fli; *.movie; *.mpe; *.qt; *.viv; *.mkv; *.vivo; *.mov; *.mpeg; *.mpg; *.wmv; *.mp4'};
			if (this.options.filter == 'audio')
				fileTypes = {'Audio (*.aif, *.mid, *.mp3, *.mpga, *.rm, *.wav)': '*.aif; *.aifc; *.aiff; *.aif; *.au; *.mka; *.kar; *.mid; *.midi; *.mp2; *.mp3; *.mpga; *.ra; *.ram; *.rm; *.rpm; *.snd; *.wav; *.tsi'};
			if (this.options.filter == 'text')
				fileTypes = {'Text (*.txt, *.rtf, *.rtx, *.html, *.htm, *.css, *.as, *.xml, *.tpl)': '*.txt; *.rtf; *.rtx; *.html; *.htm; *.css; *.as; *.xml; *.tpl'};
			if (this.options.filter == 'application')
				fileTypes = {'Application (*.bin, *.doc, *.exe, *.iso, *.js, *.odt, *.pdf, *.php, *.ppt, *.swf, *.rar, *.zip)': '*.ai; *.bin; *.ccad; *.class; *.cpt; *.dir; *.dms; *.drw; *.doc; *.dvi; *.dwg; *.eps; *.exe; *.gtar; *.gz; *.js; *.latex; *.lnk; *.lnk; *.oda; *.odt; *.ods; *.odp; *.odg; *.odc; *.odf; *.odb; *.odi; *.odm; *.ott; *.ots; *.otp; *.otg; *.pdf; *.php; *.pot; *.pps; *.ppt; *.ppz; *.pre; *.ps; *.rar; *.set; *.sh; *.skd; *.skm; *.smi; *.smil; *.spl; *.src; *.stl; *.swf; *.tar; *.tex; *.texi; *.texinfo; *.tsp; *.unv; *.vcd; *.vda; *.xlc; *.xll; *.xlm; *.xls; *.xlw; *.zip'};

			return fileTypes;
		};

		//if (typeof console !== 'undefined' && console.log) console.log('Uploader: SWF init');
		this._lastFileUploaded = null;
		this.swf = new Swiff.Uploader({
			id: 'SwiffFileManagerUpload',
			path: this.assetBasePath + 'Swiff.Uploader.swf',
			queued: false,
			target: this.upload.button,
			allowDuplicates: true,
			instantStart: true,
			appendCookieData: true, // pass along any session cookie data, etc. in the request section (PHP: $_GET[])
			data: Object.merge({},
				(self.options.propagateType == 'POST' ? self.options.propagateData : {}),
				(self.options.uploadAuthData || {})
			),
			fileClass: File,
			timeLimit: 260,
			fileSizeMax: 2600 * 2600 * 25,
			typeFilter: this.getFileTypes(),
			zIndex: this.SwiffZIndex || 9999,
			onSelectSuccess: function(){
				self.fillInfo();
				//self.info.getElement('h2.filemanager-headline').setStyle('display', 'none');
				self.info.adopt(self.upload.uploader.setStyle('display', 'block'));
				self.upload.uploader.fade(1);
			},
			onComplete: function(){

			},
			onFileComplete: function(f){
				self._lastFileUploaded = f.name;
			},
			onFail: function(error) {
				if (error !== 'empty') {
					$$(self.upload.button, self.upload.label).dispose();
					self.showError(self.language.flash[error] || self.language.flash.flash);
				}
			}
		});
	}
});

<commit_msg>Uploader: the maximum allowed filesize is configurable server-side, but not yet client-side. Now it is: 'uploadTimeLimit' and 'uploadFileSizeMax' Swiff parameters are now part of the FileManager options.<commit_after>/*
---

description: Implements Upload functionality into the FileManager based on [FancyUpload](http://digitarald.de)

authors: Christoph Pojer (@cpojer)

license: MIT-style license.

requires: [Core/*]

provides: Filemanager.Uploader

...
*/

FileManager.implement({

	options: {
		resizeImages: true,
		upload: true,
		uploadAuthData: {},            // deprecated; use FileManager.propagateData instead!
		uploadTimeLimit: 260,
		uploadFileSizeMax: 2600 * 2600 * 25
	},

	hooks: {
		show: {
			upload: function() {
				this.startUpload();
			}
		},

		cleanup: {
			upload: function(){
				if (!this.options.upload || !this.upload) return;

				if (this.upload.uploader) this.upload.uploader.set('opacity', 0).dispose();
			}
		}
	},

	_lastFileUploaded: null,  // name of the last successfully uploaded file; will be preselected in the list view

	onDialogOpenWhenUpload: function(){
		if (this.swf && this.swf.box) this.swf.box.setStyle('visibility', 'hidden');
	},

	onDialogCloseWhenUpload: function(){
		if (this.swf && this.swf.box) this.swf.box.setStyle('visibility', 'visible');
	},

	startUpload: function(){

		if (!this.options.upload || this.swf) return;

		var self = this;
		this.upload = {
			button: this.addMenuButton('upload').inject(this.menu, 'bottom').addEvents({
				click: function(){
					return false;
				},
				mouseenter: function(){
					this.addClass('hover');
				},
				mouseleave: function(){
					this.removeClass('hover');
					this.blur();
				},
				mousedown: function(){
					this.focus();
				}
			}),
			list: new Element('ul', {'class': 'filemanager-uploader-list'}),
			uploader: new Element('div', {opacity: 0, 'class': 'filemanager-uploader-area'}).adopt(
				new Element('h2', {text: this.language.upload}),
				new Element('div', {'class': 'filemanager-uploader'})
			)
		};
		this.upload.uploader.getElement('div').adopt(this.upload.list);

		if (this.options.resizeImages){
			var resizer = new Element('div', {'class': 'checkbox'}),
				check = (function(){
			this.toggleClass('checkboxChecked');
		}).bind(resizer);
			check();
			this.upload.label = new Element('label').adopt(
				resizer, new Element('span', {text: this.language.resizeImages})
			).addEvent('click', check).inject(this.menu);
		}

		var File = new Class({

			Extends: Swiff.Uploader.File,

			initialize: function(base, data){

				this.parent(base, data);

				//if (typeof console !== 'undefined' && console.log) console.log('Uploader: setOptions');
				this.setOptions({
					//data: Object.merge({}, base.options.data, self.options.uploadAuthData),
					url: self.options.url + (self.options.url.indexOf('?') == -1 ? '?' : '&') + Object.toQueryString(Object.merge({}, (self.options.propagateType == 'GET' ? self.options.propagateData : {}), {
						event: 'upload',
						directory: self.Directory,
						filter: self.options.filter,
						resize: self.options.resizeImages && resizer.hasClass('checkboxChecked') ? 1 : 0
					}))
				});
			},

			render: function(){
				if (this.invalid){
					var message = self.language.uploader.unknown, sub = {
						name: this.name,
						size: Swiff.Uploader.formatUnit(this.size, 'b')
					};

					if (self.language.uploader[this.validationError])
						message = self.language.uploader[this.validationError];

					if (this.validationError == 'sizeLimitMin')
						sub.size_min = Swiff.Uploader.formatUnit(this.base.options.fileSizeMin, 'b');
					else if (this.validationError == 'sizeLimitMax')
						sub.size_max = Swiff.Uploader.formatUnit(this.base.options.fileSizeMax, 'b');

					this.showError(message.substitute(sub, /\\?\$\{([^{}]+)\}/g));
					return this;
				}

				this.addEvents({
					open: this.onOpen,
					remove: this.onRemove,
					requeue: this.onRequeue,
					progress: this.onProgress,
					stop: this.onStop,
					complete: this.onComplete
				});

				this.ui = {};
				this.ui.icon = new Asset.image(self.assetBasePath+'Images/Icons/' + this.extension + '.png', {
					'class': 'icon',
					onerror: function(){ new Asset.image(self.assetBasePath + 'Images/Icons/default.png').replaces(this); }
				});
				this.ui.element = new Element('li', {'class': 'file', id: 'file-' + this.id});
				this.ui.title = new Element('span', {'class': 'file-title', text: this.name});
				this.ui.size = new Element('span', {'class': 'file-size', text: Swiff.Uploader.formatUnit(this.size, 'b')});

				var file = this;
				this.ui.cancel = new Asset.image(self.assetBasePath+'Images/cancel.png', {'class': 'file-cancel', title: self.language.cancel}).addEvent('click', function(){
					file.remove();
					self.tips.hide();
					self.tips.detach(this);
				});
				self.tips.attach(this.ui.cancel);

				var progress = new Element('img', {'class': 'file-progress', src: self.assetBasePath+'Images/bar.gif'});

				this.ui.element.adopt(
					this.ui.cancel,
					progress,
					this.ui.icon,
					this.ui.title,
					this.ui.size
				).inject(self.upload.list).highlight();

				this.ui.progress = new Fx.ProgressBar(progress).set(0);

				this.base.reposition();

				return this.parent();
			},

			onOpen: function(){
				this.ui.element.addClass('file-running');
			},

			onRemove: function(){
				this.ui = this.ui.element.destroy();
			},

			onProgress: function(){
				this.ui.progress.start(this.progress.percentLoaded);
			},

			onStop: function(){
				this.remove();
			},

			onComplete: function(file_obj)
			{
				var response = null;
				var failure = true;

				this.ui.progress = this.ui.progress.cancel().element.destroy();
				this.ui.cancel = this.ui.cancel.destroy();

				try
				{
					response = JSON.decode(this.response.text);
				}
				catch(e)
				{
					if (typeof console !== 'undefined' && console.log) console.log(this.response);
				}

				if (typeof response === 'undefined' || response == null)
				{
					self.showError(self.language.uploader.mod_security);
				}
				else if (!response.status)
				{
					self.showError(('' + response.error).substitute(self.language, /\\?\$\{([^{}]+)\}/g));
				}
				else
				{
					failure = false;
				}

				this.ui.element.set('tween', {duration: 2000}).highlight(!failure ? '#e6efc2' : '#f0c2c2');
				(function(){
					this.ui.element.setStyle('overflow', 'hidden').morph({
						opacity: 0,
						height: 0
					}).get('morph').chain(function(){
						this.element.destroy();
						if (!self.upload.list.getElements('li').length)
						{
							self.upload.uploader.fade(0).get('tween').chain(function(){
								self.upload.uploader.setStyle('display', 'none');
							});
						}
					});
				}).delay(!failure ? 1000 : 5000, this);

				// don't wait for the cute delays to start updating the directory view!
				self.onShow = true;
				self.load(self.Directory, self._lastFileUploaded);
				// self.fillInfo();
			}
		});

		this.getFileTypes = function() {
			var fileTypes = {};
			if (this.options.filter == 'image')
				fileTypes = {'Images (*.jpg, *.gif, *.png)': '*.jpg; *.jpeg; *.bmp; *.gif; *.png'};
			if (this.options.filter == 'video')
				fileTypes = {'Videos (*.avi, *.flv, *.mov, *.mpeg, *.mpg, *.wmv, *.mp4)': '*.avi; *.flv; *.fli; *.movie; *.mpe; *.qt; *.viv; *.mkv; *.vivo; *.mov; *.mpeg; *.mpg; *.wmv; *.mp4'};
			if (this.options.filter == 'audio')
				fileTypes = {'Audio (*.aif, *.mid, *.mp3, *.mpga, *.rm, *.wav)': '*.aif; *.aifc; *.aiff; *.aif; *.au; *.mka; *.kar; *.mid; *.midi; *.mp2; *.mp3; *.mpga; *.ra; *.ram; *.rm; *.rpm; *.snd; *.wav; *.tsi'};
			if (this.options.filter == 'text')
				fileTypes = {'Text (*.txt, *.rtf, *.rtx, *.html, *.htm, *.css, *.as, *.xml, *.tpl)': '*.txt; *.rtf; *.rtx; *.html; *.htm; *.css; *.as; *.xml; *.tpl'};
			if (this.options.filter == 'application')
				fileTypes = {'Application (*.bin, *.doc, *.exe, *.iso, *.js, *.odt, *.pdf, *.php, *.ppt, *.swf, *.rar, *.zip)': '*.ai; *.bin; *.ccad; *.class; *.cpt; *.dir; *.dms; *.drw; *.doc; *.dvi; *.dwg; *.eps; *.exe; *.gtar; *.gz; *.js; *.latex; *.lnk; *.lnk; *.oda; *.odt; *.ods; *.odp; *.odg; *.odc; *.odf; *.odb; *.odi; *.odm; *.ott; *.ots; *.otp; *.otg; *.pdf; *.php; *.pot; *.pps; *.ppt; *.ppz; *.pre; *.ps; *.rar; *.set; *.sh; *.skd; *.skm; *.smi; *.smil; *.spl; *.src; *.stl; *.swf; *.tar; *.tex; *.texi; *.texinfo; *.tsp; *.unv; *.vcd; *.vda; *.xlc; *.xll; *.xlm; *.xls; *.xlw; *.zip'};

			return fileTypes;
		};

		//if (typeof console !== 'undefined' && console.log) console.log('Uploader: SWF init');
		this._lastFileUploaded = null;
		this.swf = new Swiff.Uploader({
			id: 'SwiffFileManagerUpload',
			path: this.assetBasePath + 'Swiff.Uploader.swf',
			queued: false,
			target: this.upload.button,
			allowDuplicates: true,
			instantStart: true,
			appendCookieData: true, // pass along any session cookie data, etc. in the request section (PHP: $_GET[])
			data: Object.merge({},
				(self.options.propagateType == 'POST' ? self.options.propagateData : {}),
				(self.options.uploadAuthData || {})
			),
			fileClass: File,
			timeLimit: self.options.uploadTimeLimit,
			fileSizeMax: self.options.uploadFileSizeMax,
			typeFilter: this.getFileTypes(),
			zIndex: this.SwiffZIndex || 9999,
			onSelectSuccess: function(){
				self.fillInfo();
				//self.info.getElement('h2.filemanager-headline').setStyle('display', 'none');
				self.info.adopt(self.upload.uploader.setStyle('display', 'block'));
				self.upload.uploader.fade(1);
			},
			onComplete: function(){

			},
			onFileComplete: function(f){
				self._lastFileUploaded = f.name;
			},
			onFail: function(error) {
				if (error !== 'empty') {
					$$(self.upload.button, self.upload.label).dispose();
					self.showError(self.language.flash[error] || self.language.flash.flash);
				}
			}
		});
	}
});

<|endoftext|>