{"action":"created","comment":{"url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/comments/173114858","pull_request_review_id":102247132,"id":173114858,"diff_hunk":"@@ -119,395 +168,474 @@ LayergroupController.prototype.register = function(app) {\n     ];\n \n     app.get(\n-        app.base_url_mapconfig + '/:token/dataview/:dataviewName',\n+        `${basePath}/:token/dataview/:dataviewName`,\n         cors(),\n         userMiddleware(),\n         allowQueryParams(allowedDataviewQueryParams),\n         this.prepareContext,\n-        this.dataview.bind(this)\n+        createMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi),\n+        getDataview(this.dataviewBackend),\n+        setCacheControlHeader(),\n+        setLastModifiedHeader(),\n+        getAffectedTables(this.layergroupAffectedTables, this.pgConnection),\n+        setCacheChannelHeader(),\n+        setSurrogateKeyHeader(this.surrogateKeysCache),\n+        sendResponse()\n     );\n \n     app.get(\n-        app.base_url_mapconfig + '/:token/:layer/widget/:dataviewName',\n+        `${basePath}/:token/:layer/widget/:dataviewName`,\n         cors(),\n         userMiddleware(),\n         allowQueryParams(allowedDataviewQueryParams),\n         this.prepareContext,\n-        this.dataview.bind(this)\n+        createMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi),\n+        getDataview(this.dataviewBackend),\n+        setCacheControlHeader(),\n+        setLastModifiedHeader(),\n+        getAffectedTables(this.layergroupAffectedTables, this.pgConnection),\n+        setCacheChannelHeader(),\n+        setSurrogateKeyHeader(this.surrogateKeysCache),\n+        sendResponse()\n     );\n \n     app.get(\n-        app.base_url_mapconfig + '/:token/dataview/:dataviewName/search',\n+        `${basePath}/:token/dataview/:dataviewName/search`,\n         cors(),\n         userMiddleware(),\n         allowQueryParams(allowedDataviewQueryParams),\n         this.prepareContext,\n-        this.dataviewSearch.bind(this)\n+        createMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi),\n+        dataviewSearch(this.dataviewBackend),\n+        setCacheControlHeader(),\n+        setLastModifiedHeader(),\n+        getAffectedTables(this.layergroupAffectedTables, this.pgConnection),\n+        setCacheChannelHeader(),\n+        setSurrogateKeyHeader(this.surrogateKeysCache),\n+        sendResponse()\n     );\n \n     app.get(\n-        app.base_url_mapconfig + '/:token/:layer/widget/:dataviewName/search',\n+        `${basePath}/:token/:layer/widget/:dataviewName/search`,\n         cors(),\n         userMiddleware(),\n         allowQueryParams(allowedDataviewQueryParams),\n         this.prepareContext,\n-        this.dataviewSearch.bind(this)\n+        createMapStoreMapConfigProvider(this.mapStore, this.userLimitsApi),\n+        dataviewSearch(this.dataviewBackend),\n+        setCacheControlHeader(),\n+        setLastModifiedHeader(),\n+        getAffectedTables(this.layergroupAffectedTables, this.pgConnection),\n+        setCacheChannelHeader(),\n+        setSurrogateKeyHeader(this.surrogateKeysCache),\n+        sendResponse()\n     );\n \n     app.get(\n-        app.base_url_mapconfig + '/:token/analysis/node/:nodeId',\n+        `${basePath}/:token/analysis/node/:nodeId`,\n         cors(),\n         userMiddleware(),\n         this.prepareContext,\n-        this.analysisNodeStatus.bind(this)\n+        analysisNodeStatus(this.analysisStatusBackend),\n+        sendResponse()\n     );\n };\n \n-LayergroupController.prototype.analysisNodeStatus = function(req, res, next) {\n-    var self = this;\n+function distinguishLayergroupFromStaticRoute () {\n+    return function distinguishLayergroupFromStaticRouteMiddleware(req, res, next) {\n+        if (req.params.token === 'static') {\n+            return next('route');\n+        }\n+\n+        next();\n+    };\n+}\n \n-    step(\n-        function retrieveNodeStatus() {\n-            self.analysisStatusBackend.getNodeStatus(res.locals, this);\n-        },\n-        function finish(err, nodeStatus, stats) {\n-            req.profiler.add(stats || {});\n+function analysisNodeStatus (analysisStatusBackend) {\n+    return function analysisNodeStatusMiddleware(req, res, next) {\n+        analysisStatusBackend.getNodeStatus(res.locals, (err, nodeStatus, stats = {}) => {\n+            req.profiler.add(stats);\n \n             if (err) {\n                 err.label = 'GET NODE STATUS';\n-                next(err);\n-            } else {\n-                self.sendResponse(req, res, nodeStatus, 200, {\n-                    'Cache-Control': 'public,max-age=5',\n-                    'Last-Modified': new Date().toUTCString()\n-                });\n+                return next(err);\n             }\n+\n+            res.set({\n+                'Cache-Control': 'public,max-age=5',\n+                'Last-Modified': new Date().toUTCString()\n+            });\n+\n+            res.body = nodeStatus;\n+\n+            next();\n+        });\n+    };\n+}\n+\n+function getRequestParams(locals) {\n+    const params = Object.assign({}, locals);\n+\n+    delete params.mapConfigProvider;\n+    delete params.allowedQueryParams;\n+\n+    return params;\n+}\n+\n+function createMapStoreMapConfigProvider (mapStore, userLimitsApi, forcedFormat = null) {\n+    return function createMapStoreMapConfigProviderMiddleware (req, res, next) {\n+        const { user } = res.locals;\n+\n+        const params = getRequestParams(res.locals);\n+\n+        if (forcedFormat) {\n+            params.format = forcedFormat;\n+            params.layer = params.layer || 'all';\n         }\n-    );\n-};\n \n-LayergroupController.prototype.dataview = function(req, res, next) {\n-    var self = this;\n-\n-    step(\n-        function retrieveDataview() {\n-            var mapConfigProvider = new MapStoreMapConfigProvider(\n-                self.mapStore, res.locals.user, self.userLimitsApi, res.locals\n-            );\n-            self.dataviewBackend.getDataview(\n-                mapConfigProvider,\n-                res.locals.user,\n-                res.locals,\n-                this\n-            );\n-        },\n-        function finish(err, dataview, stats) {\n-            req.profiler.add(stats || {});\n+        const mapConfigProvider = new MapStoreMapConfigProvider(mapStore, user, userLimitsApi, params);\n+\n+        mapConfigProvider.getMapConfig((err, mapconfig) => {\n+            if (err) {\n+                return next(err);\n+            }\n+\n+            res.locals.mapConfigProvider = mapConfigProvider;\n+            res.locals.mapconfig = mapconfig;\n+\n+            next();\n+        });\n+    };\n+}\n+\n+function getDataview (dataviewBackend) {\n+    return function getDataviewMiddleware (req, res, next) {\n+        const { user, mapConfigProvider } = res.locals;\n+        const params = getRequestParams(res.locals);\n+\n+        dataviewBackend.getDataview(mapConfigProvider, user, params, (err, dataview, stats = {}) => {\n+            req.profiler.add(stats);\n \n             if (err) {\n                 err.label = 'GET DATAVIEW';\n-                next(err);\n-            } else {\n-                self.sendResponse(req, res, dataview, 200);\n+                return next(err);\n             }\n-        }\n-    );\n-};\n \n-LayergroupController.prototype.dataviewSearch = function(req, res, next) {\n-    var self = this;\n+            res.body = dataview;\n \n-    step(\n-        function searchDataview() {\n-            var mapConfigProvider = new MapStoreMapConfigProvider(\n-                self.mapStore, res.locals.user, self.userLimitsApi, res.locals\n-            );\n-            self.dataviewBackend.search(mapConfigProvider, res.locals.user, req.params.dataviewName, res.locals, this);\n-        },\n-        function finish(err, searchResult, stats) {\n-            req.profiler.add(stats || {});\n+            next();\n+        });\n+    };\n+}\n+\n+function dataviewSearch (dataviewBackend) {\n+    return function dataviewSearchMiddleware (req, res, next) {\n+        const { user, dataviewName, mapConfigProvider } = res.locals;\n+        const params = getRequestParams(res.locals);\n+\n+        dataviewBackend.search(mapConfigProvider, user, dataviewName, params, (err, searchResult, stats = {}) => {\n+            req.profiler.add(stats);\n \n             if (err) {\n                 err.label = 'GET DATAVIEW SEARCH';\n-                next(err);\n-            } else {\n-                self.sendResponse(req, res, searchResult, 200);\n+                return next(err);\n             }\n-        }\n-    );\n \n-};\n+            res.body = searchResult;\n+\n+            next();\n+        });\n+    };\n+}\n \n-LayergroupController.prototype.attributes = function(req, res, next) {\n-    var self = this;\n+function getFeatureAttributes (attributesBackend) {\n+    return function getFeatureAttributesMiddleware (req, res, next) {\n+        req.profiler.start('windshaft.maplayer_attribute');\n \n-    req.profiler.start('windshaft.maplayer_attribute');\n+        const { mapConfigProvider } = res.locals;\n+        const params = getRequestParams(res.locals);\n \n-    step(\n-        function retrieveFeatureAttributes() {\n-            var mapConfigProvider = new MapStoreMapConfigProvider(\n-                self.mapStore, res.locals.user, self.userLimitsApi, res.locals\n-            );\n-            self.attributesBackend.getFeatureAttributes(mapConfigProvider, res.locals, false, this);\n-        },\n-        function finish(err, tile, stats) {\n-            req.profiler.add(stats || {});\n+        attributesBackend.getFeatureAttributes(mapConfigProvider, params, false, (err, tile, stats = {}) => {\n+            req.profiler.add(stats);\n \n             if (err) {\n                 err.label = 'GET ATTRIBUTES';\n-                next(err);\n-            } else {\n-                self.sendResponse(req, res, tile, 200);\n+                return next(err);\n             }\n-        }\n-    );\n \n-};\n+            res.body = tile;\n \n-// Gets a tile for a given token and set of tile ZXY coords. (OSM style)\n-LayergroupController.prototype.tile = function(req, res, next) {\n-    req.profiler.start('windshaft.map_tile');\n-    this.tileOrLayer(req, res, next);\n-};\n+            next();\n+        });\n+    };\n+}\n \n-// Gets a tile for a given token, layer set of tile ZXY coords. (OSM style)\n-LayergroupController.prototype.layer = function(req, res, next) {\n-    req.profiler.start('windshaft.maplayer_tile');\n-    this.tileOrLayer(req, res, next);\n-};\n+function getStatusCode(tile, format){\n+    return tile.length === 0 && format === 'mvt'? 204 : 200;\n+}\n \n-LayergroupController.prototype.tileOrLayer = function (req, res, next) {\n-    var self = this;\n-\n-    step(\n-        function mapController$getTileOrGrid() {\n-            self.tileBackend.getTile(\n-                new MapStoreMapConfigProvider(self.mapStore, res.locals.user, self.userLimitsApi, res.locals),\n-                res.locals, this\n-            );\n-        },\n-        function mapController$finalize(err, tile, headers, stats) {\n-            req.profiler.add(stats);\n-            self.finalizeGetTileOrGrid(err, req, res, tile, headers, next);\n-        }\n-    );\n+const supportedFormats = {","path":"lib/cartodb/controllers/layergroup.js","position":483,"original_position":483,"commit_id":"6c2f8936516f496259bbff0a36d6a0ee5e2ad845","original_commit_id":"6c2f8936516f496259bbff0a36d6a0ee5e2ad845","user":{"login":"oleurud","id":421145,"avatar_url":"https://avatars3.githubusercontent.com/u/421145?v=4","gravatar_id":"","url":"https://api.github.com/users/oleurud","html_url":"https://github.com/oleurud","followers_url":"https://api.github.com/users/oleurud/followers","following_url":"https://api.github.com/users/oleurud/following{/other_user}","gists_url":"https://api.github.com/users/oleurud/gists{/gist_id}","starred_url":"https://api.github.com/users/oleurud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oleurud/subscriptions","organizations_url":"https://api.github.com/users/oleurud/orgs","repos_url":"https://api.github.com/users/oleurud/repos","events_url":"https://api.github.com/users/oleurud/events{/privacy}","received_events_url":"https://api.github.com/users/oleurud/received_events","type":"User","site_admin":false},"body":"We would use SUPPORTED_FORMATS. And maybe declare in the top","created_at":"2018-03-08T10:11:31Z","updated_at":"2018-03-08T10:11:31Z","html_url":"https://github.com/CartoDB/Windshaft-cartodb/pull/887#discussion_r173114858","pull_request_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/comments/173114858"},"html":{"href":"https://github.com/CartoDB/Windshaft-cartodb/pull/887#discussion_r173114858"},"pull_request":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887"}}},"pull_request":{"url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887","id":173432913,"html_url":"https://github.com/CartoDB/Windshaft-cartodb/pull/887","diff_url":"https://github.com/CartoDB/Windshaft-cartodb/pull/887.diff","patch_url":"https://github.com/CartoDB/Windshaft-cartodb/pull/887.patch","issue_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/887","number":887,"state":"open","locked":false,"title":"Middlewarify layergroup controller","user":{"login":"dgaubert","id":1936888,"avatar_url":"https://avatars0.githubusercontent.com/u/1936888?v=4","gravatar_id":"","url":"https://api.github.com/users/dgaubert","html_url":"https://github.com/dgaubert","followers_url":"https://api.github.com/users/dgaubert/followers","following_url":"https://api.github.com/users/dgaubert/following{/other_user}","gists_url":"https://api.github.com/users/dgaubert/gists{/gist_id}","starred_url":"https://api.github.com/users/dgaubert/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dgaubert/subscriptions","organizations_url":"https://api.github.com/users/dgaubert/orgs","repos_url":"https://api.github.com/users/dgaubert/repos","events_url":"https://api.github.com/users/dgaubert/events{/privacy}","received_events_url":"https://api.github.com/users/dgaubert/received_events","type":"User","site_admin":false},"body":"Closes #868 ","created_at":"2018-03-07T12:08:10Z","updated_at":"2018-03-08T10:11:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"57b141f32b8244fd48fb26b0320276f86f73a692","assignee":null,"assignees":[],"requested_reviewers":[{"login":"enekid","id":623492,"avatar_url":"https://avatars2.githubusercontent.com/u/623492?v=4","gravatar_id":"","url":"https://api.github.com/users/enekid","html_url":"https://github.com/enekid","followers_url":"https://api.github.com/users/enekid/followers","following_url":"https://api.github.com/users/enekid/following{/other_user}","gists_url":"https://api.github.com/users/enekid/gists{/gist_id}","starred_url":"https://api.github.com/users/enekid/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/enekid/subscriptions","organizations_url":"https://api.github.com/users/enekid/orgs","repos_url":"https://api.github.com/users/enekid/repos","events_url":"https://api.github.com/users/enekid/events{/privacy}","received_events_url":"https://api.github.com/users/enekid/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887/commits","review_comments_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887/comments","review_comment_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/comments{/number}","comments_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/887/comments","statuses_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/statuses/6c2f8936516f496259bbff0a36d6a0ee5e2ad845","head":{"label":"CartoDB:middlewarify-layergroup-controller","ref":"middlewarify-layergroup-controller","sha":"6c2f8936516f496259bbff0a36d6a0ee5e2ad845","user":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars0.githubusercontent.com/u/1799254?v=4","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"repo":{"id":2325416,"name":"Windshaft-cartodb","full_name":"CartoDB/Windshaft-cartodb","owner":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars0.githubusercontent.com/u/1799254?v=4","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CartoDB/Windshaft-cartodb","description":"Windshaft tailored for CARTO","fork":false,"url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb","forks_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/forks","keys_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/teams","hooks_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/hooks","issue_events_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/events{/number}","events_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/events","assignees_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/assignees{/user}","branches_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/branches{/branch}","tags_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/tags","blobs_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/statuses/{sha}","languages_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/languages","stargazers_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/stargazers","contributors_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/contributors","subscribers_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/subscribers","subscription_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/subscription","commits_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/contents/{+path}","compare_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/merges","archive_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/downloads","issues_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues{/number}","pulls_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls{/number}","milestones_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/milestones{/number}","notifications_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/labels{/name}","releases_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/releases{/id}","deployments_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/deployments","created_at":"2011-09-04T23:35:06Z","updated_at":"2018-03-07T07:40:41Z","pushed_at":"2018-03-08T09:56:43Z","git_url":"git://github.com/CartoDB/Windshaft-cartodb.git","ssh_url":"git@github.com:CartoDB/Windshaft-cartodb.git","clone_url":"https://github.com/CartoDB/Windshaft-cartodb.git","svn_url":"https://github.com/CartoDB/Windshaft-cartodb","homepage":"","size":34357,"stargazers_count":51,"watchers_count":51,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":46,"mirror_url":null,"archived":false,"open_issues_count":77,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause"},"forks":46,"open_issues":77,"watchers":51,"default_branch":"master"}},"base":{"label":"CartoDB:master","ref":"master","sha":"8509796743ac8d4d64a4fd675979edf7e88a7e31","user":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars0.githubusercontent.com/u/1799254?v=4","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"repo":{"id":2325416,"name":"Windshaft-cartodb","full_name":"CartoDB/Windshaft-cartodb","owner":{"login":"CartoDB","id":1799254,"avatar_url":"https://avatars0.githubusercontent.com/u/1799254?v=4","gravatar_id":"","url":"https://api.github.com/users/CartoDB","html_url":"https://github.com/CartoDB","followers_url":"https://api.github.com/users/CartoDB/followers","following_url":"https://api.github.com/users/CartoDB/following{/other_user}","gists_url":"https://api.github.com/users/CartoDB/gists{/gist_id}","starred_url":"https://api.github.com/users/CartoDB/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CartoDB/subscriptions","organizations_url":"https://api.github.com/users/CartoDB/orgs","repos_url":"https://api.github.com/users/CartoDB/repos","events_url":"https://api.github.com/users/CartoDB/events{/privacy}","received_events_url":"https://api.github.com/users/CartoDB/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CartoDB/Windshaft-cartodb","description":"Windshaft tailored for CARTO","fork":false,"url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb","forks_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/forks","keys_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/teams","hooks_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/hooks","issue_events_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/events{/number}","events_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/events","assignees_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/assignees{/user}","branches_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/branches{/branch}","tags_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/tags","blobs_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/refs{/sha}","trees_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/statuses/{sha}","languages_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/languages","stargazers_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/stargazers","contributors_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/contributors","subscribers_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/subscribers","subscription_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/subscription","commits_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/commits{/sha}","git_commits_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/git/commits{/sha}","comments_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/comments{/number}","issue_comment_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/comments{/number}","contents_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/contents/{+path}","compare_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/merges","archive_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/downloads","issues_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues{/number}","pulls_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls{/number}","milestones_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/milestones{/number}","notifications_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/labels{/name}","releases_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/releases{/id}","deployments_url":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/deployments","created_at":"2011-09-04T23:35:06Z","updated_at":"2018-03-07T07:40:41Z","pushed_at":"2018-03-08T09:56:43Z","git_url":"git://github.com/CartoDB/Windshaft-cartodb.git","ssh_url":"git@github.com:CartoDB/Windshaft-cartodb.git","clone_url":"https://github.com/CartoDB/Windshaft-cartodb.git","svn_url":"https://github.com/CartoDB/Windshaft-cartodb","homepage":"","size":34357,"stargazers_count":51,"watchers_count":51,"language":"JavaScript","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":46,"mirror_url":null,"archived":false,"open_issues_count":77,"license":{"key":"bsd-3-clause","name":"BSD 3-Clause \"New\" or \"Revised\" License","spdx_id":"BSD-3-Clause","url":"https://api.github.com/licenses/bsd-3-clause"},"forks":46,"open_issues":77,"watchers":51,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887"},"html":{"href":"https://github.com/CartoDB/Windshaft-cartodb/pull/887"},"issue":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/887"},"comments":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/issues/887/comments"},"review_comments":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887/comments"},"review_comment":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/pulls/887/commits"},"statuses":{"href":"https://api.github.com/repos/CartoDB/Windshaft-cartodb/statuses/6c2f8936516f496259bbff0a36d6a0ee5e2ad845"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"oleurud"}}