UNPKG

@nextgis/ngw-map

Version:
1,559 lines (1,459 loc) 347 kB
/** Bundle of @nextgis/ngw-map; version: 3.0.1; author: NextGIS */ var NgwMap = (function (exports) { 'use strict'; const svgPath = { brill: '<path d="m6 0-5 6 5 6 5-6z"/>', circle: '<circle cx="6" cy="6" r="6"/>', rect: '<rect width="12" height="12"/>', marker: '<path d="m6 0c-1.85 0-4 1.19-4 4.22 0 2.05 3.08 6.59 4 7.78 0.821-1.19 4-5.62 4-7.78 0-3.03-2.15-4.22-4-4.22z"/>', cross: '<path d="M 2.4,12 6,8.4 9.6,12 12,9.6 8.4,6 12,2.4 9.6,0 6,3.6 2.4,0 0,2.4 3.6,6 0,9.6 Z"/>', star: '<path d="m6 0.25 1.71 4.18 4.29-1.04e-4 -3.43 3.14 0.857 4.18-3.43-3.14-3.43 3.14 0.857-4.18-3.43-3.14 4.29-0.209z"/>', triangle: '<path d="m12 11.7h-12l6-11.2z"/>', plus: '<path d="m7.5 12v-4.5h4.5v-3h-4.5v-4.5h-3v4.5h-4.5v3h4.5v4.5z"/>', minus: '<path d="m12 7.5v-3h-12v3z"/>', asterisk: '<path d="m7.59 12v-3.27l2.83 1.64 1.58-2.74-2.85-1.64 2.83-1.64-1.56-2.74-2.83 1.64v-3.24h-3.17v3.24l-2.85-1.64-1.57 2.74 2.84 1.64-2.84 1.64 1.57 2.74 2.85-1.64v3.27z"/>' }; const VIEW_BOX = 12; const STROKE = 0.8; function generateSvg({ width, height, stroke = 0, content }) { const s = stroke / 2; const svg = `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="-${s} -${s} ${VIEW_BOX + stroke} ${VIEW_BOX + stroke}" >${content}</svg>`; return svg; } function insertSvg(svg) { const oParser = new DOMParser(); const oDOM = oParser.parseFromString(svg, "image/svg+xml"); return oDOM.documentElement; } function getIcon(opt = {}) { var _a, _b, _c, _d, _e, _f; const shape = (_a = opt.shape) != null ? _a : "circle"; const color = (_b = opt.color) != null ? _b : "blue"; const strokeColor = (_c = opt.strokeColor) != null ? _c : "white"; const size = (_d = opt.size) != null ? _d : VIEW_BOX; const rotate = (_e = opt.rotate) != null ? _e : 0; const anchor = (_f = opt.anchor) != null ? _f : [size / 2, size / 2]; const stroke = opt.stroke !== void 0 ? Number(opt.stroke) : STROKE; const pathAlias = opt.p || svgPath[shape] || "circle"; const path = typeof pathAlias === "string" ? pathAlias : pathAlias(opt); const svg = insertSvg( opt.svg || generateSvg({ width: size, height: size, stroke, content: path }) ); svg.setAttribute("width", String(size)); svg.setAttribute("height", String(size)); svg.setAttribute("fill", color); if (stroke) { svg.setAttribute("stroke", strokeColor); svg.setAttribute("stroke-width", String(stroke)); } const s = new XMLSerializer(); return { type: "icon", iconSize: [size, size], iconAnchor: anchor, html: s.serializeToString(svg), rotate, svg }; } function applyMixins(derivedCtor, baseCtors, opt = {}) { const derivedProperties = allProperties(derivedCtor.prototype); const replace = opt.replace !== void 0 ? opt.replace : true; baseCtors.forEach((baseCtor) => { Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => { const isSomeProp = derivedProperties.indexOf(name) !== -1; if (!replace && !isSomeProp || replace) { const descriptor = Object.getOwnPropertyDescriptor( baseCtor.prototype, name ); if (descriptor) { Object.defineProperty(derivedCtor.prototype, name, descriptor); } } }); }); } function allProperties(obj) { return _allProperties(obj); } function _allProperties(obj, _props = []) { for (; obj !== null; obj = Object.getPrototypeOf(obj)) { const op = Object.getOwnPropertyNames(obj); for (let i = 0; i < op.length; i++) { if (_props.indexOf(op[i]) == -1) { _props.push(op[i]); } } } return _props; } function mixinProperties(derivedCtor, baseCtor, properties) { properties.forEach((name) => { const descriptor = Object.getOwnPropertyDescriptor( baseCtor.prototype, name ); if (descriptor) { Object.defineProperty(derivedCtor.prototype, name, descriptor); } }); } function debounce(cb, wait = 10) { let timeoutId; function wrapper(...args) { wrapper.clear(); timeoutId = setTimeout(() => { timeoutId = null; cb.apply(this, args); }, wait); } wrapper.clear = function() { if (timeoutId) { clearTimeout(timeoutId); timeoutId = null; } }; return wrapper; } function debugLog(message) { { console.trace("DEBUG: " + message); return true; } } function deepmerge(target, src, mergeArray = false) { let target_ = target; const src_ = src; const array = Array.isArray(src_); let dst = array && [] || {}; if (array && Array.isArray(src_)) { if (mergeArray) { target_ = target_ || []; dst = dst.concat(target_); src_.forEach((e, i) => { if (typeof dst[i] === "undefined") { dst[i] = e; } else if (typeof e === "object") { dst[i] = deepmerge(target_[i], e, mergeArray); } else { if (target_.indexOf(e) === -1) { dst.push(e); } } }); } else { dst = src_; } } else { if (target_ && typeof target_ === "object") { Object.keys(target_).forEach(function(key) { dst[key] = target_[key]; }); } Object.keys(src_).forEach(function(key) { if (typeof src_[key] !== "object" || !src_[key]) { dst[key] = src_[key]; } else { if (typeof target_[key] === "object" && typeof src_[key] === "object") { dst[key] = deepmerge(target_[key], src_[key], mergeArray); } else { dst[key] = src_[key]; } } }); } return dst; } function defined(val) { return val !== void 0 && val !== null; } function full(val) { return typeof val === "string" ? !!val : defined(val); } function deprecatedMapClick(ev) { if (!ev.lngLat && ev.latLng) { debugLog("deprecated use of latLng in MapClickEvent, use lngLat instead"); const lat = ev.latLng.lat; const lng = ev.latLng.lng; ev.lngLat = [lng, lat]; } return ev; } function deprecatedWarn(message) { console.warn(`DEPRECATED WARN: ${message}`); } function checkExtent(extent) { const [minLon, minLat, maxLon, maxLat] = extent; const isOrderValid = minLon < maxLon && minLat < maxLat; if (!isOrderValid) { console.log("Error: The extent coordinates are not in the correct order."); console.log( `Received extent: [${minLon}, ${minLat}, ${maxLon}, ${maxLat}]` ); const correctedExtent = [ Math.min(minLon, maxLon), Math.min(minLat, maxLat), Math.max(minLon, maxLon), Math.max(maxLat, minLat) ]; console.log(`Expected order: [${correctedExtent.join(", ")}]`); } const isValidLon = minLon >= -180 && maxLon <= 180; const isValidLat = minLat >= -90 && maxLat <= 90; if (!isValidLon || !isValidLat) { console.log( "Warning: The coordinates may not be within valid geographic ranges." ); } return isOrderValid && isValidLon && isValidLat; } const EARTHS_RADIUS = 6371; function degrees2meters(lng, lat) { lat = lat > 85.06 ? 85.06 : lat < -85.06 ? -85.06 : lat; const x = lng * 2003750834e-2 / 180; let y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180); y = y * 2003750834e-2 / 180; return [x, y]; } function getBoundsPolygon(b) { const polygon = { type: "Polygon", coordinates: [getBoundsCoordinates(b)] }; return polygon; } function getBoundsCoordinates(b) { const westNorth = [b[0], b[1]]; const eastNorth = [b[2], b[1]]; const eastSouth = [b[2], b[3]]; const westSouth = [b[0], b[3]]; return [westNorth, eastNorth, eastSouth, westSouth, westNorth]; } function getBoundsFeature(b) { const feature = { type: "Feature", properties: {}, geometry: getBoundsPolygon(b) }; return feature; } const d2r = Math.PI / 180; const r2d = 180 / Math.PI; function getCirclePolygonCoordinates(lng, lat, radius = 10, points = 6) { const rlat = radius / EARTHS_RADIUS * r2d; const rlng = rlat / Math.cos(lat * d2r); const extp = []; for (let i = 0; i < points + 1; i++) { const theta = Math.PI * (i / (points / 2)); const ex = lng + rlng * Math.cos(theta); const ey = lat + rlat * Math.sin(theta); extp.push([ex, ey]); } return extp; } function getIdentifyRadius(center, zoom, pixelRadius) { pixelRadius = pixelRadius != null ? pixelRadius : 10; const metresPerPixel = 40075016686e-3 * Math.abs(Math.cos(center[1] * 180 / Math.PI)) / Math.pow(2, zoom + 8); const radius = pixelRadius * metresPerPixel * 5e-4; return radius; } function isLngLatBoundsArray(array) { return Array.isArray(array) && array.length === 4 && array.every((x) => typeof x === "number"); } function round(val, toFixed) { const n = 1; return Math.round((val + Number.EPSILON) * n) / n; } function isEqual(a, b, o, p) { if (a instanceof Array) { if (!(b instanceof Array)) return false; return b.sort().join("") === a.sort().join(""); } else if (a instanceof Date) { if (!(b instanceof Date)) return false; return "" + a === "" + b; } else if (a instanceof Function) { if (!(b instanceof Function)) return false; } else if (a instanceof Object) { if (!(b instanceof Object)) return false; if (a === o) { return b === p; } else { return objectDeepEqual(a, b); } } return a === b; } function objectDeepEqual(o, p) { const keysO = Object.keys(o).sort(); const keysP = Object.keys(p).sort(); if (keysO.length !== keysP.length) return false; if (keysO.join("") !== keysP.join("")) return false; for (let i = 0; i < keysO.length; i++) { const oVal = o[keysO[i]]; const pVal = p[keysP[i]]; if (!isEqual(oVal, pVal, o, p)) { return false; } } return true; } function objectRemoveEmpty(obj) { const newObj = {}; Object.keys(obj).forEach((key) => { if (!(obj[key] instanceof Array) && obj[key] === Object(obj[key])) { newObj[key] = objectRemoveEmpty(obj[key]); } else if (obj[key] !== void 0) { newObj[key] = obj[key]; } }); return newObj; } function isObject$1(val) { return Object.prototype.toString.call(val) === "[object Object]"; } function isArray(val) { return Object.prototype.toString.call(val) === "[object Array]"; } function fixUrlStr(url) { return url.replace(/([^:]\/)\/+/g, "$1"); } const templateRe = /\{ *([\w_-]+) *\}/g; function template(str, data) { return str.replace(templateRe, (s, key) => { let value = data[key]; if (value === void 0) { throw new Error("No value provided for letiable " + s); } else if (typeof value === "function") { value = value(data); } return value; }); } var __defProp$R = Object.defineProperty; var __getOwnPropSymbols$z = Object.getOwnPropertySymbols; var __hasOwnProp$z = Object.prototype.hasOwnProperty; var __propIsEnum$z = Object.prototype.propertyIsEnumerable; var __defNormalProp$R = (obj, key, value) => key in obj ? __defProp$R(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$y = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$z.call(b, prop)) __defNormalProp$R(a, prop, b[prop]); if (__getOwnPropSymbols$z) for (var prop of __getOwnPropSymbols$z(b)) { if (__propIsEnum$z.call(b, prop)) __defNormalProp$R(a, prop, b[prop]); } return a; }; var __async$w = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; function apiRequest(opt) { return __async$w(this, null, function* () { const { params, name, connector, requestOptions } = opt; const apiItems = yield connector.connect(); let apiItem = apiItems && apiItems[name]; if (apiItem) { apiItem = [...apiItem]; let url = apiItem.shift(); if (apiItem.length) { const replaceParams = {}; for (let fry = 0; fry < apiItem.length; fry++) { const arg = apiItem[fry]; replaceParams[fry] = `{${arg}}`; if (params[arg] === void 0) { throw new Error(`\`${arg}\` URL API argument is not specified`); } } if (url) { url = template(url, replaceParams); } } if (params) { const paramArray = []; const paramList = params.paramList; if (Array.isArray(paramList)) { paramList.forEach(([key, value]) => { paramArray.push(`${key}=${value}`); }); } for (const p in params) { if (apiItem.indexOf(p) === -1) { paramArray.push(`${p}=${params[p]}`); } } if (paramArray.length) { url = `${url}?${paramArray.join("&")}`; } } if (url) { return connector.makeQuery(url, params, __spreadValues$y({ cacheName: name }, requestOptions)); } else { throw new Error("Request URL is not set"); } } else { return void 0; } }); } var __defProp$Q = Object.defineProperty; var __defNormalProp$Q = (obj, key, value) => key in obj ? __defProp$Q(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$A = (obj, key, value) => __defNormalProp$Q(obj, typeof key !== "symbol" ? key + "" : key, value); const _Cache = class _Cache { constructor(options = {}) { __publicField$A(this, "cache", []); var _a; const namespace = (_a = options.namespace) != null ? _a : "default"; if (_Cache.instance[namespace]) { return _Cache.instance[namespace]; } _Cache.instance[namespace] = this; return this; } clean() { this.cache.length = 0; } all() { return this.cache; } /** * Caching only a non-empty value. * * Useful for get or create strategy * @example * ```javascript * const cache = new Cache(); * const getItemFunc = () => fetch(url).then((data) => { * return data.json(); // undefined * }); * const item = await cache.addFull('foo', getItemFunc); * if (!item) { * await createItem(); // 'New item' * } * * // somewhere else in the code * const item = await cache.addFull('foo', getItemFunc).then((resp) => { * console.log(resp); // 'New item' * }); * ``` */ addFull(key, valueToSet, propsOrOptions, expirationTime) { if (typeof propsOrOptions === "object" && "valueToSet" in propsOrOptions) { propsOrOptions.onlyFull = true; } return this.add(key, valueToSet, propsOrOptions, true, expirationTime); } add(key, valueToSet, propsOrOptions, onlyFull, expirationTime) { let opt; let props; if (typeof propsOrOptions === "object" && "valueToSet" in propsOrOptions) { opt = propsOrOptions; onlyFull = opt.onlyFull; expirationTime = opt.expirationTime; props = opt.props; } else { props = propsOrOptions; } const exist = this._find(key, props); if (!exist) { let value; if (valueToSet instanceof Function) { value = valueToSet(); } else { value = valueToSet; } const nonEmptyProps = props && JSON.parse(JSON.stringify(objectRemoveEmpty(props))); expirationTime = expirationTime ? Date.now() + expirationTime : void 0; const cacheItem = { key, value, props: nonEmptyProps, expirationTime }; if (onlyFull && !full(value)) { return value; } this.cache.push(cacheItem); if (value instanceof Promise) { value.catch(() => { this.delete(key, props); }); if (onlyFull) { value.then((x) => { if (!full(x)) { this.delete(key, props); } return x; }); } return value; } return value; } else { return exist.value; } } match(key, props) { const cacheRecord = this._find(key, props); if (cacheRecord && cacheRecord.expirationTime && Date.now() > cacheRecord.expirationTime) { this.delete(cacheRecord); return void 0; } return cacheRecord == null ? void 0 : cacheRecord.value; } matchAll(key, props) { const now = Date.now(); this.cache.forEach((item) => { if (item.expirationTime && now > item.expirationTime) { this.delete(item); } }); if (key) { return this.cache.filter((x) => this._filter(x, key, props)).map((x) => x.value); } return this.cache.map((x) => x.value); } delete(keyOrItem, props) { const itemsToDelete = typeof keyOrItem === "string" ? this.cache.filter((x) => this._filter(x, keyOrItem, props)) : [keyOrItem]; for (const item of itemsToDelete) { const index = this.cache.indexOf(item); if (index !== -1) { this.cache.splice(index, 1); } } } _find(key, props) { return this.cache.find((x) => this._filter(x, key, props)); } _filter(item, key, props) { if (item.key !== key) return false; if (!props) return true; const itemProps = item.props; return objectDeepEqual(itemProps || {}, objectRemoveEmpty(props)); } }; __publicField$A(_Cache, "instance", {}); let Cache = _Cache; var domain; // This constructor is used to store event handlers. Instantiating this is // faster than explicitly calling `Object.create(null)` to get a "clean" empty // object (tested with v8 v4.9). function EventHandlers() {} EventHandlers.prototype = Object.create(null); function EventEmitter() { EventEmitter.init.call(this); } // nodejs oddity // require('events') === require('events').EventEmitter EventEmitter.EventEmitter = EventEmitter; EventEmitter.usingDomains = false; EventEmitter.prototype.domain = undefined; EventEmitter.prototype._events = undefined; EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. EventEmitter.defaultMaxListeners = 10; EventEmitter.init = function() { this.domain = null; if (EventEmitter.usingDomains) { // if there is an active domain, then attach to it. if (domain.active) ; } if (!this._events || this._events === Object.getPrototypeOf(this)._events) { this._events = new EventHandlers(); this._eventsCount = 0; } this._maxListeners = this._maxListeners || undefined; }; // Obviously not all Emitters should be limited to 10. This function allows // that to be increased. Set to zero for unlimited. EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { if (typeof n !== 'number' || n < 0 || isNaN(n)) throw new TypeError('"n" argument must be a positive number'); this._maxListeners = n; return this; }; function $getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { return $getMaxListeners(this); }; // These standalone emit* functions are used to optimize calling of event // handlers for fast cases because emit() itself often has a variable number of // arguments and can be deoptimized because of that. These functions always have // the same number of arguments and thus do not get deoptimized, so the code // inside them can execute faster. function emitNone(handler, isFn, self) { if (isFn) handler.call(self); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self); } } function emitOne(handler, isFn, self, arg1) { if (isFn) handler.call(self, arg1); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self, arg1); } } function emitTwo(handler, isFn, self, arg1, arg2) { if (isFn) handler.call(self, arg1, arg2); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self, arg1, arg2); } } function emitThree(handler, isFn, self, arg1, arg2, arg3) { if (isFn) handler.call(self, arg1, arg2, arg3); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].call(self, arg1, arg2, arg3); } } function emitMany(handler, isFn, self, args) { if (isFn) handler.apply(self, args); else { var len = handler.length; var listeners = arrayClone(handler, len); for (var i = 0; i < len; ++i) listeners[i].apply(self, args); } } EventEmitter.prototype.emit = function emit(type) { var er, handler, len, args, i, events, domain; var doError = (type === 'error'); events = this._events; if (events) doError = (doError && events.error == null); else if (!doError) return false; domain = this.domain; // If there is no 'error' event listener then throw. if (doError) { er = arguments[1]; if (domain) { if (!er) er = new Error('Uncaught, unspecified "error" event'); er.domainEmitter = this; er.domain = domain; er.domainThrown = false; domain.emit('error', er); } else if (er instanceof Error) { throw er; // Unhandled 'error' event } else { // At least give some kind of context to the user var err = new Error('Uncaught, unspecified "error" event. (' + er + ')'); err.context = er; throw err; } return false; } handler = events[type]; if (!handler) return false; var isFn = typeof handler === 'function'; len = arguments.length; switch (len) { // fast cases case 1: emitNone(handler, isFn, this); break; case 2: emitOne(handler, isFn, this, arguments[1]); break; case 3: emitTwo(handler, isFn, this, arguments[1], arguments[2]); break; case 4: emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); break; // slower default: args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; emitMany(handler, isFn, this, args); } return true; }; function _addListener(target, type, listener, prepend) { var m; var events; var existing; if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); events = target._events; if (!events) { events = target._events = new EventHandlers(); target._eventsCount = 0; } else { // To avoid recursion in the case that type === "newListener"! Before // adding it to the listeners, first emit "newListener". if (events.newListener) { target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the // this._events to be assigned to a new object events = target._events; } existing = events[type]; } if (!existing) { // Optimize the case of one listener. Don't need the extra array object. existing = events[type] = listener; ++target._eventsCount; } else { if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; } else { // If we've already got an array, just append. if (prepend) { existing.unshift(listener); } else { existing.push(listener); } } // Check for listener leak if (!existing.warned) { m = $getMaxListeners(target); if (m && m > 0 && existing.length > m) { existing.warned = true; var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + type + ' listeners added. ' + 'Use emitter.setMaxListeners() to increase limit'); w.name = 'MaxListenersExceededWarning'; w.emitter = target; w.type = type; w.count = existing.length; emitWarning(w); } } } return target; } function emitWarning(e) { typeof console.warn === 'function' ? console.warn(e) : console.log(e); } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.prependListener = function prependListener(type, listener) { return _addListener(this, type, listener, true); }; function _onceWrap(target, type, listener) { var fired = false; function g() { target.removeListener(type, g); if (!fired) { fired = true; listener.apply(target, arguments); } } g.listener = listener; return g; } EventEmitter.prototype.once = function once(type, listener) { if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; // emits a 'removeListener' event iff the listener was removed EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); events = this._events; if (!events) return this; list = events[type]; if (!list) return this; if (list === listener || (list.listener && list.listener === listener)) { if (--this._eventsCount === 0) this._events = new EventHandlers(); else { delete events[type]; if (events.removeListener) this.emit('removeListener', type, list.listener || listener); } } else if (typeof list !== 'function') { position = -1; for (i = list.length; i-- > 0;) { if (list[i] === listener || (list[i].listener && list[i].listener === listener)) { originalListener = list[i].listener; position = i; break; } } if (position < 0) return this; if (list.length === 1) { list[0] = undefined; if (--this._eventsCount === 0) { this._events = new EventHandlers(); return this; } else { delete events[type]; } } else { spliceOne(list, position); } if (events.removeListener) this.emit('removeListener', type, originalListener || listener); } return this; }; // Alias for removeListener added in NodeJS 10.0 // https://nodejs.org/api/events.html#events_emitter_off_eventname_listener EventEmitter.prototype.off = function(type, listener){ return this.removeListener(type, listener); }; EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { var listeners, events; events = this._events; if (!events) return this; // not listening for removeListener, no need to emit if (!events.removeListener) { if (arguments.length === 0) { this._events = new EventHandlers(); this._eventsCount = 0; } else if (events[type]) { if (--this._eventsCount === 0) this._events = new EventHandlers(); else delete events[type]; } return this; } // emit removeListener for all listeners on all events if (arguments.length === 0) { var keys = Object.keys(events); for (var i = 0, key; i < keys.length; ++i) { key = keys[i]; if (key === 'removeListener') continue; this.removeAllListeners(key); } this.removeAllListeners('removeListener'); this._events = new EventHandlers(); this._eventsCount = 0; return this; } listeners = events[type]; if (typeof listeners === 'function') { this.removeListener(type, listeners); } else if (listeners) { // LIFO order do { this.removeListener(type, listeners[listeners.length - 1]); } while (listeners[0]); } return this; }; EventEmitter.prototype.listeners = function listeners(type) { var evlistener; var ret; var events = this._events; if (!events) ret = []; else { evlistener = events[type]; if (!evlistener) ret = []; else if (typeof evlistener === 'function') ret = [evlistener.listener || evlistener]; else ret = unwrapListeners(evlistener); } return ret; }; EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { return listenerCount.call(emitter, type); } }; EventEmitter.prototype.listenerCount = listenerCount; function listenerCount(type) { var events = this._events; if (events) { var evlistener = events[type]; if (typeof evlistener === 'function') { return 1; } else if (evlistener) { return evlistener.length; } } return 0; } EventEmitter.prototype.eventNames = function eventNames() { return this._eventsCount > 0 ? Reflect.ownKeys(this._events) : []; }; // About 1.5x faster than the two-arg version of Array#splice(). function spliceOne(list, index) { for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) list[i] = list[k]; list.pop(); } function arrayClone(arr, i) { var copy = new Array(i); while (i--) copy[i] = arr[i]; return copy; } function unwrapListeners(arr) { var ret = new Array(arr.length); for (var i = 0; i < ret.length; ++i) { ret[i] = arr[i].listener || arr[i]; } return ret; } var pkg = { name: "@nextgis/ngw-connector", version: "3.0.1", _priority: 12, description: "A lightweight HTTP client optimized for use with NextGIS Web API", main: "index.js", module: "lib/ngw-connector.esm-bundler.js", unpkg: "lib/ngw-connector.global.prod.js", jsdelivr: "lib/ngw-connector.global.prod.js", types: "lib/index.d.ts", dependencies: { "@nextgis/cache": "3.0.0", "@nextgis/cancelable-promise": "3.0.0", "@nextgis/utils": "3.0.0", "@types/events": "^3.0.0", events: "*", "form-data": "^4.0.0" }, devDependencies: { "@nextgis/build-tools": "3.0.0" }, scripts: { clean: "rimraf ./lib", dev: "node ../build-tools/lib/build.js", prod: "npm run dev -- --release", lint: "eslint ./src/**/*.ts --fix --c ../../.eslintrc", watch: "npm run dev -- --watch", "gen:types": "node ./scripts/generator" }, buildOptions: { name: "NgwConnector", formats: [ "esm-bundler", "esm-browser", "cjs", "global" ] }, keywords: [ "NextGIS", "MAP" ], author: "NextGIS", files: [ "index.js", "lib" ], license: "MIT", homepage: "https://github.com/nextgis/nextgis_frontend/tree/master/packages/ngw-connector#readme", repository: { type: "git", url: "git://github.com/nextgis/nextgis_frontend.git" }, engines: { node: ">=18.20.4" }, gitHead: "edc68033f914f6c95c4125b9738bba6d36e990b4" }; class AbortError extends Error { constructor(message = "AbortError") { super(message); this.name = "AbortError"; } } var __defProp$P = Object.defineProperty; var __defNormalProp$P = (obj, key, value) => key in obj ? __defProp$P(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$z = (obj, key, value) => __defNormalProp$P(obj, typeof key !== "symbol" ? key + "" : key, value); class NgwError extends Error { constructor(er) { super(); __publicField$z(this, "name", "NgwError"); __publicField$z(this, "title"); __publicField$z(this, "message"); __publicField$z(this, "detail"); __publicField$z(this, "exception"); __publicField$z(this, "status_code"); __publicField$z(this, "data"); __publicField$z(this, "guru_meditation"); Object.assign(this, er); Object.setPrototypeOf(this, NgwError.prototype); } } var __defProp$O = Object.defineProperty; var __defNormalProp$O = (obj, key, value) => key in obj ? __defProp$O(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$y = (obj, key, value) => __defNormalProp$O(obj, typeof key !== "symbol" ? key + "" : key, value); class InsufficientPermissionsError extends NgwError { constructor(obj) { super(obj); __publicField$y(this, "name", "InsufficientPermissionsError"); __publicField$y(this, "exception", "nextgisweb.core.exception.InsufficientPermissions"); Object.setPrototypeOf(this, InsufficientPermissionsError.prototype); } } var __defProp$N = Object.defineProperty; var __defNormalProp$N = (obj, key, value) => key in obj ? __defProp$N(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$x = (obj, key, value) => __defNormalProp$N(obj, typeof key !== "symbol" ? key + "" : key, value); let NetworksResponseError$1 = class NetworksResponseError extends NgwError { constructor(obj) { super(obj); __publicField$x(this, "message", "There is no response from the server or problem connecting to server."); __publicField$x(this, "title", "Network error"); __publicField$x(this, "detail", "Check network connectivity and try again later."); Object.setPrototypeOf(this, NetworksResponseError.prototype); } }; function extractError(error) { if (isObject$1(error)) { if (error.name && error.message && error.title) { return { title: error.title, message: error.message, detail: error.detail || null, data: error.data && error.data.data ? error.data.data : null }; } else if (error.exception) { if (error.status === void 0 || error.status === 0 || error.data === void 0) { return new NetworksResponseError$1({ title: error.title, status_code: error.status_code, exception: error.exception }); } } return { title: typeof error.title === "string" ? error.title : "Unexpected error", message: typeof error.message === "string" ? error.message : "Something went wrong." }; } } function isError(error) { if (isObject$1(error)) { return error.status_code && error.exception && error.title; } return false; } var __defProp$M = Object.defineProperty; var __defNormalProp$M = (obj, key, value) => key in obj ? __defProp$M(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$w = (obj, key, value) => __defNormalProp$M(obj, key + "" , value); class NetworkError extends Error { constructor(url) { super(); __publicField$w(this, "name", "NetworkError"); Object.setPrototypeOf(this, NetworkError.prototype); this.message = `Unable to request ${url}. Possibly invalid NGW URL entered or CORS not configured to get request from ${location.origin}`; } } var __defProp$L = Object.defineProperty; var __defNormalProp$L = (obj, key, value) => key in obj ? __defProp$L(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$v = (obj, key, value) => __defNormalProp$L(obj, typeof key !== "symbol" ? key + "" : key, value); class ResourceNotFoundError extends NgwError { constructor(obj) { super(obj); __publicField$v(this, "name", "ResourceNotFoundError"); __publicField$v(this, "exception", "nextgisweb.resource.exception.ResourceNotFound"); Object.setPrototypeOf(this, ResourceNotFoundError.prototype); } } var errors = /*#__PURE__*/Object.freeze({ __proto__: null, AbortError: AbortError, InsufficientPermissionsError: InsufficientPermissionsError, NetworkError: NetworkError, NetworksResponseError: NetworksResponseError$1, NgwError: NgwError, ResourceNotFoundError: ResourceNotFoundError, extractError: extractError, isError: isError }); var __defProp$K = Object.defineProperty; var __defNormalProp$K = (obj, key, value) => key in obj ? __defProp$K(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$u = (obj, key, value) => __defNormalProp$K(obj, typeof key !== "symbol" ? key + "" : key, value); class BaseAPIError extends Error { constructor(message) { super(message || "Something went wrong."); __publicField$u(this, "title"); this.name = "BaseAPIError"; this.title = "Unknown API error"; if (Error.captureStackTrace) { Error.captureStackTrace(this, BaseAPIError); } } } class NetworksResponseError extends BaseAPIError { // prettier-ignore constructor(message) { super(message || "There is no response from the server or problem connecting to server."); __publicField$u(this, "detail"); this.title = "Network error"; this.detail = "Check network connectivity and try again later."; } } class InvalidResponseError extends BaseAPIError { constructor(message) { super(message || "Something went wrong."); this.title = "Unexpected server response"; } } class ServerResponseError extends BaseAPIError { constructor(data) { super(data.message); __publicField$u(this, "detail"); __publicField$u(this, "data"); this.title = data.title || this.title; this.detail = data.detail || null; this.data = data; } } class LunkwillError extends Error { // prettier-ignore constructor(message, data = {}) { super(message || "Unexpected error while processing long-running request."); __publicField$u(this, "title"); __publicField$u(this, "data"); this.name = "LunkwillError"; this.title = "Long-running request error"; this.data = data; if (Error.captureStackTrace) { Error.captureStackTrace(this, LunkwillError); } } } class LunkwillRequestCancelled extends LunkwillError { constructor(data) { super("Long-running request was cancelled.", data); } } class LunkwillRequestFailed extends LunkwillError { constructor(data) { super(void 0, data); } } var __defProp$J = Object.defineProperty; var __getOwnPropSymbols$y = Object.getOwnPropertySymbols; var __hasOwnProp$y = Object.prototype.hasOwnProperty; var __propIsEnum$y = Object.prototype.propertyIsEnumerable; var __defNormalProp$J = (obj, key, value) => key in obj ? __defProp$J(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$x = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$y.call(b, prop)) __defNormalProp$J(a, prop, b[prop]); if (__getOwnPropSymbols$y) for (var prop of __getOwnPropSymbols$y(b)) { if (__propIsEnum$y.call(b, prop)) __defNormalProp$J(a, prop, b[prop]); } return a; }; var __objRest$5 = (source, exclude) => { var target = {}; for (var prop in source) if (__hasOwnProp$y.call(source, prop) && exclude.indexOf(prop) < 0) target[prop] = source[prop]; if (source != null && __getOwnPropSymbols$y) for (var prop of __getOwnPropSymbols$y(source)) { if (exclude.indexOf(prop) < 0 && __propIsEnum$y.call(source, prop)) target[prop] = source[prop]; } return target; }; var __async$v = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; function lunkwillCheckResponse(lwResp) { const ct = lwResp.headers.get("content-type"); return ct !== void 0 && ct !== null && ct.includes("application/vnd.lunkwill.request-summary+json"); } function responseJson(response) { return __async$v(this, null, function* () { try { return response.json(); } catch (e) { throw new Error(); } }); } function lunkwillResponseUrl(lwResp) { return __async$v(this, null, function* () { const lwData = yield responseJson(lwResp); let delay = lwData.delay_ms; const retry = lwData.retry_ms !== void 0 ? lwData.retry_ms : 2e3; const sum = `/api/lunkwill/${lwData.id}/summary`; const res = `/api/lunkwill/${lwData.id}/response`; const sleep = (msec) => new Promise((resolve) => setTimeout(resolve, msec)); let failed = false; let ready = false; while (!ready) { yield sleep(failed ? retry : delay); failed = false; let lwResp2; let lwData2; try { lwResp2 = yield fetch(sum, { credentials: "same-origin" }); lwData2 = yield lwResp2.json(); } catch (e) { failed = true; continue; } switch (lwData2.status) { case void 0: throw new LunkwillError(void 0, lwData2); case "ready": ready = true; break; case "cancelled": throw new LunkwillRequestCancelled(lwData2); case "failed": throw new LunkwillRequestFailed(lwData2); case "spooled": case "processing": case "buffering": delay = lwData2.delay_ms; break; default: throw new LunkwillError(void 0, lwData2); } } return res; }); } function lunkwillFetch(lwRespUrl) { return __async$v(this, null, function* () { try { return yield window.fetch(lwRespUrl, { credentials: "same-origin" }); } catch (e) { throw new NetworksResponseError(); } }); } const mediaContentTypes = [ "application/pdf", "image/png", "image/jpeg", "image/tiff", "text/csv" ]; const mediaContentTypesRegex = new RegExp(mediaContentTypes.join("|")); function isMediaContentType(contentType) { return mediaContentTypesRegex.test(contentType); } function encodeQueryParams(value) { const result = []; for (const [k, v] of Object.entries(value)) { if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") { result.push(`${k}=${encodeURIComponent(v)}`); } else if (Array.isArray(v)) { result.push(`${k}=${v.map(encodeURIComponent).join(",")}`); } else { for (const [sk, sv] of Object.entries(v)) { const ske = `${k}[${encodeURIComponent(sk)}]`; if (typeof sv === "string" || typeof sv === "number" || typeof sv === "boolean") { result.push(`${ske}=${encodeURIComponent(sv)}`); } else if (Array.isArray(sv)) { const sve = sv.map(encodeURIComponent); result.push(`${ske}=${sve.join(",")}`); } } } } return result.join("&"); } function generateUrl(path, query) { let urlParams = ""; if (query !== void 0) { urlParams = "?" + encodeQueryParams(query); } return path + urlParams; } function request(path, options, cacheEngine) { return __async$v(this, null, function* () { var _b, _c; const defaults = { method: "GET", credentials: "same-origin", headers: {} }; const _a = __spreadValues$x(__spreadValues$x({}, defaults), options), { withCredentials, responseType, cacheProps, cacheName, lunkwill, cache, query, json } = _a, opt = __objRest$5(_a, [ "withCredentials", "responseType", "cacheProps", "cacheName", "lunkwill", "cache", "query", "json" ]); opt.method = (_b = opt.method) == null ? void 0 : _b.toUpperCase(); if (withCredentials) { opt.credentials = "include"; } let useLunkwill = false; if (lunkwill !== void 0) { lunkwill.toHeaders(opt.headers || {}); useLunkwill = true; } const lunkwillReturnUrl = !!opt.lunkwillReturnUrl; delete opt.lunkwillReturnUrl; if (json !== void 0) { opt.body = JSON.stringify(json); const headers = opt.headers || {}; headers["Content-Type"] = "application/json"; opt.headers = headers; } const url = generateUrl(path, query); const makeRequest = () => __async$v(null, null, function* () { let response; try { response = yield fetch(url, opt); } catch (e) { if (opt.signal && opt.signal.aborted) { throw e; } throw new NetworksResponseError(); } if (useLunkwill && lunkwillCheckResponse(response)) { const lwRespUrl = yield lunkwillResponseUrl(response); if (lunkwillReturnUrl) { return lwRespUrl; } response = yield lunkwillFetch(lwRespUrl); } const respCType = response.headers.get("content-type"); const respJSON = respCType && (respCType.includes("application/json") || respCType.includes("application/vnd.lunkwill.request-summary+json")); let body; try { const respMedia = respCType && isMediaContentType(respCType); if (responseType === "blob" || respMedia) { body = yield response.blob(); } else if (respJSON) { body = yield response.json(); } else { throw new InvalidResponseError(); } } catch (e) { if (e.name === "AbortError" || e instanceof InvalidResponseError) { throw e; } throw new InvalidResponseError(); } if (400 <= response.status && response.status <= 599) { throw new ServerResponseError(body); } return body; }); if (cacheEngine) { if (((_c = opt.method) == null ? void 0 : _c.toUpperCase()) === "GET") { if (cache !== false) { const props = cacheProps ? cacheProps : __spreadValues$x({}, objectRemoveEmpty({ withCredentials, responseType })); return cacheEngine.add(cacheName || url, makeRequest, { props, expirationTim