<commit_before>'use strict';

angular.module('ddsApp').factory('SituationService', function($http, $sessionStorage, $filter) {
    var situation;

    return {
        nationaliteLabels: {
            fr: 'française',
            ue: 'UE',
            autre: 'hors UE'
        },

        relationTypeLabels: {
            'mariage': 'marié(e)',
            'pacs': 'pacsé(e)',
            'relation_libre': 'en relation libre'
        },

        find: function(situationId) {
            return $http.get('/api/situations/' + situationId).then(function(result) {
                return result.data;
            });
        },

        newSituation: function() {
            situation = {};
            $sessionStorage.situation = situation;
        },

        restoreLocal: function() {
            if (!situation) {
                situation = $sessionStorage.situation || {};
            }

            return situation;
        },

        createIndividusList: function(situation) {
            var individus = [situation.demandeur];

            if (situation.conjoint) {
                individus.push(situation.conjoint);
            }

            individus = individus.concat(situation.enfants).concat(situation.personnesACharge);

            return individus;
        },

        individuLabel: function(individu) {
            if ('demandeur' === individu.role) {
                return 'Vous';
            }

            if ('conjoint' === individu.role) {
                return 'Votre conjoint';
            }

            return individu.firstName;
        },

        formatStatutsSpecifiques: function(individu) {
            var statuses = [];
            _.forEach(this.statutsSpecifiquesLabels, function(statut, statutId) {
                if (individu[statutId]) {
                    statuses.push(statut);
                }
            });

            statuses = statuses.join(', ');
            statuses = $filter('uppercaseFirst')(statuses);

            return statuses;
        },

        statutsSpecifiquesLabels: {
            'boursierEnseignementSup': 'boursier enseignement supérieur',
            'etudiant': 'étudiant',
            'demandeurEmploi': 'demandeur d\'emploi',
            'retraite': 'retraité'
        },

        getMonths: function() {
            // FIXME prendre la date du serveur
            return _.map([3, 2, 1], function(i) {
                var date = moment().subtract('months', i);
                return {
                    id: date.format('YYYY-MM'),
                    label: date.format('MMMM YYYY')
                };
            });
        },

        create: function(situation) {
            var apiSituation = this.createApiCompatibleSituation(situation);
            return $http.post('/api/situations', apiSituation).then(function(result) {
                return result.data;
            });
        },

        update: function(situation) {
            var apiSituation = this.createApiCompatibleSituation(situation);
            return $http.put('/api/situations/' + situation._id, apiSituation).then(function(result) {
                return result.data;
            });
        },

        createApiCompatibleSituation: function(situation) {
            var individus = [situation.demandeur];
            situation.demandeur.role = 'demandeur';
            if (situation.demandeur.dateSituationFamilialeString) {
                situation.demandeur.dateSituationFamiliale = moment(situation.demandeur.dateSituationFamilialeString, 'DD/MM/YYYY').format('YYYY-MM-DD');
            }

            if (situation.conjoint) {
                individus.push(situation.conjoint);
                situation.conjoint.role = 'conjoint';
                situation.demandeur.statutMarital = situation.conjoint.relationType;
            } else {
                situation.demandeur.statutMarital = situation.demandeur.situationFamiliale;
            }

            situation.enfants.forEach(function(enfant) {
                enfant.role = 'enfant';
            });

            situation.personnesACharge.forEach(function(personne) {
                personne.role = 'personneACharge';
            });

            individus = individus.concat(situation.enfants).concat(situation.personnesACharge);
            individus = _.map(individus, this.createApiCompatibleIndividu);

            if (situation.logement.dateArriveeString) {
                situation.logement.dateArrivee = moment(situation.logement.dateArriveeString, 'DD/MM/YYYY').format('YYYY-MM-DD');
            }

            var result = {
                individus: individus,
                logement: situation.logement,
                mobilierValue: situation.mobilierValue,
                immobilierValue: situation.immobilierValue,
                phoneNumber: situation.phoneNumber,
                email: situation.email
            };

            return result;
        },

        createApiCompatibleIndividu: function(individu) {
            individu = _.cloneDeep(individu);
            individu.dateDeNaissance = moment(individu.birthDate, 'DD/MM/YYYY').format('YYYY-MM-DD');
            if (individu.dateArriveeFoyerString) {
                individu.dateArriveeFoyer = moment(individu.dateArriveeFoyerString, 'DD/MM/YYYY').format('YYYY-MM-DD');
            }

            return individu;
        },

        logementTypes: [
            {
                label: 'locataire',
                value: 'locataire',
                helpText: 'Locataire ou sous-locataire'
            },
            {
                label: 'colocataire',
                value: 'colocataire'
            },
            {
                label: 'propriétaire',
                value: 'proprietaire'
            },
            {
                label: 'occupant à titre gratuit',
                value: 'gratuit'
            },
            {
                label: 'occupant à titre onéreux',
                value: 'payant',
                helpText: 'Camping, caravane, hébergement payant...'
            }
        ],

        revenusSections: [
            {
                name: 'revenusActivite',
                label: 'Revenus d\'activité',
                subsections: [
                    {
                        name: 'revenusSalarie',
                        label: 'Salaires'
                    }, {
                        name: 'revenusNonSalarie',
                        label: 'Revenus non salariés'
                    }, {
                        name: 'revenusAutoEntrepreneur',
                        label: 'Revenus auto-entrepreneur'
                    }, {
                        name: 'revenusStage',
                        label: 'Revenus de stage de formation professionnelle'
                    }
                ]
            },
            {
                name: 'allocations',
                label: 'Allocations',
                subsections: [
                    {
                        name: 'allocationsChomage',
                        label: 'Allocation chômage'
                    }, {
                        name: 'allocationLogement',
                        label: 'Aide au logement'
                    }, {
                        name: 'rsa',
                        label: 'Revenu de solidarité active (RSA)'
                    }, {
                        name: 'asf',
                        label: 'Allocation de soutien familial (ASF)'
                    }, {
                        name: 'aspa',
                        label: 'Allocation de solidarité aux personnes âgées (ASPA)'
                    }, {
                        name: 'ass',
                        label: 'Allocation de solidarité spécifique (ASS)'
                    }, {
                        name: 'aah',
                        label: 'Allocation adulte handicapé'
                    }
                ]
            },
            {
                name: 'indemnites',
                label: 'Indemnités',
                subsections: [
                    {
                        name: 'indJourMaternite',
                        label: 'Indemnités de maternité, paternité, adoption'
                    }, {
                        name: 'indJourMaladie',
                        label: 'Indemnités maladie'
                    }, {
                        name: 'indJourMaladieProf',
                        label: 'Indemnités maladie professionnelle'
                    }, {
                        name: 'indJourAccidentDuTravail',
                        label: 'Indemnités accident du travail'
                    }, {
                        name: 'indChomagePartiel',
                        label: 'Indemnités de chômage partiel'
                    }
                ]
            },
            {
                name: 'pensions',
                label: 'Pensions',
                subsections: [
                    {
                        name: 'pensionsAlimentaires',
                        label: 'Pensions alimentaires'
                    }, {
                        name: 'pensionsRetraitesRentes',
                        label: 'Retraites (y compris reversion), rentes'
                    }, {
                        name: 'pensionsInvalidite',
                        label: 'Pensions d\'invalidité'
                    }
                ]
            },
            {
                name: 'autre',
                label: 'Autres ressources',
                subsections: [
                    {
                        name: 'revenusLocatifs',
                        label: 'Revenus locatifs'
                    },
                    {
                        name: 'bourseEnseignementSup',
                        label: 'Bourses de l\'enseignement supérieur'
                    }
                ]
            }
        ]
    };
});
<commit_msg>suppression temporaire du type de logement colocation car non géré<commit_after>'use strict';

