kopia lustrzana https://github.com/robhawkes/vizicities
7831 wiersze
223 KiB
JavaScript
7831 wiersze
223 KiB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
|
||
if(typeof exports === 'object' && typeof module === 'object')
|
||
module.exports = factory(require("proj4"), require("THREE"));
|
||
else if(typeof define === 'function' && define.amd)
|
||
define(["proj4", "THREE"], factory);
|
||
else if(typeof exports === 'object')
|
||
exports["VIZI"] = factory(require("proj4"), require("THREE"));
|
||
else
|
||
root["VIZI"] = factory(root["proj4"], root["THREE"]);
|
||
})(this, function(__WEBPACK_EXTERNAL_MODULE_22__, __WEBPACK_EXTERNAL_MODULE_24__) {
|
||
return /******/ (function(modules) { // webpackBootstrap
|
||
/******/ // The module cache
|
||
/******/ var installedModules = {};
|
||
/******/
|
||
/******/ // The require function
|
||
/******/ function __webpack_require__(moduleId) {
|
||
/******/
|
||
/******/ // Check if module is in cache
|
||
/******/ if(installedModules[moduleId])
|
||
/******/ return installedModules[moduleId].exports;
|
||
/******/
|
||
/******/ // Create a new module (and put it into the cache)
|
||
/******/ var module = installedModules[moduleId] = {
|
||
/******/ exports: {},
|
||
/******/ id: moduleId,
|
||
/******/ loaded: false
|
||
/******/ };
|
||
/******/
|
||
/******/ // Execute the module function
|
||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||
/******/
|
||
/******/ // Flag the module as loaded
|
||
/******/ module.loaded = true;
|
||
/******/
|
||
/******/ // Return the exports of the module
|
||
/******/ return module.exports;
|
||
/******/ }
|
||
/******/
|
||
/******/
|
||
/******/ // expose the modules object (__webpack_modules__)
|
||
/******/ __webpack_require__.m = modules;
|
||
/******/
|
||
/******/ // expose the module cache
|
||
/******/ __webpack_require__.c = installedModules;
|
||
/******/
|
||
/******/ // __webpack_public_path__
|
||
/******/ __webpack_require__.p = "";
|
||
/******/
|
||
/******/ // Load entry module and return exports
|
||
/******/ return __webpack_require__(0);
|
||
/******/ })
|
||
/************************************************************************/
|
||
/******/ ([
|
||
/* 0 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _World = __webpack_require__(1);
|
||
|
||
var _World2 = _interopRequireDefault(_World);
|
||
|
||
var _controlsIndex = __webpack_require__(28);
|
||
|
||
var _controlsIndex2 = _interopRequireDefault(_controlsIndex);
|
||
|
||
var _layerEnvironmentEnvironmentLayer = __webpack_require__(31);
|
||
|
||
var _layerEnvironmentEnvironmentLayer2 = _interopRequireDefault(_layerEnvironmentEnvironmentLayer);
|
||
|
||
var _layerTileImageTileLayer = __webpack_require__(33);
|
||
|
||
var _layerTileImageTileLayer2 = _interopRequireDefault(_layerTileImageTileLayer);
|
||
|
||
var _geoPoint = __webpack_require__(11);
|
||
|
||
var _geoPoint2 = _interopRequireDefault(_geoPoint);
|
||
|
||
var _geoLatLon = __webpack_require__(10);
|
||
|
||
var _geoLatLon2 = _interopRequireDefault(_geoLatLon);
|
||
|
||
var VIZI = {
|
||
version: '0.3',
|
||
|
||
// Public API
|
||
World: _World2['default'],
|
||
Controls: _controlsIndex2['default'],
|
||
EnvironmentLayer: _layerEnvironmentEnvironmentLayer2['default'],
|
||
ImageTileLayer: _layerTileImageTileLayer2['default'],
|
||
Point: _geoPoint2['default'],
|
||
LatLon: _geoLatLon2['default']
|
||
};
|
||
|
||
exports['default'] = VIZI;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 1 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _eventemitter3 = __webpack_require__(2);
|
||
|
||
var _eventemitter32 = _interopRequireDefault(_eventemitter3);
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _geoCRSIndex = __webpack_require__(6);
|
||
|
||
var _geoCRSIndex2 = _interopRequireDefault(_geoCRSIndex);
|
||
|
||
var _geoPoint = __webpack_require__(11);
|
||
|
||
var _geoPoint2 = _interopRequireDefault(_geoPoint);
|
||
|
||
var _geoLatLon = __webpack_require__(10);
|
||
|
||
var _geoLatLon2 = _interopRequireDefault(_geoLatLon);
|
||
|
||
var _engineEngine = __webpack_require__(23);
|
||
|
||
var _engineEngine2 = _interopRequireDefault(_engineEngine);
|
||
|
||
// Pretty much any event someone using ViziCities would need will be emitted or
|
||
// proxied by World (eg. render events, etc)
|
||
|
||
var World = (function (_EventEmitter) {
|
||
_inherits(World, _EventEmitter);
|
||
|
||
function World(domId, options) {
|
||
_classCallCheck(this, World);
|
||
|
||
_get(Object.getPrototypeOf(World.prototype), 'constructor', this).call(this);
|
||
|
||
var defaults = {
|
||
crs: _geoCRSIndex2['default'].EPSG3857
|
||
};
|
||
|
||
this.options = (0, _lodashAssign2['default'])(defaults, options);
|
||
|
||
this._layers = [];
|
||
this._controls = [];
|
||
|
||
this._initContainer(domId);
|
||
this._initEngine();
|
||
this._initEvents();
|
||
|
||
// Kick off the update and render loop
|
||
this._update();
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
_createClass(World, [{
|
||
key: '_initContainer',
|
||
value: function _initContainer(domId) {
|
||
this._container = document.getElementById(domId);
|
||
}
|
||
}, {
|
||
key: '_initEngine',
|
||
value: function _initEngine() {
|
||
this._engine = (0, _engineEngine2['default'])(this._container);
|
||
|
||
// Engine events
|
||
//
|
||
// Consider proxying these through events on World for public access
|
||
// this._engine.on('preRender', () => {});
|
||
// this._engine.on('postRender', () => {});
|
||
}
|
||
}, {
|
||
key: '_initEvents',
|
||
value: function _initEvents() {
|
||
this.on('controlsMoveEnd', this._onControlsMoveEnd);
|
||
}
|
||
}, {
|
||
key: '_onControlsMoveEnd',
|
||
value: function _onControlsMoveEnd(point) {
|
||
var _point = (0, _geoPoint2['default'])(point.x, point.z);
|
||
this._resetView(this.pointToLatLon(_point), _point);
|
||
}
|
||
|
||
// Reset world view
|
||
}, {
|
||
key: '_resetView',
|
||
value: function _resetView(latlon, point) {
|
||
this.emit('preResetView');
|
||
|
||
this._moveStart();
|
||
this._move(latlon, point);
|
||
this._moveEnd();
|
||
|
||
this.emit('postResetView');
|
||
}
|
||
}, {
|
||
key: '_moveStart',
|
||
value: function _moveStart() {
|
||
this.emit('moveStart');
|
||
}
|
||
}, {
|
||
key: '_move',
|
||
value: function _move(latlon, point) {
|
||
this._lastPosition = latlon;
|
||
this.emit('move', latlon, point);
|
||
}
|
||
}, {
|
||
key: '_moveEnd',
|
||
value: function _moveEnd() {
|
||
this.emit('moveEnd');
|
||
}
|
||
}, {
|
||
key: '_update',
|
||
value: function _update() {
|
||
var delta = this._engine.clock.getDelta();
|
||
|
||
// Once _update is called it will run forever, for now
|
||
window.requestAnimationFrame(this._update.bind(this));
|
||
|
||
// Update controls
|
||
this._controls.forEach(function (controls) {
|
||
controls.update();
|
||
});
|
||
|
||
this.emit('preUpdate');
|
||
this._engine.update(delta);
|
||
this.emit('postUpdate');
|
||
}
|
||
|
||
// Set world view
|
||
}, {
|
||
key: 'setView',
|
||
value: function setView(latlon) {
|
||
// Store initial geographic coordinate for the [0,0,0] world position
|
||
//
|
||
// The origin point doesn't move in three.js / 3D space so only set it once
|
||
// here instead of every time _resetView is called
|
||
//
|
||
// If it was updated every time then coorindates would shift over time and
|
||
// would be out of place / context with previously-placed points (0,0 would
|
||
// refer to a different point each time)
|
||
this._originLatlon = latlon;
|
||
this._originPoint = this.project(latlon);
|
||
|
||
this._resetView(latlon);
|
||
return this;
|
||
}
|
||
|
||
// Return world geographic position
|
||
}, {
|
||
key: 'getPosition',
|
||
value: function getPosition() {
|
||
return this._lastPosition;
|
||
}
|
||
|
||
// Transform geographic coordinate to world point
|
||
//
|
||
// This doesn't take into account the origin offset
|
||
//
|
||
// For example, this takes a geographic coordinate and returns a point
|
||
// relative to the origin point of the projection (not the world)
|
||
}, {
|
||
key: 'project',
|
||
value: function project(latlon) {
|
||
return this.options.crs.latLonToPoint((0, _geoLatLon2['default'])(latlon));
|
||
}
|
||
|
||
// Transform world point to geographic coordinate
|
||
//
|
||
// This doesn't take into account the origin offset
|
||
//
|
||
// For example, this takes a point relative to the origin point of the
|
||
// projection (not the world) and returns a geographic coordinate
|
||
}, {
|
||
key: 'unproject',
|
||
value: function unproject(point) {
|
||
return this.options.crs.pointToLatLon((0, _geoPoint2['default'])(point));
|
||
}
|
||
|
||
// Takes into account the origin offset
|
||
//
|
||
// For example, this takes a geographic coordinate and returns a point
|
||
// relative to the three.js / 3D origin (0,0)
|
||
}, {
|
||
key: 'latLonToPoint',
|
||
value: function latLonToPoint(latlon) {
|
||
var projectedPoint = this.project((0, _geoLatLon2['default'])(latlon));
|
||
return projectedPoint._subtract(this._originPoint);
|
||
}
|
||
|
||
// Takes into account the origin offset
|
||
//
|
||
// For example, this takes a point relative to the three.js / 3D origin (0,0)
|
||
// and returns the exact geographic coordinate at that point
|
||
}, {
|
||
key: 'pointToLatLon',
|
||
value: function pointToLatLon(point) {
|
||
var projectedPoint = (0, _geoPoint2['default'])(point).add(this._originPoint);
|
||
return this.unproject(projectedPoint);
|
||
}
|
||
|
||
// Unsure if it's a good idea to expose this here for components like
|
||
// GridLayer to use (eg. to keep track of a frustum)
|
||
}, {
|
||
key: 'getCamera',
|
||
value: function getCamera() {
|
||
return this._engine._camera;
|
||
}
|
||
}, {
|
||
key: 'addLayer',
|
||
value: function addLayer(layer) {
|
||
layer._addToWorld(this);
|
||
|
||
this._layers.push(layer);
|
||
|
||
// Could move this into Layer but it'll do here for now
|
||
this._engine._scene.add(layer._layer);
|
||
|
||
this.emit('layerAdded', layer);
|
||
return this;
|
||
}
|
||
|
||
// Remove layer and perform clean up operations
|
||
}, {
|
||
key: 'removeLayer',
|
||
value: function removeLayer(layer) {
|
||
var layerIndex = this._layers.indexOf(layer);
|
||
|
||
if (layerIndex > -1) {
|
||
// Remove from this._layers
|
||
this._layers.splice(layerIndex, 1);
|
||
};
|
||
|
||
this._engine._scene.remove(layer._layer);
|
||
|
||
layer.destroy();
|
||
|
||
this.emit('layerRemoved');
|
||
return this;
|
||
}
|
||
}, {
|
||
key: 'addControls',
|
||
value: function addControls(controls) {
|
||
controls._addToWorld(this);
|
||
|
||
this._controls.push(controls);
|
||
|
||
this.emit('controlsAdded', controls);
|
||
return this;
|
||
}
|
||
}, {
|
||
key: 'removeControls',
|
||
value: function removeControls(controls) {}
|
||
}]);
|
||
|
||
return World;
|
||
})(_eventemitter32['default']);
|
||
|
||
exports['default'] = function (domId, options) {
|
||
return new World(domId, options);
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 2 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
'use strict';
|
||
|
||
//
|
||
// We store our EE objects in a plain object whose properties are event names.
|
||
// If `Object.create(null)` is not supported we prefix the event names with a
|
||
// `~` to make sure that the built-in object properties are not overridden or
|
||
// used as an attack vector.
|
||
// We also assume that `Object.create(null)` is available when the event name
|
||
// is an ES6 Symbol.
|
||
//
|
||
var prefix = typeof Object.create !== 'function' ? '~' : false;
|
||
|
||
/**
|
||
* Representation of a single EventEmitter function.
|
||
*
|
||
* @param {Function} fn Event handler to be called.
|
||
* @param {Mixed} context Context for function execution.
|
||
* @param {Boolean} once Only emit once
|
||
* @api private
|
||
*/
|
||
function EE(fn, context, once) {
|
||
this.fn = fn;
|
||
this.context = context;
|
||
this.once = once || false;
|
||
}
|
||
|
||
/**
|
||
* Minimal EventEmitter interface that is molded against the Node.js
|
||
* EventEmitter interface.
|
||
*
|
||
* @constructor
|
||
* @api public
|
||
*/
|
||
function EventEmitter() { /* Nothing to set */ }
|
||
|
||
/**
|
||
* Holds the assigned EventEmitters by name.
|
||
*
|
||
* @type {Object}
|
||
* @private
|
||
*/
|
||
EventEmitter.prototype._events = undefined;
|
||
|
||
/**
|
||
* Return a list of assigned event listeners.
|
||
*
|
||
* @param {String} event The events that should be listed.
|
||
* @param {Boolean} exists We only need to know if there are listeners.
|
||
* @returns {Array|Boolean}
|
||
* @api public
|
||
*/
|
||
EventEmitter.prototype.listeners = function listeners(event, exists) {
|
||
var evt = prefix ? prefix + event : event
|
||
, available = this._events && this._events[evt];
|
||
|
||
if (exists) return !!available;
|
||
if (!available) return [];
|
||
if (available.fn) return [available.fn];
|
||
|
||
for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
|
||
ee[i] = available[i].fn;
|
||
}
|
||
|
||
return ee;
|
||
};
|
||
|
||
/**
|
||
* Emit an event to all registered event listeners.
|
||
*
|
||
* @param {String} event The name of the event.
|
||
* @returns {Boolean} Indication if we've emitted an event.
|
||
* @api public
|
||
*/
|
||
EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
|
||
var evt = prefix ? prefix + event : event;
|
||
|
||
if (!this._events || !this._events[evt]) return false;
|
||
|
||
var listeners = this._events[evt]
|
||
, len = arguments.length
|
||
, args
|
||
, i;
|
||
|
||
if ('function' === typeof listeners.fn) {
|
||
if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
|
||
|
||
switch (len) {
|
||
case 1: return listeners.fn.call(listeners.context), true;
|
||
case 2: return listeners.fn.call(listeners.context, a1), true;
|
||
case 3: return listeners.fn.call(listeners.context, a1, a2), true;
|
||
case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
|
||
case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
|
||
case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
|
||
}
|
||
|
||
for (i = 1, args = new Array(len -1); i < len; i++) {
|
||
args[i - 1] = arguments[i];
|
||
}
|
||
|
||
listeners.fn.apply(listeners.context, args);
|
||
} else {
|
||
var length = listeners.length
|
||
, j;
|
||
|
||
for (i = 0; i < length; i++) {
|
||
if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
|
||
|
||
switch (len) {
|
||
case 1: listeners[i].fn.call(listeners[i].context); break;
|
||
case 2: listeners[i].fn.call(listeners[i].context, a1); break;
|
||
case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
|
||
default:
|
||
if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
|
||
args[j - 1] = arguments[j];
|
||
}
|
||
|
||
listeners[i].fn.apply(listeners[i].context, args);
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
/**
|
||
* Register a new EventListener for the given event.
|
||
*
|
||
* @param {String} event Name of the event.
|
||
* @param {Functon} fn Callback function.
|
||
* @param {Mixed} context The context of the function.
|
||
* @api public
|
||
*/
|
||
EventEmitter.prototype.on = function on(event, fn, context) {
|
||
var listener = new EE(fn, context || this)
|
||
, evt = prefix ? prefix + event : event;
|
||
|
||
if (!this._events) this._events = prefix ? {} : Object.create(null);
|
||
if (!this._events[evt]) this._events[evt] = listener;
|
||
else {
|
||
if (!this._events[evt].fn) this._events[evt].push(listener);
|
||
else this._events[evt] = [
|
||
this._events[evt], listener
|
||
];
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Add an EventListener that's only called once.
|
||
*
|
||
* @param {String} event Name of the event.
|
||
* @param {Function} fn Callback function.
|
||
* @param {Mixed} context The context of the function.
|
||
* @api public
|
||
*/
|
||
EventEmitter.prototype.once = function once(event, fn, context) {
|
||
var listener = new EE(fn, context || this, true)
|
||
, evt = prefix ? prefix + event : event;
|
||
|
||
if (!this._events) this._events = prefix ? {} : Object.create(null);
|
||
if (!this._events[evt]) this._events[evt] = listener;
|
||
else {
|
||
if (!this._events[evt].fn) this._events[evt].push(listener);
|
||
else this._events[evt] = [
|
||
this._events[evt], listener
|
||
];
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Remove event listeners.
|
||
*
|
||
* @param {String} event The event we want to remove.
|
||
* @param {Function} fn The listener that we need to find.
|
||
* @param {Mixed} context Only remove listeners matching this context.
|
||
* @param {Boolean} once Only remove once listeners.
|
||
* @api public
|
||
*/
|
||
EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
|
||
var evt = prefix ? prefix + event : event;
|
||
|
||
if (!this._events || !this._events[evt]) return this;
|
||
|
||
var listeners = this._events[evt]
|
||
, events = [];
|
||
|
||
if (fn) {
|
||
if (listeners.fn) {
|
||
if (
|
||
listeners.fn !== fn
|
||
|| (once && !listeners.once)
|
||
|| (context && listeners.context !== context)
|
||
) {
|
||
events.push(listeners);
|
||
}
|
||
} else {
|
||
for (var i = 0, length = listeners.length; i < length; i++) {
|
||
if (
|
||
listeners[i].fn !== fn
|
||
|| (once && !listeners[i].once)
|
||
|| (context && listeners[i].context !== context)
|
||
) {
|
||
events.push(listeners[i]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// Reset the array, or remove it completely if we have no more listeners.
|
||
//
|
||
if (events.length) {
|
||
this._events[evt] = events.length === 1 ? events[0] : events;
|
||
} else {
|
||
delete this._events[evt];
|
||
}
|
||
|
||
return this;
|
||
};
|
||
|
||
/**
|
||
* Remove all listeners or only the listeners for the specified event.
|
||
*
|
||
* @param {String} event The event want to remove all listeners for.
|
||
* @api public
|
||
*/
|
||
EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
|
||
if (!this._events) return this;
|
||
|
||
if (event) delete this._events[prefix ? prefix + event : event];
|
||
else this._events = prefix ? {} : Object.create(null);
|
||
|
||
return this;
|
||
};
|
||
|
||
//
|
||
// Alias methods names because people roll like that.
|
||
//
|
||
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
|
||
EventEmitter.prototype.addListener = EventEmitter.prototype.on;
|
||
|
||
//
|
||
// This function doesn't apply anymore.
|
||
//
|
||
EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
|
||
return this;
|
||
};
|
||
|
||
//
|
||
// Expose the prefix.
|
||
//
|
||
EventEmitter.prefixed = prefix;
|
||
|
||
//
|
||
// Expose the module.
|
||
//
|
||
if (true) {
|
||
module.exports = EventEmitter;
|
||
}
|
||
|
||
|
||
/***/ },
|
||
/* 3 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* lodash 4.0.2 (Custom Build) <https://lodash.com/>
|
||
* Build: `lodash modularize exports="npm" -o ./`
|
||
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
* Available under MIT license <https://lodash.com/license>
|
||
*/
|
||
var keys = __webpack_require__(4),
|
||
rest = __webpack_require__(5);
|
||
|
||
/** Used as references for various `Number` constants. */
|
||
var MAX_SAFE_INTEGER = 9007199254740991;
|
||
|
||
/** `Object#toString` result references. */
|
||
var funcTag = '[object Function]',
|
||
genTag = '[object GeneratorFunction]';
|
||
|
||
/** Used to detect unsigned integer values. */
|
||
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like index.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
||
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
||
*/
|
||
function isIndex(value, length) {
|
||
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
|
||
length = length == null ? MAX_SAFE_INTEGER : length;
|
||
return value > -1 && value % 1 == 0 && value < length;
|
||
}
|
||
|
||
/** Used for built-in method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objectToString = objectProto.toString;
|
||
|
||
/**
|
||
* Assigns `value` to `key` of `object` if the existing value is not equivalent
|
||
* using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
|
||
* for equality comparisons.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to modify.
|
||
* @param {string} key The key of the property to assign.
|
||
* @param {*} value The value to assign.
|
||
*/
|
||
function assignValue(object, key, value) {
|
||
var objValue = object[key];
|
||
if ((!eq(objValue, value) ||
|
||
(eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) ||
|
||
(value === undefined && !(key in object))) {
|
||
object[key] = value;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.property` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {string} key The key of the property to get.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function baseProperty(key) {
|
||
return function(object) {
|
||
return object == null ? undefined : object[key];
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Copies properties of `source` to `object`.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object to copy properties from.
|
||
* @param {Array} props The property names to copy.
|
||
* @param {Object} [object={}] The object to copy properties to.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function copyObject(source, props, object) {
|
||
return copyObjectWith(source, props, object);
|
||
}
|
||
|
||
/**
|
||
* This function is like `copyObject` except that it accepts a function to
|
||
* customize copied values.
|
||
*
|
||
* @private
|
||
* @param {Object} source The object to copy properties from.
|
||
* @param {Array} props The property names to copy.
|
||
* @param {Object} [object={}] The object to copy properties to.
|
||
* @param {Function} [customizer] The function to customize copied values.
|
||
* @returns {Object} Returns `object`.
|
||
*/
|
||
function copyObjectWith(source, props, object, customizer) {
|
||
object || (object = {});
|
||
|
||
var index = -1,
|
||
length = props.length;
|
||
|
||
while (++index < length) {
|
||
var key = props[index],
|
||
newValue = customizer ? customizer(object[key], source[key], key, object, source) : source[key];
|
||
|
||
assignValue(object, key, newValue);
|
||
}
|
||
return object;
|
||
}
|
||
|
||
/**
|
||
* Creates a function like `_.assign`.
|
||
*
|
||
* @private
|
||
* @param {Function} assigner The function to assign values.
|
||
* @returns {Function} Returns the new assigner function.
|
||
*/
|
||
function createAssigner(assigner) {
|
||
return rest(function(object, sources) {
|
||
var index = -1,
|
||
length = sources.length,
|
||
customizer = length > 1 ? sources[length - 1] : undefined,
|
||
guard = length > 2 ? sources[2] : undefined;
|
||
|
||
customizer = typeof customizer == 'function' ? (length--, customizer) : undefined;
|
||
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
|
||
customizer = length < 3 ? undefined : customizer;
|
||
length = 1;
|
||
}
|
||
object = Object(object);
|
||
while (++index < length) {
|
||
var source = sources[index];
|
||
if (source) {
|
||
assigner(object, source, index, customizer);
|
||
}
|
||
}
|
||
return object;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Gets the "length" property value of `object`.
|
||
*
|
||
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
||
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {*} Returns the "length" value.
|
||
*/
|
||
var getLength = baseProperty('length');
|
||
|
||
/**
|
||
* Checks if the provided arguments are from an iteratee call.
|
||
*
|
||
* @private
|
||
* @param {*} value The potential iteratee value argument.
|
||
* @param {*} index The potential iteratee index or key argument.
|
||
* @param {*} object The potential iteratee object argument.
|
||
* @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`.
|
||
*/
|
||
function isIterateeCall(value, index, object) {
|
||
if (!isObject(object)) {
|
||
return false;
|
||
}
|
||
var type = typeof index;
|
||
if (type == 'number'
|
||
? (isArrayLike(object) && isIndex(index, object.length))
|
||
: (type == 'string' && index in object)) {
|
||
return eq(object[index], value);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
|
||
* comparison between two values to determine if they are equivalent.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to compare.
|
||
* @param {*} other The other value to compare.
|
||
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
||
* @example
|
||
*
|
||
* var object = { 'user': 'fred' };
|
||
* var other = { 'user': 'fred' };
|
||
*
|
||
* _.eq(object, object);
|
||
* // => true
|
||
*
|
||
* _.eq(object, other);
|
||
* // => false
|
||
*
|
||
* _.eq('a', 'a');
|
||
* // => true
|
||
*
|
||
* _.eq('a', Object('a'));
|
||
* // => false
|
||
*
|
||
* _.eq(NaN, NaN);
|
||
* // => true
|
||
*/
|
||
function eq(value, other) {
|
||
return value === other || (value !== value && other !== other);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is array-like. A value is considered array-like if it's
|
||
* not a function and has a `value.length` that's an integer greater than or
|
||
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type Function
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArrayLike([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArrayLike(document.body.children);
|
||
* // => true
|
||
*
|
||
* _.isArrayLike('abc');
|
||
* // => true
|
||
*
|
||
* _.isArrayLike(_.noop);
|
||
* // => false
|
||
*/
|
||
function isArrayLike(value) {
|
||
return value != null &&
|
||
!(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Function` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFunction(_);
|
||
* // => true
|
||
*
|
||
* _.isFunction(/abc/);
|
||
* // => false
|
||
*/
|
||
function isFunction(value) {
|
||
// The use of `Object#toString` avoids issues with the `typeof` operator
|
||
// in Safari 8 which returns 'object' for typed array constructors, and
|
||
// PhantomJS 1.9 which returns 'function' for `NodeList` instances.
|
||
var tag = isObject(value) ? objectToString.call(value) : '';
|
||
return tag == funcTag || tag == genTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like length.
|
||
*
|
||
* **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
||
* @example
|
||
*
|
||
* _.isLength(3);
|
||
* // => true
|
||
*
|
||
* _.isLength(Number.MIN_VALUE);
|
||
* // => false
|
||
*
|
||
* _.isLength(Infinity);
|
||
* // => false
|
||
*
|
||
* _.isLength('3');
|
||
* // => false
|
||
*/
|
||
function isLength(value) {
|
||
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(_.noop);
|
||
* // => true
|
||
*
|
||
* _.isObject(null);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
var type = typeof value;
|
||
return !!value && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
/**
|
||
* Assigns own enumerable properties of source objects to the destination
|
||
* object. Source objects are applied from left to right. Subsequent sources
|
||
* overwrite property assignments of previous sources.
|
||
*
|
||
* **Note:** This method mutates `object` and is loosely based on
|
||
* [`Object.assign`](https://mdn.io/Object/assign).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The destination object.
|
||
* @param {...Object} [sources] The source objects.
|
||
* @returns {Object} Returns `object`.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.c = 3;
|
||
* }
|
||
*
|
||
* function Bar() {
|
||
* this.e = 5;
|
||
* }
|
||
*
|
||
* Foo.prototype.d = 4;
|
||
* Bar.prototype.f = 6;
|
||
*
|
||
* _.assign({ 'a': 1 }, new Foo, new Bar);
|
||
* // => { 'a': 1, 'c': 3, 'e': 5 }
|
||
*/
|
||
var assign = createAssigner(function(object, source) {
|
||
copyObject(source, keys(source), object);
|
||
});
|
||
|
||
module.exports = assign;
|
||
|
||
|
||
/***/ },
|
||
/* 4 */
|
||
/***/ function(module, exports) {
|
||
|
||
/**
|
||
* lodash 4.0.2 (Custom Build) <https://lodash.com/>
|
||
* Build: `lodash modularize exports="npm" -o ./`
|
||
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
* Available under MIT license <https://lodash.com/license>
|
||
*/
|
||
|
||
/** Used as references for various `Number` constants. */
|
||
var MAX_SAFE_INTEGER = 9007199254740991;
|
||
|
||
/** `Object#toString` result references. */
|
||
var argsTag = '[object Arguments]',
|
||
funcTag = '[object Function]',
|
||
genTag = '[object GeneratorFunction]',
|
||
stringTag = '[object String]';
|
||
|
||
/** Used to detect unsigned integer values. */
|
||
var reIsUint = /^(?:0|[1-9]\d*)$/;
|
||
|
||
/**
|
||
* The base implementation of `_.times` without support for iteratee shorthands
|
||
* or max array length checks.
|
||
*
|
||
* @private
|
||
* @param {number} n The number of times to invoke `iteratee`.
|
||
* @param {Function} iteratee The function invoked per iteration.
|
||
* @returns {Array} Returns the array of results.
|
||
*/
|
||
function baseTimes(n, iteratee) {
|
||
var index = -1,
|
||
result = Array(n);
|
||
|
||
while (++index < n) {
|
||
result[index] = iteratee(index);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like index.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
|
||
* @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
|
||
*/
|
||
function isIndex(value, length) {
|
||
value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
|
||
length = length == null ? MAX_SAFE_INTEGER : length;
|
||
return value > -1 && value % 1 == 0 && value < length;
|
||
}
|
||
|
||
/** Used for built-in method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/** Used to check objects for own properties. */
|
||
var hasOwnProperty = objectProto.hasOwnProperty;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objectToString = objectProto.toString;
|
||
|
||
/** Built-in value references. */
|
||
var getPrototypeOf = Object.getPrototypeOf,
|
||
propertyIsEnumerable = objectProto.propertyIsEnumerable;
|
||
|
||
/* Built-in method references for those with the same name as other `lodash` methods. */
|
||
var nativeKeys = Object.keys;
|
||
|
||
/**
|
||
* The base implementation of `_.has` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @param {Array|string} key The key to check.
|
||
* @returns {boolean} Returns `true` if `key` exists, else `false`.
|
||
*/
|
||
function baseHas(object, key) {
|
||
// Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,
|
||
// that are composed entirely of index properties, return `false` for
|
||
// `hasOwnProperty` checks of them.
|
||
return hasOwnProperty.call(object, key) ||
|
||
(typeof object == 'object' && key in object && getPrototypeOf(object) === null);
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.keys` which doesn't skip the constructor
|
||
* property of prototypes or treat sparse arrays as dense.
|
||
*
|
||
* @private
|
||
* @type Function
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
*/
|
||
function baseKeys(object) {
|
||
return nativeKeys(Object(object));
|
||
}
|
||
|
||
/**
|
||
* The base implementation of `_.property` without support for deep paths.
|
||
*
|
||
* @private
|
||
* @param {string} key The key of the property to get.
|
||
* @returns {Function} Returns the new function.
|
||
*/
|
||
function baseProperty(key) {
|
||
return function(object) {
|
||
return object == null ? undefined : object[key];
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Gets the "length" property value of `object`.
|
||
*
|
||
* **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
|
||
* that affects Safari on at least iOS 8.1-8.3 ARM64.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {*} Returns the "length" value.
|
||
*/
|
||
var getLength = baseProperty('length');
|
||
|
||
/**
|
||
* Creates an array of index keys for `object` values of arrays,
|
||
* `arguments` objects, and strings, otherwise `null` is returned.
|
||
*
|
||
* @private
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array|null} Returns index keys, else `null`.
|
||
*/
|
||
function indexKeys(object) {
|
||
var length = object ? object.length : undefined;
|
||
if (isLength(length) &&
|
||
(isArray(object) || isString(object) || isArguments(object))) {
|
||
return baseTimes(length, String);
|
||
}
|
||
return null;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is likely a prototype object.
|
||
*
|
||
* @private
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
|
||
*/
|
||
function isPrototype(value) {
|
||
var Ctor = value && value.constructor,
|
||
proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;
|
||
|
||
return value === proto;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is likely an `arguments` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArguments(function() { return arguments; }());
|
||
* // => true
|
||
*
|
||
* _.isArguments([1, 2, 3]);
|
||
* // => false
|
||
*/
|
||
function isArguments(value) {
|
||
// Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
|
||
return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
|
||
(!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as an `Array` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type Function
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArray([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArray(document.body.children);
|
||
* // => false
|
||
*
|
||
* _.isArray('abc');
|
||
* // => false
|
||
*
|
||
* _.isArray(_.noop);
|
||
* // => false
|
||
*/
|
||
var isArray = Array.isArray;
|
||
|
||
/**
|
||
* Checks if `value` is array-like. A value is considered array-like if it's
|
||
* not a function and has a `value.length` that's an integer greater than or
|
||
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type Function
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArrayLike([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArrayLike(document.body.children);
|
||
* // => true
|
||
*
|
||
* _.isArrayLike('abc');
|
||
* // => true
|
||
*
|
||
* _.isArrayLike(_.noop);
|
||
* // => false
|
||
*/
|
||
function isArrayLike(value) {
|
||
return value != null &&
|
||
!(typeof value == 'function' && isFunction(value)) && isLength(getLength(value));
|
||
}
|
||
|
||
/**
|
||
* This method is like `_.isArrayLike` except that it also checks if `value`
|
||
* is an object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type Function
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an array-like object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isArrayLikeObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isArrayLikeObject(document.body.children);
|
||
* // => true
|
||
*
|
||
* _.isArrayLikeObject('abc');
|
||
* // => false
|
||
*
|
||
* _.isArrayLikeObject(_.noop);
|
||
* // => false
|
||
*/
|
||
function isArrayLikeObject(value) {
|
||
return isObjectLike(value) && isArrayLike(value);
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Function` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFunction(_);
|
||
* // => true
|
||
*
|
||
* _.isFunction(/abc/);
|
||
* // => false
|
||
*/
|
||
function isFunction(value) {
|
||
// The use of `Object#toString` avoids issues with the `typeof` operator
|
||
// in Safari 8 which returns 'object' for typed array constructors, and
|
||
// PhantomJS 1.9 which returns 'function' for `NodeList` instances.
|
||
var tag = isObject(value) ? objectToString.call(value) : '';
|
||
return tag == funcTag || tag == genTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is a valid array-like length.
|
||
*
|
||
* **Note:** This function is loosely based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
|
||
* @example
|
||
*
|
||
* _.isLength(3);
|
||
* // => true
|
||
*
|
||
* _.isLength(Number.MIN_VALUE);
|
||
* // => false
|
||
*
|
||
* _.isLength(Infinity);
|
||
* // => false
|
||
*
|
||
* _.isLength('3');
|
||
* // => false
|
||
*/
|
||
function isLength(value) {
|
||
return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(_.noop);
|
||
* // => true
|
||
*
|
||
* _.isObject(null);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
var type = typeof value;
|
||
return !!value && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
||
* and has a `typeof` result of "object".
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObjectLike({});
|
||
* // => true
|
||
*
|
||
* _.isObjectLike([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObjectLike(_.noop);
|
||
* // => false
|
||
*
|
||
* _.isObjectLike(null);
|
||
* // => false
|
||
*/
|
||
function isObjectLike(value) {
|
||
return !!value && typeof value == 'object';
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `String` primitive or object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isString('abc');
|
||
* // => true
|
||
*
|
||
* _.isString(1);
|
||
* // => false
|
||
*/
|
||
function isString(value) {
|
||
return typeof value == 'string' ||
|
||
(!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);
|
||
}
|
||
|
||
/**
|
||
* Creates an array of the own enumerable property names of `object`.
|
||
*
|
||
* **Note:** Non-object values are coerced to objects. See the
|
||
* [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
|
||
* for more details.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Object
|
||
* @param {Object} object The object to query.
|
||
* @returns {Array} Returns the array of property names.
|
||
* @example
|
||
*
|
||
* function Foo() {
|
||
* this.a = 1;
|
||
* this.b = 2;
|
||
* }
|
||
*
|
||
* Foo.prototype.c = 3;
|
||
*
|
||
* _.keys(new Foo);
|
||
* // => ['a', 'b'] (iteration order is not guaranteed)
|
||
*
|
||
* _.keys('hi');
|
||
* // => ['0', '1']
|
||
*/
|
||
function keys(object) {
|
||
var isProto = isPrototype(object);
|
||
if (!(isProto || isArrayLike(object))) {
|
||
return baseKeys(object);
|
||
}
|
||
var indexes = indexKeys(object),
|
||
skipIndexes = !!indexes,
|
||
result = indexes || [],
|
||
length = result.length;
|
||
|
||
for (var key in object) {
|
||
if (baseHas(object, key) &&
|
||
!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
|
||
!(isProto && key == 'constructor')) {
|
||
result.push(key);
|
||
}
|
||
}
|
||
return result;
|
||
}
|
||
|
||
module.exports = keys;
|
||
|
||
|
||
/***/ },
|
||
/* 5 */
|
||
/***/ function(module, exports) {
|
||
|
||
/**
|
||
* lodash 4.0.1 (Custom Build) <https://lodash.com/>
|
||
* Build: `lodash modularize exports="npm" -o ./`
|
||
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
* Available under MIT license <https://lodash.com/license>
|
||
*/
|
||
|
||
/** Used as the `TypeError` message for "Functions" methods. */
|
||
var FUNC_ERROR_TEXT = 'Expected a function';
|
||
|
||
/** Used as references for various `Number` constants. */
|
||
var INFINITY = 1 / 0,
|
||
MAX_INTEGER = 1.7976931348623157e+308,
|
||
NAN = 0 / 0;
|
||
|
||
/** `Object#toString` result references. */
|
||
var funcTag = '[object Function]',
|
||
genTag = '[object GeneratorFunction]';
|
||
|
||
/** Used to match leading and trailing whitespace. */
|
||
var reTrim = /^\s+|\s+$/g;
|
||
|
||
/** Used to detect bad signed hexadecimal string values. */
|
||
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
||
|
||
/** Used to detect binary string values. */
|
||
var reIsBinary = /^0b[01]+$/i;
|
||
|
||
/** Used to detect octal string values. */
|
||
var reIsOctal = /^0o[0-7]+$/i;
|
||
|
||
/** Built-in method references without a dependency on `root`. */
|
||
var freeParseInt = parseInt;
|
||
|
||
/**
|
||
* A faster alternative to `Function#apply`, this function invokes `func`
|
||
* with the `this` binding of `thisArg` and the arguments of `args`.
|
||
*
|
||
* @private
|
||
* @param {Function} func The function to invoke.
|
||
* @param {*} thisArg The `this` binding of `func`.
|
||
* @param {...*} args The arguments to invoke `func` with.
|
||
* @returns {*} Returns the result of `func`.
|
||
*/
|
||
function apply(func, thisArg, args) {
|
||
var length = args.length;
|
||
switch (length) {
|
||
case 0: return func.call(thisArg);
|
||
case 1: return func.call(thisArg, args[0]);
|
||
case 2: return func.call(thisArg, args[0], args[1]);
|
||
case 3: return func.call(thisArg, args[0], args[1], args[2]);
|
||
}
|
||
return func.apply(thisArg, args);
|
||
}
|
||
|
||
/** Used for built-in method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objectToString = objectProto.toString;
|
||
|
||
/* Built-in method references for those with the same name as other `lodash` methods. */
|
||
var nativeMax = Math.max;
|
||
|
||
/**
|
||
* Creates a function that invokes `func` with the `this` binding of the
|
||
* created function and arguments from `start` and beyond provided as an array.
|
||
*
|
||
* **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Function
|
||
* @param {Function} func The function to apply a rest parameter to.
|
||
* @param {number} [start=func.length-1] The start position of the rest parameter.
|
||
* @returns {Function} Returns the new function.
|
||
* @example
|
||
*
|
||
* var say = _.rest(function(what, names) {
|
||
* return what + ' ' + _.initial(names).join(', ') +
|
||
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
|
||
* });
|
||
*
|
||
* say('hello', 'fred', 'barney', 'pebbles');
|
||
* // => 'hello fred, barney, & pebbles'
|
||
*/
|
||
function rest(func, start) {
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
|
||
return function() {
|
||
var args = arguments,
|
||
index = -1,
|
||
length = nativeMax(args.length - start, 0),
|
||
array = Array(length);
|
||
|
||
while (++index < length) {
|
||
array[index] = args[start + index];
|
||
}
|
||
switch (start) {
|
||
case 0: return func.call(this, array);
|
||
case 1: return func.call(this, args[0], array);
|
||
case 2: return func.call(this, args[0], args[1], array);
|
||
}
|
||
var otherArgs = Array(start + 1);
|
||
index = -1;
|
||
while (++index < start) {
|
||
otherArgs[index] = args[index];
|
||
}
|
||
otherArgs[start] = array;
|
||
return apply(func, this, otherArgs);
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Function` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFunction(_);
|
||
* // => true
|
||
*
|
||
* _.isFunction(/abc/);
|
||
* // => false
|
||
*/
|
||
function isFunction(value) {
|
||
// The use of `Object#toString` avoids issues with the `typeof` operator
|
||
// in Safari 8 which returns 'object' for typed array constructors, and
|
||
// PhantomJS 1.9 which returns 'function' for `NodeList` instances.
|
||
var tag = isObject(value) ? objectToString.call(value) : '';
|
||
return tag == funcTag || tag == genTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(_.noop);
|
||
* // => true
|
||
*
|
||
* _.isObject(null);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
var type = typeof value;
|
||
return !!value && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to an integer.
|
||
*
|
||
* **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to convert.
|
||
* @returns {number} Returns the converted integer.
|
||
* @example
|
||
*
|
||
* _.toInteger(3);
|
||
* // => 3
|
||
*
|
||
* _.toInteger(Number.MIN_VALUE);
|
||
* // => 0
|
||
*
|
||
* _.toInteger(Infinity);
|
||
* // => 1.7976931348623157e+308
|
||
*
|
||
* _.toInteger('3');
|
||
* // => 3
|
||
*/
|
||
function toInteger(value) {
|
||
if (!value) {
|
||
return value === 0 ? value : 0;
|
||
}
|
||
value = toNumber(value);
|
||
if (value === INFINITY || value === -INFINITY) {
|
||
var sign = (value < 0 ? -1 : 1);
|
||
return sign * MAX_INTEGER;
|
||
}
|
||
var remainder = value % 1;
|
||
return value === value ? (remainder ? value - remainder : value) : 0;
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a number.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to process.
|
||
* @returns {number} Returns the number.
|
||
* @example
|
||
*
|
||
* _.toNumber(3);
|
||
* // => 3
|
||
*
|
||
* _.toNumber(Number.MIN_VALUE);
|
||
* // => 5e-324
|
||
*
|
||
* _.toNumber(Infinity);
|
||
* // => Infinity
|
||
*
|
||
* _.toNumber('3');
|
||
* // => 3
|
||
*/
|
||
function toNumber(value) {
|
||
if (isObject(value)) {
|
||
var other = isFunction(value.valueOf) ? value.valueOf() : value;
|
||
value = isObject(other) ? (other + '') : other;
|
||
}
|
||
if (typeof value != 'string') {
|
||
return value === 0 ? value : +value;
|
||
}
|
||
value = value.replace(reTrim, '');
|
||
var isBinary = reIsBinary.test(value);
|
||
return (isBinary || reIsOctal.test(value))
|
||
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
||
: (reIsBadHex.test(value) ? NAN : +value);
|
||
}
|
||
|
||
module.exports = rest;
|
||
|
||
|
||
/***/ },
|
||
/* 6 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _CRSEPSG3857 = __webpack_require__(7);
|
||
|
||
var _CRSEPSG38572 = _interopRequireDefault(_CRSEPSG3857);
|
||
|
||
var _CRSEPSG3395 = __webpack_require__(15);
|
||
|
||
var _CRSEPSG33952 = _interopRequireDefault(_CRSEPSG3395);
|
||
|
||
var _CRSEPSG4326 = __webpack_require__(17);
|
||
|
||
var _CRSEPSG43262 = _interopRequireDefault(_CRSEPSG4326);
|
||
|
||
var _CRSSimple = __webpack_require__(19);
|
||
|
||
var _CRSSimple2 = _interopRequireDefault(_CRSSimple);
|
||
|
||
var _CRSProj4 = __webpack_require__(20);
|
||
|
||
var _CRSProj42 = _interopRequireDefault(_CRSProj4);
|
||
|
||
var CRS = {};
|
||
|
||
CRS.EPSG3857 = _CRSEPSG38572['default'];
|
||
CRS.EPSG900913 = _CRSEPSG3857.EPSG900913;
|
||
CRS.EPSG3395 = _CRSEPSG33952['default'];
|
||
CRS.EPSG4326 = _CRSEPSG43262['default'];
|
||
CRS.Simple = _CRSSimple2['default'];
|
||
CRS.Proj4 = _CRSProj42['default'];
|
||
|
||
exports['default'] = CRS;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 7 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* CRS.EPSG3857 (WGS 84 / Pseudo-Mercator) CRS implementation.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.EPSG3857.js
|
||
*/
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _CRSEarth = __webpack_require__(8);
|
||
|
||
var _CRSEarth2 = _interopRequireDefault(_CRSEarth);
|
||
|
||
var _projectionProjectionSphericalMercator = __webpack_require__(13);
|
||
|
||
var _projectionProjectionSphericalMercator2 = _interopRequireDefault(_projectionProjectionSphericalMercator);
|
||
|
||
var _utilTransformation = __webpack_require__(14);
|
||
|
||
var _utilTransformation2 = _interopRequireDefault(_utilTransformation);
|
||
|
||
var _EPSG3857 = {
|
||
code: 'EPSG:3857',
|
||
projection: _projectionProjectionSphericalMercator2['default'],
|
||
|
||
// Work out how to de-dupe this (scoping issue)
|
||
transformScale: 1 / (Math.PI * _projectionProjectionSphericalMercator2['default'].R),
|
||
|
||
// Scale and transformation inputs changed to account for central origin in
|
||
// WebGL, instead of top-left origin used in Leaflet
|
||
transformation: (function () {
|
||
// TODO: Cannot use this.transformScale due to scope
|
||
var scale = 1 / (Math.PI * _projectionProjectionSphericalMercator2['default'].R);
|
||
|
||
return new _utilTransformation2['default'](scale, 0, -scale, 0);
|
||
})()
|
||
};
|
||
|
||
var EPSG3857 = (0, _lodashAssign2['default'])({}, _CRSEarth2['default'], _EPSG3857);
|
||
|
||
var EPSG900913 = (0, _lodashAssign2['default'])({}, EPSG3857, {
|
||
code: 'EPSG:900913'
|
||
});
|
||
|
||
exports.EPSG900913 = EPSG900913;
|
||
exports['default'] = EPSG3857;
|
||
|
||
/***/ },
|
||
/* 8 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* CRS.Earth is the base class for all CRS representing Earth.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.Earth.js
|
||
*/
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _CRS = __webpack_require__(9);
|
||
|
||
var _CRS2 = _interopRequireDefault(_CRS);
|
||
|
||
var _LatLon = __webpack_require__(10);
|
||
|
||
var _LatLon2 = _interopRequireDefault(_LatLon);
|
||
|
||
var Earth = {
|
||
wrapLon: [-180, 180],
|
||
|
||
R: 6378137,
|
||
|
||
// Distance between two geographical points using spherical law of cosines
|
||
// approximation or Haversine
|
||
//
|
||
// See: http://www.movable-type.co.uk/scripts/latlong.html
|
||
distance: function distance(latlon1, latlon2, accurate) {
|
||
var rad = Math.PI / 180;
|
||
|
||
var lat1;
|
||
var lat2;
|
||
|
||
var a;
|
||
|
||
if (!accurate) {
|
||
lat1 = latlon1.lat * rad;
|
||
lat2 = latlon2.lat * rad;
|
||
|
||
a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);
|
||
|
||
return this.R * Math.acos(Math.min(a, 1));
|
||
} else {
|
||
lat1 = latlon1.lat * rad;
|
||
lat2 = latlon2.lat * rad;
|
||
|
||
var lon1 = latlon1.lon * rad;
|
||
var lon2 = latlon2.lon * rad;
|
||
|
||
var deltaLat = lat2 - lat1;
|
||
var deltaLon = lon2 - lon1;
|
||
|
||
var halfDeltaLat = deltaLat / 2;
|
||
var halfDeltaLon = deltaLon / 2;
|
||
|
||
a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);
|
||
|
||
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
||
|
||
return this.R * c;
|
||
}
|
||
},
|
||
|
||
// Scale factor for converting between real metres and projected metres
|
||
//
|
||
// projectedMetres = realMetres * pointScale
|
||
// realMetres = projectedMetres / pointScale
|
||
//
|
||
// Defaults to a scale factor of 1 if no calculation method exists
|
||
//
|
||
// Probably need to run this through the CRS transformation or similar so the
|
||
// resulting scale is relative to the dimensions of the world space
|
||
// Eg. 1 metre in projected space is likly scaled up or down to some other
|
||
// number
|
||
pointScale: function pointScale(latlon, accurate) {
|
||
return this.projection.pointScale ? this.projection.pointScale(latlon, accurate) : [1, 1];
|
||
},
|
||
|
||
// Convert real metres to projected units
|
||
//
|
||
// Latitude scale is chosen because it fluctuates more than longitude
|
||
metresToProjected: function metresToProjected(metres, pointScale) {
|
||
return metres * pointScale[1];
|
||
},
|
||
|
||
// Convert projected units to real metres
|
||
//
|
||
// Latitude scale is chosen because it fluctuates more than longitude
|
||
projectedToMetres: function projectedToMetres(projectedUnits, pointScale) {
|
||
return projectedUnits / pointScale[1];
|
||
},
|
||
|
||
// Convert real metres to a value in world (WebGL) units
|
||
metresToWorld: function metresToWorld(metres, pointScale, zoom) {
|
||
// Transform metres to projected metres using the latitude point scale
|
||
//
|
||
// Latitude scale is chosen because it fluctuates more than longitude
|
||
var projectedMetres = this.metresToProjected(metres, pointScale);
|
||
|
||
var scale = this.scale(zoom);
|
||
|
||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||
if (zoom) {
|
||
scale /= 2;
|
||
}
|
||
|
||
// Scale projected metres
|
||
var scaledMetres = scale * (this.transformScale * projectedMetres) / pointScale[1];
|
||
|
||
return scaledMetres;
|
||
},
|
||
|
||
// Convert world (WebGL) units to a value in real metres
|
||
worldToMetres: function worldToMetres(worldUnits, pointScale, zoom) {
|
||
var scale = this.scale(zoom);
|
||
|
||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||
if (zoom) {
|
||
scale /= 2;
|
||
}
|
||
|
||
var projectedUnits = worldUnits / scale / this.transformScale * pointScale[1];
|
||
var realMetres = this.projectedToMetres(projectedUnits, pointScale);
|
||
|
||
return realMetres;
|
||
}
|
||
};
|
||
|
||
exports['default'] = (0, _lodashAssign2['default'])({}, _CRS2['default'], Earth);
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 9 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* CRS is the base object for all defined CRS (Coordinate Reference Systems)
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.js
|
||
*/
|
||
|
||
var _LatLon = __webpack_require__(10);
|
||
|
||
var _LatLon2 = _interopRequireDefault(_LatLon);
|
||
|
||
var _Point = __webpack_require__(11);
|
||
|
||
var _Point2 = _interopRequireDefault(_Point);
|
||
|
||
var _utilWrapNum = __webpack_require__(12);
|
||
|
||
var _utilWrapNum2 = _interopRequireDefault(_utilWrapNum);
|
||
|
||
var CRS = {
|
||
// Scale factor determines final dimensions of world space
|
||
//
|
||
// Projection transformation in range -1 to 1 is multiplied by scale factor to
|
||
// find final world coordinates
|
||
//
|
||
// Scale factor can be considered as half the amount of the desired dimension
|
||
// for the largest side when transformation is equal to 1 or -1, or as the
|
||
// distance between 0 and 1 on the largest side
|
||
//
|
||
// For example, if you want the world dimensions to be between -1000 and 1000
|
||
// then the scale factor will be 1000
|
||
scaleFactor: 1000000,
|
||
|
||
// Converts geo coords to pixel / WebGL ones
|
||
latLonToPoint: function latLonToPoint(latlon, zoom) {
|
||
var projectedPoint = this.projection.project(latlon);
|
||
var scale = this.scale(zoom);
|
||
|
||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||
if (zoom) {
|
||
scale /= 2;
|
||
}
|
||
|
||
return this.transformation._transform(projectedPoint, scale);
|
||
},
|
||
|
||
// Converts pixel / WebGL coords to geo coords
|
||
pointToLatLon: function pointToLatLon(point, zoom) {
|
||
var scale = this.scale(zoom);
|
||
|
||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||
if (zoom) {
|
||
scale /= 2;
|
||
}
|
||
|
||
var untransformedPoint = this.transformation.untransform(point, scale);
|
||
|
||
return this.projection.unproject(untransformedPoint);
|
||
},
|
||
|
||
// Converts geo coords to projection-specific coords (e.g. in meters)
|
||
project: function project(latlon) {
|
||
return this.projection.project(latlon);
|
||
},
|
||
|
||
// Converts projected coords to geo coords
|
||
unproject: function unproject(point) {
|
||
return this.projection.unproject(point);
|
||
},
|
||
|
||
// If zoom is provided, returns the map width in pixels for a given zoom
|
||
// Else, provides fixed scale value
|
||
scale: function scale(zoom) {
|
||
// If zoom is provided then return scale based on map tile zoom
|
||
if (zoom >= 0) {
|
||
return 256 * Math.pow(2, zoom);
|
||
// Else, return fixed scale value to expand projected coordinates from
|
||
// their 0 to 1 range into something more practical
|
||
} else {
|
||
return this.scaleFactor;
|
||
}
|
||
},
|
||
|
||
// Returns zoom level for a given scale value
|
||
// This only works with a scale value that is based on map pixel width
|
||
zoom: function zoom(scale) {
|
||
return Math.log(scale / 256) / Math.LN2;
|
||
},
|
||
|
||
// Returns the bounds of the world in projected coords if applicable
|
||
getProjectedBounds: function getProjectedBounds(zoom) {
|
||
if (this.infinite) {
|
||
return null;
|
||
}
|
||
|
||
var b = this.projection.bounds;
|
||
var s = this.scale(zoom);
|
||
|
||
// Half scale if using zoom as WebGL origin is in the centre, not top left
|
||
if (zoom) {
|
||
s /= 2;
|
||
}
|
||
|
||
// Bottom left
|
||
var min = this.transformation.transform((0, _Point2['default'])(b[0]), s);
|
||
|
||
// Top right
|
||
var max = this.transformation.transform((0, _Point2['default'])(b[1]), s);
|
||
|
||
return [min, max];
|
||
},
|
||
|
||
// Whether a coordinate axis wraps in a given range (e.g. longitude from -180 to 180); depends on CRS
|
||
// wrapLon: [min, max],
|
||
// wrapLat: [min, max],
|
||
|
||
// If true, the coordinate space will be unbounded (infinite in all directions)
|
||
// infinite: false,
|
||
|
||
// Wraps geo coords in certain ranges if applicable
|
||
wrapLatLon: function wrapLatLon(latlon) {
|
||
var lat = this.wrapLat ? (0, _utilWrapNum2['default'])(latlon.lat, this.wrapLat, true) : latlon.lat;
|
||
var lon = this.wrapLon ? (0, _utilWrapNum2['default'])(latlon.lon, this.wrapLon, true) : latlon.lon;
|
||
var alt = latlon.alt;
|
||
|
||
return (0, _LatLon2['default'])(lat, lon, alt);
|
||
}
|
||
};
|
||
|
||
exports['default'] = CRS;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 10 */
|
||
/***/ function(module, exports) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
/*
|
||
* LatLon is a helper class for ensuring consistent geographic coordinates.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js
|
||
*/
|
||
|
||
var LatLon = (function () {
|
||
function LatLon(lat, lon, alt) {
|
||
_classCallCheck(this, LatLon);
|
||
|
||
if (isNaN(lat) || isNaN(lon)) {
|
||
throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');
|
||
}
|
||
|
||
this.lat = +lat;
|
||
this.lon = +lon;
|
||
|
||
if (alt !== undefined) {
|
||
this.alt = +alt;
|
||
}
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
//
|
||
// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)
|
||
// Also converts between lng and lon
|
||
|
||
_createClass(LatLon, [{
|
||
key: 'clone',
|
||
value: function clone() {
|
||
return new LatLon(this.lat, this.lon, this.alt);
|
||
}
|
||
}]);
|
||
|
||
return LatLon;
|
||
})();
|
||
|
||
exports['default'] = function (a, b, c) {
|
||
if (a instanceof LatLon) {
|
||
return a;
|
||
}
|
||
if (Array.isArray(a) && typeof a[0] !== 'object') {
|
||
if (a.length === 3) {
|
||
return new LatLon(a[0], a[1], a[2]);
|
||
}
|
||
if (a.length === 2) {
|
||
return new LatLon(a[0], a[1]);
|
||
}
|
||
return null;
|
||
}
|
||
if (a === undefined || a === null) {
|
||
return a;
|
||
}
|
||
if (typeof a === 'object' && 'lat' in a) {
|
||
return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);
|
||
}
|
||
if (b === undefined) {
|
||
return null;
|
||
}
|
||
return new LatLon(a, b, c);
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 11 */
|
||
/***/ function(module, exports) {
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
||
/*
|
||
* Point is a helper class for ensuring consistent world positions.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js
|
||
*/
|
||
|
||
var Point = (function () {
|
||
function Point(x, y, round) {
|
||
_classCallCheck(this, Point);
|
||
|
||
this.x = round ? Math.round(x) : x;
|
||
this.y = round ? Math.round(y) : y;
|
||
}
|
||
|
||
// Accepts (point), ([x, y]) and (x, y, round)
|
||
|
||
_createClass(Point, [{
|
||
key: "clone",
|
||
value: function clone() {
|
||
return new Point(this.x, this.y);
|
||
}
|
||
|
||
// Non-destructive
|
||
}, {
|
||
key: "add",
|
||
value: function add(point) {
|
||
return this.clone()._add(_point(point));
|
||
}
|
||
|
||
// Destructive
|
||
}, {
|
||
key: "_add",
|
||
value: function _add(point) {
|
||
this.x += point.x;
|
||
this.y += point.y;
|
||
return this;
|
||
}
|
||
|
||
// Non-destructive
|
||
}, {
|
||
key: "subtract",
|
||
value: function subtract(point) {
|
||
return this.clone()._subtract(_point(point));
|
||
}
|
||
|
||
// Destructive
|
||
}, {
|
||
key: "_subtract",
|
||
value: function _subtract(point) {
|
||
this.x -= point.x;
|
||
this.y -= point.y;
|
||
return this;
|
||
}
|
||
}]);
|
||
|
||
return Point;
|
||
})();
|
||
|
||
var _point = function _point(x, y, round) {
|
||
if (x instanceof Point) {
|
||
return x;
|
||
}
|
||
if (Array.isArray(x)) {
|
||
return new Point(x[0], x[1]);
|
||
}
|
||
if (x === undefined || x === null) {
|
||
return x;
|
||
}
|
||
return new Point(x, y, round);
|
||
};
|
||
|
||
// Initialise without requiring new keyword
|
||
exports["default"] = _point;
|
||
module.exports = exports["default"];
|
||
|
||
/***/ },
|
||
/* 12 */
|
||
/***/ function(module, exports) {
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
/*
|
||
* Wrap the given number to lie within a certain range (eg. longitude)
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js
|
||
*/
|
||
|
||
var wrapNum = function wrapNum(x, range, includeMax) {
|
||
var max = range[1];
|
||
var min = range[0];
|
||
var d = max - min;
|
||
return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
|
||
};
|
||
|
||
exports["default"] = wrapNum;
|
||
module.exports = exports["default"];
|
||
|
||
/***/ },
|
||
/* 13 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* Spherical Mercator is the most popular map projection, used by EPSG:3857 CRS
|
||
* used by default.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.SphericalMercator.js
|
||
*/
|
||
|
||
var _LatLon = __webpack_require__(10);
|
||
|
||
var _LatLon2 = _interopRequireDefault(_LatLon);
|
||
|
||
var _Point = __webpack_require__(11);
|
||
|
||
var _Point2 = _interopRequireDefault(_Point);
|
||
|
||
var SphericalMercator = {
|
||
// Radius / WGS84 semi-major axis
|
||
R: 6378137,
|
||
MAX_LATITUDE: 85.0511287798,
|
||
|
||
// WGS84 eccentricity
|
||
ECC: 0.081819191,
|
||
ECC2: 0.081819191 * 0.081819191,
|
||
|
||
project: function project(latlon) {
|
||
var d = Math.PI / 180;
|
||
var max = this.MAX_LATITUDE;
|
||
var lat = Math.max(Math.min(max, latlon.lat), -max);
|
||
var sin = Math.sin(lat * d);
|
||
|
||
return (0, _Point2['default'])(this.R * latlon.lon * d, this.R * Math.log((1 + sin) / (1 - sin)) / 2);
|
||
},
|
||
|
||
unproject: function unproject(point) {
|
||
var d = 180 / Math.PI;
|
||
|
||
return (0, _LatLon2['default'])((2 * Math.atan(Math.exp(point.y / this.R)) - Math.PI / 2) * d, point.x * d / this.R);
|
||
},
|
||
|
||
// Scale factor for converting between real metres and projected metres
|
||
//
|
||
// projectedMetres = realMetres * pointScale
|
||
// realMetres = projectedMetres / pointScale
|
||
//
|
||
// Accurate scale factor uses proper Web Mercator scaling
|
||
// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf
|
||
// See: http://jsfiddle.net/robhawkes/yws924cf/
|
||
pointScale: function pointScale(latlon, accurate) {
|
||
var rad = Math.PI / 180;
|
||
|
||
var k;
|
||
|
||
if (!accurate) {
|
||
k = 1 / Math.cos(latlon.lat * rad);
|
||
|
||
// [scaleX, scaleY]
|
||
return [k, k];
|
||
} else {
|
||
var lat = latlon.lat * rad;
|
||
var lon = latlon.lon * rad;
|
||
|
||
var a = this.R;
|
||
|
||
var sinLat = Math.sin(lat);
|
||
var sinLat2 = sinLat * sinLat;
|
||
|
||
var cosLat = Math.cos(lat);
|
||
|
||
// Radius meridian
|
||
var p = a * (1 - this.ECC2) / Math.pow(1 - this.ECC2 * sinLat2, 3 / 2);
|
||
|
||
// Radius prime meridian
|
||
var v = a / Math.sqrt(1 - this.ECC2 * sinLat2);
|
||
|
||
// Scale N/S
|
||
var h = a / p / cosLat;
|
||
|
||
// Scale E/W
|
||
k = a / v / cosLat;
|
||
|
||
// [scaleX, scaleY]
|
||
return [k, h];
|
||
}
|
||
},
|
||
|
||
// Not using this.R due to scoping
|
||
bounds: (function () {
|
||
var d = 6378137 * Math.PI;
|
||
return [[-d, -d], [d, d]];
|
||
})()
|
||
};
|
||
|
||
exports['default'] = SphericalMercator;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 14 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
/*
|
||
* Transformation is an utility class to perform simple point transformations
|
||
* through a 2d-matrix.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geometry/Transformation.js
|
||
*/
|
||
|
||
var _geoPoint = __webpack_require__(11);
|
||
|
||
var _geoPoint2 = _interopRequireDefault(_geoPoint);
|
||
|
||
var Transformation = (function () {
|
||
function Transformation(a, b, c, d) {
|
||
_classCallCheck(this, Transformation);
|
||
|
||
this._a = a;
|
||
this._b = b;
|
||
this._c = c;
|
||
this._d = d;
|
||
}
|
||
|
||
_createClass(Transformation, [{
|
||
key: 'transform',
|
||
value: function transform(point, scale) {
|
||
// Copy input point as to not destroy the original data
|
||
return this._transform(point.clone(), scale);
|
||
}
|
||
|
||
// Destructive transform (faster)
|
||
}, {
|
||
key: '_transform',
|
||
value: function _transform(point, scale) {
|
||
scale = scale || 1;
|
||
|
||
point.x = scale * (this._a * point.x + this._b);
|
||
point.y = scale * (this._c * point.y + this._d);
|
||
return point;
|
||
}
|
||
}, {
|
||
key: 'untransform',
|
||
value: function untransform(point, scale) {
|
||
scale = scale || 1;
|
||
return (0, _geoPoint2['default'])((point.x / scale - this._b) / this._a, (point.y / scale - this._d) / this._c);
|
||
}
|
||
}]);
|
||
|
||
return Transformation;
|
||
})();
|
||
|
||
exports['default'] = Transformation;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 15 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* CRS.EPSG3395 (WGS 84 / World Mercator) CRS implementation.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.EPSG3395.js
|
||
*/
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _CRSEarth = __webpack_require__(8);
|
||
|
||
var _CRSEarth2 = _interopRequireDefault(_CRSEarth);
|
||
|
||
var _projectionProjectionMercator = __webpack_require__(16);
|
||
|
||
var _projectionProjectionMercator2 = _interopRequireDefault(_projectionProjectionMercator);
|
||
|
||
var _utilTransformation = __webpack_require__(14);
|
||
|
||
var _utilTransformation2 = _interopRequireDefault(_utilTransformation);
|
||
|
||
var _EPSG3395 = {
|
||
code: 'EPSG:3395',
|
||
projection: _projectionProjectionMercator2['default'],
|
||
|
||
// Work out how to de-dupe this (scoping issue)
|
||
transformScale: 1 / (Math.PI * _projectionProjectionMercator2['default'].R),
|
||
|
||
// Scale and transformation inputs changed to account for central origin in
|
||
// WebGL, instead of top-left origin used in Leaflet
|
||
transformation: (function () {
|
||
// TODO: Cannot use this.transformScale due to scope
|
||
var scale = 1 / (Math.PI * _projectionProjectionMercator2['default'].R);
|
||
|
||
return new _utilTransformation2['default'](scale, 0, -scale, 0);
|
||
})()
|
||
};
|
||
|
||
var EPSG3395 = (0, _lodashAssign2['default'])({}, _CRSEarth2['default'], _EPSG3395);
|
||
|
||
exports['default'] = EPSG3395;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 16 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* Mercator projection that takes into account that the Earth is not a perfect
|
||
* sphere. Less popular than spherical mercator; used by projections like
|
||
* EPSG:3395.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.Mercator.js
|
||
*/
|
||
|
||
var _LatLon = __webpack_require__(10);
|
||
|
||
var _LatLon2 = _interopRequireDefault(_LatLon);
|
||
|
||
var _Point = __webpack_require__(11);
|
||
|
||
var _Point2 = _interopRequireDefault(_Point);
|
||
|
||
var Mercator = {
|
||
// Radius / WGS84 semi-major axis
|
||
R: 6378137,
|
||
R_MINOR: 6356752.314245179,
|
||
|
||
// WGS84 eccentricity
|
||
ECC: 0.081819191,
|
||
ECC2: 0.081819191 * 0.081819191,
|
||
|
||
project: function project(latlon) {
|
||
var d = Math.PI / 180;
|
||
var r = this.R;
|
||
var y = latlon.lat * d;
|
||
var tmp = this.R_MINOR / r;
|
||
var e = Math.sqrt(1 - tmp * tmp);
|
||
var con = e * Math.sin(y);
|
||
|
||
var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);
|
||
y = -r * Math.log(Math.max(ts, 1E-10));
|
||
|
||
return (0, _Point2['default'])(latlon.lon * d * r, y);
|
||
},
|
||
|
||
unproject: function unproject(point) {
|
||
var d = 180 / Math.PI;
|
||
var r = this.R;
|
||
var tmp = this.R_MINOR / r;
|
||
var e = Math.sqrt(1 - tmp * tmp);
|
||
var ts = Math.exp(-point.y / r);
|
||
var phi = Math.PI / 2 - 2 * Math.atan(ts);
|
||
|
||
for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
|
||
con = e * Math.sin(phi);
|
||
con = Math.pow((1 - con) / (1 + con), e / 2);
|
||
dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi;
|
||
phi += dphi;
|
||
}
|
||
|
||
return (0, _LatLon2['default'])(phi * d, point.x * d / r);
|
||
},
|
||
|
||
// Scale factor for converting between real metres and projected metres
|
||
//
|
||
// projectedMetres = realMetres * pointScale
|
||
// realMetres = projectedMetres / pointScale
|
||
//
|
||
// See pg.8: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf
|
||
pointScale: function pointScale(latlon) {
|
||
var rad = Math.PI / 180;
|
||
var lat = latlon.lat * rad;
|
||
var sinLat = Math.sin(lat);
|
||
var sinLat2 = sinLat * sinLat;
|
||
var cosLat = Math.cos(lat);
|
||
|
||
var k = Math.sqrt(1 - this.ECC2 * sinLat2) / cosLat;
|
||
|
||
// [scaleX, scaleY]
|
||
return [k, k];
|
||
},
|
||
|
||
bounds: [[-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]]
|
||
};
|
||
|
||
exports['default'] = Mercator;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 17 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* CRS.EPSG4326 is a CRS popular among advanced GIS specialists.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.EPSG4326.js
|
||
*/
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _CRSEarth = __webpack_require__(8);
|
||
|
||
var _CRSEarth2 = _interopRequireDefault(_CRSEarth);
|
||
|
||
var _projectionProjectionLatLon = __webpack_require__(18);
|
||
|
||
var _projectionProjectionLatLon2 = _interopRequireDefault(_projectionProjectionLatLon);
|
||
|
||
var _utilTransformation = __webpack_require__(14);
|
||
|
||
var _utilTransformation2 = _interopRequireDefault(_utilTransformation);
|
||
|
||
var _EPSG4326 = {
|
||
code: 'EPSG:4326',
|
||
projection: _projectionProjectionLatLon2['default'],
|
||
|
||
// Work out how to de-dupe this (scoping issue)
|
||
transformScale: 1 / 180,
|
||
|
||
// Scale and transformation inputs changed to account for central origin in
|
||
// WebGL, instead of top-left origin used in Leaflet
|
||
//
|
||
// TODO: Cannot use this.transformScale due to scope
|
||
transformation: new _utilTransformation2['default'](1 / 180, 0, -1 / 180, 0)
|
||
};
|
||
|
||
var EPSG4326 = (0, _lodashAssign2['default'])({}, _CRSEarth2['default'], _EPSG4326);
|
||
|
||
exports['default'] = EPSG4326;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 18 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* Simple equirectangular (Plate Carree) projection, used by CRS like EPSG:4326
|
||
* and Simple.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/projection/Projection.LonLat.js
|
||
*/
|
||
|
||
var _LatLon = __webpack_require__(10);
|
||
|
||
var _LatLon2 = _interopRequireDefault(_LatLon);
|
||
|
||
var _Point = __webpack_require__(11);
|
||
|
||
var _Point2 = _interopRequireDefault(_Point);
|
||
|
||
var ProjectionLatLon = {
|
||
project: function project(latlon) {
|
||
return (0, _Point2['default'])(latlon.lon, latlon.lat);
|
||
},
|
||
|
||
unproject: function unproject(point) {
|
||
return (0, _LatLon2['default'])(point.y, point.x);
|
||
},
|
||
|
||
// Scale factor for converting between real metres and degrees
|
||
//
|
||
// degrees = realMetres * pointScale
|
||
// realMetres = degrees / pointScale
|
||
//
|
||
// See: http://stackoverflow.com/questions/639695/how-to-convert-latitude-or-longitude-to-meters
|
||
// See: http://gis.stackexchange.com/questions/75528/length-of-a-degree-where-do-the-terms-in-this-formula-come-from
|
||
pointScale: function pointScale(latlon) {
|
||
var m1 = 111132.92;
|
||
var m2 = -559.82;
|
||
var m3 = 1.175;
|
||
var m4 = -0.0023;
|
||
var p1 = 111412.84;
|
||
var p2 = -93.5;
|
||
var p3 = 0.118;
|
||
|
||
var rad = Math.PI / 180;
|
||
var lat = latlon.lat * rad;
|
||
|
||
var latlen = m1 + m2 * Math.cos(2 * lat) + m3 * Math.cos(4 * lat) + m4 * Math.cos(6 * lat);
|
||
var lonlen = p1 * Math.cos(lat) + p2 * Math.cos(3 * lat) + p3 * Math.cos(5 * lat);
|
||
|
||
return [1 / latlen, 1 / lonlen];
|
||
},
|
||
|
||
bounds: [[-180, -90], [180, 90]]
|
||
};
|
||
|
||
exports['default'] = ProjectionLatLon;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 19 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* A simple CRS that can be used for flat non-Earth maps like panoramas or game
|
||
* maps.
|
||
*
|
||
* Based on:
|
||
* https://github.com/Leaflet/Leaflet/blob/master/src/geo/crs/CRS.Simple.js
|
||
*/
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _CRS = __webpack_require__(9);
|
||
|
||
var _CRS2 = _interopRequireDefault(_CRS);
|
||
|
||
var _projectionProjectionLatLon = __webpack_require__(18);
|
||
|
||
var _projectionProjectionLatLon2 = _interopRequireDefault(_projectionProjectionLatLon);
|
||
|
||
var _utilTransformation = __webpack_require__(14);
|
||
|
||
var _utilTransformation2 = _interopRequireDefault(_utilTransformation);
|
||
|
||
var _Simple = {
|
||
projection: _projectionProjectionLatLon2['default'],
|
||
|
||
// Straight 1:1 mapping (-1, -1 would be top-left)
|
||
transformation: new _utilTransformation2['default'](1, 0, 1, 0),
|
||
|
||
scale: function scale(zoom) {
|
||
// If zoom is provided then return scale based on map tile zoom
|
||
if (zoom) {
|
||
return Math.pow(2, zoom);
|
||
// Else, make no change to scale – may need to increase this or make it a
|
||
// user-definable variable
|
||
} else {
|
||
return 1;
|
||
}
|
||
},
|
||
|
||
zoom: function zoom(scale) {
|
||
return Math.log(scale) / Math.LN2;
|
||
},
|
||
|
||
distance: function distance(latlon1, latlon2) {
|
||
var dx = latlon2.lon - latlon1.lon;
|
||
var dy = latlon2.lat - latlon1.lat;
|
||
|
||
return Math.sqrt(dx * dx + dy * dy);
|
||
},
|
||
|
||
infinite: true
|
||
};
|
||
|
||
var Simple = (0, _lodashAssign2['default'])({}, _CRS2['default'], _Simple);
|
||
|
||
exports['default'] = Simple;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 20 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* CRS.Proj4 for any Proj4-supported CRS.
|
||
*/
|
||
|
||
var _lodashAssign = __webpack_require__(3);
|
||
|
||
var _lodashAssign2 = _interopRequireDefault(_lodashAssign);
|
||
|
||
var _CRSEarth = __webpack_require__(8);
|
||
|
||
var _CRSEarth2 = _interopRequireDefault(_CRSEarth);
|
||
|
||
var _projectionProjectionProj4 = __webpack_require__(21);
|
||
|
||
var _projectionProjectionProj42 = _interopRequireDefault(_projectionProjectionProj4);
|
||
|
||
var _utilTransformation = __webpack_require__(14);
|
||
|
||
var _utilTransformation2 = _interopRequireDefault(_utilTransformation);
|
||
|
||
var _Proj4 = function _Proj4(code, def, bounds) {
|
||
var projection = (0, _projectionProjectionProj42['default'])(def, bounds);
|
||
|
||
// Transformation calcuations
|
||
var diffX = projection.bounds[1][0] - projection.bounds[0][0];
|
||
var diffY = projection.bounds[1][1] - projection.bounds[0][1];
|
||
|
||
var halfX = diffX / 2;
|
||
var halfY = diffY / 2;
|
||
|
||
// This is the raw scale factor
|
||
var scaleX = 1 / halfX;
|
||
var scaleY = 1 / halfY;
|
||
|
||
// Find the minimum scale factor
|
||
//
|
||
// The minimum scale factor comes from the largest side and is the one
|
||
// you want to use for both axis so they stay relative in dimension
|
||
var scale = Math.min(scaleX, scaleY);
|
||
|
||
// Find amount to offset each axis by to make the central point lie on
|
||
// the [0,0] origin
|
||
var offsetX = scale * (projection.bounds[0][0] + halfX);
|
||
var offsetY = scale * (projection.bounds[0][1] + halfY);
|
||
|
||
return {
|
||
code: code,
|
||
projection: projection,
|
||
|
||
transformScale: scale,
|
||
|
||
// Map the input to a [-1,1] range with [0,0] in the centre
|
||
transformation: new _utilTransformation2['default'](scale, -offsetX, -scale, offsetY)
|
||
};
|
||
};
|
||
|
||
var Proj4 = function Proj4(code, def, bounds) {
|
||
return (0, _lodashAssign2['default'])({}, _CRSEarth2['default'], _Proj4(code, def, bounds));
|
||
};
|
||
|
||
exports['default'] = Proj4;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 21 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
/*
|
||
* Proj4 support for any projection.
|
||
*/
|
||
|
||
var _proj4 = __webpack_require__(22);
|
||
|
||
var _proj42 = _interopRequireDefault(_proj4);
|
||
|
||
var _LatLon = __webpack_require__(10);
|
||
|
||
var _LatLon2 = _interopRequireDefault(_LatLon);
|
||
|
||
var _Point = __webpack_require__(11);
|
||
|
||
var _Point2 = _interopRequireDefault(_Point);
|
||
|
||
var Proj4 = function Proj4(def, bounds) {
|
||
var proj = (0, _proj42['default'])(def);
|
||
|
||
var project = function project(latlon) {
|
||
return (0, _Point2['default'])(proj.forward([latlon.lon, latlon.lat]));
|
||
};
|
||
|
||
var unproject = function unproject(point) {
|
||
var inverse = proj.inverse([point.x, point.y]);
|
||
return (0, _LatLon2['default'])(inverse[1], inverse[0]);
|
||
};
|
||
|
||
return {
|
||
project: project,
|
||
unproject: unproject,
|
||
|
||
// Scale factor for converting between real metres and projected metres\
|
||
//
|
||
// Need to work out the best way to provide the pointScale calculations
|
||
// for custom, unknown projections (if wanting to override default)
|
||
//
|
||
// For now, user can manually override crs.pointScale or
|
||
// crs.projection.pointScale
|
||
//
|
||
// projectedMetres = realMetres * pointScale
|
||
// realMetres = projectedMetres / pointScale
|
||
pointScale: function pointScale(latlon, accurate) {
|
||
return [1, 1];
|
||
},
|
||
|
||
// Try and calculate bounds if none are provided
|
||
//
|
||
// This will provide incorrect bounds for some projections, so perhaps make
|
||
// bounds a required input instead
|
||
bounds: (function () {
|
||
if (bounds) {
|
||
return bounds;
|
||
} else {
|
||
var bottomLeft = project([-90, -180]);
|
||
var topRight = project([90, 180]);
|
||
|
||
return [bottomLeft, topRight];
|
||
}
|
||
})()
|
||
};
|
||
};
|
||
|
||
exports['default'] = Proj4;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 22 */
|
||
/***/ function(module, exports) {
|
||
|
||
module.exports = __WEBPACK_EXTERNAL_MODULE_22__;
|
||
|
||
/***/ },
|
||
/* 23 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _eventemitter3 = __webpack_require__(2);
|
||
|
||
var _eventemitter32 = _interopRequireDefault(_eventemitter3);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
var _Scene = __webpack_require__(25);
|
||
|
||
var _Scene2 = _interopRequireDefault(_Scene);
|
||
|
||
var _Renderer = __webpack_require__(26);
|
||
|
||
var _Renderer2 = _interopRequireDefault(_Renderer);
|
||
|
||
var _Camera = __webpack_require__(27);
|
||
|
||
var _Camera2 = _interopRequireDefault(_Camera);
|
||
|
||
var Engine = (function (_EventEmitter) {
|
||
_inherits(Engine, _EventEmitter);
|
||
|
||
function Engine(container) {
|
||
_classCallCheck(this, Engine);
|
||
|
||
console.log('Init Engine');
|
||
|
||
_get(Object.getPrototypeOf(Engine.prototype), 'constructor', this).call(this);
|
||
|
||
this._scene = _Scene2['default'];
|
||
this._renderer = (0, _Renderer2['default'])(container);
|
||
this._camera = (0, _Camera2['default'])(container);
|
||
this.clock = new _three2['default'].Clock();
|
||
|
||
this._frustum = new _three2['default'].Frustum();
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
_createClass(Engine, [{
|
||
key: 'update',
|
||
value: function update(delta) {
|
||
this.emit('preRender');
|
||
this._renderer.render(this._scene, this._camera);
|
||
this.emit('postRender');
|
||
}
|
||
}]);
|
||
|
||
return Engine;
|
||
})(_eventemitter32['default']);
|
||
|
||
exports['default'] = function (container) {
|
||
return new Engine(container);
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 24 */
|
||
/***/ function(module, exports) {
|
||
|
||
module.exports = __WEBPACK_EXTERNAL_MODULE_24__;
|
||
|
||
/***/ },
|
||
/* 25 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
// This can be imported from anywhere and will still reference the same scene,
|
||
// though there is a helper reference in Engine.scene
|
||
|
||
exports['default'] = (function () {
|
||
var scene = new _three2['default'].Scene();
|
||
scene.fog = new _three2['default'].Fog(0xffffff, 1, 15000);
|
||
return scene;
|
||
})();
|
||
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 26 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
var _Scene = __webpack_require__(25);
|
||
|
||
var _Scene2 = _interopRequireDefault(_Scene);
|
||
|
||
// This can only be accessed from Engine.renderer if you want to reference the
|
||
// same scene in multiple places
|
||
|
||
exports['default'] = function (container) {
|
||
var renderer = new _three2['default'].WebGLRenderer({
|
||
antialias: true
|
||
});
|
||
|
||
renderer.setClearColor(_Scene2['default'].fog.color, 1);
|
||
|
||
// Gamma settings make things look nicer
|
||
renderer.gammaInput = true;
|
||
renderer.gammaOutput = true;
|
||
|
||
container.appendChild(renderer.domElement);
|
||
|
||
var updateSize = function updateSize() {
|
||
renderer.setSize(container.clientWidth, container.clientHeight);
|
||
};
|
||
|
||
window.addEventListener('resize', updateSize, false);
|
||
updateSize();
|
||
|
||
return renderer;
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 27 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
// This can only be accessed from Engine.camera if you want to reference the
|
||
// same scene in multiple places
|
||
|
||
// TODO: Ensure that FOV looks natural on all aspect ratios
|
||
// http://stackoverflow.com/q/26655930/997339
|
||
|
||
exports['default'] = function (container) {
|
||
var camera = new _three2['default'].PerspectiveCamera(45, 1, 1, 40000);
|
||
camera.position.y = 400;
|
||
camera.position.z = 400;
|
||
|
||
var updateSize = function updateSize() {
|
||
camera.aspect = container.clientWidth / container.clientHeight;
|
||
camera.updateProjectionMatrix();
|
||
};
|
||
|
||
window.addEventListener('resize', updateSize, false);
|
||
updateSize();
|
||
|
||
return camera;
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 28 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _ControlsOrbit = __webpack_require__(29);
|
||
|
||
var _ControlsOrbit2 = _interopRequireDefault(_ControlsOrbit);
|
||
|
||
var Controls = {
|
||
Orbit: _ControlsOrbit2['default']
|
||
};
|
||
|
||
exports['default'] = Controls;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 29 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _eventemitter3 = __webpack_require__(2);
|
||
|
||
var _eventemitter32 = _interopRequireDefault(_eventemitter3);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
var _vendorOrbitControls = __webpack_require__(30);
|
||
|
||
var _vendorOrbitControls2 = _interopRequireDefault(_vendorOrbitControls);
|
||
|
||
var Orbit = (function (_EventEmitter) {
|
||
_inherits(Orbit, _EventEmitter);
|
||
|
||
function Orbit() {
|
||
_classCallCheck(this, Orbit);
|
||
|
||
_get(Object.getPrototypeOf(Orbit.prototype), 'constructor', this).call(this);
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
// Proxy control events
|
||
//
|
||
// There's currently no distinction between pan, orbit and zoom events
|
||
|
||
_createClass(Orbit, [{
|
||
key: '_initEvents',
|
||
value: function _initEvents() {
|
||
var _this = this;
|
||
|
||
this._controls.addEventListener('start', function (event) {
|
||
_this._world.emit('controlsMoveStart', event.target.target);
|
||
});
|
||
|
||
this._controls.addEventListener('change', function (event) {
|
||
_this._world.emit('controlsMove', event.target.target);
|
||
});
|
||
|
||
this._controls.addEventListener('end', function (event) {
|
||
_this._world.emit('controlsMoveEnd', event.target.target);
|
||
});
|
||
}
|
||
|
||
// Moving the camera along the [x,y,z] axis based on a target position
|
||
}, {
|
||
key: '_panTo',
|
||
value: function _panTo(point, animate) {}
|
||
}, {
|
||
key: '_panBy',
|
||
value: function _panBy(pointDelta, animate) {}
|
||
|
||
// Zooming the camera in and out
|
||
}, {
|
||
key: '_zoomTo',
|
||
value: function _zoomTo(metres, animate) {}
|
||
}, {
|
||
key: '_zoomBy',
|
||
value: function _zoomBy(metresDelta, animate) {}
|
||
|
||
// Force camera to look at something other than the target
|
||
}, {
|
||
key: '_lookAt',
|
||
value: function _lookAt(point, animate) {}
|
||
|
||
// Make camera look at the target
|
||
}, {
|
||
key: '_lookAtTarget',
|
||
value: function _lookAtTarget() {}
|
||
|
||
// Tilt (up and down)
|
||
}, {
|
||
key: '_tiltTo',
|
||
value: function _tiltTo(angle, animate) {}
|
||
}, {
|
||
key: '_tiltBy',
|
||
value: function _tiltBy(angleDelta, animate) {}
|
||
|
||
// Rotate (left and right)
|
||
}, {
|
||
key: '_rotateTo',
|
||
value: function _rotateTo(angle, animate) {}
|
||
}, {
|
||
key: '_rotateBy',
|
||
value: function _rotateBy(angleDelta, animate) {}
|
||
|
||
// Fly to the given point, animating pan and tilt/rotation to final position
|
||
// with nice zoom out and in
|
||
//
|
||
// Calling flyTo a second time before the previous animation has completed
|
||
// will immediately start the new animation from wherever the previous one
|
||
// has got to
|
||
}, {
|
||
key: '_flyTo',
|
||
value: function _flyTo(point, noZoom) {}
|
||
|
||
// Proxy to OrbitControls.update()
|
||
}, {
|
||
key: 'update',
|
||
value: function update() {
|
||
this._controls.update();
|
||
}
|
||
|
||
// Add controls to world instance and store world reference
|
||
}, {
|
||
key: 'addTo',
|
||
value: function addTo(world) {
|
||
world.addControls(this);
|
||
return this;
|
||
}
|
||
|
||
// Internal method called by World.addControls to actually add the controls
|
||
}, {
|
||
key: '_addToWorld',
|
||
value: function _addToWorld(world) {
|
||
this._world = world;
|
||
|
||
// TODO: Override panLeft and panUp methods to prevent panning on Y axis
|
||
// See: http://stackoverflow.com/a/26188674/997339
|
||
this._controls = new _vendorOrbitControls2['default'](world._engine._camera, world._container);
|
||
|
||
// Disable keys for now as no events are fired for them anyway
|
||
this._controls.keys = false;
|
||
|
||
// 89 degrees
|
||
this._controls.maxPolarAngle = 1.5533;
|
||
|
||
// this._controls.enableDamping = true;
|
||
// this._controls.dampingFactor = 0.25;
|
||
|
||
this._initEvents();
|
||
|
||
this.emit('added');
|
||
}
|
||
}]);
|
||
|
||
return Orbit;
|
||
})(_eventemitter32['default']);
|
||
|
||
exports['default'] = function () {
|
||
return new Orbit();
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 30 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
// jscs:disable
|
||
/*eslint eqeqeq:0*/
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
/**
|
||
* @author qiao / https://github.com/qiao
|
||
* @author mrdoob / http://mrdoob.com
|
||
* @author alteredq / http://alteredqualia.com/
|
||
* @author WestLangley / http://github.com/WestLangley
|
||
* @author erich666 / http://erichaines.com
|
||
*/
|
||
|
||
// This set of controls performs orbiting, dollying (zooming), and panning.
|
||
// Unlike TrackballControls, it maintains the "up" direction object.up (+Y by default).
|
||
//
|
||
// Orbit - left mouse / touch: one finger move
|
||
// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish
|
||
// Pan - right mouse, or arrow keys / touch: three finter swipe
|
||
|
||
var OrbitControls = function OrbitControls(object, domElement) {
|
||
|
||
this.object = object;
|
||
|
||
this.domElement = domElement !== undefined ? domElement : document;
|
||
|
||
// Set to false to disable this control
|
||
this.enabled = true;
|
||
|
||
// "target" sets the location of focus, where the object orbits around
|
||
this.target = new _three2['default'].Vector3();
|
||
|
||
// How far you can dolly in and out ( PerspectiveCamera only )
|
||
this.minDistance = 0;
|
||
this.maxDistance = Infinity;
|
||
|
||
// How far you can zoom in and out ( OrthographicCamera only )
|
||
this.minZoom = 0;
|
||
this.maxZoom = Infinity;
|
||
|
||
// How far you can orbit vertically, upper and lower limits.
|
||
// Range is 0 to Math.PI radians.
|
||
this.minPolarAngle = 0; // radians
|
||
this.maxPolarAngle = Math.PI; // radians
|
||
|
||
// How far you can orbit horizontally, upper and lower limits.
|
||
// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].
|
||
this.minAzimuthAngle = -Infinity; // radians
|
||
this.maxAzimuthAngle = Infinity; // radians
|
||
|
||
// Set to true to enable damping (inertia)
|
||
// If damping is enabled, you must call controls.update() in your animation loop
|
||
this.enableDamping = false;
|
||
this.dampingFactor = 0.25;
|
||
|
||
// This option actually enables dollying in and out; left as "zoom" for backwards compatibility.
|
||
// Set to false to disable zooming
|
||
this.enableZoom = true;
|
||
this.zoomSpeed = 1.0;
|
||
|
||
// Set to false to disable rotating
|
||
this.enableRotate = true;
|
||
this.rotateSpeed = 1.0;
|
||
|
||
// Set to false to disable panning
|
||
this.enablePan = true;
|
||
this.keyPanSpeed = 7.0; // pixels moved per arrow key push
|
||
|
||
// Set to true to automatically rotate around the target
|
||
// If auto-rotate is enabled, you must call controls.update() in your animation loop
|
||
this.autoRotate = false;
|
||
this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60
|
||
|
||
// Set to false to disable use of the keys
|
||
this.enableKeys = true;
|
||
|
||
// The four arrow keys
|
||
this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };
|
||
|
||
// Mouse buttons
|
||
this.mouseButtons = { ORBIT: _three2['default'].MOUSE.LEFT, ZOOM: _three2['default'].MOUSE.MIDDLE, PAN: _three2['default'].MOUSE.RIGHT };
|
||
|
||
// for reset
|
||
this.target0 = this.target.clone();
|
||
this.position0 = this.object.position.clone();
|
||
this.zoom0 = this.object.zoom;
|
||
|
||
//
|
||
// public methods
|
||
//
|
||
|
||
this.getPolarAngle = function () {
|
||
|
||
return phi;
|
||
};
|
||
|
||
this.getAzimuthalAngle = function () {
|
||
|
||
return theta;
|
||
};
|
||
|
||
this.reset = function () {
|
||
|
||
scope.target.copy(scope.target0);
|
||
scope.object.position.copy(scope.position0);
|
||
scope.object.zoom = scope.zoom0;
|
||
|
||
scope.object.updateProjectionMatrix();
|
||
scope.dispatchEvent(changeEvent);
|
||
|
||
scope.update();
|
||
|
||
state = STATE.NONE;
|
||
};
|
||
|
||
// this method is exposed, but perhaps it would be better if we can make it private...
|
||
this.update = (function () {
|
||
|
||
var offset = new _three2['default'].Vector3();
|
||
|
||
// so camera.up is the orbit axis
|
||
var quat = new _three2['default'].Quaternion().setFromUnitVectors(object.up, new _three2['default'].Vector3(0, 1, 0));
|
||
var quatInverse = quat.clone().inverse();
|
||
|
||
var lastPosition = new _three2['default'].Vector3();
|
||
var lastQuaternion = new _three2['default'].Quaternion();
|
||
|
||
return function () {
|
||
|
||
var position = scope.object.position;
|
||
|
||
offset.copy(position).sub(scope.target);
|
||
|
||
// rotate offset to "y-axis-is-up" space
|
||
offset.applyQuaternion(quat);
|
||
|
||
// angle from z-axis around y-axis
|
||
|
||
theta = Math.atan2(offset.x, offset.z);
|
||
|
||
// angle from y-axis
|
||
|
||
phi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y);
|
||
|
||
if (scope.autoRotate && state === STATE.NONE) {
|
||
|
||
rotateLeft(getAutoRotationAngle());
|
||
}
|
||
|
||
theta += thetaDelta;
|
||
phi += phiDelta;
|
||
|
||
// restrict theta to be between desired limits
|
||
theta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, theta));
|
||
|
||
// restrict phi to be between desired limits
|
||
phi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, phi));
|
||
|
||
// restrict phi to be betwee EPS and PI-EPS
|
||
phi = Math.max(EPS, Math.min(Math.PI - EPS, phi));
|
||
|
||
var radius = offset.length() * scale;
|
||
|
||
// restrict radius to be between desired limits
|
||
radius = Math.max(scope.minDistance, Math.min(scope.maxDistance, radius));
|
||
|
||
// move target to panned location
|
||
scope.target.add(panOffset);
|
||
|
||
offset.x = radius * Math.sin(phi) * Math.sin(theta);
|
||
offset.y = radius * Math.cos(phi);
|
||
offset.z = radius * Math.sin(phi) * Math.cos(theta);
|
||
|
||
// rotate offset back to "camera-up-vector-is-up" space
|
||
offset.applyQuaternion(quatInverse);
|
||
|
||
position.copy(scope.target).add(offset);
|
||
|
||
scope.object.lookAt(scope.target);
|
||
|
||
if (scope.enableDamping === true) {
|
||
|
||
thetaDelta *= 1 - scope.dampingFactor;
|
||
phiDelta *= 1 - scope.dampingFactor;
|
||
} else {
|
||
|
||
thetaDelta = 0;
|
||
phiDelta = 0;
|
||
}
|
||
|
||
scale = 1;
|
||
panOffset.set(0, 0, 0);
|
||
|
||
// update condition is:
|
||
// min(camera displacement, camera rotation in radians)^2 > EPS
|
||
// using small-angle approximation cos(x/2) = 1 - x^2 / 8
|
||
|
||
if (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {
|
||
|
||
scope.dispatchEvent(changeEvent);
|
||
|
||
lastPosition.copy(scope.object.position);
|
||
lastQuaternion.copy(scope.object.quaternion);
|
||
zoomChanged = false;
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
})();
|
||
|
||
this.dispose = function () {
|
||
|
||
scope.domElement.removeEventListener('contextmenu', onContextMenu, false);
|
||
scope.domElement.removeEventListener('mousedown', onMouseDown, false);
|
||
scope.domElement.removeEventListener('mousewheel', onMouseWheel, false);
|
||
scope.domElement.removeEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox
|
||
|
||
scope.domElement.removeEventListener('touchstart', onTouchStart, false);
|
||
scope.domElement.removeEventListener('touchend', onTouchEnd, false);
|
||
scope.domElement.removeEventListener('touchmove', onTouchMove, false);
|
||
|
||
document.removeEventListener('mousemove', onMouseMove, false);
|
||
document.removeEventListener('mouseup', onMouseUp, false);
|
||
document.removeEventListener('mouseout', onMouseUp, false);
|
||
|
||
window.removeEventListener('keydown', onKeyDown, false);
|
||
|
||
//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?
|
||
};
|
||
|
||
//
|
||
// internals
|
||
//
|
||
|
||
var scope = this;
|
||
|
||
var changeEvent = { type: 'change' };
|
||
var startEvent = { type: 'start' };
|
||
var endEvent = { type: 'end' };
|
||
|
||
var STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };
|
||
|
||
var state = STATE.NONE;
|
||
|
||
var EPS = 0.000001;
|
||
|
||
// current position in spherical coordinates
|
||
var theta;
|
||
var phi;
|
||
|
||
var phiDelta = 0;
|
||
var thetaDelta = 0;
|
||
var scale = 1;
|
||
var panOffset = new _three2['default'].Vector3();
|
||
var zoomChanged = false;
|
||
|
||
var rotateStart = new _three2['default'].Vector2();
|
||
var rotateEnd = new _three2['default'].Vector2();
|
||
var rotateDelta = new _three2['default'].Vector2();
|
||
|
||
var panStart = new _three2['default'].Vector2();
|
||
var panEnd = new _three2['default'].Vector2();
|
||
var panDelta = new _three2['default'].Vector2();
|
||
|
||
var dollyStart = new _three2['default'].Vector2();
|
||
var dollyEnd = new _three2['default'].Vector2();
|
||
var dollyDelta = new _three2['default'].Vector2();
|
||
|
||
function getAutoRotationAngle() {
|
||
|
||
return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;
|
||
}
|
||
|
||
function getZoomScale() {
|
||
|
||
return Math.pow(0.95, scope.zoomSpeed);
|
||
}
|
||
|
||
function rotateLeft(angle) {
|
||
|
||
thetaDelta -= angle;
|
||
}
|
||
|
||
function rotateUp(angle) {
|
||
|
||
phiDelta -= angle;
|
||
}
|
||
|
||
var panLeft = (function () {
|
||
|
||
var v = new _three2['default'].Vector3();
|
||
|
||
// return function panLeft( distance, objectMatrix ) {
|
||
//
|
||
// var te = objectMatrix.elements;
|
||
//
|
||
// // get X column of objectMatrix
|
||
// v.set( te[ 0 ], te[ 1 ], te[ 2 ] );
|
||
//
|
||
// v.multiplyScalar( - distance );
|
||
//
|
||
// panOffset.add( v );
|
||
//
|
||
// };
|
||
|
||
// Fixed panning to x/y plane
|
||
return function panLeft(distance, objectMatrix) {
|
||
var te = objectMatrix.elements;
|
||
// var adjDist = distance / Math.cos(phi);
|
||
|
||
v.set(te[0], 0, te[2]);
|
||
v.multiplyScalar(-distance);
|
||
|
||
panOffset.add(v);
|
||
};
|
||
})();
|
||
|
||
// Fixed panning to x/y plane
|
||
var panUp = (function () {
|
||
|
||
var v = new _three2['default'].Vector3();
|
||
|
||
// return function panUp( distance, objectMatrix ) {
|
||
//
|
||
// var te = objectMatrix.elements;
|
||
//
|
||
// // get Y column of objectMatrix
|
||
// v.set( te[ 4 ], te[ 5 ], te[ 6 ] );
|
||
//
|
||
// v.multiplyScalar( distance );
|
||
//
|
||
// panOffset.add( v );
|
||
//
|
||
// };
|
||
|
||
return function panUp(distance, objectMatrix) {
|
||
var te = objectMatrix.elements;
|
||
var adjDist = distance / Math.cos(phi);
|
||
|
||
v.set(te[4], 0, te[6]);
|
||
v.multiplyScalar(adjDist);
|
||
|
||
panOffset.add(v);
|
||
};
|
||
})();
|
||
|
||
// deltaX and deltaY are in pixels; right and down are positive
|
||
var pan = (function () {
|
||
|
||
var offset = new _three2['default'].Vector3();
|
||
|
||
return function (deltaX, deltaY) {
|
||
|
||
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
||
|
||
if (scope.object instanceof _three2['default'].PerspectiveCamera) {
|
||
|
||
// perspective
|
||
var position = scope.object.position;
|
||
offset.copy(position).sub(scope.target);
|
||
var targetDistance = offset.length();
|
||
|
||
// half of the fov is center to top of screen
|
||
targetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180.0);
|
||
|
||
// we actually don't use screenWidth, since perspective camera is fixed to screen height
|
||
panLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);
|
||
panUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);
|
||
} else if (scope.object instanceof _three2['default'].OrthographicCamera) {
|
||
|
||
// orthographic
|
||
panLeft(deltaX * (scope.object.right - scope.object.left) / element.clientWidth, scope.object.matrix);
|
||
panUp(deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight, scope.object.matrix);
|
||
} else {
|
||
|
||
// camera neither orthographic nor perspective
|
||
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.');
|
||
scope.enablePan = false;
|
||
}
|
||
};
|
||
})();
|
||
|
||
function dollyIn(dollyScale) {
|
||
|
||
if (scope.object instanceof _three2['default'].PerspectiveCamera) {
|
||
|
||
scale /= dollyScale;
|
||
} else if (scope.object instanceof _three2['default'].OrthographicCamera) {
|
||
|
||
scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));
|
||
scope.object.updateProjectionMatrix();
|
||
zoomChanged = true;
|
||
} else {
|
||
|
||
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');
|
||
scope.enableZoom = false;
|
||
}
|
||
}
|
||
|
||
function dollyOut(dollyScale) {
|
||
|
||
if (scope.object instanceof _three2['default'].PerspectiveCamera) {
|
||
|
||
scale *= dollyScale;
|
||
} else if (scope.object instanceof _three2['default'].OrthographicCamera) {
|
||
|
||
scope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));
|
||
scope.object.updateProjectionMatrix();
|
||
zoomChanged = true;
|
||
} else {
|
||
|
||
console.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');
|
||
scope.enableZoom = false;
|
||
}
|
||
}
|
||
|
||
//
|
||
// event callbacks - update the object state
|
||
//
|
||
|
||
function handleMouseDownRotate(event) {
|
||
|
||
//console.log( 'handleMouseDownRotate' );
|
||
|
||
rotateStart.set(event.clientX, event.clientY);
|
||
}
|
||
|
||
function handleMouseDownDolly(event) {
|
||
|
||
//console.log( 'handleMouseDownDolly' );
|
||
|
||
dollyStart.set(event.clientX, event.clientY);
|
||
}
|
||
|
||
function handleMouseDownPan(event) {
|
||
|
||
//console.log( 'handleMouseDownPan' );
|
||
|
||
panStart.set(event.clientX, event.clientY);
|
||
}
|
||
|
||
function handleMouseMoveRotate(event) {
|
||
|
||
//console.log( 'handleMouseMoveRotate' );
|
||
|
||
rotateEnd.set(event.clientX, event.clientY);
|
||
rotateDelta.subVectors(rotateEnd, rotateStart);
|
||
|
||
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
||
|
||
// rotating across whole screen goes 360 degrees around
|
||
rotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);
|
||
|
||
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
||
rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);
|
||
|
||
rotateStart.copy(rotateEnd);
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleMouseMoveDolly(event) {
|
||
|
||
//console.log( 'handleMouseMoveDolly' );
|
||
|
||
dollyEnd.set(event.clientX, event.clientY);
|
||
|
||
dollyDelta.subVectors(dollyEnd, dollyStart);
|
||
|
||
if (dollyDelta.y > 0) {
|
||
|
||
dollyIn(getZoomScale());
|
||
} else if (dollyDelta.y < 0) {
|
||
|
||
dollyOut(getZoomScale());
|
||
}
|
||
|
||
dollyStart.copy(dollyEnd);
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleMouseMovePan(event) {
|
||
|
||
//console.log( 'handleMouseMovePan' );
|
||
|
||
panEnd.set(event.clientX, event.clientY);
|
||
|
||
panDelta.subVectors(panEnd, panStart);
|
||
|
||
pan(panDelta.x, panDelta.y);
|
||
|
||
panStart.copy(panEnd);
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleMouseUp(event) {
|
||
|
||
//console.log( 'handleMouseUp' );
|
||
|
||
}
|
||
|
||
function handleMouseWheel(event) {
|
||
|
||
//console.log( 'handleMouseWheel' );
|
||
|
||
var delta = 0;
|
||
|
||
if (event.wheelDelta !== undefined) {
|
||
|
||
// WebKit / Opera / Explorer 9
|
||
|
||
delta = event.wheelDelta;
|
||
} else if (event.detail !== undefined) {
|
||
|
||
// Firefox
|
||
|
||
delta = -event.detail;
|
||
}
|
||
|
||
if (delta > 0) {
|
||
|
||
dollyOut(getZoomScale());
|
||
} else if (delta < 0) {
|
||
|
||
dollyIn(getZoomScale());
|
||
}
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleKeyDown(event) {
|
||
|
||
//console.log( 'handleKeyDown' );
|
||
|
||
switch (event.keyCode) {
|
||
|
||
case scope.keys.UP:
|
||
pan(0, scope.keyPanSpeed);
|
||
scope.update();
|
||
break;
|
||
|
||
case scope.keys.BOTTOM:
|
||
pan(0, -scope.keyPanSpeed);
|
||
scope.update();
|
||
break;
|
||
|
||
case scope.keys.LEFT:
|
||
pan(scope.keyPanSpeed, 0);
|
||
scope.update();
|
||
break;
|
||
|
||
case scope.keys.RIGHT:
|
||
pan(-scope.keyPanSpeed, 0);
|
||
scope.update();
|
||
break;
|
||
|
||
}
|
||
}
|
||
|
||
function handleTouchStartRotate(event) {
|
||
|
||
//console.log( 'handleTouchStartRotate' );
|
||
|
||
rotateStart.set(event.touches[0].pageX, event.touches[0].pageY);
|
||
}
|
||
|
||
function handleTouchStartDolly(event) {
|
||
|
||
//console.log( 'handleTouchStartDolly' );
|
||
|
||
var dx = event.touches[0].pageX - event.touches[1].pageX;
|
||
var dy = event.touches[0].pageY - event.touches[1].pageY;
|
||
|
||
var distance = Math.sqrt(dx * dx + dy * dy);
|
||
|
||
dollyStart.set(0, distance);
|
||
}
|
||
|
||
function handleTouchStartPan(event) {
|
||
|
||
//console.log( 'handleTouchStartPan' );
|
||
|
||
panStart.set(event.touches[0].pageX, event.touches[0].pageY);
|
||
}
|
||
|
||
function handleTouchMoveRotate(event) {
|
||
|
||
//console.log( 'handleTouchMoveRotate' );
|
||
|
||
rotateEnd.set(event.touches[0].pageX, event.touches[0].pageY);
|
||
rotateDelta.subVectors(rotateEnd, rotateStart);
|
||
|
||
var element = scope.domElement === document ? scope.domElement.body : scope.domElement;
|
||
|
||
// rotating across whole screen goes 360 degrees around
|
||
rotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);
|
||
|
||
// rotating up and down along whole screen attempts to go 360, but limited to 180
|
||
rotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);
|
||
|
||
rotateStart.copy(rotateEnd);
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleTouchMoveDolly(event) {
|
||
|
||
//console.log( 'handleTouchMoveDolly' );
|
||
|
||
var dx = event.touches[0].pageX - event.touches[1].pageX;
|
||
var dy = event.touches[0].pageY - event.touches[1].pageY;
|
||
|
||
var distance = Math.sqrt(dx * dx + dy * dy);
|
||
|
||
dollyEnd.set(0, distance);
|
||
|
||
dollyDelta.subVectors(dollyEnd, dollyStart);
|
||
|
||
if (dollyDelta.y > 0) {
|
||
|
||
dollyOut(getZoomScale());
|
||
} else if (dollyDelta.y < 0) {
|
||
|
||
dollyIn(getZoomScale());
|
||
}
|
||
|
||
dollyStart.copy(dollyEnd);
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleTouchMovePan(event) {
|
||
|
||
//console.log( 'handleTouchMovePan' );
|
||
|
||
panEnd.set(event.touches[0].pageX, event.touches[0].pageY);
|
||
|
||
panDelta.subVectors(panEnd, panStart);
|
||
|
||
pan(panDelta.x, panDelta.y);
|
||
|
||
panStart.copy(panEnd);
|
||
|
||
scope.update();
|
||
}
|
||
|
||
function handleTouchEnd(event) {}
|
||
|
||
//console.log( 'handleTouchEnd' );
|
||
|
||
//
|
||
// event handlers - FSM: listen for events and reset state
|
||
//
|
||
|
||
function onMouseDown(event) {
|
||
|
||
if (scope.enabled === false) return;
|
||
|
||
event.preventDefault();
|
||
|
||
if (event.button === scope.mouseButtons.ORBIT) {
|
||
|
||
if (scope.enableRotate === false) return;
|
||
|
||
handleMouseDownRotate(event);
|
||
|
||
state = STATE.ROTATE;
|
||
} else if (event.button === scope.mouseButtons.ZOOM) {
|
||
|
||
if (scope.enableZoom === false) return;
|
||
|
||
handleMouseDownDolly(event);
|
||
|
||
state = STATE.DOLLY;
|
||
} else if (event.button === scope.mouseButtons.PAN) {
|
||
|
||
if (scope.enablePan === false) return;
|
||
|
||
handleMouseDownPan(event);
|
||
|
||
state = STATE.PAN;
|
||
}
|
||
|
||
if (state !== STATE.NONE) {
|
||
|
||
document.addEventListener('mousemove', onMouseMove, false);
|
||
document.addEventListener('mouseup', onMouseUp, false);
|
||
document.addEventListener('mouseout', onMouseUp, false);
|
||
|
||
scope.dispatchEvent(startEvent);
|
||
}
|
||
}
|
||
|
||
function onMouseMove(event) {
|
||
|
||
if (scope.enabled === false) return;
|
||
|
||
event.preventDefault();
|
||
|
||
if (state === STATE.ROTATE) {
|
||
|
||
if (scope.enableRotate === false) return;
|
||
|
||
handleMouseMoveRotate(event);
|
||
} else if (state === STATE.DOLLY) {
|
||
|
||
if (scope.enableZoom === false) return;
|
||
|
||
handleMouseMoveDolly(event);
|
||
} else if (state === STATE.PAN) {
|
||
|
||
if (scope.enablePan === false) return;
|
||
|
||
handleMouseMovePan(event);
|
||
}
|
||
}
|
||
|
||
function onMouseUp(event) {
|
||
|
||
if (scope.enabled === false) return;
|
||
|
||
handleMouseUp(event);
|
||
|
||
document.removeEventListener('mousemove', onMouseMove, false);
|
||
document.removeEventListener('mouseup', onMouseUp, false);
|
||
document.removeEventListener('mouseout', onMouseUp, false);
|
||
|
||
scope.dispatchEvent(endEvent);
|
||
|
||
state = STATE.NONE;
|
||
}
|
||
|
||
function onMouseWheel(event) {
|
||
|
||
if (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;
|
||
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
|
||
handleMouseWheel(event);
|
||
|
||
scope.dispatchEvent(startEvent); // not sure why these are here...
|
||
scope.dispatchEvent(endEvent);
|
||
}
|
||
|
||
function onKeyDown(event) {
|
||
|
||
if (scope.enabled === false || scope.enableKeys === false || scope.enablePan === false) return;
|
||
|
||
handleKeyDown(event);
|
||
}
|
||
|
||
function onTouchStart(event) {
|
||
|
||
if (scope.enabled === false) return;
|
||
|
||
switch (event.touches.length) {
|
||
|
||
case 1:
|
||
// one-fingered touch: rotate
|
||
|
||
if (scope.enableRotate === false) return;
|
||
|
||
handleTouchStartRotate(event);
|
||
|
||
state = STATE.TOUCH_ROTATE;
|
||
|
||
break;
|
||
|
||
case 2:
|
||
// two-fingered touch: dolly
|
||
|
||
if (scope.enableZoom === false) return;
|
||
|
||
handleTouchStartDolly(event);
|
||
|
||
state = STATE.TOUCH_DOLLY;
|
||
|
||
break;
|
||
|
||
case 3:
|
||
// three-fingered touch: pan
|
||
|
||
if (scope.enablePan === false) return;
|
||
|
||
handleTouchStartPan(event);
|
||
|
||
state = STATE.TOUCH_PAN;
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
state = STATE.NONE;
|
||
|
||
}
|
||
|
||
if (state !== STATE.NONE) {
|
||
|
||
scope.dispatchEvent(startEvent);
|
||
}
|
||
}
|
||
|
||
function onTouchMove(event) {
|
||
|
||
if (scope.enabled === false) return;
|
||
|
||
event.preventDefault();
|
||
event.stopPropagation();
|
||
|
||
switch (event.touches.length) {
|
||
|
||
case 1:
|
||
// one-fingered touch: rotate
|
||
|
||
if (scope.enableRotate === false) return;
|
||
if (state !== STATE.TOUCH_ROTATE) return; // is this needed?...
|
||
|
||
handleTouchMoveRotate(event);
|
||
|
||
break;
|
||
|
||
case 2:
|
||
// two-fingered touch: dolly
|
||
|
||
if (scope.enableZoom === false) return;
|
||
if (state !== STATE.TOUCH_DOLLY) return; // is this needed?...
|
||
|
||
handleTouchMoveDolly(event);
|
||
|
||
break;
|
||
|
||
case 3:
|
||
// three-fingered touch: pan
|
||
|
||
if (scope.enablePan === false) return;
|
||
if (state !== STATE.TOUCH_PAN) return; // is this needed?...
|
||
|
||
handleTouchMovePan(event);
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
state = STATE.NONE;
|
||
|
||
}
|
||
}
|
||
|
||
function onTouchEnd(event) {
|
||
|
||
if (scope.enabled === false) return;
|
||
|
||
handleTouchEnd(event);
|
||
|
||
scope.dispatchEvent(endEvent);
|
||
|
||
state = STATE.NONE;
|
||
}
|
||
|
||
function onContextMenu(event) {
|
||
|
||
event.preventDefault();
|
||
}
|
||
|
||
//
|
||
|
||
scope.domElement.addEventListener('contextmenu', onContextMenu, false);
|
||
|
||
scope.domElement.addEventListener('mousedown', onMouseDown, false);
|
||
scope.domElement.addEventListener('mousewheel', onMouseWheel, false);
|
||
scope.domElement.addEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox
|
||
|
||
scope.domElement.addEventListener('touchstart', onTouchStart, false);
|
||
scope.domElement.addEventListener('touchend', onTouchEnd, false);
|
||
scope.domElement.addEventListener('touchmove', onTouchMove, false);
|
||
|
||
window.addEventListener('keydown', onKeyDown, false);
|
||
|
||
// force an update at start
|
||
|
||
this.update();
|
||
};
|
||
|
||
OrbitControls.prototype = Object.create(_three2['default'].EventDispatcher.prototype);
|
||
OrbitControls.prototype.constructor = _three2['default'].OrbitControls;
|
||
|
||
Object.defineProperties(OrbitControls.prototype, {
|
||
|
||
center: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .center has been renamed to .target');
|
||
return this.target;
|
||
}
|
||
|
||
},
|
||
|
||
// backward compatibility
|
||
|
||
noZoom: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');
|
||
return !this.enableZoom;
|
||
},
|
||
|
||
set: function set(value) {
|
||
|
||
console.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');
|
||
this.enableZoom = !value;
|
||
}
|
||
|
||
},
|
||
|
||
noRotate: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');
|
||
return !this.enableRotate;
|
||
},
|
||
|
||
set: function set(value) {
|
||
|
||
console.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');
|
||
this.enableRotate = !value;
|
||
}
|
||
|
||
},
|
||
|
||
noPan: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');
|
||
return !this.enablePan;
|
||
},
|
||
|
||
set: function set(value) {
|
||
|
||
console.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');
|
||
this.enablePan = !value;
|
||
}
|
||
|
||
},
|
||
|
||
noKeys: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');
|
||
return !this.enableKeys;
|
||
},
|
||
|
||
set: function set(value) {
|
||
|
||
console.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');
|
||
this.enableKeys = !value;
|
||
}
|
||
|
||
},
|
||
|
||
staticMoving: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');
|
||
return !this.constraint.enableDamping;
|
||
},
|
||
|
||
set: function set(value) {
|
||
|
||
console.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');
|
||
this.constraint.enableDamping = !value;
|
||
}
|
||
|
||
},
|
||
|
||
dynamicDampingFactor: {
|
||
|
||
get: function get() {
|
||
|
||
console.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');
|
||
return this.constraint.dampingFactor;
|
||
},
|
||
|
||
set: function set(value) {
|
||
|
||
console.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');
|
||
this.constraint.dampingFactor = value;
|
||
}
|
||
|
||
}
|
||
|
||
});
|
||
|
||
exports['default'] = OrbitControls;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 31 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _Layer2 = __webpack_require__(32);
|
||
|
||
var _Layer3 = _interopRequireDefault(_Layer2);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
var EnvironmentLayer = (function (_Layer) {
|
||
_inherits(EnvironmentLayer, _Layer);
|
||
|
||
function EnvironmentLayer() {
|
||
_classCallCheck(this, EnvironmentLayer);
|
||
|
||
_get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'constructor', this).call(this);
|
||
|
||
this._initLights();
|
||
// this._initGrid();
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
_createClass(EnvironmentLayer, [{
|
||
key: '_onAdd',
|
||
value: function _onAdd() {}
|
||
|
||
// Not fleshed out or thought through yet
|
||
//
|
||
// Lights could potentially be put it their own 'layer' to keep this class
|
||
// much simpler and less messy
|
||
}, {
|
||
key: '_initLights',
|
||
value: function _initLights() {
|
||
// Position doesn't really matter (the angle is important), however it's
|
||
// used here so the helpers look more natural.
|
||
|
||
var directionalLight = new _three2['default'].DirectionalLight(0x999999);
|
||
directionalLight.intesity = 0.1;
|
||
directionalLight.position.x = 100;
|
||
directionalLight.position.y = 100;
|
||
directionalLight.position.z = 100;
|
||
|
||
var directionalLight2 = new _three2['default'].DirectionalLight(0x999999);
|
||
directionalLight2.intesity = 0.1;
|
||
directionalLight2.position.x = -100;
|
||
directionalLight2.position.y = 100;
|
||
directionalLight2.position.z = -100;
|
||
|
||
var helper = new _three2['default'].DirectionalLightHelper(directionalLight, 10);
|
||
var helper2 = new _three2['default'].DirectionalLightHelper(directionalLight2, 10);
|
||
|
||
this._layer.add(directionalLight);
|
||
this._layer.add(directionalLight2);
|
||
|
||
this._layer.add(helper);
|
||
this._layer.add(helper2);
|
||
}
|
||
|
||
// Add grid helper for context during initial development
|
||
}, {
|
||
key: '_initGrid',
|
||
value: function _initGrid() {
|
||
var size = 4000;
|
||
var step = 100;
|
||
|
||
var gridHelper = new _three2['default'].GridHelper(size, step);
|
||
this._layer.add(gridHelper);
|
||
}
|
||
}]);
|
||
|
||
return EnvironmentLayer;
|
||
})(_Layer3['default']);
|
||
|
||
exports['default'] = function () {
|
||
return new EnvironmentLayer();
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 32 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _eventemitter3 = __webpack_require__(2);
|
||
|
||
var _eventemitter32 = _interopRequireDefault(_eventemitter3);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
var _engineScene = __webpack_require__(25);
|
||
|
||
var _engineScene2 = _interopRequireDefault(_engineScene);
|
||
|
||
var Layer = (function (_EventEmitter) {
|
||
_inherits(Layer, _EventEmitter);
|
||
|
||
function Layer() {
|
||
_classCallCheck(this, Layer);
|
||
|
||
_get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this);
|
||
|
||
this._layer = new _three2['default'].Object3D();
|
||
}
|
||
|
||
// Add layer to world instance and store world reference
|
||
|
||
_createClass(Layer, [{
|
||
key: 'addTo',
|
||
value: function addTo(world) {
|
||
world.addLayer(this);
|
||
return this;
|
||
}
|
||
|
||
// Internal method called by World.addLayer to actually add the layer
|
||
}, {
|
||
key: '_addToWorld',
|
||
value: function _addToWorld(world) {
|
||
this._world = world;
|
||
this._onAdd(world);
|
||
this.emit('added');
|
||
}
|
||
|
||
// Destroys the layer and removes it from the scene and memory
|
||
}, {
|
||
key: 'destroy',
|
||
value: function destroy() {
|
||
this._world = null;
|
||
this._layer = null;
|
||
}
|
||
}]);
|
||
|
||
return Layer;
|
||
})(_eventemitter32['default']);
|
||
|
||
exports['default'] = Layer;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 33 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _TileLayer2 = __webpack_require__(34);
|
||
|
||
var _TileLayer3 = _interopRequireDefault(_TileLayer2);
|
||
|
||
var _ImageTile = __webpack_require__(44);
|
||
|
||
var _ImageTile2 = _interopRequireDefault(_ImageTile);
|
||
|
||
var _ImageTileLayerBaseMaterial = __webpack_require__(47);
|
||
|
||
var _ImageTileLayerBaseMaterial2 = _interopRequireDefault(_ImageTileLayerBaseMaterial);
|
||
|
||
var _lodashThrottle = __webpack_require__(48);
|
||
|
||
var _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
// DONE: Find a way to avoid the flashing caused by the gap between old tiles
|
||
// being removed and the new tiles being ready for display
|
||
//
|
||
// DONE: Simplest first step for MVP would be to give each tile mesh the colour
|
||
// of the basemap ground so it blends in a little more, or have a huge ground
|
||
// plane underneath all the tiles that shows through between tile updates.
|
||
//
|
||
// Could keep the old tiles around until the new ones are ready, though they'd
|
||
// probably need to be layered in a way so the old tiles don't overlap new ones,
|
||
// which is similar to how Leaflet approaches this (it has 2 layers)
|
||
//
|
||
// Could keep the tile from the previous quadtree level visible until all 4
|
||
// tiles at the new / current level have finished loading and are displayed.
|
||
// Perhaps by keeping a map of tiles by quadcode and a boolean for each of the
|
||
// child quadcodes showing whether they are loaded and in view. If all true then
|
||
// remove the parent tile, otherwise keep it on a lower layer.
|
||
|
||
// TODO: Load and display a base layer separate to the LOD grid that is at a low
|
||
// resolution – used as a backup / background to fill in empty areas / distance
|
||
|
||
// DONE: Fix the issue where some tiles just don't load, or at least the texture
|
||
// never shows up – tends to happen if you quickly zoom in / out past it while
|
||
// it's still loading, leaving a blank space
|
||
|
||
// TODO: Optimise the request of many image tiles – look at how Leaflet and
|
||
// OpenWebGlobe approach this (eg. batching, queues, etc)
|
||
|
||
// TODO: Cancel pending tile requests if they get removed from view before they
|
||
// reach a ready state (eg. cancel image requests, etc). Need to ensure that the
|
||
// images are re-requested when the tile is next in scene (even if from cache)
|
||
|
||
var ImageTileLayer = (function (_TileLayer) {
|
||
_inherits(ImageTileLayer, _TileLayer);
|
||
|
||
function ImageTileLayer(path, options) {
|
||
_classCallCheck(this, ImageTileLayer);
|
||
|
||
// Cache 1000 tiles
|
||
_get(Object.getPrototypeOf(ImageTileLayer.prototype), 'constructor', this).call(this, 1000);
|
||
|
||
this._path = path;
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
_createClass(ImageTileLayer, [{
|
||
key: '_onAdd',
|
||
value: function _onAdd(world) {
|
||
var _this = this;
|
||
|
||
_get(Object.getPrototypeOf(ImageTileLayer.prototype), '_onAdd', this).call(this, world);
|
||
|
||
this._initEvents();
|
||
|
||
// Add base layer
|
||
var geom = new _three2['default'].PlaneBufferGeometry(40000, 40000, 1);
|
||
var mesh = new _three2['default'].Mesh(geom, (0, _ImageTileLayerBaseMaterial2['default'])('#f5f5f3'));
|
||
mesh.rotation.x = -90 * Math.PI / 180;
|
||
|
||
this._baseLayer = mesh;
|
||
this._layer.add(mesh);
|
||
|
||
// Trigger initial quadtree calculation on the next frame
|
||
//
|
||
// TODO: This is a hack to ensure the camera is all set up - a better
|
||
// solution should be found
|
||
setTimeout(function () {
|
||
_this._calculateLOD();
|
||
}, 0);
|
||
}
|
||
}, {
|
||
key: '_initEvents',
|
||
value: function _initEvents() {
|
||
// Run LOD calculations based on render calls
|
||
//
|
||
// Throttled to 1 LOD calculation per 100ms
|
||
this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._onWorldUpdate, 100);
|
||
|
||
this._world.on('preUpdate', this._throttledWorldUpdate, this);
|
||
this._world.on('move', this._onWorldMove, this);
|
||
}
|
||
}, {
|
||
key: '_onWorldUpdate',
|
||
value: function _onWorldUpdate() {
|
||
this._calculateLOD();
|
||
}
|
||
}, {
|
||
key: '_onWorldMove',
|
||
value: function _onWorldMove(latlon, point) {
|
||
this._moveBaseLayer(point);
|
||
}
|
||
}, {
|
||
key: '_moveBaseLayer',
|
||
value: function _moveBaseLayer(point) {
|
||
this._baseLayer.position.x = point.x;
|
||
this._baseLayer.position.z = point.y;
|
||
}
|
||
}, {
|
||
key: '_createTile',
|
||
value: function _createTile(quadcode, layer) {
|
||
return (0, _ImageTile2['default'])(quadcode, this._path, layer);
|
||
}
|
||
|
||
// Destroys the layer and removes it from the scene and memory
|
||
}, {
|
||
key: 'destroy',
|
||
value: function destroy() {
|
||
this._world.off('preUpdate', this._throttledWorldUpdate);
|
||
this._world.off('move', this._onWorldMove);
|
||
|
||
this._throttledWorldUpdate = null;
|
||
|
||
// Dispose of mesh and materials
|
||
this._baseLayer.geometry.dispose();
|
||
this._baseLayer.geometry = null;
|
||
|
||
if (this._baseLayer.material.map) {
|
||
this._baseLayer.material.map.dispose();
|
||
this._baseLayer.material.map = null;
|
||
}
|
||
|
||
this._baseLayer.material.dispose();
|
||
this._baseLayer.material = null;
|
||
|
||
this._baseLayer = null;
|
||
|
||
// Run common destruction logic from parent
|
||
_get(Object.getPrototypeOf(ImageTileLayer.prototype), 'destroy', this).call(this);
|
||
}
|
||
}]);
|
||
|
||
return ImageTileLayer;
|
||
})(_TileLayer3['default']);
|
||
|
||
exports['default'] = function (path, options) {
|
||
return new ImageTileLayer(path, options);
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 34 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _Layer2 = __webpack_require__(32);
|
||
|
||
var _Layer3 = _interopRequireDefault(_Layer2);
|
||
|
||
var _TileCache = __webpack_require__(35);
|
||
|
||
var _TileCache2 = _interopRequireDefault(_TileCache);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
// DONE: Prevent tiles from being loaded if they are further than a certain
|
||
// distance from the camera and are unlikely to be seen anyway
|
||
|
||
// TODO: Avoid performing LOD calculation when it isn't required. For example,
|
||
// when nothing has changed since the last frame and there are no tiles to be
|
||
// loaded or in need of rendering
|
||
|
||
// TODO: Only remove tiles from the layer that aren't to be rendered in the
|
||
// current frame – it seems excessive to remove all tiles and re-add them on
|
||
// every single frame, even if it's just array manipulation
|
||
|
||
// TODO: Fix LOD calculation so min and max LOD can be changed without causing
|
||
// problems (eg. making min above 5 causes all sorts of issues)
|
||
|
||
// TODO: Reuse THREE objects where possible instead of creating new instances
|
||
// on every LOD calculation
|
||
|
||
// TODO: Consider not using THREE or LatLon / Point objects in LOD calculations
|
||
// to avoid creating unnecessary memory for garbage collection
|
||
|
||
// TODO: Prioritise loading of tiles at highest level in the quadtree (those
|
||
// closest to the camera) so visual inconsistancies during loading are minimised
|
||
|
||
var TileLayer = (function (_Layer) {
|
||
_inherits(TileLayer, _Layer);
|
||
|
||
function TileLayer(maxCache) {
|
||
var _this = this;
|
||
|
||
_classCallCheck(this, TileLayer);
|
||
|
||
_get(Object.getPrototypeOf(TileLayer.prototype), 'constructor', this).call(this);
|
||
|
||
this._tileCache = (0, _TileCache2['default'])(maxCache, function (tile) {
|
||
_this._destroyTile(tile);
|
||
});
|
||
|
||
// TODO: Work out why changing the minLOD causes loads of issues
|
||
this._minLOD = 3;
|
||
this._maxLOD = 18;
|
||
|
||
this._frustum = new _three2['default'].Frustum();
|
||
this._tiles = new _three2['default'].Object3D();
|
||
}
|
||
|
||
_createClass(TileLayer, [{
|
||
key: '_onAdd',
|
||
value: function _onAdd(world) {
|
||
this._layer.add(this._tiles);
|
||
}
|
||
}, {
|
||
key: '_updateFrustum',
|
||
value: function _updateFrustum() {
|
||
var camera = this._world.getCamera();
|
||
var projScreenMatrix = new _three2['default'].Matrix4();
|
||
projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
|
||
|
||
this._frustum.setFromMatrix(camera.projectionMatrix);
|
||
this._frustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));
|
||
}
|
||
}, {
|
||
key: '_tileInFrustum',
|
||
value: function _tileInFrustum(tile) {
|
||
var bounds = tile.getBounds();
|
||
return this._frustum.intersectsBox(new _three2['default'].Box3(new _three2['default'].Vector3(bounds[0], 0, bounds[3]), new _three2['default'].Vector3(bounds[2], 0, bounds[1])));
|
||
}
|
||
}, {
|
||
key: '_calculateLOD',
|
||
value: function _calculateLOD() {
|
||
var _this2 = this;
|
||
|
||
if (this._stop || !this._world) {
|
||
return;
|
||
}
|
||
|
||
// var start = performance.now();
|
||
|
||
var camera = this._world.getCamera();
|
||
|
||
// 1. Update and retrieve camera frustum
|
||
this._updateFrustum(this._frustum, camera);
|
||
|
||
// 2. Add the four root items of the quadtree to a check list
|
||
var checkList = this._checklist;
|
||
checkList = [];
|
||
checkList.push(this._requestTile('0', this));
|
||
checkList.push(this._requestTile('1', this));
|
||
checkList.push(this._requestTile('2', this));
|
||
checkList.push(this._requestTile('3', this));
|
||
|
||
// 3. Call Divide, passing in the check list
|
||
this._divide(checkList);
|
||
|
||
// 4. Remove all tiles from layer
|
||
this._removeTiles();
|
||
|
||
// 5. Render the tiles remaining in the check list
|
||
checkList.forEach(function (tile, index) {
|
||
// Skip tile if it's not in the current view frustum
|
||
if (!_this2._tileInFrustum(tile)) {
|
||
return;
|
||
}
|
||
|
||
// // TODO: Can probably speed this up
|
||
// var center = tile.getCenter();
|
||
// var dist = (new THREE.Vector3(center[0], 0, center[1])).sub(camera.position).length();
|
||
|
||
// Manual distance limit to cut down on tiles so far away
|
||
// if (dist > 8000) {
|
||
// return;
|
||
// }
|
||
|
||
// Does the tile have a mesh?
|
||
//
|
||
// If yes, continue
|
||
// If no, generate tile mesh, request texture and skip
|
||
if (!tile.getMesh()) {
|
||
tile.requestTileAsync();
|
||
return;
|
||
}
|
||
|
||
// Are the mesh and texture ready?
|
||
//
|
||
// If yes, continue
|
||
// If no, skip
|
||
if (!tile.isReady()) {
|
||
return;
|
||
}
|
||
|
||
// Add tile to layer (and to scene)
|
||
_this2._tiles.add(tile.getMesh());
|
||
});
|
||
|
||
// console.log(performance.now() - start);
|
||
}
|
||
}, {
|
||
key: '_divide',
|
||
value: function _divide(checkList) {
|
||
var count = 0;
|
||
var currentItem;
|
||
var quadcode;
|
||
|
||
// 1. Loop until count equals check list length
|
||
while (count != checkList.length) {
|
||
currentItem = checkList[count];
|
||
quadcode = currentItem.getQuadcode();
|
||
|
||
// 2. Increase count and continue loop if quadcode equals max LOD / zoom
|
||
if (currentItem.length === this._maxLOD) {
|
||
count++;
|
||
continue;
|
||
}
|
||
|
||
// 3. Else, calculate screen-space error metric for quadcode
|
||
if (this._screenSpaceError(currentItem)) {
|
||
// 4. If error is sufficient...
|
||
|
||
// 4a. Remove parent item from the check list
|
||
checkList.splice(count, 1);
|
||
|
||
// 4b. Add 4 child items to the check list
|
||
checkList.push(this._requestTile(quadcode + '0', this));
|
||
checkList.push(this._requestTile(quadcode + '1', this));
|
||
checkList.push(this._requestTile(quadcode + '2', this));
|
||
checkList.push(this._requestTile(quadcode + '3', this));
|
||
|
||
// 4d. Continue the loop without increasing count
|
||
continue;
|
||
} else {
|
||
// 5. Else, increase count and continue loop
|
||
count++;
|
||
}
|
||
}
|
||
}
|
||
}, {
|
||
key: '_screenSpaceError',
|
||
value: function _screenSpaceError(tile) {
|
||
var minDepth = this._minLOD;
|
||
var maxDepth = this._maxLOD;
|
||
|
||
var quadcode = tile.getQuadcode();
|
||
|
||
var camera = this._world.getCamera();
|
||
|
||
// Tweak this value to refine specific point that each quad is subdivided
|
||
//
|
||
// It's used to multiple the dimensions of the tile sides before
|
||
// comparing against the tile distance from camera
|
||
var quality = 3.0;
|
||
|
||
// 1. Return false if quadcode length is greater than maxDepth
|
||
if (quadcode.length > maxDepth) {
|
||
return false;
|
||
}
|
||
|
||
// 2. Return true if quadcode length is less than minDepth
|
||
if (quadcode.length < minDepth) {
|
||
return true;
|
||
}
|
||
|
||
// 3. Return false if quadcode bounds are not in view frustum
|
||
if (!this._tileInFrustum(tile)) {
|
||
return false;
|
||
}
|
||
|
||
var center = tile.getCenter();
|
||
|
||
// 4. Calculate screen-space error metric
|
||
// TODO: Use closest distance to one of the 4 tile corners
|
||
var dist = new _three2['default'].Vector3(center[0], 0, center[1]).sub(camera.position).length();
|
||
|
||
var error = quality * tile.getSide() / dist;
|
||
|
||
// 5. Return true if error is greater than 1.0, else return false
|
||
return error > 1.0;
|
||
}
|
||
}, {
|
||
key: '_removeTiles',
|
||
value: function _removeTiles() {
|
||
for (var i = this._tiles.children.length - 1; i >= 0; i--) {
|
||
this._tiles.remove(this._tiles.children[i]);
|
||
}
|
||
}
|
||
|
||
// Return a new tile instance
|
||
}, {
|
||
key: '_createTile',
|
||
value: function _createTile(quadcode, layer) {}
|
||
|
||
// Get a cached tile or request a new one if not in cache
|
||
}, {
|
||
key: '_requestTile',
|
||
value: function _requestTile(quadcode, layer) {
|
||
var tile = this._tileCache.getTile(quadcode);
|
||
|
||
if (!tile) {
|
||
// Set up a brand new tile
|
||
tile = this._createTile(quadcode, layer);
|
||
|
||
// Add tile to cache, though it won't be ready yet as the data is being
|
||
// requested from various places asynchronously
|
||
this._tileCache.setTile(quadcode, tile);
|
||
}
|
||
|
||
return tile;
|
||
}
|
||
}, {
|
||
key: '_destroyTile',
|
||
value: function _destroyTile(tile) {
|
||
// Remove tile from scene
|
||
this._layer.remove(tile);
|
||
|
||
// Delete any references to the tile within this component
|
||
|
||
// Call destory on tile instance
|
||
tile.destroy();
|
||
}
|
||
|
||
// Destroys the layer and removes it from the scene and memory
|
||
}, {
|
||
key: 'destroy',
|
||
value: function destroy() {
|
||
var i;
|
||
|
||
// Remove all tiles
|
||
for (i = this._tiles.children.length - 1; i >= 0; i--) {
|
||
this._tiles.remove(this._tiles.children[i]);
|
||
}
|
||
|
||
// Remove everything else in the layer
|
||
for (i = this._layer.children.length - 1; i >= 0; i--) {
|
||
this._layer.remove(this._layer.children[i]);
|
||
}
|
||
|
||
this._tileCache.destroy();
|
||
this._tileCache = null;
|
||
|
||
this._world = null;
|
||
this._tiles = null;
|
||
this._layer = null;
|
||
this._frustum = null;
|
||
}
|
||
}]);
|
||
|
||
return TileLayer;
|
||
})(_Layer3['default']);
|
||
|
||
exports['default'] = TileLayer;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 35 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
var _lruCache = __webpack_require__(36);
|
||
|
||
var _lruCache2 = _interopRequireDefault(_lruCache);
|
||
|
||
// This process is based on a similar approach taken by OpenWebGlobe
|
||
// See: https://github.com/OpenWebGlobe/WebViewer/blob/master/source/core/globecache.js
|
||
|
||
var TileCache = (function () {
|
||
function TileCache(cacheLimit, onDestroyTile) {
|
||
_classCallCheck(this, TileCache);
|
||
|
||
this._cache = (0, _lruCache2['default'])({
|
||
max: cacheLimit,
|
||
dispose: function dispose(key, tile) {
|
||
onDestroyTile(tile);
|
||
}
|
||
});
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
// Returns true if all specified tile providers are ready to be used
|
||
// Otherwise, returns false
|
||
|
||
_createClass(TileCache, [{
|
||
key: 'isReady',
|
||
value: function isReady() {
|
||
return false;
|
||
}
|
||
|
||
// Get a cached tile without requesting a new one
|
||
}, {
|
||
key: 'getTile',
|
||
value: function getTile(quadcode) {
|
||
return this._cache.get(quadcode);
|
||
}
|
||
|
||
// Add tile to cache
|
||
}, {
|
||
key: 'setTile',
|
||
value: function setTile(quadcode, tile) {
|
||
this._cache.set(quadcode, tile);
|
||
}
|
||
|
||
// Destroy the cache and remove it from memory
|
||
//
|
||
// TODO: Call destroy method on items in cache
|
||
}, {
|
||
key: 'destroy',
|
||
value: function destroy() {
|
||
this._cache.reset();
|
||
this._cache = null;
|
||
}
|
||
}]);
|
||
|
||
return TileCache;
|
||
})();
|
||
|
||
exports['default'] = function (cacheLimit, onDestroyTile) {
|
||
return new TileCache(cacheLimit, onDestroyTile);
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 36 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
module.exports = LRUCache
|
||
|
||
// This will be a proper iterable 'Map' in engines that support it,
|
||
// or a fakey-fake PseudoMap in older versions.
|
||
var Map = __webpack_require__(37)
|
||
var util = __webpack_require__(40)
|
||
|
||
// A linked list to keep track of recently-used-ness
|
||
var Yallist = __webpack_require__(43)
|
||
|
||
// use symbols if possible, otherwise just _props
|
||
var symbols = {}
|
||
var hasSymbol = typeof Symbol === 'function'
|
||
var makeSymbol
|
||
if (hasSymbol) {
|
||
makeSymbol = function (key) {
|
||
return Symbol.for(key)
|
||
}
|
||
} else {
|
||
makeSymbol = function (key) {
|
||
return '_' + key
|
||
}
|
||
}
|
||
|
||
function priv (obj, key, val) {
|
||
var sym
|
||
if (symbols[key]) {
|
||
sym = symbols[key]
|
||
} else {
|
||
sym = makeSymbol(key)
|
||
symbols[key] = sym
|
||
}
|
||
if (arguments.length === 2) {
|
||
return obj[sym]
|
||
} else {
|
||
obj[sym] = val
|
||
return val
|
||
}
|
||
}
|
||
|
||
function naiveLength () { return 1 }
|
||
|
||
// lruList is a yallist where the head is the youngest
|
||
// item, and the tail is the oldest. the list contains the Hit
|
||
// objects as the entries.
|
||
// Each Hit object has a reference to its Yallist.Node. This
|
||
// never changes.
|
||
//
|
||
// cache is a Map (or PseudoMap) that matches the keys to
|
||
// the Yallist.Node object.
|
||
function LRUCache (options) {
|
||
if (!(this instanceof LRUCache)) {
|
||
return new LRUCache(options)
|
||
}
|
||
|
||
if (typeof options === 'number') {
|
||
options = { max: options }
|
||
}
|
||
|
||
if (!options) {
|
||
options = {}
|
||
}
|
||
|
||
var max = priv(this, 'max', options.max)
|
||
// Kind of weird to have a default max of Infinity, but oh well.
|
||
if (!max ||
|
||
!(typeof max === 'number') ||
|
||
max <= 0) {
|
||
priv(this, 'max', Infinity)
|
||
}
|
||
|
||
var lc = options.length || naiveLength
|
||
if (typeof lc !== 'function') {
|
||
lc = naiveLength
|
||
}
|
||
priv(this, 'lengthCalculator', lc)
|
||
|
||
priv(this, 'allowStale', options.stale || false)
|
||
priv(this, 'maxAge', options.maxAge || 0)
|
||
priv(this, 'dispose', options.dispose)
|
||
this.reset()
|
||
}
|
||
|
||
// resize the cache when the max changes.
|
||
Object.defineProperty(LRUCache.prototype, 'max', {
|
||
set: function (mL) {
|
||
if (!mL || !(typeof mL === 'number') || mL <= 0) {
|
||
mL = Infinity
|
||
}
|
||
priv(this, 'max', mL)
|
||
trim(this)
|
||
},
|
||
get: function () {
|
||
return priv(this, 'max')
|
||
},
|
||
enumerable: true
|
||
})
|
||
|
||
Object.defineProperty(LRUCache.prototype, 'allowStale', {
|
||
set: function (allowStale) {
|
||
priv(this, 'allowStale', !!allowStale)
|
||
},
|
||
get: function () {
|
||
return priv(this, 'allowStale')
|
||
},
|
||
enumerable: true
|
||
})
|
||
|
||
Object.defineProperty(LRUCache.prototype, 'maxAge', {
|
||
set: function (mA) {
|
||
if (!mA || !(typeof mA === 'number') || mA < 0) {
|
||
mA = 0
|
||
}
|
||
priv(this, 'maxAge', mA)
|
||
trim(this)
|
||
},
|
||
get: function () {
|
||
return priv(this, 'maxAge')
|
||
},
|
||
enumerable: true
|
||
})
|
||
|
||
// resize the cache when the lengthCalculator changes.
|
||
Object.defineProperty(LRUCache.prototype, 'lengthCalculator', {
|
||
set: function (lC) {
|
||
if (typeof lC !== 'function') {
|
||
lC = naiveLength
|
||
}
|
||
if (lC !== priv(this, 'lengthCalculator')) {
|
||
priv(this, 'lengthCalculator', lC)
|
||
priv(this, 'length', 0)
|
||
priv(this, 'lruList').forEach(function (hit) {
|
||
hit.length = priv(this, 'lengthCalculator').call(this, hit.value, hit.key)
|
||
priv(this, 'length', priv(this, 'length') + hit.length)
|
||
}, this)
|
||
}
|
||
trim(this)
|
||
},
|
||
get: function () { return priv(this, 'lengthCalculator') },
|
||
enumerable: true
|
||
})
|
||
|
||
Object.defineProperty(LRUCache.prototype, 'length', {
|
||
get: function () { return priv(this, 'length') },
|
||
enumerable: true
|
||
})
|
||
|
||
Object.defineProperty(LRUCache.prototype, 'itemCount', {
|
||
get: function () { return priv(this, 'lruList').length },
|
||
enumerable: true
|
||
})
|
||
|
||
LRUCache.prototype.rforEach = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
for (var walker = priv(this, 'lruList').tail; walker !== null;) {
|
||
var prev = walker.prev
|
||
forEachStep(this, fn, walker, thisp)
|
||
walker = prev
|
||
}
|
||
}
|
||
|
||
function forEachStep (self, fn, node, thisp) {
|
||
var hit = node.value
|
||
if (isStale(self, hit)) {
|
||
del(self, node)
|
||
if (!priv(self, 'allowStale')) {
|
||
hit = undefined
|
||
}
|
||
}
|
||
if (hit) {
|
||
fn.call(thisp, hit.value, hit.key, self)
|
||
}
|
||
}
|
||
|
||
LRUCache.prototype.forEach = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
for (var walker = priv(this, 'lruList').head; walker !== null;) {
|
||
var next = walker.next
|
||
forEachStep(this, fn, walker, thisp)
|
||
walker = next
|
||
}
|
||
}
|
||
|
||
LRUCache.prototype.keys = function () {
|
||
return priv(this, 'lruList').toArray().map(function (k) {
|
||
return k.key
|
||
}, this)
|
||
}
|
||
|
||
LRUCache.prototype.values = function () {
|
||
return priv(this, 'lruList').toArray().map(function (k) {
|
||
return k.value
|
||
}, this)
|
||
}
|
||
|
||
LRUCache.prototype.reset = function () {
|
||
if (priv(this, 'dispose') &&
|
||
priv(this, 'lruList') &&
|
||
priv(this, 'lruList').length) {
|
||
priv(this, 'lruList').forEach(function (hit) {
|
||
priv(this, 'dispose').call(this, hit.key, hit.value)
|
||
}, this)
|
||
}
|
||
|
||
priv(this, 'cache', new Map()) // hash of items by key
|
||
priv(this, 'lruList', new Yallist()) // list of items in order of use recency
|
||
priv(this, 'length', 0) // length of items in the list
|
||
}
|
||
|
||
LRUCache.prototype.dump = function () {
|
||
return priv(this, 'lruList').map(function (hit) {
|
||
if (!isStale(this, hit)) {
|
||
return {
|
||
k: hit.key,
|
||
v: hit.value,
|
||
e: hit.now + (hit.maxAge || 0)
|
||
}
|
||
}
|
||
}, this).toArray().filter(function (h) {
|
||
return h
|
||
})
|
||
}
|
||
|
||
LRUCache.prototype.dumpLru = function () {
|
||
return priv(this, 'lruList')
|
||
}
|
||
|
||
LRUCache.prototype.inspect = function (n, opts) {
|
||
var str = 'LRUCache {'
|
||
var extras = false
|
||
|
||
var as = priv(this, 'allowStale')
|
||
if (as) {
|
||
str += '\n allowStale: true'
|
||
extras = true
|
||
}
|
||
|
||
var max = priv(this, 'max')
|
||
if (max && max !== Infinity) {
|
||
if (extras) {
|
||
str += ','
|
||
}
|
||
str += '\n max: ' + util.inspect(max, opts)
|
||
extras = true
|
||
}
|
||
|
||
var maxAge = priv(this, 'maxAge')
|
||
if (maxAge) {
|
||
if (extras) {
|
||
str += ','
|
||
}
|
||
str += '\n maxAge: ' + util.inspect(maxAge, opts)
|
||
extras = true
|
||
}
|
||
|
||
var lc = priv(this, 'lengthCalculator')
|
||
if (lc && lc !== naiveLength) {
|
||
if (extras) {
|
||
str += ','
|
||
}
|
||
str += '\n length: ' + util.inspect(priv(this, 'length'), opts)
|
||
extras = true
|
||
}
|
||
|
||
var didFirst = false
|
||
priv(this, 'lruList').forEach(function (item) {
|
||
if (didFirst) {
|
||
str += ',\n '
|
||
} else {
|
||
if (extras) {
|
||
str += ',\n'
|
||
}
|
||
didFirst = true
|
||
str += '\n '
|
||
}
|
||
var key = util.inspect(item.key).split('\n').join('\n ')
|
||
var val = { value: item.value }
|
||
if (item.maxAge !== maxAge) {
|
||
val.maxAge = item.maxAge
|
||
}
|
||
if (lc !== naiveLength) {
|
||
val.length = item.length
|
||
}
|
||
if (isStale(this, item)) {
|
||
val.stale = true
|
||
}
|
||
|
||
val = util.inspect(val, opts).split('\n').join('\n ')
|
||
str += key + ' => ' + val
|
||
})
|
||
|
||
if (didFirst || extras) {
|
||
str += '\n'
|
||
}
|
||
str += '}'
|
||
|
||
return str
|
||
}
|
||
|
||
LRUCache.prototype.set = function (key, value, maxAge) {
|
||
maxAge = maxAge || priv(this, 'maxAge')
|
||
|
||
var now = maxAge ? Date.now() : 0
|
||
var len = priv(this, 'lengthCalculator').call(this, value, key)
|
||
|
||
if (priv(this, 'cache').has(key)) {
|
||
if (len > priv(this, 'max')) {
|
||
del(this, priv(this, 'cache').get(key))
|
||
return false
|
||
}
|
||
|
||
var node = priv(this, 'cache').get(key)
|
||
var item = node.value
|
||
|
||
// dispose of the old one before overwriting
|
||
if (priv(this, 'dispose')) {
|
||
priv(this, 'dispose').call(this, key, item.value)
|
||
}
|
||
|
||
item.now = now
|
||
item.maxAge = maxAge
|
||
item.value = value
|
||
priv(this, 'length', priv(this, 'length') + (len - item.length))
|
||
item.length = len
|
||
this.get(key)
|
||
trim(this)
|
||
return true
|
||
}
|
||
|
||
var hit = new Entry(key, value, len, now, maxAge)
|
||
|
||
// oversized objects fall out of cache automatically.
|
||
if (hit.length > priv(this, 'max')) {
|
||
if (priv(this, 'dispose')) {
|
||
priv(this, 'dispose').call(this, key, value)
|
||
}
|
||
return false
|
||
}
|
||
|
||
priv(this, 'length', priv(this, 'length') + hit.length)
|
||
priv(this, 'lruList').unshift(hit)
|
||
priv(this, 'cache').set(key, priv(this, 'lruList').head)
|
||
trim(this)
|
||
return true
|
||
}
|
||
|
||
LRUCache.prototype.has = function (key) {
|
||
if (!priv(this, 'cache').has(key)) return false
|
||
var hit = priv(this, 'cache').get(key).value
|
||
if (isStale(this, hit)) {
|
||
return false
|
||
}
|
||
return true
|
||
}
|
||
|
||
LRUCache.prototype.get = function (key) {
|
||
return get(this, key, true)
|
||
}
|
||
|
||
LRUCache.prototype.peek = function (key) {
|
||
return get(this, key, false)
|
||
}
|
||
|
||
LRUCache.prototype.pop = function () {
|
||
var node = priv(this, 'lruList').tail
|
||
if (!node) return null
|
||
del(this, node)
|
||
return node.value
|
||
}
|
||
|
||
LRUCache.prototype.del = function (key) {
|
||
del(this, priv(this, 'cache').get(key))
|
||
}
|
||
|
||
LRUCache.prototype.load = function (arr) {
|
||
// reset the cache
|
||
this.reset()
|
||
|
||
var now = Date.now()
|
||
// A previous serialized cache has the most recent items first
|
||
for (var l = arr.length - 1; l >= 0; l--) {
|
||
var hit = arr[l]
|
||
var expiresAt = hit.e || 0
|
||
if (expiresAt === 0) {
|
||
// the item was created without expiration in a non aged cache
|
||
this.set(hit.k, hit.v)
|
||
} else {
|
||
var maxAge = expiresAt - now
|
||
// dont add already expired items
|
||
if (maxAge > 0) {
|
||
this.set(hit.k, hit.v, maxAge)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
LRUCache.prototype.prune = function () {
|
||
var self = this
|
||
priv(this, 'cache').forEach(function (value, key) {
|
||
get(self, key, false)
|
||
})
|
||
}
|
||
|
||
function get (self, key, doUse) {
|
||
var node = priv(self, 'cache').get(key)
|
||
if (node) {
|
||
var hit = node.value
|
||
if (isStale(self, hit)) {
|
||
del(self, node)
|
||
if (!priv(self, 'allowStale')) hit = undefined
|
||
} else {
|
||
if (doUse) {
|
||
priv(self, 'lruList').unshiftNode(node)
|
||
}
|
||
}
|
||
if (hit) hit = hit.value
|
||
}
|
||
return hit
|
||
}
|
||
|
||
function isStale (self, hit) {
|
||
if (!hit || (!hit.maxAge && !priv(self, 'maxAge'))) {
|
||
return false
|
||
}
|
||
var stale = false
|
||
var diff = Date.now() - hit.now
|
||
if (hit.maxAge) {
|
||
stale = diff > hit.maxAge
|
||
} else {
|
||
stale = priv(self, 'maxAge') && (diff > priv(self, 'maxAge'))
|
||
}
|
||
return stale
|
||
}
|
||
|
||
function trim (self) {
|
||
if (priv(self, 'length') > priv(self, 'max')) {
|
||
for (var walker = priv(self, 'lruList').tail;
|
||
priv(self, 'length') > priv(self, 'max') && walker !== null;) {
|
||
// We know that we're about to delete this one, and also
|
||
// what the next least recently used key will be, so just
|
||
// go ahead and set it now.
|
||
var prev = walker.prev
|
||
del(self, walker)
|
||
walker = prev
|
||
}
|
||
}
|
||
}
|
||
|
||
function del (self, node) {
|
||
if (node) {
|
||
var hit = node.value
|
||
if (priv(self, 'dispose')) {
|
||
priv(self, 'dispose').call(this, hit.key, hit.value)
|
||
}
|
||
priv(self, 'length', priv(self, 'length') - hit.length)
|
||
priv(self, 'cache').delete(hit.key)
|
||
priv(self, 'lruList').removeNode(node)
|
||
}
|
||
}
|
||
|
||
// classy, since V8 prefers predictable objects.
|
||
function Entry (key, value, length, now, maxAge) {
|
||
this.key = key
|
||
this.value = value
|
||
this.length = length
|
||
this.now = now
|
||
this.maxAge = maxAge || 0
|
||
}
|
||
|
||
|
||
/***/ },
|
||
/* 37 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(process) {if (process.env.npm_package_name === 'pseudomap' &&
|
||
process.env.npm_lifecycle_script === 'test')
|
||
process.env.TEST_PSEUDOMAP = 'true'
|
||
|
||
if (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) {
|
||
module.exports = Map
|
||
} else {
|
||
module.exports = __webpack_require__(39)
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(38)))
|
||
|
||
/***/ },
|
||
/* 38 */
|
||
/***/ function(module, exports) {
|
||
|
||
// shim for using process in browser
|
||
|
||
var process = module.exports = {};
|
||
var queue = [];
|
||
var draining = false;
|
||
var currentQueue;
|
||
var queueIndex = -1;
|
||
|
||
function cleanUpNextTick() {
|
||
draining = false;
|
||
if (currentQueue.length) {
|
||
queue = currentQueue.concat(queue);
|
||
} else {
|
||
queueIndex = -1;
|
||
}
|
||
if (queue.length) {
|
||
drainQueue();
|
||
}
|
||
}
|
||
|
||
function drainQueue() {
|
||
if (draining) {
|
||
return;
|
||
}
|
||
var timeout = setTimeout(cleanUpNextTick);
|
||
draining = true;
|
||
|
||
var len = queue.length;
|
||
while(len) {
|
||
currentQueue = queue;
|
||
queue = [];
|
||
while (++queueIndex < len) {
|
||
if (currentQueue) {
|
||
currentQueue[queueIndex].run();
|
||
}
|
||
}
|
||
queueIndex = -1;
|
||
len = queue.length;
|
||
}
|
||
currentQueue = null;
|
||
draining = false;
|
||
clearTimeout(timeout);
|
||
}
|
||
|
||
process.nextTick = function (fun) {
|
||
var args = new Array(arguments.length - 1);
|
||
if (arguments.length > 1) {
|
||
for (var i = 1; i < arguments.length; i++) {
|
||
args[i - 1] = arguments[i];
|
||
}
|
||
}
|
||
queue.push(new Item(fun, args));
|
||
if (queue.length === 1 && !draining) {
|
||
setTimeout(drainQueue, 0);
|
||
}
|
||
};
|
||
|
||
// v8 likes predictible objects
|
||
function Item(fun, array) {
|
||
this.fun = fun;
|
||
this.array = array;
|
||
}
|
||
Item.prototype.run = function () {
|
||
this.fun.apply(null, this.array);
|
||
};
|
||
process.title = 'browser';
|
||
process.browser = true;
|
||
process.env = {};
|
||
process.argv = [];
|
||
process.version = ''; // empty string to avoid regexp issues
|
||
process.versions = {};
|
||
|
||
function noop() {}
|
||
|
||
process.on = noop;
|
||
process.addListener = noop;
|
||
process.once = noop;
|
||
process.off = noop;
|
||
process.removeListener = noop;
|
||
process.removeAllListeners = noop;
|
||
process.emit = noop;
|
||
|
||
process.binding = function (name) {
|
||
throw new Error('process.binding is not supported');
|
||
};
|
||
|
||
process.cwd = function () { return '/' };
|
||
process.chdir = function (dir) {
|
||
throw new Error('process.chdir is not supported');
|
||
};
|
||
process.umask = function() { return 0; };
|
||
|
||
|
||
/***/ },
|
||
/* 39 */
|
||
/***/ function(module, exports) {
|
||
|
||
var hasOwnProperty = Object.prototype.hasOwnProperty
|
||
|
||
module.exports = PseudoMap
|
||
|
||
function PseudoMap (set) {
|
||
if (!(this instanceof PseudoMap)) // whyyyyyyy
|
||
throw new TypeError("Constructor PseudoMap requires 'new'")
|
||
|
||
this.clear()
|
||
|
||
if (set) {
|
||
if ((set instanceof PseudoMap) ||
|
||
(typeof Map === 'function' && set instanceof Map))
|
||
set.forEach(function (value, key) {
|
||
this.set(key, value)
|
||
}, this)
|
||
else if (Array.isArray(set))
|
||
set.forEach(function (kv) {
|
||
this.set(kv[0], kv[1])
|
||
}, this)
|
||
else
|
||
throw new TypeError('invalid argument')
|
||
}
|
||
}
|
||
|
||
PseudoMap.prototype.forEach = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
Object.keys(this._data).forEach(function (k) {
|
||
if (k !== 'size')
|
||
fn.call(thisp, this._data[k].value, this._data[k].key)
|
||
}, this)
|
||
}
|
||
|
||
PseudoMap.prototype.has = function (k) {
|
||
return !!find(this._data, k)
|
||
}
|
||
|
||
PseudoMap.prototype.get = function (k) {
|
||
var res = find(this._data, k)
|
||
return res && res.value
|
||
}
|
||
|
||
PseudoMap.prototype.set = function (k, v) {
|
||
set(this._data, k, v)
|
||
}
|
||
|
||
PseudoMap.prototype.delete = function (k) {
|
||
var res = find(this._data, k)
|
||
if (res) {
|
||
delete this._data[res._index]
|
||
this._data.size--
|
||
}
|
||
}
|
||
|
||
PseudoMap.prototype.clear = function () {
|
||
var data = Object.create(null)
|
||
data.size = 0
|
||
|
||
Object.defineProperty(this, '_data', {
|
||
value: data,
|
||
enumerable: false,
|
||
configurable: true,
|
||
writable: false
|
||
})
|
||
}
|
||
|
||
Object.defineProperty(PseudoMap.prototype, 'size', {
|
||
get: function () {
|
||
return this._data.size
|
||
},
|
||
set: function (n) {},
|
||
enumerable: true,
|
||
configurable: true
|
||
})
|
||
|
||
PseudoMap.prototype.values =
|
||
PseudoMap.prototype.keys =
|
||
PseudoMap.prototype.entries = function () {
|
||
throw new Error('iterators are not implemented in this version')
|
||
}
|
||
|
||
// Either identical, or both NaN
|
||
function same (a, b) {
|
||
return a === b || a !== a && b !== b
|
||
}
|
||
|
||
function Entry (k, v, i) {
|
||
this.key = k
|
||
this.value = v
|
||
this._index = i
|
||
}
|
||
|
||
function find (data, k) {
|
||
for (var i = 0, s = '_' + k, key = s;
|
||
hasOwnProperty.call(data, key);
|
||
key = s + i++) {
|
||
if (same(data[key].key, k))
|
||
return data[key]
|
||
}
|
||
}
|
||
|
||
function set (data, k, v) {
|
||
for (var i = 0, s = '_' + k, key = s;
|
||
hasOwnProperty.call(data, key);
|
||
key = s + i++) {
|
||
if (same(data[key].key, k)) {
|
||
data[key].value = v
|
||
return
|
||
}
|
||
}
|
||
data.size++
|
||
data[key] = new Entry(k, v, key)
|
||
}
|
||
|
||
|
||
/***/ },
|
||
/* 40 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.
|
||
//
|
||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||
// copy of this software and associated documentation files (the
|
||
// "Software"), to deal in the Software without restriction, including
|
||
// without limitation the rights to use, copy, modify, merge, publish,
|
||
// distribute, sublicense, and/or sell copies of the Software, and to permit
|
||
// persons to whom the Software is furnished to do so, subject to the
|
||
// following conditions:
|
||
//
|
||
// The above copyright notice and this permission notice shall be included
|
||
// in all copies or substantial portions of the Software.
|
||
//
|
||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||
|
||
var formatRegExp = /%[sdj%]/g;
|
||
exports.format = function(f) {
|
||
if (!isString(f)) {
|
||
var objects = [];
|
||
for (var i = 0; i < arguments.length; i++) {
|
||
objects.push(inspect(arguments[i]));
|
||
}
|
||
return objects.join(' ');
|
||
}
|
||
|
||
var i = 1;
|
||
var args = arguments;
|
||
var len = args.length;
|
||
var str = String(f).replace(formatRegExp, function(x) {
|
||
if (x === '%%') return '%';
|
||
if (i >= len) return x;
|
||
switch (x) {
|
||
case '%s': return String(args[i++]);
|
||
case '%d': return Number(args[i++]);
|
||
case '%j':
|
||
try {
|
||
return JSON.stringify(args[i++]);
|
||
} catch (_) {
|
||
return '[Circular]';
|
||
}
|
||
default:
|
||
return x;
|
||
}
|
||
});
|
||
for (var x = args[i]; i < len; x = args[++i]) {
|
||
if (isNull(x) || !isObject(x)) {
|
||
str += ' ' + x;
|
||
} else {
|
||
str += ' ' + inspect(x);
|
||
}
|
||
}
|
||
return str;
|
||
};
|
||
|
||
|
||
// Mark that a method should not be used.
|
||
// Returns a modified function which warns once by default.
|
||
// If --no-deprecation is set, then it is a no-op.
|
||
exports.deprecate = function(fn, msg) {
|
||
// Allow for deprecating things in the process of starting up.
|
||
if (isUndefined(global.process)) {
|
||
return function() {
|
||
return exports.deprecate(fn, msg).apply(this, arguments);
|
||
};
|
||
}
|
||
|
||
if (process.noDeprecation === true) {
|
||
return fn;
|
||
}
|
||
|
||
var warned = false;
|
||
function deprecated() {
|
||
if (!warned) {
|
||
if (process.throwDeprecation) {
|
||
throw new Error(msg);
|
||
} else if (process.traceDeprecation) {
|
||
console.trace(msg);
|
||
} else {
|
||
console.error(msg);
|
||
}
|
||
warned = true;
|
||
}
|
||
return fn.apply(this, arguments);
|
||
}
|
||
|
||
return deprecated;
|
||
};
|
||
|
||
|
||
var debugs = {};
|
||
var debugEnviron;
|
||
exports.debuglog = function(set) {
|
||
if (isUndefined(debugEnviron))
|
||
debugEnviron = process.env.NODE_DEBUG || '';
|
||
set = set.toUpperCase();
|
||
if (!debugs[set]) {
|
||
if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
|
||
var pid = process.pid;
|
||
debugs[set] = function() {
|
||
var msg = exports.format.apply(exports, arguments);
|
||
console.error('%s %d: %s', set, pid, msg);
|
||
};
|
||
} else {
|
||
debugs[set] = function() {};
|
||
}
|
||
}
|
||
return debugs[set];
|
||
};
|
||
|
||
|
||
/**
|
||
* Echos the value of a value. Trys to print the value out
|
||
* in the best way possible given the different types.
|
||
*
|
||
* @param {Object} obj The object to print out.
|
||
* @param {Object} opts Optional options object that alters the output.
|
||
*/
|
||
/* legacy: obj, showHidden, depth, colors*/
|
||
function inspect(obj, opts) {
|
||
// default options
|
||
var ctx = {
|
||
seen: [],
|
||
stylize: stylizeNoColor
|
||
};
|
||
// legacy...
|
||
if (arguments.length >= 3) ctx.depth = arguments[2];
|
||
if (arguments.length >= 4) ctx.colors = arguments[3];
|
||
if (isBoolean(opts)) {
|
||
// legacy...
|
||
ctx.showHidden = opts;
|
||
} else if (opts) {
|
||
// got an "options" object
|
||
exports._extend(ctx, opts);
|
||
}
|
||
// set default options
|
||
if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
|
||
if (isUndefined(ctx.depth)) ctx.depth = 2;
|
||
if (isUndefined(ctx.colors)) ctx.colors = false;
|
||
if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
|
||
if (ctx.colors) ctx.stylize = stylizeWithColor;
|
||
return formatValue(ctx, obj, ctx.depth);
|
||
}
|
||
exports.inspect = inspect;
|
||
|
||
|
||
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||
inspect.colors = {
|
||
'bold' : [1, 22],
|
||
'italic' : [3, 23],
|
||
'underline' : [4, 24],
|
||
'inverse' : [7, 27],
|
||
'white' : [37, 39],
|
||
'grey' : [90, 39],
|
||
'black' : [30, 39],
|
||
'blue' : [34, 39],
|
||
'cyan' : [36, 39],
|
||
'green' : [32, 39],
|
||
'magenta' : [35, 39],
|
||
'red' : [31, 39],
|
||
'yellow' : [33, 39]
|
||
};
|
||
|
||
// Don't use 'blue' not visible on cmd.exe
|
||
inspect.styles = {
|
||
'special': 'cyan',
|
||
'number': 'yellow',
|
||
'boolean': 'yellow',
|
||
'undefined': 'grey',
|
||
'null': 'bold',
|
||
'string': 'green',
|
||
'date': 'magenta',
|
||
// "name": intentionally not styling
|
||
'regexp': 'red'
|
||
};
|
||
|
||
|
||
function stylizeWithColor(str, styleType) {
|
||
var style = inspect.styles[styleType];
|
||
|
||
if (style) {
|
||
return '\u001b[' + inspect.colors[style][0] + 'm' + str +
|
||
'\u001b[' + inspect.colors[style][1] + 'm';
|
||
} else {
|
||
return str;
|
||
}
|
||
}
|
||
|
||
|
||
function stylizeNoColor(str, styleType) {
|
||
return str;
|
||
}
|
||
|
||
|
||
function arrayToHash(array) {
|
||
var hash = {};
|
||
|
||
array.forEach(function(val, idx) {
|
||
hash[val] = true;
|
||
});
|
||
|
||
return hash;
|
||
}
|
||
|
||
|
||
function formatValue(ctx, value, recurseTimes) {
|
||
// Provide a hook for user-specified inspect functions.
|
||
// Check that value is an object with an inspect function on it
|
||
if (ctx.customInspect &&
|
||
value &&
|
||
isFunction(value.inspect) &&
|
||
// Filter out the util module, it's inspect function is special
|
||
value.inspect !== exports.inspect &&
|
||
// Also filter out any prototype objects using the circular check.
|
||
!(value.constructor && value.constructor.prototype === value)) {
|
||
var ret = value.inspect(recurseTimes, ctx);
|
||
if (!isString(ret)) {
|
||
ret = formatValue(ctx, ret, recurseTimes);
|
||
}
|
||
return ret;
|
||
}
|
||
|
||
// Primitive types cannot have properties
|
||
var primitive = formatPrimitive(ctx, value);
|
||
if (primitive) {
|
||
return primitive;
|
||
}
|
||
|
||
// Look up the keys of the object.
|
||
var keys = Object.keys(value);
|
||
var visibleKeys = arrayToHash(keys);
|
||
|
||
if (ctx.showHidden) {
|
||
keys = Object.getOwnPropertyNames(value);
|
||
}
|
||
|
||
// IE doesn't make error fields non-enumerable
|
||
// http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
|
||
if (isError(value)
|
||
&& (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
|
||
return formatError(value);
|
||
}
|
||
|
||
// Some type of object without properties can be shortcutted.
|
||
if (keys.length === 0) {
|
||
if (isFunction(value)) {
|
||
var name = value.name ? ': ' + value.name : '';
|
||
return ctx.stylize('[Function' + name + ']', 'special');
|
||
}
|
||
if (isRegExp(value)) {
|
||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||
}
|
||
if (isDate(value)) {
|
||
return ctx.stylize(Date.prototype.toString.call(value), 'date');
|
||
}
|
||
if (isError(value)) {
|
||
return formatError(value);
|
||
}
|
||
}
|
||
|
||
var base = '', array = false, braces = ['{', '}'];
|
||
|
||
// Make Array say that they are Array
|
||
if (isArray(value)) {
|
||
array = true;
|
||
braces = ['[', ']'];
|
||
}
|
||
|
||
// Make functions say that they are functions
|
||
if (isFunction(value)) {
|
||
var n = value.name ? ': ' + value.name : '';
|
||
base = ' [Function' + n + ']';
|
||
}
|
||
|
||
// Make RegExps say that they are RegExps
|
||
if (isRegExp(value)) {
|
||
base = ' ' + RegExp.prototype.toString.call(value);
|
||
}
|
||
|
||
// Make dates with properties first say the date
|
||
if (isDate(value)) {
|
||
base = ' ' + Date.prototype.toUTCString.call(value);
|
||
}
|
||
|
||
// Make error with message first say the error
|
||
if (isError(value)) {
|
||
base = ' ' + formatError(value);
|
||
}
|
||
|
||
if (keys.length === 0 && (!array || value.length == 0)) {
|
||
return braces[0] + base + braces[1];
|
||
}
|
||
|
||
if (recurseTimes < 0) {
|
||
if (isRegExp(value)) {
|
||
return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
|
||
} else {
|
||
return ctx.stylize('[Object]', 'special');
|
||
}
|
||
}
|
||
|
||
ctx.seen.push(value);
|
||
|
||
var output;
|
||
if (array) {
|
||
output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
|
||
} else {
|
||
output = keys.map(function(key) {
|
||
return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
|
||
});
|
||
}
|
||
|
||
ctx.seen.pop();
|
||
|
||
return reduceToSingleString(output, base, braces);
|
||
}
|
||
|
||
|
||
function formatPrimitive(ctx, value) {
|
||
if (isUndefined(value))
|
||
return ctx.stylize('undefined', 'undefined');
|
||
if (isString(value)) {
|
||
var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
|
||
.replace(/'/g, "\\'")
|
||
.replace(/\\"/g, '"') + '\'';
|
||
return ctx.stylize(simple, 'string');
|
||
}
|
||
if (isNumber(value))
|
||
return ctx.stylize('' + value, 'number');
|
||
if (isBoolean(value))
|
||
return ctx.stylize('' + value, 'boolean');
|
||
// For some reason typeof null is "object", so special case here.
|
||
if (isNull(value))
|
||
return ctx.stylize('null', 'null');
|
||
}
|
||
|
||
|
||
function formatError(value) {
|
||
return '[' + Error.prototype.toString.call(value) + ']';
|
||
}
|
||
|
||
|
||
function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
|
||
var output = [];
|
||
for (var i = 0, l = value.length; i < l; ++i) {
|
||
if (hasOwnProperty(value, String(i))) {
|
||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||
String(i), true));
|
||
} else {
|
||
output.push('');
|
||
}
|
||
}
|
||
keys.forEach(function(key) {
|
||
if (!key.match(/^\d+$/)) {
|
||
output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
|
||
key, true));
|
||
}
|
||
});
|
||
return output;
|
||
}
|
||
|
||
|
||
function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
|
||
var name, str, desc;
|
||
desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
|
||
if (desc.get) {
|
||
if (desc.set) {
|
||
str = ctx.stylize('[Getter/Setter]', 'special');
|
||
} else {
|
||
str = ctx.stylize('[Getter]', 'special');
|
||
}
|
||
} else {
|
||
if (desc.set) {
|
||
str = ctx.stylize('[Setter]', 'special');
|
||
}
|
||
}
|
||
if (!hasOwnProperty(visibleKeys, key)) {
|
||
name = '[' + key + ']';
|
||
}
|
||
if (!str) {
|
||
if (ctx.seen.indexOf(desc.value) < 0) {
|
||
if (isNull(recurseTimes)) {
|
||
str = formatValue(ctx, desc.value, null);
|
||
} else {
|
||
str = formatValue(ctx, desc.value, recurseTimes - 1);
|
||
}
|
||
if (str.indexOf('\n') > -1) {
|
||
if (array) {
|
||
str = str.split('\n').map(function(line) {
|
||
return ' ' + line;
|
||
}).join('\n').substr(2);
|
||
} else {
|
||
str = '\n' + str.split('\n').map(function(line) {
|
||
return ' ' + line;
|
||
}).join('\n');
|
||
}
|
||
}
|
||
} else {
|
||
str = ctx.stylize('[Circular]', 'special');
|
||
}
|
||
}
|
||
if (isUndefined(name)) {
|
||
if (array && key.match(/^\d+$/)) {
|
||
return str;
|
||
}
|
||
name = JSON.stringify('' + key);
|
||
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
||
name = name.substr(1, name.length - 2);
|
||
name = ctx.stylize(name, 'name');
|
||
} else {
|
||
name = name.replace(/'/g, "\\'")
|
||
.replace(/\\"/g, '"')
|
||
.replace(/(^"|"$)/g, "'");
|
||
name = ctx.stylize(name, 'string');
|
||
}
|
||
}
|
||
|
||
return name + ': ' + str;
|
||
}
|
||
|
||
|
||
function reduceToSingleString(output, base, braces) {
|
||
var numLinesEst = 0;
|
||
var length = output.reduce(function(prev, cur) {
|
||
numLinesEst++;
|
||
if (cur.indexOf('\n') >= 0) numLinesEst++;
|
||
return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
|
||
}, 0);
|
||
|
||
if (length > 60) {
|
||
return braces[0] +
|
||
(base === '' ? '' : base + '\n ') +
|
||
' ' +
|
||
output.join(',\n ') +
|
||
' ' +
|
||
braces[1];
|
||
}
|
||
|
||
return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
|
||
}
|
||
|
||
|
||
// NOTE: These type checking functions intentionally don't use `instanceof`
|
||
// because it is fragile and can be easily faked with `Object.create()`.
|
||
function isArray(ar) {
|
||
return Array.isArray(ar);
|
||
}
|
||
exports.isArray = isArray;
|
||
|
||
function isBoolean(arg) {
|
||
return typeof arg === 'boolean';
|
||
}
|
||
exports.isBoolean = isBoolean;
|
||
|
||
function isNull(arg) {
|
||
return arg === null;
|
||
}
|
||
exports.isNull = isNull;
|
||
|
||
function isNullOrUndefined(arg) {
|
||
return arg == null;
|
||
}
|
||
exports.isNullOrUndefined = isNullOrUndefined;
|
||
|
||
function isNumber(arg) {
|
||
return typeof arg === 'number';
|
||
}
|
||
exports.isNumber = isNumber;
|
||
|
||
function isString(arg) {
|
||
return typeof arg === 'string';
|
||
}
|
||
exports.isString = isString;
|
||
|
||
function isSymbol(arg) {
|
||
return typeof arg === 'symbol';
|
||
}
|
||
exports.isSymbol = isSymbol;
|
||
|
||
function isUndefined(arg) {
|
||
return arg === void 0;
|
||
}
|
||
exports.isUndefined = isUndefined;
|
||
|
||
function isRegExp(re) {
|
||
return isObject(re) && objectToString(re) === '[object RegExp]';
|
||
}
|
||
exports.isRegExp = isRegExp;
|
||
|
||
function isObject(arg) {
|
||
return typeof arg === 'object' && arg !== null;
|
||
}
|
||
exports.isObject = isObject;
|
||
|
||
function isDate(d) {
|
||
return isObject(d) && objectToString(d) === '[object Date]';
|
||
}
|
||
exports.isDate = isDate;
|
||
|
||
function isError(e) {
|
||
return isObject(e) &&
|
||
(objectToString(e) === '[object Error]' || e instanceof Error);
|
||
}
|
||
exports.isError = isError;
|
||
|
||
function isFunction(arg) {
|
||
return typeof arg === 'function';
|
||
}
|
||
exports.isFunction = isFunction;
|
||
|
||
function isPrimitive(arg) {
|
||
return arg === null ||
|
||
typeof arg === 'boolean' ||
|
||
typeof arg === 'number' ||
|
||
typeof arg === 'string' ||
|
||
typeof arg === 'symbol' || // ES6 symbol
|
||
typeof arg === 'undefined';
|
||
}
|
||
exports.isPrimitive = isPrimitive;
|
||
|
||
exports.isBuffer = __webpack_require__(41);
|
||
|
||
function objectToString(o) {
|
||
return Object.prototype.toString.call(o);
|
||
}
|
||
|
||
|
||
function pad(n) {
|
||
return n < 10 ? '0' + n.toString(10) : n.toString(10);
|
||
}
|
||
|
||
|
||
var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
|
||
'Oct', 'Nov', 'Dec'];
|
||
|
||
// 26 Feb 16:19:34
|
||
function timestamp() {
|
||
var d = new Date();
|
||
var time = [pad(d.getHours()),
|
||
pad(d.getMinutes()),
|
||
pad(d.getSeconds())].join(':');
|
||
return [d.getDate(), months[d.getMonth()], time].join(' ');
|
||
}
|
||
|
||
|
||
// log is just a thin wrapper to console.log that prepends a timestamp
|
||
exports.log = function() {
|
||
console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
|
||
};
|
||
|
||
|
||
/**
|
||
* Inherit the prototype methods from one constructor into another.
|
||
*
|
||
* The Function.prototype.inherits from lang.js rewritten as a standalone
|
||
* function (not on Function.prototype). NOTE: If this file is to be loaded
|
||
* during bootstrapping this function needs to be rewritten using some native
|
||
* functions as prototype setup using normal JavaScript does not work as
|
||
* expected during bootstrapping (see mirror.js in r114903).
|
||
*
|
||
* @param {function} ctor Constructor function which needs to inherit the
|
||
* prototype.
|
||
* @param {function} superCtor Constructor function to inherit prototype from.
|
||
*/
|
||
exports.inherits = __webpack_require__(42);
|
||
|
||
exports._extend = function(origin, add) {
|
||
// Don't do anything if add isn't an object
|
||
if (!add || !isObject(add)) return origin;
|
||
|
||
var keys = Object.keys(add);
|
||
var i = keys.length;
|
||
while (i--) {
|
||
origin[keys[i]] = add[keys[i]];
|
||
}
|
||
return origin;
|
||
};
|
||
|
||
function hasOwnProperty(obj, prop) {
|
||
return Object.prototype.hasOwnProperty.call(obj, prop);
|
||
}
|
||
|
||
/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(38)))
|
||
|
||
/***/ },
|
||
/* 41 */
|
||
/***/ function(module, exports) {
|
||
|
||
module.exports = function isBuffer(arg) {
|
||
return arg && typeof arg === 'object'
|
||
&& typeof arg.copy === 'function'
|
||
&& typeof arg.fill === 'function'
|
||
&& typeof arg.readUInt8 === 'function';
|
||
}
|
||
|
||
/***/ },
|
||
/* 42 */
|
||
/***/ function(module, exports) {
|
||
|
||
if (typeof Object.create === 'function') {
|
||
// implementation from standard node.js 'util' module
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
ctor.prototype = Object.create(superCtor.prototype, {
|
||
constructor: {
|
||
value: ctor,
|
||
enumerable: false,
|
||
writable: true,
|
||
configurable: true
|
||
}
|
||
});
|
||
};
|
||
} else {
|
||
// old school shim for old browsers
|
||
module.exports = function inherits(ctor, superCtor) {
|
||
ctor.super_ = superCtor
|
||
var TempCtor = function () {}
|
||
TempCtor.prototype = superCtor.prototype
|
||
ctor.prototype = new TempCtor()
|
||
ctor.prototype.constructor = ctor
|
||
}
|
||
}
|
||
|
||
|
||
/***/ },
|
||
/* 43 */
|
||
/***/ function(module, exports) {
|
||
|
||
module.exports = Yallist
|
||
|
||
Yallist.Node = Node
|
||
Yallist.create = Yallist
|
||
|
||
function Yallist (list) {
|
||
var self = this
|
||
if (!(self instanceof Yallist)) {
|
||
self = new Yallist()
|
||
}
|
||
|
||
self.tail = null
|
||
self.head = null
|
||
self.length = 0
|
||
|
||
if (list && typeof list.forEach === 'function') {
|
||
list.forEach(function (item) {
|
||
self.push(item)
|
||
})
|
||
} else if (arguments.length > 0) {
|
||
for (var i = 0, l = arguments.length; i < l; i++) {
|
||
self.push(arguments[i])
|
||
}
|
||
}
|
||
|
||
return self
|
||
}
|
||
|
||
Yallist.prototype.removeNode = function (node) {
|
||
if (node.list !== this) {
|
||
throw new Error('removing node which does not belong to this list')
|
||
}
|
||
|
||
var next = node.next
|
||
var prev = node.prev
|
||
|
||
if (next) {
|
||
next.prev = prev
|
||
}
|
||
|
||
if (prev) {
|
||
prev.next = next
|
||
}
|
||
|
||
if (node === this.head) {
|
||
this.head = next
|
||
}
|
||
if (node === this.tail) {
|
||
this.tail = prev
|
||
}
|
||
|
||
node.list.length --
|
||
node.next = null
|
||
node.prev = null
|
||
node.list = null
|
||
}
|
||
|
||
Yallist.prototype.unshiftNode = function (node) {
|
||
if (node === this.head) {
|
||
return
|
||
}
|
||
|
||
if (node.list) {
|
||
node.list.removeNode(node)
|
||
}
|
||
|
||
var head = this.head
|
||
node.list = this
|
||
node.next = head
|
||
if (head) {
|
||
head.prev = node
|
||
}
|
||
|
||
this.head = node
|
||
if (!this.tail) {
|
||
this.tail = node
|
||
}
|
||
this.length ++
|
||
}
|
||
|
||
Yallist.prototype.pushNode = function (node) {
|
||
if (node === this.tail) {
|
||
return
|
||
}
|
||
|
||
if (node.list) {
|
||
node.list.removeNode(node)
|
||
}
|
||
|
||
var tail = this.tail
|
||
node.list = this
|
||
node.prev = tail
|
||
if (tail) {
|
||
tail.next = node
|
||
}
|
||
|
||
this.tail = node
|
||
if (!this.head) {
|
||
this.head = node
|
||
}
|
||
this.length ++
|
||
}
|
||
|
||
Yallist.prototype.push = function () {
|
||
for (var i = 0, l = arguments.length; i < l; i++) {
|
||
push(this, arguments[i])
|
||
}
|
||
return this.length
|
||
}
|
||
|
||
Yallist.prototype.unshift = function () {
|
||
for (var i = 0, l = arguments.length; i < l; i++) {
|
||
unshift(this, arguments[i])
|
||
}
|
||
return this.length
|
||
}
|
||
|
||
Yallist.prototype.pop = function () {
|
||
if (!this.tail)
|
||
return undefined
|
||
|
||
var res = this.tail.value
|
||
this.tail = this.tail.prev
|
||
this.tail.next = null
|
||
this.length --
|
||
return res
|
||
}
|
||
|
||
Yallist.prototype.shift = function () {
|
||
if (!this.head)
|
||
return undefined
|
||
|
||
var res = this.head.value
|
||
this.head = this.head.next
|
||
this.head.prev = null
|
||
this.length --
|
||
return res
|
||
}
|
||
|
||
Yallist.prototype.forEach = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
for (var walker = this.head, i = 0; walker !== null; i++) {
|
||
fn.call(thisp, walker.value, i, this)
|
||
walker = walker.next
|
||
}
|
||
}
|
||
|
||
Yallist.prototype.forEachReverse = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
|
||
fn.call(thisp, walker.value, i, this)
|
||
walker = walker.prev
|
||
}
|
||
}
|
||
|
||
Yallist.prototype.get = function (n) {
|
||
for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
|
||
// abort out of the list early if we hit a cycle
|
||
walker = walker.next
|
||
}
|
||
if (i === n && walker !== null) {
|
||
return walker.value
|
||
}
|
||
}
|
||
|
||
Yallist.prototype.getReverse = function (n) {
|
||
for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
|
||
// abort out of the list early if we hit a cycle
|
||
walker = walker.prev
|
||
}
|
||
if (i === n && walker !== null) {
|
||
return walker.value
|
||
}
|
||
}
|
||
|
||
Yallist.prototype.map = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
var res = new Yallist()
|
||
for (var walker = this.head; walker !== null; ) {
|
||
res.push(fn.call(thisp, walker.value, this))
|
||
walker = walker.next
|
||
}
|
||
return res
|
||
}
|
||
|
||
Yallist.prototype.mapReverse = function (fn, thisp) {
|
||
thisp = thisp || this
|
||
var res = new Yallist()
|
||
for (var walker = this.tail; walker !== null;) {
|
||
res.push(fn.call(thisp, walker.value, this))
|
||
walker = walker.prev
|
||
}
|
||
return res
|
||
}
|
||
|
||
Yallist.prototype.reduce = function (fn, initial) {
|
||
var acc
|
||
var walker = this.head
|
||
if (arguments.length > 1) {
|
||
acc = initial
|
||
} else if (this.head) {
|
||
walker = this.head.next
|
||
acc = this.head.value
|
||
} else {
|
||
throw new TypeError('Reduce of empty list with no initial value')
|
||
}
|
||
|
||
for (var i = 0; walker !== null; i++) {
|
||
acc = fn(acc, walker.value, i)
|
||
walker = walker.next
|
||
}
|
||
|
||
return acc
|
||
}
|
||
|
||
Yallist.prototype.reduceReverse = function (fn, initial) {
|
||
var acc
|
||
var walker = this.tail
|
||
if (arguments.length > 1) {
|
||
acc = initial
|
||
} else if (this.tail) {
|
||
walker = this.tail.prev
|
||
acc = this.tail.value
|
||
} else {
|
||
throw new TypeError('Reduce of empty list with no initial value')
|
||
}
|
||
|
||
for (var i = this.length - 1; walker !== null; i--) {
|
||
acc = fn(acc, walker.value, i)
|
||
walker = walker.prev
|
||
}
|
||
|
||
return acc
|
||
}
|
||
|
||
Yallist.prototype.toArray = function () {
|
||
var arr = new Array(this.length)
|
||
for (var i = 0, walker = this.head; walker !== null; i++) {
|
||
arr[i] = walker.value
|
||
walker = walker.next
|
||
}
|
||
return arr
|
||
}
|
||
|
||
Yallist.prototype.toArrayReverse = function () {
|
||
var arr = new Array(this.length)
|
||
for (var i = 0, walker = this.tail; walker !== null; i++) {
|
||
arr[i] = walker.value
|
||
walker = walker.prev
|
||
}
|
||
return arr
|
||
}
|
||
|
||
Yallist.prototype.slice = function (from, to) {
|
||
to = to || this.length
|
||
if (to < 0) {
|
||
to += this.length
|
||
}
|
||
from = from || 0
|
||
if (from < 0) {
|
||
from += this.length
|
||
}
|
||
var ret = new Yallist()
|
||
if (to < from || to < 0) {
|
||
return ret
|
||
}
|
||
if (from < 0) {
|
||
from = 0
|
||
}
|
||
if (to > this.length) {
|
||
to = this.length
|
||
}
|
||
for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
|
||
walker = walker.next
|
||
}
|
||
for (; walker !== null && i < to; i++, walker = walker.next) {
|
||
ret.push(walker.value)
|
||
}
|
||
return ret
|
||
}
|
||
|
||
Yallist.prototype.sliceReverse = function (from, to) {
|
||
to = to || this.length
|
||
if (to < 0) {
|
||
to += this.length
|
||
}
|
||
from = from || 0
|
||
if (from < 0) {
|
||
from += this.length
|
||
}
|
||
var ret = new Yallist()
|
||
if (to < from || to < 0) {
|
||
return ret
|
||
}
|
||
if (from < 0) {
|
||
from = 0
|
||
}
|
||
if (to > this.length) {
|
||
to = this.length
|
||
}
|
||
for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
|
||
walker = walker.prev
|
||
}
|
||
for (; walker !== null && i > from; i--, walker = walker.prev) {
|
||
ret.push(walker.value)
|
||
}
|
||
return ret
|
||
}
|
||
|
||
Yallist.prototype.reverse = function () {
|
||
var head = this.head
|
||
var tail = this.tail
|
||
for (var walker = head; walker !== null; walker = walker.prev) {
|
||
var p = walker.prev
|
||
walker.prev = walker.next
|
||
walker.next = p
|
||
}
|
||
this.head = tail
|
||
this.tail = head
|
||
return this
|
||
}
|
||
|
||
function push (self, item) {
|
||
self.tail = new Node(item, self.tail, null, self)
|
||
if (!self.head) {
|
||
self.head = self.tail
|
||
}
|
||
self.length ++
|
||
}
|
||
|
||
function unshift (self, item) {
|
||
self.head = new Node(item, null, self.head, self)
|
||
if (!self.tail) {
|
||
self.tail = self.head
|
||
}
|
||
self.length ++
|
||
}
|
||
|
||
function Node (value, prev, next, list) {
|
||
if (!(this instanceof Node)) {
|
||
return new Node(value, prev, next, list)
|
||
}
|
||
|
||
this.list = list
|
||
this.value = value
|
||
|
||
if (prev) {
|
||
prev.next = this
|
||
this.prev = prev
|
||
} else {
|
||
this.prev = null
|
||
}
|
||
|
||
if (next) {
|
||
next.prev = this
|
||
this.next = next
|
||
} else {
|
||
this.next = null
|
||
}
|
||
}
|
||
|
||
|
||
/***/ },
|
||
/* 44 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||
|
||
var _Tile2 = __webpack_require__(45);
|
||
|
||
var _Tile3 = _interopRequireDefault(_Tile2);
|
||
|
||
var _vendorBoxHelper = __webpack_require__(46);
|
||
|
||
var _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
var ImageTile = (function (_Tile) {
|
||
_inherits(ImageTile, _Tile);
|
||
|
||
function ImageTile(quadcode, path, layer) {
|
||
_classCallCheck(this, ImageTile);
|
||
|
||
_get(Object.getPrototypeOf(ImageTile.prototype), 'constructor', this).call(this, quadcode, path, layer);
|
||
}
|
||
|
||
// Initialise without requiring new keyword
|
||
|
||
// Request data for the various tile provider
|
||
|
||
_createClass(ImageTile, [{
|
||
key: 'requestTileAsync',
|
||
value: function requestTileAsync() {
|
||
var _this = this;
|
||
|
||
// Making this asynchronous really speeds up the LOD framerate
|
||
setTimeout(function () {
|
||
if (!_this._mesh) {
|
||
_this._mesh = _this._createMesh();
|
||
_this._requestTexture();
|
||
}
|
||
}, 0);
|
||
}
|
||
}, {
|
||
key: 'destroy',
|
||
value: function destroy() {
|
||
// Cancel any pending requests
|
||
this._abortRequest();
|
||
|
||
// Clear image reference
|
||
this._image = null;
|
||
|
||
_get(Object.getPrototypeOf(ImageTile.prototype), 'destroy', this).call(this);
|
||
}
|
||
}, {
|
||
key: '_createMesh',
|
||
value: function _createMesh() {
|
||
// Something went wrong and the tile
|
||
//
|
||
// Possibly removed by the cache before loaded
|
||
if (!this._center) {
|
||
return;
|
||
}
|
||
|
||
var mesh = new _three2['default'].Object3D();
|
||
var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);
|
||
|
||
var material = new _three2['default'].MeshBasicMaterial({
|
||
depthWrite: false
|
||
});
|
||
|
||
var localMesh = new _three2['default'].Mesh(geom, material);
|
||
localMesh.rotation.x = -90 * Math.PI / 180;
|
||
|
||
mesh.add(localMesh);
|
||
|
||
mesh.position.x = this._center[0];
|
||
mesh.position.z = this._center[1];
|
||
|
||
var box = new _vendorBoxHelper2['default'](localMesh);
|
||
mesh.add(box);
|
||
|
||
mesh.add(this._createDebugMesh());
|
||
|
||
return mesh;
|
||
}
|
||
}, {
|
||
key: '_createDebugMesh',
|
||
value: function _createDebugMesh() {
|
||
var canvas = document.createElement('canvas');
|
||
canvas.width = 256;
|
||
canvas.height = 256;
|
||
|
||
var context = canvas.getContext('2d');
|
||
context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';
|
||
context.fillStyle = '#ff0000';
|
||
context.fillText(this._quadcode, 20, canvas.width / 2 - 5);
|
||
context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);
|
||
|
||
var texture = new _three2['default'].Texture(canvas);
|
||
|
||
// Silky smooth images when tilted
|
||
texture.magFilter = _three2['default'].LinearFilter;
|
||
texture.minFilter = _three2['default'].LinearMipMapLinearFilter;
|
||
|
||
// TODO: Set this to renderer.getMaxAnisotropy() / 4
|
||
texture.anisotropy = 4;
|
||
|
||
texture.needsUpdate = true;
|
||
|
||
var material = new _three2['default'].MeshBasicMaterial({
|
||
map: texture,
|
||
transparent: true,
|
||
depthWrite: false
|
||
});
|
||
|
||
var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);
|
||
var mesh = new _three2['default'].Mesh(geom, material);
|
||
|
||
mesh.rotation.x = -90 * Math.PI / 180;
|
||
mesh.position.y = 0.1;
|
||
|
||
return mesh;
|
||
}
|
||
}, {
|
||
key: '_requestTexture',
|
||
value: function _requestTexture() {
|
||
var _this2 = this;
|
||
|
||
var urlParams = {
|
||
x: this._tile[0],
|
||
y: this._tile[1],
|
||
z: this._tile[2]
|
||
};
|
||
|
||
var url = this._getTileURL(urlParams);
|
||
|
||
var image = document.createElement('img');
|
||
|
||
image.addEventListener('load', function (event) {
|
||
var texture = new _three2['default'].Texture();
|
||
|
||
texture.image = image;
|
||
texture.needsUpdate = true;
|
||
|
||
// Silky smooth images when tilted
|
||
texture.magFilter = _three2['default'].LinearFilter;
|
||
texture.minFilter = _three2['default'].LinearMipMapLinearFilter;
|
||
|
||
// TODO: Set this to renderer.getMaxAnisotropy() / 4
|
||
texture.anisotropy = 4;
|
||
|
||
texture.needsUpdate = true;
|
||
|
||
// Something went wrong and the tile or its material is missing
|
||
//
|
||
// Possibly removed by the cache before the image loaded
|
||
if (!_this2._mesh || !_this2._mesh.children[0] || !_this2._mesh.children[0].material) {
|
||
return;
|
||
}
|
||
|
||
_this2._mesh.children[0].material.map = texture;
|
||
_this2._mesh.children[0].material.needsUpdate = true;
|
||
|
||
_this2._texture = texture;
|
||
_this2._ready = true;
|
||
}, false);
|
||
|
||
// image.addEventListener('progress', event => {}, false);
|
||
// image.addEventListener('error', event => {}, false);
|
||
|
||
image.crossOrigin = '';
|
||
|
||
// Load image
|
||
image.src = url;
|
||
|
||
this._image = image;
|
||
}
|
||
}, {
|
||
key: '_abortRequest',
|
||
value: function _abortRequest() {
|
||
if (!this._image) {
|
||
return;
|
||
}
|
||
|
||
this._image.src = '';
|
||
}
|
||
}]);
|
||
|
||
return ImageTile;
|
||
})(_Tile3['default']);
|
||
|
||
exports['default'] = function (quadcode, path, layer) {
|
||
return new ImageTile(quadcode, path, layer);
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 45 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
|
||
|
||
var _geoLatLon = __webpack_require__(10);
|
||
|
||
var _geoLatLon2 = _interopRequireDefault(_geoLatLon);
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
// Manages a single tile and its layers
|
||
|
||
var r2d = 180 / Math.PI;
|
||
|
||
var tileURLRegex = /\{([szxy])\}/g;
|
||
|
||
var Tile = (function () {
|
||
function Tile(quadcode, path, layer) {
|
||
_classCallCheck(this, Tile);
|
||
|
||
this._layer = layer;
|
||
this._quadcode = quadcode;
|
||
this._path = path;
|
||
|
||
this._ready = false;
|
||
|
||
this._tile = this._quadcodeToTile(quadcode);
|
||
|
||
// Bottom-left and top-right bounds in WGS84 coordinates
|
||
this._boundsLatLon = this._tileBoundsWGS84(this._tile);
|
||
|
||
// Bottom-left and top-right bounds in world coordinates
|
||
this._boundsWorld = this._tileBoundsFromWGS84(this._boundsLatLon);
|
||
|
||
// Tile center in world coordinates
|
||
this._center = this._boundsToCenter(this._boundsWorld);
|
||
|
||
// Length of a tile side in world coorindates
|
||
this._side = this._getSide(this._boundsWorld);
|
||
}
|
||
|
||
// Returns true if the tile mesh and texture are ready to be used
|
||
// Otherwise, returns false
|
||
|
||
_createClass(Tile, [{
|
||
key: 'isReady',
|
||
value: function isReady() {
|
||
return this._ready;
|
||
}
|
||
|
||
// Request data for the tile
|
||
}, {
|
||
key: 'requestTileAsync',
|
||
value: function requestTileAsync() {}
|
||
}, {
|
||
key: 'getQuadcode',
|
||
value: function getQuadcode() {
|
||
return this._quadcode;
|
||
}
|
||
}, {
|
||
key: 'getBounds',
|
||
value: function getBounds() {
|
||
return this._boundsWorld;
|
||
}
|
||
}, {
|
||
key: 'getCenter',
|
||
value: function getCenter() {
|
||
return this._center;
|
||
}
|
||
}, {
|
||
key: 'getSide',
|
||
value: function getSide() {
|
||
return this._side;
|
||
}
|
||
}, {
|
||
key: 'getMesh',
|
||
value: function getMesh() {
|
||
return this._mesh;
|
||
}
|
||
|
||
// Destroys the tile and removes it from the layer and memory
|
||
//
|
||
// Ensure that this leaves no trace of the tile – no textures, no meshes,
|
||
// nothing in memory or the GPU
|
||
}, {
|
||
key: 'destroy',
|
||
value: function destroy() {
|
||
// Delete reference to layer
|
||
this._layer = null;
|
||
|
||
// Delete location references
|
||
this._boundsLatLon = null;
|
||
this._boundsWorld = null;
|
||
this._center = null;
|
||
|
||
// Done if no mesh
|
||
if (!this._mesh) {
|
||
return;
|
||
}
|
||
|
||
if (this._mesh.children) {
|
||
// Dispose of mesh and materials
|
||
this._mesh.children.forEach(function (child) {
|
||
child.geometry.dispose();
|
||
child.geometry = null;
|
||
|
||
if (child.material.map) {
|
||
child.material.map.dispose();
|
||
child.material.map = null;
|
||
}
|
||
|
||
child.material.dispose();
|
||
child.material = null;
|
||
});
|
||
} else {
|
||
this._mesh.geometry.dispose();
|
||
this._mesh.geometry = null;
|
||
|
||
if (this._mesh.material.map) {
|
||
this._mesh.material.map.dispose();
|
||
this._mesh.material.map = null;
|
||
}
|
||
|
||
this._mesh.material.dispose();
|
||
this._mesh.material = null;
|
||
}
|
||
}
|
||
}, {
|
||
key: '_createMesh',
|
||
value: function _createMesh() {}
|
||
}, {
|
||
key: '_createDebugMesh',
|
||
value: function _createDebugMesh() {}
|
||
}, {
|
||
key: '_getTileURL',
|
||
value: function _getTileURL(urlParams) {
|
||
if (!urlParams.s) {
|
||
// Default to a random choice of a, b or c
|
||
s = String.fromCharCode(97 + Math.floor(Math.random() * 3));
|
||
}
|
||
|
||
tileURLRegex.lastIndex = 0;
|
||
return this._path.replace(tileURLRegex, function (value, key) {
|
||
// Replace with paramter, otherwise keep existing value
|
||
return urlParams[key];
|
||
});
|
||
}
|
||
|
||
// Convert from quadcode to TMS tile coordinates
|
||
}, {
|
||
key: '_quadcodeToTile',
|
||
value: function _quadcodeToTile(quadcode) {
|
||
var x = 0;
|
||
var y = 0;
|
||
var z = quadcode.length;
|
||
|
||
for (var i = z; i > 0; i--) {
|
||
var mask = 1 << i - 1;
|
||
var q = +quadcode[z - i];
|
||
if (q === 1) {
|
||
x |= mask;
|
||
}
|
||
if (q === 2) {
|
||
y |= mask;
|
||
}
|
||
if (q === 3) {
|
||
x |= mask;
|
||
y |= mask;
|
||
}
|
||
}
|
||
|
||
return [x, y, z];
|
||
}
|
||
|
||
// Convert WGS84 tile bounds to world coordinates
|
||
}, {
|
||
key: '_tileBoundsFromWGS84',
|
||
value: function _tileBoundsFromWGS84(boundsWGS84) {
|
||
var sw = this._layer._world.latLonToPoint((0, _geoLatLon2['default'])(boundsWGS84[1], boundsWGS84[0]));
|
||
var ne = this._layer._world.latLonToPoint((0, _geoLatLon2['default'])(boundsWGS84[3], boundsWGS84[2]));
|
||
|
||
return [sw.x, sw.y, ne.x, ne.y];
|
||
}
|
||
|
||
// Get tile bounds in WGS84 coordinates
|
||
}, {
|
||
key: '_tileBoundsWGS84',
|
||
value: function _tileBoundsWGS84(tile) {
|
||
var e = this._tile2lon(tile[0] + 1, tile[2]);
|
||
var w = this._tile2lon(tile[0], tile[2]);
|
||
var s = this._tile2lat(tile[1] + 1, tile[2]);
|
||
var n = this._tile2lat(tile[1], tile[2]);
|
||
return [w, s, e, n];
|
||
}
|
||
}, {
|
||
key: '_tile2lon',
|
||
value: function _tile2lon(x, z) {
|
||
return x / Math.pow(2, z) * 360 - 180;
|
||
}
|
||
}, {
|
||
key: '_tile2lat',
|
||
value: function _tile2lat(y, z) {
|
||
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
|
||
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
|
||
}
|
||
}, {
|
||
key: '_boundsToCenter',
|
||
value: function _boundsToCenter(bounds) {
|
||
var x = bounds[0] + (bounds[2] - bounds[0]) / 2;
|
||
var y = bounds[1] + (bounds[3] - bounds[1]) / 2;
|
||
|
||
return [x, y];
|
||
}
|
||
}, {
|
||
key: '_getSide',
|
||
value: function _getSide(bounds) {
|
||
return new _three2['default'].Vector3(bounds[0], 0, bounds[3]).sub(new _three2['default'].Vector3(bounds[0], 0, bounds[1])).length();
|
||
}
|
||
}]);
|
||
|
||
return Tile;
|
||
})();
|
||
|
||
exports['default'] = Tile;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 46 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
// jscs:disable
|
||
/*eslint eqeqeq:0*/
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
/**
|
||
* @author mrdoob / http://mrdoob.com/
|
||
*/
|
||
|
||
BoxHelper = function (object) {
|
||
|
||
var indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]);
|
||
var positions = new Float32Array(8 * 3);
|
||
|
||
var geometry = new _three2['default'].BufferGeometry();
|
||
geometry.setIndex(new _three2['default'].BufferAttribute(indices, 1));
|
||
geometry.addAttribute('position', new _three2['default'].BufferAttribute(positions, 3));
|
||
|
||
_three2['default'].LineSegments.call(this, geometry, new _three2['default'].LineBasicMaterial({ linewidth: 2, color: 0xff0000 }));
|
||
|
||
if (object !== undefined) {
|
||
|
||
this.update(object);
|
||
}
|
||
};
|
||
|
||
BoxHelper.prototype = Object.create(_three2['default'].LineSegments.prototype);
|
||
BoxHelper.prototype.constructor = BoxHelper;
|
||
|
||
BoxHelper.prototype.update = (function () {
|
||
|
||
var box = new _three2['default'].Box3();
|
||
|
||
return function (object) {
|
||
|
||
box.setFromObject(object);
|
||
|
||
if (box.isEmpty()) return;
|
||
|
||
var min = box.min;
|
||
var max = box.max;
|
||
|
||
/*
|
||
5____4
|
||
1/___0/|
|
||
| 6__|_7
|
||
2/___3/
|
||
0: max.x, max.y, max.z
|
||
1: min.x, max.y, max.z
|
||
2: min.x, min.y, max.z
|
||
3: max.x, min.y, max.z
|
||
4: max.x, max.y, min.z
|
||
5: min.x, max.y, min.z
|
||
6: min.x, min.y, min.z
|
||
7: max.x, min.y, min.z
|
||
*/
|
||
|
||
var position = this.geometry.attributes.position;
|
||
var array = position.array;
|
||
|
||
array[0] = max.x;array[1] = max.y;array[2] = max.z;
|
||
array[3] = min.x;array[4] = max.y;array[5] = max.z;
|
||
array[6] = min.x;array[7] = min.y;array[8] = max.z;
|
||
array[9] = max.x;array[10] = min.y;array[11] = max.z;
|
||
array[12] = max.x;array[13] = max.y;array[14] = min.z;
|
||
array[15] = min.x;array[16] = max.y;array[17] = min.z;
|
||
array[18] = min.x;array[19] = min.y;array[20] = min.z;
|
||
array[21] = max.x;array[22] = min.y;array[23] = min.z;
|
||
|
||
position.needsUpdate = true;
|
||
|
||
this.geometry.computeBoundingSphere();
|
||
};
|
||
})();
|
||
|
||
exports['default'] = BoxHelper;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 47 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
Object.defineProperty(exports, '__esModule', {
|
||
value: true
|
||
});
|
||
|
||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||
|
||
var _three = __webpack_require__(24);
|
||
|
||
var _three2 = _interopRequireDefault(_three);
|
||
|
||
exports['default'] = function (colour) {
|
||
var canvas = document.createElement('canvas');
|
||
canvas.width = 1;
|
||
canvas.height = 1;
|
||
|
||
var context = canvas.getContext('2d');
|
||
context.fillStyle = colour;
|
||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||
// context.strokeStyle = '#D0D0CF';
|
||
// context.strokeRect(0, 0, canvas.width, canvas.height);
|
||
|
||
var texture = new _three2['default'].Texture(canvas);
|
||
|
||
// // Silky smooth images when tilted
|
||
// texture.magFilter = THREE.LinearFilter;
|
||
// texture.minFilter = THREE.LinearMipMapLinearFilter;
|
||
// //
|
||
// // // TODO: Set this to renderer.getMaxAnisotropy() / 4
|
||
// texture.anisotropy = 4;
|
||
|
||
// texture.wrapS = THREE.RepeatWrapping;
|
||
// texture.wrapT = THREE.RepeatWrapping;
|
||
// texture.repeat.set(segments, segments);
|
||
|
||
texture.needsUpdate = true;
|
||
|
||
var material = new _three2['default'].MeshBasicMaterial({
|
||
map: texture,
|
||
depthWrite: false
|
||
});
|
||
|
||
return material;
|
||
};
|
||
|
||
;
|
||
module.exports = exports['default'];
|
||
|
||
/***/ },
|
||
/* 48 */
|
||
/***/ function(module, exports, __webpack_require__) {
|
||
|
||
/**
|
||
* lodash 4.0.0 (Custom Build) <https://lodash.com/>
|
||
* Build: `lodash modularize exports="npm" -o ./`
|
||
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
* Available under MIT license <https://lodash.com/license>
|
||
*/
|
||
var debounce = __webpack_require__(49);
|
||
|
||
/** Used as the `TypeError` message for "Functions" methods. */
|
||
var FUNC_ERROR_TEXT = 'Expected a function';
|
||
|
||
/**
|
||
* Creates a throttled function that only invokes `func` at most once per
|
||
* every `wait` milliseconds. The throttled function comes with a `cancel`
|
||
* method to cancel delayed `func` invocations and a `flush` method to
|
||
* immediately invoke them. Provide an options object to indicate whether
|
||
* `func` should be invoked on the leading and/or trailing edge of the `wait`
|
||
* timeout. The `func` is invoked with the last arguments provided to the
|
||
* throttled function. Subsequent calls to the throttled function return the
|
||
* result of the last `func` invocation.
|
||
*
|
||
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
|
||
* on the trailing edge of the timeout only if the the throttled function is
|
||
* invoked more than once during the `wait` timeout.
|
||
*
|
||
* See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
|
||
* for details over the differences between `_.throttle` and `_.debounce`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Function
|
||
* @param {Function} func The function to throttle.
|
||
* @param {number} [wait=0] The number of milliseconds to throttle invocations to.
|
||
* @param {Object} [options] The options object.
|
||
* @param {boolean} [options.leading=true] Specify invoking on the leading
|
||
* edge of the timeout.
|
||
* @param {boolean} [options.trailing=true] Specify invoking on the trailing
|
||
* edge of the timeout.
|
||
* @returns {Function} Returns the new throttled function.
|
||
* @example
|
||
*
|
||
* // avoid excessively updating the position while scrolling
|
||
* jQuery(window).on('scroll', _.throttle(updatePosition, 100));
|
||
*
|
||
* // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
|
||
* var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
|
||
* jQuery(element).on('click', throttled);
|
||
*
|
||
* // cancel a trailing throttled invocation
|
||
* jQuery(window).on('popstate', throttled.cancel);
|
||
*/
|
||
function throttle(func, wait, options) {
|
||
var leading = true,
|
||
trailing = true;
|
||
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
if (isObject(options)) {
|
||
leading = 'leading' in options ? !!options.leading : leading;
|
||
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
||
}
|
||
return debounce(func, wait, { 'leading': leading, 'maxWait': wait, 'trailing': trailing });
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(_.noop);
|
||
* // => true
|
||
*
|
||
* _.isObject(null);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
// Avoid a V8 JIT bug in Chrome 19-20.
|
||
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
|
||
var type = typeof value;
|
||
return !!value && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
module.exports = throttle;
|
||
|
||
|
||
/***/ },
|
||
/* 49 */
|
||
/***/ function(module, exports) {
|
||
|
||
/**
|
||
* lodash 4.0.1 (Custom Build) <https://lodash.com/>
|
||
* Build: `lodash modularize exports="npm" -o ./`
|
||
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
|
||
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
||
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
||
* Available under MIT license <https://lodash.com/license>
|
||
*/
|
||
|
||
/** Used as the `TypeError` message for "Functions" methods. */
|
||
var FUNC_ERROR_TEXT = 'Expected a function';
|
||
|
||
/** Used as references for various `Number` constants. */
|
||
var NAN = 0 / 0;
|
||
|
||
/** `Object#toString` result references. */
|
||
var funcTag = '[object Function]',
|
||
genTag = '[object GeneratorFunction]';
|
||
|
||
/** Used to match leading and trailing whitespace. */
|
||
var reTrim = /^\s+|\s+$/g;
|
||
|
||
/** Used to detect bad signed hexadecimal string values. */
|
||
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
||
|
||
/** Used to detect binary string values. */
|
||
var reIsBinary = /^0b[01]+$/i;
|
||
|
||
/** Used to detect octal string values. */
|
||
var reIsOctal = /^0o[0-7]+$/i;
|
||
|
||
/** Built-in method references without a dependency on `root`. */
|
||
var freeParseInt = parseInt;
|
||
|
||
/** Used for built-in method references. */
|
||
var objectProto = Object.prototype;
|
||
|
||
/**
|
||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||
* of values.
|
||
*/
|
||
var objectToString = objectProto.toString;
|
||
|
||
/* Built-in method references for those with the same name as other `lodash` methods. */
|
||
var nativeMax = Math.max;
|
||
|
||
/**
|
||
* Gets the timestamp of the number of milliseconds that have elapsed since
|
||
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @type Function
|
||
* @category Date
|
||
* @returns {number} Returns the timestamp.
|
||
* @example
|
||
*
|
||
* _.defer(function(stamp) {
|
||
* console.log(_.now() - stamp);
|
||
* }, _.now());
|
||
* // => logs the number of milliseconds it took for the deferred function to be invoked
|
||
*/
|
||
var now = Date.now;
|
||
|
||
/**
|
||
* Creates a debounced function that delays invoking `func` until after `wait`
|
||
* milliseconds have elapsed since the last time the debounced function was
|
||
* invoked. The debounced function comes with a `cancel` method to cancel
|
||
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
||
* Provide an options object to indicate whether `func` should be invoked on
|
||
* the leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
||
* with the last arguments provided to the debounced function. Subsequent calls
|
||
* to the debounced function return the result of the last `func` invocation.
|
||
*
|
||
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
|
||
* on the trailing edge of the timeout only if the the debounced function is
|
||
* invoked more than once during the `wait` timeout.
|
||
*
|
||
* See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
|
||
* for details over the differences between `_.debounce` and `_.throttle`.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Function
|
||
* @param {Function} func The function to debounce.
|
||
* @param {number} [wait=0] The number of milliseconds to delay.
|
||
* @param {Object} [options] The options object.
|
||
* @param {boolean} [options.leading=false] Specify invoking on the leading
|
||
* edge of the timeout.
|
||
* @param {number} [options.maxWait] The maximum time `func` is allowed to be
|
||
* delayed before it's invoked.
|
||
* @param {boolean} [options.trailing=true] Specify invoking on the trailing
|
||
* edge of the timeout.
|
||
* @returns {Function} Returns the new debounced function.
|
||
* @example
|
||
*
|
||
* // Avoid costly calculations while the window size is in flux.
|
||
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
||
*
|
||
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
||
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
||
* 'leading': true,
|
||
* 'trailing': false
|
||
* }));
|
||
*
|
||
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
||
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
||
* var source = new EventSource('/stream');
|
||
* jQuery(source).on('message', debounced);
|
||
*
|
||
* // Cancel the trailing debounced invocation.
|
||
* jQuery(window).on('popstate', debounced.cancel);
|
||
*/
|
||
function debounce(func, wait, options) {
|
||
var args,
|
||
maxTimeoutId,
|
||
result,
|
||
stamp,
|
||
thisArg,
|
||
timeoutId,
|
||
trailingCall,
|
||
lastCalled = 0,
|
||
leading = false,
|
||
maxWait = false,
|
||
trailing = true;
|
||
|
||
if (typeof func != 'function') {
|
||
throw new TypeError(FUNC_ERROR_TEXT);
|
||
}
|
||
wait = toNumber(wait) || 0;
|
||
if (isObject(options)) {
|
||
leading = !!options.leading;
|
||
maxWait = 'maxWait' in options && nativeMax(toNumber(options.maxWait) || 0, wait);
|
||
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
||
}
|
||
|
||
function cancel() {
|
||
if (timeoutId) {
|
||
clearTimeout(timeoutId);
|
||
}
|
||
if (maxTimeoutId) {
|
||
clearTimeout(maxTimeoutId);
|
||
}
|
||
lastCalled = 0;
|
||
args = maxTimeoutId = thisArg = timeoutId = trailingCall = undefined;
|
||
}
|
||
|
||
function complete(isCalled, id) {
|
||
if (id) {
|
||
clearTimeout(id);
|
||
}
|
||
maxTimeoutId = timeoutId = trailingCall = undefined;
|
||
if (isCalled) {
|
||
lastCalled = now();
|
||
result = func.apply(thisArg, args);
|
||
if (!timeoutId && !maxTimeoutId) {
|
||
args = thisArg = undefined;
|
||
}
|
||
}
|
||
}
|
||
|
||
function delayed() {
|
||
var remaining = wait - (now() - stamp);
|
||
if (remaining <= 0 || remaining > wait) {
|
||
complete(trailingCall, maxTimeoutId);
|
||
} else {
|
||
timeoutId = setTimeout(delayed, remaining);
|
||
}
|
||
}
|
||
|
||
function flush() {
|
||
if ((timeoutId && trailingCall) || (maxTimeoutId && trailing)) {
|
||
result = func.apply(thisArg, args);
|
||
}
|
||
cancel();
|
||
return result;
|
||
}
|
||
|
||
function maxDelayed() {
|
||
complete(trailing, timeoutId);
|
||
}
|
||
|
||
function debounced() {
|
||
args = arguments;
|
||
stamp = now();
|
||
thisArg = this;
|
||
trailingCall = trailing && (timeoutId || !leading);
|
||
|
||
if (maxWait === false) {
|
||
var leadingCall = leading && !timeoutId;
|
||
} else {
|
||
if (!maxTimeoutId && !leading) {
|
||
lastCalled = stamp;
|
||
}
|
||
var remaining = maxWait - (stamp - lastCalled),
|
||
isCalled = remaining <= 0 || remaining > maxWait;
|
||
|
||
if (isCalled) {
|
||
if (maxTimeoutId) {
|
||
maxTimeoutId = clearTimeout(maxTimeoutId);
|
||
}
|
||
lastCalled = stamp;
|
||
result = func.apply(thisArg, args);
|
||
}
|
||
else if (!maxTimeoutId) {
|
||
maxTimeoutId = setTimeout(maxDelayed, remaining);
|
||
}
|
||
}
|
||
if (isCalled && timeoutId) {
|
||
timeoutId = clearTimeout(timeoutId);
|
||
}
|
||
else if (!timeoutId && wait !== maxWait) {
|
||
timeoutId = setTimeout(delayed, wait);
|
||
}
|
||
if (leadingCall) {
|
||
isCalled = true;
|
||
result = func.apply(thisArg, args);
|
||
}
|
||
if (isCalled && !timeoutId && !maxTimeoutId) {
|
||
args = thisArg = undefined;
|
||
}
|
||
return result;
|
||
}
|
||
debounced.cancel = cancel;
|
||
debounced.flush = flush;
|
||
return debounced;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is classified as a `Function` object.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
|
||
* @example
|
||
*
|
||
* _.isFunction(_);
|
||
* // => true
|
||
*
|
||
* _.isFunction(/abc/);
|
||
* // => false
|
||
*/
|
||
function isFunction(value) {
|
||
// The use of `Object#toString` avoids issues with the `typeof` operator
|
||
// in Safari 8 which returns 'object' for typed array constructors, and
|
||
// PhantomJS 1.9 which returns 'function' for `NodeList` instances.
|
||
var tag = isObject(value) ? objectToString.call(value) : '';
|
||
return tag == funcTag || tag == genTag;
|
||
}
|
||
|
||
/**
|
||
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
|
||
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to check.
|
||
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
||
* @example
|
||
*
|
||
* _.isObject({});
|
||
* // => true
|
||
*
|
||
* _.isObject([1, 2, 3]);
|
||
* // => true
|
||
*
|
||
* _.isObject(_.noop);
|
||
* // => true
|
||
*
|
||
* _.isObject(null);
|
||
* // => false
|
||
*/
|
||
function isObject(value) {
|
||
var type = typeof value;
|
||
return !!value && (type == 'object' || type == 'function');
|
||
}
|
||
|
||
/**
|
||
* Converts `value` to a number.
|
||
*
|
||
* @static
|
||
* @memberOf _
|
||
* @category Lang
|
||
* @param {*} value The value to process.
|
||
* @returns {number} Returns the number.
|
||
* @example
|
||
*
|
||
* _.toNumber(3);
|
||
* // => 3
|
||
*
|
||
* _.toNumber(Number.MIN_VALUE);
|
||
* // => 5e-324
|
||
*
|
||
* _.toNumber(Infinity);
|
||
* // => Infinity
|
||
*
|
||
* _.toNumber('3');
|
||
* // => 3
|
||
*/
|
||
function toNumber(value) {
|
||
if (isObject(value)) {
|
||
var other = isFunction(value.valueOf) ? value.valueOf() : value;
|
||
value = isObject(other) ? (other + '') : other;
|
||
}
|
||
if (typeof value != 'string') {
|
||
return value === 0 ? value : +value;
|
||
}
|
||
value = value.replace(reTrim, '');
|
||
var isBinary = reIsBinary.test(value);
|
||
return (isBinary || reIsOctal.test(value))
|
||
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
||
: (reIsBadHex.test(value) ? NAN : +value);
|
||
}
|
||
|
||
module.exports = debounce;
|
||
|
||
|
||
/***/ }
|
||
/******/ ])
|
||
});
|
||
; |