<commit_before>'use strict';

// Main application
angular.module('MatchCalendar', ['ui.bootstrap', 'ngCookies', 'ngSanitize', 'btford.markdown', 'ui.router', 'ngClipboard'])

    .run(['$rootScope', '$cookieStore', function($rootScope, $cookieStore) {
        $rootScope.settings = {
            time_formats: ['12h', '24h'],
            time_zones: moment.tz.names(),
            time_zone: $cookieStore.get('time_zone'),
            time_format: $cookieStore.get('time_format')
        };

        $rootScope.$watch('settings.time_zone', function(newValue) {
            $cookieStore.put('time_zone', newValue);
        });
        if(null == $rootScope.settings.time_zone)
            $rootScope.settings.time_zone = 'Etc/UTC';

        $rootScope.$watch('settings.time_format', function(newValue) {
            $cookieStore.put('time_format', newValue);
        });
        if(null == $rootScope.settings.time_format)
            $rootScope.settings.time_format = '24h';
    }])

    //configuration
    .config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
        $stateProvider
            .state('list', {
                url: '/list',
                templateUrl: 'partials/list.html'
            })

            .state('generate', {
                url: '/generate',
                templateUrl: 'partials/generator.html',
                controller: 'HeaderGeneratorCtrl'
            })

            .state('settings', {
                url: '/settings',
                templateUrl: 'partials/settings.html'
            });

        $urlRouterProvider.otherwise('/list');
    }])

    //controller for the application
    .controller('AppCtrl', ['$scope', 'RedditPostsService', '$cookieStore', '$timeout', 'HtmlNotifications', function($scope, RedditPostsService, $cookieStore, $timeout, HtmlNotifications) {
        $scope.requestPermissions = function() {
            HtmlNotifications.requestPermission().then(function() {
                HtmlNotifications.notify('Notifications Enabled!');
            });
        };
        $scope.currentPermission = function() {
            return HtmlNotifications.currentPermission();
        };

        $scope.subreddits = ['ghowden', 'ultrahardcore'];

        $scope.posts = [];
        $scope.updatePosts = function() {
            RedditPostsService.query($scope.subreddits).then(function(data) {
                $scope.posts = data;
            });
        };

        (function tick() {
            $scope.current_time = moment();
            $timeout(tick, 1000);
         })();

        (function tick() {
            $scope.updatePosts();
            if(HtmlNotifications.currentPermission() === 'granted') {
                angular.forEach($scope.posts, function (post) {
                    if(post.opens == null) return;

                    var timeLeft = post.opens.diff($scope.current_time);
                    if(timeLeft < 1000 * 60 * 15) {
                        HtmlNotifications.notify('Game opening ' + post.opens.fromNow(), post.title);
                    }
                });
            }
            $timeout(tick, 1000 * 60);
        })();
    }])

    .controller('HeaderGeneratorCtrl', ['$scope', function($scope) {
        $scope.generated = {
            opens: '',
            starts: '',
            address: '',
            title: ''
        };

        $scope.$watch('opens', function(newValue) {
            $scope.generated.opens = newValue.utc().format('YYYY-MM-DDTHH:mm:ssZ');
            $scope.simpleUtcOpens = newValue.utc().format('YYYY-MM-DD HH:mm UTC');
        });
        $scope.$watch('starts', function(newValue) {
            $scope.generated.starts = newValue.utc().format('YYYY-MM-DDTHH:mm:ssZ');
            $scope.simpleUtcStarts = newValue.utc().format('YYYY-MM-DD HH:mm UTC');
        });
        $scope.$watch('address', function(newValue) {
            $scope.generated.address = newValue.replace(/\[/g, '[').replace(/\]/g, ']');
        });
        $scope.$watch('post_title', function(newValue) {
            $scope.generated.title = newValue.replace(/\[/g, '[').replace(/\]/g, ']');
        });

        $scope.$watch('generated', function(newValue) {
            $scope.generatedLink = '[' + JSON.stringify(newValue) + '](/matchpost)';
        }, true);

        $scope.opens = moment();
        $scope.starts = moment();
        $scope.address = '192.168.0.1';
        $scope.post_title = 'Game Title';
    }])

    //a match post model
    .factory('MatchPost', ['MarkdownLinkDataService', function (MarkdownLinkDataService) {

        function MatchPost(title, selftext, author, opens, starts, permalink, raw) {
            this.title = title;
            this.selftext = selftext;
            this.author = author;
            this.opens = opens;
            this.starts = starts;
            this.permalink = permalink;
            this.raw = raw;
        }

        /**
         * @param element the raw post element from the JSON api
         * @returns {MatchPost}
         */
        MatchPost.parseData = function (element) {
            var linkData = MarkdownLinkDataService.fetch('/matchpost', element.selftext);

            var opens, starts, title;

            var parsedLink = false;
            if(linkData != null) {
                try {
                    var json = JSON.parse(linkData);

                    opens = moment(json.opens, 'YYYY-MM-DDTHH:mm:ssZ');
                    starts = moment(json.starts, 'YYYY-MM-DDTHH:mm:ssZ');
                    title = element.title;

                    parsedLink = true;
                } catch (err) {}
            }

            if(!parsedLink) {
                //fall back to old style title parsing

                //attempt to parse the date from the post title
                starts = moment.utc(/[\w]+ [\d]+ [\d]+:[\d]+/.exec(element.title), 'MMM DD HH:mm', 'en');
                opens = starts;

                //get everything after the first '- ' in the title as the actual title
                title = element.title.substring(element.title.indexOf('-') + 2);
            }

            //get the time right now
            var currentTime = moment();

            //if it's invalid (no parsable date) read as unparsed
            if(!starts.isValid()) {
                starts = null;
            } else if(starts.diff(currentTime) < 0) {
                //if it's in the past don't show it at all
                return null;
            }

            //if it's invalid (no parsable date) read as unparsed
            if(!opens.isValid()) {
                opens = null;
            }

            var link = 'http://reddit.com/' + element.permalink;

            return new MatchPost(title, element.selftext, element.author, opens, starts, link, element);
        };

        //Return the constructor function
        return MatchPost;
    }])

    //service for matching markdown links to specific URL path
    .factory( 'MarkdownLinkDataService', [function() {
        return {
            /**
             * Returns the raw string for the markdown link in format [data](link)
             * @param path {string} the URL that was linked to
             * @param markdown {string} the markdown
             * @returns {string} data for the link
             */
            fetch: function(path, markdown) {
                //simple regex for [data](/link) type links
                var regex = new RegExp('\\[([^\\[\\]]+)\\]\\('+path+'\\)', 'g');
                var matches = regex.exec(markdown);
                if(matches == null) {
                    return null;
                } else {
                    return matches[1];
                }
            }
        }
    }])

    //service for fetching reddit posts from the JSON api
    .factory( 'RedditPostsService', ['$http', '$q', '$filter', 'MatchPost', function( $http, $q, $filter, MatchPost ) {
        var uri = 'ultrahardcore/';

        return {
            //fetch all
            query: function (subreddits, limit, sort) {
                //set defaults
                limit = limit || 100;
                sort = sort || 'new';

                var deferreds = [];
                angular.forEach(subreddits, function(subreddit) {
                    var deferred = $q.defer();

                    var parsed = [];
                    var unparsed = [];
                    //get the posts
                    $http.get('http://www.reddit.com/r/' + subreddit + '/search.json?q=flair%3AUpcoming_Match&restrict_sr=on&limit=' + limit + '&sort=' + sort).then(
                        function(data) {
                            angular.forEach(data.data.data.children, function(element) {
                                //parse the post
                                var matchPost = MatchPost.parseData(element.data);

                                if(null == matchPost) {
                                    return;
                                }

                                //if time was invalid push to the invalid stack
                                matchPost.starts == null ? unparsed.push(matchPost) : parsed.push(matchPost);
                            });
                            deferred.resolve({
                                parsed: parsed,
                                unparsed: unparsed
                            });
                        },
                        function() {
                            deferred.resolve({
                                parsed: parsed,
                                unparsed: unparsed
                            });
                        }
                    );
                    deferreds.push(deferred.promise);
                });

                var deferred = $q.defer();
                $q.all(deferreds).then(function(data) {
                    var parsed = [];
                    var unparsed = [];
                    angular.forEach(data, function(element) {
                        parsed.push.apply(parsed, element.parsed);
                        unparsed.push.apply(unparsed, element.unparsed);
                    });

                    //filter the parsed ones in time order
                    var filtered = $filter('orderBy')(parsed, function(element) {
                        return element.starts.format('X');
                    });

                    //add the unparsed matches to the end
                    filtered.push.apply(filtered, unparsed);
                    deferred.resolve(filtered);
                });

                return deferred.promise;
            }
        };
    }])

    .factory('HtmlNotifications', ['$q', function($q) {
        return {
            /**
             * @returns boolean true if notification available, false otherwise
             */
            supports: function() {
                return "Notification" in window;
            },
            currentPermission: function() {
                if(!Notification.permission) {
                    Notification.permission = 'default';
                }
                return Notification.permission;
            },
            /**
             * @returns {promise} resolves on granted, rejects on not
             */
            requestPermission: function() {
                var def = $q.defer();
                if(Notification.permission !== 'granted') {
                    //request the permission and update the permission value
                    Notification.requestPermission(function (status) {
                        console.log(status);
                        if (Notification.permission !== status) {
                            Notification.permission = status;
                        }
                        status === 'granted' ? def.resolve() : def.reject();
                    });
                } else {
                    def.resolve();
                }
                return def.promise;
            },
            /**
             * @param title the title for the notification
             * @param options
             * @param body the body of the notification
             */
            notify: function(title, body, options) {
                this.requestPermission().then(function() {
                    options = options || [];
                    options.icon = options.icon || 'images/favicon.png';
                    options.body = body || '';

                    new Notification(title, options);
                });
            }
        };
    }])

    .directive('dateTimePicker', [function() {
        return {
            restrict: 'AE',
            scope: {
                minDate: '=?',
                pickedDate: '=',
                meridian: '=',
                timeZone: '='
            },
            templateUrl: 'partials/dateTimePicker.html',
            link: function($scope, $element, $attr) {
                $scope.opened = false;

                $scope.internalJSDate = $scope.pickedDate.toDate();
                $scope.internalMinDate = $scope.minDate.toDate();

                $scope.$watch('internalJSDate', function() {
                    $scope.updatePickedDate();
                });
                $scope.$watch('timeZone', function() {
                    $scope.updatePickedDate();
                });

                $scope.updatePickedDate = function() {
                    var pickedMoment = moment($scope.internalJSDate);
                    var formattedMoment = pickedMoment.format('MMM DD HH:mm');
                    $scope.pickedDate = moment.tz(formattedMoment, 'MMM DD HH:mm', $scope.timeZone);
                };

                $scope.toggle = function($event) {
                    $event.preventDefault();
                    $event.stopPropagation();
                    $scope.opened = !$scope.opened;
                }
            }
        }
    }]);<commit_msg>don't add raw data to the matchpost object<commit_after>'use strict';