angular.module('ddsApp').factory('SituationService', function($http, $sessionStorage, $filter) {
    var situation;

    return {
        nationaliteLabels: {
            fr: 'française',
            ue: 'UE',
            autre: 'hors UE'
        },

        relationTypeLabels: {
            'mariage': 'marié(e)',
            'pacs': 'pacsé(e)',
            'relation_libre': 'en relation libre'
        },

        find: function(situationId) {
            return $http.get('/api/situations/' + situationId).then(function(result) {
                return result.data;
            });
        },

        newSituation: function() {
            situation = {};
            $sessionStorage.situation = situation;
        },

        restoreLocal: function() {
            if (!situation) {
                situation = $sessionStorage.situation || {};
            }

            return situation;
        },

        createIndividusList: function(situation) {
            var individus = [situation.demandeur];

            if (situation.conjoint) {
                individus.push(situation.conjoint);
            }

            individus = individus.concat(situation.enfants).concat(situation.personnesACharge);

            return individus;
        },

        individuLabel: function(individu) {
            if ('demandeur' === individu.role) {
                return 'Vous';
            }

            if ('conjoint' === individu.role) {
                return 'Votre conjoint';
            }

            return individu.firstName;
        },

        formatStatutsSpecifiques: function(individu) {
            var statuses = [];
            _.forEach(this.statutsSpecifiquesLabels, function(statut, statutId) {
                if (individu[statutId]) {
                    statuses.push(statut);
                }
            });

            statuses = statuses.join(', ');
            statuses = $filter('uppercaseFirst')(statuses);

            return statuses;
        },

        statutsSpecifiquesLabels: {
            'boursierEnseignementSup': 'boursier enseignement supérieur',
            'etudiant': 'étudiant',
            'demandeurEmploi': 'demandeur d\'emploi',
            'retraite': 'retraité'
        },

        getMonths: function() {
            // FIXME prendre la date du serveur
            return _.map([3, 2, 1], function(i) {
                var date = moment().subtract('months', i);
                return {
                    id: date.format('YYYY-MM'),
                    label: date.format('MMMM YYYY')
                };
            });
        },

        create: function(situation) {
            var apiSituation = this.createApiCompatibleSituation(situation);
            return $http.post('/api/situations', apiSituation).then(function(result) {
                return result.data;
            });
        },

        update: function(situation) {
            var apiSituation = this.createApiCompatibleSituation(situation);
            return $http.put('/api/situations/' + situation._id, apiSituation).then(function(result) {
                return result.data;
            });
        },

        createApiCompatibleSituation: function(situation) {
            var individus = [situation.demandeur];
            situation.demandeur.role = 'demandeur';
            if (situation.demandeur.dateSituationFamilialeString) {
                situation.demandeur.dateSituationFamiliale = moment(situation.demandeur.dateSituationFamilialeString, 'DD/MM/YYYY').format('YYYY-MM-DD');
            }

            if (situation.conjoint) {
                individus.push(situation.conjoint);
                situation.conjoint.role = 'conjoint';
                situation.demandeur.statutMarital = situation.conjoint.relationType;
            } else {
                situation.demandeur.statutMarital = situation.demandeur.situationFamiliale;
            }

            situation.enfants.forEach(function(enfant) {
                enfant.role = 'enfant';
            });

            situation.personnesACharge.forEach(function(personne) {
                personne.role = 'personneACharge';
            });

            individus = individus.concat(situation.enfants).concat(situation.personnesACharge);
            individus = _.map(individus, this.createApiCompatibleIndividu);

            if (situation.logement.dateArriveeString) {
                situation.logement.dateArrivee = moment(situation.logement.dateArriveeString, 'DD/MM/YYYY').format('YYYY-MM-DD');
            }

            var result = {
                individus: individus,
                logement: situation.logement,
                mobilierValue: situation.mobilierValue,
                immobilierValue: situation.immobilierValue,
                phoneNumber: situation.phoneNumber,
                email: situation.email
            };

            return result;
        },

        createApiCompatibleIndividu: function(individu) {
            individu = _.cloneDeep(individu);
            individu.dateDeNaissance = moment(individu.birthDate, 'DD/MM/YYYY').format('YYYY-MM-DD');
            if (individu.dateArriveeFoyerString) {
                individu.dateArriveeFoyer = moment(individu.dateArriveeFoyerString, 'DD/MM/YYYY').format('YYYY-MM-DD');
            }

            return individu;
        },

        logementTypes: [
            {
                label: 'locataire',
                value: 'locataire',
                helpText: 'Locataire ou sous-locataire'
            },
            {
                label: 'propriétaire',
                value: 'proprietaire'
            },
            {
                label: 'occupant à titre gratuit',
                value: 'gratuit'
            },
            {
                label: 'occupant à titre onéreux',
                value: 'payant',
                helpText: 'Camping, caravane, hébergement payant...'
            }
        ],

        revenusSections: [
            {
                name: 'revenusActivite',
                label: 'Revenus d\'activité',
                subsections: [
                    {
                        name: 'revenusSalarie',
                        label: 'Salaires'
                    }, {
                        name: 'revenusNonSalarie',
                        label: 'Revenus non salariés'
                    }, {
                        name: 'revenusAutoEntrepreneur',
                        label: 'Revenus auto-entrepreneur'
                    }, {
                        name: 'revenusStage',
                        label: 'Revenus de stage de formation professionnelle'
                    }
                ]
            },
            {
                name: 'allocations',
                label: 'Allocations',
                subsections: [
                    {
                        name: 'allocationsChomage',
                        label: 'Allocation chômage'
                    }, {
                        name: 'allocationLogement',
                        label: 'Aide au logement'
                    }, {
                        name: 'rsa',
                        label: 'Revenu de solidarité active (RSA)'
                    }, {
                        name: 'asf',
                        label: 'Allocation de soutien familial (ASF)'
                    }, {
                        name: 'aspa',
                        label: 'Allocation de solidarité aux personnes âgées (ASPA)'
                    }, {
                        name: 'ass',
                        label: 'Allocation de solidarité spécifique (ASS)'
                    }, {
                        name: 'aah',
                        label: 'Allocation adulte handicapé'
                    }
                ]
            },
            {
                name: 'indemnites',
                label: 'Indemnités',
                subsections: [
                    {
                        name: 'indJourMaternite',
                        label: 'Indemnités de maternité, paternité, adoption'
                    }, {
                        name: 'indJourMaladie',
                        label: 'Indemnités maladie'
                    }, {
                        name: 'indJourMaladieProf',
                        label: 'Indemnités maladie professionnelle'
                    }, {
                        name: 'indJourAccidentDuTravail',
                        label: 'Indemnités accident du travail'
                    }, {
                        name: 'indChomagePartiel',
                        label: 'Indemnités de chômage partiel'
                    }
                ]
            },
            {
                name: 'pensions',
                label: 'Pensions',
                subsections: [
                    {
                        name: 'pensionsAlimentaires',
                        label: 'Pensions alimentaires'
                    }, {
                        name: 'pensionsRetraitesRentes',
                        label: 'Retraites (y compris reversion), rentes'
                    }, {
                        name: 'pensionsInvalidite',
                        label: 'Pensions d\'invalidité'
                    }
                ]
            },
            {
                name: 'autre',
                label: 'Autres ressources',
                subsections: [
                    {
                        name: 'revenusLocatifs',
                        label: 'Revenus locatifs'
                    },
                    {
                        name: 'bourseEnseignementSup',
                        label: 'Bourses de l\'enseignement supérieur'
                    }
                ]
            }
        ]
    };
});
<|endoftext|>


<commit_before>var frameRate = 50, interval;
var corners, startTime;
var gameActive = false, pageLoaded = false;
var clock, clockHeight = 0, seconds = 0, minutes = 0, hours = 0, t, timeMult = 1;
var standardArea = 1520000, screenFactor = 1;//used to scale up size/speed of game for large displays

//The rat, Brie, follows the mouse pointer
var rat = {
    pos: [],
    speed : 8, //number of pixels rat can move per frame
    maxSpeed: 8,
    id: "ratPic",
    height: 30,
    width: 20,
    goal: [],
    updateGoal : function() {
        this.goal = [window.mouseX+24, window.mouseY - clockHeight+20];//offsets for cheese cursor size
        //adjust rat's speed to prevent overshooting goal
        var dist = distance(this.pos, this.goal);
        if ( dist < 3 ) {
            this.speed = 0;
        } else {
            this.speed = Math.min(this.maxSpeed, dist);
            //rotate the rat image to face the goal (if not too close already)
            var theta = Math.atan2(this.goal[1] - this.pos[1], this.goal[0] - this.pos[0]);
            document.getElementById("ratPic").style.transform = "rotate("+(theta*57.296-90)+"deg)";
        }
    }
};

//Cat1, Willy, goes straight for the rat, but slowly (chaser)
var cat1 = {
    pos: [],
    speed : 4, //pixels per frame
    goal: [],
    id: "cat1",
    img: "cat-orange.png",
    imgNear: "cat-orange-bite.png",
    height: 46,
    width: 50,
    updateGoal : function() {
        this.goal =  rat.pos;
    }
};

//Cat2, Whiskers, goes to random places (wanderer)
var cat2 = {
    pos: [],
    speed : 8, //pixels per frame
    goal: [],
    id: "cat2",
    img: "cat-blue.png",
    imgNear: "cat-blue-bite.png",
    height: 46,
    width: 50,
    updateGoal : function() {
        if( inRange( this.pos, this.goal, this.width) ) {
            this.goal = [Math.round(Math.random()*window.innerWidth),
                         Math.round(Math.random()*window.innerHeight)];
        }
    }
};

//Cat3, Wendy, runs around the edges, and attacks when lined up with the rat (dasher)
var cat3 = {
    pos: [],
    speed : 11, //pixels per frame
    goal: [],
    id:"cat3",
    img: "cat-pink.png",
    imgNear: "cat-pink-bite.png",
    height:46,
    width: 50,
    state: "CW", //toggles clockwise or counter-clockwise edge movement
    setToEdgeState: function(){
        if(this.state=="ATK"){
            if(Math.random() > 0.5)
                this.state = "CW";
            else
                this.state = "CCW";
        }
    },
    isAtTop: function(){return this.pos[1] <= this.height;},
    isAtRight: function(){return this.pos[0] >= window.innerWidth - this.width;},
    isAtBottom: function(){return this.pos[1] >= window.innerHeight - this.height;},
    isAtLeft: function(){return this.pos[0] <= this.width;},
    updateGoal : function() {
        if( inRange( this.pos, this.goal, this.width) ) {  //pick a corner for new goal
            if( this.isAtTop() && !this.isAtRight()){//goal = top right
                this.goal = corners[1];
                this.setToEdgeState();
            } else if(this.isAtRight() && !this.isAtBottom()){//goal = bottom right
                this.goal = corners[2];
                this.setToEdgeState();
            } else if(this.isAtBottom() && !this.isAtLeft()){//goal = bottom left
                this.goal = corners[3];
                this.setToEdgeState();
            } else if(this.isAtLeft() && !this.isAtTop()) { //goal = top left
                this.goal = corners[0];
                this.setToEdgeState();
            }
        }
        //attack if rat is aligned orthogonally (only when roaming edge)
        if(this.state!="ATK"){
            if (this.isAtLeft() || this.isAtRight() ||
                this.isAtTop() || this.isAtBottom()) {
                if( Math.abs(this.pos[0]-rat.pos[0]) < rat.width ) { //vertical attack
                    if( this.pos[1] <= this.height)
                        this.goal = [this.pos[0], corners[2][1]]; //downward
                    else
                        this.goal = [this.pos[0], corners[0][1]]; //upward
                    this.state = "ATK";
                } else if( Math.abs(this.pos[1]-rat.pos[1]) < rat.height ) { //horizontal attack
                    if( this.pos[0] <= this.width)
                        this.goal = [corners[2][0], this.pos[1]];//rightward
                    else
                        this.goal = [corners[0][0], this.pos[1]];//leftward
                   this.state = "ATK";
                }
            }
        }
    }
};

