<commit_before>const _ = require('underscore');

const PlotCard = require('../../../plotcard.js');

class WildfireAssault extends PlotCard {
    constructor(owner, cardData) {
        super(owner, cardData);

        this.state = {};
    }

    onReveal(player) {
        if(!this.inPlay || this.owner !== player) {
            return true;
        }

        var firstPlayer = this.game.getFirstPlayer();

        if(!firstPlayer) {
            return true;
        }

        var otherPlayer = this.game.getOtherPlayer(firstPlayer);

        this.state[firstPlayer.id] = {};
        this.state[firstPlayer.id].selecting = true;
        this.state[firstPlayer.id].doneSelecting = false;

        this.setupSelection(firstPlayer);

        if(otherPlayer) {
            this.state[otherPlayer.id] = {};
            this.state[otherPlayer.id].selecting = false;
            this.state[otherPlayer.id].doneSelecting = false;
        }

        return false;
    }

    setupSelection(player) {
        var buttons = [{ command: 'plot', method: 'cancelSelection', text: 'Done' }];

        this.state[player.id].selecting = true;

        var otherPlayer = this.game.getOtherPlayer(player);
        if(otherPlayer) {
            otherPlayer.menuTitle = 'Waiting for opponent to select characters';
            otherPlayer.buttons = [];
        }

        this.game.promptForSelect(player, this.onCardSelected.bind(this), 'Select characters to save', buttons, true);
    }

    cancelSelection(player) {
        if(!this.inPlay || !this.state[player.id].selecting) {
            return;
        }

        this.state[player.id].doneSelecting = true;

        this.proceedToNextStep();
    }

    onCardSelected(player, cardId) {
        if(!this.inPlay || !this.state[player.id].selecting) {
            return false;
        }

        var card = player.findCardInPlayByUuid(cardId);
        if(!card || card.getType() !== 'character') {
            return false;
        }

        var numSelected = player.cardsInPlay.reduce((counter, card) => {
            if(!card.selected) {
                return counter;
            }

            return counter + 1;
        }, 0);

        if(numSelected === 3 && !card.selected) {
            return false;
        }

        card.selected = !card.selected;

        return true;
    }

    doDiscard() {
        var sortedPlayers = this.game.getPlayersInFirstPlayerOrder();

        _.each(sortedPlayers, player => {
            var toKill = player.cardsInPlay.filter(card => {
                return card.getType() === 'character' && !card.selected;
            });

            var params = '';
            var paramIndex = 2;

            _.each(toKill, card => {
                card.selected = false;

                player.discardCard(card.uuid, player.deadPile);

                params += '{' + paramIndex++ + '} ';

            });

            if(_.isEmpty(toKill)) {
                this.game.addMessage('{0} does not kill any characters with {1}', player, this);
            } else {
                this.game.addMessage('{0} uses {1} to kill ' + params, player, this, ...toKill);
            }

            player.cardsInPlay.each(card => {
                card.selected = false;
            });

            player.selectCard = false;
        });

        _.each(this.state, s => {
            s.selecting = false;
        });

        this.game.playerRevealDone(this.owner);
    }

    proceedToNextStep() {
        var stillToSelect = _.find(this.game.getPlayers(), player => {
            return !this.state[player.id].doneSelecting;
        });

        if(!stillToSelect) {
            this.doDiscard();

            return;
        }

        this.setupSelection(stillToSelect);
    }
}

WildfireAssault.code = '01026';

module.exports = WildfireAssault;
<commit_msg>Fix crash caused by more than one wildfire assault resolving at once fixes #87<commit_after>const _ = require('underscore');

const PlotCard = require('../../../plotcard.js');

class WildfireAssault extends PlotCard {
    constructor(owner, cardData) {
        super(owner, cardData);

        this.state = {};
    }

    onReveal(player) {
        if(!this.inPlay || this.owner !== player) {
            return true;
        }

        var firstPlayer = this.game.getFirstPlayer();

        if(!firstPlayer) {
            return true;
        }

        var otherPlayer = this.game.getOtherPlayer(firstPlayer);

        this.state[firstPlayer.id] = {};
        this.state[firstPlayer.id].selecting = true;
        this.state[firstPlayer.id].doneSelecting = false;

        this.setupSelection(firstPlayer);

        if(otherPlayer) {
            this.state[otherPlayer.id] = {};
            this.state[otherPlayer.id].selecting = false;
            this.state[otherPlayer.id].doneSelecting = false;
        }

        return false;
    }

    setupSelection(player) {
        var buttons = [{ command: 'plot', method: 'cancelSelection', text: 'Done' }];

        this.state[player.id].selecting = true;

        var otherPlayer = this.game.getOtherPlayer(player);
        if(otherPlayer) {
            otherPlayer.menuTitle = 'Waiting for opponent to select characters';
            otherPlayer.buttons = [];
        }

        this.waitingForSelection = true;

        this.game.promptForSelect(player, this.onCardSelected.bind(this), 'Select characters to save', buttons, true);
    }

    cancelSelection(player) {
        if(!this.inPlay || !this.waitingForSelection || !this.state[player.id].selecting) {
            return;
        }

        this.state[player.id].doneSelecting = true;

        this.proceedToNextStep();
    }

    onCardSelected(player, cardId) {
        if(!this.inPlay || !this.waitingForSelection || !this.state[player.id].selecting) {
            return false;
        }

        var card = player.findCardInPlayByUuid(cardId);
        if(!card || card.getType() !== 'character') {
            return false;
        }

        var numSelected = player.cardsInPlay.reduce((counter, card) => {
            if(!card.selected) {
                return counter;
            }

            return counter + 1;
        }, 0);

        if(numSelected === 3 && !card.selected) {
            return false;
        }

        card.selected = !card.selected;

        return true;
    }

    doDiscard() {
        var sortedPlayers = this.game.getPlayersInFirstPlayerOrder();

        _.each(sortedPlayers, player => {
            var toKill = player.cardsInPlay.filter(card => {
                return card.getType() === 'character' && !card.selected;
            });

            var params = '';
            var paramIndex = 2;

            _.each(toKill, card => {
                card.selected = false;

                player.discardCard(card.uuid, player.deadPile);

                params += '{' + paramIndex++ + '} ';

            });

            if(_.isEmpty(toKill)) {
                this.game.addMessage('{0} does not kill any characters with {1}', player, this);
            } else {
                this.game.addMessage('{0} uses {1} to kill ' + params, player, this, ...toKill);
            }

            player.cardsInPlay.each(card => {
                card.selected = false;
            });

            player.selectCard = false;
        });

        _.each(this.state, s => {
            s.selecting = false;
        });

        this.waitingForSelection = false;

        this.game.playerRevealDone(this.owner);
    }

    proceedToNextStep() {
        var stillToSelect = _.find(this.game.getPlayers(), player => {
            return !this.state[player.id].doneSelecting;
        });

        if(!stillToSelect) {
            this.doDiscard();

            return;
        }

        this.setupSelection(stillToSelect);
    }
}

WildfireAssault.code = '01026';

module.exports = WildfireAssault;
<|endoftext|>


<commit_before>const GLib = imports.gi.GLib;
const NoFlo = imports.noflo;
const Options = imports.options;
const Utils = imports.utils;

const CmdOptions = [
    {
        name: 'version',
        shortName: 'v',
        requireArgument: true,
        defaultValue: '0.0.1',
    },
    {
        name: 'name',
        shortName: 'n',
        requireArgument: true,
        defaultValue: 'MyApplication',
    },
];

//
let exec = function(args) {
    let manifestPath = GLib.getenv('PWD') + '/manifest.json';
    if (GLib.file_test(manifestPath, GLib.FileTest.EXISTS))
        throw new Error('Cannot initialize repository, already initialized');

    let options = Options.parseArguments(CmdOptions, args);

    let manifest = {
        name: options.options['name'],
        version: options.options['version'],
        ui: [],
        noflo: {
            components: {},
            graphs: {
                'Main': 'graphs/Main.json'
            },
            main: 'Main'
        },
    };
    let mainGraphPath = GLib.getenv('PWD') + '/' + manifest.noflo.graphs.Main;

    try {
        let oldManifest = Utils.parseJSON(Utils.loadTextFileContent(manifestPath));
        Utils.mergeProps(manifest, oldManifest);
    } catch (e) {
    }

    Utils.saveTextFileContent(manifestPath, JSON.stringify(manifest, null, "  "));
    Utils.saveTextFileContent(mainGraphPath,
                              JSON.stringify((new NoFlo.NoFlo.Graph(manifest.noflo.main)).toJSON(),
                                             null, "  "));

    return 0;
};
<commit_msg>builder: init: use printHelp()<commit_after>const GLib = imports.gi.GLib;
const NoFlo = imports.noflo;
const Options = imports.options;
const Utils = imports.utils;

const CmdOptions = [
    {
        name: 'version',
        shortName: 'v',
        requireArgument: true,
        defaultValue: '0.0.1',
        help: 'Version for application repository'
    },
    {
        name: 'name',
        shortName: 'n',
        requireArgument: true,
        defaultValue: 'MyApplication',
        help: 'Name for application repository'
    },
    {
        name: 'help',
        shortName: 'h',
        requireArgument: false,
        defaultValue: false,
        help: 'Print this screen'
    },
];

