<commit_before>define([
    "require"
], function(
    require
) {
    var deck = [
        'gwc_add_card_slot',
        'gwc_bld_efficiency_cdr',
        'gwc_bld_efficiency_fabs',
        'gwc_cost_air',
        'gwc_cost_artillery',
        'gwc_cost_bots',
        'gwc_cost_defenses',
        'gwc_cost_economy',
        //'gwc_cost_intel',
        'gwc_cost_orbital',
        'gwc_cost_sea',
        'gwc_cost_super_weapons',
        'gwc_cost_vehicles',
        'gwc_damage_air',
        'gwc_damage_artillery',
        'gwc_damage_bots',
        'gwc_damage_commander',
        'gwc_damage_defenses',
        'gwc_damage_orbital',
        'gwc_damage_sea',
        'gwc_damage_vehicles',
        'gwc_enable_air_t1',
        //'gwc_enable_air_t2',
        'gwc_enable_artillery',
        'gwc_enable_bots_t1',
        //'gwc_enable_bots_t2',
        'gwc_enable_defenses_t2',
        //'gwc_enable_orbital_t1',
        //'gwc_enable_orbital_t2',
        //'gwc_enable_sea_t1',
        //'gwc_enable_sea_t2',
        'gwc_enable_super_weapons',
        'gwc_enable_vehicles_t1',
        //'gwc_enable_vehicles_t2',
        //'gwc_energy_efficiency_intel',
        //'gwc_energy_efficiency_weapons',
        'gwc_health_air',
        'gwc_health_bots',
        'gwc_health_commander',
        'gwc_health_orbital',
        'gwc_health_sea',
        'gwc_health_structures',
        'gwc_health_vehicles',
        'gwc_speed_air',
        'gwc_speed_bots',
        'gwc_speed_commander',
        'gwc_speed_orbital',
        'gwc_speed_sea',
        'gwc_speed_vehicles',
        'gwc_storage_1',
        'gwc_storage_and_buff',
        'gwc_minion',
        'gwc_combat_structures',
        'gwc_combat_vehicles',
        'gwc_combat_sea',
        'gwc_combat_air',
        'gwc_combat_commander',
        'gwc_combat_bots',
        'gwc_combat_orbital',
        'gwc_enable_air_all',
        'gwc_enable_bots_all',
        'gwc_enable_vehicles_all',
        'gwc_enable_orbital_all',
        'gwc_enable_sea_all',
        'gwc_enable_titans',
        'gwc_cost_titans'
    ];

    var aiDeck = [
        'gwc_add_card_slot',
        'gwc_combat_structures',
        'gwc_combat_vehicles',
        'gwc_combat_sea',
        'gwc_combat_air',
        'gwc_combat_commander',
        'gwc_combat_bots',
        'gwc_combat_orbital',
        'gwc_enable_air_all',
        'gwc_enable_bots_all',
        'gwc_enable_artillery',
        'gwc_enable_defenses_t2',
        'gwc_enable_orbital_all',
        'gwc_enable_sea_all',
        'gwc_enable_super_weapons',
        'gwc_enable_vehicles_all',
        'gwc_bld_efficiency_cdr',
        'gwc_bld_efficiency_fabs',
        'gwc_storage_1',
        'gwc_storage_and_buff',
        'gwc_minion',
    ];

    var extraDeck = [
        'gwc_start_vehicle',
        'gwc_start_air',
        'gwc_start_bot',
        'gwc_start_orbital',
        'gwc_start_artillery',
        'gwc_start_subcdr',
        'gwc_start_combatcdr',
        'gwc_start_allfactory',
    ];

    var cards = [];
    var aiCards = [];
    var extraCards = {};
    var cardContexts = {};

    var loadCount = deck.length + aiDeck.length + extraDeck.length;
    var loaded = $.Deferred();

    var saveDeck = deck;
    deck = [];
    _.forEach(saveDeck, function (cardId) {
        //api.debug.log('ADDING CARD: '+cardId);
        require(['cards/' + cardId], function (card) {
            card.id = cardId;
            cards.push(card);
            deck.push(cardId);
            if (--loadCount === 0)
                loaded.resolve();
        });
    })

    var saveAIDeck = aiDeck;
    aiDeck = [];
    _.forEach(saveAIDeck, function(cardId) {
        require(['cards/' + cardId], function(card) {
            card.id = cardId;
            aiCards.push(card);
            aiDeck.push(cardId);
            if (--loadCount === 0)
                loaded.resolve();
        });
    })

    _.forEach(extraDeck, function(cardId) {
        require(['cards/' + cardId], function(card) {
            card.id = cardId;
            extraCards[cardId] = card;
            if (--loadCount === 0)
                loaded.resolve();
        });
    })

    var allCards = [];
    var allDeck = [];
    loaded.then(function() {
        allCards = cards.concat(aiCards).concat(_.values(extraCards));
        allDeck = deck.concat(aiDeck).concat(extraDeck);
    });

    return {
        deal: function (params) {
            var galaxy = params.galaxy;
            var inventory = params.inventory;
            var ready = params.ready;
            var rng = params.rng || new Math.seedrandom();

            var result = $.Deferred();

            var run = function() {
                //api.debug.log("DEALER");
                var remainingAICards = aiCards.slice(0);
                var remainingAIDeck = aiDeck.slice(0);

                _.forEach(allCards, function(card) {
                    if (card.getContext && !cardContexts[card.id])
                        cardContexts[card.id] = card.getContext(galaxy, inventory);
                });

                var CARDS_PER_NORMAL_SYSTEM = 3;
                var CARDS_PER_LOADOUT_SYSTEM = 1;
                var first_pass = true;

                var loadout_systems = {};

                var dealCardToEachSystem = function () {

                    _.forEach(galaxy.stars(), function (system, systemIndex) {

                        var systemCards = [];
                        var systemDeck = [];
                        var fullHand = [];
                        var hand = [];
                        var resultIndex = undefined;
                        var predealtCard = false;

                        if (first_pass && !_.isEmpty(system.cardList())) {

                            var preCard = system.cardList()[0];
                            if (!_.isString(preCard))
                                return; // If the system already has a card, consider it dealt

                            loadout_systems[system.name()] = true;
                            predealtCard = true;

                            var extra = extraCards[preCard];
                            if (extra && extra.getContext && !cardContexts[preCard])
                                cardContexts[preCard] = extra.getContext(galaxy, inventory);
                            var context = cardContexts[preCard];
                            var deal = extra && extra.deal(system, context);
                            if (deal && _.isObject(deal)) {
                                systemCards = [extra];
                                systemDeck = [preCard];

                                fullHand = [deal];
                                hand = fullHand;
                                resultIndex = 0;
                            }
                        }

                        if (!hand.length)
                        {
                            var aiSystem = (system.ai() && !!remainingAICards.length);
                            var bossSystem = aiSystem && system.ai().boss;
                            systemCards = bossSystem ? remainingAICards : cards;
                            systemDeck = bossSystem ? remainingAIDeck : deck;

                            fullHand = _.map(systemCards, function(card, cardIndex) {
                                var context = cardContexts[card.id];
                                var match = _.any(system.cardList(), function (element) {
                                    return element.id === card.id;
                                });

                                var result = card.deal && card.deal(system, context, inventory);
                                if (match)
                                    result.chance = 0;

                                return result;
                            });
                            hand = _.map(fullHand, function(deal, index) {
                                if (!_.isObject(deal))
                                    return;
                                deal.index = index;
                                return deal;
                            });
                            hand = _.filter(hand, 'chance');
                        }

                        if (hand.length) {
                            if (resultIndex === undefined) {
                                var probability = _.reduce(hand, function(sum, card) {
                                    return sum + card.chance;
                                }, 0);
                                var roll = rng() * probability;
                                var index = 0;
                                for(; roll >= hand[index].chance && index < hand.length; ++index) {
                                    roll -= hand[index].chance;
                                }
                                if (index < hand.length) {
                                    var result = hand[index];
                                    resultIndex = result.index;
                                }
                            }
                            if (resultIndex !== undefined) {
                                var resultDeal = fullHand[resultIndex];
                                var params = resultDeal && resultDeal.params;
                                var cardId = systemDeck[resultIndex];
                                var systemCard = {
                                    id: cardId
                                };

                                if (params && _.isObject(params))
                                    _.extend(systemCard, params);

                                if (predealtCard)
                                    system.cardList([]);

                                var boss = loadout_systems[system.name()];
                                var done = boss
                                        ? system.cardList().length === CARDS_PER_LOADOUT_SYSTEM
                                        : system.cardList().length === CARDS_PER_NORMAL_SYSTEM;

                                if (!done)
                                    system.cardList().push(systemCard);
                            }
                        }

                        _.forEach(fullHand, function(params, index) {
                            var card = systemCards[index];
                            var cardId = systemDeck[index];
                            var context = cardContexts[cardId];
                            if (index === resultIndex) {
                                //api.debug.log("Keep: " + cardId);
                                card.keep && card.keep(params, context);
                            }
                            else {
                                card.discard && card.discard(params, context);
                            }
                        });

                        // Remove AI cards from the deck
                        if (system.ai()) {
                            remainingAICards.splice(index, 1);
                            remainingAIDeck.splice(index, 1);
                        }
                    });

                    first_pass = false;
                };

                _.times(CARDS_PER_NORMAL_SYSTEM, dealCardToEachSystem);

                _.forEach(allCards, function(card, index) {
                    var cardId = allDeck[index];
                    var context = cardContexts[cardId];
                    card.releaseContext && card.releaseContext(context);
                    if (context)
                        delete cardContexts[cardId];
                });

                if (ready)
                    ready();
                result.resolve();
            };

            loaded.then(run);
            return result.promise();
        },

        // Do everything necessary to deal a single card
        // params: (example)
        //      {
        //          id: 'gwc_minion',
        //          galaxy: game.galaxy(),
        //          inventory: game.inventory(),
        //          star: game.galaxy().stars()[0]
        //      }
        dealCard: function (params) {
            var result = $.Deferred();
            loaded.then(function() {
                var allCards = cards.concat(aiCards).concat(_.values(extraCards));
                var card = _.find(allCards, { id: params.id });

                // Simulate a deal
                var context = card.getContext && card.getContext(params.galaxy, params.inventory);

                var deal = (card.deal && card.deal(params.star, context));
                var product = { id: params.id };
                var cardParams = deal && deal.params;
                if (cardParams && _.isObject(cardParams))
                    _.extend(product, cardParams);
                card.keep && card.keep(deal, context);
                card.releaseContext && card.releaseContext(context);

                result.resolve(product, deal);

            });
            return result;
        },

        dealBossCards: function (params /* galaxy inventory */) {
            var inventory = params.inventory;
            var galaxy = params.galaxy;
            var result = $.Deferred();

            loaded.then(function () {
                var allCards = cards.concat(aiCards).concat(_.values(extraCards));
                _.forEach(galaxy.stars(), function (star) {
                    _.forEach(star.cardList(), function (id, cardIndex) {
                        var card = _.find(allCards, { id: id });
                        // Simulate a deal
                        var context = card.getContext && card.getContext(params.galaxy, params.inventory);

                        var deal = (card.deal && card.deal(params.star, context));
                        var product = { id: id };
                        var cardParams = deal && deal.params;
                        if (cardParams && _.isObject(cardParams))
                            _.extend(product, cardParams);
                        card.keep && card.keep(deal, context);
                        card.releaseContext && card.releaseContext(context);

                        star.cardList()[cardIndex] = product;
                    });
                });

                result.resolve({});
            });

            return result;
        },

        chooseCards: function (params) {
            var inventory = params.inventory;
            var ready = params.ready;
            var rng = params.rng || new Math.seedrandom();
            var count = params.count;
            var star = params.star;
            var galaxy = params.galaxy;

            var start = _.now();

            var result = $.Deferred();
            loaded.then(function () {

                _.forEach(allCards, function (card) {
                    if (card.getContext && !cardContexts[card.id])
                        cardContexts[card.id] = card.getContext(galaxy, inventory);
                });

                var list = [];

                _.times(count, function () {

                    var fullHand = [];
                    var hand = [];

                    fullHand = _.map(cards, function (card, cardIndex) {
                        var context = cardContexts[card.id];

                        var match = inventory.hasCard(card.id) || _.any(list, function (element) {
                            return element.id === card.id;
                        });

                        var result = card.deal && card.deal(star, context, inventory);
                        if (match)
                            result.chance = 0;

                        return result;
                    });

                    fullHand = _.map(fullHand, function (deal, index) {
                        deal.index = index;
                        return deal;
                    });

                    hand = _.filter(fullHand, function (deal) {
                        if (!deal)
                            return false;

                        if (!deal.chance)
                            return false;

                        return true;
                    });

                    if (hand.length) {
                        var resultIndex;

                        var probability = _.reduce(hand, function (sum, card) {
                            return sum + card.chance;
                        }, 0);
                        var roll = rng() * probability;
                        var index = 0;
                        for (; roll >= hand[index].chance && index < hand.length; ++index) {
                            roll -= hand[index].chance;
                        }
                        if (index < hand.length) {
                            var result = hand[index];
                            resultIndex = result.index;
                        }

                        if (resultIndex !== undefined) {
                            var resultDeal = fullHand[resultIndex];
                            var params = resultDeal && resultDeal.params;
                            var cardId = deck[resultIndex];
                            var systemCard = {
                                id: cardId
                            };

                            if (params && _.isObject(params))
                                _.extend(systemCard, params);

                            list.push(systemCard);
                        }
                    }

                });

                result.resolve(list);
            });
            return result;
        },

        allCards: function() {
            var result = $.Deferred();
            loaded.then(function() {
                var allCards = cards.concat(aiCards).concat(_.values(extraCards));
                result.resolve(allCards);
            });
            return result;
        }
    };
});
<commit_msg>add methods to edit GW card pools<commit_after>define([
    "require"
], function(
    require
) {
    var deck = [
        'gwc_add_card_slot',
        'gwc_bld_efficiency_cdr',
        'gwc_bld_efficiency_fabs',
        'gwc_cost_air',
        'gwc_cost_artillery',
        'gwc_cost_bots',
        'gwc_cost_defenses',
        'gwc_cost_economy',
        //'gwc_cost_intel',
        'gwc_cost_orbital',
        'gwc_cost_sea',
        'gwc_cost_super_weapons',
        'gwc_cost_vehicles',
        'gwc_damage_air',
        'gwc_damage_artillery',
        'gwc_damage_bots',
        'gwc_damage_commander',
        'gwc_damage_defenses',
        'gwc_damage_orbital',
        'gwc_damage_sea',
        'gwc_damage_vehicles',
        'gwc_enable_air_t1',
        //'gwc_enable_air_t2',
        'gwc_enable_artillery',
        'gwc_enable_bots_t1',
        //'gwc_enable_bots_t2',
        'gwc_enable_defenses_t2',
        //'gwc_enable_orbital_t1',
        //'gwc_enable_orbital_t2',
        //'gwc_enable_sea_t1',
        //'gwc_enable_sea_t2',
        'gwc_enable_super_weapons',
        'gwc_enable_vehicles_t1',
        //'gwc_enable_vehicles_t2',
        //'gwc_energy_efficiency_intel',
        //'gwc_energy_efficiency_weapons',
        'gwc_health_air',
        'gwc_health_bots',
        'gwc_health_commander',
        'gwc_health_orbital',
        'gwc_health_sea',
        'gwc_health_structures',
        'gwc_health_vehicles',
        'gwc_speed_air',
        'gwc_speed_bots',
        'gwc_speed_commander',
        'gwc_speed_orbital',
        'gwc_speed_sea',
        'gwc_speed_vehicles',
        'gwc_storage_1',
        'gwc_storage_and_buff',
        'gwc_minion',
        'gwc_combat_structures',
        'gwc_combat_vehicles',
        'gwc_combat_sea',
        'gwc_combat_air',
        'gwc_combat_commander',
        'gwc_combat_bots',
        'gwc_combat_orbital',
        'gwc_enable_air_all',
        'gwc_enable_bots_all',
        'gwc_enable_vehicles_all',
        'gwc_enable_orbital_all',
        'gwc_enable_sea_all',
        'gwc_enable_titans',
        'gwc_cost_titans'
    ];

    var aiDeck = [
        'gwc_add_card_slot',
        'gwc_combat_structures',
        'gwc_combat_vehicles',
        'gwc_combat_sea',
        'gwc_combat_air',
        'gwc_combat_commander',
        'gwc_combat_bots',
        'gwc_combat_orbital',
        'gwc_enable_air_all',
        'gwc_enable_bots_all',
        'gwc_enable_artillery',
        'gwc_enable_defenses_t2',
        'gwc_enable_orbital_all',
        'gwc_enable_sea_all',
        'gwc_enable_super_weapons',
        'gwc_enable_vehicles_all',
        'gwc_bld_efficiency_cdr',
        'gwc_bld_efficiency_fabs',
        'gwc_storage_1',
        'gwc_storage_and_buff',
        'gwc_minion',
    ];

    var extraDeck = [
        'gwc_start_vehicle',
        'gwc_start_air',
        'gwc_start_bot',
        'gwc_start_orbital',
        'gwc_start_artillery',
        'gwc_start_subcdr',
        'gwc_start_combatcdr',
        'gwc_start_allfactory',
    ];

    var cards = [];
    var aiCards = [];
    var extraCards = {};
    var cardContexts = {};

    var loadCount = deck.length + aiDeck.length + extraDeck.length;
    var loaded = $.Deferred();

    var saveDeck = deck;
    deck = [];
    _.forEach(saveDeck, function (cardId) {
        //api.debug.log('ADDING CARD: '+cardId);
        require(['cards/' + cardId], function (card) {
            card.id = cardId;
            cards.push(card);
            deck.push(cardId);
            if (--loadCount === 0)
                loaded.resolve();
        });
    })

    var saveAIDeck = aiDeck;
    aiDeck = [];
    _.forEach(saveAIDeck, function(cardId) {
        require(['cards/' + cardId], function(card) {
            card.id = cardId;
            aiCards.push(card);
            aiDeck.push(cardId);
            if (--loadCount === 0)
                loaded.resolve();
        });
    })

    _.forEach(extraDeck, function(cardId) {
        require(['cards/' + cardId], function(card) {
            card.id = cardId;
            extraCards[cardId] = card;
            if (--loadCount === 0)
                loaded.resolve();
        });
    })

    var allCards = [];
    var allDeck = [];
    loaded.then(function() {
        allCards = cards.concat(aiCards).concat(_.values(extraCards));
        allDeck = deck.concat(aiDeck).concat(extraDeck);
    });

    return {
        deal: function (params) {
            var galaxy = params.galaxy;
            var inventory = params.inventory;
            var ready = params.ready;
            var rng = params.rng || new Math.seedrandom();

            var result = $.Deferred();

            var run = function() {
                //api.debug.log("DEALER");
                var remainingAICards = aiCards.slice(0);
                var remainingAIDeck = aiDeck.slice(0);

                _.forEach(allCards, function(card) {
                    if (card.getContext && !cardContexts[card.id])
                        cardContexts[card.id] = card.getContext(galaxy, inventory);
                });

                var CARDS_PER_NORMAL_SYSTEM = 3;
                var CARDS_PER_LOADOUT_SYSTEM = 1;
                var first_pass = true;

                var loadout_systems = {};

                var dealCardToEachSystem = function () {

                    _.forEach(galaxy.stars(), function (system, systemIndex) {

                        var systemCards = [];
                        var systemDeck = [];
                        var fullHand = [];
                        var hand = [];
                        var resultIndex = undefined;
                        var predealtCard = false;

                        if (first_pass && !_.isEmpty(system.cardList())) {

                            var preCard = system.cardList()[0];
                            if (!_.isString(preCard))
                                return; // If the system already has a card, consider it dealt

                            loadout_systems[system.name()] = true;
                            predealtCard = true;

                            var extra = extraCards[preCard];
                            if (extra && extra.getContext && !cardContexts[preCard])
                                cardContexts[preCard] = extra.getContext(galaxy, inventory);
                            var context = cardContexts[preCard];
                            var deal = extra && extra.deal(system, context);
                            if (deal && _.isObject(deal)) {
                                systemCards = [extra];
                                systemDeck = [preCard];

                                fullHand = [deal];
                                hand = fullHand;
                                resultIndex = 0;
                            }
                        }

                        if (!hand.length)
                        {
                            var aiSystem = (system.ai() && !!remainingAICards.length);
                            var bossSystem = aiSystem && system.ai().boss;
                            systemCards = bossSystem ? remainingAICards : cards;
                            systemDeck = bossSystem ? remainingAIDeck : deck;

                            fullHand = _.map(systemCards, function(card, cardIndex) {
                                var context = cardContexts[card.id];
                                var match = _.any(system.cardList(), function (element) {
                                    return element.id === card.id;
                                });

                                var result = card.deal && card.deal(system, context, inventory);
                                if (match)
                                    result.chance = 0;

                                return result;
                            });
                            hand = _.map(fullHand, function(deal, index) {
                                if (!_.isObject(deal))
                                    return;
                                deal.index = index;
                                return deal;
                            });
                            hand = _.filter(hand, 'chance');
                        }

                        if (hand.length) {
                            if (resultIndex === undefined) {
                                var probability = _.reduce(hand, function(sum, card) {
                                    return sum + card.chance;
                                }, 0);
                                var roll = rng() * probability;
                                var index = 0;
                                for(; roll >= hand[index].chance && index < hand.length; ++index) {
                                    roll -= hand[index].chance;
                                }
                                if (index < hand.length) {
                                    var result = hand[index];
                                    resultIndex = result.index;
                                }
                            }
                            if (resultIndex !== undefined) {
                                var resultDeal = fullHand[resultIndex];
                                var params = resultDeal && resultDeal.params;
                                var cardId = systemDeck[resultIndex];
                                var systemCard = {
                                    id: cardId
                                };

                                if (params && _.isObject(params))
                                    _.extend(systemCard, params);

                                if (predealtCard)
                                    system.cardList([]);

                                var boss = loadout_systems[system.name()];
                                var done = boss
                                        ? system.cardList().length === CARDS_PER_LOADOUT_SYSTEM
                                        : system.cardList().length === CARDS_PER_NORMAL_SYSTEM;

                                if (!done)
                                    system.cardList().push(systemCard);
                            }
                        }

                        _.forEach(fullHand, function(params, index) {
                            var card = systemCards[index];
                            var cardId = systemDeck[index];
                            var context = cardContexts[cardId];
                            if (index === resultIndex) {
                                //api.debug.log("Keep: " + cardId);
                                card.keep && card.keep(params, context);
                            }
                            else {
                                card.discard && card.discard(params, context);
                            }
                        });

                        // Remove AI cards from the deck
                        if (system.ai()) {
                            remainingAICards.splice(index, 1);
                            remainingAIDeck.splice(index, 1);
                        }
                    });

                    first_pass = false;
                };

                _.times(CARDS_PER_NORMAL_SYSTEM, dealCardToEachSystem);

                _.forEach(allCards, function(card, index) {
                    var cardId = allDeck[index];
                    var context = cardContexts[cardId];
                    card.releaseContext && card.releaseContext(context);
                    if (context)
                        delete cardContexts[cardId];
                });

                if (ready)
                    ready();
                result.resolve();
            };

            loaded.then(run);
            return result.promise();
        },

        // Do everything necessary to deal a single card
        // params: (example)
        //      {
        //          id: 'gwc_minion',
        //          galaxy: game.galaxy(),
        //          inventory: game.inventory(),
        //          star: game.galaxy().stars()[0]
        //      }
        dealCard: function (params) {
            var result = $.Deferred();
            loaded.then(function() {
                var allCards = cards.concat(aiCards).concat(_.values(extraCards));
                var card = _.find(allCards, { id: params.id });

                // Simulate a deal
                var context = card.getContext && card.getContext(params.galaxy, params.inventory);

                var deal = (card.deal && card.deal(params.star, context));
                var product = { id: params.id };
                var cardParams = deal && deal.params;
                if (cardParams && _.isObject(cardParams))
                    _.extend(product, cardParams);
                card.keep && card.keep(deal, context);
                card.releaseContext && card.releaseContext(context);

                result.resolve(product, deal);

            });
            return result;
        },

        dealBossCards: function (params /* galaxy inventory */) {
            var inventory = params.inventory;
            var galaxy = params.galaxy;
            var result = $.Deferred();

            loaded.then(function () {
                var allCards = cards.concat(aiCards).concat(_.values(extraCards));
                _.forEach(galaxy.stars(), function (star) {
                    _.forEach(star.cardList(), function (id, cardIndex) {
                        var card = _.find(allCards, { id: id });
                        // Simulate a deal
                        var context = card.getContext && card.getContext(params.galaxy, params.inventory);

                        var deal = (card.deal && card.deal(params.star, context));
                        var product = { id: id };
                        var cardParams = deal && deal.params;
                        if (cardParams && _.isObject(cardParams))
                            _.extend(product, cardParams);
                        card.keep && card.keep(deal, context);
                        card.releaseContext && card.releaseContext(context);

                        star.cardList()[cardIndex] = product;
                    });
                });

                result.resolve({});
            });

            return result;
        },

        chooseCards: function (params) {
            var inventory = params.inventory;
            var ready = params.ready;
            var rng = params.rng || new Math.seedrandom();
            var count = params.count;
            var star = params.star;
            var galaxy = params.galaxy;

            var start = _.now();

            var result = $.Deferred();
            loaded.then(function () {

                _.forEach(allCards, function (card) {
                    if (card.getContext && !cardContexts[card.id])
                        cardContexts[card.id] = card.getContext(galaxy, inventory);
                });

                var list = [];

                _.times(count, function () {

                    var fullHand = [];
                    var hand = [];

                    fullHand = _.map(cards, function (card, cardIndex) {
                        var context = cardContexts[card.id];

                        var match = inventory.hasCard(card.id) || _.any(list, function (element) {
                            return element.id === card.id;
                        });

                        var result = card.deal && card.deal(star, context, inventory);
                        if (match)
                            result.chance = 0;

                        return result;
                    });

                    fullHand = _.map(fullHand, function (deal, index) {
                        deal.index = index;
                        return deal;
                    });

                    hand = _.filter(fullHand, function (deal) {
                        if (!deal)
                            return false;

                        if (!deal.chance)
                            return false;

                        return true;
                    });

                    if (hand.length) {
                        var resultIndex;

                        var probability = _.reduce(hand, function (sum, card) {
                            return sum + card.chance;
                        }, 0);
                        var roll = rng() * probability;
                        var index = 0;
                        for (; roll >= hand[index].chance && index < hand.length; ++index) {
                            roll -= hand[index].chance;
                        }
                        if (index < hand.length) {
                            var result = hand[index];
                            resultIndex = result.index;
                        }

                        if (resultIndex !== undefined) {
                            var resultDeal = fullHand[resultIndex];
                            var params = resultDeal && resultDeal.params;
                            var cardId = deck[resultIndex];
                            var systemCard = {
                                id: cardId
                            };

                            if (params && _.isObject(params))
                                _.extend(systemCard, params);

                            list.push(systemCard);
                        }
                    }

                });

                result.resolve(list);
            });
            return result;
        },

        allCards: function() {
            var result = $.Deferred();
            loaded.then(function() {
                var allCards = cards.concat(aiCards).concat(_.values(extraCards));
                result.resolve(allCards);
            });
            return result;
        },
        addCards: function(ids) {
          var myLoad = $.Deferred();
          var count = ids.length;
          _.forEach(ids, function (cardId) {
              //api.debug.log('ADDING CARD: '+cardId);
              require(['cards/' + cardId], function (card) {
                  card.id = cardId;
                  cards.push(card);
                  deck.push(cardId);
                  if (--count === 0)
                      myLoad.resolve();
              });
          })
          return $.when(loaded, myLoad).then(function() {
            allCards = cards.concat(aiCards).concat(_.values(extraCards));
            allDeck = deck.concat(aiDeck).concat(extraDeck);
          })
        },
        removeCards: function(ids) {
          deck = _.difference(deck, ids);
          cards = cards.filter(function(card) {
            return ids.indexOf(card.id) == -1
          })
          return loaded.then(function() {
            allCards = cards.concat(aiCards).concat(_.values(extraCards));
            allDeck = deck.concat(aiDeck).concat(extraDeck);
          })
        },
        addAiCards: function(ids) {
          var myLoad = $.Deferred();
          var count = ids.length;
          _.forEach(ids, function (cardId) {
              //api.debug.log('ADDING CARD: '+cardId);
              require(['cards/' + cardId], function (card) {
                  card.id = cardId;
                  aiCards.push(card);
                  aiDeck.push(cardId);
                  if (--count === 0)
                      myLoad.resolve();
              });
          })
          return $.when(loaded, myLoad).then(function() {
            allCards = cards.concat(aiCards).concat(_.values(extraCards));
            allDeck = deck.concat(aiDeck).concat(extraDeck);
          })
        },
        removeAiCards: function(ids) {
          aiDeck = _.difference(aiDeck, ids);
          aiCards = aiCards.filter(function(card) {
            return ids.indexOf(card.id) == -1
          })
          return loaded.then(function() {
            allCards = cards.concat(aiCards).concat(_.values(extraCards));
            allDeck = deck.concat(aiDeck).concat(extraDeck);
          })
        },
        addStartCards: function(ids) {
          var myLoad = $.Deferred();
          var count = ids.length;
          _.forEach(ids, function(cardId) {
              require(['cards/' + cardId], function(card) {
                  card.id = cardId;
                  extraCards[cardId] = card;
                  extraDeck.push(cardId);
                  if (--count === 0)
                      myLoad.resolve();
              })
          })
          return $.when(loaded, myLoad).then(function() {
            allCards = cards.concat(aiCards).concat(_.values(extraCards));
            allDeck = deck.concat(aiDeck).concat(extraDeck);
          })
        },
        // note that factions will need to be updated to not name removed cards
        removeStartCards: function(ids) {
          extraDeck = _.difference(extraDeck, ids);
          ids.forEach(function(cardId) {
            delete extraCards[cardId];
          })
          return loaded.then(function() {
            allCards = cards.concat(aiCards).concat(_.values(extraCards));
            allDeck = deck.concat(aiDeck).concat(extraDeck);
          })
        },
    };
});
<|endoftext|>