//Cat4, Bob, is wants to move toward the rat, but avoids other cats (flanker)
var cat4 = {
    pos: [],
    speed : 6, //pixels per frame
    repulse: -60,//repulsive force from other cats
    goal: [],
    id: "cat4",
    img: "cat-yellow.png",
    imgNear: "cat-yellow-bite.png",
    height: 46,
    width: 50,
    updateGoal : function() {
        //add up superposition forces from rat & cats
        //constant attractive force toward rat (doesn't scale with distance)
        var theta = Math.atan2(rat.pos[1] - this.pos[1], rat.pos[0] - this.pos[0]);
        this.goal[0] = this.pos[0] + Math.round( this.speed * Math.cos(theta) );
        this.goal[1] = this.pos[1] + Math.round( this.speed * Math.sin(theta) );
        var distF;
        //add repulsive forces from other cats (large forces that drop with distance factor)
        for (var i=0; i < 3; i++) {
            theta = Math.atan2(cats[i].pos[1] - this.pos[1], cats[i].pos[0] - this.pos[0]);
            distF = Math.pow(distance(this.pos, cats[i].pos),0.57);
            if(distF != 0) {
                this.goal[0] += Math.round( this.repulse * Math.cos(theta) ) / distF;
                this.goal[1] += Math.round( this.repulse * Math.sin(theta) ) / distF;
            }
        }
    }
};

var cats = [cat1, cat2, cat3, cat4];//for looping over the cats
var players = [rat, cat1, cat2, cat3, cat4];//for looping over all players

document.onmousemove = function(e) {
    var event = e || window.event;
    window.mouseX = event.clientX;
    window.mouseY = event.clientY;
}

function setClassDisplay(className, disp) {
    var x = document.getElementsByClassName(className);
    for (var i = 0; i < x.length; i++) {
        x[i].style.display = disp;
    }
}

function distance(p1, p2) {
    var x = p1[0] - p2[0];
    var y = p1[1] - p2[1];
    return Math.sqrt( (x*x) + (y*y) );
}

function inRange(pos1, pos2, dist) {
    return distance(pos1, pos2) <= dist;
}

function moveTowardGoal(mover) {
    var theta = Math.atan2(mover.goal[1] - mover.pos[1], mover.goal[0] - mover.pos[0]);
    mover.pos[0] += Math.round( mover.speed * timeMult * screenFactor * Math.cos(theta) );
    mover.pos[1] += Math.round( mover.speed * timeMult * screenFactor * Math.sin(theta) );
    document.getElementById(mover.id).style.marginLeft = mover.pos[0] - mover.width + "px";
    document.getElementById(mover.id).style.marginTop = mover.pos[1] - mover.height + "px";
}

//Update the game area
function updateGameState() {
    if(window.mouseX == undefined || window.mouseY == undefined || gameActive == false){
        return;
    }

    //each rat/cat gets to update and move
    for(var i=0; i < players.length; i++){
        players[i].updateGoal();
        moveTowardGoal(players[i]);
    }

    //Check lose condition and update cat image if near rat
    for(i=0; i < cats.length; i++){
        if( inRange(rat.pos, cats[i].pos, cats[i].width*1.1))
            endGame();
        else if( inRange(rat.pos, cats[i].pos, cats[i].width*2.5))
            $('#'+cats[i].id).attr("src", cats[i].imgNear);
        else
            $('#'+cats[i].id).attr("src", cats[i].img);
    }
}

function addSec() {
    seconds++;
    if (seconds >= 60) {
        seconds = 0;
        minutes++;
        if (minutes >= 60) {
            minutes = 0;
            hours++;
        }
    }
    clock.textContent = (hours ? (hours > 9 ? hours : "0" + hours) : "00") +
                        ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") +
                        ":" + (seconds > 9 ? seconds : "0" + seconds);
    timer();
}
function timer() {
    t = setTimeout(addSec, 1000/timeMult);
}

function startGame() {
    if(!pageLoaded) {
        return;//the page must finish loading before game can start
    }
    timeMult = Number($('#timeMultiplier').val());
    interval = setInterval(updateGameState, 1000/(frameRate));
    gameActive = true;
    clock = document.getElementById('clock')
    clock.textContent = "00:00:00";
    seconds = 0; minutes = 0; hours = 0;
    timer();
    //reset game pieces
    rat.pos =  [window.innerWidth/2, window.innerHeight/2];
    cat1.pos = [corners[2][0], corners[2][1]];
    cat2.pos = [corners[0][0], corners[0][1]];
    cat2.goal = [corners[0][0], corners[0][1]];
    cat3.pos = [corners[1][0], corners[1][1]];
    cat3.goal = [corners[2][0], corners[2][1]];
    cat4.pos = [corners[3][0], corners[3][1]];
    cat4.goal = [corners[3][0], corners[3][1]];

    setClassDisplay("game", "block");
    setClassDisplay("preGame", "none");
    document.getElementsByTagName("body")[0].style.cursor = "url(cheese.png), auto";
}

function endGame() {
    clearInterval(interval);
    gameActive = false;
    clearTimeout(t);
    //show non-game elements
    setClassDisplay("preGame", "block");
    //hide game elements
    setClassDisplay("game", "none");
    document.getElementsByTagName("body")[0].style.cursor = "default";
}

function adjustToWindow(){
    //Scale size/speed of game elements based on display size.
    //Average of 1 and ratio of expected screen size
    screenFactor = (1+(window.innerHeight * window.innerWidth / standardArea))/2;

    //use loaded elements to get game dimensions
    rat.height = $('#ratPic').height()/2;
    rat.width = $('#ratPic').width()/2;
    cat1.height = cat2.height = cat3.height = $('#cat1').height()/2;
    cat1.width = cat2.width = cat3.width = $('#cat1').width()/2;
    clockHeight = $('#clock').height();
    corners = [ [cat3.width, cat3.height],
                [window.innerWidth-cat3.width, cat3.height],
                [window.innerWidth-cat3.width, window.innerHeight-cat3.height],
                [cat3.width, window.innerHeight-cat3.height] ];
}

window.onresize = function(event) {
    adjustToWindow();
};

window.onload = function() {
    adjustToWindow();
    //Hide game elements until game starts
    setClassDisplay("game", "none");
    pageLoaded = true;
}<commit_msg>Added counter-clockwise move option to pink cat<commit_after>var frameRate = 50, interval;
var corners, startTime;
var gameActive = false, pageLoaded = false;
var clock, clockHeight = 0, seconds = 0, minutes = 0, hours = 0, t, timeMult = 1;
var standardArea = 1520000, screenFactor = 1;//used to scale up size/speed of game for large displays

//The rat, Brie, follows the mouse pointer
var rat = {
    pos: [],
    speed : 8, //number of pixels rat can move per frame
    maxSpeed: 8,
    id: "ratPic",
    height: 30,
    width: 20,
    goal: [],
    updateGoal : function() {
        this.goal = [window.mouseX+24, window.mouseY - clockHeight+20];//offsets for cheese cursor size
        //adjust rat's speed to prevent overshooting goal
        var dist = distance(this.pos, this.goal);
        if ( dist < 3 ) {
            this.speed = 0;
        } else {
            this.speed = Math.min(this.maxSpeed, dist);
            //rotate the rat image to face the goal (if not too close already)
            var theta = Math.atan2(this.goal[1] - this.pos[1], this.goal[0] - this.pos[0]);
            document.getElementById("ratPic").style.transform = "rotate("+(theta*57.296-90)+"deg)";
        }
    }
};

//Cat1, Willy, goes straight for the rat, but slowly (chaser)
var cat1 = {
    pos: [],
    speed : 4, //pixels per frame
    goal: [],
    id: "cat1",
    img: "cat-orange.png",
    imgNear: "cat-orange-bite.png",
    height: 46,
    width: 50,
    updateGoal : function() {
        this.goal =  rat.pos;
    }
};

//Cat2, Whiskers, goes to random places (wanderer)
var cat2 = {
    pos: [],
    speed : 8, //pixels per frame
    goal: [],
    id: "cat2",
    img: "cat-blue.png",
    imgNear: "cat-blue-bite.png",
    height: 46,
    width: 50,
    updateGoal : function() {
        if( inRange( this.pos, this.goal, this.width) ) {
            this.goal = [Math.round(Math.random()*window.innerWidth),
                         Math.round(Math.random()*window.innerHeight)];
        }
    }
};

//Cat3, Wendy, runs around the edges, and attacks when lined up with the rat (dasher)
var cat3 = {
    pos: [],
    speed : 11, //pixels per frame
    goal: [],
    id:"cat3",
    img: "cat-pink.png",
    imgNear: "cat-pink-bite.png",
    height:46,
    width: 50,
    state: "CW", //toggles clockwise or counter-clockwise edge movement
    setToEdgeState: function(){
        if(this.state=="ATK"){
            if(Math.random() > 0.5)
                this.state = "CW";
            else
                this.state = "CCW";
        }
    },
    isAtTop: function(){return this.pos[1] <= this.height;},
    isAtRight: function(){return this.pos[0] >= window.innerWidth - this.width;},
    isAtBottom: function(){return this.pos[1] >= window.innerHeight - this.height;},
    isAtLeft: function(){return this.pos[0] <= this.width;},
    updateGoal : function() {
        console.log("state="+this.state);
        if( inRange( this.pos, this.goal, this.width) ) {  //pick a corner for new goal
            this.setToEdgeState();
            if(this.state=="CW"){
                if( this.isAtTop() && !this.isAtRight()){//goal = top right
                    this.goal = corners[1];
                } else if(this.isAtLeft()){//goal = top left
                    this.goal = corners[0];
                } else if(this.isAtBottom()){//goal = bottom left
                    this.goal = corners[3];
                } else if(this.isAtRight()) { //goal = bottom right
                    this.goal = corners[2];
                }
            } else if(this.state=="CCW"){
                if( this.isAtTop() && !this.isAtLeft()){//goal = top left
                    this.goal = corners[0];
                } else if(this.isAtRight()){//goal = top right
                    this.goal = corners[1];
                } else if(this.isAtBottom()){//goal = bottom right
                    this.goal = corners[2];
                } else if(this.isAtLeft()) { //goal = bottom left
                    this.goal = corners[3];
                }
            }
        }
        //attack if rat is aligned orthogonally (only when roaming edge)
        if(this.state!="ATK"){
            if (this.isAtLeft() || this.isAtRight() ||
                this.isAtTop() || this.isAtBottom()) {
                if( Math.abs(this.pos[0]-rat.pos[0]) < rat.width ) { //vertical attack
                    if( this.pos[1] <= this.height)
                        this.goal = [this.pos[0], corners[2][1]]; //downward
                    else
                        this.goal = [this.pos[0], corners[0][1]]; //upward
                    this.state = "ATK";
                } else if( Math.abs(this.pos[1]-rat.pos[1]) < rat.height ) { //horizontal attack
                    if( this.pos[0] <= this.width)
                        this.goal = [corners[2][0], this.pos[1]];//rightward
                    else
                        this.goal = [corners[0][0], this.pos[1]];//leftward
                   this.state = "ATK";
                }
            }
        }
    }
};