//
let exec = function(args) {
    let options = Options.parseArguments(CmdOptions, args);

    if (options.options.help) {
        Options.printHelp('noflo-gnome init', CmdOptions);
        return 0;
    }

    let manifestPath = GLib.getenv('PWD') + '/manifest.json';
    if (GLib.file_test(manifestPath, GLib.FileTest.EXISTS))
        throw new Error('Cannot initialize repository, already initialized');

    let manifest = {
        name: options.options['name'],
        version: options.options['version'],
        ui: [],
        noflo: {
            components: {},
            graphs: {
                'Main': 'graphs/Main.json'
            },
            main: 'Main'
        },
    };
    let mainGraphPath = GLib.getenv('PWD') + '/' + manifest.noflo.graphs.Main;

    try {
        let oldManifest = Utils.parseJSON(Utils.loadTextFileContent(manifestPath));
        Utils.mergeProps(manifest, oldManifest);
    } catch (e) {
    }

    Utils.saveTextFileContent(manifestPath, JSON.stringify(manifest, null, "  "));
    Utils.saveTextFileContent(mainGraphPath,
                              JSON.stringify((new NoFlo.NoFlo.Graph(manifest.noflo.main)).toJSON(),
                                             null, "  "));

    return 0;
};
<|endoftext|>


<commit_before>/*
 * Copyright 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.analytics.form.DatasourcesMenu',
    dependencies: [],
    obj: function () {
        var module = this, Block = og.common.util.ui.Block;
        var DatasourcesMenu = function (config) {
            if (!config) return og.dev.warn('og.analytics.DatasourcesMenu: Missing param [config] to constructor.');

            if (!(config.hasOwnProperty('form')) || !(config.form instanceof og.common.util.ui.Form))
                return og.dev.warn('og.analytics.DatasourcesMenu: Missing param key [config.form] to constructor.');

            // Private
            var block = this, form = config.form, menu, query = [], resolver_keys = [], snapshots = {}, $query,
                default_type_txt = 'select type...', default_sel_txt = 'select data source...',
                del_s = '.og-icon-delete', parent_s = '.OG-dropmenu-options', type_s = '.type', source_s = '.source',
                extra_opts_s = '.extra-opts', latest_s = '.latest', custom_s = '.custom', custom_val = 'Custom',
                date_selected_s = 'date-selected', active_s = 'active', versions_s = '.versions',
                corrections_s = '.corrections', initialized = false, datasources,
                sources = {
                    live: {
                        type:'Live',
                        source:'',
                        datasource: 'livedatasources',
                        api_opts:{ cache_for:5000 }
                    },
                    snapshot: {
                        type:'Snapshot',
                        source:'',
                        datasource: 'marketdatasnapshots',
                        api_opts:{ cache_for:5000 }
                    },
                    historical: {
                        type:'Historical',
                        source:'',
                        date:'',
                        datasource: 'configs',
                        api_opts:{ type: 'HistoricalTimeSeriesRating' }
                    }
                };

            var add_handler = function (obj) {
                add_row_handler(obj).html(function (html) {
                    menu.add_handler($(html));
                    menu.opts[menu.opts.length-1].data('type', obj.type.toLowerCase());
                    source_handler(menu.opts.length-1);
                });
            };

            var add_row_handler = function (obj) {
                return new form.Block({
                    module: 'og.analytics.form_datasources_row_tash',
                    extras: {
                        type: obj.type.toLowerCase(),
                        type_list: ['Live', 'Snapshot', 'Historical'].map(function (entry) {
                            return {text: entry, selected: obj.type === entry};
                        })
                    },
                    children: [add_source_dropdown(obj)]
                });
            };

            var add_source_dropdown = function (obj) {
                var datasource = obj.datasource.split('.').reduce(function (api, key) {return api[key];}, og.api.rest);
                return new form.Block({
                    module: 'og.analytics.form_datasources_source_tash',
                    generator: function (handler, tmpl, data) {
                        datasource.get(obj.api_opts).pipe(function (resp) {
                            if (resp.error) return og.dev.warn('og.analytics.DatasourcesMenu: ' + resp.error);
                            data.source = obj.type === 'Live' ? resp.data.map(function (entry) {
                                return { text: entry, value: entry, selected: obj.source === entry };
                            }) : obj.type === 'Snapshot' ? resp.data[0].snapshots.map(function (entry) {
                                return { text: entry.name, value: entry.id, selected: obj.source === entry.id };
                            }) : obj.type === 'Historical' ? resp.data.data.map(
                                function (entry) {
                                    var arr = entry.split('|');
                                    return { text: arr[1], value: arr[1], selected: obj.source === arr[1]};
                            }) : {};
                            if (obj.type === 'Historical') data.historical = {
                                    fixed: obj.date ? true : false,
                                    latest: obj.date === '' ? true : false
                                };
                            if (data.historical && data.historical.fixed) data.historical.date = obj.date;
                            handler(tmpl(data));
                        });
                    }
                });
            };

            var date_handler = function (entry) { // TODO AG: refocus custom, hide datepicker
                if (!menu.opts[entry]) return;
                var custom = $(custom_s, menu.opts[entry]), latest = $(latest_s, menu.opts[entry]),
                    idx = query.pluck('pos').indexOf(menu.opts[entry].data('pos'));
                if (custom) custom.addClass(active_s+ ' ' +date_selected_s);
                if (latest) latest.removeClass(active_s);
                if (custom.parent().is(versions_s)) query[idx].version_date = custom.datepicker('getDate');
                else if (custom.parent().is(corrections_s)) query[idx].correction_date = custom.val();
                else query[idx].date = custom.val();
            };

            var delete_handler = function (entry) {
                if (!menu.opts[entry]) return;
                if (menu.opts.length === 1 && query.length) return remove_ext_opts(entry), reset_query(entry);
                var idx = query.pluck('pos').indexOf(menu.opts[entry].data('pos')),
                    sel_pos = menu.opts[entry].data('pos');
                menu.delete_handler(menu.opts[entry]);
                if (menu.opts.length) {
                    for (var i = ~idx ? idx : sel_pos, len = query.length; i < len; query[i++].pos -= 1);
                    if (~idx) return remove_entry(idx), display_query(); // fire; optsrepositioned
                }
            };

            var deserialize = function (data) {
                return data.map(function (entry) { // TODO AG: refactor.
                    var obj;
                    switch (entry.marketDataType) {
                        case 'live': obj = $.extend({}, sources['live'], { source: entry.source }); break;
                        case 'snapshot': obj = $.extend({}, sources['snapshot'], { source: entry.snapshotId }); break;
                        case 'latestHistorical':
                            obj = $.extend({}, sources['historical'], { source: entry.resolverKey }); break;
                        case 'fixedHistorical':
                            obj = $.extend({}, sources['historical'], {source: entry.resolverKey, date: entry.date});
                            break;
                        //no default
                    }
                    return obj;
                });
            };

            var display_datepicker = function (entry) {
                if (!menu.opts[entry]) return;
                var custom_dp = $(custom_s, menu.opts[entry]), widget;
                custom_dp.datepicker({
                    dateFormat:'yy-mm-dd',
                    onSelect: function () {
                        date_handler(entry);
                        widget.off('mouseup.prevent_blurkill');
                    }
                });
                custom_dp.datepicker('show');
                widget = custom_dp.datepicker('widget').on('mouseup.prevent_blurkill', function(event) {
                    menu.fire('dropmenu:open');
                });
            };

            var display_query = function () {
                if(query.length) {
                    var i = 0, arr = [];
                    query.sort(menu.sort_opts).forEach(function (entry) { // revisit the need for sorting this..
                        if (i > 0) arr[i++] = menu.$dom.toggle_infix.html() + ' ';
                        arr[i++] = entry;
                    });
                    $query.html(arr.reduce(function (a, v) {
                        return a += v.type ? menu.capitalize(v.type) + ':' + v.txt : menu.capitalize(v);
                    }, ''));
                } else $query.text(default_sel_txt);
            };

            var enable_extra_options = function (entry, val, preload) {
                if (!menu.opts[entry]) return;
                var inputs = $(extra_opts_s, menu.opts[entry]).find('input');
                if (!inputs || preload) return;
                if (val) inputs.removeAttr('disabled').filter(latest_s).addClass(active_s);
                else inputs.attr('disabled', true).filter('.'+active_s).removeClass(active_s);
                inputs.filter(custom_s).removeClass(active_s+ ' ' +date_selected_s).val(custom_val);
            };

            var init = function () {
                menu = new og.analytics.form.DropMenu({cntr: $('.OG-analytics-form .og-datasources')});
                if (menu.$dom) {
                    $query = $('.datasources-query', menu.$dom.toggle);
                    if (menu.$dom.menu)
                        menu.$dom.menu.on('click', 'input, button, div.og-icon-delete, a.OG-link-add', menu_handler)
                            .on('change', 'select', menu_handler);
                    menu.opts.forEach(function (entry, idx) { source_handler(idx, true); });
                    og.common.events.on('datasources:dropmenu:open', function() {menu.fire('dropmenu:open', this);});
                    og.common.events.on('datasources:dropmenu:close', function() {menu.fire('dropmenu:close', this);});
                    og.common.events.on('datasources:dropmenu:focus', function() {menu.fire('dropmenu:focus', this);});
                    menu.fire('initialized', [initialized = true]);
                }
            };

            var menu_handler = function (event) {
                var entry, elem = $(event.srcElement || event.target), parent = elem.parents(parent_s);
                if (!parent) return;
                entry = parent.data('pos');
                if (elem.is(menu.$dom.add)) return menu.stop(event), add_handler(default_source);
                if (elem.is(del_s)) return menu.stop(event), delete_handler(entry);
                if (elem.is(type_s)) return type_handler(entry);
                if (elem.is(source_s)) return source_handler(entry);
                if (elem.is(custom_s)) return display_datepicker(entry);
                if (elem.is(latest_s)) return remove_date(entry);
                if (elem.is('button')) return menu.button_handler(elem.text()), menu.stop(event), false;
            };

            var remove_date = function (entry) {
                if (!menu.opts[entry]) return;
                var custom = $(custom_s, menu.opts[entry]).removeClass(active_s+ ' ' +date_selected_s).val(custom_val),
                    latest = $(latest_s, menu.opts[entry]).addClass(active_s);
                if (custom.parent().is(versions_s)) delete query[entry].version_date;
                else if (custom.parent().is(corrections_s)) delete query[entry].correction_date;
                else delete query[entry].date;
            };

            var remove_entry = function (entry) {
                if (menu.opts.length === 1 && query.length === 1) return query.length = 0; // fire; resetquery
                if (~entry) query.splice(entry, 1);
            };

            var remove_ext_opts = function (entry) {
                if (!menu.opts[entry]) return;
                var parent = menu.opts[entry];
                return reset_source_select(entry), parent.removeClass(parent.data('type')).find(extra_opts_s).remove();
            };

            var remove_orphans = function () {
                for (var i = menu.opts.length-1; i >= 0; i-=1){
                    if (menu.opts.length === 1) break;
                    var option = menu.opts[i];
                    if ($(type_s, option).val() === default_type_txt || $(source_s, option).val() === default_sel_txt)
                        menu.delete_handler(option);
                }
            };

            var reset_query = function (entry) {
                if (!menu.opts[entry]) return;
                var type_select = $(type_s, menu.opts[entry]);
                return $query.text(default_sel_txt), type_select.val(default_sel_txt).focus(), remove_entry();
            };

            var reset_source_select = function (entry) {
                if (!menu.opts[entry]) return;
                var source_select = $(source_s, menu.opts[entry]).hide(), options = $('option', source_select), i;
                if (!source_select || !options.length) return;
                options.each(function(idx){ // IE
                    if (idx > 0) $(this).remove();
                });
                source_select.show();
            };

            var serialize = function () {
                if (!query.length) return;
                var arr = [];
                query.forEach(function (entry) {
                    var obj = {}, val = entry.type.toLowerCase();
                    switch (val) {
                        case 'live': obj['marketDataType'] = val, obj['source'] = entry.src; break;
                        case 'snapshot': obj['marketDataType'] = val, obj['snapshotId'] = entry.src; break;
                        case 'historical':
                            if (entry.date) {
                                obj['marketDataType'] = 'fixedHistorical';
                                obj['date'] = entry.date;
                            } else obj['marketDataType'] = 'latestHistorical';
                            obj['resolverKey'] = entry.src; break;
                        //no default
                    }
                    arr.push(obj);
                });
                return arr;
            };

            var source_handler = function (entry, preload) {
                if (!menu.opts[entry]) return;
                var val, src, option, sel_pos = menu.opts[entry].data('pos'),
                    type_val = $(type_s, menu.opts[entry]).val().toLowerCase(),
                    source_select = $(source_s, menu.opts[entry]),
                    source_val = source_select.val(),
                    source_txt = source_select.find('option:selected').text();
                    idx = query.pluck('pos').indexOf(sel_pos),
                    date = $('.extra-opts .custom', menu.opts[entry]).val();
                    date = date !== 'Custom' ? date : null;
                if (source_val === default_sel_txt) {
                    return remove_entry(idx), display_query(), enable_extra_options(entry, false);
                } else if (~idx) query[idx] = {pos:sel_pos, type:type_val, src:source_val, txt: source_txt, date: date};
                else query.splice(sel_pos, 0, {pos:sel_pos, type:type_val, src:source_val, txt: source_txt, date: date});
                enable_extra_options(entry, true, preload);
                display_query();
            };

            var type_handler = function (entry) {
                if (!menu.opts[entry]) return;
                var parent = menu.opts[entry], type_select = $(type_s, parent), src_parent = $('.datasource', parent),
                    type_val = type_select.val().toLowerCase(), idx = query.pluck('pos').indexOf(parent.data('pos'));
                if (type_val === default_type_txt.toLowerCase()){
                    if (menu.opts.length === 1 && query.length === 1) return remove_ext_opts(entry), reset_query(entry);
                    return remove_entry(idx), remove_ext_opts(entry), display_query(),
                        enable_extra_options(entry, false);
                }
                if (parent.hasClass(parent.data('type'))) {
                    remove_entry(idx); remove_ext_opts(entry); display_query();
                }
                add_source_dropdown(sources[type_val]).html(function (html) {
                    src_parent.html($(html));
                    menu.opts[entry].data('type', type_val);
                    parent.addClass(parent.data('type'));
                    source_handler(parent.data('pos'));
                });
            };

            default_source = $.extend({}, sources.live);
            default_source.source = 'Bloomberg';
            datasources = config.source ? deserialize(config.source) : [default_source];

            form.Block.call(block, {
                data: { providers: [] },
                module: 'og.analytics.form_datasources_tash',
                children: datasources.map(add_row_handler),
                processor: function (data) {
                    data.providers = serialize();
                }
            });

            form.on('form:load', init);
        };

        DatasourcesMenu.prototype = new Block;
        return DatasourcesMenu;
    }
});<commit_msg>initial commit for displaying the first available datasource option as a default selected option<commit_after>/*
 * Copyright 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */
$.register_module({
    name: 'og.analytics.form.DatasourcesMenu',
    dependencies: [],
    obj: function () {
        var Block = og.common.util.ui.Block;
        var DatasourcesMenu = function (config) {
            if (!config) return og.dev.warn('og.analytics.DatasourcesMenu: Missing param [config] to constructor.');

            if (!(config.hasOwnProperty('form')) || !(config.form instanceof og.common.util.ui.Form))
                return og.dev.warn('og.analytics.DatasourcesMenu: Missing param key [config.form] to constructor.');

            // Private
            var block = this, initialized = false, form = config.form, menu, query = [], $query,
                default_type_txt = 'select type...', default_sel_txt = 'select data source...',
                del_s = '.og-icon-delete', parent_s = '.OG-dropmenu-options', type_s = '.type', source_s = '.source',
                extra_opts_s = '.extra-opts', latest_s = '.latest', custom_s = '.custom', custom_val = 'Custom',
                date_selected_s = 'date-selected', active_s = 'active', versions_s = '.versions',
                corrections_s = '.corrections', types = [], avail_types = ['Live', 'Snapshot', 'Historical'],
                datasources, default_source,
                sources = {
                    live: {
                        type:'Live',
                        source:'',
                        datasource: 'livedatasources',
                        api_opts:{ cache_for:5000 }
                    },
                    snapshot: {
                        type:'Snapshot',
                        source:'',
                        datasource: 'marketdatasnapshots',
                        api_opts:{ cache_for:5000 }
                    },
                    historical: {
                        type:'Historical',
                        source:'',
                        date:'',
                        datasource: 'configs',
                        api_opts:{ type: 'HistoricalTimeSeriesRating' }
                    }
                };

            var add_handler = function (obj) {
                add_row_handler(obj).html(function (html) {
                    menu.add_handler($(html));
                    menu.opts[menu.opts.length-1].data('type', obj.type.toLowerCase());
                    source_handler(menu.opts.length-1);
                });
            };

            var add_row_handler = function (obj) {
                return new form.Block({
                    module: 'og.analytics.form_datasources_row_tash',
                    extras: {
                        type: obj.type.toLowerCase(),
                        type_list: types.map(function (entry) {
                            return {text: entry.type, selected: obj.type === entry.type};
                        })
                    },
                    children: [add_source_dropdown(obj)]
                });
            };

            var add_source_dropdown = function (obj) {
                var datasource = obj.datasource.split('.').reduce(function (api, key) {return api[key];}, og.api.rest);
                return new form.Block({
                    module: 'og.analytics.form_datasources_source_tash',
                    generator: function (handler, tmpl, data) {
                        datasource.get(obj.api_opts).pipe(function (resp) {
                            if (resp.error) return og.dev.warn('og.analytics.DatasourcesMenu: ' + resp.error);
                            data.source = obj.type === 'Live' ? resp.data.map(function (entry) {
                                return { text: entry, value: entry, selected: obj.source === entry };
                            }) : obj.type === 'Historical' ? resp.data.data.map(
                                function (entry) {
                                    var arr = entry.split('|');
                                    return { text: arr[1], value: arr[1], selected: obj.source === arr[1]};
                            }) : obj.type === 'Snapshot' ? resp.data[0].snapshots.map(function (entry) {
                                return { text: entry.name, value: entry.id, selected: obj.source === entry.id };
                            }) : {};
                            if (obj.type === 'Historical') data.historical = {
                                    fixed: obj.date ? true : false,
                                    latest: !!(obj.date === '')
                                };
                            if (data.historical && data.historical.fixed) data.historical.date = obj.date;
                            handler(tmpl(data));
                        });
                    }
                });
            };

            var date_handler = function (entry) { // TODO AG: refocus custom, hide datepicker
                if (!menu.opts[entry]) return;
                var custom = $(custom_s, menu.opts[entry]), latest = $(latest_s, menu.opts[entry]),
                    idx = query.pluck('pos').indexOf(menu.opts[entry].data('pos'));
                if (custom) custom.addClass(active_s+ ' ' +date_selected_s);
                if (latest) latest.removeClass(active_s);
                if (custom.parent().is(versions_s)) query[idx].version_date = custom.datepicker('getDate');
                else if (custom.parent().is(corrections_s)) query[idx].correction_date = custom.val();
                else query[idx].date = custom.val();
            };

            var delete_handler = function (entry) {
                if (!menu.opts[entry]) return;
                if (menu.opts.length === 1 && query.length) return remove_ext_opts(entry), reset_query(entry);
                var idx = query.pluck('pos').indexOf(menu.opts[entry].data('pos')),
                    sel_pos = menu.opts[entry].data('pos');
                menu.delete_handler(menu.opts[entry]);
                if (menu.opts.length) {
                    for (var i = ~idx ? idx : sel_pos, len = query.length; i < len; query[i++].pos -= 1);
                    if (~idx) return remove_entry(idx), display_query(); // fire; optsrepositioned
                }
            };

            var deserialize = function (data) {
                return data.map(function (entry) { // TODO AG: refactor.
                    var obj;
                    switch (entry.marketDataType) {
                        case 'live': obj = $.extend({}, sources['live'], { source: entry.source }); break;
                        case 'snapshot': obj = $.extend({}, sources['snapshot'], { source: entry.snapshotId }); break;
                        case 'latestHistorical':
                            obj = $.extend({}, sources['historical'], { source: entry.resolverKey }); break;
                        case 'fixedHistorical':
                            obj = $.extend({}, sources['historical'], { source: entry.resolverKey, date: entry.date });
                            break;
                        //no default
                    }
                    return obj;
                });
            };

            var display_datepicker = function (entry) {
                if (!menu.opts[entry]) return;
                var custom_dp = $(custom_s, menu.opts[entry]), widget;
                custom_dp.datepicker({
                    dateFormat:'yy-mm-dd',
                    onSelect: function () {
                        date_handler(entry);
                        widget.off('mouseup.prevent_blurkill');
                    }
                });
                custom_dp.datepicker('show');
                widget = custom_dp.datepicker('widget').on('mouseup.prevent_blurkill', function() {
                    menu.fire('dropmenu:open');
                });
            };

            var display_query = function () {
                if(query.length) {
                    var i = 0, arr = [];
                    query.sort(menu.sort_opts).forEach(function (entry) { // revisit the need for sorting this..
                        if (i > 0) arr[i++] = menu.$dom.toggle_infix.html() + ' ';
                        arr[i++] = entry;
                    });
                    $query.html(arr.reduce(function (a, v) {
                        return a += v.type ? menu.capitalize(v.type) + ':' + v.txt : menu.capitalize(v);
                    }, ''));
                } else $query.text(default_sel_txt);
            };

            var enable_extra_options = function (entry, val, preload) {
                if (!menu.opts[entry]) return;
                var inputs = $(extra_opts_s, menu.opts[entry]).find('input');
                if (!inputs || preload) return;
                if (val) inputs.removeAttr('disabled').filter(latest_s).addClass(active_s);
                else inputs.attr('disabled', true).filter('.'+active_s).removeClass(active_s);
                inputs.filter(custom_s).removeClass(active_s+ ' ' +date_selected_s).val(custom_val);
            };

            var init = function () {
                menu = new og.analytics.form.DropMenu({cntr: $('.OG-analytics-form .og-datasources')});
                if (menu.$dom) {
                    $query = $('.datasources-query', menu.$dom.toggle);
                    if (menu.$dom.menu)
                        menu.$dom.menu.on('click', 'input, button, div.og-icon-delete, a.OG-link-add', menu_handler)
                            .on('change', 'select', menu_handler);
                    menu.opts.forEach(function (entry, idx) { source_handler(idx, true); });
                    og.common.events.on('datasources:dropmenu:open', function() {menu.fire('dropmenu:open', this);});
                    og.common.events.on('datasources:dropmenu:close', function() {menu.fire('dropmenu:close', this);});
                    og.common.events.on('datasources:dropmenu:focus', function() {menu.fire('dropmenu:focus', this);});
                    menu.fire('initialized', [initialized = true]);
                }
            };

            var menu_handler = function (event) {
                var entry, elem = $(event.srcElement || event.target), parent = elem.parents(parent_s);
                if (!parent) return;
                entry = parent.data('pos');
                if (elem.is(menu.$dom.add)) return menu.stop(event), add_handler(default_source);
                if (elem.is(del_s)) return menu.stop(event), delete_handler(entry);
                if (elem.is(type_s)) return type_handler(entry);
                if (elem.is(source_s)) return source_handler(entry);
                if (elem.is(custom_s)) return display_datepicker(entry);
                if (elem.is(latest_s)) return remove_date(entry);
                if (elem.is('button')) return menu.button_handler(elem.text()), menu.stop(event), false;
            };

            var remove_date = function (entry) {
                if (!menu.opts[entry]) return;
                var custom = $(custom_s, menu.opts[entry]).removeClass(active_s+ ' ' +date_selected_s).val(custom_val);
                $(latest_s, menu.opts[entry]).addClass(active_s);
                if (custom.parent().is(versions_s)) delete query[entry].version_date;
                else if (custom.parent().is(corrections_s)) delete query[entry].correction_date;
                else delete query[entry].date;
            };

            var remove_entry = function (entry) {
                if (menu.opts.length === 1 && query.length === 1) return query.length = 0; // fire; resetquery
                if (~entry) query.splice(entry, 1);
            };

            var remove_ext_opts = function (entry) {
                if (!menu.opts[entry]) return;
                var parent = menu.opts[entry];
                return reset_source_select(entry), parent.removeClass(parent.data('type')).find(extra_opts_s).remove();
            };

            var remove_orphans = function () {
                for (var i = menu.opts.length-1; i >= 0; i-=1){
                    if (menu.opts.length === 1) break;
                    var option = menu.opts[i];
                    if ($(type_s, option).val() === default_type_txt || $(source_s, option).val() === default_sel_txt)
                        menu.delete_handler(option);
                }
            };

            var reset_query = function (entry) {
                if (!menu.opts[entry]) return;
                var type_select = $(type_s, menu.opts[entry]);
                return $query.text(default_sel_txt), type_select.val(default_sel_txt).focus(), remove_entry();
            };

            var reset_source_select = function (entry) {
                if (!menu.opts[entry]) return;
                var source_select = $(source_s, menu.opts[entry]).hide(), options = $('option', source_select), i;
                if (!source_select || !options.length) return;
                options.each(function(idx){ // IE
                    if (idx > 0) $(this).remove();
                });
                source_select.show();
            };

            var serialize = function () {
                if (!query.length) return;
                var arr = [];
                query.forEach(function (entry) {
                    var obj = {}, val = entry.type.toLowerCase();
                    switch (val) {
                        case 'live': obj['marketDataType'] = val, obj['source'] = entry.src; break;
                        case 'snapshot': obj['marketDataType'] = val, obj['snapshotId'] = entry.src; break;
                        case 'historical':
                            if (entry.date) {
                                obj['marketDataType'] = 'fixedHistorical';
                                obj['date'] = entry.date;
                            } else obj['marketDataType'] = 'latestHistorical';
                            obj['resolverKey'] = entry.src; break;
                        //no default
                    }
                    arr.push(obj);
                });
                return arr;
            };

            var source_handler = function (entry, preload) {
                if (!menu.opts[entry]) return;
                var option, sel_pos = menu.opts[entry].data('pos'),
                    type_val = $(type_s, menu.opts[entry]).val().toLowerCase(),
                    source_select = $(source_s, menu.opts[entry]),
                    source_val = source_select.val(),
                    source_txt = source_select.find('option:selected').text(),
                    idx = query.pluck('pos').indexOf(sel_pos),
                    date = $('.extra-opts .custom', menu.opts[entry]).val();
                    date = date !== 'Custom' ? date : null;
                if (source_val === default_sel_txt) {
                    return remove_entry(idx), display_query(), enable_extra_options(entry, false);
                } else if (~idx) query[idx] = {pos:sel_pos, type:type_val, src:source_val, txt: source_txt, date: date};
                else query.splice(sel_pos, 0, {pos:sel_pos, type:type_val, src:source_val, txt: source_txt, date: date});
                enable_extra_options(entry, true, preload);
                display_query();
            };

            var type_handler = function (entry) {
                if (!menu.opts[entry]) return;
                var parent = menu.opts[entry], type_select = $(type_s, parent), src_parent = $('.datasource', parent),
                    type_val = type_select.val().toLowerCase(), idx = query.pluck('pos').indexOf(parent.data('pos'));
                if (type_val === default_type_txt.toLowerCase()){
                    if (menu.opts.length === 1 && query.length === 1) return remove_ext_opts(entry), reset_query(entry);
                    return remove_entry(idx), remove_ext_opts(entry), display_query(),
                        enable_extra_options(entry, false);
                }
                if (parent.hasClass(parent.data('type'))) {
                    remove_entry(idx); remove_ext_opts(entry); display_query();
                }
                add_source_dropdown(sources[type_val]).html(function (html) {
                    src_parent.html($(html));
                    menu.opts[entry].data('type', type_val);
                    parent.addClass(parent.data('type'));
                    source_handler(parent.data('pos'));
                });
            };

            avail_types.forEach(function (entry, idx) {
                sources[entry.toLowerCase()].datasource.split('.')
                .reduce(function (api, key) { return api[key]; }, og.api.rest)
                .get(sources[entry.toLowerCase()].api_opts)
                .pipe(function (resp) {
                    if (entry === 'Live' && resp.data.length) {
                        types.push({type: entry, source: resp.data[0]});
                    } else if (entry === 'Snapshot' && resp.data[0].snapshots.length) {
                        types.push({type: entry, source: resp.data[0].snapshots[0]});
                    } else if (entry === 'Historical') {
                        if (resp.data.data.length)
                            types.push({type: entry, source: resp.data.data[0].split('|')[1]});
                        default_source = $.extend({}, sources[types[0].type.toLowerCase()]);
                        default_source.source = types[0].source;
                        datasources = config.source ? deserialize(config.source) : [default_source];
                        form.Block.call(block, {
                            data: { providers: [] },
                            module: 'og.analytics.form_datasources_tash',
                            children: datasources.map(add_row_handler),
                            processor: function (data) {
                                data.providers = serialize();
                            }
                        });
                        form.on('form:load', init);
                        form.dom();
                    }
                });
            });
        };

        DatasourcesMenu.prototype = new Block;
        return DatasourcesMenu;
    }
});<|endoftext|>


