<commit_before>module.exports = function(ctx) {
	var Lab = require('lab');
	var async = require('async');

	// Test shortcuts
	var expect = Lab.expect;
	var before = Lab.before;
	var after = Lab.after;
	var describe = Lab.experiment;
	var it = Lab.test;

	describe('race-order-bug', function() {

		it('should be cool to delete all pool entries', function(done) {
			ctx.getSet(function(res) {
				console.log('set has num entries: ' + res.result.pool.length);
				var taskList = [];
				res.result.pool.forEach(function(poolEntry) {
					taskList.push(function(callback) {
						ctx.server.inject({method: 'delete', url: ctx.baseSetUrl + '/poolEntry/' + poolEntry.key}, function(res) {
							expect(res.statusCode).to.equal(200);
							callback();
						});
					});
				});
				async.series(taskList, function() {
					done();
				});
			});
		});

		it('is now a smoldering hole in the ground', function(done) {
			ctx.getSet(function(res) {
				if (res.result.pool.length >= 1) console.log(res.result.pool[0].key);
				expect(res.result.pool.length).to.equal(0);
				done();
			});
		});

		var numTries = 100;
		it('will now try to reproduce the race condition with n=' + numTries, function(done) {
			function runloop() {
				var entryId1, entryId2;
				async.series([
					function(callback) {
						ctx.server.inject({method: 'post', url: ctx.baseSetUrl + '/poolEntry'}, function(res) {
							expect(res.statusCode).to.equal(200);
							entryId1 = res.result.key;
							callback();
						});
					},
					function(callback) {
						ctx.server.inject({method: 'post', url: ctx.baseSetUrl + '/poolEntry'}, function(res) {
							expect(res.statusCode).to.equal(200);
							entryId2 = res.result.key;
							callback();
						});
					},
					function(callback) {
						ctx.getSet(function(res) {
							expect(res.result.pool.length).to.equal(2);
							callback();
						});
					},
					function(callback) {
						ctx.server.inject({method: 'delete', url: ctx.baseSetUrl + '/poolEntry/' + entryId1}, function(res) {
							expect(res.statusCode).to.equal(200);
							callback();
						});
					}
				], function() {
					ctx.getSet(function(res) {
						expect(res.result.pool.length).to.equal(1);
						expect(res.result.pool[0].key).to.equal(entryId2);

						tryNextLoop();
					});
				});
			};

			// this actually sucks. is there a way to call an async function N times without eating up stack?
			function tryNextLoop() {
				if (--counter > 0) {
					setTimeout(runLoop, 0);
				} else {
					done();
				}
			}

			var counter = numTries;
			runloop();
		});
	});
};
<commit_msg>This would also make a good interview question.<commit_after>module.exports = function(ctx) {
	var Lab = require('lab');
	var async = require('async');

	// Test shortcuts
	var expect = Lab.expect;
	var before = Lab.before;
	var after = Lab.after;
	var describe = Lab.experiment;
	var it = Lab.test;

	describe('race-order-bug', function() {

		it('should be cool to delete all pool entries', function(done) {
			ctx.getSet(function(res) {
				console.log('set has num entries: ' + res.result.pool.length);
				var taskList = [];
				res.result.pool.forEach(function(poolEntry) {
					taskList.push(function(callback) {
						ctx.server.inject({method: 'delete', url: ctx.baseSetUrl + '/poolEntry/' + poolEntry.key}, function(res) {
							expect(res.statusCode).to.equal(200);
							callback();
						});
					});
				});
				async.series(taskList, function() {
					done();
				});
			});
		});

		it('is now a smoldering hole in the ground', function(done) {
			ctx.getSet(function(res) {
				if (res.result.pool.length >= 1) console.log(res.result.pool[0].key);
				expect(res.result.pool.length).to.equal(0);
				done();
			});
		});

		var numTries = 100;
		it('will now try to reproduce the race condition with n=' + numTries, function(done) {
			function runloop() {
				var entryId1, entryId2;
				async.series([
					function(callback) {
						ctx.server.inject({method: 'post', url: ctx.baseSetUrl + '/poolEntry'}, function(res) {
							expect(res.statusCode).to.equal(200);
							entryId1 = res.result.key;
							callback();
						});
					},
					function(callback) {
						ctx.server.inject({method: 'post', url: ctx.baseSetUrl + '/poolEntry'}, function(res) {
							expect(res.statusCode).to.equal(200);
							entryId2 = res.result.key;
							callback();
						});
					},
					function(callback) {
						ctx.getSet(function(res) {
							expect(res.result.pool.length).to.equal(2);
							callback();
						});
					},
					function(callback) {
						ctx.server.inject({method: 'delete', url: ctx.baseSetUrl + '/poolEntry/' + entryId1}, function(res) {
							expect(res.statusCode).to.equal(200);
							callback();
						});
					}
				], function() {
					ctx.getSet(function(res) {
						expect(res.result.pool.length).to.equal(1);
						expect(res.result.pool[0].key).to.equal(entryId2);

						tryNextLoop();
					});
				});
			};

			function tryNextLoop() {
				if (--counter > 0) {
					setTimeout(runLoop, 0);  // so we don't eat up callstack
				} else {
					done();
				}
			}

			var counter = numTries;
			runloop();
		});
	});
};
<|endoftext|>


<commit_before>angular.module("commonModule")
    /*
     *  HTML top page header manipulator (direct service mapping)
     */
    .controller("commonHeaderController", [
        "$scope",

        "$commonApiService",
        "$categoryService",
        function ($scope, $commonApiService, $categoryService) {

            $scope.hideNav = function () {
                $("#pageslide").css("display", "none");
                $(".mini-cart").css("display", "none");
                $(".h-block ul li.active").removeClass("active");
                $(".h-block nav").removeClass("active");
                $(".shadow").css("display", "none");
            };

            $scope.categories = [];
            $scope.categoryService = $categoryService;

            var tree;
            tree = $categoryService.getTree();
            if (typeof tree === "undefined") {
                $commonApiService.getCategories().$promise.then(
                    function (response) {
                        var categories = response.result || [];
                        $scope.categories = categories;
                        $categoryService.setTree(categories);
                    }
                );
            } else {
                $scope.categories = tree;
            }
        }
    ])

    .controller("commonBreadcrumbsController", [
        "$scope",
        "$commonBreadcrumbsService",
        function ($scope, $commonBreadcrumbsService) {
            $scope.it = $commonBreadcrumbsService;
            $scope.crumbs = $commonBreadcrumbsService.getItems();
        }
    ])

    .controller("commonController", [
        "$scope",
        "$commonPageService",
        "$designService",
        "$commonApiService",
        "$commonBreadcrumbsService",
        "$cartService",
        "$visitorLoginService",
        "cfpLoadingBar",
        function (
            $scope,
            $commonPageService,
            $designService,
            $commonApiService,
            $commonBreadcrumbsService,
            $cartService,
            $visitorLoginService,
            cfpLoadingBar) {

            /**
             * Home, 404 - pages
             */

            // We need to enforce the default seo options
            $commonPageService.setTitle();
            $commonPageService.setMetaDescription();
            $commonPageService.setMetaKeywords();

            // HANDLERS FOR BREADCRUMBS (START)
            //
            $scope.$on("$locationChangeSuccess", function () {
                $commonBreadcrumbsService.clear();
                $commonBreadcrumbsService.addItem("Home", "/");
            });

            $scope.$on("add-breadcrumbs", function (event, param) {
                $commonBreadcrumbsService.addItem(param.label, param.url);
            });

            // Page loading event handler
            $scope.load_completed = false;

            $scope.$on('cfpLoadingBar:completed', function(e,param) {
                $scope.load_completed = true;
            });
            //
            // HANDLERS FOR BREADCRUMBS (STOP)

            /**
             * Cart initialization
             */
            $cartService.init();

            $scope.visitorProps = $visitorLoginService.props;
        }
    ]
);<commit_msg>consistent comments between repos<commit_after>angular.module("commonModule")
    /*
     *  HTML top page header manipulator (direct service mapping)
     */
    .controller("commonHeaderController", [
        "$scope",

        "$commonApiService",
        "$categoryService",
        function ($scope, $commonApiService, $categoryService) {

            $scope.hideNav = function () {
                $("#pageslide").css("display", "none");
                $(".mini-cart").css("display", "none");
                $(".h-block ul li.active").removeClass("active");
                $(".h-block nav").removeClass("active");
                $(".shadow").css("display", "none");
            };

            $scope.categories = [];
            $scope.categoryService = $categoryService;

            var tree;
            tree = $categoryService.getTree();
            if (typeof tree === "undefined") {
                $commonApiService.getCategories().$promise.then(
                    function (response) {
                        var categories = response.result || [];
                        $scope.categories = categories;
                        $categoryService.setTree(categories);
                    }
                );
            } else {
                $scope.categories = tree;
            }
        }
    ])

    .controller("commonBreadcrumbsController", [
        "$scope",
        "$commonBreadcrumbsService",
        function ($scope, $commonBreadcrumbsService) {
            $scope.it = $commonBreadcrumbsService;
            $scope.crumbs = $commonBreadcrumbsService.getItems();
        }
    ])

    .controller("commonController", [
        "$scope",
        "$commonPageService",
        "$designService",
        "$commonApiService",
        "$commonBreadcrumbsService",
        "$cartService",
        "$visitorLoginService",
        "cfpLoadingBar",
        function (
            $scope,
            $commonPageService,
            $designService,
            $commonApiService,
            $commonBreadcrumbsService,
            $cartService,
            $visitorLoginService,
            cfpLoadingBar) {

            /**
             * Home, 404 - pages
             */

            // We need to enforce the default seo options
            $commonPageService.setTitle();
            $commonPageService.setMetaDescription();
            $commonPageService.setMetaKeywords();

            // Handlers for breadcrumbs
            $scope.$on("$locationChangeSuccess", function () {
                $commonBreadcrumbsService.clear();
                $commonBreadcrumbsService.addItem("Home", "/");
            });

            $scope.$on("add-breadcrumbs", function (event, param) {
                $commonBreadcrumbsService.addItem(param.label, param.url);
            });

            // Page loading event handler
            $scope.load_completed = false;

            $scope.$on('cfpLoadingBar:completed', function(e,param) {
                $scope.load_completed = true;
            });

            // Cart initialization
            $cartService.init();

            // Visitor init
            $scope.visitorProps = $visitorLoginService.props;
        }
    ]
);<|endoftext|>


