<commit_before>/*global require */
/* jshint -W106 */

'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', 'views/clusterdropdown', 'helpers/animation', 'views/graphwall-view', 'helpers/graph-utils', 'statemachine', 'marionette', 'bootstrap'], function($, _, Backbone, humanize, views, models, configloader, Poller, Generate, Collection, UserDropDown, ClusterDropDown, animation, GraphWall, helpers, StateMachine) {
    /* Default Configuration */
    var config = {
        offline: true,
        'delta-osd-api': 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);
    });
    /* 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 Backbone.Marionette.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: {
                    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);
        });
        App.vent.listenTo(App.vent, 'navigate:graph', function(host) {
            appRouter.navigate('graph/' + host, {
                trigger: true
            });
        });
        /* Demo Code */

        /* Widget Setup */
        var gaugesLayout = new views.GaugesLayout({
            el: '.gauges'
        });
        gaugesLayout.render();
        var healthView = new views.HealthView({
            App: App,
            model: new models.HealthModel({})
        });
        gaugesLayout.health.show(healthView);
        var gauge = new views.UsageView({
            App: App,
            model: new models.UsageModel({}),
            title: 'Usage'
        });
        gauge.listenTo(gauge, 'item:postrender', function() {
            App.vent.trigger('updateTotals');
        });

        var statusView = new views.StatusView({
            App: App,
            model: new models.StatusModel({})
        });
        gaugesLayout.status.show(statusView);

        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);
        });

        _.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',
            'about_a_month_ago': '1M',
            'months_ago': 'M',
            'a_year_ago': '1y',
            'years_ago': 'y'
        });
        views.NotificationCardView.view.setElement($('.notifications')).render();
        views.NotificationCardView.collection.add(
        [{
            title: 'OSD',
            message: 'OSD.100 has stopped responding',
            timestamp: humanize.time() - 24 * 60 * 60,
            priority: 2
        }, {
            title: 'Processes',
            message: 'MDS 192.168.20.2 is online',
            timestamp: humanize.time() - 60 * 60,
            priority: 0
        }, {
            title: 'Processes',
            message: 'OSD.10 has stopped responding',
            timestamp: humanize.time() - 60,
            priority: 2
        }, {
            title: 'Processes',
            message: 'MDS 192.168.20.2 has become unreachable',
            timestamp: humanize.time(),
            priority: 1
        }]);
        /* 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 poller = new Poller({
                App: App,
                cluster: cluster.get('id')
            });
            var graphWall = new GraphWall({
                App: App,
                graphiteHost: 'mira022.front.sepia.ceph.com:8080'
            });

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

            var toWorkBenchAnimation = animation.single('toWorkBenchAnim');
            App.onentergraphmode = function( /*event, from, to, host, osd */ ) {
                $('.row').css('visibility', 'hidden');
                graphWall.render();
                $('.container').append(graphWall.$el);
            };
            App.ongraph = function(event, from, to, host, osd) {
                console.log('ongraph>> host: ' + host + ' osd: ' + osd);
                graphWall.hideGraphs();
                if (host === 'all') {
                    graphWall.populateAll('CPU Load for Cluster', graphWall.makeHostUrls(graphWall.makeCPUGraphUrl));
                } else {
                    var hosts = App.ReqRes.request('get:hosts');
                    if (_.contains(hosts, host)) {
                        graphWall.populateAll('Host Graphs for ' + host, graphWall.makeHostGraphUrl(host));
                    }
                }
            };
            App.onleavegraphmode = function() {
                graphWall.close();
                $('.row').css('visibility', 'visible');
            };
            App.onentervizmode = function(event, from) {
                var d = $.Deferred();
                var $body = $('body');
                var vent = App.vent;
                if (from === 'dashmode') {
                    vent.trigger('gauges:disappear', function() {
                        d.resolve();
                    });
                } else {
                    d.resolve();
                }

                d.promise().then(function() {
                    $body.addClass('workbench-mode');
                    toWorkBenchAnimation($body);
                    vent.trigger('viz:fullscreen', function() {
                        vent.trigger('gauges:collapse');
                    });
                });
            };
            var toDashboardAnimation = animation.single('toDashboardAnim');
            App.onleavevizmode = function(event, from, to) {
                var $body = $('body');
                var vent = App.vent;
                $body.removeClass('workbench-mode');
                var d = $.Deferred();
                if (to === 'dashmode') {
                    toDashboardAnimation($body).then(function() {
                        vent.trigger('viz:dashboard', function() {
                            d.resolve();
                        });
                    });

                } else {
                    vent.trigger('viz:dashboard', function() {
                        d.resolve();
                    });
                }
                d.promise().then(function() {
                    vent.trigger('gauges:expand', function() {
                        vent.trigger('gauges:reappear');
                    });
                });
            };
            App.onenterdashmode = function() {};

            App.onleavedashmode = function() {};

            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);
            });

            appRouter.navigate('dashboard');

            App.fsm = StateMachine.create({
                initial: 'dashmode',
                events: [{
                    name: 'dashboard',
                    from: ['vizmode', 'graphmode'],
                    to: 'dashmode'
                }, {
                    name: 'viz',
                    from: ['dashmode', 'graphmode'],
                    to: 'vizmode'
                }, {
                    name: 'graph',
                    from: ['dashmode', 'vizmode', 'graphmode'],
                    to: 'graphmode'
                }],
                callbacks: {
                    onentervizmode: App.onentervizmode,
                    onleavevizmode: App.onleavevizmode,
                    onentergraphmode: App.onentergraphmode,
                    onleavegraphmode: App.onleavegraphmode,
                    onenterdashmode: App.onenterdashmode,
                    onleavedashmode: App.onleavedashmode,
                    ongraph: App.ongraph
                },
            });

            _.bindAll(App.fsm);

            App.listenTo(App.vent, 'app:fullscreen', function() {
                appRouter.navigate('workbench', {
                    trigger: true
                });
            });
            App.listenTo(App.vent, 'app:dashboard', function() {
                appRouter.navigate('dashboard', {
                    trigger: true
                });
            });
            App.listenTo(App.vent, 'app:graph', function() {
                appRouter.navigate('graph/all', {
                    trigger: true
                });
            });

            // Global Exports
            window.inktank = {
                App: App,
                Router: appRouter,
                ClusterMenu: clusterMenu,
                Gauge: gauge,
                Gauges: gaugesLayout,
                GraphWallView: graphWall,
                HealthView: healthView,
                Poller: poller,
                StatusView: statusView,
                UserMenu: userMenu,
                Viz: viz,
                models: models,
                helpers: helpers
            };
        });
        /* Defer Visualization startup to after loading the cluster metadata */
    });

    Backbone.history.start();

});
<commit_msg>Fix up navigate<commit_after>/*global require */
/* jshint -W106 */

'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', 'views/clusterdropdown', 'helpers/animation', 'views/graphwall-view', 'helpers/graph-utils', 'statemachine', 'marionette', 'bootstrap'], function($, _, Backbone, humanize, views, models, configloader, Poller, Generate, Collection, UserDropDown, ClusterDropDown, animation, GraphWall, helpers, StateMachine) {
    /* Default Configuration */
    var config = {
        offline: true,
        'delta-osd-api': 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);
    });
    /* 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 Backbone.Marionette.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: {
                    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);
        });
        App.vent.listenTo(App.vent, 'navigate:graph', function(host) {
            appRouter.navigate('graph/' + host);
        });
        /* Demo Code */

        /* Widget Setup */
        var gaugesLayout = new views.GaugesLayout({
            el: '.gauges'
        });
        gaugesLayout.render();
        var healthView = new views.HealthView({
            App: App,
            model: new models.HealthModel({})
        });
        gaugesLayout.health.show(healthView);
        var gauge = new views.UsageView({
            App: App,
            model: new models.UsageModel({}),
            title: 'Usage'
        });
        gauge.listenTo(gauge, 'item:postrender', function() {
            App.vent.trigger('updateTotals');
        });

        var statusView = new views.StatusView({
            App: App,
            model: new models.StatusModel({})
        });
        gaugesLayout.status.show(statusView);

        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);
        });

        _.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',
            'about_a_month_ago': '1M',
            'months_ago': 'M',
            'a_year_ago': '1y',
            'years_ago': 'y'
        });
        views.NotificationCardView.view.setElement($('.notifications')).render();
        views.NotificationCardView.collection.add(
        [{
            title: 'OSD',
            message: 'OSD.100 has stopped responding',
            timestamp: humanize.time() - 24 * 60 * 60,
            priority: 2
        }, {
            title: 'Processes',
            message: 'MDS 192.168.20.2 is online',
            timestamp: humanize.time() - 60 * 60,
            priority: 0
        }, {
            title: 'Processes',
            message: 'OSD.10 has stopped responding',
            timestamp: humanize.time() - 60,
            priority: 2
        }, {
            title: 'Processes',
            message: 'MDS 192.168.20.2 has become unreachable',
            timestamp: humanize.time(),
            priority: 1
        }]);
        /* 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 poller = new Poller({
                App: App,
                cluster: cluster.get('id')
            });
            var graphWall = new GraphWall({
                App: App,
                graphiteHost: 'mira022.front.sepia.ceph.com:8080'
            });

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

            var toWorkBenchAnimation = animation.single('toWorkBenchAnim');
            App.onentergraphmode = function( /*event, from, to, host, osd */ ) {
                $('.row').css('visibility', 'hidden');
                graphWall.render();
                $('.container').append(graphWall.$el);
            };
            App.ongraph = function(event, from, to, host, osd) {
                console.log('ongraph>> host: ' + host + ' osd: ' + osd);
                graphWall.hideGraphs();
                if (host === 'all') {
                    graphWall.populateAll('CPU Load for Cluster', graphWall.makeHostUrls(graphWall.makeCPUGraphUrl));
                } else {
                    var hosts = App.ReqRes.request('get:hosts');
                    if (_.contains(hosts, host)) {
                        graphWall.populateAll('Host Graphs for ' + host, graphWall.makeHostGraphUrl(host));
                    }
                }
            };
            App.onleavegraphmode = function() {
                graphWall.close();
                $('.row').css('visibility', 'visible');
            };
            App.onentervizmode = function(event, from) {
                var d = $.Deferred();
                var $body = $('body');
                var vent = App.vent;
                if (from === 'dashmode') {
                    vent.trigger('gauges:disappear', function() {
                        d.resolve();
                    });
                } else {
                    d.resolve();
                }

                d.promise().then(function() {
                    $body.addClass('workbench-mode');
                    toWorkBenchAnimation($body);
                    vent.trigger('viz:fullscreen', function() {
                        vent.trigger('gauges:collapse');
                    });
                });
            };
            var toDashboardAnimation = animation.single('toDashboardAnim');
            App.onleavevizmode = function(event, from, to) {
                var $body = $('body');
                var vent = App.vent;
                $body.removeClass('workbench-mode');
                var d = $.Deferred();
                if (to === 'dashmode') {
                    toDashboardAnimation($body).then(function() {
                        vent.trigger('viz:dashboard', function() {
                            d.resolve();
                        });
                    });

                } else {
                    vent.trigger('viz:dashboard', function() {
                        d.resolve();
                    });
                }
                d.promise().then(function() {
                    vent.trigger('gauges:expand', function() {
                        vent.trigger('gauges:reappear');
                    });
                });
            };
            App.onenterdashmode = function() {};

            App.onleavedashmode = function() {};

            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);
            });

            appRouter.navigate('dashboard');

            App.fsm = StateMachine.create({
                initial: 'dashmode',
                events: [{
                    name: 'dashboard',
                    from: ['vizmode', 'graphmode'],
                    to: 'dashmode'
                }, {
                    name: 'viz',
                    from: ['dashmode', 'graphmode'],
                    to: 'vizmode'
                }, {
                    name: 'graph',
                    from: ['dashmode', 'vizmode', 'graphmode'],
                    to: 'graphmode'
                }],
                callbacks: {
                    onentervizmode: App.onentervizmode,
                    onleavevizmode: App.onleavevizmode,
                    onentergraphmode: App.onentergraphmode,
                    onleavegraphmode: App.onleavegraphmode,
                    onenterdashmode: App.onenterdashmode,
                    onleavedashmode: App.onleavedashmode,
                    ongraph: App.ongraph
                },
            });

            _.bindAll(App.fsm);

            App.listenTo(App.vent, 'app:fullscreen', function() {
                appRouter.navigate('workbench', {
                    trigger: true
                });
            });
            App.listenTo(App.vent, 'app:dashboard', function() {
                appRouter.navigate('dashboard', {
                    trigger: true
                });
            });
            App.listenTo(App.vent, 'app:graph', function() {
                appRouter.navigate('graph/all', {
                    trigger: true
                });
            });

            // Global Exports
            window.inktank = {
                App: App,
                Router: appRouter,
                ClusterMenu: clusterMenu,
                Gauge: gauge,
                Gauges: gaugesLayout,
                GraphWallView: graphWall,
                HealthView: healthView,
                Poller: poller,
                StatusView: statusView,
                UserMenu: userMenu,
                Viz: viz,
                models: models,
                helpers: helpers
            };
        });
        /* Defer Visualization startup to after loading the cluster metadata */
    });

    Backbone.history.start();

});
<|endoftext|>


