var require = function (file, cwd) { var resolved = require.resolve(file, cwd || '/'); var mod = require.modules[resolved]; if (!mod) throw new Error( 'Failed to resolve module ' + file + ', tried ' + resolved ); var cached = require.cache[resolved]; var res = cached? cached.exports : mod(); return res; }; require.paths = []; require.modules = {}; require.cache = {}; require.extensions = [".js",".coffee",".json"]; require._core = { 'assert': true, 'events': true, 'fs': true, 'path': true, 'vm': true }; require.resolve = (function () { return function (x, cwd) { if (!cwd) cwd = '/'; if (require._core[x]) return x; var path = require.modules.path(); cwd = path.resolve('/', cwd); var y = cwd || '/'; if (x.match(/^(?:\.\.?\/|\/)/)) { var m = loadAsFileSync(path.resolve(y, x)) || loadAsDirectorySync(path.resolve(y, x)); if (m) return m; } var n = loadNodeModulesSync(x, y); if (n) return n; throw new Error("Cannot find module '" + x + "'"); function loadAsFileSync (x) { x = path.normalize(x); if (require.modules[x]) { return x; } for (var i = 0; i < require.extensions.length; i++) { var ext = require.extensions[i]; if (require.modules[x + ext]) return x + ext; } } function loadAsDirectorySync (x) { x = x.replace(/\/+$/, ''); var pkgfile = path.normalize(x + '/package.json'); if (require.modules[pkgfile]) { var pkg = require.modules[pkgfile](); var b = pkg.browserify; if (typeof b === 'object' && b.main) { var m = loadAsFileSync(path.resolve(x, b.main)); if (m) return m; } else if (typeof b === 'string') { var m = loadAsFileSync(path.resolve(x, b)); if (m) return m; } else if (pkg.main) { var m = loadAsFileSync(path.resolve(x, pkg.main)); if (m) return m; } } return loadAsFileSync(x + '/index'); } function loadNodeModulesSync (x, start) { var dirs = nodeModulesPathsSync(start); for (var i = 0; i < dirs.length; i++) { var dir = dirs[i]; var m = loadAsFileSync(dir + '/' + x); if (m) return m; var n = loadAsDirectorySync(dir + '/' + x); if (n) return n; } var m = loadAsFileSync(x); if (m) return m; } function nodeModulesPathsSync (start) { var parts; if (start === '/') parts = [ '' ]; else parts = path.normalize(start).split('/'); var dirs = []; for (var i = parts.length - 1; i >= 0; i--) { if (parts[i] === 'node_modules') continue; var dir = parts.slice(0, i + 1).join('/') + '/node_modules'; dirs.push(dir); } return dirs; } }; })(); require.alias = function (from, to) { var path = require.modules.path(); var res = null; try { res = require.resolve(from + '/package.json', '/'); } catch (err) { res = require.resolve(from, '/'); } var basedir = path.dirname(res); var keys = (Object.keys || function (obj) { var res = []; for (var key in obj) res.push(key); return res; })(require.modules); for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (key.slice(0, basedir.length + 1) === basedir + '/') { var f = key.slice(basedir.length); require.modules[to + f] = require.modules[basedir + f]; } else if (key === basedir) { require.modules[to] = require.modules[basedir]; } } }; (function () { var process = {}; var global = typeof window !== 'undefined' ? window : {}; var definedProcess = false; require.define = function (filename, fn) { if (!definedProcess && require.modules.__browserify_process) { process = require.modules.__browserify_process(); definedProcess = true; } var dirname = require._core[filename] ? '' : require.modules.path().dirname(filename) ; var require_ = function (file) { var requiredModule = require(file, dirname); var cached = require.cache[require.resolve(file, dirname)]; if (cached && cached.parent === null) { cached.parent = module_; } return requiredModule; }; require_.resolve = function (name) { return require.resolve(name, dirname); }; require_.modules = require.modules; require_.define = require.define; require_.cache = require.cache; var module_ = { id : filename, filename: filename, exports : {}, loaded : false, parent: null }; require.modules[filename] = function () { require.cache[filename] = module_; fn.call( module_.exports, require_, module_, module_.exports, dirname, filename, process, global ); module_.loaded = true; return module_.exports; }; }; })(); require.define("path",function(require,module,exports,__dirname,__filename,process,global){function filter (xs, fn) { var res = []; for (var i = 0; i < xs.length; i++) { if (fn(xs[i], i, xs)) res.push(xs[i]); } return res; } // resolves . and .. elements in a path array with directory names there // must be no slashes, empty elements, or device names (c:\) in the array // (so also no leading and trailing slashes - it does not distinguish // relative and absolute paths) function normalizeArray(parts, allowAboveRoot) { // if the path tries to go above the root, `up` ends up > 0 var up = 0; for (var i = parts.length; i >= 0; i--) { var last = parts[i]; if (last == '.') { parts.splice(i, 1); } else if (last === '..') { parts.splice(i, 1); up++; } else if (up) { parts.splice(i, 1); up--; } } // if the path is allowed to go above the root, restore leading ..s if (allowAboveRoot) { for (; up--; up) { parts.unshift('..'); } } return parts; } // Regex to split a filename into [*, dir, basename, ext] // posix version var splitPathRe = /^(.+\/(?!$)|\/)?((?:.+?)?(\.[^.]*)?)$/; // path.resolve([from ...], to) // posix version exports.resolve = function() { var resolvedPath = '', resolvedAbsolute = false; for (var i = arguments.length; i >= -1 && !resolvedAbsolute; i--) { var path = (i >= 0) ? arguments[i] : process.cwd(); // Skip empty and invalid entries if (typeof path !== 'string' || !path) { continue; } resolvedPath = path + '/' + resolvedPath; resolvedAbsolute = path.charAt(0) === '/'; } // At this point the path should be resolved to a full absolute path, but // handle relative paths to be safe (might happen when process.cwd() fails) // Normalize the path resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { return !!p; }), !resolvedAbsolute).join('/'); return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; }; // path.normalize(path) // posix version exports.normalize = function(path) { var isAbsolute = path.charAt(0) === '/', trailingSlash = path.slice(-1) === '/'; // Normalize the path path = normalizeArray(filter(path.split('/'), function(p) { return !!p; }), !isAbsolute).join('/'); if (!path && !isAbsolute) { path = '.'; } if (path && trailingSlash) { path += '/'; } return (isAbsolute ? '/' : '') + path; }; // posix version exports.join = function() { var paths = Array.prototype.slice.call(arguments, 0); return exports.normalize(filter(paths, function(p, index) { return p && typeof p === 'string'; }).join('/')); }; exports.dirname = function(path) { var dir = splitPathRe.exec(path)[1] || ''; var isWindows = false; if (!dir) { // No dirname return '.'; } else if (dir.length === 1 || (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) { // It is just a slash or a drive letter with a slash return dir; } else { // It is a full dirname, strip trailing slash return dir.substring(0, dir.length - 1); } }; exports.basename = function(path, ext) { var f = splitPathRe.exec(path)[2] || ''; // TODO: make this comparison case-insensitive on windows? if (ext && f.substr(-1 * ext.length) === ext) { f = f.substr(0, f.length - ext.length); } return f; }; exports.extname = function(path) { return splitPathRe.exec(path)[3] || ''; }; exports.relative = function(from, to) { from = exports.resolve(from).substr(1); to = exports.resolve(to).substr(1); function trim(arr) { var start = 0; for (; start < arr.length; start++) { if (arr[start] !== '') break; } var end = arr.length - 1; for (; end >= 0; end--) { if (arr[end] !== '') break; } if (start > end) return []; return arr.slice(start, end - start + 1); } var fromParts = trim(from.split('/')); var toParts = trim(to.split('/')); var length = Math.min(fromParts.length, toParts.length); var samePartsLength = length; for (var i = 0; i < length; i++) { if (fromParts[i] !== toParts[i]) { samePartsLength = i; break; } } var outputParts = []; for (var i = samePartsLength; i < fromParts.length; i++) { outputParts.push('..'); } outputParts = outputParts.concat(toParts.slice(samePartsLength)); return outputParts.join('/'); }; }); require.define("__browserify_process",function(require,module,exports,__dirname,__filename,process,global){var process = module.exports = {}; process.nextTick = (function () { var canSetImmediate = typeof window !== 'undefined' && window.setImmediate; var canPost = typeof window !== 'undefined' && window.postMessage && window.addEventListener ; if (canSetImmediate) { return function (f) { return window.setImmediate(f) }; } if (canPost) { var queue = []; window.addEventListener('message', function (ev) { if (ev.source === window && ev.data === 'browserify-tick') { ev.stopPropagation(); if (queue.length > 0) { var fn = queue.shift(); fn(); } } }, true); return function nextTick(fn) { queue.push(fn); window.postMessage('browserify-tick', '*'); }; } return function nextTick(fn) { setTimeout(fn, 0); }; })(); process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.binding = function (name) { if (name === 'evals') return (require)('vm') else throw new Error('No such module. (Possibly not yet loaded)') }; (function () { var cwd = '/'; var path; process.cwd = function () { return cwd }; process.chdir = function (dir) { if (!path) path = require('path'); cwd = path.resolve(dir, cwd); }; })(); }); require.define("/Core.js",function(require,module,exports,__dirname,__filename,process,global){var Point = (function () { function Point(x, y) { this.x = x; this.y = y; } Point.prototype.toString = function () { return "(" + this.x.toFixed(3) + ", " + this.y.toFixed(3) + ")"; }; return Point; })(); exports.Point = Point; var Coordinate = (function () { function Coordinate(row, column, zoom) { this.row = row; this.column = column; this.zoom = zoom; } Coordinate.prototype.toString = function () { return "(" + this.row.toFixed(3) + ", " + this.column.toFixed(3) + " @" + this.zoom.toFixed(3) + ")"; }; Coordinate.prototype.copy = function () { return new Coordinate(this.row, this.column, this.zoom); }; Coordinate.prototype.container = function () { var coord = this.zoomTo(Math.floor(this.zoom)); return new Coordinate(Math.floor(coord.row), Math.floor(coord.column), coord.zoom); }; Coordinate.prototype.zoomTo = function (destination) { var power = Math.pow(2, destination - this.zoom); return new Coordinate(this.row * power, this.column * power, destination); }; Coordinate.prototype.zoomBy = function (distance) { var power = Math.pow(2, distance); return new Coordinate(this.row * power, this.column * power, this.zoom + distance); }; Coordinate.prototype.up = function (distance) { if (typeof distance === "undefined") { distance = 1; } return new Coordinate(this.row - distance, this.column, this.zoom); }; Coordinate.prototype.right = function (distance) { if (typeof distance === "undefined") { distance = 1; } return new Coordinate(this.row, this.column + distance, this.zoom); }; Coordinate.prototype.down = function (distance) { if (typeof distance === "undefined") { distance = 1; } return new Coordinate(this.row + distance, this.column, this.zoom); }; Coordinate.prototype.left = function (distance) { if (typeof distance === "undefined") { distance = 1; } return new Coordinate(this.row, this.column - distance, this.zoom); }; return Coordinate; })(); exports.Coordinate = Coordinate; }); require.define("/Tile.js",function(require,module,exports,__dirname,__filename,process,global){ var Map = require("./Map") var Tile = (function () { function Tile(coordinate, map) { this.coord = coordinate; this.map = map; } Tile.prototype.toString = function () { return [ this.coord.toString(), this.left(), this.top() ].join(' '); }; Tile.prototype.toKey = function () { return [ Math.floor(this.coord.zoom), Math.floor(this.coord.column), Math.floor(this.coord.row) ].join('/'); }; Tile.prototype.left = function () { var point = this.map.coordinatePoint(this.coord.container()); return Math.round(point.x) + 'px'; }; Tile.prototype.top = function () { var point = this.map.coordinatePoint(this.coord.container()); return Math.round(point.y) + 'px'; }; Tile.prototype.width = function () { var scale = Math.pow(2, this.map.coord.zoom - this.coord.zoom); return Math.ceil(scale * Map.TileSize) + 'px'; }; Tile.prototype.height = function () { var scale = Math.pow(2, this.map.coord.zoom - this.coord.zoom); return Math.ceil(scale * Map.TileSize) + 'px'; }; Tile.prototype.transform = function () { var scale = Math.pow(2, this.map.coord.zoom - this.coord.zoom); if(scale * Map.TileSize % 1) { scale += (1 - scale * Map.TileSize % 1) / Map.TileSize; } var zoomedCoord = this.map.roundCoord().zoomBy(this.coord.zoom - this.map.roundCoord().zoom), x = Math.round(this.map.center.x + (this.coord.column - zoomedCoord.column) * Map.TileSize * scale), y = Math.round(this.map.center.y + (this.coord.row - zoomedCoord.row) * Map.TileSize * scale); return matrix_string(scale, x, y, Map.TileSize / 2.0, Map.TileSize / 2.0); }; return Tile; })(); exports.Tile = Tile; exports.transform_property = null; if('transform' in document.documentElement.style) { exports.transform_property = 'transform'; } else if('-webkit-transform' in document.documentElement.style) { exports.transform_property = '-webkit-transform'; } else if('-o-transform' in document.documentElement.style) { exports.transform_property = '-o-transform'; } else if('-moz-transform' in document.documentElement.style) { exports.transform_property = '-moz-transform'; } else if('-ms-transform' in document.documentElement.style) { exports.transform_property = '-ms-transform'; } function matrix_string(scale, x, y, cx, cy) { if('WebKitCSSMatrix' in window && ('m11' in new window['WebKitCSSMatrix']())) { scale = scale || 1; return 'translate3d(' + [ x.toFixed(0), y.toFixed(0), '0px' ].join('px,') + ') scale3d(' + [ scale.toFixed(8), scale.toFixed(8), '1' ].join(',') + ')'; } var unit = (exports.transform_property == 'MozTransform') ? 'px' : ''; return 'matrix(' + [ (scale || '1'), 0, 0, (scale || '1'), (x + ((cx * scale) - cx)) + unit, (y + ((cy * scale) - cy)) + unit ].join(',') + ')'; } exports.matrix_string = matrix_string; }); require.define("/Map.js",function(require,module,exports,__dirname,__filename,process,global){var Core = require("./Core") var Tile = require("./Tile") exports.TileSize = 256; exports.TileExp = Math.log(exports.TileSize) / Math.log(2); var Map = (function () { function Map(center) { this.center = center; } Map.prototype.roundCoord = function () { return this.coord.zoomTo(Math.round(this.coord.zoom)); }; Map.prototype.resize = function (size) { this.center = new Core.Point(size.x / 2, size.y / 2); }; Map.prototype.panBy = function (diff) { var new_center = new Core.Point(this.center.x - diff.x, this.center.y - diff.y); this.coord = this.pointCoordinate(new_center); }; Map.prototype.zoomByAbout = function (delta, anchor) { var offset = new Core.Point(this.center.x * 2 - anchor.x, this.center.y * 2 - anchor.y), coord = this.pointCoordinate(new Core.Point(anchor.x, anchor.y)); this.coord = coord; this.coord = this.coord.zoomBy(delta); this.coord = this.pointCoordinate(offset); }; Map.prototype.coordinatePoint = function (coord) { var pixel_center = this.coord.zoomBy(exports.TileExp), pixel_coord = coord.zoomTo(pixel_center.zoom), x = this.center.x - pixel_center.column + pixel_coord.column, y = this.center.y - pixel_center.row + pixel_coord.row; return new Core.Point(x, y); }; Map.prototype.pointCoordinate = function (point) { var x = point.x - this.center.x, y = point.y - this.center.y, pixel_center = this.coord.zoomBy(exports.TileExp), pixel_coord = pixel_center.right(x).down(y); return pixel_coord.zoomTo(this.coord.zoom); }; Map.prototype.visible_tiles = function () { var round_coord = this.roundCoord(), tl = this.pointCoordinate(new Core.Point(0, 0)), br = this.pointCoordinate(new Core.Point(this.center.x * 2, this.center.y * 2)); tl = tl.zoomTo(round_coord.zoom).container(); br = br.zoomTo(round_coord.zoom).container(); var tiles = []; for(var i = tl.row; i <= br.row; i++) { for(var j = tl.column; j <= br.column; j++) { var coord = new Core.Coordinate(i, j, round_coord.zoom); tiles.push(new Tile.Tile(coord, this)); } } return tiles; }; return Map; })(); exports.Map = Map; }); require.define("/Grid.js",function(require,module,exports,__dirname,__filename,process,global){var Core = require("./Core") var Tile = require("./Tile") var Map = require("./Map") var Grid = (function () { function Grid(parent) { this.selection = d3.select('#' + parent.id); this.parent = parent; var center = new Core.Point(this.parent.clientWidth / 2, this.parent.clientHeight / 2); this.map = new Map.Map(center); this.map.coord = new Core.Coordinate(0.5, 0.5, 0).zoomTo(3.4); var grid = this; this.selection.on('mousedown.map', function () { grid.onMousedown(); }).on('mousewheel.map', function () { grid.onMousewheel(); }).on('DOMMouseScroll.map', function () { grid.onMousewheel(); }); } Grid.prototype.redraw = function () { var tiles = this.map.visible_tiles(), join = this.selection.selectAll('img').data(tiles, Grid.tile_key); join.exit().remove(); join.enter().append('img').attr('src', function (tile) { return 'http://otile1.mqcdn.com/tiles/1.0.0/osm/' + tile.toKey() + '.jpg'; }); if(Tile.transform_property) { this.selection.selectAll('img').style(Tile.transform_property, Grid.tile_xform); } else { this.selection.selectAll('img').style('left', Grid.tile_left).style('top', Grid.tile_top).style('width', Grid.tile_width).style('height', Grid.tile_height); } }; Grid.tile_key = function tile_key(tile) { return tile.toKey(); }; Grid.tile_left = function tile_left(tile) { return tile.left(); }; Grid.tile_top = function tile_top(tile) { return tile.top(); }; Grid.tile_width = function tile_width(tile) { return tile.width(); }; Grid.tile_height = function tile_height(tile) { return tile.height(); }; Grid.tile_xform = function tile_xform(tile) { return tile.transform(); }; Grid.prototype.onMousedown = function () { var grid = this, start_mouse = new Core.Point(d3.event.pageX, d3.event.pageY); d3.select(window).on('mousemove.map', this.getOnMousemove(start_mouse)).on('mouseup.map', function () { grid.onMouseup(); }); d3.event.preventDefault(); d3.event.stopPropagation(); }; Grid.prototype.onMouseup = function () { d3.select(window).on('mousemove.map', null).on('mouseup.map', null); }; Grid.prototype.getOnMousemove = function (start) { var grid = this, prev = start; return function () { var curr = new Core.Point(d3.event.pageX, d3.event.pageY), diff = new Core.Point(curr.x - prev.x, curr.y - prev.y); grid.map.panBy(diff); grid.redraw(); prev = curr; }; }; Grid.prototype.onMousewheel = function () { var delta = Math.min(18 - this.map.coord.zoom, Math.max(0 - this.map.coord.zoom, this.d3_behavior_zoom_delta())); if(delta != 0) { var mouse = d3.mouse(this.parent), anchor = new Core.Point(mouse[0], mouse[1]); this.map.zoomByAbout(delta, anchor); this.redraw(); } d3.event.preventDefault(); d3.event.stopPropagation(); }; Grid.prototype.d3_behavior_zoom_delta = function () { if(!this.d3_behavior_zoom_div) { this.d3_behavior_zoom_div = d3.select("body").append("div").style("visibility", "hidden").style("top", 0).style("height", 0).style("width", 0).style("overflow-y", "scroll").append("div").style("height", "2000px").node().parentNode; } var e = d3.event, delta; try { this.d3_behavior_zoom_div['scrollTop'] = 250; this.d3_behavior_zoom_div.dispatchEvent(e); delta = 250 - this.d3_behavior_zoom_div['scrollTop']; } catch (error) { delta = e.wheelDelta || (-e.detail * 5); } return delta * 0.005; }; return Grid; })(); function makeMap(parent) { return new Grid(parent); } window['makeMap'] = makeMap; }); require("/Grid.js");