// Main application
angular.module('MatchCalendar', ['ui.bootstrap', 'ngCookies', 'ngSanitize', 'btford.markdown', 'ui.router', 'ngClipboard'])

    .run(['$rootScope', '$cookieStore', function($rootScope, $cookieStore) {
        $rootScope.settings = {
            time_formats: ['12h', '24h'],
            time_zones: moment.tz.names(),
            time_zone: $cookieStore.get('time_zone'),
            time_format: $cookieStore.get('time_format')
        };

        $rootScope.$watch('settings.time_zone', function(newValue) {
            $cookieStore.put('time_zone', newValue);
        });
        if(null == $rootScope.settings.time_zone)
            $rootScope.settings.time_zone = 'Etc/UTC';

        $rootScope.$watch('settings.time_format', function(newValue) {
            $cookieStore.put('time_format', newValue);
        });
        if(null == $rootScope.settings.time_format)
            $rootScope.settings.time_format = '24h';
    }])

    //configuration
    .config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
        $stateProvider
            .state('list', {
                url: '/list',
                templateUrl: 'partials/list.html'
            })

            .state('generate', {
                url: '/generate',
                templateUrl: 'partials/generator.html',
                controller: 'HeaderGeneratorCtrl'
            })

            .state('settings', {
                url: '/settings',
                templateUrl: 'partials/settings.html'
            });

        $urlRouterProvider.otherwise('/list');
    }])

    //controller for the application
    .controller('AppCtrl', ['$scope', 'RedditPostsService', '$cookieStore', '$timeout', 'HtmlNotifications', function($scope, RedditPostsService, $cookieStore, $timeout, HtmlNotifications) {
        $scope.requestPermissions = function() {
            HtmlNotifications.requestPermission().then(function() {
                HtmlNotifications.notify('Notifications Enabled!');
            });
        };
        $scope.currentPermission = function() {
            return HtmlNotifications.currentPermission();
        };

        $scope.subreddits = ['ghowden', 'ultrahardcore'];

        $scope.posts = [];
        $scope.updatePosts = function() {
            RedditPostsService.query($scope.subreddits).then(function(data) {
                $scope.posts = data;
            });
        };

        (function tick() {
            $scope.current_time = moment();
            $timeout(tick, 1000);
         })();

        (function tick() {
            $scope.updatePosts();
            if(HtmlNotifications.currentPermission() === 'granted') {
                angular.forEach($scope.posts, function (post) {
                    if(post.opens == null) return;

                    var timeLeft = post.opens.diff($scope.current_time);
                    if(timeLeft < 1000 * 60 * 15) {
                        HtmlNotifications.notify('Game opening ' + post.opens.fromNow(), post.title);
                    }
                });
            }
            $timeout(tick, 1000 * 60);
        })();
    }])

    .controller('HeaderGeneratorCtrl', ['$scope', function($scope) {
        $scope.generated = {
            opens: '',
            starts: '',
            address: '',
            title: ''
        };

        $scope.$watch('opens', function(newValue) {
            $scope.generated.opens = newValue.utc().format('YYYY-MM-DDTHH:mm:ssZ');
            $scope.simpleUtcOpens = newValue.utc().format('YYYY-MM-DD HH:mm UTC');
        });
        $scope.$watch('starts', function(newValue) {
            $scope.generated.starts = newValue.utc().format('YYYY-MM-DDTHH:mm:ssZ');
            $scope.simpleUtcStarts = newValue.utc().format('YYYY-MM-DD HH:mm UTC');
        });
        $scope.$watch('address', function(newValue) {
            $scope.generated.address = newValue.replace(/\[/g, '[').replace(/\]/g, ']');
        });
        $scope.$watch('post_title', function(newValue) {
            $scope.generated.title = newValue.replace(/\[/g, '[').replace(/\]/g, ']');
        });

        $scope.$watch('generated', function(newValue) {
            $scope.generatedLink = '[' + JSON.stringify(newValue) + '](/matchpost)';
        }, true);

        $scope.opens = moment();
        $scope.starts = moment();
        $scope.address = '192.168.0.1';
        $scope.post_title = 'Game Title';
    }])

    //a match post model
    .factory('MatchPost', ['MarkdownLinkDataService', function (MarkdownLinkDataService) {

        function MatchPost(title, selftext, author, opens, starts, permalink) {
            this.title = title;
            this.selftext = selftext;
            this.author = author;
            this.opens = opens;
            this.starts = starts;
            this.permalink = permalink;
        }

        /**
         * @param element the raw post element from the JSON api
         * @returns {MatchPost}
         */
        MatchPost.parseData = function (element) {
            var linkData = MarkdownLinkDataService.fetch('/matchpost', element.selftext);

            var opens, starts, title;

            var parsedLink = false;
            if(linkData != null) {
                try {
                    var json = JSON.parse(linkData);

                    opens = moment(json.opens, 'YYYY-MM-DDTHH:mm:ssZ');
                    starts = moment(json.starts, 'YYYY-MM-DDTHH:mm:ssZ');
                    title = element.title;

                    parsedLink = true;
                } catch (err) {}
            }

            if(!parsedLink) {
                //fall back to old style title parsing

                //attempt to parse the date from the post title
                starts = moment.utc(/[\w]+ [\d]+ [\d]+:[\d]+/.exec(element.title), 'MMM DD HH:mm', 'en');
                opens = starts;

                //get everything after the first '- ' in the title as the actual title
                title = element.title.substring(element.title.indexOf('-') + 2);
            }

            //get the time right now
            var currentTime = moment();

            //if it's invalid (no parsable date) read as unparsed
            if(!starts.isValid()) {
                starts = null;
            } else if(starts.diff(currentTime) < 0) {
                //if it's in the past don't show it at all
                return null;
            }

            //if it's invalid (no parsable date) read as unparsed
            if(!opens.isValid()) {
                opens = null;
            }

            var link = 'http://reddit.com/' + element.permalink;

            return new MatchPost(title, element.selftext, element.author, opens, starts, link);
        };

        //Return the constructor function
        return MatchPost;
    }])

    //service for matching markdown links to specific URL path
    .factory( 'MarkdownLinkDataService', [function() {
        return {
            /**
             * Returns the raw string for the markdown link in format [data](link)
             * @param path {string} the URL that was linked to
             * @param markdown {string} the markdown
             * @returns {string} data for the link
             */
            fetch: function(path, markdown) {
                //simple regex for [data](/link) type links
                var regex = new RegExp('\\[([^\\[\\]]+)\\]\\('+path+'\\)', 'g');
                var matches = regex.exec(markdown);
                if(matches == null) {
                    return null;
                } else {
                    return matches[1];
                }
            }
        }
    }])

    //service for fetching reddit posts from the JSON api
    .factory( 'RedditPostsService', ['$http', '$q', '$filter', 'MatchPost', function( $http, $q, $filter, MatchPost ) {
        var uri = 'ultrahardcore/';

        return {
            //fetch all
            query: function (subreddits, limit, sort) {
                //set defaults
                limit = limit || 100;
                sort = sort || 'new';

                var deferreds = [];
                angular.forEach(subreddits, function(subreddit) {
                    var deferred = $q.defer();

                    var parsed = [];
                    var unparsed = [];
                    //get the posts
                    $http.get('http://www.reddit.com/r/' + subreddit + '/search.json?q=flair%3AUpcoming_Match&restrict_sr=on&limit=' + limit + '&sort=' + sort).then(
                        function(data) {
                            angular.forEach(data.data.data.children, function(element) {
                                //parse the post
                                var matchPost = MatchPost.parseData(element.data);

                                if(null == matchPost) {
                                    return;
                                }

                                //if time was invalid push to the invalid stack
                                matchPost.starts == null ? unparsed.push(matchPost) : parsed.push(matchPost);
                            });
                            deferred.resolve({
                                parsed: parsed,
                                unparsed: unparsed
                            });
                        },
                        function() {
                            deferred.resolve({
                                parsed: parsed,
                                unparsed: unparsed
                            });
                        }
                    );
                    deferreds.push(deferred.promise);
                });

                var deferred = $q.defer();
                $q.all(deferreds).then(function(data) {
                    var parsed = [];
                    var unparsed = [];
                    angular.forEach(data, function(element) {
                        parsed.push.apply(parsed, element.parsed);
                        unparsed.push.apply(unparsed, element.unparsed);
                    });

                    //filter the parsed ones in time order
                    var filtered = $filter('orderBy')(parsed, function(element) {
                        return element.starts.format('X');
                    });

                    //add the unparsed matches to the end
                    filtered.push.apply(filtered, unparsed);
                    deferred.resolve(filtered);
                });

                return deferred.promise;
            }
        };
    }])

    .factory('HtmlNotifications', ['$q', function($q) {
        return {
            /**
             * @returns boolean true if notification available, false otherwise
             */
            supports: function() {
                return "Notification" in window;
            },
            currentPermission: function() {
                if(!Notification.permission) {
                    Notification.permission = 'default';
                }
                return Notification.permission;
            },
            /**
             * @returns {promise} resolves on granted, rejects on not
             */
            requestPermission: function() {
                var def = $q.defer();
                if(Notification.permission !== 'granted') {
                    //request the permission and update the permission value
                    Notification.requestPermission(function (status) {
                        console.log(status);
                        if (Notification.permission !== status) {
                            Notification.permission = status;
                        }
                        status === 'granted' ? def.resolve() : def.reject();
                    });
                } else {
                    def.resolve();
                }
                return def.promise;
            },
            /**
             * @param title the title for the notification
             * @param options
             * @param body the body of the notification
             */
            notify: function(title, body, options) {
                this.requestPermission().then(function() {
                    options = options || [];
                    options.icon = options.icon || 'images/favicon.png';
                    options.body = body || '';

                    new Notification(title, options);
                });
            }
        };
    }])

    .directive('dateTimePicker', [function() {
        return {
            restrict: 'AE',
            scope: {
                minDate: '=?',
                pickedDate: '=',
                meridian: '=',
                timeZone: '='
            },
            templateUrl: 'partials/dateTimePicker.html',
            link: function($scope, $element, $attr) {
                $scope.opened = false;

                $scope.internalJSDate = $scope.pickedDate.toDate();
                $scope.internalMinDate = $scope.minDate.toDate();

                $scope.$watch('internalJSDate', function() {
                    $scope.updatePickedDate();
                });
                $scope.$watch('timeZone', function() {
                    $scope.updatePickedDate();
                });

                $scope.updatePickedDate = function() {
                    var pickedMoment = moment($scope.internalJSDate);
                    var formattedMoment = pickedMoment.format('MMM DD HH:mm');
                    $scope.pickedDate = moment.tz(formattedMoment, 'MMM DD HH:mm', $scope.timeZone);
                };

                $scope.toggle = function($event) {
                    $event.preventDefault();
                    $event.stopPropagation();
                    $scope.opened = !$scope.opened;
                }
            }
        }
    }]);<|endoftext|>