<commit_before>/*
    json.js
    2006-04-28

    This file adds these methods to JavaScript:

        object.toJSONString()

            This method produces a JSON text from an object. The
            object must not contain any cyclical references.

        array.toJSONString()

            This method produces a JSON text from an array. The
            array must not contain any cyclical references.

        string.parseJSON()

            This method parses a JSON text to produce an object or
            array. It will return false if there is an error.
*/
(function () {
    var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        s = {
            array: function (x) {
                var a = ['['], b, f, i, l = x.length, v;
                for (i = 0; i < l; i += 1) {
                    v = x[i];
                    f = s[typeof v];
                    if (f) {
                        v = f(v);
                        if (typeof v == 'string') {
                            if (b) {
                                a[a.length] = ',';
                            }
                            a[a.length] = v;
                            b = true;
                        }
                    }
                }
                a[a.length] = ']';
                return a.join('');
            },
            'boolean': function (x) {
                return String(x);
            },
            'null': function (x) {
                return "null";
            },
            number: function (x) {
                return isFinite(x) ? String(x) : 'null';
            },
            object: function (x) {
                if (x) {
                    if (x instanceof Array) {
                        return s.array(x);
                    }
                    var a = ['{'], b, f, i, v;
                    for (i in x) {
                        v = x[i];
                        f = s[typeof v];
                        if (f) {
                            v = f(v);
                            if (typeof v == 'string') {
                                if (b) {
                                    a[a.length] = ',';
                                }
                                a.push(s.string(i), ':', v);
                                b = true;
                            }
                        }
                    }
                    a[a.length] = '}';
                    return a.join('');
                }
                return 'null';
            },
            string: function (x) {
                if (/["\\\x00-\x1f]/.test(x)) {
                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                        var c = m[b];
                        if (c) {
                            return c;
                        }
                        c = b.charCodeAt();
                        return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
                    });
                }
                return '"' + x + '"';
            }
        };

    Object.prototype.toJSONString = function () {
        return s.object(this);
    };

    Array.prototype.toJSONString = function () {
        return s.array(this);
    };
})();

String.prototype.parseJSON = function () {
    try {
        return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                this.replace(/"(\\.|[^"\\])*"/g, ''))) &&
            eval('(' + this + ')');
    } catch (e) {
        return false;
    }
};
<commit_msg>switched from object oriented methods to static ones<commit_after>/*
    json.js
    2006-04-28

    This file adds these methods to JavaScript:

        object.toJSONString()

            This method produces a JSON text from an object. The
            object must not contain any cyclical references.

        array.toJSONString()

            This method produces a JSON text from an array. The
            array must not contain any cyclical references.

        string.parseJSON()

            This method parses a JSON text to produce an object or
            array. It will return false if there is an error.
*/
function JSON() {}
JSON.toString = function (obj) {
    var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        s = {
            array: function (x) {
                var a = ['['], b, f, i, l = x.length, v;
                for (i = 0; i < l; i += 1) {
                    v = x[i];
                    f = s[typeof v];
                    if (f) {
                        v = f(v);
                        if (typeof v == 'string') {
                            if (b) {
                                a[a.length] = ',';
                            }
                            a[a.length] = v;
                            b = true;
                        }
                    }
                }
                a[a.length] = ']';
                return a.join('');
            },
            'boolean': function (x) {
                return String(x);
            },
            'null': function (x) {
                return "null";
            },
            number: function (x) {
                return isFinite(x) ? String(x) : 'null';
            },
            object: function (x) {
                if (x) {
                    if (x instanceof Array) {
                        return s.array(x);
                    }
                    var a = ['{'], b, f, i, v;
                    for (i in x) {
                        v = x[i];
                        f = s[typeof v];
                        if (f) {
                            v = f(v);
                            if (typeof v == 'string') {
                                if (b) {
                                    a[a.length] = ',';
                                }
                                a.push(s.string(i), ':', v);
                                b = true;
                            }
                        }
                    }
                    a[a.length] = '}';
                    return a.join('');
                }
                return 'null';
            },
            string: function (x) {
                if (/["\\\x00-\x1f]/.test(x)) {
                    x = x.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                        var c = m[b];
                        if (c) {
                            return c;
                        }
                        c = b.charCodeAt();
                        return '\\u00' +
                            Math.floor(c / 16).toString(16) +
                            (c % 16).toString(16);
                    });
                }
                return '"' + x + '"';
            }
        };

switch (typeof(obj)) {
 case 'object':
        return s.object(obj);
 case 'array':
	 return s.array(obj);

}
};

JSON.parse = function (str) {
    try {
        return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
                str.replace(/"(\\.|[^"\\])*"/g, ''))) &&
            eval('(' + str + ')');
    } catch (e) {
        return false;
    }
};
<|endoftext|>