<commit_before>/*jshint camelcase: false */

var basePort = 8001,
    testPort = 8002;

module.exports = function(grunt) {

    grunt.initConfig({

        sass: {
            dist: {
                options: {
                    style: 'expanded',
                    compass: false
                },
                files: {
                    'assets/css/style.css': 'assets/sass/style.scss'
                }
            }
        },

        autoprefixer: {
            options: {
                browsers: ['last 10 version']
            },
            multiple_files: {
                expand: true,
                flatten: true,
                src: 'assets/css/*.css',
                dest: 'app/static/css/'
            }
        },

        cssmin: {
            combine: {
                files: {
                    'app/static/css/style.min.css': ['app/static/css/style.css']
                }
            }
        },

        imagemin: {
            dynamic: {
                files: [{
                    expand: true,
                    cwd: 'assets/images/',
                    src: ['**/*.{png,jpg,gif}'],
                    dest: 'app/static/images/'
                }]
            }
        },

        copy: {
            main: {
                files: [
                    // front-end
                    {
                        expand: true,
                        cwd: 'bower_components/normalize.css',
                        src: ['normalize.css'],
                        dest: 'app/static/css/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/fontawesome/fonts',
                        src: ['*'],
                        dest: 'app/static/fonts/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/fontawesome/css',
                        src: ['font-awesome.min.css'],
                        dest: 'app/static/css/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/html5shiv/dist',
                        src: ['html5shiv.min.js'],
                        dest: 'app/static/js/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/respond/dest',
                        src: ['respond.min.js'],
                        dest: 'app/static/js/',
                        filter: 'isFile'
                    },
                    // angular
                    {
                        expand: true,
                        cwd: 'bower_components/angular',
                        src: ['angular.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-loader',
                        src: ['angular-loader.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-ui-router/release',
                        src: ['angular-ui-router.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-cookies',
                        src: ['angular-cookies.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-resource',
                        src: ['angular-resource.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-scroll',
                        src: ['angular-scroll.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/satellizer',
                        src: ['satellizer.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-gravatar/build',
                        src: ['angular-gravatar.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angucomplete-alt',
                      src: ['angucomplete-alt.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angucomplete-alt',
                      src: ['angucomplete-alt.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/momentjs',
                      src: ['moment.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-moment',
                      src: ['angular-moment.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-spinner',
                      src: ['angular-spinner.min.js', 'angular-spinner.min.js.map'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/spin.js',
                      src: ['spin.js'],
                      dest: 'app/static/js/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-loading-spinner',
                      src: ['angular-loading-spinner.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-flash-alert/src',
                      src: ['angular-flash.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-flash-alert/src',
                      src: ['angular-flash.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-animate',
                      src: ['angular-animate.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate',
                      src: ['angular-translate.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate-storage-cookie',
                      src: ['angular-translate-storage-cookie.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate-storage-local',
                      src: ['angular-translate-storage-local.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate-loader-static-files',
                      src: ['angular-translate-loader-static-files.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-cron-jobs/dist',
                      src: ['angular-cron-jobs.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-cron-jobs/dist',
                      src: ['angular-cron-jobs.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    }
                ]
            }
        },

        protractor_webdriver: {
            options: {
                path: 'node_modules/protractor/bin/',
                command: 'webdriver-manager start --standalone'
            },
            test: {},
            daemonize: {
                options: {
                    keepAlive: true
                }
            }
        },

        protractor: {
            options: {
                configFile: 'test/protractor.conf.js', // Default config file
                keepAlive: false, // If false, the grunt process stops when the test fails.
                noColor: false, // If true, protractor will not use colors in its output.
            },
            test: {
                options: {
                    args: {
                        baseUrl: 'http://localhost:' + testPort
                    }
                }
            },
            fasttest: {
                options: {
                    args: {
                        baseUrl: 'http://localhost:' + basePort
                    }
                }
            }
        },

        watch: {
            options: {
                livereload: true
            },
            css: {
                files: ['assets/sass/*.scss', 'assets/sass/*/*.scss'],
                tasks: ['sass', 'autoprefixer'],
                options: {
                    spawn: false,
                    livereload: false,
                }
            },
            autoprefixer: {
                files: 'assets/css/**',
                tasks: ['autoprefixer']
            },
            images: {
                files: ['assets/images/*.{png,jpg,gif}'],
                tasks: ['imagemin'],
            }
        },

        connect: {
            options: {
                port: basePort,
                hostname: 'localhost',
                base: 'app'
            },
            server: {},
            test: {
                options: {
                    port: testPort,
                }
            }
        },

        nggettext_extract: {
            pot: {
                files: {
                  'i18n/template.pot': ['app/views/**/*.html']
                }
            },
        },

        po2json_angular_translate: {
            app: {
                options: {
                    pretty: true
                },
                files: {
                  'app/static/js/i18n/': ['i18n/*.po'],
                }
            }
        },

    });

    require('load-grunt-tasks')(grunt);

    grunt.registerTask(
        'build', ['copy', 'imagemin', 'sass', 'autoprefixer', 'cssmin']);
    grunt.registerTask(
        'run', ['copy', 'connect:server', 'imagemin', 'sass', 'autoprefixer', 'watch']);
    grunt.registerTask('serve', ['connect',]);
    grunt.registerTask('default', ['run']);
    grunt.registerTask('test',
        ['connect:test', 'imagemin', 'sass', 'autoprefixer', 'protractor_webdriver:test', 'protractor:test']);

    grunt.loadNpmTasks('grunt-angular-gettext');
    grunt.loadNpmTasks('grunt-po2json-angular-translate');

};
<commit_msg>Grunt config for cart.js (SAAS-466)<commit_after>/*jshint camelcase: false */

var basePort = 8001,
    testPort = 8002;

module.exports = function(grunt) {

    grunt.initConfig({

        sass: {
            dist: {
                options: {
                    style: 'expanded',
                    compass: false
                },
                files: {
                    'assets/css/style.css': 'assets/sass/style.scss'
                }
            }
        },

        autoprefixer: {
            options: {
                browsers: ['last 10 version']
            },
            multiple_files: {
                expand: true,
                flatten: true,
                src: 'assets/css/*.css',
                dest: 'app/static/css/'
            }
        },

        cssmin: {
            combine: {
                files: {
                    'app/static/css/style.min.css': ['app/static/css/style.css']
                }
            }
        },

        imagemin: {
            dynamic: {
                files: [{
                    expand: true,
                    cwd: 'assets/images/',
                    src: ['**/*.{png,jpg,gif}'],
                    dest: 'app/static/images/'
                }]
            }
        },

        copy: {
            main: {
                files: [
                    // front-end
                    {
                        expand: true,
                        cwd: 'bower_components/normalize.css',
                        src: ['normalize.css'],
                        dest: 'app/static/css/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/fontawesome/fonts',
                        src: ['*'],
                        dest: 'app/static/fonts/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/fontawesome/css',
                        src: ['font-awesome.min.css'],
                        dest: 'app/static/css/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/html5shiv/dist',
                        src: ['html5shiv.min.js'],
                        dest: 'app/static/js/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/respond/dest',
                        src: ['respond.min.js'],
                        dest: 'app/static/js/',
                        filter: 'isFile'
                    },
                    // angular
                    {
                        expand: true,
                        cwd: 'bower_components/angular',
                        src: ['angular.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-loader',
                        src: ['angular-loader.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-ui-router/release',
                        src: ['angular-ui-router.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-cookies',
                        src: ['angular-cookies.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-resource',
                        src: ['angular-resource.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-scroll',
                        src: ['angular-scroll.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/satellizer',
                        src: ['satellizer.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                        expand: true,
                        cwd: 'bower_components/angular-gravatar/build',
                        src: ['angular-gravatar.js'],
                        dest: 'app/static/js/angular/',
                        filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angucomplete-alt',
                      src: ['angucomplete-alt.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angucomplete-alt',
                      src: ['angucomplete-alt.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/momentjs',
                      src: ['moment.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-moment',
                      src: ['angular-moment.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-spinner',
                      src: ['angular-spinner.min.js', 'angular-spinner.min.js.map'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/spin.js',
                      src: ['spin.js'],
                      dest: 'app/static/js/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-loading-spinner',
                      src: ['angular-loading-spinner.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-flash-alert/src',
                      src: ['angular-flash.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-flash-alert/src',
                      src: ['angular-flash.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-animate',
                      src: ['angular-animate.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate',
                      src: ['angular-translate.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate-storage-cookie',
                      src: ['angular-translate-storage-cookie.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate-storage-local',
                      src: ['angular-translate-storage-local.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-translate-loader-static-files',
                      src: ['angular-translate-loader-static-files.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-cron-jobs/dist',
                      src: ['angular-cron-jobs.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-cron-jobs/dist',
                      src: ['angular-cron-jobs.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-chart.js/dist',
                      src: ['angular-chart.js'],
                      dest: 'app/static/js/angular/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/Chart.js',
                      src: ['Chart.js'],
                      dest: 'app/static/js/',
                      filter: 'isFile'
                    },
                    {
                      expand: true,
                      cwd: 'bower_components/angular-chart.js/dist',
                      src: ['angular-chart.css'],
                      dest: 'app/static/css/',
                      filter: 'isFile'
                    }
                ]
            }
        },

        protractor_webdriver: {
            options: {
                path: 'node_modules/protractor/bin/',
                command: 'webdriver-manager start --standalone'
            },
            test: {},
            daemonize: {
                options: {
                    keepAlive: true
                }
            }
        },

        protractor: {
            options: {
                configFile: 'test/protractor.conf.js', // Default config file
                keepAlive: false, // If false, the grunt process stops when the test fails.
                noColor: false, // If true, protractor will not use colors in its output.
            },
            test: {
                options: {
                    args: {
                        baseUrl: 'http://localhost:' + testPort
                    }
                }
            },
            fasttest: {
                options: {
                    args: {
                        baseUrl: 'http://localhost:' + basePort
                    }
                }
            }
        },

        watch: {
            options: {
                livereload: true
            },
            css: {
                files: ['assets/sass/*.scss', 'assets/sass/*/*.scss'],
                tasks: ['sass', 'autoprefixer'],
                options: {
                    spawn: false,
                    livereload: false,
                }
            },
            autoprefixer: {
                files: 'assets/css/**',
                tasks: ['autoprefixer']
            },
            images: {
                files: ['assets/images/*.{png,jpg,gif}'],
                tasks: ['imagemin'],
            }
        },

        connect: {
            options: {
                port: basePort,
                hostname: 'localhost',
                base: 'app'
            },
            server: {},
            test: {
                options: {
                    port: testPort,
                }
            }
        },

        nggettext_extract: {
            pot: {
                files: {
                  'i18n/template.pot': ['app/views/**/*.html']
                }
            },
        },

        po2json_angular_translate: {
            app: {
                options: {
                    pretty: true
                },
                files: {
                  'app/static/js/i18n/': ['i18n/*.po'],
                }
            }
        },

    });

    require('load-grunt-tasks')(grunt);

    grunt.registerTask(
        'build', ['copy', 'imagemin', 'sass', 'autoprefixer', 'cssmin']);
    grunt.registerTask(
        'run', ['copy', 'connect:server', 'imagemin', 'sass', 'autoprefixer', 'watch']);
    grunt.registerTask('serve', ['connect',]);
    grunt.registerTask('default', ['run']);
    grunt.registerTask('test',
        ['connect:test', 'imagemin', 'sass', 'autoprefixer', 'protractor_webdriver:test', 'protractor:test']);

    grunt.loadNpmTasks('grunt-angular-gettext');
    grunt.loadNpmTasks('grunt-po2json-angular-translate');

};
<|endoftext|>


<commit_before>var rssConfig = require('../config.json')
var guildList = rssConfig.sources
const sqlCmds = require('../rss/sql/commands.js')
const update = require('../util/updateJSON.js')

module.exports = function (bot, guild) {
  console.log(`Guild "${guild.name}" (Users: ${guild.members.size}) has removed the bot.`)

  for (let rssIndex in rssConfig.sources[guild.id]) {
    sqlCmds.dropTable(rssConfig.databaseName, rssConfig.sources[guild.id][rssIndex])
  }

  delete rssConfig.sources[guild.id]
  update('./config.json', rssConfig)
}
<commit_msg>fixed typo<commit_after>var rssConfig = require('../config.json')
var guildList = rssConfig.sources
const sqlCmds = require('../rss/sql/commands.js')
const update = require('../util/updateJSON.js')

module.exports = function (bot, guild) {
  console.log(`Guild "${guild.name}" (Users: ${guild.members.size}) has removed the bot.`)

  for (let rssIndex in rssConfig.sources[guild.id]) {
    sqlCmds.dropTable(rssConfig.databaseName, rssConfig.sources[guild.id][rssIndex].name)
  }

  delete rssConfig.sources[guild.id]
  update('./config.json', rssConfig)
}
<|endoftext|>


<commit_before>"use strict";
const IrcServer = require("../../lib/irc/IrcServer");
const extend = require("extend");
describe("IrcServer", function() {
    describe("getNick", function() {
        it("should get a nick from a userid", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar")).toBe("M-foobar");
        });
        it("should get a nick from a displayname", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar", "wiggle")).toBe("M-wiggle");
        });
        it("should get a reduced nick if the displayname contains some invalid chars", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar", "💩wiggleケ")).toBe("M-wiggle");
        });
        it("should use userid if the displayname is all invalid chars", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar", "💩ケ")).toBe("M-foobar");
        });
    });
});
<commit_msg>More tests for invalid chars<commit_after>"use strict";
const IrcServer = require("../../lib/irc/IrcServer");
const extend = require("extend");
describe("IrcServer", function() {
    describe("getNick", function() {
        it("should get a nick from a userid", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar")).toBe("M-foobar");
        });
        it("should get a nick from a displayname", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar", "wiggle")).toBe("M-wiggle");
        });
        it("should get a reduced nick if the displayname contains some invalid chars", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar", "💩wiggleケ")).toBe("M-wiggle");
        });
        it("should use localpart if the displayname is all invalid chars", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@foobar:foobar", "💩ケ")).toBe("M-foobar");
        });
        // These situations shouldn't happen, but we want to avoid rogue homeservers blowing us up.
        it("should get a reduced nick if the localpart contains some invalid chars", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@💩foobarケ:foobar")).toBe("M-foobar");
        });
        it("should use displayname if the localpart is all invalid chars", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(server.getNick("@💩ケ:foobar", "wiggle")).toBe("M-wiggle");
        });
        it("should throw if no characters could be used", function() {
            const server = new IrcServer("irc.foobar",
                extend(true, IrcServer.DEFAULT_CONFIG, {})
            );
            expect(() => {server.getNick("@💩ケ:foobar", "💩ケ")}).toThrow();
        });
    });
});
<|endoftext|>


<commit_before>var queryUtils = require('../../utils/query-utils');
const PhasedExecution = require('../../utils/phased-execution');
const AggregationMapConfig = require('../../models/aggregation/aggregation-mapconfig');
var SubstitutionTokens = require('../../utils/substitution-tokens');

// Instantiate a query with tokens for a given zoom level
function queryForZoom(sql, zoom, singleTile=false) {
    const tileRes = 256;
    const wmSize = 6378137.0*2*Math.PI;
    const nTiles = Math.pow(2, zoom);
    const tileSize = wmSize / nTiles;
    const resolution = tileSize / tileRes;
    const scaleDenominator = resolution / 0.00028;
    const x0 = -wmSize/2, y0 = -wmSize/2;
    let bbox = `ST_MakeEnvelope(${x0}, ${y0}, ${x0+wmSize}, ${y0+wmSize})`;
    if (singleTile) {
        bbox = `ST_MakeEnvelope(${x0}, ${y0}, ${x0 + tileSize}, ${y0 + tileSize})`;
    }
    return SubstitutionTokens.replace(sql, {
        bbox: bbox,
        scale_denominator: scaleDenominator,
        pixel_width: resolution,
        pixel_height: resolution
    });
}

function MapnikLayerStats () {
    this._types = {
        mapnik: true,
        cartodb: true
    };
}

MapnikLayerStats.prototype.is = function (type) {
    return this._types[type] ? this._types[type] : false;
};

function queryPromise(dbConnection, query, callback) {
    return new Promise(function(resolve, reject) {
        dbConnection.query(query, function (err, res) {
            err = callback(err, res);
            if (err) {
                reject(err);
            }
            else {
                resolve();
            }
        });

    });
}

function columnAggregations(field) {
    if (field.type === 'number') {
        return ['min', 'max', 'avg', 'sum'];
    }
    if (field.type === 'date') { // TODO other types too?
        return ['min', 'max'];
    }
    return [];
}

/* Helper to add a task to the queries PhasedExecution
 * type can be either 'pre' (for pre-aggregation metadata) or 'post'
 * zoom is used only for post-aggregation metadata
 * query is a function that generates a metadata query from a data query
 * assign is a function to assign the results of the metadata query
 * if a assignDefault function is present, it will be used in case of error
 * during the query execution and any errors will be ignored
 */
function addStat(queries, ctx, type, zoom, query, assign, assignDefault=null) {
    let sql;
    if (type === 'pre') {
        sql = ctx. preQuery;
    }
    else {
        sql = queryForZoom(ctx.aggrQuery, zoom);
    }
    sql = query(sql);
    queries.task(
        queryPromise(
            ctx.dbConnection,
            sql,
            (err, res) => {
                if (!err) {
                    assign(res);
                }
                else if (assignDefault !== null) {
                    assignDefault();
                    return null;
                }
                return err;
            }
        )
    );
}

function _estimatedFeatureCount(queries, ctx) {
    if (queries.results.estimatedFeatureCount === undefined) {
        // This is always computed; a default value of -1 is used in case of error
        addStat(
            queries,
            ctx,
            'pre', 0,
            queryUtils.getQueryRowEstimation,
            res => queries.results.estimatedFeatureCount = res.rows[0].rows,
            () => queries.results.estimatedFeatureCount = -1
        );
    }
}

function _featureCount(queries, ctx) {
    if (ctx.metaOptions.featureCount) {
        // TODO: if ctx.metaOptions.columnStats we can combine this with column stats query
        addStat(
            queries,
            ctx,
            'pre', 0,
            queryUtils.getQueryActualRowCount,
            res => queries.results.featureCount = res.rows[0].rows
        );
    }
}

function _aggrFeatureCount(queries, ctx) {
    if (ctx.metaOptions.hasOwnProperty('aggrFeatureCount')) {
        // We expect as zoom level as the value of aggrFeatureCount
        // TODO: it'd be nice to admit an array of zoom levels to
        // return metadata for multiple levels.
        addStat(
            queries,
            ctx,
            'post', ctx.metaOptions.aggrFeatureCount || 0,
            queryUtils.getQueryActualRowCount,
            res => queries.results.aggrfeatureCount = res.rows[0].rows
        );
    }
}

function _geometryType(queries, ctx) {
    if (ctx.metaOptions.geometryType && queries.results.geometryType === undefined) {
        const geometryColumn = AggregationMapConfig.getAggregationGeometryColumn();
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => queryUtils.getQueryGeometryType(sql, geometryColumn),
            res => queries.results.geometryType = res.rows[0].geom_type
        );
    }
}

function _columns(queries, ctx) {
    if (ctx.metaOptions.columns || ctx.metaOptions.columnStats) {
        // note: post-aggregation columns are in layer.options.columns when aggregation is present
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => queryUtils.getQueryLimited(sql, 0),
            res => queries.results.columns = formatResultFields(ctx.dbConnection, res.fields)
        );
    }
}

function firstPhaseQueries(queries, ctx) {
    _estimatedFeatureCount(queries, ctx);
    _featureCount(queries, ctx);
    _aggrFeatureCount(queries, ctx);
    _geometryType(queries, ctx);
    _columns(queries, ctx);
}

function _sample(queries, ctx) {
    if (ctx.metaOptions.sample) {
        const numRows = queries.results.featureCount === undefined ?
            queries.results.estimatedFeatureCount :
            queries.results.featureCount;
        const sampleProb = Math.min(ctx.metaOptions.sample / numRows, 1);
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => queryUtils.getQuerySample(sql, sampleProb),
            res => queries.results.sample = res.rows
        );
    }
}

function _columnStats(queries, ctx) {
    if (ctx.metaOptions.columnStats) {
        let aggr = [];
        Object.keys(queries.results.columns).forEach(name => {
            aggr = aggr.concat(
                columnAggregations(queries.results.columns[name])
                .map(fn => `${fn}(${name}) AS ${name}_${fn}`)
            );
            if (queries.results.columns[name].type === 'string') {
                const topN = ctx.metaOptions.columnStats.topCategories || 1024;
                // TODO:  ctx.metaOptions.columnStats.maxCategories
                //        => use PG stats to dismiss columns with more distinct values
                addStat(
                    queries,
                    ctx,
                    'pre', 0,
                    sql => queryUtils.getQueryTopCategories(sql, name, topN),
                    res => queries.results.columns[name].categories = res.rows
                );
            }
        });
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => `SELECT ${aggr.join(',')} FROM (${sql}) AS __cdb_query`,
            res => {
                Object.keys(queries.results.columns).forEach(name => {
                    columnAggregations(queries.results.columns[name]).forEach(fn => {
                        queries.results.columns[name][fn] = res.rows[0][`${name}_${fn}`];
                    });
                });
            }
        );
    }
}

function secondPhaseQueries(queries, ctx) {
    _sample(queries, ctx);
    _columnStats(queries, ctx);
}

// This is adapted from SQL API:
function fieldType(cname) {
    let tname;
    switch (true) {
        case /bool/.test(cname):
            tname = 'boolean';
            break;
        case /int|float|numeric/.test(cname):
            tname = 'number';
            break;
        case /text|char|unknown/.test(cname):
            tname = 'string';
            break;
        case /date|time/.test(cname):
            tname = 'date';
            break;
        default:
            tname = cname;
    }
    if ( tname && cname.match(/^_/) ) {
        tname += '[]';
    }
    return tname;
}

// columns are returned as an object { columnName1: { type1: ...}, ..}
// for consistency with SQL API
function formatResultFields(dbConnection, flds) {
    flds = flds || [];
    var nfields = {};
    for (var i=0; i<flds.length; ++i) {
      var f = flds[i];
      var cname = dbConnection.typeName(f.dataTypeID);
      var tname;
      if ( ! cname ) {
        tname = 'unknown(' + f.dataTypeID + ')';
      } else {
        tname = fieldType(cname);
      }
      nfields[f.name] = { type: tname };
    }
    return nfields;
}

MapnikLayerStats.prototype.getStats =
function (layer, dbConnection, callback) {
    let aggrQuery = layer.options.sql_raw || layer.options.sql;
    let preQuery = layer.options.aggregation_metadata ?
        layer.options.aggregation_metadata.pre_aggregation_sql :
        aggrQuery;

    let context = {
        dbConnection,
        preQuery,
        aggrQuery,
        aggrMeta: layer.options.aggregation_metadata,
        metaOptions: layer.options.metadata || {}
    };

    let queries = new PhasedExecution();

    // TODO: could save some queries if queryUtils.getAggregationMetadata() has been used and kept somewhere
    // we would set queries.results.estimatedFeatureCount and queries.results.geometryType
    // (if metaOptions.geometryType) from it.

    // Queries will be executed in two phases, with results from the first phase needed
    // to define the queries of the second phase
    queries.phase(() => firstPhaseQueries(queries, context));
    queries.phase(() => secondPhaseQueries(queries, context));
    queries.run()
        .then(results => callback(null, results))
        .catch(error => callback(error));

};

module.exports = MapnikLayerStats;
<commit_msg>Rename misleading function argument<commit_after>var queryUtils = require('../../utils/query-utils');
const PhasedExecution = require('../../utils/phased-execution');
const AggregationMapConfig = require('../../models/aggregation/aggregation-mapconfig');
var SubstitutionTokens = require('../../utils/substitution-tokens');

// Instantiate a query with tokens for a given zoom level
function queryForZoom(sql, zoom, singleTile=false) {
    const tileRes = 256;
    const wmSize = 6378137.0*2*Math.PI;
    const nTiles = Math.pow(2, zoom);
    const tileSize = wmSize / nTiles;
    const resolution = tileSize / tileRes;
    const scaleDenominator = resolution / 0.00028;
    const x0 = -wmSize/2, y0 = -wmSize/2;
    let bbox = `ST_MakeEnvelope(${x0}, ${y0}, ${x0+wmSize}, ${y0+wmSize})`;
    if (singleTile) {
        bbox = `ST_MakeEnvelope(${x0}, ${y0}, ${x0 + tileSize}, ${y0 + tileSize})`;
    }
    return SubstitutionTokens.replace(sql, {
        bbox: bbox,
        scale_denominator: scaleDenominator,
        pixel_width: resolution,
        pixel_height: resolution
    });
}

function MapnikLayerStats () {
    this._types = {
        mapnik: true,
        cartodb: true
    };
}

MapnikLayerStats.prototype.is = function (type) {
    return this._types[type] ? this._types[type] : false;
};

function queryPromise(dbConnection, query, setResults) {
    return new Promise(function(resolve, reject) {
        dbConnection.query(query, function (err, res) {
            err = setResults(err, res);
            if (err) {
                reject(err);
            }
            else {
                resolve();
            }
        });

    });
}

function columnAggregations(field) {
    if (field.type === 'number') {
        return ['min', 'max', 'avg', 'sum'];
    }
    if (field.type === 'date') { // TODO other types too?
        return ['min', 'max'];
    }
    return [];
}

/* Helper to add a task to the queries PhasedExecution
 * type can be either 'pre' (for pre-aggregation metadata) or 'post'
 * zoom is used only for post-aggregation metadata
 * query is a function that generates a metadata query from a data query
 * assign is a function to assign the results of the metadata query
 * if a assignDefault function is present, it will be used in case of error
 * during the query execution and any errors will be ignored
 */
function addStat(queries, ctx, type, zoom, query, assign, assignDefault=null) {
    let sql;
    if (type === 'pre') {
        sql = ctx. preQuery;
    }
    else {
        sql = queryForZoom(ctx.aggrQuery, zoom);
    }
    sql = query(sql);
    queries.task(
        queryPromise(
            ctx.dbConnection,
            sql,
            (err, res) => {
                if (!err) {
                    assign(res);
                }
                else if (assignDefault !== null) {
                    assignDefault();
                    return null;
                }
                return err;
            }
        )
    );
}

function _estimatedFeatureCount(queries, ctx) {
    if (queries.results.estimatedFeatureCount === undefined) {
        // This is always computed; a default value of -1 is used in case of error
        addStat(
            queries,
            ctx,
            'pre', 0,
            queryUtils.getQueryRowEstimation,
            res => queries.results.estimatedFeatureCount = res.rows[0].rows,
            () => queries.results.estimatedFeatureCount = -1
        );
    }
}

function _featureCount(queries, ctx) {
    if (ctx.metaOptions.featureCount) {
        // TODO: if ctx.metaOptions.columnStats we can combine this with column stats query
        addStat(
            queries,
            ctx,
            'pre', 0,
            queryUtils.getQueryActualRowCount,
            res => queries.results.featureCount = res.rows[0].rows
        );
    }
}

function _aggrFeatureCount(queries, ctx) {
    if (ctx.metaOptions.hasOwnProperty('aggrFeatureCount')) {
        // We expect as zoom level as the value of aggrFeatureCount
        // TODO: it'd be nice to admit an array of zoom levels to
        // return metadata for multiple levels.
        addStat(
            queries,
            ctx,
            'post', ctx.metaOptions.aggrFeatureCount || 0,
            queryUtils.getQueryActualRowCount,
            res => queries.results.aggrfeatureCount = res.rows[0].rows
        );
    }
}

function _geometryType(queries, ctx) {
    if (ctx.metaOptions.geometryType && queries.results.geometryType === undefined) {
        const geometryColumn = AggregationMapConfig.getAggregationGeometryColumn();
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => queryUtils.getQueryGeometryType(sql, geometryColumn),
            res => queries.results.geometryType = res.rows[0].geom_type
        );
    }
}

function _columns(queries, ctx) {
    if (ctx.metaOptions.columns || ctx.metaOptions.columnStats) {
        // note: post-aggregation columns are in layer.options.columns when aggregation is present
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => queryUtils.getQueryLimited(sql, 0),
            res => queries.results.columns = formatResultFields(ctx.dbConnection, res.fields)
        );
    }
}

function firstPhaseQueries(queries, ctx) {
    _estimatedFeatureCount(queries, ctx);
    _featureCount(queries, ctx);
    _aggrFeatureCount(queries, ctx);
    _geometryType(queries, ctx);
    _columns(queries, ctx);
}

function _sample(queries, ctx) {
    if (ctx.metaOptions.sample) {
        const numRows = queries.results.featureCount === undefined ?
            queries.results.estimatedFeatureCount :
            queries.results.featureCount;
        const sampleProb = Math.min(ctx.metaOptions.sample / numRows, 1);
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => queryUtils.getQuerySample(sql, sampleProb),
            res => queries.results.sample = res.rows
        );
    }
}

function _columnStats(queries, ctx) {
    if (ctx.metaOptions.columnStats) {
        let aggr = [];
        Object.keys(queries.results.columns).forEach(name => {
            aggr = aggr.concat(
                columnAggregations(queries.results.columns[name])
                .map(fn => `${fn}(${name}) AS ${name}_${fn}`)
            );
            if (queries.results.columns[name].type === 'string') {
                const topN = ctx.metaOptions.columnStats.topCategories || 1024;
                // TODO:  ctx.metaOptions.columnStats.maxCategories
                //        => use PG stats to dismiss columns with more distinct values
                addStat(
                    queries,
                    ctx,
                    'pre', 0,
                    sql => queryUtils.getQueryTopCategories(sql, name, topN),
                    res => queries.results.columns[name].categories = res.rows
                );
            }
        });
        addStat(
            queries,
            ctx,
            'pre', 0,
            sql => `SELECT ${aggr.join(',')} FROM (${sql}) AS __cdb_query`,
            res => {
                Object.keys(queries.results.columns).forEach(name => {
                    columnAggregations(queries.results.columns[name]).forEach(fn => {
                        queries.results.columns[name][fn] = res.rows[0][`${name}_${fn}`];
                    });
                });
            }
        );
    }
}

function secondPhaseQueries(queries, ctx) {
    _sample(queries, ctx);
    _columnStats(queries, ctx);
}

// This is adapted from SQL API:
function fieldType(cname) {
    let tname;
    switch (true) {
        case /bool/.test(cname):
            tname = 'boolean';
            break;
        case /int|float|numeric/.test(cname):
            tname = 'number';
            break;
        case /text|char|unknown/.test(cname):
            tname = 'string';
            break;
        case /date|time/.test(cname):
            tname = 'date';
            break;
        default:
            tname = cname;
    }
    if ( tname && cname.match(/^_/) ) {
        tname += '[]';
    }
    return tname;
}

// columns are returned as an object { columnName1: { type1: ...}, ..}
// for consistency with SQL API
function formatResultFields(dbConnection, flds) {
    flds = flds || [];
    var nfields = {};
    for (var i=0; i<flds.length; ++i) {
      var f = flds[i];
      var cname = dbConnection.typeName(f.dataTypeID);
      var tname;
      if ( ! cname ) {
        tname = 'unknown(' + f.dataTypeID + ')';
      } else {
        tname = fieldType(cname);
      }
      nfields[f.name] = { type: tname };
    }
    return nfields;
}

MapnikLayerStats.prototype.getStats =
function (layer, dbConnection, callback) {
    let aggrQuery = layer.options.sql_raw || layer.options.sql;
    let preQuery = layer.options.aggregation_metadata ?
        layer.options.aggregation_metadata.pre_aggregation_sql :
        aggrQuery;

    let context = {
        dbConnection,
        preQuery,
        aggrQuery,
        aggrMeta: layer.options.aggregation_metadata,
        metaOptions: layer.options.metadata || {}
    };

    let queries = new PhasedExecution();

    // TODO: could save some queries if queryUtils.getAggregationMetadata() has been used and kept somewhere
    // we would set queries.results.estimatedFeatureCount and queries.results.geometryType
    // (if metaOptions.geometryType) from it.

    // Queries will be executed in two phases, with results from the first phase needed
    // to define the queries of the second phase
    queries.phase(() => firstPhaseQueries(queries, context));
    queries.phase(() => secondPhaseQueries(queries, context));
    queries.run()
        .then(results => callback(null, results))
        .catch(error => callback(error));

};

module.exports = MapnikLayerStats;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Audit a page to see if it's using console.time()/console.timeEnd.
 */

'use strict';

const url = require('url');
const Audit = require('../audit');
const Formatter = require('../../formatters/formatter');

class NoConsoleTimeAudit extends Audit {

  /**
   * @return {!AuditMeta}
   */
  static get meta() {
    return {
      category: 'JavaScript',
      name: 'no-console-time',
      description: 'Site does not use console.time() in its own scripts',
      helpText: 'Consider using the User Timine API (performance.mark() and performance.measure()), which is a standard, uses high resolution timestamps, and has the added benefit of integrating with the DevTools timeline.',
      requiredArtifacts: ['URL', 'ConsoleTimeUsage']
    };
  }

  /**
   * @param {!Artifacts} artifacts
   * @return {!AuditResult}
   */
  static audit(artifacts) {
    if (artifacts.ConsoleTimeUsage.value === -1) {
      let debugString = 'Unknown error with the ConsoleTimeUsage gatherer';
      if (artifacts.ConsoleTimeUsage.debugString) {
        debugString = artifacts.ConsoleTimeUsage.debugString;
      }

      return NoConsoleTimeAudit.generateAuditResult({
        rawValue: -1,
        debugString
      });
    }

    const pageHost = url.parse(artifacts.URL.finalUrl).host;
    // Filter usage from other hosts and keep eval'd code.
    const results = artifacts.ConsoleTimeUsage.usage.filter(err => {
      return err.isEval ? err.url : url.parse(err.url).host === pageHost;
    }).map(err => {
      return Object.assign({
        label: `line: ${err.line}, col: ${err.col}`
      }, err);
    });

    return NoConsoleTimeAudit.generateAuditResult({
      rawValue: results.length === 0,
      extendedInfo: {
        formatter: Formatter.SUPPORTED_FORMATS.URLLIST,
        value: results
      }
    });
  }
}

module.exports = NoConsoleTimeAudit;
<commit_msg>fix typo (#1142)<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Audit a page to see if it's using console.time()/console.timeEnd.
 */

'use strict';

const url = require('url');
const Audit = require('../audit');
const Formatter = require('../../formatters/formatter');

class NoConsoleTimeAudit extends Audit {

  /**
   * @return {!AuditMeta}
   */
  static get meta() {
    return {
      category: 'JavaScript',
      name: 'no-console-time',
      description: 'Site does not use console.time() in its own scripts',
      helpText: 'Consider using the User Timing API (performance.mark() and performance.measure()), which is a standard, uses high resolution timestamps, and has the added benefit of integrating with the DevTools timeline.',
      requiredArtifacts: ['URL', 'ConsoleTimeUsage']
    };
  }

  /**
   * @param {!Artifacts} artifacts
   * @return {!AuditResult}
   */
  static audit(artifacts) {
    if (artifacts.ConsoleTimeUsage.value === -1) {
      let debugString = 'Unknown error with the ConsoleTimeUsage gatherer';
      if (artifacts.ConsoleTimeUsage.debugString) {
        debugString = artifacts.ConsoleTimeUsage.debugString;
      }

      return NoConsoleTimeAudit.generateAuditResult({
        rawValue: -1,
        debugString
      });
    }

    const pageHost = url.parse(artifacts.URL.finalUrl).host;
    // Filter usage from other hosts and keep eval'd code.
    const results = artifacts.ConsoleTimeUsage.usage.filter(err => {
      return err.isEval ? err.url : url.parse(err.url).host === pageHost;
    }).map(err => {
      return Object.assign({
        label: `line: ${err.line}, col: ${err.col}`
      }, err);
    });

    return NoConsoleTimeAudit.generateAuditResult({
      rawValue: results.length === 0,
      extendedInfo: {
        formatter: Formatter.SUPPORTED_FORMATS.URLLIST,
        value: results
      }
    });
  }
}

module.exports = NoConsoleTimeAudit;
<|endoftext|>


<commit_before>/**
 * Create initial config Object
 *
 * @type {Object}
 */
const config = {};

/**
 * Set application page information
 */

// Set application title
config.title  = 'EdenJS';

// Set application domain
config.domain = 'edenjs.com';

// Set application version
config.version = '0.01';

// Set logo
config.logo = '/public/assets/images/logo.svg';

/**
 * Set application server configuration
 */

// Set app environment
config.environment = 'dev';

// Set starting port
config.port = 1337;

// Set server host
config.host = '0.0.0.0';

// set amount of express threads to run
// setting this as null will count your CPU cores
config.expressThreads = 1;

// set amount of compute threads to run
// setting this as null will use 1 compute thread
// compute threads are threads used for backend processes they do not run
// the express application, but do run all daemons
config.computeThreads = 1;

// Websocket configuration
config.socket = {
  'url'    : '//' + config.domain + (config.environment === 'dev' ? ':' + config.port : ''),
  'params' : {
    'reconnect' : true
  }
};

// Redis configuration
config.redis = {
  'host' : 'localhost',
  'port' : 6379
};

// i18n configuration
config.i18n = {
  'cache' : {
    'prefix'         : 'lang_',
    'enabled'        : true,
    'versions'       : {},
    'expirationTime' : 7 * 24 * 60 * 60 * 1000,
  },
  'detection' : {
    'caches'            : ['cookie'],
    'lookupCookie'      : 'lang',
    'lookupQuerystring' : 'lang'
  },
  'defaultNS'    : 'default',
  'fallbackNS'   : 'default',
  'fallbackLng'  : 'en-au',
  'lowerCaseLng' : true
};

// add media dir
config.media = {
  'dir' : 'media'
};

/**
 * Set database configuration
 */

// Set config database object
config.database = {
  'plug'   : 'MongoPlug', // can be MongoPlug, RethinkPlug, CouchPlug or ElasticPlug
  'config' : {
    'db'  : config.domain.split ('.')[0],
    'url' : 'mongodb://localhost:27017'
  }
};

/**
 * Set email transport configuration
 */

// Set SMTP config email object
config.email = {
  'service' : 'Zoho',
  'auth'    : {
    'user' : 'email@domain.com',
    'pass' : 'supersecretemailpassword'
  }
};

/**
 * Set included files
 */

// Set scss imports
// These are imported into app.min.css by default
config.sass = [
  './node_modules/bootstrap/scss/bootstrap.scss'
];

// Set js imports
// These are imported into app.min.js at the top
config.js = [
  './node_modules/whatwg-fetch/fetch.js',
  './node_modules/promise-polyfill/dist/promise.min.js',
  './node_modules/jquery/dist/jquery.min.js',
  './node_modules/popper.js/dist/umd/popper.min.js',
  './node_modules/bootstrap/dist/js/bootstrap.js'
];

/**
 * Set application session secret
 */

// Secret for crypto
config.secret = 'someStrongSecretHash';

// Secret for session
config.session = {
  'key'    : config.domain.split ('.')[0] + '.session.id',
  'cookie' : {
    // Setting secure to true allows for secure sessions over HTTPS;
    // if you are not using https then sessions will break
    'secure'   : false,
    'httpOnly' : false
  }
};

/**
 * Set default ACL information
 */

// Set acl object
config.acl = {
  // default acl per user
  // this is added by default to every registered user
  'default' : [
    {
      name  : 'User',
      value : [
        'user.authenticated'
      ]
    }
  ],
  // default acl for first user (admin)
  // this acl is added only to the first user
  'admin' : [
    {
      name  : 'Admin',
      value : true // assigning true to value gives access to everything
    }
  ]
};

/**
 * Set view import functionality
 */

// Create view object
config.view = {
  // Modules will be required at the top of riot's tags.min.js
  'include' : {
    // Include alert module
    'alert'  : 'alert/public/js/bootstrap',
    // Include socket module
    'socket' : 'socket/public/js/bootstrap'
  }
};

/**
 * Set misc settings
 */

// Create log level setting
config.logLevel = 'info';

/**
 * Export config
 *
 * @type {Object}
 */
module.exports = config;
<commit_msg>enable sitemap by default<commit_after>/**
 * Create initial config Object
 *
 * @type {Object}
 */
const config = {};

/**
 * Set application page information
 */

// Set application title
config.title  = 'EdenJS';

// Set application domain
config.domain = 'edenjs.com';

// Set application version
config.version = '0.01';

// Set logo
config.logo = '/public/assets/images/logo.svg';

/**
 * Set application server configuration
 */

// Set app environment
config.environment = 'dev';

// Set starting port
config.port = 1337;

// Set server host
config.host = '0.0.0.0';

// set amount of express threads to run
// setting this as null will count your CPU cores
config.expressThreads = 1;

// set amount of compute threads to run
// setting this as null will use 1 compute thread
// compute threads are threads used for backend processes they do not run
// the express application, but do run all daemons
config.computeThreads = 1;

// Websocket configuration
config.socket = {
  'url'    : '//' + config.domain + (config.environment === 'dev' ? ':' + config.port : ''),
  'params' : {
    'reconnect' : true
  }
};

// Redis configuration
config.redis = {
  'host' : 'localhost',
  'port' : 6379
};

// i18n configuration
config.i18n = {
  'cache' : {
    'prefix'         : 'lang_',
    'enabled'        : true,
    'versions'       : {},
    'expirationTime' : 7 * 24 * 60 * 60 * 1000,
  },
  'detection' : {
    'caches'            : ['cookie'],
    'lookupCookie'      : 'lang',
    'lookupQuerystring' : 'lang'
  },
  'defaultNS'    : 'default',
  'fallbackNS'   : 'default',
  'fallbackLng'  : 'en-au',
  'lowerCaseLng' : true
};

// add media dir
config.media = {
  'dir' : 'media'
};

// create sitemap
config.sitemap = {
  'enabled' : true
};

/**
 * Set database configuration
 */

// Set config database object
config.database = {
  'plug'   : 'MongoPlug', // can be MongoPlug, RethinkPlug, CouchPlug or ElasticPlug
  'config' : {
    'db'  : config.domain.split ('.')[0],
    'url' : 'mongodb://localhost:27017'
  }
};

/**
 * Set email transport configuration
 */

// Set SMTP config email object
config.email = {
  'service' : 'Zoho',
  'auth'    : {
    'user' : 'email@domain.com',
    'pass' : 'supersecretemailpassword'
  }
};

/**
 * Set included files
 */

// Set scss imports
// These are imported into app.min.css by default
config.sass = [
  './node_modules/bootstrap/scss/bootstrap.scss'
];

// Set js imports
// These are imported into app.min.js at the top
config.js = [
  './node_modules/whatwg-fetch/fetch.js',
  './node_modules/promise-polyfill/dist/promise.min.js',
  './node_modules/jquery/dist/jquery.min.js',
  './node_modules/popper.js/dist/umd/popper.min.js',
  './node_modules/bootstrap/dist/js/bootstrap.js'
];

/**
 * Set application session secret
 */

// Secret for crypto
config.secret = 'someStrongSecretHash';

// Secret for session
config.session = {
  'key'    : config.domain.split ('.')[0] + '.session.id',
  'cookie' : {
    // Setting secure to true allows for secure sessions over HTTPS;
    // if you are not using https then sessions will break
    'secure'   : false,
    'httpOnly' : false
  }
};

/**
 * Set default ACL information
 */

// Set acl object
config.acl = {
  // default acl per user
  // this is added by default to every registered user
  'default' : [
    {
      name  : 'User',
      value : [
        'user.authenticated'
      ]
    }
  ],
  // default acl for first user (admin)
  // this acl is added only to the first user
  'admin' : [
    {
      name  : 'Admin',
      value : true // assigning true to value gives access to everything
    }
  ]
};

/**
 * Set view import functionality
 */

// Create view object
config.view = {
  // Modules will be required at the top of riot's tags.min.js
  'include' : {
    // Include alert module
    'alert'  : 'alert/public/js/bootstrap',
    // Include socket module
    'socket' : 'socket/public/js/bootstrap'
  }
};

/**
 * Set misc settings
 */

// Create log level setting
config.logLevel = 'info';

/**
 * Export config
 *
 * @type {Object}
 */
module.exports = config;
<|endoftext|>


<commit_before>// Copyright (c) 2009, Baidu Inc. All rights reserved.
//
// Licensed under the BSD License
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://tangram.baidu.com/license.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
 * Tangram
 * Copyright 2009 Baidu Inc. All rights reserved.
 */

 /**
 * @namespace T Tangram七巧板
 * @name T
 * @version 1.3.9
*/

/**
 * 声明baidu包
 * @author: allstar, erik, meizz, berg
 */
var T,
    baidu = T = baidu || {version: "1.5.0"};

//提出guid，防止在与老版本Tangram混用时
//在下一行错误的修改window[undefined]
baidu.guid = "$BAIDU$";

//Tangram可能被放在闭包中
//一些页面级别唯一的属性，需要挂载在window[baidu.guid]上
window[baidu.guid] = window[baidu.guid] || {};
<commit_msg>修改版本号<commit_after>// Copyright (c) 2009, Baidu Inc. All rights reserved.
//
// Licensed under the BSD License
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://tangram.baidu.com/license.html
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/*
 * Tangram
 * Copyright 2009 Baidu Inc. All rights reserved.
 */

 /**
 * @namespace T Tangram七巧板
 * @name T
 * @version 1.5.0
*/

/**
 * 声明baidu包
 * @author: allstar, erik, meizz, berg
 */
var T,
    baidu = T = baidu || {version: "1.5.0"};

//提出guid，防止在与老版本Tangram混用时
//在下一行错误的修改window[undefined]
baidu.guid = "$BAIDU$";

//Tangram可能被放在闭包中
//一些页面级别唯一的属性，需要挂载在window[baidu.guid]上
window[baidu.guid] = window[baidu.guid] || {};
<|endoftext|>


<commit_before>/* global navigator */
// require the main entry points for each of these packages
// this is so that the global exports occur properly
import "ember-metal";
import "ember-runtime";
import "ember-handlebars";
import "ember-views";
import "ember-routing";
import "ember-routing-handlebars";
import "ember-application";
import "ember-extension-support";

// do this to ensure that Ember.Test is defined properly on the global
// if it is present.
if (Ember.__loader.registry['ember-testing']) {
  requireModule('ember-testing');
}

/**
Ember

@module ember
*/

Ember.deprecate('Usage of Ember is deprecated for Internet Explorer 6 and 7, support will be removed in the next major version.', !navigator.userAgent.match(/MSIE [67]/));
<commit_msg>Ensure `ember-htmlbars` exports are setup.<commit_after>/* global navigator */
// require the main entry points for each of these packages
// this is so that the global exports occur properly
import "ember-metal";
import "ember-runtime";
import "ember-handlebars";
import "ember-views";
import "ember-routing";
import "ember-routing-handlebars";
import "ember-application";
import "ember-extension-support";
import "ember-htmlbars";

// do this to ensure that Ember.Test is defined properly on the global
// if it is present.
if (Ember.__loader.registry['ember-testing']) {
  requireModule('ember-testing');
}

/**
Ember

@module ember
*/

Ember.deprecate('Usage of Ember is deprecated for Internet Explorer 6 and 7, support will be removed in the next major version.', !navigator.userAgent.match(/MSIE [67]/));
<|endoftext|>


<commit_before>define('event', [], function() {
	function addEvent(el, eventName, command, named) {
		var named = named || 'undefined';
		el['_event'] = el['_event'] || {};
		el['_event'][eventName] = el['_event'][eventName] || {};
		el['_event'][eventName][named] = el['_event'][eventName][named] || [];
		el['_event'][eventName][named].push(command);
	}

	function removeEvent(el, eventName, named) {
		if (el['_event']) {
			if (named && el['_event'][eventName]) {
				el['_event'][eventName][named] = [];
			} else {
				el['_event'][eventName] = {};
			}
		}
	}

	function eventsCommandsFor(el, eventName, named) {
		if (named) {
			if (el['_event'] && el['_event'][eventName]) {
				return el['_event'][eventName][named] || [];
			}
			return [];
		}
		var commands = [];
		if (el['_event']) {
			for (key in el['_event'][eventName]) {
				commands = commands.concat(el['_event'][eventName][key]);
			}
		}
		return commands;
	}

	return {
		addEvent : function(el, eventName, command, namedOrConfigs) {
			var named;
			if (typeof namedOrConfigs === "string") {
				named = namedOrConfigs;
			} else if (typeof namedOrConfigs === "object") {
				named = namedOrConfigs.named;
			}

			if (el.addEventListener) {
				if (namedOrConfigs && namedOrConfigs.passive){
					el.addEventListener(eventName, command, { passive: namedOrConfigs.passive });
				} else {
					el.addEventListener(eventName, command);
				}
				addEvent(el, eventName, command, named);
			} else {
				var newCommand = function() {
					return command.apply(el, arguments);
				};
				el.attachEvent("on" + eventName, newCommand);
				addEvent(el, eventName, newCommand, named);
			}
		},
		removeEvent : function(el, eventName, named) {
			var commands = eventsCommandsFor(el, eventName, named);
			for (var i = 0; i < commands.length; i++) {
				if (el.removeEventListener) {
					el.removeEventListener(eventName, commands[i]);
				} else {
					el.detachEvent('on' + eventName, commands[i]);
				}
			}
			removeEvent(el, eventName, named);
		}
	}
});
<commit_msg>fixes from code review<commit_after>define('event', [], function() {
	function addEvent(el, eventName, command, named) {
		var named = named || 'undefined';
		el['_event'] = el['_event'] || {};
		el['_event'][eventName] = el['_event'][eventName] || {};
		el['_event'][eventName][named] = el['_event'][eventName][named] || [];
		el['_event'][eventName][named].push(command);
	}

	function removeEvent(el, eventName, named) {
		if (el['_event']) {
			if (named && el['_event'][eventName]) {
				el['_event'][eventName][named] = [];
			} else {
				el['_event'][eventName] = {};
			}
		}
	}

	function eventsCommandsFor(el, eventName, named) {
		if (named) {
			if (el['_event'] && el['_event'][eventName]) {
				return el['_event'][eventName][named] || [];
			}
			return [];
		}
		var commands = [];
		if (el['_event']) {
			for (key in el['_event'][eventName]) {
				commands = commands.concat(el['_event'][eventName][key]);
			}
		}
		return commands;
	}

	return {
		addEvent : function(el, eventName, command, namedOrConfigs) {
			var named;
			if (typeof namedOrConfigs === "string") {
				named = namedOrConfigs;
			} else if (typeof namedOrConfigs === "object") {
				named = namedOrConfigs.named;
			}

			if (el.addEventListener) {
				if (namedOrConfigs && namedOrConfigs.passive){
					el.addEventListener(eventName, command, namedOrConfigs);
				} else {
					el.addEventListener(eventName, command);
				}
				addEvent(el, eventName, command, named);
			} else {
				var newCommand = function() {
					return command.apply(el, arguments);
				};
				el.attachEvent("on" + eventName, newCommand);
				addEvent(el, eventName, newCommand, named);
			}
		},
		removeEvent : function(el, eventName, named) {
			var commands = eventsCommandsFor(el, eventName, named);
			for (var i = 0; i < commands.length; i++) {
				if (el.removeEventListener) {
					el.removeEventListener(eventName, commands[i]);
				} else {
					el.detachEvent('on' + eventName, commands[i]);
				}
			}
			removeEvent(el, eventName, named);
		}
	}
});
<|endoftext|>