//Cat4, Bob, is wants to move toward the rat, but avoids other cats (flanker)
var cat4 = {
    pos: [],
    speed : 6, //pixels per frame
    repulse: -60,//repulsive force from other cats
    goal: [],
    id: "cat4",
    img: "cat-yellow.png",
    imgNear: "cat-yellow-bite.png",
    height: 46,
    width: 50,
    updateGoal : function() {
        //add up superposition forces from rat & cats
        //constant attractive force toward rat (doesn't scale with distance)
        var theta = Math.atan2(rat.pos[1] - this.pos[1], rat.pos[0] - this.pos[0]);
        this.goal[0] = this.pos[0] + Math.round( this.speed * Math.cos(theta) );
        this.goal[1] = this.pos[1] + Math.round( this.speed * Math.sin(theta) );
        var distF;
        //add repulsive forces from other cats (large forces that drop with distance factor)
        for (var i=0; i < 3; i++) {
            theta = Math.atan2(cats[i].pos[1] - this.pos[1], cats[i].pos[0] - this.pos[0]);
            distF = Math.pow(distance(this.pos, cats[i].pos),0.56);
            if(distF != 0) {
                this.goal[0] += Math.round( this.repulse * Math.cos(theta) ) / distF;
                this.goal[1] += Math.round( this.repulse * Math.sin(theta) ) / distF;
            }
        }
    }
};

var cats = [cat1, cat2, cat3, cat4];//for looping over the cats
var players = [rat, cat1, cat2, cat3, cat4];//for looping over all players

document.onmousemove = function(e) {
    var event = e || window.event;
    window.mouseX = event.clientX;
    window.mouseY = event.clientY;
}

function setClassDisplay(className, disp) {
    var x = document.getElementsByClassName(className);
    for (var i = 0; i < x.length; i++) {
        x[i].style.display = disp;
    }
}

function distance(p1, p2) {
    var x = p1[0] - p2[0];
    var y = p1[1] - p2[1];
    return Math.sqrt( (x*x) + (y*y) );
}

function inRange(pos1, pos2, dist) {
    return distance(pos1, pos2) <= dist;
}

function moveTowardGoal(mover) {
    var theta = Math.atan2(mover.goal[1] - mover.pos[1], mover.goal[0] - mover.pos[0]);
    mover.pos[0] += Math.round( mover.speed * timeMult * screenFactor * Math.cos(theta) );
    mover.pos[1] += Math.round( mover.speed * timeMult * screenFactor * Math.sin(theta) );
    document.getElementById(mover.id).style.marginLeft = mover.pos[0] - mover.width + "px";
    document.getElementById(mover.id).style.marginTop = mover.pos[1] - mover.height + "px";
}

//Update the game area
function updateGameState() {
    if(window.mouseX == undefined || window.mouseY == undefined || gameActive == false){
        return;
    }

    //each rat/cat gets to update and move
    for(var i=0; i < players.length; i++){
        players[i].updateGoal();
        moveTowardGoal(players[i]);
    }

    //Check lose condition and update cat image if near rat
    for(i=0; i < cats.length; i++){
        if( inRange(rat.pos, cats[i].pos, cats[i].width*1.1))
            endGame();
        else if( inRange(rat.pos, cats[i].pos, cats[i].width*2.5))
            $('#'+cats[i].id).attr("src", cats[i].imgNear);
        else
            $('#'+cats[i].id).attr("src", cats[i].img);
    }
}

function addSec() {
    seconds++;
    if (seconds >= 60) {
        seconds = 0;
        minutes++;
        if (minutes >= 60) {
            minutes = 0;
            hours++;
        }
    }
    clock.textContent = (hours ? (hours > 9 ? hours : "0" + hours) : "00") +
                        ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") +
                        ":" + (seconds > 9 ? seconds : "0" + seconds);
    timer();
}
function timer() {
    t = setTimeout(addSec, 1000/timeMult);
}

function startGame() {
    if(!pageLoaded) {
        return;//the page must finish loading before game can start
    }
    timeMult = Number($('#timeMultiplier').val());
    interval = setInterval(updateGameState, 1000/(frameRate));
    gameActive = true;
    clock = document.getElementById('clock')
    clock.textContent = "00:00:00";
    seconds = 0; minutes = 0; hours = 0;
    timer();
    //reset game pieces
    rat.pos =  [window.innerWidth/2, window.innerHeight/2];
    cat1.pos = [corners[2][0], corners[2][1]];
    cat2.pos = [corners[0][0], corners[0][1]];
    cat2.goal = [corners[0][0], corners[0][1]];
    cat3.pos = [corners[1][0], corners[1][1]];
    cat3.goal = [corners[2][0], corners[2][1]];
    cat4.pos = [corners[3][0], corners[3][1]];
    cat4.goal = [corners[3][0], corners[3][1]];

    setClassDisplay("game", "block");
    setClassDisplay("preGame", "none");
    document.getElementsByTagName("body")[0].style.cursor = "url(cheese.png), auto";
}

function endGame() {
    clearInterval(interval);
    gameActive = false;
    clearTimeout(t);
    //show non-game elements
    setClassDisplay("preGame", "block");
    //hide game elements
    setClassDisplay("game", "none");
    document.getElementsByTagName("body")[0].style.cursor = "default";
}

function adjustToWindow(){
    //Scale size/speed of game elements based on display size.
    //Average of 1 and ratio of expected screen size
    screenFactor = (1+(window.innerHeight * window.innerWidth / standardArea))/2;

    //use loaded elements to get game dimensions
    rat.height = $('#ratPic').height()/2;
    rat.width = $('#ratPic').width()/2;
    cat1.height = cat2.height = cat3.height = $('#cat1').height()/2;
    cat1.width = cat2.width = cat3.width = $('#cat1').width()/2;
    clockHeight = $('#clock').height();
    corners = [ [cat3.width, cat3.height],
                [window.innerWidth-cat3.width, cat3.height],
                [window.innerWidth-cat3.width, window.innerHeight-cat3.height],
                [cat3.width, window.innerHeight-cat3.height] ];
}

window.onresize = function(event) {
    adjustToWindow();
};

window.onload = function() {
    adjustToWindow();
    //Hide game elements until game starts
    setClassDisplay("game", "none");
    pageLoaded = true;
}<|endoftext|>


<commit_before>define(function(require) {
  var Backbone = require('backbone'),
      Handlebars = require('handlebars'),
      $ = require('jquery'),
      d3 = require('d3'),
      _ = require('underscore'),
      Where = require('summary/where'),
      util = require('summary/util'),
      ScorpionResult = require('summary/scorpionresult'),
      ScorpionResultView = require('summary/scorpionresultview'),
      Query = require('summary/query');

  var ScorpionResultsView = Backbone.View.extend({
    template: Handlebars.compile($("#scorpion-results-template").html()),

    initialize: function(attrs) {
      this.state = {
        locked: null,  // null = base results, int = scorpion result views
        where: null,   // global where object
        query: null
      };
      _.extend(this.state, attrs);

      this.listenTo(this.collection, 'add', this.addTo);
      this.listenTo(this.collection, 'reset', this.reset);
      this.listenTo(this.state.query, 'change:db', this.clear);
      this.listenTo(this.state.query, 'change:table', this.clear);

    },

    render: function() {
      this.$el.html(this.template({}));
      this.$list = this.$('.scorpion-results');
      return this;
    },

    setActive: function(model) {
      var where = null,
          clauses = [],
          _this = this;
      if (model != null) {
        where = util.negateClause(model.toSQL());
        clauses = model.get('clauses');
      } else if (model == null) {
        if (this.state.locked != null) {
          where = util.negateClause(this.state.locked.toSQL());
          clauses = this.state.locked.get('clauses');
        } else {
          where = util.negateClause(this.state.where.toSQL());
          clauses = [];
        }
      }

      console.log(['setactive', model, this.state.locked, where]);
      //this.state.query.set('where', where);
      this.state.where.setSelection(clauses);
      this.state.query.attributes.where = where;

      if (where) {
        var query = new Query(this.state.query.toJSON());
        query.set('where', where);
        query.fetch({
          data: query.toJSON(),
          context: this,
          success: function(model, resp, opts) {
            this.trigger('modifiedData', resp.data);
          }
        });
      } else {
        this.trigger('modifiedData', null);
      }

      this.trigger('setActive', model);
    },

    toggleLocked: function(model) {
      if (this.state.locked == model) {
        this.state.locked = null;
      } else {
        this.state.locked = model;
      }
      console.log(['newstate:', this.state.locked])
      this.setActive(model);
    },

    clickResult: function(view) {
      var model = (view)? view.model : null;
      this.$list.find('.filter-clause').removeClass("locked");
      this.toggleLocked(model);
      if (view)
        view.$('.filter-clause')
          .toggleClass("locked", this.state.locked == model);
    },

    unlockAll: function() {
      if (this.state.locked) {
        this.$list.find('.filter-clause').removeClass('locked');
        this.state.locked = null;
        this.trigger('modifiedData', null);
        var selection = this.state.where.get('selection');
        this.state.where.clearScorpionSelections();
      }
    },

    clear: function() {
      this.collection.reset();
    },

    reset: function() {
      this.$list.empty();
      this.collection.each(this.addTo.bind(this));
    },

    addTo: function(model) {
      var _this = this;
      var view = new ScorpionResultView({model:model});
      this.$list.append(view.render().el);
      view.on('selected', function() { _this.setActive(view.model); });
      view.on('unselected', function() { _this.setActive(null); });
      view.on('click', this.clickResult.bind(this));
      return this;
    }
  });

  return ScorpionResultsView;
})
<commit_msg>this -> _this bug<commit_after>define(function(require) {
  var Backbone = require('backbone'),
      Handlebars = require('handlebars'),
      $ = require('jquery'),
      d3 = require('d3'),
      _ = require('underscore'),
      Where = require('summary/where'),
      util = require('summary/util'),
      ScorpionResult = require('summary/scorpionresult'),
      ScorpionResultView = require('summary/scorpionresultview'),
      Query = require('summary/query');

  var ScorpionResultsView = Backbone.View.extend({
    template: Handlebars.compile($("#scorpion-results-template").html()),

    initialize: function(attrs) {
      this.state = {
        locked: null,  // null = base results, int = scorpion result views
        where: null,   // global where object
        query: null
      };
      _.extend(this.state, attrs);

      this.listenTo(this.collection, 'add', this.addTo);
      this.listenTo(this.collection, 'reset', this.reset);
      this.listenTo(this.state.query, 'change:db', this.clear);
      this.listenTo(this.state.query, 'change:table', this.clear);

    },

    render: function() {
      this.$el.html(this.template({}));
      this.$list = this.$('.scorpion-results');
      return this;
    },

    setActive: function(model) {
      var where = null,
          clauses = [],
          _this = this;
      if (model != null) {
        where = util.negateClause(model.toSQL());
        clauses = model.get('clauses');
      } else if (model == null) {
        if (this.state.locked != null) {
          where = util.negateClause(this.state.locked.toSQL());
          clauses = this.state.locked.get('clauses');
        } else {
          where = util.negateClause(this.state.where.toSQL());
          clauses = [];
        }
      }

      console.log(['setactive', model, this.state.locked, where]);
      //this.state.query.set('where', where);
      this.state.where.setSelection(clauses);
      this.state.query.attributes.where = where;

      if (where) {
        var query = new Query(this.state.query.toJSON());
        query.set('where', where);
        query.fetch({
          data: query.toJSON(),
          context: this,
          success: function(model, resp, opts) {
            _this.trigger('modifiedData', resp.data);
          }
        });
      } else {
        this.trigger('modifiedData', null);
      }

      this.trigger('setActive', model);
    },

    toggleLocked: function(model) {
      if (this.state.locked == model) {
        this.state.locked = null;
      } else {
        this.state.locked = model;
      }
      console.log(['newstate:', this.state.locked])
      this.setActive(model);
    },

    clickResult: function(view) {
      var model = (view)? view.model : null;
      this.$list.find('.filter-clause').removeClass("locked");
      this.toggleLocked(model);
      if (view)
        view.$('.filter-clause')
          .toggleClass("locked", this.state.locked == model);
    },

    unlockAll: function() {
      if (this.state.locked) {
        this.$list.find('.filter-clause').removeClass('locked');
        this.state.locked = null;
        this.trigger('modifiedData', null);
        var selection = this.state.where.get('selection');
        this.state.where.clearScorpionSelections();
      }
    },

    clear: function() {
      this.collection.reset();
    },

    reset: function() {
      this.$list.empty();
      this.collection.each(this.addTo.bind(this));
    },

    addTo: function(model) {
      var _this = this;
      var view = new ScorpionResultView({model:model});
      this.$list.append(view.render().el);
      view.on('selected', function() { _this.setActive(view.model); });
      view.on('unselected', function() { _this.setActive(null); });
      view.on('click', this.clickResult.bind(this));
      return this;
    }
  });

  return ScorpionResultsView;
})
<|endoftext|>