<commit_before>//  ██████╗ ██╗   ██╗██╗██╗     ██████╗     ███████╗ ██████╗██╗  ██╗███████╗███╗   ███╗ █████╗
//  ██╔══██╗██║   ██║██║██║     ██╔══██╗    ██╔════╝██╔════╝██║  ██║██╔════╝████╗ ████║██╔══██╗
//  ██████╔╝██║   ██║██║██║     ██║  ██║    ███████╗██║     ███████║█████╗  ██╔████╔██║███████║
//  ██╔══██╗██║   ██║██║██║     ██║  ██║    ╚════██║██║     ██╔══██║██╔══╝  ██║╚██╔╝██║██╔══██║
//  ██████╔╝╚██████╔╝██║███████╗██████╔╝    ███████║╚██████╗██║  ██║███████╗██║ ╚═╝ ██║██║  ██║
//  ╚═════╝  ╚═════╝ ╚═╝╚══════╝╚═════╝     ╚══════╝ ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝
//
// Build a schema object that is suitable for using in a Create Table query.

var _ = require('@sailshq/lodash');

module.exports = function buildSchema(definition) {
  if (!definition) {
    throw new Error('`buildSchema()` requires a valid definition be passed in, but no argument was provided.');
  }

  //  ╔╗╔╔═╗╦═╗╔╦╗╔═╗╦  ╦╔═╗╔═╗  ┌─┐┌─┐┬  ┬ ┬┌┬┐┌┐┌  ┌┬┐┬ ┬┌─┐┌─┐
  //  ║║║║ ║╠╦╝║║║╠═╣║  ║╔═╝║╣   │  │ ││  │ │││││││   │ └┬┘├─┘├┤
  //  ╝╚╝╚═╝╩╚═╩ ╩╩ ╩╩═╝╩╚═╝╚═╝  └─┘└─┘┴─┘└─┘┴ ┴┘└┘   ┴  ┴ ┴  └─┘
  var normalizeType = function normalizeType(type) {
    switch (type.toLowerCase()) {

      // Default column types from sails-hook-orm.
      case '_number':
        return 'REAL';
      case '_numberkey':
        return 'INTEGER';
      case '_numbertimestamp':
        return 'BIGINT';
      case '_string':
        return 'TEXT';
      case '_stringkey':
        return 'VARCHAR';
      case '_stringtimestamp':
        return 'VARCHAR';
      case '_boolean':
        return 'BOOLEAN';
      case '_json':
        return 'JSON';
      case '_ref':
        return 'TEXT';

      default:
        return type;
    }
  };

  // Build up a string of column attributes
  var columns = _.map(definition, function map(attribute, name) {
    if (_.isString(attribute)) {
      var val = attribute;
      attribute = {};
      attribute.type = val;
    }

    // Note:  For auto-increment columns, in the general case (i.e. when logical
    // type is number + no specific physical column type set), always use SERIAL
    // as the columnType.  Otherwise, usethe specific column type that was set.
    // For example, this allows for UUID autoincrement:
	  //     columnType: 'UUID DEFAULT uuid_generate_v4()'
    var computedColumnType = (attribute.autoIncrement && attribute.columnType === '_number') ? 'SERIAL' : attribute.columnType;
    var columnType = normalizeType(computedColumnType || '');
    var nullable = attribute.notNull && 'NOT NULL';
    var unique = attribute.unique && 'UNIQUE';

    return _.compact(['"' + name + '"', columnType, nullable, unique]).join(' ');
  }).join(',');

  // Grab the Primary Key
  var primaryKeys = _.keys(_.pick(definition, function findPK(attribute) {
    return attribute.primaryKey;
  }));

  // Add the Primary Key to the definition
  var constraints = _.compact([
    primaryKeys.length && 'PRIMARY KEY ("' + primaryKeys.join('","') + '")'
  ]).join(', ');

  var schema = _.compact([columns, constraints]).join(', ');

  return schema;
};
<commit_msg>Further cleanup<commit_after>//  ██████╗ ██╗   ██╗██╗██╗     ██████╗     ███████╗ ██████╗██╗  ██╗███████╗███╗   ███╗ █████╗
//  ██╔══██╗██║   ██║██║██║     ██╔══██╗    ██╔════╝██╔════╝██║  ██║██╔════╝████╗ ████║██╔══██╗
//  ██████╔╝██║   ██║██║██║     ██║  ██║    ███████╗██║     ███████║█████╗  ██╔████╔██║███████║
//  ██╔══██╗██║   ██║██║██║     ██║  ██║    ╚════██║██║     ██╔══██║██╔══╝  ██║╚██╔╝██║██╔══██║
//  ██████╔╝╚██████╔╝██║███████╗██████╔╝    ███████║╚██████╗██║  ██║███████╗██║ ╚═╝ ██║██║  ██║
//  ╚═════╝  ╚═════╝ ╚═╝╚══════╝╚═════╝     ╚══════╝ ╚═════╝╚═╝  ╚═╝╚══════╝╚═╝     ╚═╝╚═╝  ╚═╝
//
// Build data that is suitable for use in a Create Table query.