<commit_before>import ZoneId from '../../../../../resources/zone_id';
import NetRegexes from '../../../../../resources/netregexes';
import Conditions from '../../../../../resources/conditions';
import { Responses } from '../../../../../resources/responses';

const sharedOutputStrings = {
  teleportEast: {
    en: 'Teleport to east platform',
    de: 'Teleport zur östlichen plattform',
  },
  teleportWest: {
    en: 'Teleport to west platform',
    de: 'Teleport zur westlichen plattform',
  },
};

export default {
  zoneId: ZoneId.TheCloudDeck,
  timelineFile: 'diamond_weapon.txt',
  triggers: [
    {
      id: 'Diamond Diamond Rain',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FA7', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FA7', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FA7', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FA7', capture: false }),
      condition: Conditions.caresAboutAOE(),
      response: Responses.aoe(),
    },
    {
      id: 'Diamond Claw Swipe East',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5F9A', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5F9A', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5F9A', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5F9A', capture: false }),
      durationSeconds: 10,
      alertText: (data, _, output) => output.teleportWest(),
      outputStrings: sharedOutputStrings,
    },
    {
      id: 'Diamond Claw Swipe West',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5F9B', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5F9B', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5F9B', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5F9B', capture: false }),
      durationSeconds: 10,
      alertText: (data, _, output) => output.teleportEast(),
      outputStrings: sharedOutputStrings,
    },
    {
      id: 'Diamond Photon Burst',
      netRegex: NetRegexes.headMarker({ id: '0057' }),
      condition: Conditions.targetIsYou(),
      alertText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Flare on YOU',
          de: 'Flare auf DIR',
          fr: 'Brasier sur VOUS',
          ja: '自分にフレア',
          cn: '核爆点名',
          ko: '플레어 대상자',
        },
      },
    },
    {
      // There is no head marker for this mechanic, instead Unknown_5779 creates the indicator
      id: 'Diamond Diamond Flash',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '5779' }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '5779' }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '5779' }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '5779' }),
      durationSeconds: 5,
      response: Responses.stackMarkerOn(),
    },
    {
      id: 'Diamond Auri Cyclone',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FE6', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FE6', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FE6', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FE6', capture: false }),
      delaySeconds: 0.5,
      durationSeconds: 6,
      response: Responses.knockback(),
    },
    {
      id: 'Diamond Airship\'s Bane',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FE8', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FE8', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FE8', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FE8', capture: false }),
      durationSeconds: 5,
      alertText: (data, _, output) => output.teleportEast(),
      outputStrings: sharedOutputStrings,
    },
    {
      id: 'Diamond Outrage',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FD7', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FD7', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FD7', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FD7', capture: false }),
      condition: Conditions.caresAboutAOE(),
      response: Responses.aoe(),
    },
    {
      id: 'Diamond Auri Doomstead',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FD8' }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FD8' }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FD8' }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FD8' }),
      response: Responses.tankBuster(),
    },
    {
      id: 'Diamond Vertical Cleave',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FE5', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FE5', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FE5', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FE5', capture: false }),
      durationSeconds: 5,
      response: Responses.knockback(),
    },
    {
      id: 'Diamond Diamond Shrapnel',
      netRegex: NetRegexes.headMarker({ id: '00C5' }),
      condition: Conditions.targetIsYou(),
      durationSeconds: 7,
      alertText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Diamond Shrapnel on YOU',
          de: 'Diamantschub auf DIR',
        },
      },
    },
    {
      id: 'Diamond Articulated Bits',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '5FA9', capture: false }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '5FA9', capture: false }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '5FA9', capture: false }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '5FA9', capture: false }),
      infoText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Avoid Bits',
          de: 'Weiche den Satelliten aus',
        },
      },
    },
    {
      id: 'Diamond Adamant Sphere',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '6144', capture: false }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '6144', capture: false }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '6144', capture: false }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '6144', capture: false }),
      durationSeconds: 8,
      infoText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Get Towers',
          de: 'Türme nehmen',
          fr: 'Prenez les tours',
          ja: '塔を踏む',
          cn: '踩塔',
          ko: '장판 하나씩 들어가기',
        },
      },
    },
    {
      // Diamond Weapon starts using this Adamant Purge ~10 seconds before the head markers
      id: 'Diamond Homing Laser',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '5F9C', capture: false }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '5F9C', capture: false }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '5F9C', capture: false }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '5F9C', capture: false }),
      delaySeconds: 3,
      durationSeconds: 7,
      response: Responses.spread(),
    },
  ],
  timelineReplace: [
    {
      'locale': 'de',
      'missingTranslations': true,
      'replaceSync': {
        'The Diamond Weapon': 'Diamant-Waffe',
      },
    },
    {
      'locale': 'fr',
      'missingTranslations': true,
      'replaceSync': {
        'The Diamond Weapon': 'Arme Diamant',
      },
    },
    {
      'locale': 'ja',
      'missingTranslations': true,
      'replaceSync': {
        'The Diamond Weapon': 'ダイヤウェポン',
      },
    },
  ],
};
<commit_msg>raidboss: diamond weapon fr (#2742)<commit_after>import ZoneId from '../../../../../resources/zone_id';
import NetRegexes from '../../../../../resources/netregexes';
import Conditions from '../../../../../resources/conditions';
import { Responses } from '../../../../../resources/responses';

const sharedOutputStrings = {
  teleportEast: {
    en: 'Teleport to east platform',
    de: 'Teleport zur östlichen plattform',
    fr: 'Téléportez-vous vers la plateforme est',
  },
  teleportWest: {
    en: 'Teleport to west platform',
    de: 'Teleport zur westlichen plattform',
    fr: 'Téléportez-vous vers la plateforme ouest',
  },
};

export default {
  zoneId: ZoneId.TheCloudDeck,
  timelineFile: 'diamond_weapon.txt',
  triggers: [
    {
      id: 'Diamond Diamond Rain',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FA7', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FA7', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FA7', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FA7', capture: false }),
      condition: Conditions.caresAboutAOE(),
      response: Responses.aoe(),
    },
    {
      id: 'Diamond Claw Swipe East',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5F9A', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5F9A', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5F9A', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5F9A', capture: false }),
      durationSeconds: 10,
      alertText: (data, _, output) => output.teleportWest(),
      outputStrings: sharedOutputStrings,
    },
    {
      id: 'Diamond Claw Swipe West',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5F9B', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5F9B', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5F9B', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5F9B', capture: false }),
      durationSeconds: 10,
      alertText: (data, _, output) => output.teleportEast(),
      outputStrings: sharedOutputStrings,
    },
    {
      id: 'Diamond Photon Burst',
      netRegex: NetRegexes.headMarker({ id: '0057' }),
      condition: Conditions.targetIsYou(),
      alertText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Flare on YOU',
          de: 'Flare auf DIR',
          fr: 'Brasier sur VOUS',
          ja: '自分にフレア',
          cn: '核爆点名',
          ko: '플레어 대상자',
        },
      },
    },
    {
      // There is no head marker for this mechanic, instead Unknown_5779 creates the indicator
      id: 'Diamond Diamond Flash',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '5779' }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '5779' }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '5779' }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '5779' }),
      durationSeconds: 5,
      response: Responses.stackMarkerOn(),
    },
    {
      id: 'Diamond Auri Cyclone',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FE6', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FE6', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FE6', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FE6', capture: false }),
      delaySeconds: 0.5,
      durationSeconds: 6,
      response: Responses.knockback(),
    },
    {
      id: 'Diamond Airship\'s Bane',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FE8', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FE8', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FE8', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FE8', capture: false }),
      durationSeconds: 5,
      alertText: (data, _, output) => output.teleportEast(),
      outputStrings: sharedOutputStrings,
    },
    {
      id: 'Diamond Outrage',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FD7', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FD7', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FD7', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FD7', capture: false }),
      condition: Conditions.caresAboutAOE(),
      response: Responses.aoe(),
    },
    {
      id: 'Diamond Auri Doomstead',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FD8' }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FD8' }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FD8' }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FD8' }),
      response: Responses.tankBuster(),
    },
    {
      id: 'Diamond Vertical Cleave',
      netRegex: NetRegexes.startsUsing({ source: 'The Diamond Weapon', id: '5FE5', capture: false }),
      netRegexDe: NetRegexes.startsUsing({ source: 'Diamant-Waffe', id: '5FE5', capture: false }),
      netRegexFr: NetRegexes.startsUsing({ source: 'Arme Diamant', id: '5FE5', capture: false }),
      netRegexJa: NetRegexes.startsUsing({ source: 'ダイヤウェポン', id: '5FE5', capture: false }),
      durationSeconds: 5,
      response: Responses.knockback(),
    },
    {
      id: 'Diamond Diamond Shrapnel',
      netRegex: NetRegexes.headMarker({ id: '00C5' }),
      condition: Conditions.targetIsYou(),
      durationSeconds: 7,
      alertText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Diamond Shrapnel on YOU',
          de: 'Diamantschub auf DIR',
          fr: 'Salve adamantine sur VOUS',
        },
      },
    },
    {
      id: 'Diamond Articulated Bits',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '5FA9', capture: false }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '5FA9', capture: false }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '5FA9', capture: false }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '5FA9', capture: false }),
      infoText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Avoid Bits',
          de: 'Weiche den Satelliten aus',
          fr: 'Évitez les bras',
        },
      },
    },
    {
      id: 'Diamond Adamant Sphere',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '6144', capture: false }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '6144', capture: false }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '6144', capture: false }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '6144', capture: false }),
      durationSeconds: 8,
      infoText: (data, _, output) => output.text(),
      outputStrings: {
        text: {
          en: 'Get Towers',
          de: 'Türme nehmen',
          fr: 'Prenez les tours',
          ja: '塔を踏む',
          cn: '踩塔',
          ko: '장판 하나씩 들어가기',
        },
      },
    },
    {
      // Diamond Weapon starts using this Adamant Purge ~10 seconds before the head markers
      id: 'Diamond Homing Laser',
      netRegex: NetRegexes.ability({ source: 'The Diamond Weapon', id: '5F9C', capture: false }),
      netRegexDe: NetRegexes.ability({ source: 'Diamant-Waffe', id: '5F9C', capture: false }),
      netRegexFr: NetRegexes.ability({ source: 'Arme Diamant', id: '5F9C', capture: false }),
      netRegexJa: NetRegexes.ability({ source: 'ダイヤウェポン', id: '5F9C', capture: false }),
      delaySeconds: 3,
      durationSeconds: 7,
      response: Responses.spread(),
    },
  ],
  timelineReplace: [
    {
      'locale': 'de',
      'missingTranslations': true,
      'replaceSync': {
        'The Diamond Weapon': 'Diamant-Waffe',
      },
    },
    {
      'locale': 'fr',
      'missingTranslations': true,
      'replaceSync': {
        'The Diamond Weapon': 'Arme Diamant',
      },
    },
    {
      'locale': 'ja',
      'missingTranslations': true,
      'replaceSync': {
        'The Diamond Weapon': 'ダイヤウェポン',
      },
    },
  ],
};
<|endoftext|>