<commit_before>/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

(function () {

  var module = angular.module('pnc.project');

  module.controller('ProductImportCtrl', [
    'ProductImportDAO',
    'TreeFactory',
    '$scope',
    '$timeout',
    'Notifications',
    '$state',
    'ProductVersionDAO',
    function (ProductImportDAO, TreeFactory, scope, $timeout, Notifications, $state, ProductVersionDAO) {

      scope.started = false;
      scope.display = 'start';
      scope.$watch('display', function(newval) {
        scope.$root.importProductState = newval;
      });
      var data = {}; // data loaded from analyzer endpoints
      scope.startData = {};
      scope.startSubmitDisabled = false;
      scope.finishSubmitDisabled = false;
      scope.bcData = {}; // data for the left-side form
      var tree = TreeFactory.build();
      scope.tree = tree;
      scope.validateFormCaller = {call: _.noop()};

      /**
       * Given node, return string label to use in the tree.
       */
      var getNodeText = function (node) {
        return node.nodeData.gav.groupId + ':' +
          node.nodeData.gav.artifactId + ':' +
          node.nodeData.gav.version + (nodeIsValid(node) ? '' : '');
      };

      var getNodeGavString = function (node) {
        return node.nodeData.gav.groupId + ':' +
          node.nodeData.gav.artifactId + ':' +
          node.nodeData.gav.version;
      };

      var nodeIsValid = function (node) {
        if (!_(node).has('valid')) {
          node.valid = true;
        }
        return node.valid;
      };

      /**
       * Handle clicking on a BC in the tree.
       */
      var nodeSelect = function (node) {
        $timeout(function () {
          scope.bcData = node;
        });
      };

      /**
       * Handle toggling a checkbox in the tree.
       * Also check the parent boxes.
       */
      var nodeToggle = function (node) {
        $timeout(function () {
          if (_.isUndefined(node.state)) {
            node.state = {};
          }
          node.state.checked = node.state.checked !== true;
          if (node.state.checked) {
            var n = node.getParent();
            while (n !== null) {
              if (_.isUndefined(n.state)) {
                n.state = {};
              }
              n.state.checked = true;
              n = n.getParent();
            }
          } else {
            var recursiveUncheck = function (n) {
              if (_.isUndefined(n.state)) {
                n.state = {};
              }
              n.state.checked = false;
              _(n.nodes).each(function (e) {
                recursiveUncheck(e);
              });
            };
            recursiveUncheck(node);
          }
          tree._refresh();
        });
      };

      /**
       * Handle clicking on the arrow for expanding/collapsing a subtree.
       */
      var nodeExpand = function (node) {
        $timeout(function () {
          if (_.isUndefined(node.state)) {
            node.state = {};
          }
          node.state.expanded = node.state.expanded !== true;
          tree._refresh();
        });
      };

      var isStrNonEmpty = function (str) {
        return _.isString(str) && str.length > 0;
      };

      var isValidURL = function (url) {
        var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@\-\/]))?$/;
        return URL_REGEXP.test(url);
      };

      var nodeValidate = function (node) {
        node.valid = isStrNonEmpty(node.nodeData.name) &&
          (!isStrNonEmpty(node.nodeData.scmUrl) || isValidURL(node.nodeData.scmUrl)) &&
          (node.nodeData.environmentId !== null) &&
          (node.nodeData.projectId !== null);
        return node.valid;
      };

      /**
       * Stick the above handlers on each tree node
       * when it is being parsed from received data.
       */
      var processNode = function (node) {
        node.select = _.partial(nodeSelect, node);
        node.text = getNodeText(node);
        node.gavString = getNodeGavString(node);
        node.toggle = _.partial(nodeToggle, node);
        node.analyze = _.partial(analyzeNextLevel, node);
        node.expand = _.partial(nodeExpand, node);
        node.validate = _.partial(nodeValidate, node);
      };

      /**
       * Given a tree and the JSON data structure from the analyzer REST endpoint,
       * parse the structure to add nodes on the tree as needed.
       * @return true on success
       */
      var parseData = function (tree, data) {
        /**
         * Check if the node contains child representing the given dependency,
         * so there are no duplicates in the tree.
         */
        var find = function (node, dependency) {
          return _(node.nodes).find(function (e) {
            return _.isEqual(e.nodeData.gav, dependency.gav);
          });
        };

        var recursiveParse = function (node, dataNode) {
          var subNode = find(node, dataNode);
          if (_.isUndefined(subNode)) {
            var subNodeData = _.omit(dataNode, 'dependencies');
            subNode = node.append(subNodeData);
            processNode(subNode);
          }
          if (_.isArray(dataNode.dependencies)) {
            var res = true;
            _(dataNode.dependencies).each(function (dependency) {
              res = recursiveParse(subNode, dependency) && res;
            });
            return res;
          } else {
            return false;
          }
        };
        return recursiveParse(tree, data.topLevelBc);
      };

      /**
       * Parse the tree to get the required JSON data structure,
       * basically the reverse of {@link parseData}.
       * @param tree
       * @param update function that allows to use this function in a more general way.
       * Is called for each node parsed and returns 'BC object' for that node, which is the included
       * in the resulting JSON data.
       */
      var parseTree0 = function (tree, update) {
        var res = _.chain(data).clone().omit('scmUrl', 'scmRevision', 'topLevelBc').value();
        res.bcSetName = scope.bcSetName;
        var recursiveParse = function (node) {
          var n = update(node);
          n.dependencies = _(node.nodes).map(function (e) {
            return recursiveParse(e);
          });
          return n;
        };

        res.topLevelBc = recursiveParse(tree.nodes[0]);
        return res;
      };

      /**
       * Parse tree for analyzing next level.
       */
      var parseTree = function (tree) {
        return parseTree0(tree, function (node) {
          node.nodeData.cloneRepo = false;
          return _.clone(node.nodeData);
        });
      };

      /**
       * Parse tree for finishing process.
       * Takes checkboxes into account.
       */
      var parseTreeFinish = function (tree) {
        return parseTree0(tree, function (node) {
          node.nodeData.cloneRepo = false;
          var n = _.clone(node.nodeData);
          n.selected = !_.isUndefined(node.state) && node.state.checked;
          return n;
        });
      };

      var validateTree = function (tree) {
        var recursiveParse = function (node) {
          var valid = true;
          node.selected = !_.isUndefined(node.state) && node.state.checked;
          //var isValid = node.validate();
          if (node.selected && !node.nodeData.useExistingBc) {
            valid = node.validate();//isValid;
          }
          if (_(node).has('nodes')) {
            _(node.nodes).each(function (n) {
              valid = recursiveParse(n) && valid;
            });
          }
          node.text = getNodeText(node);
          return valid;
        };
        return recursiveParse(tree.nodes[0]);
      };

      scope.startProcess = function () {
        scope.startSubmitDisabled = true;
        Notifications.info('Preparing analysis. This may take a minute, please be patient.');
        ProductImportDAO.startProcess(scope.startData).then(function (r) {
          scope.startSubmitDisabled = true;
          if (_(r).has('name')) {
            data = r;
            scope.productName = data.name;
            scope.bcSetName = data.bcSetName;
            parseData(tree, data);
            tree.nodes[0].nlaSuccessful = true;
            tree.nodes[0].select();
            scope.display = 'bc';
            tree._refresh();
          } else {
            Notifications.error('Something went wrong. Make sure that you entered correct data.');
          }
        });
      };

      var analyzeNextLevel = function (node) {
        node.nlaSuccessful = true;
        tree.nodes[0].select();
        node.select();
        node.nodeData.selected = true;
        data = parseTree(tree);
        Notifications.info('Analyzing \'' + node.gavString + '\'. This may take a minute, please be patient.');
        ProductImportDAO.analyzeNextLevel(data).then(function (r) {
          if (_(r).has('name')) {
            data = r;
            if (parseData(tree, data)) {
              node.nlaSuccessful = true;
              tree.nodes[0].select();
              node.select();
              node.expand();
              Notifications.success('Successfully analyzed ' + (_.isUndefined(node.nodes) ? 0 : node.nodes.length) + ' dependencies for \'' + node.gavString + '\'.');
            } else {
              Notifications.warn('Could not find dependencies of \'' + node.gavString + '\' in a repository.');
            }
          } else {
            node.nlaSuccessful = false;
            tree.nodes[0].select();
            node.select();
            Notifications.error('Could not analyze \'' + node.gavString + '\'. Check that the information in the form is correct.');
          }
        });
      };

      var goToProductVersion = function(id) { // TODO unnecessary rest call
        ProductVersionDAO.get({versionId:id}).$promise.then(function(r) {
          $state.go('product.detail.version', {productId: r.productId,versionId: r.id});
        });
      };

      scope.finishProcess = function () {
        if(_.isUndefined(tree.nodes[0].state) || tree.nodes[0].state.checked !== true) {
          Notifications.warn('You have to select at least one BC.');
          return;
        }
        data = parseTreeFinish(tree);
        if (validateTree(tree)) {
          scope.finishSubmitDisabled = true;
          Notifications.info('Product is being imported. This may take a minute, please be patient.');
          ProductImportDAO.finishProcess(data).then(function (r) {
            if(r.success) {
              Notifications.success('Product import completed!');
              goToProductVersion(r.productVersionId);
            } else {
              Notifications.error('Product import failed. ' + r.message);
            }
            scope.finishSubmitDisabled = false;
          });
        } else {
          tree._refresh();
          Notifications.warn('Some data are invalid or missing. Verify  all checked BCs.');
        }
      };

      scope.reset = function () {
        data = {};
        tree.clear();
        scope.display = 'start';
      };
    }
  ]);

})
();
<commit_msg>NCL-1344 Remove reset warning after successful import.<commit_after>/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
'use strict';