var _ = require('@sailshq/lodash');

module.exports = function buildSchema(definition) {
  if (!definition) {
    throw new Error('`buildSchema()` requires a valid definition be passed in, but no argument was provided.');
  }

  //  ╔╗╔╔═╗╦═╗╔╦╗╔═╗╦  ╦╔═╗╔═╗  ┌─┐┌─┐┬  ┬ ┬┌┬┐┌┐┌  ┌┬┐┬ ┬┌─┐┌─┐   ┌─┐┌┬┐┌─┐
  //  ║║║║ ║╠╦╝║║║╠═╣║  ║╔═╝║╣   │  │ ││  │ │││││││   │ └┬┘├─┘├┤    ├┤  │ │
  //  ╝╚╝╚═╝╩╚═╩ ╩╩ ╩╩═╝╩╚═╝╚═╝  └─┘└─┘┴─┘└─┘┴ ┴┘└┘   ┴  ┴ ┴  └─┘┘  └─┘ ┴ └─┘

  // Build up a string of column attributes
  var columns = _.map(definition, function map(attribute, name) {
    if (_.isString(attribute)) {
      var val = attribute;
      attribute = {};
      attribute.type = val;
    }

    // Note:  For auto-increment columns, in the general case (i.e. when logical
    // type is number + no specific physical column type set), always use SERIAL
    // as the columnType.  Otherwise, usethe specific column type that was set.
    // For example, this allows for UUID autoincrement:
	  //     columnType: 'UUID DEFAULT uuid_generate_v4()'
    var computedColumnType = ((attribute.autoIncrement && attribute.columnType === '_number') ? 'SERIAL' : attribute.columnType) || '';

    // Handle default column types from sails-hook-orm.
    switch (computedColumnType.toLowerCase()) {
      case '_number':
        computedColumnType = 'REAL';
      case '_numberkey':
        computedColumnType = 'INTEGER';
      case '_numbertimestamp':
        computedColumnType = 'BIGINT';
      case '_string':
        computedColumnType = 'TEXT';
      case '_stringkey':
        computedColumnType = 'VARCHAR';
      case '_stringtimestamp':
        computedColumnType = 'VARCHAR';
      case '_boolean':
        computedColumnType = 'BOOLEAN';
      case '_json':
        computedColumnType = 'JSON';
      case '_ref':
        computedColumnType = 'TEXT';
    }

    // Mix in other auto-migration directives to get the PostgreSQL-ready SQL
    // we'll use to declare this column's physical data type.
    var nullable = attribute.notNull && 'NOT NULL';
    var unique = attribute.unique && 'UNIQUE';
    return _.compact(['"' + name + '"', computedColumnType, nullable, unique]).join(' ');
  }).join(',');

  // Grab the Primary Key
  var primaryKeys = _.keys(_.pick(definition, function findPK(attribute) {
    return attribute.primaryKey;
  }));

  // Add the Primary Key to the definition
  var constraints = _.compact([
    primaryKeys.length && 'PRIMARY KEY ("' + primaryKeys.join('","') + '")'
  ]).join(', ');

  var schema = _.compact([columns, constraints]).join(', ');

  return schema;
};
<|endoftext|>


