mapbox-gl
Version:
A WebGL interactive maps library
1,405 lines (1,387 loc) • 2.24 MB
JavaScript
/* Mapbox GL JS is licensed under the 3-Clause BSD License. Full text of license: https://github.com/mapbox/mapbox-gl-js/blob/v1.8.0-dev/LICENSE.txt */
(function(global, factory) {
typeof exports === 'object' && typeof module !== 'undefined'
? (module.exports = factory())
: typeof define === 'function' && define.amd
? define(factory)
: ((global = global || self), (global.mapboxgl = factory()));
})(this, function() {
'use strict';
/* eslint-disable */
var shared, worker, mapboxgl;
// define gets called three times: one for each chunk. we rely on the order
// they're imported to know which is which
function define(_, chunk) {
if (!shared) {
shared = chunk;
} else if (!worker) {
worker = chunk;
} else {
var workerBundleString =
'var sharedChunk = {}; (' +
shared +
')(sharedChunk); (' +
worker +
')(sharedChunk);';
var sharedChunk = {};
shared(sharedChunk);
mapboxgl = chunk(sharedChunk);
mapboxgl.workerUrl = window.URL.createObjectURL(
new Blob([workerBundleString], { type: 'text/javascript' })
);
}
}
define(['exports'], function(exports) {
'use strict';
function createCommonjsModule(fn, module) {
return (
(module = { exports: {} }),
fn(module, module.exports),
module.exports
);
}
var version = '1.8.0-dev';
var unitbezier = UnitBezier;
function UnitBezier(p1x, p1y, p2x, p2y) {
this.cx = 3 * p1x;
this.bx = 3 * (p2x - p1x) - this.cx;
this.ax = 1 - this.cx - this.bx;
this.cy = 3 * p1y;
this.by = 3 * (p2y - p1y) - this.cy;
this.ay = 1 - this.cy - this.by;
this.p1x = p1x;
this.p1y = p2y;
this.p2x = p2x;
this.p2y = p2y;
}
UnitBezier.prototype.sampleCurveX = function(t) {
return ((this.ax * t + this.bx) * t + this.cx) * t;
};
UnitBezier.prototype.sampleCurveY = function(t) {
return ((this.ay * t + this.by) * t + this.cy) * t;
};
UnitBezier.prototype.sampleCurveDerivativeX = function(t) {
return (3 * this.ax * t + 2 * this.bx) * t + this.cx;
};
UnitBezier.prototype.solveCurveX = function(x, epsilon) {
if (typeof epsilon === 'undefined') {
epsilon = 0.000001;
}
var t0, t1, t2, x2, i;
for (t2 = x, i = 0; i < 8; i++) {
x2 = this.sampleCurveX(t2) - x;
if (Math.abs(x2) < epsilon) {
return t2;
}
var d2 = this.sampleCurveDerivativeX(t2);
if (Math.abs(d2) < 0.000001) {
break;
}
t2 = t2 - x2 / d2;
}
t0 = 0;
t1 = 1;
t2 = x;
if (t2 < t0) {
return t0;
}
if (t2 > t1) {
return t1;
}
while (t0 < t1) {
x2 = this.sampleCurveX(t2);
if (Math.abs(x2 - x) < epsilon) {
return t2;
}
if (x > x2) {
t0 = t2;
} else {
t1 = t2;
}
t2 = (t1 - t0) * 0.5 + t0;
}
return t2;
};
UnitBezier.prototype.solve = function(x, epsilon) {
return this.sampleCurveY(this.solveCurveX(x, epsilon));
};
var pointGeometry = Point;
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype = {
clone: function() {
return new Point(this.x, this.y);
},
add: function(p) {
return this.clone()._add(p);
},
sub: function(p) {
return this.clone()._sub(p);
},
multByPoint: function(p) {
return this.clone()._multByPoint(p);
},
divByPoint: function(p) {
return this.clone()._divByPoint(p);
},
mult: function(k) {
return this.clone()._mult(k);
},
div: function(k) {
return this.clone()._div(k);
},
rotate: function(a) {
return this.clone()._rotate(a);
},
rotateAround: function(a, p) {
return this.clone()._rotateAround(a, p);
},
matMult: function(m) {
return this.clone()._matMult(m);
},
unit: function() {
return this.clone()._unit();
},
perp: function() {
return this.clone()._perp();
},
round: function() {
return this.clone()._round();
},
mag: function() {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
equals: function(other) {
return this.x === other.x && this.y === other.y;
},
dist: function(p) {
return Math.sqrt(this.distSqr(p));
},
distSqr: function(p) {
var dx = p.x - this.x,
dy = p.y - this.y;
return dx * dx + dy * dy;
},
angle: function() {
return Math.atan2(this.y, this.x);
},
angleTo: function(b) {
return Math.atan2(this.y - b.y, this.x - b.x);
},
angleWith: function(b) {
return this.angleWithSep(b.x, b.y);
},
angleWithSep: function(x, y) {
return Math.atan2(
this.x * y - this.y * x,
this.x * x + this.y * y
);
},
_matMult: function(m) {
var x = m[0] * this.x + m[1] * this.y,
y = m[2] * this.x + m[3] * this.y;
this.x = x;
this.y = y;
return this;
},
_add: function(p) {
this.x += p.x;
this.y += p.y;
return this;
},
_sub: function(p) {
this.x -= p.x;
this.y -= p.y;
return this;
},
_mult: function(k) {
this.x *= k;
this.y *= k;
return this;
},
_div: function(k) {
this.x /= k;
this.y /= k;
return this;
},
_multByPoint: function(p) {
this.x *= p.x;
this.y *= p.y;
return this;
},
_divByPoint: function(p) {
this.x /= p.x;
this.y /= p.y;
return this;
},
_unit: function() {
this._div(this.mag());
return this;
},
_perp: function() {
var y = this.y;
this.y = this.x;
this.x = -y;
return this;
},
_rotate: function(angle) {
var cos = Math.cos(angle),
sin = Math.sin(angle),
x = cos * this.x - sin * this.y,
y = sin * this.x + cos * this.y;
this.x = x;
this.y = y;
return this;
},
_rotateAround: function(angle, p) {
var cos = Math.cos(angle),
sin = Math.sin(angle),
x = p.x + cos * (this.x - p.x) - sin * (this.y - p.y),
y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
this.x = x;
this.y = y;
return this;
},
_round: function() {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
}
};
Point.convert = function(a) {
if (a instanceof Point) {
return a;
}
if (Array.isArray(a)) {
return new Point(a[0], a[1]);
}
return a;
};
function deepEqual(a, b) {
if (Array.isArray(a)) {
if (!Array.isArray(b) || a.length !== b.length) {
return false;
}
for (var i = 0; i < a.length; i++) {
if (!deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
if (typeof a === 'object' && a !== null && b !== null) {
if (!(typeof b === 'object')) {
return false;
}
var keys = Object.keys(a);
if (keys.length !== Object.keys(b).length) {
return false;
}
for (var key in a) {
if (!deepEqual(a[key], b[key])) {
return false;
}
}
return true;
}
return a === b;
}
function easeCubicInOut(t) {
if (t <= 0) {
return 0;
}
if (t >= 1) {
return 1;
}
var t2 = t * t,
t3 = t2 * t;
return 4 * (t < 0.5 ? t3 : 3 * (t - t2) + t3 - 0.75);
}
function bezier(p1x, p1y, p2x, p2y) {
var bezier = new unitbezier(p1x, p1y, p2x, p2y);
return function(t) {
return bezier.solve(t);
};
}
var ease = bezier(0.25, 0.1, 0.25, 1);
function clamp(n, min, max) {
return Math.min(max, Math.max(min, n));
}
function wrap(n, min, max) {
var d = max - min;
var w = ((((n - min) % d) + d) % d) + min;
return w === min ? max : w;
}
function asyncAll(array, fn, callback) {
if (!array.length) {
return callback(null, []);
}
var remaining = array.length;
var results = new Array(array.length);
var error = null;
array.forEach(function(item, i) {
fn(item, function(err, result) {
if (err) {
error = err;
}
results[i] = result;
if (--remaining === 0) {
callback(error, results);
}
});
});
}
function values(obj) {
var result = [];
for (var k in obj) {
result.push(obj[k]);
}
return result;
}
function keysDifference(obj, other) {
var difference = [];
for (var i in obj) {
if (!(i in other)) {
difference.push(i);
}
}
return difference;
}
function extend(dest) {
var sources = [],
len = arguments.length - 1;
while (len-- > 0) sources[len] = arguments[len + 1];
for (var i = 0, list = sources; i < list.length; i += 1) {
var src = list[i];
for (var k in src) {
dest[k] = src[k];
}
}
return dest;
}
function pick(src, properties) {
var result = {};
for (var i = 0; i < properties.length; i++) {
var k = properties[i];
if (k in src) {
result[k] = src[k];
}
}
return result;
}
var id = 1;
function uniqueId() {
return id++;
}
function uuid() {
function b(a) {
return a
? (a ^ ((Math.random() * 16) >> (a / 4))).toString(16)
: (
[10000000] +
-[1000] +
-4000 +
-8000 +
-100000000000
).replace(/[018]/g, b);
}
return b();
}
function validateUuid(str) {
return str
? /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
str
)
: false;
}
function bindAll(fns, context) {
fns.forEach(function(fn) {
if (!context[fn]) {
return;
}
context[fn] = context[fn].bind(context);
});
}
function endsWith(string, suffix) {
return string.indexOf(suffix, string.length - suffix.length) !== -1;
}
function mapObject(input, iterator, context) {
var output = {};
for (var key in input) {
output[key] = iterator.call(
context || this,
input[key],
key,
input
);
}
return output;
}
function filterObject(input, iterator, context) {
var output = {};
for (var key in input) {
if (iterator.call(context || this, input[key], key, input)) {
output[key] = input[key];
}
}
return output;
}
function clone(input) {
if (Array.isArray(input)) {
return input.map(clone);
} else if (typeof input === 'object' && input) {
return mapObject(input, clone);
} else {
return input;
}
}
function arraysIntersect(a, b) {
for (var l = 0; l < a.length; l++) {
if (b.indexOf(a[l]) >= 0) {
return true;
}
}
return false;
}
var warnOnceHistory = {};
function warnOnce(message) {
if (!warnOnceHistory[message]) {
if (typeof console !== 'undefined') {
console.warn(message);
}
warnOnceHistory[message] = true;
}
}
function isCounterClockwise(a, b, c) {
return (c.y - a.y) * (b.x - a.x) > (b.y - a.y) * (c.x - a.x);
}
function calculateSignedArea(ring) {
var sum = 0;
for (
var i = 0,
len = ring.length,
j = len - 1,
p1 = void 0,
p2 = void 0;
i < len;
j = i++
) {
p1 = ring[i];
p2 = ring[j];
sum += (p2.x - p1.x) * (p1.y + p2.y);
}
return sum;
}
function sphericalToCartesian(ref) {
var r = ref[0];
var azimuthal = ref[1];
var polar = ref[2];
azimuthal += 90;
azimuthal *= Math.PI / 180;
polar *= Math.PI / 180;
return {
x: r * Math.cos(azimuthal) * Math.sin(polar),
y: r * Math.sin(azimuthal) * Math.sin(polar),
z: r * Math.cos(polar)
};
}
function isWorker() {
return (
typeof WorkerGlobalScope !== 'undefined' &&
typeof self !== 'undefined' &&
self instanceof WorkerGlobalScope
);
}
function parseCacheControl(cacheControl) {
var re = /(?:^|(?:\s*\,\s*))([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)(?:\=(?:([^\x00-\x20\(\)<>@\,;\:\\"\/\[\]\?\=\{\}\x7F]+)|(?:\"((?:[^"\\]|\\.)*)\")))?/g;
var header = {};
cacheControl.replace(re, function($0, $1, $2, $3) {
var value = $2 || $3;
header[$1] = value ? value.toLowerCase() : true;
return '';
});
if (header['max-age']) {
var maxAge = parseInt(header['max-age'], 10);
if (isNaN(maxAge)) {
delete header['max-age'];
} else {
header['max-age'] = maxAge;
}
}
return header;
}
var _isSafari = null;
function isSafari(scope) {
if (_isSafari == null) {
var userAgent = scope.navigator
? scope.navigator.userAgent
: null;
_isSafari =
!!scope.safari ||
!!(
userAgent &&
(/\b(iPad|iPhone|iPod)\b/.test(userAgent) ||
(!!userAgent.match('Safari') &&
!userAgent.match('Chrome')))
);
}
return _isSafari;
}
function storageAvailable(type) {
try {
var storage = self[type];
storage.setItem('_mapbox_test_', 1);
storage.removeItem('_mapbox_test_');
return true;
} catch (e) {
return false;
}
}
function b64EncodeUnicode(str) {
return self.btoa(
encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(
match,
p1
) {
return String.fromCharCode(Number('0x' + p1));
})
);
}
function b64DecodeUnicode(str) {
return decodeURIComponent(
self
.atob(str)
.split('')
.map(function(c) {
return (
'%' +
('00' + c.charCodeAt(0).toString(16)).slice(-2)
);
})
.join('')
);
}
var now =
self.performance && self.performance.now
? self.performance.now.bind(self.performance)
: Date.now.bind(Date);
var raf =
self.requestAnimationFrame ||
self.mozRequestAnimationFrame ||
self.webkitRequestAnimationFrame ||
self.msRequestAnimationFrame;
var cancel =
self.cancelAnimationFrame ||
self.mozCancelAnimationFrame ||
self.webkitCancelAnimationFrame ||
self.msCancelAnimationFrame;
var linkEl;
var reducedMotionQuery;
var exported = {
now: now,
frame: function frame(fn) {
var frame = raf(fn);
return {
cancel: function() {
return cancel(frame);
}
};
},
getImageData: function getImageData(img, padding) {
if (padding === void 0) padding = 0;
var canvas = self.document.createElement('canvas');
var context = canvas.getContext('2d');
if (!context) {
throw new Error('failed to create canvas 2d context');
}
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0, img.width, img.height);
return context.getImageData(
-padding,
-padding,
img.width + 2 * padding,
img.height + 2 * padding
);
},
resolveURL: function resolveURL(path) {
if (!linkEl) {
linkEl = self.document.createElement('a');
}
linkEl.href = path;
return linkEl.href;
},
hardwareConcurrency: self.navigator.hardwareConcurrency || 4,
get devicePixelRatio() {
return self.devicePixelRatio;
},
get prefersReducedMotion() {
if (!self.matchMedia) {
return false;
}
if (reducedMotionQuery == null) {
reducedMotionQuery = self.matchMedia(
'(prefers-reduced-motion: reduce)'
);
}
return reducedMotionQuery.matches;
}
};
var config = {
API_URL: 'https://api.mapbox.com',
get EVENTS_URL() {
if (!this.API_URL) {
return null;
}
if (this.API_URL.indexOf('https://api.mapbox.cn') === 0) {
return 'https://events.mapbox.cn/events/v2';
} else if (
this.API_URL.indexOf('https://api.mapbox.com') === 0
) {
return 'https://events.mapbox.com/events/v2';
} else {
return null;
}
},
FEEDBACK_URL: 'https://apps.mapbox.com/feedback',
REQUIRE_ACCESS_TOKEN: true,
ACCESS_TOKEN: null,
MAX_PARALLEL_IMAGE_REQUESTS: 16
};
var exported$1 = {
supported: false,
testSupport: testSupport
};
var glForTesting;
var webpCheckComplete = false;
var webpImgTest;
var webpImgTestOnloadComplete = false;
if (self.document) {
webpImgTest = self.document.createElement('img');
webpImgTest.onload = function() {
if (glForTesting) {
testWebpTextureUpload(glForTesting);
}
glForTesting = null;
webpImgTestOnloadComplete = true;
};
webpImgTest.onerror = function() {
webpCheckComplete = true;
glForTesting = null;
};
webpImgTest.src =
'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=';
}
function testSupport(gl) {
if (webpCheckComplete || !webpImgTest) {
return;
}
if (webpImgTestOnloadComplete) {
testWebpTextureUpload(gl);
} else {
glForTesting = gl;
}
}
function testWebpTextureUpload(gl) {
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
try {
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
gl.RGBA,
gl.UNSIGNED_BYTE,
webpImgTest
);
if (gl.isContextLost()) {
return;
}
exported$1.supported = true;
} catch (e) {}
gl.deleteTexture(texture);
webpCheckComplete = true;
}
var SKU_ID = '01';
function createSkuToken() {
var TOKEN_VERSION = '1';
var base62chars =
'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
var sessionRandomizer = '';
for (var i = 0; i < 10; i++) {
sessionRandomizer +=
base62chars[Math.floor(Math.random() * 62)];
}
var expiration = 12 * 60 * 60 * 1000;
var token = [TOKEN_VERSION, SKU_ID, sessionRandomizer].join('');
var tokenExpiresAt = Date.now() + expiration;
return {
token: token,
tokenExpiresAt: tokenExpiresAt
};
}
var RequestManager = function RequestManager(
transformRequestFn,
customAccessToken
) {
this._transformRequestFn = transformRequestFn;
this._customAccessToken = customAccessToken;
this._createSkuToken();
};
RequestManager.prototype._createSkuToken = function _createSkuToken() {
var skuToken = createSkuToken();
this._skuToken = skuToken.token;
this._skuTokenExpiresAt = skuToken.tokenExpiresAt;
};
RequestManager.prototype._isSkuTokenExpired = function _isSkuTokenExpired() {
return Date.now() > this._skuTokenExpiresAt;
};
RequestManager.prototype.transformRequest = function transformRequest(
url,
type
) {
if (this._transformRequestFn) {
return this._transformRequestFn(url, type) || { url: url };
}
return { url: url };
};
RequestManager.prototype.normalizeStyleURL = function normalizeStyleURL(
url,
accessToken
) {
if (!isMapboxURL(url)) {
return url;
}
var urlObject = parseUrl(url);
urlObject.path = '/styles/v1' + urlObject.path;
return this._makeAPIURL(
urlObject,
this._customAccessToken || accessToken
);
};
RequestManager.prototype.normalizeGlyphsURL = function normalizeGlyphsURL(
url,
accessToken
) {
if (!isMapboxURL(url)) {
return url;
}
var urlObject = parseUrl(url);
urlObject.path = '/fonts/v1' + urlObject.path;
return this._makeAPIURL(
urlObject,
this._customAccessToken || accessToken
);
};
RequestManager.prototype.normalizeSourceURL = function normalizeSourceURL(
url,
accessToken
) {
if (!isMapboxURL(url)) {
return url;
}
var urlObject = parseUrl(url);
urlObject.path = '/v4/' + urlObject.authority + '.json';
urlObject.params.push('secure');
return this._makeAPIURL(
urlObject,
this._customAccessToken || accessToken
);
};
RequestManager.prototype.normalizeSpriteURL = function normalizeSpriteURL(
url,
format,
extension,
accessToken
) {
var urlObject = parseUrl(url);
if (!isMapboxURL(url)) {
urlObject.path += '' + format + extension;
return formatUrl(urlObject);
}
urlObject.path =
'/styles/v1' + urlObject.path + '/sprite' + format + extension;
return this._makeAPIURL(
urlObject,
this._customAccessToken || accessToken
);
};
RequestManager.prototype.normalizeTileURL = function normalizeTileURL(
tileURL,
tileSize
) {
if (this._isSkuTokenExpired()) {
this._createSkuToken();
}
if (tileURL && !isMapboxURL(tileURL) && !isMapboxHTTPURL(tileURL)) {
return tileURL;
}
var urlObject = parseUrl(tileURL);
var imageExtensionRe = /(\.(png|jpg)\d*)(?=$)/;
var tileURLAPIPrefixRe = /^.+\/v4\//;
var suffix =
exported.devicePixelRatio >= 2 || tileSize === 512 ? '@2x' : '';
var extension = exported$1.supported ? '.webp' : '$1';
urlObject.path = urlObject.path.replace(
imageExtensionRe,
'' + suffix + extension
);
urlObject.path = urlObject.path.replace(tileURLAPIPrefixRe, '/');
urlObject.path = '/v4' + urlObject.path;
var accessToken =
this._customAccessToken ||
getAccessToken(urlObject.params) ||
config.ACCESS_TOKEN;
if (config.REQUIRE_ACCESS_TOKEN && accessToken && this._skuToken) {
urlObject.params.push('sku=' + this._skuToken);
}
return this._makeAPIURL(urlObject, accessToken);
};
RequestManager.prototype.canonicalizeTileURL = function canonicalizeTileURL(
url,
removeAccessToken
) {
var version = '/v4/';
var extensionRe = /\.[\w]+$/;
var urlObject = parseUrl(url);
if (
!urlObject.path.match(/(^\/v4\/)/) ||
!urlObject.path.match(extensionRe)
) {
return url;
}
var result = 'mapbox://tiles/';
result += urlObject.path.replace(version, '');
var params = urlObject.params;
if (removeAccessToken) {
params = params.filter(function(p) {
return !p.match(/^access_token=/);
});
}
if (params.length) {
result += '?' + params.join('&');
}
return result;
};
RequestManager.prototype.canonicalizeTileset = function canonicalizeTileset(
tileJSON,
sourceURL
) {
var removeAccessToken = sourceURL ? isMapboxURL(sourceURL) : false;
var canonical = [];
for (
var i = 0, list = tileJSON.tiles || [];
i < list.length;
i += 1
) {
var url = list[i];
if (isMapboxHTTPURL(url)) {
canonical.push(
this.canonicalizeTileURL(url, removeAccessToken)
);
} else {
canonical.push(url);
}
}
return canonical;
};
RequestManager.prototype._makeAPIURL = function _makeAPIURL(
urlObject,
accessToken
) {
var help =
'See https://www.mapbox.com/api-documentation/#access-tokens-and-token-scopes';
var apiUrlObject = parseUrl(config.API_URL);
urlObject.protocol = apiUrlObject.protocol;
urlObject.authority = apiUrlObject.authority;
if (apiUrlObject.path !== '/') {
urlObject.path = '' + apiUrlObject.path + urlObject.path;
}
if (!config.REQUIRE_ACCESS_TOKEN) {
return formatUrl(urlObject);
}
accessToken = accessToken || config.ACCESS_TOKEN;
if (!accessToken) {
throw new Error(
'An API access token is required to use Mapbox GL. ' + help
);
}
if (accessToken[0] === 's') {
throw new Error(
'Use a public access token (pk.*) with Mapbox GL, not a secret access token (sk.*). ' +
help
);
}
urlObject.params = urlObject.params.filter(function(d) {
return d.indexOf('access_token') === -1;
});
urlObject.params.push('access_token=' + accessToken);
return formatUrl(urlObject);
};
function isMapboxURL(url) {
return url.indexOf('mapbox:') === 0;
}
var mapboxHTTPURLRe = /^((https?:)?\/\/)?([^\/]+\.)?mapbox\.c(n|om)(\/|\?|$)/i;
function isMapboxHTTPURL(url) {
return mapboxHTTPURLRe.test(url);
}
function hasCacheDefeatingSku(url) {
return url.indexOf('sku=') > 0 && isMapboxHTTPURL(url);
}
function getAccessToken(params) {
for (var i = 0, list = params; i < list.length; i += 1) {
var param = list[i];
var match = param.match(/^access_token=(.*)$/);
if (match) {
return match[1];
}
}
return null;
}
var urlRe = /^(\w+):\/\/([^/?]*)(\/[^?]+)?\??(.+)?/;
function parseUrl(url) {
var parts = url.match(urlRe);
if (!parts) {
throw new Error('Unable to parse URL object');
}
return {
protocol: parts[1],
authority: parts[2],
path: parts[3] || '/',
params: parts[4] ? parts[4].split('&') : []
};
}
function formatUrl(obj) {
var params = obj.params.length ? '?' + obj.params.join('&') : '';
return obj.protocol + '://' + obj.authority + obj.path + params;
}
var telemEventKey = 'mapbox.eventData';
function parseAccessToken(accessToken) {
if (!accessToken) {
return null;
}
var parts = accessToken.split('.');
if (!parts || parts.length !== 3) {
return null;
}
try {
var jsonData = JSON.parse(b64DecodeUnicode(parts[1]));
return jsonData;
} catch (e) {
return null;
}
}
var TelemetryEvent = function TelemetryEvent(type) {
this.type = type;
this.anonId = null;
this.eventData = {};
this.queue = [];
this.pendingRequest = null;
};
TelemetryEvent.prototype.getStorageKey = function getStorageKey(
domain
) {
var tokenData = parseAccessToken(config.ACCESS_TOKEN);
var u = '';
if (tokenData && tokenData['u']) {
u = b64EncodeUnicode(tokenData['u']);
} else {
u = config.ACCESS_TOKEN || '';
}
return domain
? telemEventKey + '.' + domain + ':' + u
: telemEventKey + ':' + u;
};
TelemetryEvent.prototype.fetchEventData = function fetchEventData() {
var isLocalStorageAvailable = storageAvailable('localStorage');
var storageKey = this.getStorageKey();
var uuidKey = this.getStorageKey('uuid');
if (isLocalStorageAvailable) {
try {
var data = self.localStorage.getItem(storageKey);
if (data) {
this.eventData = JSON.parse(data);
}
var uuid = self.localStorage.getItem(uuidKey);
if (uuid) {
this.anonId = uuid;
}
} catch (e) {
warnOnce('Unable to read from LocalStorage');
}
}
};
TelemetryEvent.prototype.saveEventData = function saveEventData() {
var isLocalStorageAvailable = storageAvailable('localStorage');
var storageKey = this.getStorageKey();
var uuidKey = this.getStorageKey('uuid');
if (isLocalStorageAvailable) {
try {
self.localStorage.setItem(uuidKey, this.anonId);
if (Object.keys(this.eventData).length >= 1) {
self.localStorage.setItem(
storageKey,
JSON.stringify(this.eventData)
);
}
} catch (e) {
warnOnce('Unable to write to LocalStorage');
}
}
};
TelemetryEvent.prototype.processRequests = function processRequests(
_
) {};
TelemetryEvent.prototype.postEvent = function postEvent(
timestamp,
additionalPayload,
callback,
customAccessToken
) {
var this$1 = this;
if (!config.EVENTS_URL) {
return;
}
var eventsUrlObject = parseUrl(config.EVENTS_URL);
eventsUrlObject.params.push(
'access_token=' +
(customAccessToken || config.ACCESS_TOKEN || '')
);
var payload = {
event: this.type,
created: new Date(timestamp).toISOString(),
sdkIdentifier: 'mapbox-gl-js',
sdkVersion: version,
skuId: SKU_ID,
userId: this.anonId
};
var finalPayload = additionalPayload
? extend(payload, additionalPayload)
: payload;
var request = {
url: formatUrl(eventsUrlObject),
headers: { 'Content-Type': 'text/plain' },
body: JSON.stringify([finalPayload])
};
this.pendingRequest = postData(request, function(error) {
this$1.pendingRequest = null;
callback(error);
this$1.saveEventData();
this$1.processRequests(customAccessToken);
});
};
TelemetryEvent.prototype.queueRequest = function queueRequest(
event,
customAccessToken
) {
this.queue.push(event);
this.processRequests(customAccessToken);
};
var MapLoadEvent = (function(TelemetryEvent) {
function MapLoadEvent() {
TelemetryEvent.call(this, 'map.load');
this.success = {};
this.skuToken = '';
}
if (TelemetryEvent) MapLoadEvent.__proto__ = TelemetryEvent;
MapLoadEvent.prototype = Object.create(
TelemetryEvent && TelemetryEvent.prototype
);
MapLoadEvent.prototype.constructor = MapLoadEvent;
MapLoadEvent.prototype.postMapLoadEvent = function postMapLoadEvent(
tileUrls,
mapId,
skuToken,
customAccessToken
) {
this.skuToken = skuToken;
if (
(config.EVENTS_URL && customAccessToken) ||
(config.ACCESS_TOKEN &&
Array.isArray(tileUrls) &&
tileUrls.some(function(url) {
return isMapboxURL(url) || isMapboxHTTPURL(url);
}))
) {
this.queueRequest(
{
id: mapId,
timestamp: Date.now()
},
customAccessToken
);
}
};
MapLoadEvent.prototype.processRequests = function processRequests(
customAccessToken
) {
var this$1 = this;
if (this.pendingRequest || this.queue.length === 0) {
return;
}
var ref = this.queue.shift();
var id = ref.id;
var timestamp = ref.timestamp;
if (id && this.success[id]) {
return;
}
if (!this.anonId) {
this.fetchEventData();
}
if (!validateUuid(this.anonId)) {
this.anonId = uuid();
}
this.postEvent(
timestamp,
{ skuToken: this.skuToken },
function(err) {
if (!err) {
if (id) {
this$1.success[id] = true;
}
}
},
customAccessToken
);
};
return MapLoadEvent;
})(TelemetryEvent);
var TurnstileEvent = (function(TelemetryEvent) {
function TurnstileEvent(customAccessToken) {
TelemetryEvent.call(this, 'appUserTurnstile');
this._customAccessToken = customAccessToken;
}
if (TelemetryEvent) TurnstileEvent.__proto__ = TelemetryEvent;
TurnstileEvent.prototype = Object.create(
TelemetryEvent && TelemetryEvent.prototype
);
TurnstileEvent.prototype.constructor = TurnstileEvent;
TurnstileEvent.prototype.postTurnstileEvent = function postTurnstileEvent(
tileUrls,
customAccessToken
) {
if (
config.EVENTS_URL &&
config.ACCESS_TOKEN &&
Array.isArray(tileUrls) &&
tileUrls.some(function(url) {
return isMapboxURL(url) || isMapboxHTTPURL(url);
})
) {
this.queueRequest(Date.now(), customAccessToken);
}
};
TurnstileEvent.prototype.processRequests = function processRequests(
customAccessToken
) {
var this$1 = this;
if (this.pendingRequest || this.queue.length === 0) {
return;
}
if (
!this.anonId ||
!this.eventData.lastSuccess ||
!this.eventData.tokenU
) {
this.fetchEventData();
}
var tokenData = parseAccessToken(config.ACCESS_TOKEN);
var tokenU = tokenData ? tokenData['u'] : config.ACCESS_TOKEN;
var dueForEvent = tokenU !== this.eventData.tokenU;
if (!validateUuid(this.anonId)) {
this.anonId = uuid();
dueForEvent = true;
}
var nextUpdate = this.queue.shift();
if (this.eventData.lastSuccess) {
var lastUpdate = new Date(this.eventData.lastSuccess);
var nextDate = new Date(nextUpdate);
var daysElapsed =
(nextUpdate - this.eventData.lastSuccess) /
(24 * 60 * 60 * 1000);
dueForEvent =
dueForEvent ||
daysElapsed >= 1 ||
daysElapsed < -1 ||
lastUpdate.getDate() !== nextDate.getDate();
} else {
dueForEvent = true;
}
if (!dueForEvent) {
return this.processRequests();
}
this.postEvent(
nextUpdate,
{ 'enabled.telemetry': false },
function(err) {
if (!err) {
this$1.eventData.lastSuccess = nextUpdate;
this$1.eventData.tokenU = tokenU;
}
},
customAccessToken
);
};
return TurnstileEvent;
})(TelemetryEvent);
var turnstileEvent_ = new TurnstileEvent();
var postTurnstileEvent = turnstileEvent_.postTurnstileEvent.bind(
turnstileEvent_
);
var mapLoadEvent_ = new MapLoadEvent();
var postMapLoadEvent = mapLoadEvent_.postMapLoadEvent.bind(
mapLoadEvent_
);
var CACHE_NAME = 'mapbox-tiles';
var cacheLimit = 500;
var cacheCheckThreshold = 50;
var MIN_TIME_UNTIL_EXPIRY = 1000 * 60 * 7;
var sharedCache;
function cacheOpen() {
if (self.caches && !sharedCache) {
sharedCache = self.caches.open(CACHE_NAME);
}
}
var responseConstructorSupportsReadableStream;
function prepareBody(response, callback) {
if (responseConstructorSupportsReadableStream === undefined) {
try {
new Response(new ReadableStream());
responseConstructorSupportsReadableStream = true;
} catch (e) {
responseConstructorSupportsReadableStream = false;
}
}
if (responseConstructorSupportsReadableStream) {
callback(response.body);
} else {
response.blob().then(callback);
}
}
function cachePut(request, response, requestTime) {
cacheOpen();
if (!sharedCache) {
return;
}
var options = {
status: response.status,
statusText: response.statusText,
headers: new self.Headers()
};
response.headers.forEach(function(v, k) {
return options.headers.set(k, v);
});
var cacheControl = parseCacheControl(
response.headers.get('Cache-Control') || ''
);
if (cacheControl['no-store']) {
return;
}
if (cacheControl['max-age']) {
options.headers.set(
'Expires',
new Date(
requestTime + cacheControl['max-age'] * 1000
).toUTCString()
);
}
var timeUntilExpiry =
new Date(options.headers.get('Expires')).getTime() -
requestTime;
if (timeUntilExpiry < MIN_TIME_UNTIL_EXPIRY) {
return;
}
prepareBody(response, function(body) {
var clonedResponse = new self.Response(body, options);
cacheOpen();
if (!sharedCache) {
return;
}
sharedCache
.then(function(cache) {
return cache.put(
stripQueryParameters(request.url),
clonedResponse
);
})
.catch(function(e) {
return warnOnce(e.message);
});
});
}
function stripQueryParameters(url) {
var start = url.indexOf('?');
return start < 0 ? url : url.slice(0, start);
}
function cacheGet(request, callback) {
cacheOpen();
if (!sharedCache) {
return callback(null);
}
var strippedURL = stripQueryParameters(request.url);
sharedCache
.then(function(cache) {
cache
.match(strippedURL)
.then(function(response) {
var fresh = isFresh(response);
cache.delete(strippedURL);
if (fresh) {
cache.put(strippedURL, response.clone());
}
callback(null, response, fresh);
})
.catch(callback);
})
.catch(callback);
}
function isFresh(response) {
if (!response) {
return false;
}
var expires = new Date(response.headers.get('Expires') || 0);
var cacheControl = parseCacheControl(
response.headers.get('Cache-Control') || ''
);
return expires > Date.now() && !cacheControl['no-cache'];
}
var globalEntryCounter = Infinity;
function cacheEntryPossiblyAdded(dispatcher) {
globalEntryCounter++;
if (globalEntryCounter > cacheCheckThreshold) {
dispatcher.getActor().send('enforceCacheSizeLimit', cacheLimit);
globalEntryCounter = 0;
}
}
function enforceCacheSizeLimit(limit) {
cacheOpen();
if (!sharedCache) {
return;
}
sharedCache.then(function(cache) {
cache.keys().then(function(keys) {
for (var i = 0; i < keys.length - limit; i++) {
cache.delete(keys[i]);
}
});
});
}
function clearTileCache(callback) {
var promise = self.caches.delete(CACHE_NAME);
if (callback) {
promise.catch(callback).then(function() {
return callback();
});
}
}
function setCacheLimits(limit, checkThreshold) {
cacheLimit = limit;
cacheCheckThreshold = checkThreshold;
}
var supportsOffscreenCanvas;
function offscreenCanvasSupported() {
if (supportsOffscreenCanvas == null) {
supportsOffscreenCanvas =
self.OffscreenCanvas &&