<commit_before>$(document).ready(function() {

    /*
     * Data Tables
     */

    // Setup - add a text input to filtesearch footers
    $('#table-maplist tfoot th.filtersearch').each( function () {
        var title = $(this).text();
        $(this).html( '<input type="text" placeholder="filter '+title+'" />' );
    } );

    // Setup - add a dropdown to dropdownsearch footers
    $('#table-maplist tfoot th.dropdownsearch').each( function () {
        var title = $(this).text();
        $(this).html( '<select><option value=""></option><option value="yes">' + title + '</option><option value="no">no ' + title + '</option></select>' );
    } );

    var table = $('#table-maplist').DataTable( {
        "ajax": "data/maps.json",
        "lengthMenu": [[50, 100, 250, 500, 1000], [50, 100, 250, 500, 1000]],
        "pageLength": 250,
        "colReorder": true,
        "stateSave": true,
        "fixedHeader": {
            "header": true,
            "headerOffset": $('#main-nav').height()
        },
        "processing": true,
        "deferRender": true,
        "language": {
            "search": "",
            "lengthMenu": "_MENU_",
            "processing": '
Processing a large file, this might take a second

'
        },
        "buttons": [
            {
                "extend": "csvHtml5",
                "text": '',
            },
            {
                "extend": "colvis",
                "postfixButtons": [ 'colvisRestore' ],
                "text": ''
            }
        ],
        "dom": "<'#table-controls'lfB>" +
                "<'row'<'col-sm-12'tr>>" +
                "<'row'<'col-sm-5'i><'col-sm-7'p>>",
        "columns": [
            { "data": "pk3" },
            { "data": "bsp[
 ]" },
            { "data": "filesize" },
            { "data": "filesize" },
            { "data": "shasum" },
            { "data": "mapshot" },
            { "data": "title" },
            { "data": "author" },
            { "data": "gametypes[, ]" },
            { "data": "map[, ]" },
            { "data": "radar[, ]" },
            { "data": "waypoints[, ]" },
            { "data": "license" },
            { "data": "date" }
        ],
        "columnDefs": [
            {   // pk3
                "targets": 0,
                "render": function ( data, type, full, meta ) {
                    var pk3 = data;
                    if (type === 'display' && data.length > 40) {
                        data = ''+data.substr( 0, 38 )+'...';
                    }
                    return '' + data + '';
                }
            },
            {   // bsp
                "targets": 1,
                "render": function ( data, type, full, meta ) {
                    if (data != false && data.length > 0) {
            			if (data.length > 40 && data.indexOf('
') == -1) {
                            data = ''+data.substr( 0, 38 )+'...';
        		    	}
        		    }
                    return data;
                }
            },
            {   // filesize
                "targets": 2,
                "orderData": 3,
                "render": function ( data, type, full, meta ) {
                    return(bytesToSize(data));
                }
            },
            {   // filesize (bytes)
                "targets": 3,
                "visible": false,
                "searchable": false
            },
            {   // shasum
                "targets": 4,
                "visible": false,
            },
            {   // mapshot file
                "targets": 5,
                "render": function ( data, type, full, meta ) {
                    var string = "";
                    if (data.length > 0) {
                        data.forEach(function(value, index, array) {
                            string += '';
                        });
                    }
                    return string;
                }
            },
            {   // title
                "targets": 6,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? data : "";
                }
            },
            {   // author
                "targets": 7,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? data : "";
                }
            },
            {   // map file
                "targets": 9,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {   // radar file
                "targets": 10,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {   // waypoints file
                "targets": 11,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {   // license file
                "targets": 12,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {
                // date
                "targets": 13,
                "render": function ( data, type, full, meta ) {
                    d = new Date(0);
                    d.setUTCSeconds(data);
                    return d.toISOString().slice(0,10);
                }
            }
        ],
        "initComplete": function( settings, json ) {
            // clear filters on page load
            $("tfoot input").val('').trigger('change');
            $("tfoot select").val('').trigger('change');
            // Hacky way to put the controls in the navbar
            $("#table-controls .btn").addClass("btn-sm");
            $("#table-maplist_length").addClass("pull-right");
            $("#table-maplist_filter").addClass("pull-right");
            $("#table-controls").detach().appendTo('#nav-table-controls');
            initPopovers();
        }
    } );

    // Reorder callback
    table.on( 'column-reorder', function ( e, settings, details ) {
        initPopovers();
    });

    // Popover image previews
    function initPopovers() {
        $('a[rel=popover]').popover({
            html: true,
            trigger: 'hover',
            content: function () {
                return '';
            }
        });
    }

    // Apply filtersearch and dropdownsearch
    table.columns().every( function () {
        var that = this;

        $( 'input', this.footer() ).on( 'keyup change', function () {
            if ( that.search() !== this.value ) {
                that
                    .search( this.value )
                    .draw();
            }
        } );

        $( 'select', this.footer() ).on( 'change', function () {
            if ( that.search() !== this.value ) {
                that
                    .search( this.value )
                    .draw();
            }
        } );

    } );

    /*
     * Charts
     */

    var chartsDrawn = false;
    var allCharts = [];

    function drawCharts(data) {
            $("#charts").show();

            // Pie
            allCharts[0] = c3.generate(data.mapinfos);
            allCharts[1] = c3.generate(data.mapshots);
            allCharts[2] = c3.generate(data.maps);
            allCharts[3] = c3.generate(data.radars);
            allCharts[4] = c3.generate(data.waypoints);
            allCharts[5] = c3.generate(data.licenses);

            // Scatter
            var filesizes = {
                axis: { x: { show: false }, rotated: true },
                tooltip: {
                    format: {
                        title: function (x) { return; },
                        name: function (name, ratio, id, index) { return "size"; },
                        value: function (value, ratio, id, index) { return bytesToSize(value); }
                    }
                }
            };

            $.extend(filesizes, data.filesizes);
            allCharts[6] = c3.generate(filesizes);

            // Line
            allCharts[7] = c3.generate(data.mapsbyyear);

            $("#loading-charts").hide();
    }

    function hideCharts() {
        allCharts.forEach(function(value, index, array) {
            value.hide();
        });
    }

    function showCharts() {
        $("#loading-charts").hide();
        $("#charts").show();
        allCharts.forEach(function(value, index, array) {
            value.show();
        });
    }

    // Need to hide datatables when changing tabs for fixedHeader
    var visible = true;
    var tableContainer = $(table.table().container());

    // Bootstrap tab shown event
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {

        // decide whether to show the table or not
        if (visible) { // hide table
            $("#nav-table-controls").hide();
            tableContainer.css('display', 'none');
        } else { // show table
            $("#nav-table-controls").show();
            tableContainer.css('display', 'block');
            hideCharts();
        }

        table.fixedHeader.adjust();

        visible = ! visible;

        $("#charts").hide();
        $("#loading-charts").show();

        if (!chartsDrawn) {
            $.get('data/charts.json', function(data) {
                drawCharts(data);
                chartsDrawn = true;
            });
        } else {
            showCharts();
        }

    });

} );

function bytesToSize(bytes) {
   var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
   if (bytes == 0) return '0 Byte';
   var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
   return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};

<commit_msg>had to put the drawcallback back<commit_after>$(document).ready(function() {

    /*
     * Data Tables
     */

    // Setup - add a text input to filtesearch footers
    $('#table-maplist tfoot th.filtersearch').each( function () {
        var title = $(this).text();
        $(this).html( '<input type="text" placeholder="filter '+title+'" />' );
    } );

    // Setup - add a dropdown to dropdownsearch footers
    $('#table-maplist tfoot th.dropdownsearch').each( function () {
        var title = $(this).text();
        $(this).html( '<select><option value=""></option><option value="yes">' + title + '</option><option value="no">no ' + title + '</option></select>' );
    } );

    var table = $('#table-maplist').DataTable( {
        "ajax": "data/maps.json",
        "lengthMenu": [[50, 100, 250, 500, 1000], [50, 100, 250, 500, 1000]],
        "pageLength": 250,
        "colReorder": true,
        "stateSave": true,
        "fixedHeader": {
            "header": true,
            "headerOffset": $('#main-nav').height()
        },
        "processing": true,
        "deferRender": true,
        "language": {
            "search": "",
            "lengthMenu": "_MENU_",
            "processing": '
Processing a large file, this might take a second

'
        },
        "buttons": [
            {
                "extend": "csvHtml5",
                "text": '',
            },
            {
                "extend": "colvis",
                "postfixButtons": [ 'colvisRestore' ],
                "text": ''
            }
        ],
        "dom": "<'#table-controls'lfB>" +
                "<'row'<'col-sm-12'tr>>" +
                "<'row'<'col-sm-5'i><'col-sm-7'p>>",
        "columns": [
            { "data": "pk3" },
            { "data": "bsp[
 ]" },
            { "data": "filesize" },
            { "data": "filesize" },
            { "data": "shasum" },
            { "data": "mapshot" },
            { "data": "title" },
            { "data": "author" },
            { "data": "gametypes[, ]" },
            { "data": "map[, ]" },
            { "data": "radar[, ]" },
            { "data": "waypoints[, ]" },
            { "data": "license" },
            { "data": "date" }
        ],
        "columnDefs": [
            {   // pk3
                "targets": 0,
                "render": function ( data, type, full, meta ) {
                    var pk3 = data;
                    if (type === 'display' && data.length > 40) {
                        data = ''+data.substr( 0, 38 )+'...';
                    }
                    return '' + data + '';
                }
            },
            {   // bsp
                "targets": 1,
                "render": function ( data, type, full, meta ) {
                    if (data != false && data.length > 0) {
            			if (data.length > 40 && data.indexOf('
') == -1) {
                            data = ''+data.substr( 0, 38 )+'...';
        		    	}
        		    }
                    return data;
                }
            },
            {   // filesize
                "targets": 2,
                "orderData": 3,
                "render": function ( data, type, full, meta ) {
                    return(bytesToSize(data));
                }
            },
            {   // filesize (bytes)
                "targets": 3,
                "visible": false,
                "searchable": false
            },
            {   // shasum
                "targets": 4,
                "visible": false,
            },
            {   // mapshot file
                "targets": 5,
                "render": function ( data, type, full, meta ) {
                    var string = "";
                    if (data.length > 0) {
                        data.forEach(function(value, index, array) {
                            string += '';
                        });
                    }
                    return string;
                }
            },
            {   // title
                "targets": 6,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? data : "";
                }
            },
            {   // author
                "targets": 7,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? data : "";
                }
            },
            {   // map file
                "targets": 9,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {   // radar file
                "targets": 10,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {   // waypoints file
                "targets": 11,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {   // license file
                "targets": 12,
                "render": function ( data, type, full, meta ) {
                    return (data != false) ? "yes" : "no";
                }
            },
            {
                // date
                "targets": 13,
                "render": function ( data, type, full, meta ) {
                    d = new Date(0);
                    d.setUTCSeconds(data);
                    return d.toISOString().slice(0,10);
                }
            }
        ],
        "initComplete": function( settings, json ) {
            // clear filters on page load
            $("tfoot input").val('').trigger('change');
            $("tfoot select").val('').trigger('change');
            // Hacky way to put the controls in the navbar
            $("#table-controls .btn").addClass("btn-sm");
            $("#table-maplist_length").addClass("pull-right");
            $("#table-maplist_filter").addClass("pull-right");
            $("#table-controls").detach().appendTo('#nav-table-controls');
        },
        "drawCallback": function( settings ) {
            initPopovers();
        }
    } );

    // Reorder callback
    table.on( 'column-reorder', function ( e, settings, details ) {
        initPopovers();
    });

    // Popover image previews
    function initPopovers() {
        $('a[rel=popover]').popover({
            html: true,
            trigger: 'hover',
            content: function () {
                return '';
            }
        });
    }

    // Apply filtersearch and dropdownsearch
    table.columns().every( function () {
        var that = this;

        $( 'input', this.footer() ).on( 'keyup change', function () {
            if ( that.search() !== this.value ) {
                that
                    .search( this.value )
                    .draw();
            }
        } );

        $( 'select', this.footer() ).on( 'change', function () {
            if ( that.search() !== this.value ) {
                that
                    .search( this.value )
                    .draw();
            }
        } );

    } );

    /*
     * Charts
     */

    var chartsDrawn = false;
    var allCharts = [];

    function drawCharts(data) {
            $("#charts").show();

            // Pie
            allCharts[0] = c3.generate(data.mapinfos);
            allCharts[1] = c3.generate(data.mapshots);
            allCharts[2] = c3.generate(data.maps);
            allCharts[3] = c3.generate(data.radars);
            allCharts[4] = c3.generate(data.waypoints);
            allCharts[5] = c3.generate(data.licenses);

            // Scatter
            var filesizes = {
                axis: { x: { show: false }, rotated: true },
                tooltip: {
                    format: {
                        title: function (x) { return; },
                        name: function (name, ratio, id, index) { return "size"; },
                        value: function (value, ratio, id, index) { return bytesToSize(value); }
                    }
                }
            };

            $.extend(filesizes, data.filesizes);
            allCharts[6] = c3.generate(filesizes);

            // Line
            allCharts[7] = c3.generate(data.mapsbyyear);

            $("#loading-charts").hide();
    }

    function hideCharts() {
        allCharts.forEach(function(value, index, array) {
            value.hide();
        });
    }

    function showCharts() {
        $("#loading-charts").hide();
        $("#charts").show();
        allCharts.forEach(function(value, index, array) {
            value.show();
        });
    }

    // Need to hide datatables when changing tabs for fixedHeader
    var visible = true;
    var tableContainer = $(table.table().container());

    // Bootstrap tab shown event
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {

        // decide whether to show the table or not
        if (visible) { // hide table
            $("#nav-table-controls").hide();
            tableContainer.css('display', 'none');
        } else { // show table
            $("#nav-table-controls").show();
            tableContainer.css('display', 'block');
            hideCharts();
        }

        table.fixedHeader.adjust();

        visible = ! visible;

        $("#charts").hide();
        $("#loading-charts").show();

        if (!chartsDrawn) {
            $.get('data/charts.json', function(data) {
                drawCharts(data);
                chartsDrawn = true;
            });
        } else {
            showCharts();
        }

    });

} );

function bytesToSize(bytes) {
   var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
   if (bytes == 0) return '0 Byte';
   var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
   return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
};

<|endoftext|>


<commit_before>var table = null;
var socket = io.connect(window.location.protocol + '//' + document.domain + ':' + location.port);
var uuid;
var running = false;

$('#codeform').on('submit', function(d) { d.preventDefault(); });

function submitCode() {
    var form = $('#codeform');

    $('#errorconsoletab').css('font-weight', 'normal');
    $('#errors').html('');
    $('#output').html('')

    socket.emit('submit', {
        code: $('#code').val(),
        inputs: $('#inputs').val(),
        debug: $('#debug').val(),
        version: $('#version').data('version'),
        uid: uuid
    }, function(resp){
        console.log('Successfully submitted job.');

        // Change the status and update the button functionality
        running = true;
        $('#run').text('Kill');
    });
}

socket.on('connect', function(data){
    console.log('Connected to server.');
    $('#run').removeClass('disabled');
    $('#run').text('Run');
});

// When the server acknowledges that we are connected it will issue
// us an ID which we can use to get updates
socket.on('connection', function(data) {
    uuid = data.session_id;
    console.log('Session ID: ' + uuid);
});

$('#explain').on('click', function(d) {
    var code = $('#code').val();
    var version = $('#version').data('version');

    // Do not submit the form unless there is code
    if ( code === '' ) {
        return;
    }

    $('#modal-explain').text('Parsing...');

    // Going to get the explanation and post it in a balloon
    $('#explainmodal').modal();

    $.ajax({
        url: '/explain',
        method: 'GET',
        data:{
            code: code,
            version: version
        },
        success: function(resp) {
            alltext = '';
            resp['data'].forEach(function (item) {
                alltext = alltext + item.value
            });
            $('#modal-explain').text(alltext);
        }
    });
});

function getlink() {

    var data = {
        'code': $('#code').val(),
        'inputs': $('#inputs').val(),
        'version': $('#version').data('version')};

    var link = $.param(data);

    // Now sanitize for SE
    return link.replace(/[!'()*]/g, function(ch) {
        return '%' + ch.charCodeAt(0).toString(16);
    });
}

socket.on('killed', function(data) {
    $('#run').text('Run');
    running = false;
    console.log('Task killed.');
});

socket.on('complete', function(msg) {
    $('#run').text('Run');
    running = false;
    console.log('Task complete.');
});

$('#run').on('click', function() {
    if ( running ) {
        socket.emit('kill', {uid: uuid});
    } else {
        submitCode();
    }
});

socket.on('status', function(data) {
    var output = $('#output');
    var errors = $('#errors');

    console.log('Output received.');

    // Clear the output
    output.text('');

    if ( data['session'] === uuid ) {
        data['data'].forEach(function(item) {
            switch ( item.type ) {
                case 'image':
                case 'image_nn':

                    // Remove any previous images (simulates drawnow)
                    var thumb = $('.thumb');

                    if ( thumb.length ){
                        $(thumb).find('.imshow').attr('src', item.value);
                    } else {
                        val = '
';
                        output.append(val);
                        $('.thumb').on('click', function(e) {
                            var url = $(this).find('.imshow').attr('src');
                            $('#imagepreview').attr('src', url);
                            var img = $('#imagepreview').get(0);

                            $('#dimensions').text(img.naturalHeight + ' x ' + img.naturalWidth);
                            $('#imagemodal').modal('show');
                        });

                        if ( item.type === 'image_nn' ){
                            $('.imshow').addClass('nn-interp');
                            $('#imagepreview').addClass('nn-interp');
                        } else {
                            $('.imshow').removeClass('nn-interp');
                            $('#imagepreview').removeClass('nn-interp');
                        }
                    }

                    break;
                case 'stderr':
                    errors.append(document.createTextNode(item.value + '\n'));
                    $('#errorconsoletab').css('font-weight', 'bold');
                    break;
                default:
                    output.append(document.createTextNode(item.value));
            }
        });
    }
});

function refreshHelp() {
    // If the table is initialized, then refresh it
    if ( table ) {
        table.ajax.url('help/' + $('#version').data('version')).load();
    }
}

function checkInputType(obj){
    // If contains any alpha-numeric characters
    var str = $(obj).val();

    if ( str.toLowerCase() === str.toUpperCase() ){
        // Then we assume that this is numeric
        $('#array_input').prop('checked', true);
        $('#string_input').prop('checked', false);
    } else {
        $('#array_input').prop('checked', false);
        $('#string_input').prop('checked', true);
    }
}

function parseArray(str){
    // Replace ][ with ; and [[ with [ and ]] with ]
    return str.replace(/\]\s*,?\s*\[/g, '; ').
               replace(/\[\s*\[\s*/g, '[').
               replace(/\]\s*\]\s*/g, ']').
               replace(/\s+/g, ' ').
               replace(/\s*,\s*/g, ', ');
}

function parseString(str){
    // Parse as raw string
    str = str.split('\n');

    // Now pad any strings as needed
    var maxLength = 0;
    $.each(str, function(index, val){
        maxLength = Math.max(maxLength, val.length);
    });

    if ( str.length > 1 ){
        output = "[";
    } else {
        output = '';
    }

    for ( var k = 0; k < str.length; ++k ){
        num2pad = maxLength - str[k].length;
        str[k] += new Array(num2pad+1).join(' ');
        output = output + "'" + str[k] + "';";
    }

    output = output.replace(/;$/g, '');

    if ( str.length > 1 ){
        output = output + ']';
    }

    return output;
}

$('#paste_apply').on('click', function(evnt){

    var input = $('#paste_input_field').val();

    switch ( $("input[name=format]:checked").val() ) {
        case 'array':
            input = parseArray(input);
            break;
        case 'string':
            input = parseString(input);
            break;
    }

    if ( $('#inputs').val().length ){
        input = '\n' + input;
    }

    $('#inputs').val($('#inputs').val() + input);
    $('#pastemodal').modal('toggle');
    $('#paste_input_field').val('');
});

$('#paste_input').on('click', function(evnt){
    // Open up modal dialog to add data
    $('#pastemodal').modal();
});

$('#pastemodal').on('shown.bs.modal', function(){
    $('#paste_input_field').focus();
});

$('.version').on('click', function(e) {
    $('#version').text(e.target.text).data('version', $(e.target).data('version'));
    refreshHelp();
    e.preventDefault();
});

$('#save').on('click', function(e) {
    link = '?' + getlink();
    history.pushState({'Title': '', 'Url': link}, '', link);
    e.preventDefault();
});

// When the image preview dialog is closed, reset the share link
$('#imagemodal').on('hidden.bs.modal', function () {
    $('#share').removeClass('flip-side-2').addClass('flip-side-1');
    $('#sharelink').removeClass('flip-side-1');
});

// Be sure that we place the CSRF token in all AJAX request headers
$.ajaxSetup({
    // Add a header containing the CSRF token if needed
    beforeSend: function(xhr, settings) {
        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken",
                $('meta[name=csrf-token]').attr('content'));
        }
    }
});

$('#share').on('click', function(e){
    // Display loading while we upload to imgur and get the link
    $('#imgurlink').val('Loading...').css('color', '');

    // Flip over to the link to prevent the user from clicking share again
    $('#share').addClass('flip-side-2');
    $('#sharelink').addClass('flip-side-1');

    $.post({
        url: '/share',
        data: {'data': $('.thumb').find('.imshow').attr('src')},
        success: function(resp){
            // Paste the link into the input box and highlight it
            $('#imgurlink').val(resp.link)
                .prop('disabled', false)
                .css('color', 'black')
                .select();
        },
        error: function(resp){
            // Some unspecified error happened (could be CSRF or others)
            $('#imgurlink').val('SERVER ERROR')
                .css('color', 'red');
        }
    });
});

function countChar(val) {
    var count = val.value.length;

    if ( count === 1 ) {
        $('#charcount').text('(' + count + ' character)');
    } else {
        $('#charcount').text('(' + count + ' characters)');
    }
}

function toggleDocumentation(){

    var navitem = $('#doctoggle').parent();
    var activeClasses = 'col-md-6 col-lg-6 col-sm-6';

    if ( navitem.hasClass('active') ){
        navitem.removeClass('active');
        $('#left_div').removeClass(activeClasses);
        $('.drawer').drawer('hide');
    } else {
        navitem.addClass('active');
        $('#left_div').addClass(activeClasses);
        $('.drawer').drawer('show');

        // Create the datatable if it doesn't exist already
        if ( table === null ){
            table = $('#documentation').DataTable({
                paging: false,
                ordering: false,
                info: false,
                ajax: 'help/' + $('#version').data('version'),
                stripe: true,
                scrollY: '100vh',
                scrollX: false,
                scrollCollapse: true,
                order: [[ 0, "asc"]],
                columns: [
                    {
                        data: 'source',
                        orderable: true
                    },
                    {
                        data: null,
                        orderable: false,
                        render: function(data) {
                            output = '' + data.brief + '';
                            if ( data.arguments ){
                                output = output + '\n' + data.arguments;
                            }
                            return output + '\n' + data.description;
                        }
                    }]
            });

            // Custom search function to handle single " characters
            $('input[type=search]').on( 'keyup', function () {

                var str = this.value;
                var hasQuote = false;

                // If only one " then replace with ""
                if ( (str.match(/"/g) || []).length === 1 ){
                    str = str.replace(/"/g, '""');
                    hasQuote = true;
                }

                // Get the original length of the input
                var origLen = this.value.length;

                // Determine if it starts with X, Y, or Z
                var hasXYZ = str.match('^[XYZ]');

                // If we have a single character OR the search string
                // starts with X, Y, or Z and is two characters (or 3 if
                // one is a quote)
                if ( origLen === 1 || ( hasXYZ && origLen === 2 ) ) {
                    // Search just the first column (no regex, non-smart,
                    // and case-sensitive)
                    table.columns(0).search(this.value, false, false, false).draw();
                } else {
                    // Clear any searches on the first column
                    table.columns(0).search('').draw();

                    // Apply the search to the table as a whole
                    table.search(str).draw();
                }
            });
        }
    }
}

$('.drawer').on('shown.bs.drawer', function(){
    $('input[type=search]').focus();
});

$('#doctoggle').on('click', function(evnt){
    toggleDocumentation();
    evnt.preventDefault();
});

$('#docbutton').on('click', function(evnt){
    toggleDocumentation();
});
<commit_msg>Add timeout for submitting code so we can track errors<commit_after>var table = null;
var socket = io.connect(window.location.protocol + '//' + document.domain + ':' + location.port);
var uuid;
var running = false;

$('#codeform').on('submit', function(d) { d.preventDefault(); });

function timeoutFcn() {
    // Send a google analytics event if it's defined
    try {
        ga('send', 'event', 'errors', 'error', 'Submit failed');
    } catch(err) {}

    // Force the socket to reconnect
    socket.disconnect();
    socket.connect();
}

function submitCode() {
    var form = $('#codeform');

    $('#errorconsoletab').css('font-weight', 'normal');
    $('#errors').html('');
    $('#output').html('');

    var timeoutId = setTimeout(timeoutFcn, 2000);

    socket.emit('submit', {
        code: $('#code').val(),
        inputs: $('#inputs').val(),
        debug: $('#debug').val(),
        version: $('#version').data('version'),
        uid: uuid
    }, function(resp){
        // Make sure that we don't fire the timeout callback
        clearTimeout(timeoutId);

        // Change the status and update the button functionality
        running = true;
        $('#run').text('Kill');
    });
}

socket.on('connect', function(data){
    console.log('Connected to server.');
    $('#run').removeClass('disabled');
    $('#run').text('Run');
});

// When the server acknowledges that we are connected it will issue
// us an ID which we can use to get updates
socket.on('connection', function(data) {
    uuid = data.session_id;
    console.log('Session ID: ' + uuid);
});

$('#explain').on('click', function(d) {
    var code = $('#code').val();
    var version = $('#version').data('version');

    // Do not submit the form unless there is code
    if ( code === '' ) {
        return;
    }

    $('#modal-explain').text('Parsing...');

    // Going to get the explanation and post it in a balloon
    $('#explainmodal').modal();

    $.ajax({
        url: '/explain',
        method: 'GET',
        data:{
            code: code,
            version: version
        },
        success: function(resp) {
            alltext = '';
            resp['data'].forEach(function (item) {
                alltext = alltext + item.value
            });
            $('#modal-explain').text(alltext);
        }
    });
});

function getlink() {

    var data = {
        'code': $('#code').val(),
        'inputs': $('#inputs').val(),
        'version': $('#version').data('version')};

    var link = $.param(data);

    // Now sanitize for SE
    return link.replace(/[!'()*]/g, function(ch) {
        return '%' + ch.charCodeAt(0).toString(16);
    });
}

socket.on('killed', function(data) {
    $('#run').text('Run');
    running = false;
    console.log('Task killed.');
});

socket.on('complete', function(msg) {
    $('#run').text('Run');
    running = false;
    console.log('Task complete.');
});

$('#run').on('click', function() {
    if ( running ) {
        socket.emit('kill', {uid: uuid});
    } else {
        submitCode();
    }
});

socket.on('status', function(data) {
    var output = $('#output');
    var errors = $('#errors');

    console.log('Output received.');

    // Clear the output
    output.text('');

    if ( data['session'] === uuid ) {
        data['data'].forEach(function(item) {
            switch ( item.type ) {
                case 'image':
                case 'image_nn':

                    // Remove any previous images (simulates drawnow)
                    var thumb = $('.thumb');

                    if ( thumb.length ){
                        $(thumb).find('.imshow').attr('src', item.value);
                    } else {
                        val = '
';
                        output.append(val);
                        $('.thumb').on('click', function(e) {
                            var url = $(this).find('.imshow').attr('src');
                            $('#imagepreview').attr('src', url);
                            var img = $('#imagepreview').get(0);

                            $('#dimensions').text(img.naturalHeight + ' x ' + img.naturalWidth);
                            $('#imagemodal').modal('show');
                        });

                        if ( item.type === 'image_nn' ){
                            $('.imshow').addClass('nn-interp');
                            $('#imagepreview').addClass('nn-interp');
                        } else {
                            $('.imshow').removeClass('nn-interp');
                            $('#imagepreview').removeClass('nn-interp');
                        }
                    }

                    break;
                case 'stderr':
                    errors.append(document.createTextNode(item.value + '\n'));
                    $('#errorconsoletab').css('font-weight', 'bold');
                    break;
                default:
                    output.append(document.createTextNode(item.value));
            }
        });
    }
});

function refreshHelp() {
    // If the table is initialized, then refresh it
    if ( table ) {
        table.ajax.url('help/' + $('#version').data('version')).load();
    }
}

function checkInputType(obj){
    // If contains any alpha-numeric characters
    var str = $(obj).val();

    if ( str.toLowerCase() === str.toUpperCase() ){
        // Then we assume that this is numeric
        $('#array_input').prop('checked', true);
        $('#string_input').prop('checked', false);
    } else {
        $('#array_input').prop('checked', false);
        $('#string_input').prop('checked', true);
    }
}

function parseArray(str){
    // Replace ][ with ; and [[ with [ and ]] with ]
    return str.replace(/\]\s*,?\s*\[/g, '; ').
               replace(/\[\s*\[\s*/g, '[').
               replace(/\]\s*\]\s*/g, ']').
               replace(/\s+/g, ' ').
               replace(/\s*,\s*/g, ', ');
}

function parseString(str){
    // Parse as raw string
    str = str.split('\n');

    // Now pad any strings as needed
    var maxLength = 0;
    $.each(str, function(index, val){
        maxLength = Math.max(maxLength, val.length);
    });

    if ( str.length > 1 ){
        output = "[";
    } else {
        output = '';
    }

    for ( var k = 0; k < str.length; ++k ){
        num2pad = maxLength - str[k].length;
        str[k] += new Array(num2pad+1).join(' ');
        output = output + "'" + str[k] + "';";
    }

    output = output.replace(/;$/g, '');

    if ( str.length > 1 ){
        output = output + ']';
    }

    return output;
}

$('#paste_apply').on('click', function(evnt){

    var input = $('#paste_input_field').val();

    switch ( $("input[name=format]:checked").val() ) {
        case 'array':
            input = parseArray(input);
            break;
        case 'string':
            input = parseString(input);
            break;
    }

    if ( $('#inputs').val().length ){
        input = '\n' + input;
    }

    $('#inputs').val($('#inputs').val() + input);
    $('#pastemodal').modal('toggle');
    $('#paste_input_field').val('');
});

$('#paste_input').on('click', function(evnt){
    // Open up modal dialog to add data
    $('#pastemodal').modal();
});

$('#pastemodal').on('shown.bs.modal', function(){
    $('#paste_input_field').focus();
});

$('.version').on('click', function(e) {
    $('#version').text(e.target.text).data('version', $(e.target).data('version'));
    refreshHelp();
    e.preventDefault();
});

$('#save').on('click', function(e) {
    link = '?' + getlink();
    history.pushState({'Title': '', 'Url': link}, '', link);
    e.preventDefault();
});

// When the image preview dialog is closed, reset the share link
$('#imagemodal').on('hidden.bs.modal', function () {
    $('#share').removeClass('flip-side-2').addClass('flip-side-1');
    $('#sharelink').removeClass('flip-side-1');
});

// Be sure that we place the CSRF token in all AJAX request headers
$.ajaxSetup({
    // Add a header containing the CSRF token if needed
    beforeSend: function(xhr, settings) {
        if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
            xhr.setRequestHeader("X-CSRFToken",
                $('meta[name=csrf-token]').attr('content'));
        }
    }
});

$('#share').on('click', function(e){
    // Display loading while we upload to imgur and get the link
    $('#imgurlink').val('Loading...').css('color', '');

    // Flip over to the link to prevent the user from clicking share again
    $('#share').addClass('flip-side-2');
    $('#sharelink').addClass('flip-side-1');

    $.post({
        url: '/share',
        data: {'data': $('.thumb').find('.imshow').attr('src')},
        success: function(resp){
            // Paste the link into the input box and highlight it
            $('#imgurlink').val(resp.link)
                .prop('disabled', false)
                .css('color', 'black')
                .select();
        },
        error: function(resp){
            // Some unspecified error happened (could be CSRF or others)
            $('#imgurlink').val('SERVER ERROR')
                .css('color', 'red');
        }
    });
});

function countChar(val) {
    var count = val.value.length;

    if ( count === 1 ) {
        $('#charcount').text('(' + count + ' character)');
    } else {
        $('#charcount').text('(' + count + ' characters)');
    }
}

function toggleDocumentation(){

    var navitem = $('#doctoggle').parent();
    var activeClasses = 'col-md-6 col-lg-6 col-sm-6';

    if ( navitem.hasClass('active') ){
        navitem.removeClass('active');
        $('#left_div').removeClass(activeClasses);
        $('.drawer').drawer('hide');
    } else {
        navitem.addClass('active');
        $('#left_div').addClass(activeClasses);
        $('.drawer').drawer('show');

        // Create the datatable if it doesn't exist already
        if ( table === null ){
            table = $('#documentation').DataTable({
                paging: false,
                ordering: false,
                info: false,
                ajax: 'help/' + $('#version').data('version'),
                stripe: true,
                scrollY: '100vh',
                scrollX: false,
                scrollCollapse: true,
                order: [[ 0, "asc"]],
                columns: [
                    {
                        data: 'source',
                        orderable: true
                    },
                    {
                        data: null,
                        orderable: false,
                        render: function(data) {
                            output = '' + data.brief + '';
                            if ( data.arguments ){
                                output = output + '\n' + data.arguments;
                            }
                            return output + '\n' + data.description;
                        }
                    }]
            });

            // Custom search function to handle single " characters
            $('input[type=search]').on( 'keyup', function () {

                var str = this.value;
                var hasQuote = false;

                // If only one " then replace with ""
                if ( (str.match(/"/g) || []).length === 1 ){
                    str = str.replace(/"/g, '""');
                    hasQuote = true;
                }

                // Get the original length of the input
                var origLen = this.value.length;

                // Determine if it starts with X, Y, or Z
                var hasXYZ = str.match('^[XYZ]');

                // If we have a single character OR the search string
                // starts with X, Y, or Z and is two characters (or 3 if
                // one is a quote)
                if ( origLen === 1 || ( hasXYZ && origLen === 2 ) ) {
                    // Search just the first column (no regex, non-smart,
                    // and case-sensitive)
                    table.columns(0).search(this.value, false, false, false).draw();
                } else {
                    // Clear any searches on the first column
                    table.columns(0).search('').draw();

                    // Apply the search to the table as a whole
                    table.search(str).draw();
                }
            });
        }
    }
}

$('.drawer').on('shown.bs.drawer', function(){
    $('input[type=search]').focus();
});

$('#doctoggle').on('click', function(evnt){
    toggleDocumentation();
    evnt.preventDefault();
});

$('#docbutton').on('click', function(evnt){
    toggleDocumentation();
});
<|endoftext|>


<commit_before>$(document).ready(function() {

	// Get Money Raised Data and Adjust Progress Bar
	var khs_spreadsheet = "https://spreadsheets.google.com/feeds/list/1PE1umwfQwSwaNxX_Hishe8kKmcNPRQmRBv-GrPrBFDw/od6/public/basic?alt=json";

	$.getJSON(khs_spreadsheet).done(function(data) {

		var money_raised = 0;

		for (var i = 1; i < data.feed.entry.length; i++) {

			if (data.feed.entry[i].content['$t'].length > 0) {

				var entry = data.feed.entry[i].content['$t'];

				money_raised += parseInt(entry.replace(/[^0-9.]/g, ""));
			}
		};

		var goal = 5000;
		var current_money = (money_raised / goal) * 100;

		$("#money_raised_bar").css({"width": current_money + "%" });
		$("#money_raised_bar").attr("aria-valuenow", current_money);
		$("#current_money").text("$" + money_raised);

	}).fail(function(jqxhr, textStatus, error ) {

		var status = textStatus + ", " + error;
		console.error("Request Failed: " + status );

	});

	// Validate Input Fields and Send Email
	$("#send_email").click(function() {

		event.preventDefault();

		var name = $("#name").val();
		var email = $("#email").val();
		var committe = $("#committe").val();
		var subject = $("#subject").val();
		var message  = $("#message").val();

		if(name === '' || name.length === 0) {
			alert("Name is required.");
			$("#name").focus();
            return false;
		}

		if(email === '' || email.length === 0) {

			alert("Email is required.");
			$("#email").focus();
            return false;
		}

		if(subject === '' || subject.length === 0) {

			alert("Subject is required.");
			$("#subject").focus();
            return false;
		}

		if(message === '' || message.length === 0) {

			alert("Message is required.");
			$("#message").focus();
            return false;
		} else {

			$.post("server/email.php",
				{ name: name,
				  email: email,
				  committe: committe,
				  subject: subject,
				  message: message
				}
			).done(function() {

				// Confirmation takes too long and we can't wait..time for a hail mary play
				alert("Email was sent! Thank you.");
				$('#contact_form').trigger("reset");

			});
		}
	});

  // Image Gallery Initiation and Settings
  // **VIDEO POP-UP ONLY WORK IN A SERVER**
	$('.swipebox').swipebox();
	$('.swipebox-video').swipebox();

});
<commit_msg>Someday we will have email... some day...<commit_after>$(document).ready(function() {

	// Get Money Raised Data and Adjust Progress Bar
	// Spreadsheet: https://docs.google.com/spreadsheets/d/1PE1umwfQwSwaNxX_Hishe8kKmcNPRQmRBv-GrPrBFDw/pubhtml
	var khs_spreadsheet = "https://spreadsheets.google.com/feeds/list/1PE1umwfQwSwaNxX_Hishe8kKmcNPRQmRBv-GrPrBFDw/od6/public/basic?alt=json";

	$.getJSON(khs_spreadsheet).done(function(data) {

		var money_raised = 0;

		for (var i = 1; i < data.feed.entry.length; i++) {

			if (data.feed.entry[i].content['$t'].length > 0) {

				var entry = data.feed.entry[i].content['$t'];

				money_raised += parseInt(entry.replace(/[^0-9.]/g, ""));
			}
		};

		var goal = 5000;
		var current_money = (money_raised / goal) * 100;

		$("#money_raised_bar").css({"width": current_money + "%" });
		$("#money_raised_bar").attr("aria-valuenow", current_money);
		$("#current_money").text("$" + money_raised);

	}).fail(function(jqxhr, textStatus, error ) {

		var status = textStatus + ", " + error;
		console.error("Request Failed: " + status );

	});

  // Image Gallery Initiation and Settings
  // **VIDEO POP-UP ONLY WORK IN A SERVER**
	$('.swipebox').swipebox();
	$('.swipebox-video').swipebox();

});
<|endoftext|>


<commit_before>var __ = window.__ = require('underscore'),
    Backbone = require('backbone'),
    $ = require('jquery');
Backbone.$ = $;
//add to global scope for non-modular libraries
window.Backbone = Backbone;
window.$ = $;
window.jQuery = $;
window.Backbone.$ = $;

var Polyglot = require('node-polyglot'),
    getBTPrice = require('./utils/getBitcoinPrice'),
    router = require('./router'),
    newRouter,
    userModel = require('./models/userMd'),
    userProfileModel = require('./models/userProfileMd'),
    languagesModel = require('./models/languagesMd'),
    mouseWheel = require('jquery-mousewheel'),
    mCustomScrollbar = require('./utils/jquery.mCustomScrollbar.js'),
    pageNavView = require('./views/pageNavVw'),
    chatAppView = require('./views/chatAppVw'),
    newPageNavView,
    newSocketView,
    newChatAppView,
    user = new userModel(),
    userProfile = new userProfileModel(),
    languages = new languagesModel(),
    socketView = require('./views/socketVw'),
    guid = "",
    avatar_hash = "",
    cCode = "",
    serverUrlLocal = "",
    loadProfileCount = 1,
    loadProfileTimeout,
    loadProfileCountdownInterval,
    loadProfileCountdown = 5;

serverUrlLocal = "http://192.168.1.22:18469/api/v1/" || localStorage.getItem("serverUrl") || "http://localhost:18469/api/v1/";

//set the urlRoot of the user model. Defaults to local host if not found
user.urlRoot = serverUrlLocal + "settings";

//set the urlRoot of the user model. Defaults to local host if not found
userProfile.urlRoot = serverUrlLocal + "profile";

//put language in the window so all templates and models can reach it. It's especially important in formatting currency.
window.lang = user.get("language");

//put polyglot in the window so all templates can reach it
window.polyglot = new Polyglot({locale: window.lang});

//retrieve the object that has a matching language code
window.polyglot.extend(__.where(languages.get('languages'), {langCode: window.lang})[0]);

//put the event bus into the window so it's available everywhere
window.obEventBus =  __.extend({}, Backbone.Events);

var reloadProfile = function(){
  "use strict";
  $('.js-loadingMessageModal').removeClass('hide').find('.js-closeIndexModal').addClass('hide');
  loadProfileCountdown=3;

  if(loadProfileCount < 10){
    loadProfileCountdownInterval = setInterval(function(){
      if(loadProfileCountdown > 0){
        $('.js-indexLoadingMsg4').text(loadProfileCountdown);
        loadProfileCountdown--;
      } else {
        $('.js-indexLoadingMsg4').text("");
        clearInterval(loadProfileCountdownInterval);
        loadProfileCount++;
        loadProfile();
      }
    }, 2000);
  } else {
    alert("Your server may not be working correctly. Loading using default settings.");
    $('.js-loadingMessageModal').addClass('hide');
    user.set('serverUrl', serverUrlLocal);
    newSocketView = new socketView({model: user});
    newPageNavView = new pageNavView({model: user, socketView: newSocketView});
    newRouter = new router({userModel: user, socketView: newSocketView});
    Backbone.history.start();
    window.clearTimeout(loadProfileTimeout);
  }
};

var setCurrentBitCoin = function(cCode, userModel, callback) {
  "use strict";
  getBTPrice(cCode, function (btAve, currencyList) {
    //put the current bitcoin price in the window so it doesn't have to be passed to models
    if (!btAve){
      currencyList = currencyList.join("\n");
      alert("Bitcoin prices for your selected currency are not available. Your currency has been set to BTC. " +
          "You can change this in the settings console. \n\n The following currencies are available: \n\n" + currencyList);
      window.currentBitcoin = 1;
      userModel.set('currency_code', 'BTC');
    }
    window.currentBitcoin = btAve;
    typeof callback === 'function' && callback();
  });
}

var loadProfile = function() {
  //get the guid from the user profile to put in the user model
  userProfile.fetch({
    success: function (model, response) {
      $('.js-loadingModal').addClass('hide');
      "use strict";
      //make sure profile is not blank
      if (response.profile){
        guid = model.get('profile').guid;
        avatar_hash = model.get('profile').avatar_hash;
        //get the user
        user.fetch({
          success: function (model, response) {
            user.set('serverUrl', serverUrlLocal);
            user.set('guid', guid);
            user.set('avatar_hash', avatar_hash);
            cCode = model.get('currency_code');

            //get user bitcoin price before loading pages
            setCurrentBitCoin(cCode, user, function(){
              $('.js-loadingMessageModal').addClass('hide');
              newSocketView = new socketView({model: user});
              newPageNavView = new pageNavView({model: user, socketView: newSocketView});
              newChatAppView = new chatAppView({model: user, socketView: newSocketView})
              newRouter = new router({userModel: user, socketView: newSocketView});
              Backbone.history.start();
            });

            //every 15 minutes update the bitcoin price for the currently selected currency
            window.bitCoinPriceChecker = setInterval(function () {
              setCurrentBitCoin(model.get('currency_code'), user);
            }, 54000000);
          },
          error: function (model, response) {
            alert("No user was found. Your server may not be working correctly. Loading using default settings.");
            $('.js-loadingMessageModal').addClass('hide');
            user.set('serverUrl', serverUrlLocal);
            newSocketView = new socketView({model: user});
            newPageNavView = new pageNavView({model: user, socketView: newSocketView});
            newChatAppView = new chatAppView({model: user, socketView: newSocketView})
            newRouter = new router({userModel: user, socketView: newSocketView});
            Backbone.history.start();
          }
        });
      }else{
        $('.js-indexLoadingMsg1').text("User profile did not load.");
        $('.js-indexLoadingMsg2').text("Attempting to reach " + serverUrlLocal);
        $('.js-indexLoadingMsg3').text("Reload attempt " + loadProfileCount);
        reloadProfile();
      }
    },
    error: function (model, response) {
      $('.js-loadingModal').addClass('hide');
      $('.js-indexLoadingMsg1').text("Information for your user profile could not be loaded: " + response.statusText);
      $('.js-indexLoadingMsg2').text("Attempting to reach " + serverUrlLocal);
      $('.js-indexLoadingMsg3').text("Reload attempt " + loadProfileCount);
      reloadProfile();
    }
  });
};

loadProfile();
<commit_msg>Revert stupid BC21 issue<commit_after>var __ = window.__ = require('underscore'),
    Backbone = require('backbone'),
    $ = require('jquery');
Backbone.$ = $;
//add to global scope for non-modular libraries
window.Backbone = Backbone;
window.$ = $;
window.jQuery = $;
window.Backbone.$ = $;

var Polyglot = require('node-polyglot'),
    getBTPrice = require('./utils/getBitcoinPrice'),
    router = require('./router'),
    newRouter,
    userModel = require('./models/userMd'),
    userProfileModel = require('./models/userProfileMd'),
    languagesModel = require('./models/languagesMd'),
    mouseWheel = require('jquery-mousewheel'),
    mCustomScrollbar = require('./utils/jquery.mCustomScrollbar.js'),
    pageNavView = require('./views/pageNavVw'),
    chatAppView = require('./views/chatAppVw'),
    newPageNavView,
    newSocketView,
    newChatAppView,
    user = new userModel(),
    userProfile = new userProfileModel(),
    languages = new languagesModel(),
    socketView = require('./views/socketVw'),
    guid = "",
    avatar_hash = "",
    cCode = "",
    serverUrlLocal = "",
    loadProfileCount = 1,
    loadProfileTimeout,
    loadProfileCountdownInterval,
    loadProfileCountdown = 5;

serverUrlLocal = localStorage.getItem("serverUrl") || "http://localhost:18469/api/v1/";

//set the urlRoot of the user model. Defaults to local host if not found
user.urlRoot = serverUrlLocal + "settings";

//set the urlRoot of the user model. Defaults to local host if not found
userProfile.urlRoot = serverUrlLocal + "profile";

//put language in the window so all templates and models can reach it. It's especially important in formatting currency.
window.lang = user.get("language");

//put polyglot in the window so all templates can reach it
window.polyglot = new Polyglot({locale: window.lang});

//retrieve the object that has a matching language code
window.polyglot.extend(__.where(languages.get('languages'), {langCode: window.lang})[0]);

//put the event bus into the window so it's available everywhere
window.obEventBus =  __.extend({}, Backbone.Events);

var reloadProfile = function(){
  "use strict";
  $('.js-loadingMessageModal').removeClass('hide').find('.js-closeIndexModal').addClass('hide');
  loadProfileCountdown=3;

  if(loadProfileCount < 10){
    loadProfileCountdownInterval = setInterval(function(){
      if(loadProfileCountdown > 0){
        $('.js-indexLoadingMsg4').text(loadProfileCountdown);
        loadProfileCountdown--;
      } else {
        $('.js-indexLoadingMsg4').text("");
        clearInterval(loadProfileCountdownInterval);
        loadProfileCount++;
        loadProfile();
      }
    }, 2000);
  } else {
    alert("Your server may not be working correctly. Loading using default settings.");
    $('.js-loadingMessageModal').addClass('hide');
    user.set('serverUrl', serverUrlLocal);
    newSocketView = new socketView({model: user});
    newPageNavView = new pageNavView({model: user, socketView: newSocketView});
    newRouter = new router({userModel: user, socketView: newSocketView});
    Backbone.history.start();
    window.clearTimeout(loadProfileTimeout);
  }
};

var setCurrentBitCoin = function(cCode, userModel, callback) {
  "use strict";
  getBTPrice(cCode, function (btAve, currencyList) {
    //put the current bitcoin price in the window so it doesn't have to be passed to models
    if (!btAve){
      currencyList = currencyList.join("\n");
      alert("Bitcoin prices for your selected currency are not available. Your currency has been set to BTC. " +
          "You can change this in the settings console. \n\n The following currencies are available: \n\n" + currencyList);
      window.currentBitcoin = 1;
      userModel.set('currency_code', 'BTC');
    }
    window.currentBitcoin = btAve;
    typeof callback === 'function' && callback();
  });
}

var loadProfile = function() {
  //get the guid from the user profile to put in the user model
  userProfile.fetch({
    success: function (model, response) {
      $('.js-loadingModal').addClass('hide');
      "use strict";
      //make sure profile is not blank
      if (response.profile){
        guid = model.get('profile').guid;
        avatar_hash = model.get('profile').avatar_hash;
        //get the user
        user.fetch({
          success: function (model, response) {
            user.set('serverUrl', serverUrlLocal);
            user.set('guid', guid);
            user.set('avatar_hash', avatar_hash);
            cCode = model.get('currency_code');

            //get user bitcoin price before loading pages
            setCurrentBitCoin(cCode, user, function(){
              $('.js-loadingMessageModal').addClass('hide');
              newSocketView = new socketView({model: user});
              newPageNavView = new pageNavView({model: user, socketView: newSocketView});
              newChatAppView = new chatAppView({model: user, socketView: newSocketView})
              newRouter = new router({userModel: user, socketView: newSocketView});
              Backbone.history.start();
            });

            //every 15 minutes update the bitcoin price for the currently selected currency
            window.bitCoinPriceChecker = setInterval(function () {
              setCurrentBitCoin(model.get('currency_code'), user);
            }, 54000000);
          },
          error: function (model, response) {
            alert("No user was found. Your server may not be working correctly. Loading using default settings.");
            $('.js-loadingMessageModal').addClass('hide');
            user.set('serverUrl', serverUrlLocal);
            newSocketView = new socketView({model: user});
            newPageNavView = new pageNavView({model: user, socketView: newSocketView});
            newChatAppView = new chatAppView({model: user, socketView: newSocketView})
            newRouter = new router({userModel: user, socketView: newSocketView});
            Backbone.history.start();
          }
        });
      }else{
        $('.js-indexLoadingMsg1').text("User profile did not load.");
        $('.js-indexLoadingMsg2').text("Attempting to reach " + serverUrlLocal);
        $('.js-indexLoadingMsg3').text("Reload attempt " + loadProfileCount);
        reloadProfile();
      }
    },
    error: function (model, response) {
      $('.js-loadingModal').addClass('hide');
      $('.js-indexLoadingMsg1').text("Information for your user profile could not be loaded: " + response.statusText);
      $('.js-indexLoadingMsg2').text("Attempting to reach " + serverUrlLocal);
      $('.js-indexLoadingMsg3').text("Reload attempt " + loadProfileCount);
      reloadProfile();
    }
  });
};

loadProfile();
<|endoftext|>