<commit_before>/*!
 * Cartie.js - jQuery Cookie Cart Plugin
 * https://github.com/yusufbesim/cartie.js
 *
 * Copyright 2015
 * Released under the MIT license
 *
 * Thanks to Klaus Hartl for cookie manage jquery cookie plugin. This plugins cookie managment code blocks from him
 */
(function (factory) {
    if (typeof define === 'function' && define.amd) { // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') { // CommonJS
        factory(require('jquery'));
    } else { // Browser Globals
        factory(jQuery);
    }
}(function ($) {
    var pluses = /\+/g;

    function encode(s) {
        return config.raw ? s : encodeURIComponent(s);
    }

    function decode(s) {
        return config.raw ? s : decodeURIComponent(s);
    }

    function stringifyCookieValue(value) {
        return encode(config.json ? JSON.stringify(value) : String(value));
    }

    function parseCookieValue(s) {
        if (s.indexOf('"') === 0) {
            // This is a quoted cookie as according to RFC2068, unescape...
            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
        }

        try {
            // Replace server-side written pluses with spaces.
            // If we can't decode the cookie, ignore it, it's unusable.
            // If we can't parse the cookie, ignore it, it's unusable.
            s = decodeURIComponent(s.replace(pluses, ' '));
            return config.json ? JSON.parse(s) : s;
        } catch(e) {}
    }

    function read(s, converter) {
        var value = config.raw ? s : parseCookieValue(s);
        return $.isFunction(converter) ? converter(value) : value;
    }
    function cookieManage(key, value, options){
        // Write Cart Data
        if (arguments.length > 1 && !$.isFunction(value)) {
            options = $.extend({}, config.defaults, options);

            if (typeof options.expires === 'number') {
                var days = options.expires, t = options.expires = new Date();
                t.setTime(+t + days * 864e+5);
            }

            return (document.cookie = [
                encode(key), '=', stringifyCookieValue(value),
                options.expires ? '; expires=' + options.expires.toUTCString() : '',
                options.path    ? '; path=' + options.path : '',
                options.domain  ? '; domain=' + options.domain : '',
                options.secure  ? '; secure' : ''
            ].join(''));
        }

        // Read Cart Data
        var result = key ? undefined : {};
        var cookies = document.cookie ? document.cookie.split('; ') : [];

        for (var i = 0, l = cookies.length; i < l; i++) {
            var parts = cookies[i].split('=');
            var name = decode(parts.shift());
            var cookie = parts.join('=');

            if (key && key === name) {
                // If second argument (value) is a function it's a converter...
                result = read(cookie, value);
                break;
            }

            // Prevent storing a cookie that we couldn't decode.
            if (!key && (cookie = read(cookie)) !== undefined) {
                result[name] = cookie;
            }
        }
        return result;
    }
    function calculateCart(){
        var totalPrice = 0;
        var items = config.cart.items;
        for(var index in items) {
            totalPrice += items[index].price * items[index].qty;
        }
        return totalPrice;
    }
    var config = $.cartie = function (action, options) {
        var result = false;
        if(typeof(action) === "object"){ // IF set defaults
            for(var index in action) {
                config.defaults[index] = action[index];
            }
        } else { // IF actions fired
            switch(action){
                case "default":
                    result = config.defaults[options];
                    break;
                case "items":
                    return config.cart.items;
                    break;
                case "totalPrice":
                    result = config.cart.total;
                    break;
                case "add":
                    result = true;
                    var alreadyInCart = false;
                    var items = config.cart.items;
                    for(var index in items) {
                        if(items[index].id == options.id){
                            config.cart.items[index].qty += options.qty;
                            alreadyInCart = true;
                        }
                    }
                    if(!alreadyInCart){
                        if(options.id !== undefined && options.price !== undefined){
                            config.cart.items.push({
                                id:options.id,
                                qty:(options.qty === undefined?0:options.qty),
                                price:options.price,
                                name:options.name,
                                image:options.image,
                                description:options.description
                            });
                        } else {
                            result = false;
                        }
                    }
                    config.cart.total = calculateCart();
                    cookieManage("cartie",JSON.stringify(config.cart));
                    break;
                case "remove":
                    var items = config.cart.items;
                    for(var index in items) {
                        if(items[index].id == options.id){
                            config.cart.items[index].qty -= options.qty;
                            if(config.cart.items[index].qty < 1){delete config.cart.items[index]}
                        }
                    }
                    config.cart.total = calculateCart();
                    cookieManage("cartie",JSON.stringify(config.cart));
                    result = true;
                    break;
                case "clear":
                    config.cart = {
                        items:[],
                        total:0,
                        currency:config.defaults.currency
                    }
                    return true;
                    break;
                default:
                    break;
            }
        }
        return result;
    };

    config.defaults = {
        currency:"USD"
    };
    config.cart = {
        items:[],
        total:0,
        currency:config.defaults.currency
    }
    try {
        var cartTMP = cookieManage("cartie");
        cartTMP = JSON.parse(cartTMP);
        if(typeof(cartTMP) === "object"){
            config.cart = cartTMP;
        }
    } catch(e) {
        cookieManage("cartie",JSON.stringify(config.cart));
    }
}));<commit_msg>Bug fix<commit_after>/*!
 * Cartie.js - jQuery Cookie Cart Plugin
 * https://github.com/yusufbesim/cartie.js
 *
 * Copyright 2015
 * Released under the MIT license
 *
 * Thanks to Klaus Hartl for cookie manage jquery cookie plugin. This plugins cookie managment code blocks from him
 */