<commit_before>import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import { applyMiddleware, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import { Provider } from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import {
    UPDATE,
} from './actiontypes';
import ukelonnReducer from './reducers';
import { rootSaga } from './sagas';
const sagaMiddleware = createSagaMiddleware();
import { createBrowserHistory } from 'history';
import { routerMiddleware } from 'connected-react-router';

const history = createBrowserHistory();
const store = createStore(ukelonnReducer,
                          composeWithDevTools(
                              applyMiddleware(
                                  sagaMiddleware,
                                  routerMiddleware(history)
                              )
                          )
                         );
sagaMiddleware.run(rootSaga);

if (typeof Notification !== 'undefined') {
    Notification.requestPermission().then(function(result) {
        store.dispatch(UPDATE({ notificationAvailable: true }));
        console.log(result);
    });
} else {
    store.dispatch(UPDATE({ notificationAvailable: false }));
}

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);
<commit_msg>Use redux-starter-kit to set up and configure the redux store<commit_after>import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
import { configureStore } from 'redux-starter-kit';
import { Provider } from 'react-redux';
import createSagaMiddleware from 'redux-saga';
import {
    UPDATE,
} from './actiontypes';
import ukelonnReducer from './reducers';
import { rootSaga } from './sagas';
const sagaMiddleware = createSagaMiddleware();
import { createBrowserHistory } from 'history';
import { routerMiddleware } from 'connected-react-router';