(function () {

  var module = angular.module('pnc.project');

  module.controller('ProductImportCtrl', [
    'ProductImportDAO',
    'TreeFactory',
    '$scope',
    '$timeout',
    'Notifications',
    '$state',
    'ProductVersionDAO',
    function (ProductImportDAO, TreeFactory, scope, $timeout, Notifications, $state, ProductVersionDAO) {

      scope.started = false;
      scope.display = 'start';
      scope.$watch('display', function(newval) {
        scope.$root.importProductState = newval;
      });
      var data = {}; // data loaded from analyzer endpoints
      scope.startData = {};
      scope.startSubmitDisabled = false;
      scope.finishSubmitDisabled = false;
      scope.bcData = {}; // data for the left-side form
      var tree = TreeFactory.build();
      scope.tree = tree;
      scope.validateFormCaller = {call: _.noop()};

      /**
       * Given node, return string label to use in the tree.
       */
      var getNodeText = function (node) {
        return node.nodeData.gav.groupId + ':' +
          node.nodeData.gav.artifactId + ':' +
          node.nodeData.gav.version + (nodeIsValid(node) ? '' : '');
      };

      var getNodeGavString = function (node) {
        return node.nodeData.gav.groupId + ':' +
          node.nodeData.gav.artifactId + ':' +
          node.nodeData.gav.version;
      };

      var nodeIsValid = function (node) {
        if (!_(node).has('valid')) {
          node.valid = true;
        }
        return node.valid;
      };

      /**
       * Handle clicking on a BC in the tree.
       */
      var nodeSelect = function (node) {
        $timeout(function () {
          scope.bcData = node;
        });
      };

      /**
       * Handle toggling a checkbox in the tree.
       * Also check the parent boxes.
       */
      var nodeToggle = function (node) {
        $timeout(function () {
          if (_.isUndefined(node.state)) {
            node.state = {};
          }
          node.state.checked = node.state.checked !== true;
          if (node.state.checked) {
            var n = node.getParent();
            while (n !== null) {
              if (_.isUndefined(n.state)) {
                n.state = {};
              }
              n.state.checked = true;
              n = n.getParent();
            }
          } else {
            var recursiveUncheck = function (n) {
              if (_.isUndefined(n.state)) {
                n.state = {};
              }
              n.state.checked = false;
              _(n.nodes).each(function (e) {
                recursiveUncheck(e);
              });
            };
            recursiveUncheck(node);
          }
          tree._refresh();
        });
      };

      /**
       * Handle clicking on the arrow for expanding/collapsing a subtree.
       */
      var nodeExpand = function (node) {
        $timeout(function () {
          if (_.isUndefined(node.state)) {
            node.state = {};
          }
          node.state.expanded = node.state.expanded !== true;
          tree._refresh();
        });
      };

      var isStrNonEmpty = function (str) {
        return _.isString(str) && str.length > 0;
      };

      var isValidURL = function (url) {
        var URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@\-\/]))?$/;
        return URL_REGEXP.test(url);
      };

      var nodeValidate = function (node) {
        node.valid = isStrNonEmpty(node.nodeData.name) &&
          (!isStrNonEmpty(node.nodeData.scmUrl) || isValidURL(node.nodeData.scmUrl)) &&
          (node.nodeData.environmentId !== null) &&
          (node.nodeData.projectId !== null);
        return node.valid;
      };

      /**
       * Stick the above handlers on each tree node
       * when it is being parsed from received data.
       */
      var processNode = function (node) {
        node.select = _.partial(nodeSelect, node);
        node.text = getNodeText(node);
        node.gavString = getNodeGavString(node);
        node.toggle = _.partial(nodeToggle, node);
        node.analyze = _.partial(analyzeNextLevel, node);
        node.expand = _.partial(nodeExpand, node);
        node.validate = _.partial(nodeValidate, node);
      };

      /**
       * Given a tree and the JSON data structure from the analyzer REST endpoint,
       * parse the structure to add nodes on the tree as needed.
       * @return true on success
       */
      var parseData = function (tree, data) {
        /**
         * Check if the node contains child representing the given dependency,
         * so there are no duplicates in the tree.
         */
        var find = function (node, dependency) {
          return _(node.nodes).find(function (e) {
            return _.isEqual(e.nodeData.gav, dependency.gav);
          });
        };

        var recursiveParse = function (node, dataNode) {
          var subNode = find(node, dataNode);
          if (_.isUndefined(subNode)) {
            var subNodeData = _.omit(dataNode, 'dependencies');
            subNode = node.append(subNodeData);
            processNode(subNode);
          }
          if (_.isArray(dataNode.dependencies)) {
            var res = true;
            _(dataNode.dependencies).each(function (dependency) {
              res = recursiveParse(subNode, dependency) && res;
            });
            return res;
          } else {
            return false;
          }
        };
        return recursiveParse(tree, data.topLevelBc);
      };

      /**
       * Parse the tree to get the required JSON data structure,
       * basically the reverse of {@link parseData}.
       * @param tree
       * @param update function that allows to use this function in a more general way.
       * Is called for each node parsed and returns 'BC object' for that node, which is the included
       * in the resulting JSON data.
       */
      var parseTree0 = function (tree, update) {
        var res = _.chain(data).clone().omit('scmUrl', 'scmRevision', 'topLevelBc').value();
        res.bcSetName = scope.bcSetName;
        var recursiveParse = function (node) {
          var n = update(node);
          n.dependencies = _(node.nodes).map(function (e) {
            return recursiveParse(e);
          });
          return n;
        };

        res.topLevelBc = recursiveParse(tree.nodes[0]);
        return res;
      };

      /**
       * Parse tree for analyzing next level.
       */
      var parseTree = function (tree) {
        return parseTree0(tree, function (node) {
          node.nodeData.cloneRepo = false;
          return _.clone(node.nodeData);
        });
      };

      /**
       * Parse tree for finishing process.
       * Takes checkboxes into account.
       */
      var parseTreeFinish = function (tree) {
        return parseTree0(tree, function (node) {
          node.nodeData.cloneRepo = false;
          var n = _.clone(node.nodeData);
          n.selected = !_.isUndefined(node.state) && node.state.checked;
          return n;
        });
      };

      var validateTree = function (tree) {
        var recursiveParse = function (node) {
          var valid = true;
          node.selected = !_.isUndefined(node.state) && node.state.checked;
          //var isValid = node.validate();
          if (node.selected && !node.nodeData.useExistingBc) {
            valid = node.validate();//isValid;
          }
          if (_(node).has('nodes')) {
            _(node.nodes).each(function (n) {
              valid = recursiveParse(n) && valid;
            });
          }
          node.text = getNodeText(node);
          return valid;
        };
        return recursiveParse(tree.nodes[0]);
      };

      scope.startProcess = function () {
        scope.startSubmitDisabled = true;
        Notifications.info('Preparing analysis. This may take a minute, please be patient.');
        ProductImportDAO.startProcess(scope.startData).then(function (r) {
          scope.startSubmitDisabled = true;
          if (_(r).has('name')) {
            data = r;
            scope.productName = data.name;
            scope.bcSetName = data.bcSetName;
            parseData(tree, data);
            tree.nodes[0].nlaSuccessful = true;
            tree.nodes[0].select();
            scope.display = 'bc';
            tree._refresh();
          } else {
            Notifications.error('Something went wrong. Make sure that you entered correct data.');
          }
        });
      };

      var analyzeNextLevel = function (node) {
        node.nlaSuccessful = true;
        tree.nodes[0].select();
        node.select();
        node.nodeData.selected = true;
        data = parseTree(tree);
        Notifications.info('Analyzing \'' + node.gavString + '\'. This may take a minute, please be patient.');
        ProductImportDAO.analyzeNextLevel(data).then(function (r) {
          if (_(r).has('name')) {
            data = r;
            if (parseData(tree, data)) {
              node.nlaSuccessful = true;
              tree.nodes[0].select();
              node.select();
              node.expand();
              Notifications.success('Successfully analyzed ' + (_.isUndefined(node.nodes) ? 0 : node.nodes.length) + ' dependencies for \'' + node.gavString + '\'.');
            } else {
              Notifications.warn('Could not find dependencies of \'' + node.gavString + '\' in a repository.');
            }
          } else {
            node.nlaSuccessful = false;
            tree.nodes[0].select();
            node.select();
            Notifications.error('Could not analyze \'' + node.gavString + '\'. Check that the information in the form is correct.');
          }
        });
      };

      var goToProductVersion = function(id) { // TODO unnecessary rest call
        ProductVersionDAO.get({versionId:id}).$promise.then(function(r) {
          $state.go('product.detail.version', {productId: r.productId,versionId: r.id});
        });
      };

      scope.finishProcess = function () {
        if(_.isUndefined(tree.nodes[0].state) || tree.nodes[0].state.checked !== true) {
          Notifications.warn('You have to select at least one BC.');
          return;
        }
        data = parseTreeFinish(tree);
        if (validateTree(tree)) {
          scope.finishSubmitDisabled = true;
          Notifications.info('Product is being imported. This may take a minute, please be patient.');
          ProductImportDAO.finishProcess(data).then(function (r) {
            if(r.success) {
              Notifications.success('Product import completed!');
              scope.display = 'start';
              goToProductVersion(r.productVersionId);
            } else {
              Notifications.error('Product import failed. ' + r.message);
            }
            scope.finishSubmitDisabled = false;
          });
        } else {
          tree._refresh();
          Notifications.warn('Some data are invalid or missing. Verify  all checked BCs.');
        }
      };

      scope.reset = function () {
        data = {};
        tree.clear();
        scope.display = 'start';
      };
    }
  ]);

})
();
<|endoftext|>