(function (factory) {
    if (typeof define === 'function' && define.amd) { // AMD
        define(['jquery'], factory);
    } else if (typeof exports === 'object') { // CommonJS
        factory(require('jquery'));
    } else { // Browser Globals
        factory(jQuery);
    }
}(function ($) {
    var pluses = /\+/g;

    function encode(s) {
        return config.raw ? s : encodeURIComponent(s);
    }

    function decode(s) {
        return config.raw ? s : decodeURIComponent(s);
    }

    function stringifyCookieValue(value) {
        return encode(config.json ? JSON.stringify(value) : String(value));
    }

    function parseCookieValue(s) {
        if (s.indexOf('"') === 0) {
            // This is a quoted cookie as according to RFC2068, unescape...
            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
        }

        try {
            // Replace server-side written pluses with spaces.
            // If we can't decode the cookie, ignore it, it's unusable.
            // If we can't parse the cookie, ignore it, it's unusable.
            s = decodeURIComponent(s.replace(pluses, ' '));
            return config.json ? JSON.parse(s) : s;
        } catch(e) {}
    }

    function read(s, converter) {
        var value = config.raw ? s : parseCookieValue(s);
        return $.isFunction(converter) ? converter(value) : value;
    }
    function cookieManage(key, value, options){
        // Write Cart Data
        if (arguments.length > 1 && !$.isFunction(value)) {
            options = $.extend({}, config.defaults, options);

            if (typeof options.expires === 'number') {
                var days = options.expires, t = options.expires = new Date();
                t.setTime(+t + days * 864e+5);
            }

            return (document.cookie = [
                encode(key), '=', stringifyCookieValue(value),
                options.expires ? '; expires=' + options.expires.toUTCString() : '',
                options.path    ? '; path=' + options.path : '',
                options.domain  ? '; domain=' + options.domain : '',
                options.secure  ? '; secure' : ''
            ].join(''));
        }

        // Read Cart Data
        var result = key ? undefined : {};
        var cookies = document.cookie ? document.cookie.split('; ') : [];

        for (var i = 0, l = cookies.length; i < l; i++) {
            var parts = cookies[i].split('=');
            var name = decode(parts.shift());
            var cookie = parts.join('=');

            if (key && key === name) {
                // If second argument (value) is a function it's a converter...
                result = read(cookie, value);
                break;
            }

            // Prevent storing a cookie that we couldn't decode.
            if (!key && (cookie = read(cookie)) !== undefined) {
                result[name] = cookie;
            }
        }
        return result;
    }
    function calculateCart(){
        var totalPrice = 0;
        var items = config.cart.items;
        for(var index in items) {
            totalPrice += items[index].price * items[index].qty;
        }
        return Math.ceil(totalPrice * 100) / 100;
    }
    var config = $.cartie = function (action, options) {
        options = (options=="undefined"?{}:options);
        var result = false;
        if(typeof(action) === "object"){ // IF set defaults
            for(var index in action) {
                config.defaults[index] = action[index];
                if(index == "currency"){config.cart["currency"] = action["currency"]}
            }
            result = true;
        } else { // IF actions fired
            switch(action){
                case "default":
                    result = config.defaults[options.option];
                    break;
                case "items":
                    return config.cart.items;
                    break;
                case "totalPrice":
                    result = config.cart.total;
                    break;
                case "add":
                    result = true;
                    var alreadyInCart = false;
                    var items = config.cart.items;
                    for(var index in items) {
                        if(items[index].id == options.id){
                            config.cart.items[index].qty += parseInt(options.qty);
                            alreadyInCart = true;
                        }
                    }
                    if(!alreadyInCart){
                        if(options.id !== undefined && options.price !== undefined){
                            config.cart.items.push({
                                id:options.id,
                                qty:parseInt(options.qty === undefined?0:options.qty),
                                price:parseFloat(options.price),
                                name:options.name,
                                image:options.image,
                                description:options.description
                            });
                        } else {
                            result = false;
                        }
                    }
                    config.cart.total = calculateCart();
                    break;
                case "remove":
                    var items = config.cart.items;
                    for(var index in items) {
                        if(items[index].id == options.id){
                            config.cart.items[index].qty -= options.qty;
                            if(config.cart.items[index].qty < 1){delete config.cart.items[index]}
                        }
                    }
                    config.cart.total = calculateCart();
                    result = true;
                    break;
                case "clear":
                    config.cart = {
                        items:[],
                        total:0,
                        currency:config.defaults.currency
                    }
                    return true;
                    break;
                default:
                    break;
            }
        }
        cookieManage("cartie",JSON.stringify(config.cart));
        return result;
    };

    config.defaults = {
        currency:"USD"
    };
    config.cart = {
        items:[],
        total:0,
        currency:config.defaults.currency
    }
    try {
        var cartTMP = cookieManage("cartie");
        cartTMP = JSON.parse(cartTMP);
        if(typeof(cartTMP) === "object"){
            config.cart = cartTMP;
        }
    } catch(e) {
        cookieManage("cartie",JSON.stringify(config.cart));
    }
}));<|endoftext|>


<commit_before>var sales = require('cloud/sales.js');
var support = require('cloud/support.js');

Parse.Cloud.beforeSave("Sales", function(request, response) {

  var ticket = JSON.stringify(request.object);
  ticket = JSON.parse(ticket);

  if(sales.valid(ticket)) {
    sales.save(ticket, function (data) {
      request.object.set('zendeskId', data.ticket.id.toString());
      response.success();
    }, function (error) {
      response.error(error);
    });
  } else {
    response.error('Error!');
  }
});

Parse.Cloud.afterSave("Sales", function(request) {
  var zendeskId = request.object.get('zendeskId');
  var ticket = {
    ticket: {
      external_id: request.object.id
    }
  };
  sales.update(zendeskId, ticket, function (data) {
  }, function (error) {
    console.error("Got an error " + error.code + " : " + error.message);
  });
});

Parse.Cloud.beforeSave("Support", function(request, response) {

  var ticket = JSON.stringify(request.object);
  ticket = JSON.parse(ticket);

  if(support.valid(ticket)) {
    support.save(ticket, function (data) {
      request.object.set('zendeskId', data.ticket.id.toString());
      response.success();
    }, function (error) {
      response.error(error);
    });
  } else {
    response.error('Error!');
  }
});

Parse.Cloud.afterSave("Support", function(request) {
  var zendeskId = request.object.get('zendeskId');
  var ticket = {
    ticket: {
      external_id: request.object.id
    }
  };
  sales.update(zendeskId, ticket, function (data) {
  }, function (error) {
    console.error("Got an error " + error.code + " : " + error.message);
  });
});
<commit_msg>Logs error back to client.<commit_after>var sales = require('cloud/sales.js');
var support = require('cloud/support.js');

Parse.Cloud.beforeSave("Sales", function(request, response) {

  var ticket = JSON.stringify(request.object);
  ticket = JSON.parse(ticket);

  if(sales.valid(ticket)) {
    sales.save(ticket, function (data) {
      request.object.set('zendeskId', data.ticket.id.toString());
      response.success();
    }, function (error) {
      response.error(error);
    });
  } else {
    response.error(sales.errors(ticket));
  }
});

Parse.Cloud.afterSave("Sales", function(request) {
  var zendeskId = request.object.get('zendeskId');
  var ticket = {
    ticket: {
      external_id: request.object.id
    }
  };
  sales.update(zendeskId, ticket, function (data) {
  }, function (error) {
    console.error("Got an error " + error.code + " : " + error.message);
  });
});

Parse.Cloud.beforeSave("Support", function(request, response) {

  var ticket = JSON.stringify(request.object);
  ticket = JSON.parse(ticket);

  if(support.valid(ticket)) {
    support.save(ticket, function (data) {
      request.object.set('zendeskId', data.ticket.id.toString());
      response.success();
    }, function (error) {
      response.error(error);
    });
  } else {
    response.error(support.errors(ticket));
  }
});

Parse.Cloud.afterSave("Support", function(request) {
  var zendeskId = request.object.get('zendeskId');
  var ticket = {
    ticket: {
      external_id: request.object.id
    }
  };
  sales.update(zendeskId, ticket, function (data) {
  }, function (error) {
    console.error("Got an error " + error.code + " : " + error.message);
  });
});
<|endoftext|>


<commit_before>// NOTE: this isn't working for me... intended to prevent loading of `wizard.js`

// http://stackoverflow.com/questions/4755546/remove-div-tag-using-javascript-or-jquery
//  - http://stackoverflow.com/questions/4726362/use-javascript-to-prevent-a-later-script-tag-from-being-evaluated

// http://www.w3schools.com/jsref/met_document_getelementsbytagname.asp
var scripts = document.getElementsByTagName('script');

// http://www.w3schools.com/js/js_loop_for.asp
for(i = 0; i < scripts.length; i++) {
    if (scripts[i].hasAttribute('src') && scripts[i].getAttribute('src') == 'C:\Program Files (x86)\BigFix Enterprise\BES Console\reference\wizards.js') {
         scripts[i].parentNode.removeChild(scripts[i]);
    }
}
<commit_msg>Delete removescript.js<commit_after><|endoftext|>