const history = createBrowserHistory();
const store = configureStore({
    reducer: ukelonnReducer,
    middleware: [
        sagaMiddleware,
        routerMiddleware(history),
    ],
});
sagaMiddleware.run(rootSaga);

if (typeof Notification !== 'undefined') {
    Notification.requestPermission().then(function(result) {
        store.dispatch(UPDATE({ notificationAvailable: true }));
        console.log(result);
    });
} else {
    store.dispatch(UPDATE({ notificationAvailable: false }));
}

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);
<|endoftext|>


<commit_before>/* --------------------------------------- *
* Guerrilla UI                             *
* @module: Background Loaded jQuery plugin *
* ---------------------------------------- */
$.GUI().create('background', function(gui) {

    return {
        fn: function($el, options) {
            var _this = this, defaults, settings;

            defaults = {
                afterLoaded: function() {
                    this.addClass('bg-loaded');
                }
            };
            settings = gui.utils.merge({}, defaults, options);

            gui.each(function() {
                var $this = gui.$(this), bgImages;

                bgImages = window.getComputedStyle($this.get(0), '::before').getPropertyValue('content').replace(/'/g, "").replace(/"/g, "").split(', ');

                $this.data('loaded-count', 0);

                gui.each(bgImages, function(key, value) {
                    var img = value.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');

                    gui.$('<img/>').attr('src', img).load(function() {
                        $(this).remove(); // prevent memory leaks

                        $this.data('loaded-count', $this.data('loaded-count') + 1);

                        if ($this.data('loaded-count') >= bgImages.length) {
                            settings.afterLoaded.call($this);
                        }
                    });
                });
            });
        }
    };
}).start('background');
<commit_msg>--fix background plugin to properly loop through found images.<commit_after>/* --------------------------------------- *
* Guerrilla UI                             *
* @module: Background Loaded jQuery plugin *
* ---------------------------------------- */
$.GUI().create('background', function(gui) {

    return {
        fn: function($el, options) {
            var _this = this, defaults, settings;

            defaults = {
                afterLoaded: function() {
                    this.addClass('bg-loaded');
                }
            };
            settings = gui.utils.merge({}, defaults, options);

            $el.each(function() {
                var $this = gui.$(this), bgImages;

                bgImages = window.getComputedStyle($this.get(0), '::before').getPropertyValue('content').replace(/'/g, "").replace(/"/g, "").split(', ');

                $this.data('loaded-count', 0);

                gui.each(bgImages, function(key, value) {
                    var img = value.replace(/^url\(["']?/, '').replace(/["']?\)$/, '');

                    gui.$('<img/>').attr('src', img).load(function() {
                        $(this).remove(); // prevent memory leaks

                        $this.data('loaded-count', $this.data('loaded-count') + 1);

                        if ($this.data('loaded-count') >= bgImages.length) {
                            settings.afterLoaded.call($this);
                        }
                    });
                });
            });
        }
    };
}).start('background');
<|endoftext|>


<commit_before>/*global require */
'use strict';
require(['jquery', 'underscore', 'backbone', 'humanize', 'views/application-view', 'models/application-model', 'helpers/config-loader', 'poller', 'helpers/generate-osds', 'collections/osd-collection', 'views/userdropdown-view', 'views/clusterdropdown-view', 'views/graphwall-view', 'helpers/graph-utils', 'gitcommit', 'application', 'marionette', 'bootstrap', 'notytheme'], function($, _, Backbone, humanize, views, models, configloader, Poller, Generate, Collection, UserDropDown, ClusterDropDown, GraphWall, helpers, gitcommit, Application) {
    /* Default Configuration */
    var hostname = document.location.hostname;
    //hostname = 'mira022.front.sepia.ceph.com';
    var config = {
        offline: true,
        'delta-osd-api': false,
        'graphite-host': 'http://' + hostname + ':8080',
        'api-request-timeout-ms': 3000,
        'long-polling-interval-ms': 20000,
        'disable-network-checks': false
    };

    /* Default Configuration */
    var AppRouter = Backbone.Router.extend({
        routes: {
            'workbench': 'workbench',
            'dashboard': 'dashboard',
            'graph/:host(/:osd)': 'graph'
        }
    });
    var appRouter = new AppRouter();
    /* Load Config.json first before starting app */
    var promise = configloader('scripts/config.json').then(function(result) {
        _.extend(config, result);
    }).fail(function(jqXHR) {
        window.alert(jqXHR);
        console.log(jqXHR);
    });
    /* Load Config.json first before starting app */

    // TODO replace this with CSS version
    var replaceText = function($el, text, removeClass, addClass) {
        $el.css('display', 'none').text(text);
        if (removeClass !== undefined) {
            $el.removeClass(removeClass);
        }
        if (addClass !== undefined) {
            $el.addClass(addClass);
        }
        $el.fadeIn().css('display', '');
    };

    var App, userMenu, clusterMenu;
    promise.then(function() {
        App = new Application();
        App.ReqRes = new Backbone.Wreqr.RequestResponse();
        App.Config = config;
        userMenu = new UserDropDown({
            el: $('.usermenu'),
            App: App
        });
        userMenu.fetch();
        /* Demo Code */
        App.vent.listenTo(App.vent, 'status:healthok', function() {
            replaceText($('.warn-pg, .warn-osd, .warn-pool'), '0');
            replaceText($('.ok-pg'), 2400);
            replaceText($('.ok-pool'), 10);
        });
        App.vent.listenTo(App.vent, 'status:healthwarn', function() {
            var pg = Math.round(Math.random() * 45) + 5;
            var pool = Math.round(Math.random() * 1) + 1;
            replaceText($('.warn-pg'), pg);
            replaceText($('.warn-pool'), pool);
            replaceText($('.ok-pg'), 2400 - pg);
            replaceText($('.ok-pool'), 10 - pool);
        });
        App.vent.listenTo(App.vent, 'updateTotals', function() {
            var ONE_GIGABYTE = 1024 * 1024 * 1024;
            var totalUsed = 0,
                totalCapacity = 0,
                totalObj = 0,
                totalObjSpace = 0;
            viz.collection.each(function(m) {
                totalUsed += m.get('used');
                totalCapacity += m.get('capacity');
                totalObj += Math.random(Date.now()) * 100;
            });

            var settings = {
                cluster: 1,
                space: {
                    /* jshint -W106 */
                    free_bytes: totalCapacity * ONE_GIGABYTE,
                    capacity_bytes: totalCapacity * ONE_GIGABYTE,
                    used_bytes: totalUsed * ONE_GIGABYTE
                }
            };
            gauge.set(new models.UsageModel(settings));
            $('.objcount').text(Math.floor(totalObj));
            totalObjSpace = totalObj * 50;
            totalObjSpace = humanize.filesize(Math.floor(totalObjSpace)).replace(' Kb', 'K');
            $('.objspace').text(totalObjSpace);
        });
        /* Demo Code */

        /* Widget Setup */
        var gaugesLayout = new views.GaugesLayout({
            el: '.gauges'
        });
        gaugesLayout.render();
        var osdView = new views.OsdView({
            App: App
        });
        gaugesLayout.a.show(osdView);
        var monView = new views.MonView({
            App: App
        });
        gaugesLayout.b.show(monView);
        var gauge = new views.UsageView({
            App: App,
            model: new models.UsageModel({}),
            title: 'Usage'
        });
        var hostsView = new views.HostsView({
            App: App
        });
        gaugesLayout.d.show(hostsView);
        gauge.listenTo(gauge, 'item:postrender', function() {
            App.vent.trigger('updateTotals');
        });

        var mapsLayout = new views.GaugesLayout({
            el: '.maps'
        });
        mapsLayout.render();

        var pgView = new views.PgView({
            App: App
        });
        mapsLayout.a.show(pgView);

        var poolsView = new views.PoolsView({
            App: App
        });
        mapsLayout.b.show(poolsView);

        var iopsLayout = new views.GaugesLayout({
            el: '.iops'
        });
        iopsLayout.render();

        var iopsView = new views.IopsView({
            App: App
        });
        iopsLayout.a.show(iopsView);

        var collection;
        if (config.offline) {
            collection = Generate.osds(160);
        } else {
            collection = new Collection([], {});
        }
        var viz = new views.OSDVisualization({
            App: App,
            collection: collection,
            el: '.raphael-one'
        });

        $('body').on('keyup', function(evt) {
            App.vent.trigger('keyup', evt);
        });

        var statusLine = new views.StatusLine({
            App: App,
            el: '.status-line'
        });
        statusLine.render();

        _.extend(humanize.catalog, {
            'about_a_minute_ago': '1m',
            'minutes_ago': 'm',
            'about_an_hour_ago': '1h',
            'hours_ago': 'h',
            'one_day_ago': '1d',
            'days_ago': 'd'
        });

        /* Widget Setup */

        /* Defer Visualization startup to after loading the cluster metadata */
        var clusterDeferred = $.Deferred();
        clusterMenu = new ClusterDropDown({
            el: $('.clustermenu'),
            App: App
        });
        clusterMenu.fetch().done(function() {
            clusterDeferred.resolve(clusterMenu.collection.at(0));
        });
        clusterDeferred.promise().done(function(cluster) {
            var alertsView = new views.AlertsView({
                App: App
            });

            var poller = new Poller({
                App: App,
                cluster: cluster.get('id')
            });
            App.graphWall = new GraphWall({
                App: App,
                AppRouter: appRouter,
                graphiteHost: config['graphite-host']
            });

            viz.render().then(function() {
                gaugesLayout.c.show(gauge);
                if (!config.offline) {
                    poller.start();
                }
            });

            var breadcrumbView = new views.BreadCrumbView({
                App: App,
                AppRouter: appRouter,
                el: '.inknav'
            });
            breadcrumbView.render();

            appRouter.on('route:workbench', function() {
                App.fsm.viz();
            });
            appRouter.on('route:dashboard', function() {
                App.fsm.dashboard();
            });
            appRouter.on('route:graph', function(host, osd) {
                console.log('router>> host: ' + host + ' osd: ' + osd);
                App.fsm.graph(host, osd);
            });

            App.start({
                appRouter: appRouter
            });

            appRouter.navigate('dashboard');

            // Global Exports
            window.inktank = {
                App: App,
                Router: appRouter,
                ClusterMenu: clusterMenu,
                Gauge: gauge,
                Gauges: gaugesLayout,
                GraphWallView: App.graphWall,
                Poller: poller,
                OsdView: osdView,
                MonView: monView,
                PgView: pgView,
                UserMenu: userMenu,
                Viz: viz,
                Alerts: alertsView,
                StatusLine: statusLine,
                models: models,
                helpers: helpers,
                commit: gitcommit['git-commit'],
                views: views,
                PoolsView: poolsView,
                IopsView: iopsView
            };
        });
        /* Defer Visualization startup to after loading the cluster metadata */
    });

    Backbone.history.start();

});
<commit_msg>Increase network time outs to 10 seconds.<commit_after>/*global require */
'use strict';
require(['jquery', 'underscore', 'backbone', 'humanize', 'views/application-view', 'models/application-model', 'helpers/config-loader', 'poller', 'helpers/generate-osds', 'collections/osd-collection', 'views/userdropdown-view', 'views/clusterdropdown-view', 'views/graphwall-view', 'helpers/graph-utils', 'gitcommit', 'application', 'marionette', 'bootstrap', 'notytheme'], function($, _, Backbone, humanize, views, models, configloader, Poller, Generate, Collection, UserDropDown, ClusterDropDown, GraphWall, helpers, gitcommit, Application) {
    /* Default Configuration */
    var hostname = document.location.hostname;
    //hostname = 'mira022.front.sepia.ceph.com';
    var config = {
        offline: true,
        'delta-osd-api': false,
        'graphite-host': 'http://' + hostname + ':8080',
        'api-request-timeout-ms': 10000,
        'long-polling-interval-ms': 20000,
        'disable-network-checks': false
    };

    /* Default Configuration */
    var AppRouter = Backbone.Router.extend({
        routes: {
            'workbench': 'workbench',
            'dashboard': 'dashboard',
            'graph/:host(/:osd)': 'graph'
        }
    });
    var appRouter = new AppRouter();
    /* Load Config.json first before starting app */
    var promise = configloader('scripts/config.json').then(function(result) {
        _.extend(config, result);
    }).fail(function(jqXHR) {
        window.alert(jqXHR);
        console.log(jqXHR);
    });
    /* Load Config.json first before starting app */

    // TODO replace this with CSS version
    var replaceText = function($el, text, removeClass, addClass) {
        $el.css('display', 'none').text(text);
        if (removeClass !== undefined) {
            $el.removeClass(removeClass);
        }
        if (addClass !== undefined) {
            $el.addClass(addClass);
        }
        $el.fadeIn().css('display', '');
    };

    var App, userMenu, clusterMenu;
    promise.then(function() {
        App = new Application();
        App.ReqRes = new Backbone.Wreqr.RequestResponse();
        App.Config = config;
        userMenu = new UserDropDown({
            el: $('.usermenu'),
            App: App
        });
        userMenu.fetch();
        /* Demo Code */
        App.vent.listenTo(App.vent, 'status:healthok', function() {
            replaceText($('.warn-pg, .warn-osd, .warn-pool'), '0');
            replaceText($('.ok-pg'), 2400);
            replaceText($('.ok-pool'), 10);
        });
        App.vent.listenTo(App.vent, 'status:healthwarn', function() {
            var pg = Math.round(Math.random() * 45) + 5;
            var pool = Math.round(Math.random() * 1) + 1;
            replaceText($('.warn-pg'), pg);
            replaceText($('.warn-pool'), pool);
            replaceText($('.ok-pg'), 2400 - pg);
            replaceText($('.ok-pool'), 10 - pool);
        });
        App.vent.listenTo(App.vent, 'updateTotals', function() {
            var ONE_GIGABYTE = 1024 * 1024 * 1024;
            var totalUsed = 0,
                totalCapacity = 0,
                totalObj = 0,
                totalObjSpace = 0;
            viz.collection.each(function(m) {
                totalUsed += m.get('used');
                totalCapacity += m.get('capacity');
                totalObj += Math.random(Date.now()) * 100;
            });

            var settings = {
                cluster: 1,
                space: {
                    /* jshint -W106 */
                    free_bytes: totalCapacity * ONE_GIGABYTE,
                    capacity_bytes: totalCapacity * ONE_GIGABYTE,
                    used_bytes: totalUsed * ONE_GIGABYTE
                }
            };
            gauge.set(new models.UsageModel(settings));
            $('.objcount').text(Math.floor(totalObj));
            totalObjSpace = totalObj * 50;
            totalObjSpace = humanize.filesize(Math.floor(totalObjSpace)).replace(' Kb', 'K');
            $('.objspace').text(totalObjSpace);
        });
        /* Demo Code */

        /* Widget Setup */
        var gaugesLayout = new views.GaugesLayout({
            el: '.gauges'
        });
        gaugesLayout.render();
        var osdView = new views.OsdView({
            App: App
        });
        gaugesLayout.a.show(osdView);
        var monView = new views.MonView({
            App: App
        });
        gaugesLayout.b.show(monView);
        var gauge = new views.UsageView({
            App: App,
            model: new models.UsageModel({}),
            title: 'Usage'
        });
        var hostsView = new views.HostsView({
            App: App
        });
        gaugesLayout.d.show(hostsView);
        gauge.listenTo(gauge, 'item:postrender', function() {
            App.vent.trigger('updateTotals');
        });

        var mapsLayout = new views.GaugesLayout({
            el: '.maps'
        });
        mapsLayout.render();

        var pgView = new views.PgView({
            App: App
        });
        mapsLayout.a.show(pgView);

        var poolsView = new views.PoolsView({
            App: App
        });
        mapsLayout.b.show(poolsView);

        var iopsLayout = new views.GaugesLayout({
            el: '.iops'
        });
        iopsLayout.render();

        var iopsView = new views.IopsView({
            App: App
        });
        iopsLayout.a.show(iopsView);

        var collection;
        if (config.offline) {
            collection = Generate.osds(160);
        } else {
            collection = new Collection([], {});
        }
        var viz = new views.OSDVisualization({
            App: App,
            collection: collection,
            el: '.raphael-one'
        });

        $('body').on('keyup', function(evt) {
            App.vent.trigger('keyup', evt);
        });

        var statusLine = new views.StatusLine({
            App: App,
            el: '.status-line'
        });
        statusLine.render();

        _.extend(humanize.catalog, {
            'about_a_minute_ago': '1m',
            'minutes_ago': 'm',
            'about_an_hour_ago': '1h',
            'hours_ago': 'h',
            'one_day_ago': '1d',
            'days_ago': 'd'
        });

        /* Widget Setup */

        /* Defer Visualization startup to after loading the cluster metadata */
        var clusterDeferred = $.Deferred();
        clusterMenu = new ClusterDropDown({
            el: $('.clustermenu'),
            App: App
        });
        clusterMenu.fetch().done(function() {
            clusterDeferred.resolve(clusterMenu.collection.at(0));
        });
        clusterDeferred.promise().done(function(cluster) {
            var alertsView = new views.AlertsView({
                App: App
            });

            var poller = new Poller({
                App: App,
                cluster: cluster.get('id')
            });
            App.graphWall = new GraphWall({
                App: App,
                AppRouter: appRouter,
                graphiteHost: config['graphite-host']
            });

            viz.render().then(function() {
                gaugesLayout.c.show(gauge);
                if (!config.offline) {
                    poller.start();
                }
            });

            var breadcrumbView = new views.BreadCrumbView({
                App: App,
                AppRouter: appRouter,
                el: '.inknav'
            });
            breadcrumbView.render();

            appRouter.on('route:workbench', function() {
                App.fsm.viz();
            });
            appRouter.on('route:dashboard', function() {
                App.fsm.dashboard();
            });
            appRouter.on('route:graph', function(host, osd) {
                console.log('router>> host: ' + host + ' osd: ' + osd);
                App.fsm.graph(host, osd);
            });

            App.start({
                appRouter: appRouter
            });

            appRouter.navigate('dashboard');

            // Global Exports
            window.inktank = {
                App: App,
                Router: appRouter,
                ClusterMenu: clusterMenu,
                Gauge: gauge,
                Gauges: gaugesLayout,
                GraphWallView: App.graphWall,
                Poller: poller,
                OsdView: osdView,
                MonView: monView,
                PgView: pgView,
                UserMenu: userMenu,
                Viz: viz,
                Alerts: alertsView,
                StatusLine: statusLine,
                models: models,
                helpers: helpers,
                commit: gitcommit['git-commit'],
                views: views,
                PoolsView: poolsView,
                IopsView: iopsView
            };
        });
        /* Defer Visualization startup to after loading the cluster metadata */
    });

    Backbone.history.start();

});
<|endoftext|>


<commit_before>/// <autosync enabled="true" />
/// <reference path="../gulpfile.js" />
/// <reference path="lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js" />
/// <reference path="lib/jquery-validation/jquery.validate.js" />
/// <reference path="lib/jquery/dist/jquery.js" />
/// <reference path="lib/bootstrap/dist/js/bootstrap.js" />
/// <reference path="js/site.js" />
<commit_msg>sure update references<commit_after>/// <autosync enabled="true" />
/// <reference path="../gulpfile.js" />
/// <reference path="js/site.js" />
/// <reference path="lib/bootstrap/dist/js/bootstrap.js" />
/// <reference path="lib/jquery/dist/jquery.js" />
/// <reference path="lib/jquery-validation/dist/jquery.validate.js" />
/// <reference path="lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js" />
<|endoftext|>


<commit_before>var Class = require('../../utils/Class');
var Sprite = require('../sprite/Sprite');
var Vector2 = require('../../math/Vector2');

var PathFollower = new Class({

    Extends: Sprite,

    initialize:

    function PathFollower (scene, path, x, y, texture, frame)
    {
        Sprite.call(this, scene, x, y, texture, frame);

        this.path = path;

        this.pathOffset = new Vector2(x, y);

        this.pathVector = new Vector2();

        this.pathTween;
    },

    start: function (config)
    {
        if (config === undefined) { config = {}; }

        if (this.pathTween && this.pathTween.isPlaying())
        {
            return;
        }

        if (typeof config === 'number')
        {
            config = { duration: config };
        }

        //  Override in case they've been specified in the config
        config.from = 0;
        config.to = 1;

        //  Can also read extra values out of the config, like autoRotate

        this.pathTween = this.scene.sys.tweens.addCounter(config);

        //  The starting point of the path, relative to this follower
        this.path.getStartPoint(this.pathOffset);

        this.pathOffset.x = this.x - this.pathOffset.x;
        this.pathOffset.y = this.y - this.pathOffset.y;

        return this;
    },

    stop: function ()
    {
        if (this.pathTween && this.pathTween.isPlaying())
        {
            this.pathTween.stop();
        }

        return this;
    },

    /*
    playing: {

        get: function ()
        {
            return this.pathData.playing;
        },

        set: function (value)
        {
            if (!value)
            {
                this.stop();
            }
            else
            {
                this.start();
            }
        }

    }
    */

    preUpdate: function (time, delta)
    {
        this.anims.update(time, delta);

        if (this.pathTween && this.pathTween.isPlaying())
        {
            this.path.getPoint(this.pathTween.getValue(), this.pathVector);

            this.pathVector.add(this.pathOffset);

            this.setPosition(this.pathVector.x, this.pathVector.y);
        }
    }

});

module.exports = PathFollower;
<commit_msg>Added rotate option.<commit_after>var Class = require('../../utils/Class');
var GetBoolean = require('../../tween/builder/GetBoolean');
var GetValue = require('../../utils/object/getValue');
var Sprite = require('../sprite/Sprite');
var Vector2 = require('../../math/Vector2');

var PathFollower = new Class({

    Extends: Sprite,

    initialize:

    function PathFollower (scene, path, x, y, texture, frame)
    {
        Sprite.call(this, scene, x, y, texture, frame);

        this.path = path;

        this.rotateToPath = false;
        this.pathRotationOffset = 0;

        this.pathOffset = new Vector2(x, y);

        this.pathVector = new Vector2();

        this.pathTween;
    },

    setRotateToPath: function (value, offset)
    {
        if (offset === undefined) { offset = 0; }

        this.rotateToPath = value;
        this.pathRotationOffset = offset;

        return this;
    },

    start: function (config)
    {
        if (config === undefined) { config = {}; }

        if (this.pathTween && this.pathTween.isPlaying())
        {
            return;
        }

        if (typeof config === 'number')
        {
            config = { duration: config };
        }

        //  Override in case they've been specified in the config
        config.from = 0;
        config.to = 1;

        //  Can also read extra values out of the config:

        this.rotateToPath = GetBoolean(config, 'rotateToPath', false);
        this.pathRotationOffset = GetValue(config, 'rotationOffset', 0);

        this.pathTween = this.scene.sys.tweens.addCounter(config);

        //  The starting point of the path, relative to this follower
        this.path.getStartPoint(this.pathOffset);

        this.pathOffset.x = this.x - this.pathOffset.x;
        this.pathOffset.y = this.y - this.pathOffset.y;

        return this;
    },

    stop: function ()
    {
        if (this.pathTween && this.pathTween.isPlaying())
        {
            this.pathTween.stop();
        }

        return this;
    },

    /*
    playing: {

        get: function ()
        {
            return this.pathData.playing;
        },

        set: function (value)
        {
            if (!value)
            {
                this.stop();
            }
            else
            {
                this.start();
            }
        }

    }
    */

    preUpdate: function (time, delta)
    {
        this.anims.update(time, delta);

        if (this.pathTween && this.pathTween.isPlaying())
        {
            this.path.getPoint(this.pathTween.getValue(), this.pathVector);

            this.pathVector.add(this.pathOffset);

            var oldX = this.x;
            var oldY = this.y;

            this.setPosition(this.pathVector.x, this.pathVector.y);

            if (this.rotateToPath)
            {
                this.rotation = Math.atan2(this.y - oldY, this.x - oldX) + this.pathRotationOffset;
            }
        }
    }

});

module.exports = PathFollower;
<|endoftext|>


<commit_before>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require accounting.min
//= require spree/frontend

//= require_tree .
<commit_msg>Include js routes in frontend<commit_after>// This is a manifest file that'll be compiled into including all the files listed below.
// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
// be included in the compiled file accessible from http://example.com/assets/application.js
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
//= require jquery
//= require jquery_ujs
//= require accounting.min
//= require js-routes
//= require spree/frontend

//= require_tree .
<|endoftext|>


<commit_before>'use strict';

const toType = function (obj) {
    // toType credit goes to Angus Croll @ https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
};

class Result {
  constructor(invalidProps, reasons) {
    this.invalidProps = invalidProps;
    this.reasons = reasons;
    if (invalidProps.length > 0) {
      this.isValid = false;
    } else {
      this.isValid = true;
    }
  }
}

class Schema {
  constructor(props) {
    this.validTypes = ["object", "array", "arguments", "error",
    "math", "json", "date", "regexp", "string", "boolean", "number", "any"];
    //Check prop syntax for errors
    for (let prop in props) {
      if (this.validTypes.indexOf(props[prop]) !== -1 ||
          props[prop] instanceof Schema ||
          toType(props[prop]) === "array") {
        // Convert shortcut syntax (i.e prop: "string") into prop: {type: "string"}
        let type = props[prop];
        props[prop] = {type};
      } else if (toType(props[prop]) !== "object") {
        throw new Error("Invalid porperty description at: " + prop);
      }
      if (!props[prop].type) throw new Error("Type is required @: " + prop);
    }
    this.props = props;
  }

  getRequiredProps() {
    let props = [];
    for (let prop in this.props) {
      let optional = this.props[prop].optional;
      if (!optional) {
        props.push(prop);
      }
    }
    return props;
  }

  _validateArray(array, propDef) {
    let type = propDef.type[0];

    for (let val of array) {
      if (type instanceof Schema) {
        return type.validate(val);
      } else if (toType(val) !== type && type !== "any") {
        return "array item does not match type: " + type + " @ " + val;
      } else if (propDef.subRules) {
        for (let rule of propDef.subRules) {
          let result = rule(val, type);
          if (result instanceof Error) {
            return result.message;
          } else if (result === false) {
            return "fails against a subrule with an undefined message";
          }
        }
      }
    }
  }

  _validateObjProp(val, propDef) {
    if (propDef.type instanceof Schema) {
      if (toType(val) === "object") {
        return propDef.type.validate(val);
      } else {
        return "is not an an object";
      }
    }

    // Check type, immediatley return if there is an error here
    if (toType(val) !== propDef.type && propDef.type !== "any") {
      return "does not match type: " +  propDef.type;
    }

    // Special validation for arrays
    if (toType(val) === "array") {
       return this._validateArray(val, propDef);
    }

    // Run rule functions
    if (propDef.rules) {
      propDef.rules.forEach((rule) => {
        let result = rule(val, propDef.type);
        if (result instanceof Error) {
          return result.message;
        } else if (result === false) {
          return "fails against a rule with an undefined message";
        }
      });
    }

    return null;
  }

  validate(obj) {
    let invalidProps = [];
    let reasons = {};

    // Make sure all requiredProps are set
    let requiredProps = this.getRequiredProps();
    for (let prop of requiredProps) {
      if (obj[prop] === undefined) {
        invalidProps.push(prop);
        reasons[prop] = prop + " is required";
      }
    }

    // Make sure all props are valid
    for (let objProp in obj) {
      if (!(objProp in this.props)) {
        invalidProps.push(objProp);
        reasons[objProp] = objProp + " not in schema rules";
      } else {
        let result = this._validateObjProp(obj[objProp], this.props[objProp]);
        if (result && result.isValid !== true) {
          invalidProps.push(objProp);
          reasons[objProp] = result;
        }
      }
    }

    return new Result(invalidProps, reasons);
  }
}

let rules = {};
rules.messages = {
  max: "Exceeds maximum allowable",
  min: "Does not meet minimum required",
  regex: "Fails regex statement test"
};

rules.max = function(maxNum) {
  return function(val, message) {
    let success;
    if (toType(val) == "number") {
      success = val < maxNum;
    } else {
      if (val.length === undefined) {
        throw new Error("Value cannot be compared");
      }
      success = val.length < maxNum;
    }
    if (!success) return new Error(message || rules.messages.max);
  };
};

rules.min = function(minNum) {
  return function(val, message) {
    let success;
    if (toType(val) == "number") {
      success = val > minNum;
    } else {
      if (val.length === undefined) {
        throw new Error("Value cannot be compared");
      }
      success = val.length > minNum;
    }
    if (!success) return new Error(message || rules.messages.min);
  };
};

rules.regex = function(regStmnt) {
  return function(str, message) {
    let success = regStmnt.test(str);
    if (!success) return new Error(message || rules.messages.regex);
  };
};

exports.Schema = Schema;
exports.Result = Result;
exports.rules = rules;
<commit_msg>fix array validation<commit_after>'use strict';

const toType = function (obj) {
    // toType credit goes to Angus Croll @ https://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
    return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
};

class Result {
  constructor(invalidProps, reasons) {
    this.invalidProps = invalidProps;
    this.reasons = reasons;
    if (invalidProps.length > 0) {
      this.isValid = false;
    } else {
      this.isValid = true;
    }
  }
}

class Schema {
  constructor(props) {
    this.validTypes = ["object", "array", "arguments", "error",
    "math", "json", "date", "regexp", "string", "boolean", "number", "any"];
    //Check prop syntax for errors
    for (let prop in props) {
      if (this.validTypes.indexOf(props[prop]) !== -1 ||
          props[prop] instanceof Schema ||
          toType(props[prop]) === "array") {
        // Convert shortcut syntax (i.e prop: "string") into prop: {type: "string"}
        let type = props[prop];
        props[prop] = {type};
      } else if (toType(props[prop]) !== "object") {
        throw new Error("Invalid porperty description at: " + prop);
      }
      if (!props[prop].type) throw new Error("Type is required @: " + prop);
    }
    this.props = props;
  }

  getRequiredProps() {
    let props = [];
    for (let prop in this.props) {
      let optional = this.props[prop].optional;
      if (!optional) {
        props.push(prop);
      }
    }
    return props;
  }

  _validateArray(array, propDef) {
    let type = propDef.type[0];

    for (let val of array) {
      if (type instanceof Schema) {
        return type.validate(val);
      } else if (toType(val) !== type && type !== "any") {
        return "array item does not match type: " + type + " @ " + val;
      } else if (propDef.subRules) {
        for (let rule of propDef.subRules) {
          let result = rule(val, type);
          if (result instanceof Error) {
            return result.message;
          } else if (result === false) {
            return "fails against a subrule with an undefined message";
          }
        }
      }
    }
  }

  _validateObjProp(val, propDef) {
    // Validate subschema
    if (propDef.type instanceof Schema) {
      if (toType(val) === "object") {
        return propDef.type.validate(val);
      } else {
        return "is not an an object";
      }
    }

    // Validate array
    if (toType(propDef.type) === "array") {
      return this._validateArray(val, propDef);
    }

    // Check type, immediatley return if there is an error here
    if (toType(val) !== propDef.type && propDef.type !== "any") {
      return "does not match type: " +  propDef.type;
    }

    // Run rule functions
    if (propDef.rules) {
      propDef.rules.forEach((rule) => {
        let result = rule(val, propDef.type);
        if (result instanceof Error) {
          return result.message;
        } else if (result === false) {
          return "fails against a rule with an undefined message";
        }
      });
    }

    return null;
  }

  validate(obj) {
    let invalidProps = [];
    let reasons = {};

    // Make sure all requiredProps are set
    let requiredProps = this.getRequiredProps();
    for (let prop of requiredProps) {
      if (obj[prop] === undefined) {
        invalidProps.push(prop);
        reasons[prop] = prop + " is required";
      }
    }

    // Make sure all props are valid
    for (let objProp in obj) {
      if (!(objProp in this.props)) {
        invalidProps.push(objProp);
        reasons[objProp] = objProp + " not in schema rules";
      } else {
        let result = this._validateObjProp(obj[objProp], this.props[objProp]);
        if (result && result.isValid !== true) {
          invalidProps.push(objProp);
          reasons[objProp] = result;
        }
      }
    }

    return new Result(invalidProps, reasons);
  }
}

let rules = {};
rules.messages = {
  max: "Exceeds maximum allowable",
  min: "Does not meet minimum required",
  regex: "Fails regex statement test"
};

rules.max = function(maxNum) {
  return function(val, message) {
    let success;
    if (toType(val) == "number") {
      success = val < maxNum;
    } else {
      if (val.length === undefined) {
        throw new Error("Value cannot be compared");
      }
      success = val.length < maxNum;
    }
    if (!success) return new Error(message || rules.messages.max);
  };
};

rules.min = function(minNum) {
  return function(val, message) {
    let success;
    if (toType(val) == "number") {
      success = val > minNum;
    } else {
      if (val.length === undefined) {
        throw new Error("Value cannot be compared");
      }
      success = val.length > minNum;
    }
    if (!success) return new Error(message || rules.messages.min);
  };
};

rules.regex = function(regStmnt) {
  return function(str, message) {
    let success = regStmnt.test(str);
    if (!success) return new Error(message || rules.messages.regex);
  };
};

exports.Schema = Schema;
exports.Result = Result;
exports.rules = rules;
<|endoftext|>