<commit_before>if (typeof web3 !== 'undefined') {
	web3 = new Web3(web3.currentProvider);
} else {
	// set the provider you want from Web3.providers
	web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

var TicTacToeRules;
var TicTacToeAdjudicator;
var TicTacToeLockedState;

function sign(signingAddress, hash) {
	var signature = web3.eth.sign(signingAddress, hash);
	return [
		27 + parseInt(signature.slice(130, 132), 16),
		signature.slice(0, 66),
		'0x' + signature.slice(66, 130)
	];
}

function createTicTacToeRules(form) {
	TicTacToeRules = web3.eth.contract(TIC_TAC_TOE_RULES_INTERFACE).new(
		web3.eth.accounts[form.addressX.value],
		web3.eth.accounts[form.addressO.value],
		form.timeout.value,
		{
			from: web3.eth.accounts[$('#sender').val()],
			data: CONTRACT_BYTECODE,
			gas: 4700000
		}, function (e, contract) {
			if (typeof contract.address !== 'undefined') {
				TicTacToeAdjudicator = web3.eth.contract(TIC_TAC_TOE_ADJUDICATOR_INTERFACE).at(contract.getAdjudicatorAddress());
				TicTacToeLockedState = web3.eth.contract(TIC_TAC_TOE_LOCKED_STATE_INTERFACE).at(TicTacToeAdjudicator.getLockedStateAddress());
				$('#existingContract input[name=address]').val(contract.address);
				localStorage.setItem('address', contract.address);
				alert('Contract has been mined at: ' +contract.address);
			} else {
				alert('Contract transaction: ' +contract.transactionHash);
			}
		}
	);
}

function attachToContract(form) {
	TicTacToeRules = web3.eth.contract(TIC_TAC_TOE_RULES_INTERFACE).at(form.address.value);
	TicTacToeAdjudicator = web3.eth.contract(TIC_TAC_TOE_ADJUDICATOR_INTERFACE).at(TicTacToeRules.getAdjudicatorAddress());
	TicTacToeLockedState = web3.eth.contract(TIC_TAC_TOE_LOCKED_STATE_INTERFACE).at(TicTacToeAdjudicator.getLockedStateAddress());
	localStorage.setItem('address', form.address.value);
	alert("Attached to contract!");
}

function signState(form) {
	var state = ('00' + (
			parseInt(form.winner.value)
			| (form.adjudicationDepositX.checked ? parseInt(form.adjudicationDepositX.value) : 0)
			| (form.adjudicationDepositO.checked ? parseInt(form.adjudicationDepositO.value) : 0)
			| (form.disconnectDepositX.checked ? parseInt(form.disconnectDepositX.value) : 0)
			| (form.disconnectDepositO.checked ? parseInt(form.disconnectDepositO.value) : 0)
			| (form.immutable.checked ? parseInt(form.immutable.value) : 0)
		).toString(16)).slice(-2);

	var nonce = '';
	for (var i = 0; i < 64; i++) {
		nonce += '0';
	}
	nonce += parseInt(form.nonce.value).toString(16);

	var toBeHashed = '0x'
		+state
		+nonce.slice(-64)
		+TicTacToeRules.address.slice(2);

	var signature = sign(web3.eth.accounts[$('#sender').val()], web3.sha3(toBeHashed, {encoding: 'hex'}));

	$('#stateTable').append('
'
			+ web3.eth.accounts[$('#sender').val()]
			+ '	'
			+ '0x' +state
			+ '	'
			+ form.nonce.value
			+ '	'
			+ signature[0]
			+ '	'
			+ signature[1]
			+ '	'
			+ signature[2]
		);
}

function signBoard(form) {
	var board = '';

	var boardElements = $(form).find('.boardItem');
	for (var i = 0; i < boardElements.length; i++) {
		board += ('00' + parseInt(boardElements[i].value).toString(16)).slice(-2);
	}
	board += ('00' + parseInt(form.lastPlayer.value).toString(16)).slice(-2);
	board.slice(-20);

	var nonce = '';
	for (var i = 0; i < 64; i++) {
		nonce += '0';
	}
	nonce += parseInt(form.nonce.value).toString(16);

	var toBeHashed = '0x'
		+board
		+nonce.slice(-64)
		+TicTacToeRules.address.slice(2);

	var signature = sign(web3.eth.accounts[$('#sender').val()], web3.sha3(toBeHashed, {encoding: 'hex'}));

	$('#boardTable').append('
'
			+ web3.eth.accounts[$('#sender').val()]
			+ '	'
			+ '0x' +board
			+ '	'
			+ form.nonce.value
			+ '	'
			+ signature[0]
			+ '	'
			+ signature[1]
			+ '	'
			+ signature[2]
		);
}

function sendState(form) {
	console.log(form);
	TicTacToeRules.sendState.sendTransaction(
			form.state.value,
			parseInt(form.nonce.value),
			parseInt(form.vX.value),
			form.rX.value,
			form.sX.value,
			parseInt(form.vO.value),
			form.rO.value,
			form.sO.value,
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function sendBoard(form) {
	TicTacToeRules.sendBoard.sendTransaction(
			form.board.value,
			parseInt(form.nonce.value),
			parseInt(form.v.value),
			form.r.value,
			form.s.value,
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function badBoardSent(form) {
	TicTacToeRules.badBoardSent.sendTransaction(
			form.oldBoard.value,
			parseInt(form.oldNonce.value),
			parseInt(form.oldV.value),
			form.oldR.value,
			form.oldS.value,
			form.newBoard.value,
			parseInt(form.newNonce.value),
			parseInt(form.newV.value),
			form.newR.value,
			form.newS.value,
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function checkIn(form) {
	TicTacToeRules.checkIn.sendTransaction(
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
}

function getState(form) {
	alert(TicTacToeAdjudicator.getStateAt(0));
}

function getNonce(form) {
	alert(TicTacToeAdjudicator.getNonce());
}

function giveConsent(form) {
	var nonce = '';
	for (var i = 0; i < 64; i++) {
		nonce += '0';
	}
	nonce += parseInt(form.nonce.value).toString(16);

	var toBeHashed = '0x'
		+nonce.slice(-64)
		+TicTacToeRules.address.slice(2);

	var signature = sign(web3.eth.accounts[$('#sender').val()], web3.sha3(toBeHashed, {encoding: 'hex'}));

	TicTacToeAdjudicator.giveConsent.sendTransaction(
			signature[0],
			signature[1],
			signature[2],
			{
				from: web3.eth.accounts[$('#sender').val()]
			}
		);

	$('#consentTable').append('
'
			+ web3.eth.accounts[$('#sender').val()]
			+ '	'
			+ form.nonce.value
			+ '	'
			+ signature[0]
			+ '	'
			+ signature[1]
			+ '	'
			+ signature[2]
		);
}

function finaliseChannel(form) {
	TicTacToeAdjudicator.finaliseChannel.sendTransaction({
			from: web3.eth.accounts[$('#sender').val()]
	});
	alert('Call sent to blockchain.');
}

function depositFunds(form) {
	TicTacToeLockedState.deposit.sendTransaction(
			parseInt(form.account.value),
			{
				from: web3.eth.accounts[$('#sender').val()],
				value: form.amount.value
			}
		);
	alert('Call sent to blockchain.');
}

function getBalance(form) {
	alert(TicTacToeLockedState.getBalance(parseInt(form.account.value)));
}

$(document).ready(function () {
	// Populate address lists with addresses from web3.eth
	for (var i = 0; i < web3.eth.accounts.length; i++) {
		$('.addresses').append("<option value=\"" +i +"\">" +web3.eth.accounts[i] +"</option>");
	}

	// Persistent state
	if (localStorage.getItem('address')) {
		$('#existingContract input[name=address]').val(localStorage.getItem('address'));
	}

});
<commit_msg>Give user notice when Check In is pressed<commit_after>if (typeof web3 !== 'undefined') {
	web3 = new Web3(web3.currentProvider);
} else {
	// set the provider you want from Web3.providers
	web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}

var TicTacToeRules;
var TicTacToeAdjudicator;
var TicTacToeLockedState;

function sign(signingAddress, hash) {
	var signature = web3.eth.sign(signingAddress, hash);
	return [
		27 + parseInt(signature.slice(130, 132), 16),
		signature.slice(0, 66),
		'0x' + signature.slice(66, 130)
	];
}

function createTicTacToeRules(form) {
	TicTacToeRules = web3.eth.contract(TIC_TAC_TOE_RULES_INTERFACE).new(
		web3.eth.accounts[form.addressX.value],
		web3.eth.accounts[form.addressO.value],
		form.timeout.value,
		{
			from: web3.eth.accounts[$('#sender').val()],
			data: CONTRACT_BYTECODE,
			gas: 4700000
		}, function (e, contract) {
			if (typeof contract.address !== 'undefined') {
				TicTacToeAdjudicator = web3.eth.contract(TIC_TAC_TOE_ADJUDICATOR_INTERFACE).at(contract.getAdjudicatorAddress());
				TicTacToeLockedState = web3.eth.contract(TIC_TAC_TOE_LOCKED_STATE_INTERFACE).at(TicTacToeAdjudicator.getLockedStateAddress());
				$('#existingContract input[name=address]').val(contract.address);
				localStorage.setItem('address', contract.address);
				alert('Contract has been mined at: ' +contract.address);
			} else {
				alert('Contract transaction: ' +contract.transactionHash);
			}
		}
	);
}

function attachToContract(form) {
	TicTacToeRules = web3.eth.contract(TIC_TAC_TOE_RULES_INTERFACE).at(form.address.value);
	TicTacToeAdjudicator = web3.eth.contract(TIC_TAC_TOE_ADJUDICATOR_INTERFACE).at(TicTacToeRules.getAdjudicatorAddress());
	TicTacToeLockedState = web3.eth.contract(TIC_TAC_TOE_LOCKED_STATE_INTERFACE).at(TicTacToeAdjudicator.getLockedStateAddress());
	localStorage.setItem('address', form.address.value);
	alert("Attached to contract!");
}

function signState(form) {
	var state = ('00' + (
			parseInt(form.winner.value)
			| (form.adjudicationDepositX.checked ? parseInt(form.adjudicationDepositX.value) : 0)
			| (form.adjudicationDepositO.checked ? parseInt(form.adjudicationDepositO.value) : 0)
			| (form.disconnectDepositX.checked ? parseInt(form.disconnectDepositX.value) : 0)
			| (form.disconnectDepositO.checked ? parseInt(form.disconnectDepositO.value) : 0)
			| (form.immutable.checked ? parseInt(form.immutable.value) : 0)
		).toString(16)).slice(-2);

	var nonce = '';
	for (var i = 0; i < 64; i++) {
		nonce += '0';
	}
	nonce += parseInt(form.nonce.value).toString(16);

	var toBeHashed = '0x'
		+state
		+nonce.slice(-64)
		+TicTacToeRules.address.slice(2);

	var signature = sign(web3.eth.accounts[$('#sender').val()], web3.sha3(toBeHashed, {encoding: 'hex'}));

	$('#stateTable').append('
'
			+ web3.eth.accounts[$('#sender').val()]
			+ '	'
			+ '0x' +state
			+ '	'
			+ form.nonce.value
			+ '	'
			+ signature[0]
			+ '	'
			+ signature[1]
			+ '	'
			+ signature[2]
		);
}

function signBoard(form) {
	var board = '';

	var boardElements = $(form).find('.boardItem');
	for (var i = 0; i < boardElements.length; i++) {
		board += ('00' + parseInt(boardElements[i].value).toString(16)).slice(-2);
	}
	board += ('00' + parseInt(form.lastPlayer.value).toString(16)).slice(-2);
	board.slice(-20);

	var nonce = '';
	for (var i = 0; i < 64; i++) {
		nonce += '0';
	}
	nonce += parseInt(form.nonce.value).toString(16);

	var toBeHashed = '0x'
		+board
		+nonce.slice(-64)
		+TicTacToeRules.address.slice(2);

	var signature = sign(web3.eth.accounts[$('#sender').val()], web3.sha3(toBeHashed, {encoding: 'hex'}));

	$('#boardTable').append('
'
			+ web3.eth.accounts[$('#sender').val()]
			+ '	'
			+ '0x' +board
			+ '	'
			+ form.nonce.value
			+ '	'
			+ signature[0]
			+ '	'
			+ signature[1]
			+ '	'
			+ signature[2]
		);
}

function sendState(form) {
	console.log(form);
	TicTacToeRules.sendState.sendTransaction(
			form.state.value,
			parseInt(form.nonce.value),
			parseInt(form.vX.value),
			form.rX.value,
			form.sX.value,
			parseInt(form.vO.value),
			form.rO.value,
			form.sO.value,
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function sendBoard(form) {
	TicTacToeRules.sendBoard.sendTransaction(
			form.board.value,
			parseInt(form.nonce.value),
			parseInt(form.v.value),
			form.r.value,
			form.s.value,
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function badBoardSent(form) {
	TicTacToeRules.badBoardSent.sendTransaction(
			form.oldBoard.value,
			parseInt(form.oldNonce.value),
			parseInt(form.oldV.value),
			form.oldR.value,
			form.oldS.value,
			form.newBoard.value,
			parseInt(form.newNonce.value),
			parseInt(form.newV.value),
			form.newR.value,
			form.newS.value,
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function checkIn(form) {
	TicTacToeRules.checkIn.sendTransaction(
			{
				from: web3.eth.accounts[$('#sender').val()],
				gas: 4700000
			}
		);
		alert('Call sent to blockchain.');
}

function getState(form) {
	alert(TicTacToeAdjudicator.getStateAt(0));
}

function getNonce(form) {
	alert(TicTacToeAdjudicator.getNonce());
}

function giveConsent(form) {
	var nonce = '';
	for (var i = 0; i < 64; i++) {
		nonce += '0';
	}
	nonce += parseInt(form.nonce.value).toString(16);

	var toBeHashed = '0x'
		+nonce.slice(-64)
		+TicTacToeRules.address.slice(2);

	var signature = sign(web3.eth.accounts[$('#sender').val()], web3.sha3(toBeHashed, {encoding: 'hex'}));

	TicTacToeAdjudicator.giveConsent.sendTransaction(
			signature[0],
			signature[1],
			signature[2],
			{
				from: web3.eth.accounts[$('#sender').val()]
			}
		);

	$('#consentTable').append('
'
			+ web3.eth.accounts[$('#sender').val()]
			+ '	'
			+ form.nonce.value
			+ '	'
			+ signature[0]
			+ '	'
			+ signature[1]
			+ '	'
			+ signature[2]
		);
}

function finaliseChannel(form) {
	TicTacToeAdjudicator.finaliseChannel.sendTransaction({
			from: web3.eth.accounts[$('#sender').val()]
	});
	alert('Call sent to blockchain.');
}

function depositFunds(form) {
	TicTacToeLockedState.deposit.sendTransaction(
			parseInt(form.account.value),
			{
				from: web3.eth.accounts[$('#sender').val()],
				value: form.amount.value
			}
		);
	alert('Call sent to blockchain.');
}

function getBalance(form) {
	alert(TicTacToeLockedState.getBalance(parseInt(form.account.value)));
}

$(document).ready(function () {
	// Populate address lists with addresses from web3.eth
	for (var i = 0; i < web3.eth.accounts.length; i++) {
		$('.addresses').append("<option value=\"" +i +"\">" +web3.eth.accounts[i] +"</option>");
	}

	// Persistent state
	if (localStorage.getItem('address')) {
		$('#existingContract input[name=address]').val(localStorage.getItem('address'));
	}

});
<|endoftext|>


<commit_before>/**
 * Created by Alexey Ostrovsky.
 * Date: 21.12.13
 * Time: 14:06
 */
var nStore = require('nstore');
nStore = nStore.extend(require('nstore/query')());

/* TEAMS */
exports.addTeam = function(name, cb) {
    var db = nStore.new('db/teams.db', function () {

        db.save(null, {name: name}, cb);
    });
};

exports.removeTeam = function(id, cb) {
    var db = nStore.new('db/teams.db', function () {

        db.remove(id, cb);
    });
};

exports.getTeams = function(cb) {
    var db = nStore.new('db/teams.db', function () {
        db.all(cb);
    });
};
/* /TEAMS */

/* EVENTS */
exports.addEvent = function(data, cb, id) {
    // id - optional
    id = id || null;

    var db = nStore.new('db/events.db', function () {

        db.save(id, data, cb);
    });
};

exports.removeEvent = function(id, cb) {
    var db = nStore.new('db/events.db', function () {

        db.remove(id, cb);
    });
};

exports.getEvent = function(id, cb) {
    var db = nStore.new('db/events.db', function () {

        db.get(id, cb);
    });
};

exports.getEvents = function(cb) {
    var db = nStore.new('db/events.db', function () {
        db.all(cb);
    });
};
/* /EVENTS */<commit_msg>DB module refactoring<commit_after>/**
 * Created by Alexey Ostrovsky.
 * Date: 21.12.13
 * Time: 14:06
 */
var nStore = require('nstore');
nStore = nStore.extend(require('nstore/query')());

var dbAdress = {
    teams: "db/teams.db",
    events: "db/events.db"
};

/* TEAMS */
exports.addTeam = function(name, cb) {
    var db = nStore.new(dbAdress.teams, function () {

        db.save(null, {name: name}, cb);
    });
};

exports.removeTeam = function(id, cb) {
    var db = nStore.new(dbAdress.teams, function () {

        db.remove(id, cb);
    });
};

exports.getTeams = function(cb) {
    var db = nStore.new(dbAdress.teams, function () {
        db.all(cb);
    });
};
/* /TEAMS */

/* EVENTS */
exports.addEvent = function(data, cb, id) {
    // id - optional
    id = id || null;

    var db = nStore.new(dbAdress.events, function () {

        db.save(id, data, cb);
    });
};

exports.removeEvent = function(id, cb) {
    var db = nStore.new(dbAdress.events, function () {

        db.remove(id, cb);
    });
};

exports.getEvent = function(id, cb) {
    var db = nStore.new(dbAdress.events, function () {

        db.get(id, cb);
    });
};

exports.getEvents = function(cb) {
    var db = nStore.new(dbAdress.events, function () {
        db.all(cb);
    });
};
/* /EVENTS */<|endoftext|>


<commit_before>/* Blob.js
 * A Blob implementation.
 * 2013-06-20
 *
 * By Eli Grey, http://eligrey.com
 * By Devin Samarin, https://github.com/eboyjr
 * License: X11/MIT
 *   See LICENSE.md
 */

/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
  plusplus: true */

/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */

if (typeof Blob !== "function" || typeof URL === "undefined")
if (typeof Blob === "function" && typeof webkitURL !== "undefined") var URL = webkitURL;
else var Blob = (function (view) {
	"use strict";

	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
		var
			  get_class = function(object) {
				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
			}
			, FakeBlobBuilder = function BlobBuilder() {
				this.data = [];
			}
			, FakeBlob = function Blob(data, type, encoding) {
				this.data = data;
				this.size = data.length;
				this.type = type;
				this.encoding = encoding;
			}
			, FBB_proto = FakeBlobBuilder.prototype
			, FB_proto = FakeBlob.prototype
			, FileReaderSync = view.FileReaderSync
			, FileException = function(type) {
				this.code = this[this.name = type];
			}
			, file_ex_codes = (
				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
			).split(" ")
			, file_ex_code = file_ex_codes.length
			, real_URL = view.URL || view.webkitURL || view
			, real_create_object_URL = real_URL.createObjectURL
			, real_revoke_object_URL = real_URL.revokeObjectURL
			, URL = real_URL
			, btoa = view.btoa
			, atob = view.atob
			, can_apply_typed_arrays = false
			, can_apply_typed_arrays_test = function(pass) {
				can_apply_typed_arrays = !pass;
			}

			, ArrayBuffer = view.ArrayBuffer
			, Uint8Array = view.Uint8Array
		;
		FakeBlob.fake = FB_proto.fake = true;
		while (file_ex_code--) {
			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
		}
		try {
			if (Uint8Array) {
				can_apply_typed_arrays_test.apply(0, new Uint8Array(1));
			}
		} catch (ex) {}
		if (!real_URL.createObjectURL) {
			URL = view.URL = {};
		}
		URL.createObjectURL = function(blob) {
			var
				  type = blob.type
				, data_URI_header
			;
			if (type === null) {
				type = "application/octet-stream";
			}
			if (blob instanceof FakeBlob) {
				data_URI_header = "data:" + type;
				if (blob.encoding === "base64") {
					return data_URI_header + ";base64," + blob.data;
				} else if (blob.encoding === "URI") {
					return data_URI_header + "," + decodeURIComponent(blob.data);
				} if (btoa) {
					return data_URI_header + ";base64," + btoa(blob.data);
				} else {
					return data_URI_header + "," + encodeURIComponent(blob.data);
				}
			} else if (real_create_object_URL) {
				return real_create_object_URL.call(real_URL, blob);
			}
		};
		URL.revokeObjectURL = function(object_URL) {
			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
				real_revoke_object_URL.call(real_URL, object_URL);
			}
		};
		FBB_proto.append = function(data/*, endings*/) {
			var bb = this.data;
			// decode data to a binary string
			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
				if (can_apply_typed_arrays) {
					bb.push(String.fromCharCode.apply(String, new Uint8Array(data)));
				} else {
					var
						  str = ""
						, buf = new Uint8Array(data)
						, i = 0
						, buf_len = buf.length
					;
					for (; i < buf_len; i++) {
						str += String.fromCharCode(buf[i]);
					}
				}
			} else if (get_class(data) === "Blob" || get_class(data) === "File") {
				if (FileReaderSync) {
					var fr = new FileReaderSync;
					bb.push(fr.readAsBinaryString(data));
				} else {
					// async FileReader won't work as BlobBuilder is sync
					throw new FileException("NOT_READABLE_ERR");
				}
			} else if (data instanceof FakeBlob) {
				if (data.encoding === "base64" && atob) {
					bb.push(atob(data.data));
				} else if (data.encoding === "URI") {
					bb.push(decodeURIComponent(data.data));
				} else if (data.encoding === "raw") {
					bb.push(data.data);
				}
			} else {
				if (typeof data !== "string") {
					data += ""; // convert unsupported types to strings
				}
				// decode UTF-16 to binary string
				bb.push(unescape(encodeURIComponent(data)));
			}
		};
		FBB_proto.getBlob = function(type) {
			if (!arguments.length) {
				type = null;
			}
			return new FakeBlob(this.data.join(""), type, "raw");
		};
		FBB_proto.toString = function() {
			return "[object BlobBuilder]";
		};
		FB_proto.slice = function(start, end, type) {
			var args = arguments.length;
			if (args < 3) {
				type = null;
			}
			return new FakeBlob(
				  this.data.slice(start, args > 1 ? end : this.data.length)
				, type
				, this.encoding
			);
		};
		FB_proto.toString = function() {
			return "[object Blob]";
		};
		return FakeBlobBuilder;
	}(view));

	return function Blob(blobParts, options) {
		var type = options ? (options.type || "") : "";
		var builder = new BlobBuilder();
		if (blobParts) {
			for (var i = 0, len = blobParts.length; i < len; i++) {
				builder.append(blobParts[i]);
			}
		}
		return builder.getBlob(type);
	};
}(self));
<commit_msg>Fixes #9<commit_after>/* Blob.js
 * A Blob implementation.
 * 2013-06-20
 *
 * By Eli Grey, http://eligrey.com
 * By Devin Samarin, https://github.com/eboyjr
 * License: X11/MIT
 *   See LICENSE.md
 */

/*global self, unescape */
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
  plusplus: true */

/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */

if (typeof Blob !== "function" || typeof URL === "undefined")
if (typeof Blob === "function" && typeof webkitURL !== "undefined") self.URL = webkitURL;
else var Blob = (function (view) {
	"use strict";

	var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) {
		var
			  get_class = function(object) {
				return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
			}
			, FakeBlobBuilder = function BlobBuilder() {
				this.data = [];
			}
			, FakeBlob = function Blob(data, type, encoding) {
				this.data = data;
				this.size = data.length;
				this.type = type;
				this.encoding = encoding;
			}
			, FBB_proto = FakeBlobBuilder.prototype
			, FB_proto = FakeBlob.prototype
			, FileReaderSync = view.FileReaderSync
			, FileException = function(type) {
				this.code = this[this.name = type];
			}
			, file_ex_codes = (
				  "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
				+ "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
			).split(" ")
			, file_ex_code = file_ex_codes.length
			, real_URL = view.URL || view.webkitURL || view
			, real_create_object_URL = real_URL.createObjectURL
			, real_revoke_object_URL = real_URL.revokeObjectURL
			, URL = real_URL
			, btoa = view.btoa
			, atob = view.atob
			, can_apply_typed_arrays = false
			, can_apply_typed_arrays_test = function(pass) {
				can_apply_typed_arrays = !pass;
			}

			, ArrayBuffer = view.ArrayBuffer
			, Uint8Array = view.Uint8Array
		;
		FakeBlob.fake = FB_proto.fake = true;
		while (file_ex_code--) {
			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
		}
		try {
			if (Uint8Array) {
				can_apply_typed_arrays_test.apply(0, new Uint8Array(1));
			}
		} catch (ex) {}
		if (!real_URL.createObjectURL) {
			URL = view.URL = {};
		}
		URL.createObjectURL = function(blob) {
			var
				  type = blob.type
				, data_URI_header
			;
			if (type === null) {
				type = "application/octet-stream";
			}
			if (blob instanceof FakeBlob) {
				data_URI_header = "data:" + type;
				if (blob.encoding === "base64") {
					return data_URI_header + ";base64," + blob.data;
				} else if (blob.encoding === "URI") {
					return data_URI_header + "," + decodeURIComponent(blob.data);
				} if (btoa) {
					return data_URI_header + ";base64," + btoa(blob.data);
				} else {
					return data_URI_header + "," + encodeURIComponent(blob.data);
				}
			} else if (real_create_object_URL) {
				return real_create_object_URL.call(real_URL, blob);
			}
		};
		URL.revokeObjectURL = function(object_URL) {
			if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
				real_revoke_object_URL.call(real_URL, object_URL);
			}
		};
		FBB_proto.append = function(data/*, endings*/) {
			var bb = this.data;
			// decode data to a binary string
			if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
				if (can_apply_typed_arrays) {
					bb.push(String.fromCharCode.apply(String, new Uint8Array(data)));
				} else {
					var
						  str = ""
						, buf = new Uint8Array(data)
						, i = 0
						, buf_len = buf.length
					;
					for (; i < buf_len; i++) {
						str += String.fromCharCode(buf[i]);
					}
				}
			} else if (get_class(data) === "Blob" || get_class(data) === "File") {
				if (FileReaderSync) {
					var fr = new FileReaderSync;
					bb.push(fr.readAsBinaryString(data));
				} else {
					// async FileReader won't work as BlobBuilder is sync
					throw new FileException("NOT_READABLE_ERR");
				}
			} else if (data instanceof FakeBlob) {
				if (data.encoding === "base64" && atob) {
					bb.push(atob(data.data));
				} else if (data.encoding === "URI") {
					bb.push(decodeURIComponent(data.data));
				} else if (data.encoding === "raw") {
					bb.push(data.data);
				}
			} else {
				if (typeof data !== "string") {
					data += ""; // convert unsupported types to strings
				}
				// decode UTF-16 to binary string
				bb.push(unescape(encodeURIComponent(data)));
			}
		};
		FBB_proto.getBlob = function(type) {
			if (!arguments.length) {
				type = null;
			}
			return new FakeBlob(this.data.join(""), type, "raw");
		};
		FBB_proto.toString = function() {
			return "[object BlobBuilder]";
		};
		FB_proto.slice = function(start, end, type) {
			var args = arguments.length;
			if (args < 3) {
				type = null;
			}
			return new FakeBlob(
				  this.data.slice(start, args > 1 ? end : this.data.length)
				, type
				, this.encoding
			);
		};
		FB_proto.toString = function() {
			return "[object Blob]";
		};
		return FakeBlobBuilder;
	}(view));

	return function Blob(blobParts, options) {
		var type = options ? (options.type || "") : "";
		var builder = new BlobBuilder();
		if (blobParts) {
			for (var i = 0, len = blobParts.length; i < len; i++) {
				builder.append(blobParts[i]);
			}
		}
		return builder.getBlob(type);
	};
}(self));
<|endoftext|>


<commit_before>exports.BattleScripts = {
  init: function() {
		this.modData('Pokedex', 'cherrimsunshine').types = ['Grass', 'Fire'];

		// Give Hurricane to all the Bug/Flying Quiver-dancers
		// Precedent: Volcarona
		this.modData('Learnsets', 'masquerain').learnset.hurricane = ['5L100'];
		this.modData('Learnsets', 'butterfree').learnset.hurricane = ['5L100'];
		this.modData('Learnsets', 'beautifly').learnset.hurricane = ['5L100'];
		this.modData('Learnsets', 'mothim').learnset.hurricane = ['5L100'];

		// Masquerain also gets Surf because we want it to be viable
		this.modData('Learnsets', 'masquerain').learnset.surf = ['5M'];

		// Shuckle gets Leech Seed
		this.modData('Learnsets', 'shuckle').learnset.leechseed = ['5L100'];

		// Roserade gets Sludge
		this.modData('Learnsets', 'roserade').learnset.sludge = ['5L100'];

		// Meloetta: Fiery Dance
		this.modData('Learnsets', 'meloetta').learnset.fierydance = ['5L100'];

		// Galvantula: Zap Cannon
		this.modData('Learnsets', 'galvantula').learnset.zapcannon = ['5L100'];

		// Virizion: Horn Leech
		this.modData('Learnsets', 'virizion').learnset.hornleech = ['5L100'];

		// Scolipede, Milotic, Steelix: Coil
		this.modData('Learnsets', 'milotic').learnset.coil = ['5L100'];
		this.modData('Learnsets', 'scolipede').learnset.coil = ['5L100'];
		this.modData('Learnsets', 'steelix').learnset.coil = ['5L100'];

		// Rotoms: lots of moves
		this.modData('Learnsets', 'rotomwash').learnset.bubblebeam = ['5L100'];
		this.modData('Learnsets', 'rotomfan').learnset.hurricane = ['5L100'];
		this.modData('Learnsets', 'rotomfan').learnset.twister = ['5L100'];
		this.modData('Learnsets', 'rotomfrost').learnset.frostbreath = ['5L100'];
		this.modData('Learnsets', 'rotomheat').learnset.heatwave = ['5L100'];
		this.modData('Learnsets', 'rotommow').learnset.magicalleaf = ['5L100'];

		// Zororark: much wider movepool
		this.modData('Learnsets', 'zoroark').learnset.earthquake = ['5M'];
		this.modData('Learnsets', 'zoroark').learnset.stoneedge = ['5M'];
		this.modData('Learnsets', 'zoroark').learnset.icebeam = ['5M'];
		this.modData('Learnsets', 'zoroark').learnset.xscissor = ['5M'];
		this.modData('Learnsets', 'zoroark').learnset.gigadrain = ['5T'];
		this.modData('Learnsets', 'zoroark').learnset.superpower = ['5T'];

		// Mantine: lots of moves
		this.modData('Learnsets', 'mantine').learnset.recover = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.whirlwind = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.batonpass = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.wish = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.soak = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.lockon = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.acidspray = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.octazooka = ['5L100'];
		this.modData('Learnsets', 'mantine').learnset.stockpile = ['5L100'];

		// Aipom: eggSketch! :D
		this.modData('Learnsets', 'aipom').learnset.sketch = ['5E'];

		// Azumarill: free Belly Drum
		this.modData('Learnsets', 'azumarill').learnset.bellydrum = ['5L100'];

		// Spinda: free Superpower
		this.modData('Learnsets', 'spinda').learnset.superpower = ['5L100'];

		// Venusaur
		this.modData('Pokedex', 'venusaur').abilities['1'] = 'Leaf Guard';
		// Charizard
		this.modData('Pokedex', 'charizard').abilities['1'] = 'Flash Fire';
		// Blastoise
		this.modData('Pokedex', 'blastoise').abilities['1'] = 'Shell Armor';
		// Meganium
		this.modData('Pokedex', 'meganium').abilities['1'] = 'Harvest';
		// Typhlosion
		this.modData('Pokedex', 'typhlosion').abilities['1'] = 'Flame Body';
		// Feraligatr
		this.modData('Pokedex', 'feraligatr').abilities['1'] = 'Intimidate';
		// Sceptile
		this.modData('Pokedex', 'sceptile').abilities['1'] = 'Limber';
		// Blaziken
		this.modData('Pokedex', 'blaziken').abilities['1'] = 'Reckless';
		// Swampert
		this.modData('Pokedex', 'swampert').abilities['1'] = 'Hydration';
		// Torterra
		this.modData('Pokedex', 'torterra').abilities['1'] = 'Weak Armor';
		// Infernape
		this.modData('Pokedex', 'infernape').abilities['1'] = 'No Guard';
		// Empoleon
		this.modData('Pokedex', 'empoleon').abilities['1'] = 'Ice Body';
		// Serperior
		this.modData('Pokedex', 'serperior').abilities['1'] = 'Own Tempo';
		// Emboar
		this.modData('Pokedex', 'emboar').abilities['1'] = 'Sheer Force';
		// Samurott
		this.modData('Pokedex', 'samurott').abilities['1'] = 'Technician';

		// Levitate mons
		this.modData('Pokedex', 'unown').abilities['1'] = 'Adaptability';
		this.modData('Pokedex', 'flygon').abilities['1'] = 'Compoundeyes';
		this.modData('Pokedex', 'weezing').abilities['1'] = 'Aftermath';
		this.modData('Pokedex', 'eelektross').abilities['1'] = 'Poison Heal';
		this.modData('Pokedex', 'claydol').abilities['1'] = 'Filter';
		this.modData('Pokedex', 'gengar').abilities['1'] = 'Cursed Body';
		this.modData('Pokedex', 'mismagius').abilities['1'] = 'Cursed Body';
		this.modData('Pokedex', 'cryogonal').abilities['1'] = 'Ice Body';

		// Every DW ability that isn't Shadow Tag becomes released
		for (var i in this.data.FormatsData) {
			if (i !== 'chandelure' && i !== 'gothitelle') {
				this.modData('FormatsData', i).dreamWorldRelease = true;
			}
		}
	}
};
<commit_msg>Update scripts.js<commit_after>exports.BattleScripts = {
  init: function() {
		// Everything learns sketch, you look at the name and tell me what I'm supposed to do :/
		this.modData('Learnsets').learnset.sketch = ['5L0'];
	}
};
<|endoftext|>


<commit_before>String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
};

String.prototype.uncapitalize = function() {
    return this.charAt(0).toLowerCase() + this.slice(1);
};

String.prototype.titleCase = function() {
    return this.replace(/[^-'\s]+/g, function(word) {
        return word.replace(/^./, function(first) {
            return first.toUpperCase();
        });
    });
};

String.prototype.humanize = function() {
    return this.underscore(' ').titleCase();
};

String.prototype.toCamelCase = function() {
    return this.uncapitalize().replace(/(\s|\-|\_|\.)+(.)/g, function(match) {
        return match.slice(-1).toUpperCase();
    });
};

String.prototype.startsWith = function(needle) {
    return (this.indexOf(needle) === 0);
};

String.prototype.toPascalCase = function() {
    return this.toCamelCase().capitalize();
};

String.prototype.underscore = function(separator) {
    if (!separator) separator = "_";
    return this.toCamelCase().replace(/[A-Z]/g, function(match) {
        return separator + match.toLowerCase();
    })
};

String.prototype.wordCount = function() {
    if (this.length) {
        let match = this.match(/(\S+)/g);
        return (match && match.length) || 0;
    } else {
        return 0;
    }
};

String.prototype.surround = function(str) {
    return str + this + str;
};

String.prototype.reduceText = function(numWords) {
    let lines = this.split('\n');
    let result = '';
    while (result.wordCount() < numWords && lines.length) {
        result += lines.shift() + '\n';
    }
    return result.trim();
};

String.prototype.wordwrap = function(width = 60, brk = '\n', cut = false) {
    let regex = '.{1,' +width+ '}(\\s|$)' + (cut ? '|.{' +width+ '}|.+$' : '|\\S+?(\\s|$)');

    return this.match(new RegExp(regex, 'g')).map(function(str) {
        return str.trim()
    }).join(brk);
};

// convert integer to a bytes string
Number.prototype.toBytes = function(precision) {
    if (typeof precision === 'undefined') precision = 1;
    let units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
        number = Math.floor(Math.log(this) / Math.log(1024));
    return (this / Math.pow(1024, Math.floor(number))).toFixed(precision) +  ' ' + units[number];
};

// parse input bytes string into an integer
Number.prototype.parseBytes = function(bytesString) {
    let sp = bytesString.split(' ');
    if (!sp || sp.length < 2) return 0;
    let units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
    let power = units.indexOf(sp[1]);
    if (power === -1) {
        return 0;
    } else {
        return Math.floor(Number.parseFloat(sp[0]) * Math.pow(1024, power));
    }
};

Number.prototype.toPercentage = function(precision) {
    return (this * 100).toFixed(precision).toString() + "%";
};

// concatenates this with array and assigns the result to this
// does nothing if either this or array are undefined
Array.prototype.unite = function(array) {
    if (this && array) {
        for (let i = 0; i < array.length; i++) {
            this.push(array[i]);
        }
    }
};

// gets a random item from the array
Array.prototype.random = function() {
    return this[Math.floor((Math.random() * this.length))];
};

Array.prototype.remove = function(needle) {
    let n = this.indexOf(needle);
    if (n > -1) this.splice(n, 1);
    return n;
};

Array.prototype.subtract = function(otherArray) {
    if (!otherArray) return this;
    return this.filter((item) => { return otherArray.indexOf(item) === -1 });
};

Array.prototype.sortOnKey = function(key, sortFn) {
    sortFn = sortFn || function(a, b, key) {
        if (a[key] < b[key]) return -1;
        if (a[key] > b[key]) return 1;
        return 0;
    };
    return this.sort(function(a, b) {
        return sortFn(a, b, key);
    });
};

Array.prototype.groupBy = function(propertyName) {
    let obj = {};
    this.forEach(function(item) {
        let key = item[propertyName] + '';
        if (obj.hasOwnProperty(key)) {
            obj[key].push(item);
        } else {
            obj[key] = [item];
        }
    });
    return obj;
};

Array.prototype.equals = function(otherArray) {
    if (!otherArray || this.length !== otherArray.length) return false;
    for (let index = 0; index < this.length; index++) {
        let item = this[index],
            otherItem = otherArray[index],
            itemType = typeof item,
            otherItemType = typeof otherItem;
        if (itemType !== otherItemType) return false;
        if (itemType === 'object') {
            if (!item.equals(otherItem)) return false;
        } else if (item !== otherItem) {
            return false;
        }
    }
    return true;
};

Array.prototype.forEachDesc = function(callback) {
    for (let i = this.length; i > -1; i--) {
        callback(this[i], i, this);
    }
};

Array.prototype.forEachNested = function(callback, nestingKey) {
    let nestedCallback = function(element, index, array) {
        if (callback(element, index, array) && element.hasOwnProperty(nestingKey)) {
            element[nestingKey].forEachDesc(nestedCallback);
        }
    };
    this.forEachDesc(nestedCallback);
};

Array.prototype.trimFalsy = function() {
    let n;
    for (n = this.length - 1; n > -1; n--) {
        if (this[n]) break;
    }
    return n < this.length - 1 ? this.slice(0, n + 1) : this;
};

Array.prototype.last = function() {
    return this[this.length - 1];
};

Object.prototype.equals = () => {};
Object.defineProperty(Object.prototype, 'equals', {
    enumerable: false,
    value: function(otherObject) {
        if (!object || !otherObject) return false;
        let object = this,
            objectKeys = Object.keys(object);
        if (!objectKeys.equals(Object.keys(otherObject))) return false;
        for (let i = 0; i < objectKeys.length; i++) {
            let key = objectKeys[i],
                value = object[key], otherValue = otherObject[key],
                valueType = typeof value, otherValueType = typeof otherValue;
            if (valueType !== otherValueType) return false;
            if (valueType === 'object') {
                if (!value.equals(otherValue)) return false;
            } else if (value !== otherValue) {
                return false;
            }
        }
        return true;
    }
});

Object.deepAssign = function(target, varArgs) {
    if (target === null) { // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
    }

    let to = Object(target);
    for (let index = 1; index < arguments.length; index++) {
        let nextSource = arguments[index];
        if (nextSource === null) continue; // Skip over if undefined or null
        Object.keys(nextSource).forEach(function (nextKey) {
            let value = nextSource[nextKey];
            if (typeof value === 'object' && value.constructor === Object) {
                if (!Object.prototype.hasOwnProperty.call(to, nextKey)) {
                    to[nextKey] = {};
                }
                Object.deepAssign(to[nextKey], value);
            } else {
                to[nextKey] = value;
            }
        });
    }
    return to;
};

// angular polyfills
if (window.hasOwnProperty('angular')) {
    angular.inherit = function(scope, attribute) {
        if (angular.isUndefined(scope[attribute])) {
            scope[attribute] = scope.$parent[attribute];
        }
    };

    angular.default = function(scope, attribute, value) {
        if (angular.isUndefined(scope[attribute])) {
            scope[attribute] = value;
        }
    };

    angular.copyProperties = function(source, destination) {
        for (let prop in source) {
            if (source.hasOwnProperty(prop)) {
                destination[prop] = source[prop];
            }
        }
    };

    angular.inheritScope = function(scope, attribute) {
        let obj = scope[attribute] || scope.$parent[attribute];
        if (angular.isUndefined(obj)) return;
        angular.copyProperties(obj, scope);
    };
}<commit_msg>added findByKey array prototype<commit_after>String.prototype.capitalize = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
};

String.prototype.uncapitalize = function() {
    return this.charAt(0).toLowerCase() + this.slice(1);
};

String.prototype.titleCase = function() {
    return this.replace(/[^-'\s]+/g, function(word) {
        return word.replace(/^./, function(first) {
            return first.toUpperCase();
        });
    });
};

String.prototype.humanize = function() {
    return this.underscore(' ').titleCase();
};

String.prototype.toCamelCase = function() {
    return this.uncapitalize().replace(/(\s|\-|\_|\.)+(.)/g, function(match) {
        return match.slice(-1).toUpperCase();
    });
};

String.prototype.startsWith = function(needle) {
    return (this.indexOf(needle) === 0);
};

String.prototype.toPascalCase = function() {
    return this.toCamelCase().capitalize();
};

String.prototype.underscore = function(separator) {
    if (!separator) separator = "_";
    return this.toCamelCase().replace(/[A-Z]/g, function(match) {
        return separator + match.toLowerCase();
    })
};

String.prototype.wordCount = function() {
    if (this.length) {
        let match = this.match(/(\S+)/g);
        return (match && match.length) || 0;
    } else {
        return 0;
    }
};

String.prototype.surround = function(str) {
    return str + this + str;
};

String.prototype.reduceText = function(numWords) {
    let lines = this.split('\n');
    let result = '';
    while (result.wordCount() < numWords && lines.length) {
        result += lines.shift() + '\n';
    }
    return result.trim();
};

String.prototype.wordwrap = function(width = 60, brk = '\n', cut = false) {
    let regex = '.{1,' +width+ '}(\\s|$)' + (cut ? '|.{' +width+ '}|.+$' : '|\\S+?(\\s|$)');

    return this.match(new RegExp(regex, 'g')).map(function(str) {
        return str.trim()
    }).join(brk);
};

// convert integer to a bytes string
Number.prototype.toBytes = function(precision) {
    if (typeof precision === 'undefined') precision = 1;
    let units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
        number = Math.floor(Math.log(this) / Math.log(1024));
    return (this / Math.pow(1024, Math.floor(number))).toFixed(precision) +  ' ' + units[number];
};

// parse input bytes string into an integer
Number.prototype.parseBytes = function(bytesString) {
    let sp = bytesString.split(' ');
    if (!sp || sp.length < 2) return 0;
    let units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
    let power = units.indexOf(sp[1]);
    if (power === -1) {
        return 0;
    } else {
        return Math.floor(Number.parseFloat(sp[0]) * Math.pow(1024, power));
    }
};

Number.prototype.toPercentage = function(precision) {
    return (this * 100).toFixed(precision).toString() + "%";
};

// concatenates this with array and assigns the result to this
// does nothing if either this or array are undefined
Array.prototype.unite = function(array) {
    if (this && array) {
        for (let i = 0; i < array.length; i++) {
            this.push(array[i]);
        }
    }
};

// gets a random item from the array
Array.prototype.random = function() {
    return this[Math.floor((Math.random() * this.length))];
};

Array.prototype.remove = function(needle) {
    let n = this.indexOf(needle);
    if (n > -1) this.splice(n, 1);
    return n;
};

Array.prototype.subtract = function(otherArray) {
    if (!otherArray) return this;
    return this.filter((item) => { return otherArray.indexOf(item) === -1 });
};

Array.prototype.findByKey = function(key, value) {
    return this.find((item) => { return item[key] === value });
};

Array.prototype.sortOnKey = function(key, sortFn) {
    sortFn = sortFn || function(a, b, key) {
        if (a[key] < b[key]) return -1;
        if (a[key] > b[key]) return 1;
        return 0;
    };
    return this.sort(function(a, b) {
        return sortFn(a, b, key);
    });
};

Array.prototype.groupBy = function(propertyName) {
    let obj = {};
    this.forEach(function(item) {
        let key = item[propertyName] + '';
        if (obj.hasOwnProperty(key)) {
            obj[key].push(item);
        } else {
            obj[key] = [item];
        }
    });
    return obj;
};

Array.prototype.equals = function(otherArray) {
    if (!otherArray || this.length !== otherArray.length) return false;
    for (let index = 0; index < this.length; index++) {
        let item = this[index],
            otherItem = otherArray[index],
            itemType = typeof item,
            otherItemType = typeof otherItem;
        if (itemType !== otherItemType) return false;
        if (itemType === 'object') {
            if (!item.equals(otherItem)) return false;
        } else if (item !== otherItem) {
            return false;
        }
    }
    return true;
};

Array.prototype.forEachDesc = function(callback) {
    for (let i = this.length; i > -1; i--) {
        callback(this[i], i, this);
    }
};

Array.prototype.forEachNested = function(callback, nestingKey) {
    let nestedCallback = function(element, index, array) {
        if (callback(element, index, array) && element.hasOwnProperty(nestingKey)) {
            element[nestingKey].forEachDesc(nestedCallback);
        }
    };
    this.forEachDesc(nestedCallback);
};

Array.prototype.trimFalsy = function() {
    let n;
    for (n = this.length - 1; n > -1; n--) {
        if (this[n]) break;
    }
    return n < this.length - 1 ? this.slice(0, n + 1) : this;
};

Array.prototype.last = function() {
    return this[this.length - 1];
};

Object.prototype.equals = () => {};
Object.defineProperty(Object.prototype, 'equals', {
    enumerable: false,
    value: function(otherObject) {
        if (!object || !otherObject) return false;
        let object = this,
            objectKeys = Object.keys(object);
        if (!objectKeys.equals(Object.keys(otherObject))) return false;
        for (let i = 0; i < objectKeys.length; i++) {
            let key = objectKeys[i],
                value = object[key], otherValue = otherObject[key],
                valueType = typeof value, otherValueType = typeof otherValue;
            if (valueType !== otherValueType) return false;
            if (valueType === 'object') {
                if (!value.equals(otherValue)) return false;
            } else if (value !== otherValue) {
                return false;
            }
        }
        return true;
    }
});

Object.deepAssign = function(target, varArgs) {
    if (target === null) { // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
    }

    let to = Object(target);
    for (let index = 1; index < arguments.length; index++) {
        let nextSource = arguments[index];
        if (nextSource === null) continue; // Skip over if undefined or null
        Object.keys(nextSource).forEach(function (nextKey) {
            let value = nextSource[nextKey];
            if (typeof value === 'object' && value.constructor === Object) {
                if (!Object.prototype.hasOwnProperty.call(to, nextKey)) {
                    to[nextKey] = {};
                }
                Object.deepAssign(to[nextKey], value);
            } else {
                to[nextKey] = value;
            }
        });
    }
    return to;
};

// angular polyfills
if (window.hasOwnProperty('angular')) {
    angular.inherit = function(scope, attribute) {
        if (angular.isUndefined(scope[attribute])) {
            scope[attribute] = scope.$parent[attribute];
        }
    };

    angular.default = function(scope, attribute, value) {
        if (angular.isUndefined(scope[attribute])) {
            scope[attribute] = value;
        }
    };

    angular.copyProperties = function(source, destination) {
        for (let prop in source) {
            if (source.hasOwnProperty(prop)) {
                destination[prop] = source[prop];
            }
        }
    };

    angular.inheritScope = function(scope, attribute) {
        let obj = scope[attribute] || scope.$parent[attribute];
        if (angular.isUndefined(obj)) return;
        angular.copyProperties(obj, scope);
    };
}
<|endoftext|>


<commit_before>'use strict';

angular.module('flowsimUiApp')
  .factory('Profile', function(ETHERNET, fgConstraints) {

var TIPS = {};
var TESTS = {};

function Datapath(dp) {

  if(dp) {
    this.datapath_id   = dp.datapath_id;
    this.ip_reassembly = dp.ip_reassembly;
    this.n_buffers     = dp.n_buffers;
    this.n_tables      = dp.n_tables;

    this.mfc_desc   = dp.mfc_desc;
    this.hw_desc    = dp.hw_desc;
    this.sw_desc    = dp.sw_desc;
    this.serial_num = dp.serial_num;
    this.dp_desc    = dp.dp_desc;
  } else {
  // Capabilities
    this.datapath_id   = '01:23:45:67:89:ab'; // <- need a better answer than t
    this.n_buffers     = 1024;
    this.n_tables      = 256;
    this.ip_reassembly = true;

    // Descriptions
    this.mfr_description = '';
    this.hw_description  = '';
    this.sw_description  = '';
    this.serial_num      = '';
    this.dp_description  = '';
  }
}
var DatapathUI = Datapath;

DatapathUI.prototype.toBase = function() {
  return new Datapath(this);
}

TIPS.datapath = {
  datapath_id: 'Unique id of the datapath',
  ip_reassembly: 'Datapath can reassemble IP fragments',
  n_buffers: 'Number of packets that can be buffered for controller',
  n_tables: 'Number of flow tables available',
  mfr_desc: '',
  hw_desc: '',
  serial_num: '',
  dp_desc: ''
};

TESTS.datapath = {
  datapath_id: function() { return true; },
  n_buffers: fgConstraints.isUInt(0, 0xffff),
  n_tables: fgConstraints.isUInt(1, 256),
  mfr_desc: function(v) { return !v || v.length <= 256 ; },
  hw_desc: function(v) { return !v || v.length <= 256; },
  sw_desc: function(v) { return !v || v.length <= 256; },
  serial_num: function(v) { return !v || v.length <= 32; },
  dp_desc: function(v) { return !v || v.length <= 256; }
};

function Port(p) {
  if(p) {
  }
  if() {
    this.port_id = p
    this.mac     = mac ? mac : '00:00:00:00:00:00';
    this.name    = name ? name : 'eth' + id;
    this.speed   = speed ? speed : '1_gbps';
    this.mode    = mode ? mode : 'full_duplex';
    this.medium  = medium ? medium : 'Copper';
  } else if(p) {

  this.port_id = p.port_id;
  this.mac     = p.mac;
  this.name    = p.name;
  this.speed   = p.speed;
  this.mode    = p.mode;
  this.medium  = p.medium;
}

PortUI.prototype.toBase = function() {
  var result= new Port();
  result.mac = port.mac;
  this.name = port.name;
  this.speed = port.speed;
  this.mode = port.mode;
  this.medium = port.medium;
  return result;
}

PortUI.TIPS = {
  port_id: '',
  mac: '',
  name: '',
  speed: '',
  mode: '',
  medium: ''
};

PortUI.TESTS = {
  mac: ETHERNET.isMac,
  name: function(v) { return /[a-zA-Z_][a-zA-Z_0-9]*/.test(v) }
};

PortUI.SPEEDS = [{
  label: '10 Mbps',
  value: '10_mbps'
}, {
  label: '100 Mbps',
  value: '100_mbps'
}, {
  label: '1 Gbps',
  value: '1_gbps'
}, {
  label: '10 Gbps',
  value: '10_gbps'
}, {
  label: '40 Gbps',
  value: '40_gbps'
}, {
  label: '100 Gbps',
  value: '100_gbps'
}, {
  label: '1 Tbps',
  value: '1_tbps'
}];

PortUI.MODES = [{
  label: 'Half Duplex',
  value: 'half_duplex'
}, {
  label: 'Full Duplex',
  value: 'full_duplex'
}];

PortUI.MEDIUMS = [
  'Copper',
  'Fiber'
];

function Ports() {
  this.n_ports = 24;
  this.ports = _.map(_.range(this.n_ports), function(idx) {
    return new Port(idx);
  });
  this.vports = {
    port_stats: true,
    stp:        false,
    in_port:    true,
    table:      true,
    normal:     true,
    flood:      true,
    all:        true,
    controller: true,
    local:      true,
    any:        true,
    none:       true
  };
}

function PortsUI(ports) {
  ports = ports === undefined ? new Ports() : ports;
  this.n_ports = ports.n_ports;
  this.ports = _.map(ports.ports, function(port) {
    return new Port(port);
  });
  this.vports = _.map(ports.vports, function(value, key) {
    return {
      name: key,
      value: value
    };
  });
}

PortsUI.prototype.toBase = function() {
  var result = new Ports();
  result.n_ports = this.n_ports;
  result.ports = _.map(this.ports, function(port) {
    return port.toBase();
  });
  result.vports = this.vports;
  return result;
};

function Meters() {
}

function MetersUI(m) {
  if(m) {
  } else {
  }
}

MetersUI.prototype.toBase = function() {
  var result = new Meters();
  return result;
};

function Tables() {
}

function TablesUI(t) {
  if(t) {
  } else {
  }
}

TablesUI.prototype.toBase = function() {
  var result = new Tables();
  return result;
};

function Groups() {
}
function GroupsUI(g) {
  if(g) {
  } else {
  }
}

GroupsUI.prototype.toBase = function() {
  var result = new Groups();
  return result;
};

function Profile(name) {
  this.name = name;
  this.datapath = new Datapath();
  this.ports    = new Ports();
  this.meters   = new Meters();
  this.tables   = new Tables();
  this.groups   = new Groups();
}

function ProfileUI(profile) {
  profile = typeof profile === 'string' ? new Profile(profile) : profile;
  this.name = profile.name;
  this.datapath = new DatapathUI(profile.datapath);
  this.ports    = new PortsUI(profile.ports);
  this.meters   = new MetersUI(profile.meters);
  this.tables   = new TablesUI(profile.tables);
  this.groups   = new GroupsUI(profile.groups);
}

ProfileUI.prototype.toBase = function() {
  var result = new Profile(this.name);
  result.datapath = this.datapath.toBase();
  result.ports = this.ports.toBase();
  result.meters = this.meters.toBase();
  result.tables = this.tables.toBase();
  result.groups = this.groups.toBase();
  return result;
};

/**
 * @ngdoc service
 * @name flowsimUiApp.profile
 * @description
 * # profile
 * Service in the flowsimUiApp.
 */

    function create(name) {
      return new Profile(name);
    }

    function createUI(profile) {
      return new ProfileUI(profile);
    }

    function setVersion(profile, version) {
      console.log('version: '+version);
    }

    return {
      create: create,
      createUI: createUI,
      setVersion: setVersion,
      tips: TIPS,
      tests: TESTS
    };

});
<commit_msg>latest<commit_after>'use strict';

angular.module('flowsimUiApp')
  .factory('Profile', function(ETHERNET, fgConstraints) {

var TIPS = {};
var TESTS = {};

function Datapath(dp) {
  // Copy constructor
  if(dp && dp instanceof Datapath) {
    this.datapath_id   = dp.datapath_id;
    this.ip_reassembly = dp.ip_reassembly;
    this.n_buffers     = dp.n_buffers;
    this.n_tables      = dp.n_tables;

    this.mfc_desc   = dp.mfc_desc;
    this.hw_desc    = dp.hw_desc;
    this.sw_desc    = dp.sw_desc;
    this.serial_num = dp.serial_num;
    this.dp_desc    = dp.dp_desc;
  }
  // Default constructor
  else {
    this.datapath_id   = '01:23:45:67:89:ab'; // FIXME: bad default
    this.n_buffers     = 1024;
    this.n_tables      = 256;
    this.ip_reassembly = true;

    // Descriptions
    this.mfr_description = '';
    this.hw_description  = '';
    this.sw_description  = '';
    this.serial_num      = '';
    this.dp_description  = '';
  }
}

Datapath.prototype.clone = function() {
  return new Datapath(this);
};

var DatapathUI = Datapath;
DatapathUI.prototype.toBase = Datapath.prototype.clone;

TIPS.datapath = {
  datapath_id: 'Unique id of the datapath',
  ip_reassembly: 'Datapath can reassemble IP fragments',
  n_buffers: 'Number of packets that can be buffered for controller',
  n_tables: 'Number of flow tables available',
  mfr_desc: '',
  hw_desc: '',
  serial_num: '',
  dp_desc: ''
};

TESTS.datapath = {
  datapath_id: function() { return true; },
  n_buffers:   fgConstraints.isUInt(0, 0xffff),
  n_tables:    fgConstraints.isUInt(1, 256),
  mfr_desc:    function(v) { return !v || v.length <= 256 ; },
  hw_desc:     function(v) { return !v || v.length <= 256; },
  sw_desc:     function(v) { return !v || v.length <= 256; },
  serial_num:  function(v) { return !v || v.length <= 32; },
  dp_desc:     function(v) { return !v || v.length <= 256; }
};

function Port(p) {
  // Copy constructor
  if(p && p instanceof Port) {
    this.port_id = p.port_id;
    this.mac     = p.mac;
    this.name    = p.name;
    this.speed   = p.speed;
    this.mode    = p.mode;
    this.medium  = p.medium;
  } else {
    if(p && typeof p === 'number') {
      this.port_id = p;
    } else {
      this.port_id = 0
    }
    this.mac    = '00:00:00:00:00:00';
    this.name   = 'eth' + this.port_id;
    this.speed  = '1_gbps';
    this.mode   = 'full_duplex';
    this.medium = 'Copper';
  }
}

Port.prototype.clone = function() {
  return new Port(this);
};

var PortUI              = Port;
PortUI.prototype.toBase = Port.prototype.clone;

TIPS.port = {
  port_id: 'Ethernet port identifier',
  mac:     'MAC address used by port in spanning tree',
  name:    'display name of the port',
  speed:   'physical layer speed of port',
  mode:    'physical layer transmission mode',
  medium:  'physical layer medium of port'
};

TESTS.port = {
  mac: ETHERNET.isMac,
  name: function(v) { return /[a-zA-Z_][a-zA-Z_0-9]*/.test(v) }
};

var SPEEDS = [{
  label: '10 Mbps',
  value: '10_mbps'
}, {
  label: '100 Mbps',
  value: '100_mbps'
}, {
  label: '1 Gbps',
  value: '1_gbps'
}, {
  label: '10 Gbps',
  value: '10_gbps'
}, {
  label: '40 Gbps',
  value: '40_gbps'
}, {
  label: '100 Gbps',
  value: '100_gbps'
}, {
  label: '1 Tbps',
  value: '1_tbps'
}];

var MODES = [{
  label: 'Half Duplex',
  value: 'half_duplex'
}, {
  label: 'Full Duplex',
  value: 'full_duplex'
}];

var MEDIUMS = [
  'Copper',
  'Fiber'
];

function Ports(ports) {
  if(ports && ports instanceof Ports) {
    this.n_ports = ports.n_ports;
    this.ports = _.map(ports.ports, function(port) {
      return new Port(port);
    });
    this.vports = _.clone(ports.vports);
  } else {
    if(ports && typeof ports === 'number'){
      this.n_ports = ports;
    }
    this.ports = _.map(_.range(this.n_ports), function(idx) {
      return new Port(idx);
    });
    this.vports = {
      port_stats: true,
      stp:        false,
      in_port:    true,
      table:      true,
      normal:     true,
      flood:      true,
      all:        true,
      controller: true,
      local:      true,
      any:        true,
      none:       true
    };
  }
}

Ports.prototype.clone = function() {
  return new Ports(this);
}

var PortsUI              = Ports;
PortsUI.prototype.toBase = Ports.prototype.clone;

function Meters(meters) {
  if(meters && meters instanceof Meters) {
  } else {
  }
}
Meters.prototype.clone = function() {
  return new Meters(this);
}

var MetersUI = Meters;
MetersUI.prototype.toBase = Meters.prototype.clone;

function Tables(tables) {
  if(tables && tables instanceof Tables) {
  } else {
  }
}

Tables.prototype.clone = function() {
  return new Tables(this);
}

var TablesUI = Tables;
TablesUI.prototype.toBase = Tables.prototype.clone;

function Groups(groups) {
  if(groups && groups instanceof Groups) {
  } else {
  }
}

Groups.prototype.clone = function() {
  return new Groups(this);
}

var GroupsUI              = Groups;
GroupsUI.prototype.toBase = Groups.prototype.clone;

function Profile(name) {
  this.name = name;
  this.datapath = new Datapath();
  this.ports    = new Ports();
  this.meters   = new Meters();
  this.tables   = new Tables();
  this.groups   = new Groups();
}

function ProfileUI(profile) {
  profile = typeof profile === 'string' ? new Profile(profile) : profile;
  this.name = profile.name;
  this.datapath = new DatapathUI(profile.datapath);
  this.ports    = new PortsUI(profile.ports);
  this.meters   = new MetersUI(profile.meters);
  this.tables   = new TablesUI(profile.tables);
  this.groups   = new GroupsUI(profile.groups);
}

ProfileUI.prototype.toBase = function() {
  var result = new Profile(this.name);
  result.datapath = this.datapath.toBase();
  result.ports = this.ports.toBase();
  result.meters = this.meters.toBase();
  result.tables = this.tables.toBase();
  result.groups = this.groups.toBase();
  return result;
};

/**
 * @ngdoc service
 * @name flowsimUiApp.profile
 * @description
 * # profile
 * Service in the flowsimUiApp.
 */

    function create(name) {
      return new Profile(name);
    }

    function createUI(profile) {
      return new ProfileUI(profile);
    }

    function setVersion(profile, version) {
      console.log('version: '+version);
    }

    return {
      create: create,
      createUI: createUI,
      setVersion: setVersion,
      tips: TIPS,
      tests: TESTS
    };

});
<|endoftext|>