<commit_before>$(function() {
    "use strict";

    /**
     * set up margins for SVG; These are chosen arbitrarily
     */
    var margin = { top: 20, right: 50, bottom: 30, left: 20 };
    var width = 960 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;

    /**
     * Sets up an ordinal scale that will be used on the X axis date labels
     */
    var xScale = d3.scale.ordinal()
        .rangeRoundBands([0, width]);

    /**
     * Sets up a linear Y scale
     */
    var yScale = d3.scale.linear()
        .rangeRound([height, 0]);

    /**
     * Defines an ordinal scale to map Stuffed Animal names to colors
     */
    var color = d3.scale.ordinal()
        .domain(["Teddy Bear", "Dog", "Horse", "Cat"])
        .range(["blue", "red", "green", "purple"])

    /**
     * sets up the x axis; orients the scale at the bottom
     */
    var xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("bottom")

    /**
     * Sets up a vertical right axis on the right hand side
     */
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("right");

    /**
     * Selects an HTML section element and appends the SVG element
     */
    var svg = d3.select("#chartSection").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g") //appends a group element to the SVG element
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //moves the SVG element

    /**
     * Makes an asynchronous call to the csv file; formats the returned data
     * into an Array of Arrays
     */
    d3.csv("stuffedAnimals2.csv", type, function(data) { //Loading the CSV file asynchronously
        // console.log("pretty data: ", JSON.stringify(data, null, '\t'));
        //Used d3.keys to return an Array of keys from the parsed CSV, then filtered that Array to only include the Month headers
        var stuffedAnimals = d3.keys(data[0]).filter(function(key) {
            return key !== "Month"; });
        var months = data.map(function(data){
            return data["Month"]
        });

        var formattedData = stuffedAnimals.map(function(header, headerIndex) { //Called map function on headers Array; will return a new Array
            return data.map(function(eachMonthData, index){ //Called map function on original parsed CSV data; will return a new array
            	return {x: eachMonthData["Month"], y: eachMonthData[header], animal:header} //returns a new object at each iteration; sets x value to be the Stuff animal name and the y value to be the number sold for a given month using the value from the header Array as a lookup
            })
        });
        // console.log("formattedData: ", JSON.stringify(formattedData, null, '\t'));

        //Uses the d3.layout.stack() convenience method to calculate the stack data
        var stack = d3.layout.stack()
        var formattedLayers = stack(formattedData);

        //Defines the domain of the xScale, will be the names of the Stuffed Animals
        xScale.domain(months.map(function(header) {
            return header;
        }))

        /*defines the domain of the yScale;
        d3.max Returns the maximum value in the given array using natural order
        We use formattedLayers.length - 1 to look at the last element of the formattedLayers Array
        The accessor function then acts similar to Array.map in that returns a new Array with the results of calling a provided function on every element in this array
        .nice() Extends the domain so that it starts and ends on nice round values*/
        yScale.domain([0, d3.max(formattedLayers[formattedLayers.length - 1], function(d) {
            return d.y0 + d.y;
        })]).nice();

        //Binds the data (data join) and appends a group element to the yet to be created bars
        var layer = svg.selectAll(".layer")
            .data(formattedLayers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function(d, i) {
                return color(d[i].animal);
            }); //fills with color according to d3.scale.category10()

        //Appends the scaled rectangles
        layer.selectAll("rect")
            .data(function(d) {
                return d;
            })
            .enter().append("rect")
            .attr("x", function(d, i) {
                return xScale(d.x);
            })
            .attr("y", function(d) {
                return yScale(d.y + d.y0); })
            .attr("height", function(d) {
                return yScale(d.y0) - yScale(d.y + d.y0); })
            .attr("width", xScale.rangeBand() - 1)
            .on("mouseover", function(d){
                //Get this bar's x/y values, then augment for the tooltip
                var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2;
                var yPosition = parseFloat(d3.select(this).attr("y")) + 14;

                //Update the tooltip position and value
                d3.select("#tooltip")
                  .style("left", xPosition + "px")
                  .style("top", yPosition + "px")
                  .select("#value")
                    .text(d.y);

                d3.select("#title")
                    .text(d.animal)

                //Show the tooltip
                d3.select("#tooltip").classed("hidden", false);
            })
            .on("mouseout", function() {
                //Hide the tooltip
                d3.select("#tooltip").classed("hidden", true);
            });

        //appends the xAxis
        svg.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);
        //appends the yAxis
        svg.append("g")
            .attr("class", "axis axis--y")
            .attr("transform", "translate(" + width + ",0)")
            .call(yAxis);
    });
    //Accessor function that converts the amount sold that was parsed from the CSV from a String to a Number
    function type(d) {
        var filteredKeys = d3.keys(d).filter(function(key) {
            return key !== "Month"; });
        filteredKeys.forEach(function(month) {
            d[month] = +d[month];
        });
        return d;
    }

});

<commit_msg>Added legend<commit_after>$(function() {
    "use strict";

    /**
    * sample code from https://bl.ocks.org/mbostock/3886208
    */

    /**
     * set up margins for SVG; These are chosen arbitrarily
     * saraford: increasing right margin for legend
     */
    var margin = { top: 20, right: 200, bottom: 30, left: 20 };
    var width = 960 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;

    /**
     * Sets up an ordinal scale that will be used on the X axis date labels
     */
    var xScale = d3.scale.ordinal()
        .rangeRoundBands([0, width]);

    /**
     * Sets up a linear Y scale
     */
    var yScale = d3.scale.linear()
        .rangeRound([height, 0]);

    /**
     * Defines an ordinal scale to map Stuffed Animal names to colors
     */
    var color = d3.scale.ordinal()
        .domain(["Teddy Bear", "Dog", "Horse", "Cat"])
        .range(["blue", "red", "green", "purple"])

    /**
     * sets up the x axis; orients the scale at the bottom
     */
    var xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("bottom")

    /**
     * Sets up a vertical right axis on the right hand side
     */
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("right");

    /**
     * Selects an HTML section element and appends the SVG element
     */
    var svg = d3.select("#chartSection").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g") //appends a group element to the SVG element
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); //moves the SVG element

    /**
     * Makes an asynchronous call to the csv file; formats the returned data
     * into an Array of Arrays
     */
    d3.csv("stuffedAnimals2.csv", type, function(data) { //Loading the CSV file asynchronously
        // console.log("pretty data: ", JSON.stringify(data, null, '\t'));
        //Used d3.keys to return an Array of keys from the parsed CSV, then filtered that Array to only include the Month headers
        var stuffedAnimals = d3.keys(data[0]).filter(function(key) {
            return key !== "Month"; });
        var months = data.map(function(data){
            return data["Month"]
        });

        var formattedData = stuffedAnimals.map(function(header, headerIndex) { //Called map function on headers Array; will return a new Array
            return data.map(function(eachMonthData, index){ //Called map function on original parsed CSV data; will return a new array
            	return {x: eachMonthData["Month"], y: eachMonthData[header], animal:header} //returns a new object at each iteration; sets x value to be the Stuff animal name and the y value to be the number sold for a given month using the value from the header Array as a lookup
            })
        });
        // console.log("formattedData: ", JSON.stringify(formattedData, null, '\t'));

        //Uses the d3.layout.stack() convenience method to calculate the stack data
        var stack = d3.layout.stack()
        var formattedLayers = stack(formattedData);

        //Defines the domain of the xScale, will be the names of the Stuffed Animals
        xScale.domain(months.map(function(header) {
            return header;
        }))

        /*defines the domain of the yScale;
        d3.max Returns the maximum value in the given array using natural order
        We use formattedLayers.length - 1 to look at the last element of the formattedLayers Array
        The accessor function then acts similar to Array.map in that returns a new Array with the results of calling a provided function on every element in this array
        .nice() Extends the domain so that it starts and ends on nice round values*/
        yScale.domain([0, d3.max(formattedLayers[formattedLayers.length - 1], function(d) {
            return d.y0 + d.y;
        })]).nice();

        //Binds the data (data join) and appends a group element to the yet to be created bars
        var layer = svg.selectAll(".layer")
            .data(formattedLayers)
            .enter().append("g")
            .attr("class", "layer")
            .style("fill", function(d, i) {
                return color(d[i].animal);
            }); //fills with color according to d3.scale.category10()

        //Appends the scaled rectangles
        layer.selectAll("rect")
            .data(function(d) {
                return d;
            })
            .enter().append("rect")
            .attr("x", function(d, i) {
                return xScale(d.x);
            })
            .attr("y", function(d) {
                return yScale(d.y + d.y0); })
            .attr("height", function(d) {
                return yScale(d.y0) - yScale(d.y + d.y0); })
            .attr("width", xScale.rangeBand() - 1)
            .on("mouseover", function(d){
                //Get this bar's x/y values, then augment for the tooltip
                var xPosition = parseFloat(d3.select(this).attr("x")) + xScale.rangeBand() / 2;
                var yPosition = parseFloat(d3.select(this).attr("y")) + 14;

                //Update the tooltip position and value
                d3.select("#tooltip")
                  .style("left", xPosition + "px")
                  .style("top", yPosition + "px")
                  .select("#value")
                    .text(d.y);

                d3.select("#title")
                    .text(d.animal)

                //Show the tooltip
                d3.select("#tooltip").classed("hidden", false);
            })
            .on("mouseout", function() {
                //Hide the tooltip
                d3.select("#tooltip").classed("hidden", true);
            });

        //appends the xAxis
        svg.append("g")
            .attr("class", "axis axis--x")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);
        //appends the yAxis
        svg.append("g")
            .attr("class", "axis axis--y")
            .attr("transform", "translate(" + width + ",0)")
            .call(yAxis);

        // creates the legend in the upper-right corner
        var legend = svg.selectAll(".legend")
            .data(color.domain().slice().reverse())
            .enter().append("g")
            .attr("class", "legend")
            .attr("transform", function(d, i) { return "translate(200," + i * 20 + ")"; });

        legend.append("rect")
            .attr("x", width - 18)
            .attr("width", 18)
            .attr("height", 18)
            .style("fill", color);

        legend.append("text")
            .attr("x", width - 24)
            .attr("y", 9)
            .attr("dy", ".35em")
            .style("text-anchor", "end")
            .text(function(d) { return d; });
    });
    //Accessor function that converts the amount sold that was parsed from the CSV from a String to a Number
    function type(d) {
        var filteredKeys = d3.keys(d).filter(function(key) {
            return key !== "Month"; });
        filteredKeys.forEach(function(month) {
            d[month] = +d[month];
        });
        return d;
    }

});
<|endoftext|>