<commit_before>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	Schema = mongoose.Schema;

/**
 * Typecast Schema
 */
var TypecastSchema = new Schema({
	name: {
		type: String,
		default: '',
		required: 'Please fill Typecast name',
		trim: true,
		unique: true
	},
	created: {
		type: Date,
		default: Date.now
	},
	user: {
		type: Schema.ObjectId,
		ref: 'User'
	}
});

mongoose.model('Typecast', TypecastSchema);<commit_msg>Typecast dup checker<commit_after>'use strict';

/**
 * Module dependencies.
 */
var mongoose = require('mongoose'),
	Schema = mongoose.Schema;

/**
 * Typecast Schema
 */
var TypecastSchema = new Schema({
	name: {
		type: String,
		default: '',
		required: 'Please fill Typecast name',
		trim: true,
		unique: true,
		dropDups: true
	},
	created: {
		type: Date,
		default: Date.now
	},
	user: {
		type: Schema.ObjectId,
		ref: 'User'
	}
});

mongoose.model('Typecast', TypecastSchema);<|endoftext|>


<commit_before>var Builds = function () {

    function runs(project, branch, build, buildValidationStamp) {
        var html = '';
        $.each(buildValidationStamp.runs, function (index, run) {
            html += '
'.format(run.status);
            html += ' {5}'
                .format(
                    project.html(),
                    branch.html(),
                    build.html(),
                    buildValidationStamp.name.html(),
                    run.runOrder,
                    run.status.html());
            html += ' {0}'.format(run.statusDescription.html());
            html += '
';
        });
        return html;
    }

    function generateTableBuildRows (project, branch, branchBuilds) {
        var html = '';
        $.each (branchBuilds.builds, function (index, buildCompleteStatus) {
            html += '
';
                html += '';
                    html += '{2}'.format(project.html(),branch.html(),buildCompleteStatus.name.html());
                html += '	';
                $.each(branchBuilds.validationStamps, function (index, validationStamp) {
                    var buildValidationStamp = buildCompleteStatus.validationStamps[validationStamp.name];
                    html += '';
                    if (buildValidationStamp) {
                        if (buildValidationStamp.run) {
                            html += runs(project, branch, buildCompleteStatus.name, buildValidationStamp);
                        } else {
                            html += '{0}'.format(loc('validationRun.notRun'));
                        }
                    } else {
                        html += '-';
                    }
                    html += '	';
                });
            html += '
';
        });
        return html;
    }

    function generateTableBranchBuilds (project, branch, branchBuilds) {
        var html = '

';
        // Header
        html += '
';
            html += '{0}	'.format(loc('model.build'));
            html += '{0}	'.format(loc('branch.validation_stamps'), branchBuilds.validationStamps.length);
        html += '
';
        html += '
';
        $.each(branchBuilds.validationStamps, function (index, validationStamp) {
            html += '';
            html += ''.format(project.html(), branch.html(), validationStamp.name.html());
            html += ValidationStamps.validationStampImage(project, branch, validationStamp);
            html += '';
            html += '	';
        });
        html += '
';
        // Items
        html += '

';
        html += generateTableBuildRows(project, branch, branchBuilds);
        // End
        html += '

';
        return html;
    }

	function buildTemplate (project, branch) {
	    return Template.config({
	        url: 'ui/manage/build/{0}/{1}?u=1'.format(project, branch),
	        more: true,
	        refresh: true,
	        dataLength: function (branchBuilds) {
	            return branchBuilds.builds.length;
	        },
	        render: function (containerId, append, config, branchBuilds) {
                var containerSelector = '#' + containerId;
                if (append === true && $(containerSelector).has("tbody").length) {
                    $(containerSelector + " tbody").append(generateTableBuildRows(project, branch, branchBuilds));
                } else {
                    // No table defined, or no need to append
                    // Some items
                    if (branchBuilds.builds.length > 0) {
                        // Direct filling of the container
                        $(containerSelector).empty();
                        $(containerSelector).append(generateTableBranchBuilds(project, branch, branchBuilds));
                    }
                    // No items
                    else {
                        $(containerSelector).empty();
                        $(containerSelector).append('
{0}
'.format(loc('branch.nobuild')));
                    }
                }
	        }
         });
	}

	function buildValidationStampTemplate (project, branch, build) {
	    return Template.config({
	        url: 'ui/manage/build/{0}/{1}/{2}/validationStamps'.format(project, branch, build),
	        refresh: true,
	        render: Template.asTable(function (stamp) {
                var pClass;
                if (!stamp.run) {
                    pClass = 'validation-stamp-norun';
                }
                var html = '
'.format(pClass);
                html += ValidationStamps.validationStampImage(project, branch, stamp);
                html += ' {2}'.format(project.html(), branch.html(), stamp.name.html());
                if (stamp.run) {
                    html += runs(project, branch, build, stamp);
                }
                html += '
';
                return html;
	        })
	    });
	}

	function buildPromotionLevelsTemplate (project, branch, build) {
        return Template.config({
            url: 'ui/manage/build/{0}/{1}/{2}/promotionLevels'.format(project, branch, build),
            refresh: true,
            render: Template.fill(function (data, append) {
                var html = '';
                var count = data.length;
                if (count == 0) {
                    html += '{0}'.format(loc('build.promotion_levels.none'));
                } else {
                    for (var i = 0 ; i < count ; i++) {
                        // Promotion
                        var promotion = data[i];
                        // Separator
                        if (i > 0) {
                            html += '  ';
                        }
                        // Image of the promotion level
                        html += ''.format(
                            project.html(),
                            branch.html(),
                            promotion.name
                        );
                        // Link to the promotion level
                        html += ' {2}'.format(
                            project.html(),
                            branch.html(),
                            promotion.name
                        );
                    }
                }
                return html;
            })
        });
	}

	return {
		buildTemplate: buildTemplate,
		buildValidationStampTemplate: buildValidationStampTemplate,
		buildPromotionLevelsTemplate: buildPromotionLevelsTemplate
	};

} ();<commit_msg>Promotion levels: for a branch<commit_after>var Builds = function () {

    function runs(project, branch, build, buildValidationStamp) {
        var html = '';
        $.each(buildValidationStamp.runs, function (index, run) {
            html += '
'.format(run.status);
            html += ' {5}'
                .format(
                    project.html(),
                    branch.html(),
                    build.html(),
                    buildValidationStamp.name.html(),
                    run.runOrder,
                    run.status.html());
            html += ' {0}'.format(run.statusDescription.html());
            html += '
';
        });
        return html;
    }

    function generateTableBuildRows (project, branch, branchBuilds) {
        var html = '';
        $.each (branchBuilds.builds, function (index, buildCompleteStatus) {
            html += '
';
                html += '';
                    html += '{2}'.format(project.html(),branch.html(),buildCompleteStatus.name.html());
                html += '	';
                    html += generateBuildPromotionLevels(project,branch)(buildCompleteStatus.promotionLevels);
                html += '	';
                $.each(branchBuilds.validationStamps, function (index, validationStamp) {
                    var buildValidationStamp = buildCompleteStatus.validationStamps[validationStamp.name];
                    html += '';
                    if (buildValidationStamp) {
                        if (buildValidationStamp.run) {
                            html += runs(project, branch, buildCompleteStatus.name, buildValidationStamp);
                        } else {
                            html += '{0}'.format(loc('validationRun.notRun'));
                        }
                    } else {
                        html += '-';
                    }
                    html += '	';
                });
            html += '
';
        });
        return html;
    }

    function generateTableBranchBuilds (project, branch, branchBuilds) {
        var html = '

';
        // Header
        html += '
';
            html += '{0}	'.format(loc('model.build'));
            html += '{0}	'.format(loc('branch.promotion_levels'));
            html += '{0}	'.format(loc('branch.validation_stamps'), branchBuilds.validationStamps.length);
        html += '
';
        html += '
';
        $.each(branchBuilds.validationStamps, function (index, validationStamp) {
            html += '';
            html += ''.format(project.html(), branch.html(), validationStamp.name.html());
            html += ValidationStamps.validationStampImage(project, branch, validationStamp);
            html += '';
            html += '	';
        });
        html += '
';
        // Items
        html += '

';
        html += generateTableBuildRows(project, branch, branchBuilds);
        // End
        html += '

';
        return html;
    }

	function buildTemplate (project, branch) {
	    return Template.config({
	        url: 'ui/manage/build/{0}/{1}?u=1'.format(project, branch),
	        more: true,
	        refresh: true,
	        dataLength: function (branchBuilds) {
	            return branchBuilds.builds.length;
	        },
	        render: function (containerId, append, config, branchBuilds) {
                var containerSelector = '#' + containerId;
                if (append === true && $(containerSelector).has("tbody").length) {
                    $(containerSelector + " tbody").append(generateTableBuildRows(project, branch, branchBuilds));
                } else {
                    // No table defined, or no need to append
                    // Some items
                    if (branchBuilds.builds.length > 0) {
                        // Direct filling of the container
                        $(containerSelector).empty();
                        $(containerSelector).append(generateTableBranchBuilds(project, branch, branchBuilds));
                    }
                    // No items
                    else {
                        $(containerSelector).empty();
                        $(containerSelector).append('
{0}
'.format(loc('branch.nobuild')));
                    }
                }
	        }
         });
	}

	function buildValidationStampTemplate (project, branch, build) {
	    return Template.config({
	        url: 'ui/manage/build/{0}/{1}/{2}/validationStamps'.format(project, branch, build),
	        refresh: true,
	        render: Template.asTable(function (stamp) {
                var pClass;
                if (!stamp.run) {
                    pClass = 'validation-stamp-norun';
                }
                var html = '
'.format(pClass);
                html += ValidationStamps.validationStampImage(project, branch, stamp);
                html += ' {2}'.format(project.html(), branch.html(), stamp.name.html());
                if (stamp.run) {
                    html += runs(project, branch, build, stamp);
                }
                html += '
';
                return html;
	        })
	    });
	}

	function generateBuildPromotionLevels (project, branch) {
	    return function (promotionLevels) {
            var html = '';
            var count = promotionLevels.length;
            if (count == 0) {
                html += '{0}'.format(loc('build.promotion_levels.none'));
            } else {
                for (var i = 0 ; i < count ; i++) {
                    // Promotion
                    var promotion = promotionLevels[i];
                    // Separator
                    if (i > 0) {
                        html += '  ';
                    }
                    // Image of the promotion level
                    html += ''.format(
                        project.html(),
                        branch.html(),
                        promotion.name
                    );
                    // Link to the promotion level
                    html += ' {2}'.format(
                        project.html(),
                        branch.html(),
                        promotion.name
                    );
                }
            }
            return html;
        };
	}

	function buildPromotionLevelsTemplate (project, branch, build) {
        return Template.config({
            url: 'ui/manage/build/{0}/{1}/{2}/promotionLevels'.format(project, branch, build),
            refresh: true,
            render: Template.fill(generateBuildPromotionLevels(project,branch))
        });
	}

	return {
		buildTemplate: buildTemplate,
		buildValidationStampTemplate: buildValidationStampTemplate,
		buildPromotionLevelsTemplate: buildPromotionLevelsTemplate
	};

} ();<|endoftext|>


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

  angular.module('ToDo')
  .controller('ToDoController',ToDoController);

  ToDoController.$inject = ['firebaseService'];
  function ToDoController(firebaseService){
    var vm = this;
    /*====================== Delegation Variables =========================== */
    vm.addItem = addItem;
    vm.addItemButton = addItemButton;
    vm.editItem = editItem;
    vm.editModeButton = editModeButton;
    vm.exitEditMode = exitEditMode;
    vm.saveButton = saveButton;
    vm.signInButton = signInButton;
    vm.signOutButton = signOutButton;
    vm.signUpButton = signUpButton;
    vm.removeItem = removeItem;
    /*====================== public Variables =============================== */
    vm.displayList = [{value:" "},{value:" "}];
    vm.inputData = "";
    vm.list = [{value:" "},{value:" "}];
    //vm.logedIn = false;
    vm.profileMode = "signIn";
    vm.userEmail = "";//<!> should be moved to profile controler add encryption
    vm.userPassword = ""///<!> should be moved to profile controler add encryption
    vm.pageSize = 25;
    /*====================== private Variables ============================== */
    /*====================== Services ======================================= */
    var fbSvc = firebaseService;
    /*====================== Public Methods ================================= */
    function addItem(index,item){
        vm.list.splice(index,0,item);
        vm.inputData = "";
        addItemToDisplayList(index,item);
    }
    function addItemButton($event){
        if($event.code === 'Enter'){
          var item = {value:vm.inputData, editMode: false};
          addItem(vm.list.length,item)
        }
    }
    function editItem(index, content){
      vm.list[index].value = content;
      vm.displayList[index].value = content;
    }
    function editModeButton($index){
      if(vm.displayList[$index].editMode){
        console.log(vm.list[$index].value);
        editItem($index,vm.displayList[$index].value);
        console.log(vm.list[$index].value);
      }
      vm.displayList[$index].editMode = !vm.displayList[$index].editMode;
    }
    function exitEditMode($event,$index){
      if($event.code === 'Enter'){
        editModeButton($index);
      }
    }
    function removeItem(index){
      vm.list.splice(index,1);
      clearDisplay();
      loadList();
    }
    function saveButton(){
      //set up save list
      //to get rid of angular hash key and keys used only client side
      var list_ = []
      for(let i =0, l =vm.list.length; i < l; i++){
        list_.push({value:vm.list[i].value});
      }
      saveList(list_)
    }
    function signInButton(){

    }
    function signOutButton(){

    }
    function signUpButton(){
      fbSvc.signInUser("rwp140@gmail.com","tempPassword")
    }
    function saveList(_list){
      fbSvc.writeData("testUser","lists/","testList",_list);
    }
    /*====================== Private Methods ================================ */
    function addItemToDisplayList(index, item){//clunky way of getting around my lack of html finise ;)
      vm.displayList[index] = item;
    }
    function clearDisplay(){
      vm.displayList = createEmptyList(vm.pageSize);
    }
    function createEmptyList(_size){
      //create empty list at variable size!
      var list_ = [];//out going list
      for(let i =0, l = _size; i<l; i++){
        list_.push({value:" ",empty:true, editMode: false});
      }
      return list_
    }
    function init(){
      vm.displayList = createEmptyList(vm.pageSize);
      vm.list = [];
    }
    function loadList(){
      for(let i=0,l=vm.list.length;i<l;i++){
        addItemToDisplayList(i,vm.list[i]);
      }
    }
    /*====================== Actions ======================================== */
    init();
  }
})();
<commit_msg>fixed missing line ending<commit_after>(function(){
  'use strict'

  angular.module('ToDo')
  .controller('ToDoController',ToDoController);

  ToDoController.$inject = ['firebaseService'];
  function ToDoController(firebaseService){
    var vm = this;
    /*====================== Delegation Variables =========================== */
    vm.addItem = addItem;
    vm.addItemButton = addItemButton;
    vm.editItem = editItem;
    vm.editModeButton = editModeButton;
    vm.exitEditMode = exitEditMode;
    vm.saveButton = saveButton;
    vm.signInButton = signInButton;
    vm.signOutButton = signOutButton;
    vm.signUpButton = signUpButton;
    vm.removeItem = removeItem;
    /*====================== public Variables =============================== */
    vm.displayList = [{value:" "},{value:" "}];
    vm.inputData = "";
    vm.list = [{value:" "},{value:" "}];
    //vm.logedIn = false;
    vm.profileMode = "signIn";
    vm.userEmail = "";//<!> should be moved to profile controler add encryption
    vm.userPassword = ""///<!> should be moved to profile controler add encryption
    vm.pageSize = 25;
    /*====================== private Variables ============================== */
    /*====================== Services ======================================= */
    var fbSvc = firebaseService;
    /*====================== Public Methods ================================= */
    function addItem(index,item){
        vm.list.splice(index,0,item);
        vm.inputData = "";
        addItemToDisplayList(index,item);
    }
    function addItemButton($event){
        if($event.code === 'Enter'){
          var item = {value:vm.inputData, editMode: false};
          addItem(vm.list.length,item)
        }
    }
    function editItem(index, content){
      vm.list[index].value = content;
      vm.displayList[index].value = content;
    }
    function editModeButton($index){
      if(vm.displayList[$index].editMode){
        console.log(vm.list[$index].value);
        editItem($index,vm.displayList[$index].value);
        console.log(vm.list[$index].value);
      }
      vm.displayList[$index].editMode = !vm.displayList[$index].editMode;
    }
    function exitEditMode($event,$index){
      if($event.code === 'Enter'){
        editModeButton($index);
      }
    }
    function removeItem(index){
      vm.list.splice(index,1);
      clearDisplay();
      loadList();
    }
    function saveButton(){
      //set up save list
      //to get rid of angular hash key and keys used only client side
      var list_ = []
      for(let i =0, l =vm.list.length; i < l; i++){
        list_.push({value:vm.list[i].value});
      }
      saveList(list_);
    }
    function signInButton(){

    }
    function signOutButton(){

    }
    function signUpButton(){
      fbSvc.signInUser("rwp140@gmail.com","tempPassword")
    }
    function saveList(_list){
      fbSvc.writeData("testUser","lists/","testList",_list);
    }
    /*====================== Private Methods ================================ */
    function addItemToDisplayList(index, item){//clunky way of getting around my lack of html finise ;)
      vm.displayList[index] = item;
    }
    function clearDisplay(){
      vm.displayList = createEmptyList(vm.pageSize);
    }
    function createEmptyList(_size){
      //create empty list at variable size!
      var list_ = [];//out going list
      for(let i =0, l = _size; i<l; i++){
        list_.push({value:" ",empty:true, editMode: false});
      }
      return list_
    }
    function init(){
      vm.displayList = createEmptyList(vm.pageSize);
      vm.list = [];
    }
    function loadList(){
      for(let i=0,l=vm.list.length;i<l;i++){
        addItemToDisplayList(i,vm.list[i]);
      }
    }
    /*====================== Actions ======================================== */
    init();
  }
})();
<|endoftext|>