(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['deck'] = factory(); else root['deck'] = factory();})(globalThis, function () { "use strict"; var __exports__ = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __commonJS = (cb, mod3) => function __require() { return mod3 || (0, cb[__getOwnPropNames(cb)[0]])((mod3 = { exports: {} }).exports, mod3), mod3.exports; }; var __export = (target, all) => { for (var name2 in all) __defProp(target, name2, { get: all[name2], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod3, isNodeMode, target) => (target = mod3 != null ? __create(__getProtoOf(mod3)) : {}, __copyProps( isNodeMode || !mod3 || !mod3.__esModule ? __defProp(target, "default", { value: mod3, enumerable: true }) : target, mod3 )); var __toCommonJS = (mod3) => __copyProps(__defProp({}, "__esModule", { value: true }), mod3); var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; // ../../node_modules/hammerjs/hammer.js var require_hammer = __commonJS({ "../../node_modules/hammerjs/hammer.js"(exports, module) { (function(window2, document2, exportName, undefined2) { "use strict"; var VENDOR_PREFIXES = ["", "webkit", "Moz", "MS", "ms", "o"]; var TEST_ELEMENT = document2.createElement("div"); var TYPE_FUNCTION = "function"; var round6 = Math.round; var abs = Math.abs; var now = Date.now; function setTimeoutContext(fn, timeout, context) { return setTimeout(bindFn(fn, context), timeout); } function invokeArrayArg(arg, fn, context) { if (Array.isArray(arg)) { each(arg, context[fn], context); return true; } return false; } function each(obj, iterator, context) { var i; if (!obj) { return; } if (obj.forEach) { obj.forEach(iterator, context); } else if (obj.length !== undefined2) { i = 0; while (i < obj.length) { iterator.call(context, obj[i], i, obj); i++; } } else { for (i in obj) { obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj); } } } function deprecate(method, name2, message2) { var deprecationMessage = "DEPRECATED METHOD: " + name2 + "\n" + message2 + " AT \n"; return function() { var e2 = new Error("get-stack-trace"); var stack = e2 && e2.stack ? e2.stack.replace(/^[^\(]+?[\n$]/gm, "").replace(/^\s+at\s+/gm, "").replace(/^Object.\s*\(/gm, "{anonymous}()@") : "Unknown Stack Trace"; var log3 = window2.console && (window2.console.warn || window2.console.log); if (log3) { log3.call(window2.console, deprecationMessage, stack); } return method.apply(this, arguments); }; } var assign; if (typeof Object.assign !== "function") { assign = function assign2(target) { if (target === undefined2 || target === null) { throw new TypeError("Cannot convert undefined or null to object"); } var output = Object(target); for (var index2 = 1; index2 < arguments.length; index2++) { var source = arguments[index2]; if (source !== undefined2 && source !== null) { for (var nextKey in source) { if (source.hasOwnProperty(nextKey)) { output[nextKey] = source[nextKey]; } } } } return output; }; } else { assign = Object.assign; } var extend = deprecate(function extend2(dest, src, merge2) { var keys = Object.keys(src); var i = 0; while (i < keys.length) { if (!merge2 || merge2 && dest[keys[i]] === undefined2) { dest[keys[i]] = src[keys[i]]; } i++; } return dest; }, "extend", "Use `assign`."); var merge = deprecate(function merge2(dest, src) { return extend(dest, src, true); }, "merge", "Use `assign`."); function inherit(child, base, properties) { var baseP = base.prototype, childP; childP = child.prototype = Object.create(baseP); childP.constructor = child; childP._super = baseP; if (properties) { assign(childP, properties); } } function bindFn(fn, context) { return function boundFn() { return fn.apply(context, arguments); }; } function boolOrFn(val, args) { if (typeof val == TYPE_FUNCTION) { return val.apply(args ? args[0] || undefined2 : undefined2, args); } return val; } function ifUndefined(val1, val2) { return val1 === undefined2 ? val2 : val1; } function addEventListeners(target, types, handler) { each(splitStr(types), function(type) { target.addEventListener(type, handler, false); }); } function removeEventListeners(target, types, handler) { each(splitStr(types), function(type) { target.removeEventListener(type, handler, false); }); } function hasParent(node, parent) { while (node) { if (node == parent) { return true; } node = node.parentNode; } return false; } function inStr(str5, find) { return str5.indexOf(find) > -1; } function splitStr(str5) { return str5.trim().split(/\s+/g); } function inArray(src, find, findByKey) { if (src.indexOf && !findByKey) { return src.indexOf(find); } else { var i = 0; while (i < src.length) { if (findByKey && src[i][findByKey] == find || !findByKey && src[i] === find) { return i; } i++; } return -1; } } function toArray(obj) { return Array.prototype.slice.call(obj, 0); } function uniqueArray(src, key, sort) { var results = []; var values = []; var i = 0; while (i < src.length) { var val = key ? src[i][key] : src[i]; if (inArray(values, val) < 0) { results.push(src[i]); } values[i] = val; i++; } if (sort) { if (!key) { results = results.sort(); } else { results = results.sort(function sortUniqueArray(a, b) { return a[key] > b[key]; }); } } return results; } function prefixed(obj, property) { var prefix, prop; var camelProp = property[0].toUpperCase() + property.slice(1); var i = 0; while (i < VENDOR_PREFIXES.length) { prefix = VENDOR_PREFIXES[i]; prop = prefix ? prefix + camelProp : property; if (prop in obj) { return prop; } i++; } return undefined2; } var _uniqueId = 1; function uniqueId() { return _uniqueId++; } function getWindowForElement(element) { var doc = element.ownerDocument || element; return doc.defaultView || doc.parentWindow || window2; } var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i; var SUPPORT_TOUCH = "ontouchstart" in window2; var SUPPORT_POINTER_EVENTS = prefixed(window2, "PointerEvent") !== undefined2; var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); var INPUT_TYPE_TOUCH = "touch"; var INPUT_TYPE_PEN = "pen"; var INPUT_TYPE_MOUSE = "mouse"; var INPUT_TYPE_KINECT = "kinect"; var COMPUTE_INTERVAL = 25; var INPUT_START2 = 1; var INPUT_MOVE2 = 2; var INPUT_END2 = 4; var INPUT_CANCEL = 8; var DIRECTION_NONE = 1; var DIRECTION_LEFT = 2; var DIRECTION_RIGHT = 4; var DIRECTION_UP = 8; var DIRECTION_DOWN = 16; var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; var PROPS_XY = ["x", "y"]; var PROPS_CLIENT_XY = ["clientX", "clientY"]; function Input2(manager, callback) { var self2 = this; this.manager = manager; this.callback = callback; this.element = manager.element; this.target = manager.options.inputTarget; this.domHandler = function(ev) { if (boolOrFn(manager.options.enable, [manager])) { self2.handler(ev); } }; this.init(); } Input2.prototype = { handler: function() { }, init: function() { this.evEl && addEventListeners(this.element, this.evEl, this.domHandler); this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler); this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); }, destroy: function() { this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler); this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler); this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); } }; function createInputInstance(manager) { var Type2; var inputClass = manager.options.inputClass; if (inputClass) { Type2 = inputClass; } else if (SUPPORT_POINTER_EVENTS) { Type2 = PointerEventInput2; } else if (SUPPORT_ONLY_TOUCH) { Type2 = TouchInput; } else if (!SUPPORT_TOUCH) { Type2 = MouseInput2; } else { Type2 = TouchMouseInput; } return new Type2(manager, inputHandler); } function inputHandler(manager, eventType, input) { var pointersLen = input.pointers.length; var changedPointersLen = input.changedPointers.length; var isFirst = eventType & INPUT_START2 && pointersLen - changedPointersLen === 0; var isFinal = eventType & (INPUT_END2 | INPUT_CANCEL) && pointersLen - changedPointersLen === 0; input.isFirst = !!isFirst; input.isFinal = !!isFinal; if (isFirst) { manager.session = {}; } input.eventType = eventType; computeInputData(manager, input); manager.emit("hammer.input", input); manager.recognize(input); manager.session.prevInput = input; } function computeInputData(manager, input) { var session = manager.session; var pointers = input.pointers; var pointersLength = pointers.length; if (!session.firstInput) { session.firstInput = simpleCloneInputData(input); } if (pointersLength > 1 && !session.firstMultiple) { session.firstMultiple = simpleCloneInputData(input); } else if (pointersLength === 1) { session.firstMultiple = false; } var firstInput = session.firstInput; var firstMultiple = session.firstMultiple; var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center; var center = input.center = getCenter(pointers); input.timeStamp = now(); input.deltaTime = input.timeStamp - firstInput.timeStamp; input.angle = getAngle(offsetCenter, center); input.distance = getDistance(offsetCenter, center); computeDeltaXY(session, input); input.offsetDirection = getDirection(input.deltaX, input.deltaY); var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY); input.overallVelocityX = overallVelocity.x; input.overallVelocityY = overallVelocity.y; input.overallVelocity = abs(overallVelocity.x) > abs(overallVelocity.y) ? overallVelocity.x : overallVelocity.y; input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1; input.rotation = firstMultiple ? getRotation2(firstMultiple.pointers, pointers) : 0; input.maxPointers = !session.prevInput ? input.pointers.length : input.pointers.length > session.prevInput.maxPointers ? input.pointers.length : session.prevInput.maxPointers; computeIntervalInputData(session, input); var target = manager.element; if (hasParent(input.srcEvent.target, target)) { target = input.srcEvent.target; } input.target = target; } function computeDeltaXY(session, input) { var center = input.center; var offset = session.offsetDelta || {}; var prevDelta = session.prevDelta || {}; var prevInput = session.prevInput || {}; if (input.eventType === INPUT_START2 || prevInput.eventType === INPUT_END2) { prevDelta = session.prevDelta = { x: prevInput.deltaX || 0, y: prevInput.deltaY || 0 }; offset = session.offsetDelta = { x: center.x, y: center.y }; } input.deltaX = prevDelta.x + (center.x - offset.x); input.deltaY = prevDelta.y + (center.y - offset.y); } function computeIntervalInputData(session, input) { var last = session.lastInterval || input, deltaTime = input.timeStamp - last.timeStamp, velocity, velocityX, velocityY, direction; if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined2)) { var deltaX = input.deltaX - last.deltaX; var deltaY = input.deltaY - last.deltaY; var v = getVelocity(deltaTime, deltaX, deltaY); velocityX = v.x; velocityY = v.y; velocity = abs(v.x) > abs(v.y) ? v.x : v.y; direction = getDirection(deltaX, deltaY); session.lastInterval = input; } else { velocity = last.velocity; velocityX = last.velocityX; velocityY = last.velocityY; direction = last.direction; } input.velocity = velocity; input.velocityX = velocityX; input.velocityY = velocityY; input.direction = direction; } function simpleCloneInputData(input) { var pointers = []; var i = 0; while (i < input.pointers.length) { pointers[i] = { clientX: round6(input.pointers[i].clientX), clientY: round6(input.pointers[i].clientY) }; i++; } return { timeStamp: now(), pointers, center: getCenter(pointers), deltaX: input.deltaX, deltaY: input.deltaY }; } function getCenter(pointers) { var pointersLength = pointers.length; if (pointersLength === 1) { return { x: round6(pointers[0].clientX), y: round6(pointers[0].clientY) }; } var x = 0, y = 0, i = 0; while (i < pointersLength) { x += pointers[i].clientX; y += pointers[i].clientY; i++; } return { x: round6(x / pointersLength), y: round6(y / pointersLength) }; } function getVelocity(deltaTime, x, y) { return { x: x / deltaTime || 0, y: y / deltaTime || 0 }; } function getDirection(x, y) { if (x === y) { return DIRECTION_NONE; } if (abs(x) >= abs(y)) { return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; } return y < 0 ? DIRECTION_UP : DIRECTION_DOWN; } function getDistance(p1, p2, props) { if (!props) { props = PROPS_XY; } var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]]; return Math.sqrt(x * x + y * y); } function getAngle(p1, p2, props) { if (!props) { props = PROPS_XY; } var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]]; return Math.atan2(y, x) * 180 / Math.PI; } function getRotation2(start, end) { return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY); } function getScale(start, end) { return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY); } var MOUSE_INPUT_MAP2 = { mousedown: INPUT_START2, mousemove: INPUT_MOVE2, mouseup: INPUT_END2 }; var MOUSE_ELEMENT_EVENTS = "mousedown"; var MOUSE_WINDOW_EVENTS = "mousemove mouseup"; function MouseInput2() { this.evEl = MOUSE_ELEMENT_EVENTS; this.evWin = MOUSE_WINDOW_EVENTS; this.pressed = false; Input2.apply(this, arguments); } inherit(MouseInput2, Input2, { handler: function MEhandler(ev) { var eventType = MOUSE_INPUT_MAP2[ev.type]; if (eventType & INPUT_START2 && ev.button === 0) { this.pressed = true; } if (eventType & INPUT_MOVE2 && ev.which !== 1) { eventType = INPUT_END2; } if (!this.pressed) { return; } if (eventType & INPUT_END2) { this.pressed = false; } this.callback(this.manager, eventType, { pointers: [ev], changedPointers: [ev], pointerType: INPUT_TYPE_MOUSE, srcEvent: ev }); } }); var POINTER_INPUT_MAP = { pointerdown: INPUT_START2, pointermove: INPUT_MOVE2, pointerup: INPUT_END2, pointercancel: INPUT_CANCEL, pointerout: INPUT_CANCEL }; var IE10_POINTER_TYPE_ENUM = { 2: INPUT_TYPE_TOUCH, 3: INPUT_TYPE_PEN, 4: INPUT_TYPE_MOUSE, 5: INPUT_TYPE_KINECT }; var POINTER_ELEMENT_EVENTS = "pointerdown"; var POINTER_WINDOW_EVENTS = "pointermove pointerup pointercancel"; if (window2.MSPointerEvent && !window2.PointerEvent) { POINTER_ELEMENT_EVENTS = "MSPointerDown"; POINTER_WINDOW_EVENTS = "MSPointerMove MSPointerUp MSPointerCancel"; } function PointerEventInput2() { this.evEl = POINTER_ELEMENT_EVENTS; this.evWin = POINTER_WINDOW_EVENTS; Input2.apply(this, arguments); this.store = this.manager.session.pointerEvents = []; } inherit(PointerEventInput2, Input2, { handler: function PEhandler(ev) { var store = this.store; var removePointer = false; var eventTypeNormalized = ev.type.toLowerCase().replace("ms", ""); var eventType = POINTER_INPUT_MAP[eventTypeNormalized]; var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType; var isTouch = pointerType == INPUT_TYPE_TOUCH; var storeIndex = inArray(store, ev.pointerId, "pointerId"); if (eventType & INPUT_START2 && (ev.button === 0 || isTouch)) { if (storeIndex < 0) { store.push(ev); storeIndex = store.length - 1; } } else if (eventType & (INPUT_END2 | INPUT_CANCEL)) { removePointer = true; } if (storeIndex < 0) { return; } store[storeIndex] = ev; this.callback(this.manager, eventType, { pointers: store, changedPointers: [ev], pointerType, srcEvent: ev }); if (removePointer) { store.splice(storeIndex, 1); } } }); var SINGLE_TOUCH_INPUT_MAP = { touchstart: INPUT_START2, touchmove: INPUT_MOVE2, touchend: INPUT_END2, touchcancel: INPUT_CANCEL }; var SINGLE_TOUCH_TARGET_EVENTS = "touchstart"; var SINGLE_TOUCH_WINDOW_EVENTS = "touchstart touchmove touchend touchcancel"; function SingleTouchInput() { this.evTarget = SINGLE_TOUCH_TARGET_EVENTS; this.evWin = SINGLE_TOUCH_WINDOW_EVENTS; this.started = false; Input2.apply(this, arguments); } inherit(SingleTouchInput, Input2, { handler: function TEhandler(ev) { var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; if (type === INPUT_START2) { this.started = true; } if (!this.started) { return; } var touches = normalizeSingleTouches.call(this, ev, type); if (type & (INPUT_END2 | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) { this.started = false; } this.callback(this.manager, type, { pointers: touches[0], changedPointers: touches[1], pointerType: INPUT_TYPE_TOUCH, srcEvent: ev }); } }); function normalizeSingleTouches(ev, type) { var all = toArray(ev.touches); var changed = toArray(ev.changedTouches); if (type & (INPUT_END2 | INPUT_CANCEL)) { all = uniqueArray(all.concat(changed), "identifier", true); } return [all, changed]; } var TOUCH_INPUT_MAP = { touchstart: INPUT_START2, touchmove: INPUT_MOVE2, touchend: INPUT_END2, touchcancel: INPUT_CANCEL }; var TOUCH_TARGET_EVENTS = "touchstart touchmove touchend touchcancel"; function TouchInput() { this.evTarget = TOUCH_TARGET_EVENTS; this.targetIds = {}; Input2.apply(this, arguments); } inherit(TouchInput, Input2, { handler: function MTEhandler(ev) { var type = TOUCH_INPUT_MAP[ev.type]; var touches = getTouches.call(this, ev, type); if (!touches) { return; } this.callback(this.manager, type, { pointers: touches[0], changedPointers: touches[1], pointerType: INPUT_TYPE_TOUCH, srcEvent: ev }); } }); function getTouches(ev, type) { var allTouches = toArray(ev.touches); var targetIds = this.targetIds; if (type & (INPUT_START2 | INPUT_MOVE2) && allTouches.length === 1) { targetIds[allTouches[0].identifier] = true; return [allTouches, allTouches]; } var i, targetTouches, changedTouches = toArray(ev.changedTouches), changedTargetTouches = [], target = this.target; targetTouches = allTouches.filter(function(touch) { return hasParent(touch.target, target); }); if (type === INPUT_START2) { i = 0; while (i < targetTouches.length) { targetIds[targetTouches[i].identifier] = true; i++; } } i = 0; while (i < changedTouches.length) { if (targetIds[changedTouches[i].identifier]) { changedTargetTouches.push(changedTouches[i]); } if (type & (INPUT_END2 | INPUT_CANCEL)) { delete targetIds[changedTouches[i].identifier]; } i++; } if (!changedTargetTouches.length) { return; } return [ uniqueArray(targetTouches.concat(changedTargetTouches), "identifier", true), changedTargetTouches ]; } var DEDUP_TIMEOUT = 2500; var DEDUP_DISTANCE = 25; function TouchMouseInput() { Input2.apply(this, arguments); var handler = bindFn(this.handler, this); this.touch = new TouchInput(this.manager, handler); this.mouse = new MouseInput2(this.manager, handler); this.primaryTouch = null; this.lastTouches = []; } inherit(TouchMouseInput, Input2, { handler: function TMEhandler(manager, inputEvent, inputData) { var isTouch = inputData.pointerType == INPUT_TYPE_TOUCH, isMouse = inputData.pointerType == INPUT_TYPE_MOUSE; if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) { return; } if (isTouch) { recordTouches.call(this, inputEvent, inputData); } else if (isMouse && isSyntheticEvent.call(this, inputData)) { return; } this.callback(manager, inputEvent, inputData); }, destroy: function destroy() { this.touch.destroy(); this.mouse.destroy(); } }); function recordTouches(eventType, eventData) { if (eventType & INPUT_START2) { this.primaryTouch = eventData.changedPointers[0].identifier; setLastTouch.call(this, eventData); } else if (eventType & (INPUT_END2 | INPUT_CANCEL)) { setLastTouch.call(this, eventData); } } function setLastTouch(eventData) { var touch = eventData.changedPointers[0]; if (touch.identifier === this.primaryTouch) { var lastTouch = { x: touch.clientX, y: touch.clientY }; this.lastTouches.push(lastTouch); var lts = this.lastTouches; var removeLastTouch = function() { var i = lts.indexOf(lastTouch); if (i > -1) { lts.splice(i, 1); } }; setTimeout(removeLastTouch, DEDUP_TIMEOUT); } } function isSyntheticEvent(eventData) { var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY; for (var i = 0; i < this.lastTouches.length; i++) { var t = this.lastTouches[i]; var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y); if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) { return true; } } return false; } var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, "touchAction"); var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined2; var TOUCH_ACTION_COMPUTE = "compute"; var TOUCH_ACTION_AUTO = "auto"; var TOUCH_ACTION_MANIPULATION = "manipulation"; var TOUCH_ACTION_NONE = "none"; var TOUCH_ACTION_PAN_X = "pan-x"; var TOUCH_ACTION_PAN_Y = "pan-y"; var TOUCH_ACTION_MAP = getTouchActionProps(); function TouchAction(manager, value) { this.manager = manager; this.set(value); } TouchAction.prototype = { set: function(value) { if (value == TOUCH_ACTION_COMPUTE) { value = this.compute(); } if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) { this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; } this.actions = value.toLowerCase().trim(); }, update: function() { this.set(this.manager.options.touchAction); }, compute: function() { var actions = []; each(this.manager.recognizers, function(recognizer) { if (boolOrFn(recognizer.options.enable, [recognizer])) { actions = actions.concat(recognizer.getTouchAction()); } }); return cleanTouchActions(actions.join(" ")); }, preventDefaults: function(input) { var srcEvent = input.srcEvent; var direction = input.offsetDirection; if (this.manager.session.prevented) { srcEvent.preventDefault(); return; } var actions = this.actions; var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE]; var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y]; var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X]; if (hasNone) { var isTapPointer = input.pointers.length === 1; var isTapMovement = input.distance < 2; var isTapTouchTime = input.deltaTime < 250; if (isTapPointer && isTapMovement && isTapTouchTime) { return; } } if (hasPanX && hasPanY) { return; } if (hasNone || hasPanY && direction & DIRECTION_HORIZONTAL || hasPanX && direction & DIRECTION_VERTICAL) { return this.preventSrc(srcEvent); } }, preventSrc: function(srcEvent) { this.manager.session.prevented = true; srcEvent.preventDefault(); } }; function cleanTouchActions(actions) { if (inStr(actions, TOUCH_ACTION_NONE)) { return TOUCH_ACTION_NONE; } var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); if (hasPanX && hasPanY) { return TOUCH_ACTION_NONE; } if (hasPanX || hasPanY) { return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y; } if (inStr(actions, TOUCH_ACTION_MANIPULATION)) { return TOUCH_ACTION_MANIPULATION; } return TOUCH_ACTION_AUTO; } function getTouchActionProps() { if (!NATIVE_TOUCH_ACTION) { return false; } var touchMap = {}; var cssSupports = window2.CSS && window2.CSS.supports; ["auto", "manipulation", "pan-y", "pan-x", "pan-x pan-y", "none"].forEach(function(val) { touchMap[val] = cssSupports ? window2.CSS.supports("touch-action", val) : true; }); return touchMap; } var STATE_POSSIBLE = 1; var STATE_BEGAN = 2; var STATE_CHANGED = 4; var STATE_ENDED = 8; var STATE_RECOGNIZED = STATE_ENDED; var STATE_CANCELLED = 16; var STATE_FAILED = 32; function Recognizer(options) { this.options = assign({}, this.defaults, options || {}); this.id = uniqueId(); this.manager = null; this.options.enable = ifUndefined(this.options.enable, true); this.state = STATE_POSSIBLE; this.simultaneous = {}; this.requireFail = []; } Recognizer.prototype = { defaults: {}, set: function(options) { assign(this.options, options); this.manager && this.manager.touchAction.update(); return this; }, recognizeWith: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, "recognizeWith", this)) { return this; } var simultaneous = this.simultaneous; otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); if (!simultaneous[otherRecognizer.id]) { simultaneous[otherRecognizer.id] = otherRecognizer; otherRecognizer.recognizeWith(this); } return this; }, dropRecognizeWith: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, "dropRecognizeWith", this)) { return this; } otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); delete this.simultaneous[otherRecognizer.id]; return this; }, requireFailure: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, "requireFailure", this)) { return this; } var requireFail = this.requireFail; otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); if (inArray(requireFail, otherRecognizer) === -1) { requireFail.push(otherRecognizer); otherRecognizer.requireFailure(this); } return this; }, dropRequireFailure: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, "dropRequireFailure", this)) { return this; } otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); var index2 = inArray(this.requireFail, otherRecognizer); if (index2 > -1) { this.requireFail.splice(index2, 1); } return this; }, hasRequireFailures: function() { return this.requireFail.length > 0; }, canRecognizeWith: function(otherRecognizer) { return !!this.simultaneous[otherRecognizer.id]; }, emit: function(input) { var self2 = this; var state = this.state; function emit(event) { self2.manager.emit(event, input); } if (state < STATE_ENDED) { emit(self2.options.event + stateStr(state)); } emit(self2.options.event); if (input.additionalEvent) { emit(input.additionalEvent); } if (state >= STATE_ENDED) { emit(self2.options.event + stateStr(state)); } }, tryEmit: function(input) { if (this.canEmit()) { return this.emit(input); } this.state = STATE_FAILED; }, canEmit: function() { var i = 0; while (i < this.requireFail.length) { if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) { return false; } i++; } return true; }, recognize: function(inputData) { var inputDataClone = assign({}, inputData); if (!boolOrFn(this.options.enable, [this, inputDataClone])) { this.reset(); this.state = STATE_FAILED; return; } if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) { this.state = STATE_POSSIBLE; } this.state = this.process(inputDataClone); if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) { this.tryEmit(inputDataClone); } }, process: function(inputData) { }, getTouchAction: function() { }, reset: function() { } }; function stateStr(state) { if (state & STATE_CANCELLED) { return "cancel"; } else if (state & STATE_ENDED) { return "end"; } else if (state & STATE_CHANGED) { return "move"; } else if (state & STATE_BEGAN) { return "start"; } return ""; } function directionStr(direction) { if (direction == DIRECTION_DOWN) { return "down"; } else if (direction == DIRECTION_UP) { return "up"; } else if (direction == DIRECTION_LEFT) { return "left"; } else if (direction == DIRECTION_RIGHT) { return "right"; } return ""; } function getRecognizerByNameIfManager(otherRecognizer, recognizer) { var manager = recognizer.manager; if (manager) { return manager.get(otherRecognizer); } return otherRecognizer; } function AttrRecognizer() { Recognizer.apply(this, arguments); } inherit(AttrRecognizer, Recognizer, { defaults: { pointers: 1 }, attrTest: function(input) { var optionPointers = this.options.pointers; return optionPointers === 0 || input.pointers.length === optionPointers; }, process: function(input) { var state = this.state; var eventType = input.eventType; var isRecognized = state & (STATE_BEGAN | STATE_CHANGED); var isValid = this.attrTest(input); if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) { return state | STATE_CANCELLED; } else if (isRecognized || isValid) { if (eventType & INPUT_END2) { return state | STATE_ENDED; } else if (!(state & STATE_BEGAN)) { return STATE_BEGAN; } return state | STATE_CHANGED; } return STATE_FAILED; } }); function PanRecognizer() { AttrRecognizer.apply(this, arguments); this.pX = null; this.pY = null; } inherit(PanRecognizer, AttrRecognizer, { defaults: { event: "pan", threshold: 10, pointers: 1, direction: DIRECTION_ALL }, getTouchAction: function() { var direction = this.options.direction; var actions = []; if (direction & DIRECTION_HORIZONTAL) { actions.push(TOUCH_ACTION_PAN_Y); } if (direction & DIRECTION_VERTICAL) { actions.push(TOUCH_ACTION_PAN_X); } return actions; }, directionTest: function(input) { var options = this.options; var hasMoved = true; var distance5 = input.distance; var direction = input.direction; var x = input.deltaX; var y = input.deltaY; if (!(direction & options.direction)) { if (options.direction & DIRECTION_HORIZONTAL) { direction = x === 0 ? DIRECTION_NONE : x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; hasMoved = x != this.pX; distance5 = Math.abs(input.deltaX); } else { direction = y === 0 ? DIRECTION_NONE : y < 0 ? DIRECTION_UP : DIRECTION_DOWN; hasMoved = y != this.pY; distance5 = Math.abs(input.deltaY); } } input.direction = direction; return hasMoved && distance5 > options.threshold && direction & options.direction; }, attrTest: function(input) { return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || !(this.state & STATE_BEGAN) && this.directionTest(input)); }, emit: function(input) { this.pX = input.deltaX; this.pY = input.deltaY; var direction = directionStr(input.direction); if (direction) { input.additionalEvent = this.options.event + direction; } this._super.emit.call(this, input); } }); function PinchRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(PinchRecognizer, AttrRecognizer, { defaults: { event: "pinch", threshold: 0, pointers: 2 }, getTouchAction: function() { return [TOUCH_ACTION_NONE]; }, attrTest: function(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); }, emit: function(input) { if (input.scale !== 1) { var inOut = input.scale < 1 ? "in" : "out"; input.additionalEvent = this.options.event + inOut; } this._super.emit.call(this, input); } }); function PressRecognizer() { Recognizer.apply(this, arguments); this._timer = null; this._input = null; } inherit(PressRecognizer, Recognizer, { defaults: { event: "press", pointers: 1, time: 251, threshold: 9 }, getTouchAction: function() { return [TOUCH_ACTION_AUTO]; }, process: function(input) { var options = this.options; var validPointers = input.pointers.length === options.pointers; var validMovement = input.distance < options.threshold; var validTime = input.deltaTime > options.time; this._input = input; if (!validMovement || !validPointers || input.eventType & (INPUT_END2 | INPUT_CANCEL) && !validTime) { this.reset(); } else if (input.eventType & INPUT_START2) { this.reset(); this._timer = setTimeoutContext(function() { this.state = STATE_RECOGNIZED; this.tryEmit(); }, options.time, this); } else if (input.eventType & INPUT_END2) { return STATE_RECOGNIZED; } return STATE_FAILED; }, reset: function() { clearTimeout(this._timer); }, emit: function(input) { if (this.state !== STATE_RECOGNIZED) { return; } if (input && input.eventType & INPUT_END2) { this.manager.emit(this.options.event + "up", input); } else { this._input.timeStamp = now(); this.manager.emit(this.options.event, this._input); } } }); function RotateRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(RotateRecognizer, AttrRecognizer, { defaults: { event: "rotate", threshold: 0, pointers: 2 }, getTouchAction: function() { return [TOUCH_ACTION_NONE]; }, attrTest: function(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN); } }); function SwipeRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(SwipeRecognizer, AttrRecognizer, { defaults: { event: "swipe", threshold: 10, velocity: 0.3, direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL, pointers: 1 }, getTouchAction: function() { return PanRecognizer.prototype.getTouchAction.call(this); }, attrTest: function(input) { var direction = this.options.direction; var velocity; if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) { velocity = input.overallVelocity; } else if (direction & DIRECTION_HORIZONTAL) { velocity = input.overallVelocityX; } else if (direction & DIRECTION_VERTICAL) { velocity = input.overallVelocityY; } return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END2; }, emit: function(input) { var direction = directionStr(input.offsetDirection); if (direction) { this.manager.emit(this.options.event + direction, input); } this.manager.emit(this.options.event, input); } }); function TapRecognizer() { Recognizer.apply(this, arguments); this.pTime = false; this.pCenter = false; this._timer = null; this._input = null; this.count = 0; } inherit(TapRecognizer, Recognizer, { defaults: { event: "tap", pointers: 1, taps: 1, interval: 300, time: 250, threshold: 9, posThreshold: 10 }, getTouchAction: function() { return [TOUCH_ACTION_MANIPULATION]; }, process: function(input) { var options = this.options; var validPointers = input.pointers.length === options.pointers; var validMovement = input.distance < options.threshold; var validTouchTime = input.deltaTime < options.time; this.reset(); if (input.eventType & INPUT_START2 && this.count === 0) { return this.failTimeout(); } if (validMovement && validTouchTime && validPointers) { if (input.eventType != INPUT_END2) { return this.failTimeout(); } var validInterval = this.pTime ? input.timeStamp - this.pTime < options.interval : true; var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold; this.pTime = input.timeStamp; this.pCenter = input.center; if (!validMultiTap || !validInterval) { this.count = 1; } else { this.count += 1; } this._input = input; var tapCount = this.count % options.taps; if (tapCount === 0) { if (!this.hasRequireFailures()) { return STATE_RECOGNIZED; } else { this._timer = setTimeoutContext(function() { this.state = STATE_RECOGNIZED; this.tryEmit(); }, options.interval, this); return STATE_BEGAN; } } } return STATE_FAILED; }, failTimeout: function() { this._timer = setTimeoutContext(function() { this.state = STATE_FAILED; }, this.options.interval, this); return STATE_FAILED; }, reset: function() { clearTimeout(this._timer); }, emit: function() { if (this.state == STATE_RECOGNIZED) { this._input.tapCount = this.count; this.manager.emit(this.options.event, this._input); } } }); function Hammer(element, options) { options = options || {}; options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset); return new Manager3(element, options); } Hammer.VERSION = "2.0.7"; Hammer.defaults = { domEvents: false, touchAction: TOUCH_ACTION_COMPUTE, enable: true, inputTarget: null, inputClass: null, preset: [ [RotateRecognizer, { enable: false }], [PinchRecognizer, { enable: false }, ["rotate"]], [SwipeRecognizer, { direction: DIRECTION_HORIZONTAL }], [PanRecognizer, { direction: DIRECTION_HORIZONTAL }, ["swipe"]], [TapRecognizer], [TapRecognizer, { event: "doubletap", taps: 2 }, ["tap"]], [PressRecognizer] ], cssProps: { userSelect: "none", touchSelect: "none", touchCallout: "none", contentZooming: "none", userDrag: "none", tapHighlightColor: "rgba(0,0,0,0)" } }; var STOP = 1; var FORCED_STOP = 2; function Manager3(element, options) { this.options = assign({}, Hammer.defaults, options || {}); this.options.inputTarget = this.options.inputTarget || element; this.handlers = {}; this.session = {}; this.recognizers = []; this.oldCssProps = {}; this.element = element; this.input = createInputInstance(this); this.touchAction = new TouchAction(this, this.options.touchAction); toggleCssProps(this, true); each(this.options.recognizers, function(item) { var recognizer = this.add(new item[0](item[1])); item[2] && recognizer.recognizeWith(item[2]); item[3] && recognizer.requireFailure(item[3]); }, this); } Manager3.prototype = { set: function(options) { assign(this.options, options); if (options.touchAction) { this.touchAction.update(); } if (options.inputTarget) { this.input.destroy(); this.input.target = options.inputTarget; this.input.init(); } return this; }, stop: function(force) { this.session.stopped = force ? FORCED_STOP : STOP; }, recognize: function(inputData) { var session = this.session; if (session.stopped) { return; } this.touchAction.preventDefaults(inputData); var recognizer; var recognizers = this.recognizers; var curRecognizer = session.curRecognizer; if (!curRecognizer || curRecognizer && curRecognizer.state & STATE_RECOGNIZED) { curRecognizer = session.curRecognizer = null; } var i = 0; while (i < recognizers.length) { recognizer = recognizers[i]; if (session.stopped !== FORCED_STOP && (!curRecognizer || recognizer == curRecognizer || recognizer.canRecognizeWith(curRecognizer))) { recognizer.recognize(inputData); } else { recognizer.reset(); } if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) { curRecognizer = session.curRecognizer = recognizer; } i++; } }, get: function(recognizer) { if (recognizer instanceof Recognizer) { return recognizer; } var recognizers = this.recognizers; for (var i = 0; i < recognizers.length; i++) { if (recognizers[i].options.event == recognizer) { return recognizers[i]; } } return null; }, add: function(recognizer) { if (invokeArrayArg(recognizer, "add", this)) { return this; } var existing = this.get(recognizer.options.event); if (existing) { this.remove(existing); } this.recognizers.push(recognizer); recognizer.manager = this; this.touchAction.update(); return recognizer; }, remove: function(recognizer) { if (invokeArrayArg(recognizer, "remove", this)) { return this; } recognizer = this.get(recognizer); if (recognizer) { var recognizers = this.recognizers; var index2 = inArray(recognizers, recognizer); if (index2 !== -1) { recognizers.splice(index2, 1); this.touchAction.update(); } } return this; }, on: function(events, handler) { if (events === undefined2) { return; } if (handler === undefined2) { return; } var handlers = this.handlers; each(splitStr(events), function(event) { handlers[event] = handlers[event] || []; handlers[event].push(handler); }); return this; }, off: function(events, handler) { if (events === undefined2) { return; } var handlers = this.handlers; each(splitStr(events), function(event) { if (!handler) { delete handlers[event]; } else { handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1); } }); return this; }, emit: function(event, data) { if (this.options.domEvents) { triggerDomEvent(event, data); } var handlers = this.handlers[event] && this.handlers[event].slice(); if (!handlers || !handlers.length) { return; } data.type = event; data.preventDefault = function() { data.srcEvent.preventDefault(); }; var i = 0; while (i < handlers.length) { handlers[i](data); i++; } }, destroy: function() { this.element && toggleCssProps(this, false); this.handlers = {}; this.session = {}; this.input.destroy(); this.element = null; } }; function toggleCssProps(manager, add6) { var element = manager.element; if (!element.style) { return; } var prop; each(manager.options.cssProps, function(value, name2) { prop = prefixed(element.style, name2); if (add6) { manager.oldCssProps[prop] = element.style[prop]; element.style[prop] = value; } else { element.style[prop] = manager.oldCssProps[prop] || ""; } }); if (!add6) { manager.oldCssProps = {}; } } function triggerDomEvent(event, data) { var gestureEvent = document2.createEvent("Event"); gestureEvent.initEvent(event, true, true); gestureEvent.gesture = data; data.target.dispatchEvent(gestureEvent); } assign(Hammer, { INPUT_START: INPUT_START2, INPUT_MOVE: INPUT_MOVE2, INPUT_END: INPUT_END2, INPUT_CANCEL, STATE_POSSIBLE, STATE_BEGAN, STATE_CHANGED, STATE_ENDED, STATE_RECOGNIZED, STATE_CANCELLED, STATE_FAILED, DIRECTION_NONE, DIRECTION_LEFT, DIRECTION_RIGHT, DIRECTION_UP, DIRECTION_DOWN, DIRECTION_HORIZONTAL, DIRECTION_VERTICAL, DIRECTION_ALL, Manager: Manager3, Input: Input2, TouchAction, TouchInput, MouseInput: MouseInput2, PointerEventInput: PointerEventInput2, TouchMouseInput, SingleTouchInput, Recognizer, AttrRecognizer, Tap: TapRecognizer, Pan: PanRecognizer, Swipe: SwipeRecognizer, Pinch: PinchRecognizer, Rotate: RotateRecognizer, Press: PressRecognizer, on: addEventListeners, off: removeEventListeners, each, merge, extend, assign, inherit, bindFn, prefixed }); var freeGlobal = typeof window2 !== "undefined" ? window2 : typeof self !== "undefined" ? self : {}; freeGlobal.Hammer = Hammer; if (undefined2 === "function" && define.amd) { define(function() { return Hammer; }); } else if (typeof module != "undefined" && module.exports) { module.exports = Hammer; } else { window2[exportName] = Hammer; } })(window, document, "Hammer"); } }); // bundle/index.ts var bundle_exports = {}; __export(bundle_exports, { AmbientLight: () => AmbientLight, Attribute: () => Attribute2, AttributeManager: () => AttributeManager, COORDINATE_SYSTEM: () => COORDINATE_SYSTEM, CompositeLayer: () => CompositeLayer, Controller: () => Controller, Deck: () => Deck, DeckGL: () => DeckGL, DeckRenderer: () => DeckRenderer, DirectionalLight: () => DirectionalLight, FirstPersonController: () => FirstPersonController, FirstPersonView: () => FirstPersonView, FirstPersonViewport: () => FirstPersonViewport, FlyToInterpolator: () => FlyToInterpolator, Layer: () => Layer, LayerExtension: () => LayerExtension, LayerManager: () => LayerManager, LightingEffect: () => LightingEffect, LinearInterpolator: () => LinearInterpolator, MapController: () => MapController, MapView: () => MapView, OPERATION: () => OPERATION, OrbitController: () => OrbitController, OrbitView: () => OrbitView, OrbitViewport: () => OrbitViewport, OrthographicController: () => OrthographicController, OrthographicView: () => OrthographicView, OrthographicViewport: () => OrthographicViewport, PointLight: () => PointLight, PostProcessEffect: () => PostProcessEffect, TRANSITION_EVENTS: () => TRANSITION_EVENTS, Tesselator: () => Tesselator, TransitionInterpolator: () => TransitionInterpolator, UNIT: () => UNIT, VERSION: () => VERSION5, View: () => View, Viewport: () => Viewport, WebMercatorViewport: () => WebMercatorViewport2, _CameraLight: () => CameraLight, _Component: () => Component, _ComponentState: () => ComponentState, _GlobeController: () => GlobeController, _GlobeView: () => GlobeView, _GlobeViewport: () => GlobeViewport, _LayersPass: () => LayersPass, _PickLayersPass: () => PickLayersPass, _SunLight: () => SunLight, _compareProps: () => compareProps, _count: () => count, _deepEqual: () => deepEqual2, _fillArray: () => fillArray2, _flatten: () => flatten, _memoize: () => memoize, _mergeShaders: () => mergeShaders, _registerLoggers: () => register, assert: () => assert8, createIterable: () => createIterable, fp64LowPart: () => fp64LowPart2, getShaderAssembler: () => getShaderAssembler, gouraudLighting: () => gouraudLighting, log: () => log_default, phongLighting: () => phongLighting, picking: () => picking_default, project: () => project_default, project32: () => project32_default, shadow: () => shadow_default }); // src/scripting/lumagl.ts var lumagl_exports = {}; __export(lumagl_exports, { Buffer: () => Buffer2, BufferTransform: () => BufferTransform, CubeGeometry: () => CubeGeometry, Device: () => Device, Framebuffer: () => Framebuffer, Geometry: () => Geometry, GroupNode: () => GroupNode, Model: () => Model, ModelNode: () => ModelNode, ScenegraphNode: () => ScenegraphNode, SphereGeometry: () => SphereGeometry, Texture: () => Texture, TextureTransform: () => TextureTransform, attachDevice: () => attachDevice, createDevice: () => createDevice, enforceWebGL2: () => enforceWebGL2, getAvailableDevices: () => getAvailableDevices, getSupportedDevices: () => getSupportedDevices, registerDevices: () => registerDevices, setDefaultDeviceProps: () => setDefaultDeviceProps, stats: () => stats }); // ../../node_modules/@probe.gl/env/dist/lib/globals.js var window_ = globalThis; var document_ = globalThis.document || {}; var process_ = globalThis.process || {}; var console_ = globalThis.console; var navigator_ = globalThis.navigator || {}; // ../../node_modules/@probe.gl/env/dist/lib/is-electron.js function isElectron(mockUserAgent) { if (typeof window !== "undefined" && window.process?.type === "renderer") { return true; } if (typeof process !== "undefined" && Boolean(process.versions?.["electron"])) { return true; } const realUserAgent = typeof navigator !== "undefined" && navigator.userAgent; const userAgent2 = mockUserAgent || realUserAgent; return Boolean(userAgent2 && userAgent2.indexOf("Electron") >= 0); } // ../../node_modules/@probe.gl/env/dist/lib/is-browser.js function isBrowser() { const isNode = typeof process === "object" && String(process) === "[object process]" && !process?.browser; return !isNode || isElectron(); } // ../../node_modules/@probe.gl/env/dist/lib/get-browser.js function getBrowser(mockUserAgent) { if (!mockUserAgent && !isBrowser()) { return "Node"; } if (isElectron(mockUserAgent)) { return "Electron"; } const userAgent2 = mockUserAgent || navigator_.userAgent || ""; if (userAgent2.indexOf("Edge") > -1) { return "Edge"; } if (globalThis.chrome) { return "Chrome"; } if (globalThis.safari) { return "Safari"; } if (globalThis.mozInnerScreenX) { return "Firefox"; } return "Unknown"; } // ../../node_modules/@probe.gl/env/dist/index.js var VERSION = true ? "4.0.7" : "untranspiled source"; // ../../node_modules/@probe.gl/log/dist/utils/local-storage.js function getStorage(type) { try { const storage = window[type]; const x = "__storage_test__"; storage.setItem(x, x); storage.removeItem(x); return storage; } catch (e2) { return null; } } var LocalStorage = class { constructor(id, defaultConfig, type = "sessionStorage") { this.storage = getStorage(type); this.id = id; this.config = defaultConfig; this._loadConfiguration(); } getConfiguration() { return this.config; } setConfiguration(configuration) { Object.assign(this.config, configuration); if (this.storage) { const serialized = JSON.stringify(this.config); this.storage.setItem(this.id, serialized); } } _loadConfiguration() { let configuration = {}; if (this.storage) { const serializedConfiguration = this.storage.getItem(this.id); configuration = serializedConfiguration ? JSON.parse(serializedConfiguration) : {}; } Object.assign(this.config, configuration); return this; } }; // ../../node_modules/@probe.gl/log/dist/utils/formatters.js function formatTime(ms) { let formatted; if (ms < 10) { formatted = `${ms.toFixed(2)}ms`; } else if (ms < 100) { formatted = `${ms.toFixed(1)}ms`; } else if (ms < 1e3) { formatted = `${ms.toFixed(0)}ms`; } else { formatted = `${(ms / 1e3).toFixed(2)}s`; } return formatted; } function leftPad(string, length4 = 8) { const padLength = Math.max(length4 - string.length, 0); return `${" ".repeat(padLength)}${string}`; } // ../../node_modules/@probe.gl/log/dist/utils/color.js var COLOR; (function(COLOR2) { COLOR2[COLOR2["BLACK"] = 30] = "BLACK"; COLOR2[COLOR2["RED"] = 31] = "RED"; COLOR2[COLOR2["GREEN"] = 32] = "GREEN"; COLOR2[COLOR2["YELLOW"] = 33] = "YELLOW"; COLOR2[COLOR2["BLUE"] = 34] = "BLUE"; COLOR2[COLOR2["MAGENTA"] = 35] = "MAGENTA"; COLOR2[COLOR2["CYAN"] = 36] = "CYAN"; COLOR2[COLOR2["WHITE"] = 37] = "WHITE"; COLOR2[COLOR2["BRIGHT_BLACK"] = 90] = "BRIGHT_BLACK"; COLOR2[COLOR2["BRIGHT_RED"] = 91] = "BRIGHT_RED"; COLOR2[COLOR2["BRIGHT_GREEN"] = 92] = "BRIGHT_GREEN"; COLOR2[COLOR2["BRIGHT_YELLOW"] = 93] = "BRIGHT_YELLOW"; COLOR2[COLOR2["BRIGHT_BLUE"] = 94] = "BRIGHT_BLUE"; COLOR2[COLOR2["BRIGHT_MAGENTA"] = 95] = "BRIGHT_MAGENTA"; COLOR2[COLOR2["BRIGHT_CYAN"] = 96] = "BRIGHT_CYAN"; COLOR2[COLOR2["BRIGHT_WHITE"] = 97] = "BRIGHT_WHITE"; })(COLOR || (COLOR = {})); var BACKGROUND_INCREMENT = 10; function getColor(color) { if (typeof color !== "string") { return color; } color = color.toUpperCase(); return COLOR[color] || COLOR.WHITE; } function addColor(string, color, background) { if (!isBrowser && typeof string === "string") { if (color) { const colorCode = getColor(color); string = `\x1B[${colorCode}m${string}\x1B[39m`; } if (background) { const colorCode = getColor(background); string = `\x1B[${colorCode + BACKGROUND_INCREMENT}m${string}\x1B[49m`; } } return string; } // ../../node_modules/@probe.gl/log/dist/utils/autobind.js function autobind(obj, predefined = ["constructor"]) { const proto = Object.getPrototypeOf(obj); const propNames = Object.getOwnPropertyNames(proto); const object = obj; for (const key of propNames) { const value = object[key]; if (typeof value === "function") { if (!predefined.find((name2) => key === name2)) { object[key] = value.bind(obj); } } } } // ../../node_modules/@probe.gl/log/dist/utils/assert.js function assert(condition, message2) { if (!condition) { throw new Error(message2 || "Assertion failed"); } } // ../../node_modules/@probe.gl/log/dist/utils/hi-res-timestamp.js function getHiResTimestamp() { let timestamp; if (isBrowser() && window_.performance) { timestamp = window_?.performance?.now?.(); } else if ("hrtime" in process_) { const timeParts = process_?.hrtime?.(); timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6; } else { timestamp = Date.now(); } return timestamp; } // ../../node_modules/@probe.gl/log/dist/log.js var originalConsole = { debug: isBrowser() ? console.debug || console.log : console.log, log: console.log, info: console.info, warn: console.warn, error: console.error }; var DEFAULT_LOG_CONFIGURATION = { enabled: true, level: 0 }; function noop() { } var cache = {}; var ONCE = { once: true }; var Log = class { constructor({ id } = { id: "" }) { this.VERSION = VERSION; this._startTs = getHiResTimestamp(); this._deltaTs = getHiResTimestamp(); this.userData = {}; this.LOG_THROTTLE_TIMEOUT = 0; this.id = id; this.userData = {}; this._storage = new LocalStorage(`__probe-${this.id}__`, DEFAULT_LOG_CONFIGURATION); this.timeStamp(`${this.id} started`); autobind(this); Object.seal(this); } set level(newLevel) { this.setLevel(newLevel); } get level() { return this.getLevel(); } isEnabled() { return this._storage.config.enabled; } getLevel() { return this._storage.config.level; } getTotal() { return Number((getHiResTimestamp() - this._startTs).toPrecision(10)); } getDelta() { return Number((getHiResTimestamp() - this._deltaTs).toPrecision(10)); } set priority(newPriority) { this.level = newPriority; } get priority() { return this.level; } getPriority() { return this.level; } enable(enabled = true) { this._storage.setConfiguration({ enabled }); return this; } setLevel(level) { this._storage.setConfiguration({ level }); return this; } get(setting) { return this._storage.config[setting]; } set(setting, value) { this._storage.setConfiguration({ [setting]: value }); } settings() { if (console.table) { console.table(this._storage.config); } else { console.log(this._storage.config); } } assert(condition, message2) { if (!condition) { throw new Error(message2 || "Assertion failed"); } } warn(message2) { return this._getLogFunction(0, message2, originalConsole.warn, arguments, ONCE); } error(message2) { return this._getLogFunction(0, message2, originalConsole.error, arguments); } deprecated(oldUsage, newUsage) { return this.warn(`\`${oldUsage}\` is deprecated and will be removed in a later version. Use \`${newUsage}\` instead`); } removed(oldUsage, newUsage) { return this.error(`\`${oldUsage}\` has been removed. Use \`${newUsage}\` instead`); } probe(logLevel, message2) { return this._getLogFunction(logLevel, message2, originalConsole.log, arguments, { time: true, once: true }); } log(logLevel, message2) { return this._getLogFunction(logLevel, message2, originalConsole.debug, arguments); } info(logLevel, message2) { return this._getLogFunction(logLevel, message2, console.info, arguments); } once(logLevel, message2) { return this._getLogFunction(logLevel, message2, originalConsole.debug || originalConsole.info, arguments, ONCE); } table(logLevel, table, columns) { if (table) { return this._getLogFunction(logLevel, table, console.table || noop, columns && [columns], { tag: getTableHeader(table) }); } return noop; } time(logLevel, message2) { return this._getLogFunction(logLevel, message2, console.time ? console.time : console.info); } timeEnd(logLevel, message2) { return this._getLogFunction(logLevel, message2, console.timeEnd ? console.timeEnd : console.info); } timeStamp(logLevel, message2) { return this._getLogFunction(logLevel, message2, console.timeStamp || noop); } group(logLevel, message2, opts = { collapsed: false }) { const options = normalizeArguments({ logLevel, message: message2, opts }); const { collapsed } = opts; options.method = (collapsed ? console.groupCollapsed : console.group) || console.info; return this._getLogFunction(options); } groupCollapsed(logLevel, message2, opts = {}) { return this.group(logLevel, message2, Object.assign({}, opts, { collapsed: true })); } groupEnd(logLevel) { return this._getLogFunction(logLevel, "", console.groupEnd || noop); } withGroup(logLevel, message2, func) { this.group(logLevel, message2)(); try { func(); } finally { this.groupEnd(logLevel)(); } } trace() { if (console.trace) { console.trace(); } } _shouldLog(logLevel) { return this.isEnabled() && this.getLevel() >= normalizeLogLevel(logLevel); } _getLogFunction(logLevel, message2, method, args, opts) { if (this._shouldLog(logLevel)) { opts = normalizeArguments({ logLevel, message: message2, args, opts }); method = method || opts.method; assert(method); opts.total = this.getTotal(); opts.delta = this.getDelta(); this._deltaTs = getHiResTimestamp(); const tag = opts.tag || opts.message; if (opts.once && tag) { if (!cache[tag]) { cache[tag] = getHiResTimestamp(); } else { return noop; } } message2 = decorateMessage(this.id, opts.message, opts); return method.bind(console, message2, ...opts.args); } return noop; } }; Log.VERSION = VERSION; function normalizeLogLevel(logLevel) { if (!logLevel) { return 0; } let resolvedLevel; switch (typeof logLevel) { case "number": resolvedLevel = logLevel; break; case "object": resolvedLevel = logLevel.logLevel || logLevel.priority || 0; break; default: return 0; } assert(Number.isFinite(resolvedLevel) && resolvedLevel >= 0); return resolvedLevel; } function normalizeArguments(opts) { const { logLevel, message: message2 } = opts; opts.logLevel = normalizeLogLevel(logLevel); const args = opts.args ? Array.from(opts.args) : []; while (args.length && args.shift() !== message2) { } switch (typeof logLevel) { case "string": case "function": if (message2 !== void 0) { args.unshift(message2); } opts.message = logLevel; break; case "object": Object.assign(opts, logLevel); break; default: } if (typeof opts.message === "function") { opts.message = opts.message(); } const messageType = typeof opts.message; assert(messageType === "string" || messageType === "object"); return Object.assign(opts, { args }, opts.opts); } function decorateMessage(id, message2, opts) { if (typeof message2 === "string") { const time = opts.time ? leftPad(formatTime(opts.total)) : ""; message2 = opts.time ? `${id}: ${time} ${message2}` : `${id}: ${message2}`; message2 = addColor(message2, opts.color, opts.background); } return message2; } function getTableHeader(table) { for (const key in table) { for (const title in table[key]) { return title || "untitled"; } } return "empty"; } // ../../node_modules/@probe.gl/log/dist/init.js globalThis.probe = {}; // ../../node_modules/@probe.gl/log/dist/index.js var dist_default = new Log({ id: "@probe.gl/log" }); // ../../node_modules/@luma.gl/core/dist/utils/log.js var log = new Log({ id: "luma.gl" }); // ../../node_modules/@probe.gl/stats/dist/utils/hi-res-timestamp.js function getHiResTimestamp2() { let timestamp; if (typeof window !== "undefined" && window.performance) { timestamp = window.performance.now(); } else if (typeof process !== "undefined" && process.hrtime) { const timeParts = process.hrtime(); timestamp = timeParts[0] * 1e3 + timeParts[1] / 1e6; } else { timestamp = Date.now(); } return timestamp; } // ../../node_modules/@probe.gl/stats/dist/lib/stat.js var Stat = class { constructor(name2, type) { this.sampleSize = 1; this.time = 0; this.count = 0; this.samples = 0; this.lastTiming = 0; this.lastSampleTime = 0; this.lastSampleCount = 0; this._count = 0; this._time = 0; this._samples = 0; this._startTime = 0; this._timerPending = false; this.name = name2; this.type = type; this.reset(); } reset() { this.time = 0; this.count = 0; this.samples = 0; this.lastTiming = 0; this.lastSampleTime = 0; this.lastSampleCount = 0; this._count = 0; this._time = 0; this._samples = 0; this._startTime = 0; this._timerPending = false; return this; } setSampleSize(samples) { this.sampleSize = samples; return this; } incrementCount() { this.addCount(1); return this; } decrementCount() { this.subtractCount(1); return this; } addCount(value) { this._count += value; this._samples++; this._checkSampling(); return this; } subtractCount(value) { this._count -= value; this._samples++; this._checkSampling(); return this; } addTime(time) { this._time += time; this.lastTiming = time; this._samples++; this._checkSampling(); return this; } timeStart() { this._startTime = getHiResTimestamp2(); this._timerPending = true; return this; } timeEnd() { if (!this._timerPending) { return this; } this.addTime(getHiResTimestamp2() - this._startTime); this._timerPending = false; this._checkSampling(); return this; } getSampleAverageCount() { return this.sampleSize > 0 ? this.lastSampleCount / this.sampleSize : 0; } getSampleAverageTime() { return this.sampleSize > 0 ? this.lastSampleTime / this.sampleSize : 0; } getSampleHz() { return this.lastSampleTime > 0 ? this.sampleSize / (this.lastSampleTime / 1e3) : 0; } getAverageCount() { return this.samples > 0 ? this.count / this.samples : 0; } getAverageTime() { return this.samples > 0 ? this.time / this.samples : 0; } getHz() { return this.time > 0 ? this.samples / (this.time / 1e3) : 0; } _checkSampling() { if (this._samples === this.sampleSize) { this.lastSampleTime = this._time; this.lastSampleCount = this._count; this.count += this._count; this.time += this._time; this.samples += this._samples; this._time = 0; this._count = 0; this._samples = 0; } } }; // ../../node_modules/@probe.gl/stats/dist/lib/stats.js var Stats = class { constructor(options) { this.stats = {}; this.id = options.id; this.stats = {}; this._initializeStats(options.stats); Object.seal(this); } get(name2, type = "count") { return this._getOrCreate({ name: name2, type }); } get size() { return Object.keys(this.stats).length; } reset() { for (const stat of Object.values(this.stats)) { stat.reset(); } return this; } forEach(fn) { for (const stat of Object.values(this.stats)) { fn(stat); } } getTable() { const table = {}; this.forEach((stat) => { table[stat.name] = { time: stat.time || 0, count: stat.count || 0, average: stat.getAverageTime() || 0, hz: stat.getHz() || 0 }; }); return table; } _initializeStats(stats2 = []) { stats2.forEach((stat) => this._getOrCreate(stat)); } _getOrCreate(stat) { const { name: name2, type } = stat; let result = this.stats[name2]; if (!result) { if (stat instanceof Stat) { result = stat; } else { result = new Stat(name2, type); } this.stats[name2] = result; } return result; } }; // ../../node_modules/@luma.gl/core/dist/utils/stats-manager.js var StatsManager = class { stats = /* @__PURE__ */ new Map(); getStats(name2) { return this.get(name2); } get(name2) { if (!this.stats.has(name2)) { this.stats.set(name2, new Stats({ id: name2 })); } return this.stats.get(name2); } }; var lumaStats = new StatsManager(); // ../../node_modules/@luma.gl/core/dist/init.js function initializeLuma() { const VERSION6 = true ? "9.0.27" : "running from source"; const STARTUP_MESSAGE = "set luma.log.level=1 (or higher) to trace rendering"; if (globalThis.luma && globalThis.luma.VERSION !== VERSION6) { throw new Error(`luma.gl - multiple VERSIONs detected: ${globalThis.luma.VERSION} vs ${VERSION6}`); } if (!globalThis.luma) { if (isBrowser()) { log.log(1, `${VERSION6} - ${STARTUP_MESSAGE}`)(); } globalThis.luma = globalThis.luma || { VERSION: VERSION6, version: VERSION6, log, stats: lumaStats }; } return VERSION6; } var VERSION2 = initializeLuma(); // ../../node_modules/@luma.gl/core/dist/utils/is-array.js function isTypedArray(value) { return ArrayBuffer.isView(value) && !(value instanceof DataView) ? value : null; } function isNumberArray(value) { if (Array.isArray(value)) { return value.length === 0 || typeof value[0] === "number" ? value : null; } return isTypedArray(value); } // ../../node_modules/@luma.gl/core/dist/utils/utils.js var uidCounters = {}; function uid(id = "id") { uidCounters[id] = uidCounters[id] || 1; const count2 = uidCounters[id]++; return `${id}-${count2}`; } function isObjectEmpty(obj) { let isEmpty = true; for (const key in obj) { isEmpty = false; break; } return isEmpty; } // ../../node_modules/@luma.gl/core/dist/adapter/resources/resource.js var Resource = class { id; props; userData = {}; _device; destroyed = false; allocatedBytes = 0; _attachedResources = /* @__PURE__ */ new Set(); constructor(device, props, defaultProps3) { if (!device) { throw new Error("no device"); } this._device = device; this.props = selectivelyMerge(props, defaultProps3); const id = this.props.id !== "undefined" ? this.props.id : uid(this[Symbol.toStringTag]); this.props.id = id; this.id = id; this.userData = this.props.userData || {}; this.addStats(); } destroy() { this.destroyResource(); } delete() { this.destroy(); return this; } toString() { return `${this[Symbol.toStringTag] || this.constructor.name}(${this.id})`; } getProps() { return this.props; } attachResource(resource) { this._attachedResources.add(resource); } detachResource(resource) { this._attachedResources.delete(resource); } destroyAttachedResource(resource) { if (this._attachedResources.delete(resource)) { resource.destroy(); } } destroyAttachedResources() { for (const resource of Object.values(this._attachedResources)) { resource.destroy(); } this._attachedResources = /* @__PURE__ */ new Set(); } destroyResource() { this.destroyAttachedResources(); this.removeStats(); this.destroyed = true; } removeStats() { const stats2 = this._device.statsManager.getStats("Resource Counts"); const name2 = this[Symbol.toStringTag]; stats2.get(`${name2}s Active`).decrementCount(); } trackAllocatedMemory(bytes, name2 = this[Symbol.toStringTag]) { const stats2 = this._device.statsManager.getStats("Resource Counts"); stats2.get("GPU Memory").addCount(bytes); stats2.get(`${name2} Memory`).addCount(bytes); this.allocatedBytes = bytes; } trackDeallocatedMemory(name2 = this[Symbol.toStringTag]) { const stats2 = this._device.statsManager.getStats("Resource Counts"); stats2.get("GPU Memory").subtractCount(this.allocatedBytes); stats2.get(`${name2} Memory`).subtractCount(this.allocatedBytes); this.allocatedBytes = 0; } addStats() { const stats2 = this._device.statsManager.getStats("Resource Counts"); const name2 = this[Symbol.toStringTag]; stats2.get("Resources Created").incrementCount(); stats2.get(`${name2}s Created`).incrementCount(); stats2.get(`${name2}s Active`).incrementCount(); } }; __publicField(Resource, "defaultProps", { id: "undefined", handle: void 0, userData: void 0 }); function selectivelyMerge(props, defaultProps3) { const mergedProps = { ...defaultProps3 }; for (const key in props) { if (props[key] !== void 0) { mergedProps[key] = props[key]; } } return mergedProps; } // ../../node_modules/@luma.gl/core/dist/adapter/resources/buffer.js var _Buffer = class extends Resource { get [Symbol.toStringTag]() { return "Buffer"; } usage; indexType; updateTimestamp; constructor(device, props) { const deducedProps = { ...props }; if ((props.usage || 0) & _Buffer.INDEX && !props.indexType) { if (props.data instanceof Uint32Array) { deducedProps.indexType = "uint32"; } else if (props.data instanceof Uint16Array) { deducedProps.indexType = "uint16"; } } super(device, deducedProps, _Buffer.defaultProps); this.usage = props.usage || 0; this.indexType = deducedProps.indexType; this.updateTimestamp = device.incrementTimestamp(); } readSyncWebGL(byteOffset, byteLength) { throw new Error("not implemented"); } debugData = new ArrayBuffer(0); _setDebugData(data, byteOffset, byteLength) { const buffer = ArrayBuffer.isView(data) ? data.buffer : data; const debugDataLength = Math.min(data ? data.byteLength : byteLength, _Buffer.DEBUG_DATA_MAX_LENGTH); if (data === null) { this.debugData = new ArrayBuffer(debugDataLength); } else if (byteOffset === 0 && byteLength === data.byteLength) { this.debugData = buffer.slice(0, debugDataLength); } else { this.debugData = buffer.slice(byteOffset, byteOffset + debugDataLength); } } }; var Buffer2 = _Buffer; __publicField(Buffer2, "defaultProps", { ...Resource.defaultProps, usage: 0, byteLength: 0, byteOffset: 0, data: null, indexType: "uint16", mappedAtCreation: false }); __publicField(Buffer2, "MAP_READ", 1); __publicField(Buffer2, "MAP_WRITE", 2); __publicField(Buffer2, "COPY_SRC", 4); __publicField(Buffer2, "COPY_DST", 8); __publicField(Buffer2, "INDEX", 16); __publicField(Buffer2, "VERTEX", 32); __publicField(Buffer2, "UNIFORM", 64); __publicField(Buffer2, "STORAGE", 128); __publicField(Buffer2, "INDIRECT", 256); __publicField(Buffer2, "QUERY_RESOLVE", 512); __publicField(Buffer2, "DEBUG_DATA_MAX_LENGTH", 32); // ../../node_modules/@luma.gl/core/dist/adapter/type-utils/decode-data-type.js function decodeVertexType(type) { const dataType = TYPE_MAP[type]; const bytes = getDataTypeBytes(dataType); const normalized = type.includes("norm"); const integer = !normalized && !type.startsWith("float"); const signed = type.startsWith("s"); return { dataType: TYPE_MAP[type], byteLength: bytes, integer, signed, normalized }; } function getDataTypeBytes(type) { const bytes = TYPE_SIZES[type]; return bytes; } var TYPE_MAP = { uint8: "uint8", sint8: "sint8", unorm8: "uint8", snorm8: "sint8", uint16: "uint16", sint16: "sint16", unorm16: "uint16", snorm16: "sint16", float16: "float16", float32: "float32", uint32: "uint32", sint32: "sint32" }; var TYPE_SIZES = { uint8: 1, sint8: 1, uint16: 2, sint16: 2, float16: 2, float32: 4, uint32: 4, sint32: 4 }; // ../../node_modules/@luma.gl/core/dist/adapter/type-utils/decode-texture-format.js var COMPRESSED_TEXTURE_FORMAT_PREFIXES = [ "bc1", "bc2", "bc3", "bc4", "bc5", "bc6", "bc7", "etc1", "etc2", "eac", "atc", "astc", "pvrtc" ]; var REGEX = /^(rg?b?a?)([0-9]*)([a-z]*)(-srgb)?(-webgl|-unsized)?$/; function isTextureFormatCompressed(textureFormat) { return COMPRESSED_TEXTURE_FORMAT_PREFIXES.some((prefix) => textureFormat.startsWith(prefix)); } function decodeTextureFormat(format) { const matches3 = REGEX.exec(format); if (matches3) { const [, format2, length4, type, srgb, suffix] = matches3; if (format2) { const dataType = `${type}${length4}`; const decodedType = decodeVertexType(dataType); return { format: format2, components: format2.length, srgb: srgb === "-srgb", unsized: suffix === "-unsized", webgl: suffix === "-webgl", ...decodedType }; } } return decodeNonStandardFormat(format); } var EXCEPTIONS = { "rgba4unorm-webgl": { format: "rgba", bpp: 2 }, "rgb565unorm-webgl": { format: "rgb", bpp: 2 }, "rgb5a1unorm-webgl": { format: "rgba", bbp: 2 }, rgb9e5ufloat: { format: "rgb", bbp: 4 }, rg11b10ufloat: { format: "rgb", bbp: 4 }, rgb10a2unorm: { format: "rgba", bbp: 4 }, "rgb10a2uint-webgl": { format: "rgba", bbp: 4 }, stencil8: { components: 1, bpp: 1, a: "stencil" }, depth16unorm: { components: 1, bpp: 2, a: "depth" }, depth24plus: { components: 1, bpp: 3, a: "depth" }, depth32float: { components: 1, bpp: 4, a: "depth" }, "depth24plus-stencil8": { components: 2, bpp: 4, a: "depth-stencil" }, "depth24unorm-stencil8": { components: 2, bpp: 4, a: "depth-stencil" }, "depth32float-stencil8": { components: 2, bpp: 4, a: "depth-stencil" } }; function decodeNonStandardFormat(format) { const data = EXCEPTIONS[format]; if (!data) { throw new Error(`Unknown format ${format}`); } return { format: data.format || "", components: data.components || data.format?.length || 1, byteLength: data.bpp || 1, srgb: false, unsized: false }; } // ../../node_modules/@luma.gl/core/dist/adapter/device.js var DeviceLimits = class { }; var DeviceFeatures = class { features; disabledFeatures; constructor(features = [], disabledFeatures) { this.features = new Set(features); this.disabledFeatures = disabledFeatures || {}; } *[Symbol.iterator]() { yield* this.features; } has(feature) { return !this.disabledFeatures[feature] && this.features.has(feature); } }; var _Device = class { get [Symbol.toStringTag]() { return "Device"; } constructor(props) { this.props = { ..._Device.defaultProps, ...props }; this.id = this.props.id || uid(this[Symbol.toStringTag].toLowerCase()); } id; props; userData = {}; statsManager = lumaStats; _lumaData = {}; isTextureFormatCompressed(format) { return isTextureFormatCompressed(format); } loseDevice() { return false; } getCanvasContext() { if (!this.canvasContext) { throw new Error("Device has no CanvasContext"); } return this.canvasContext; } createTexture(props) { if (props instanceof Promise || typeof props === "string") { props = { data: props }; } return this._createTexture(props); } createCommandEncoder(props = {}) { throw new Error("not implemented"); } readPixelsToArrayWebGL(source, options) { throw new Error("not implemented"); } readPixelsToBufferWebGL(source, options) { throw new Error("not implemented"); } setParametersWebGL(parameters) { throw new Error("not implemented"); } getParametersWebGL(parameters) { throw new Error("not implemented"); } withParametersWebGL(parameters, func) { throw new Error("not implemented"); } clearWebGL(options) { throw new Error("not implemented"); } resetWebGL() { throw new Error("not implemented"); } timestamp = 0; incrementTimestamp() { return this.timestamp++; } onError(error) { this.props.onError(error); } _getBufferProps(props) { if (props instanceof ArrayBuffer || ArrayBuffer.isView(props)) { props = { data: props }; } const newProps = { ...props }; if ((props.usage || 0) & Buffer2.INDEX && !props.indexType) { if (props.data instanceof Uint32Array) { newProps.indexType = "uint32"; } else if (props.data instanceof Uint16Array) { newProps.indexType = "uint16"; } else { log.warn("indices buffer content must be of integer type")(); } } return newProps; } }; var Device = _Device; __publicField(Device, "defaultProps", { id: null, canvas: null, container: null, manageState: true, width: 800, height: 600, requestMaxLimits: true, debug: Boolean(log.get("debug")), spector: Boolean(log.get("spector") || log.get("spectorjs")), break: [], initalizeFeatures: true, disabledFeatures: { "compilation-status-async-webgl": true }, gl: null, onError: (error) => log.error(error.message) }); __publicField(Device, "VERSION", VERSION2); // ../../node_modules/@luma.gl/core/dist/utils/assert.js function assert2(condition, message2) { if (!condition) { throw new Error(message2 || "luma.gl: assertion failed."); } } // ../../node_modules/@luma.gl/core/dist/lib/luma.js var deviceMap = /* @__PURE__ */ new Map(); var _luma = class { static registerDevices(deviceClasses) { for (const deviceClass of deviceClasses) { assert2(deviceClass.type && deviceClass.isSupported && deviceClass.create); deviceMap.set(deviceClass.type, deviceClass); } } static getAvailableDevices() { return Array.from(deviceMap).map((Device3) => Device3.type); } static getSupportedDevices() { return Array.from(deviceMap).filter((Device3) => Device3.isSupported()).map((Device3) => Device3.type); } static setDefaultDeviceProps(props) { Object.assign(Device.defaultProps, props); } static async attachDevice(props) { const devices = getDeviceMap(props.devices) || deviceMap; if (props.handle instanceof WebGL2RenderingContext) { const WebGLDevice2 = devices.get("webgl"); if (WebGLDevice2) { return await WebGLDevice2.attach(props.handle); } } if (props.handle === null) { const UnknownDevice = devices.get("unknown"); if (UnknownDevice) { return await UnknownDevice.attach(null); } } throw new Error("Failed to attach device. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported."); } static async createDevice(props = {}) { props = { ..._luma.defaultProps, ...props }; if (props.gl) { props.type = "webgl"; } const devices = getDeviceMap(props.devices) || deviceMap; let WebGPUDevice; let WebGLDevice2; switch (props.type) { case "webgpu": WebGPUDevice = devices.get("webgpu"); if (WebGPUDevice) { return await WebGPUDevice.create(props); } break; case "webgl": WebGLDevice2 = devices.get("webgl"); if (WebGLDevice2) { return await WebGLDevice2.create(props); } break; case "unknown": const UnknownDevice = devices.get("unknown"); if (UnknownDevice) { return await UnknownDevice.create(props); } break; case "best-available": WebGPUDevice = devices.get("webgpu"); if (WebGPUDevice?.isSupported?.()) { return await WebGPUDevice.create(props); } WebGLDevice2 = devices.get("webgl"); if (WebGLDevice2?.isSupported?.()) { return await WebGLDevice2.create(props); } break; } throw new Error("No matching device found. Ensure `@luma.gl/webgl` and/or `@luma.gl/webgpu` modules are imported."); } static enforceWebGL2(enforce = true) { const prototype = HTMLCanvasElement.prototype; if (!enforce && prototype.originalGetContext) { prototype.getContext = prototype.originalGetContext; prototype.originalGetContext = void 0; return; } prototype.originalGetContext = prototype.getContext; prototype.getContext = function(contextId, options) { if (contextId === "webgl" || contextId === "experimental-webgl") { return this.originalGetContext("webgl2", options); } return this.originalGetContext(contextId, options); }; } }; var luma = _luma; __publicField(luma, "defaultProps", { ...Device.defaultProps, type: "best-available", devices: void 0 }); __publicField(luma, "stats", lumaStats); __publicField(luma, "log", log); function getDeviceMap(deviceClasses) { if (!deviceClasses || deviceClasses?.length === 0) { return null; } const map3 = /* @__PURE__ */ new Map(); for (const deviceClass of deviceClasses) { map3.set(deviceClass.type, deviceClass); } return map3; } // ../../node_modules/@luma.gl/core/dist/adapter/canvas-context.js var isPage = isBrowser() && typeof document !== "undefined"; var isPageLoaded = () => isPage && document.readyState === "complete"; var DEFAULT_CANVAS_CONTEXT_PROPS = { canvas: null, width: 800, height: 600, useDevicePixels: true, autoResize: true, container: null, visible: true, colorSpace: "srgb", alphaMode: "opaque" }; var CanvasContext = class { id; props; canvas; htmlCanvas; offscreenCanvas; type; width = 1; height = 1; resizeObserver; _canvasSizeInfo = { clientWidth: 0, clientHeight: 0, devicePixelRatio: 1 }; static get isPageLoaded() { return isPageLoaded(); } constructor(props) { this.props = { ...DEFAULT_CANVAS_CONTEXT_PROPS, ...props }; props = this.props; if (!isBrowser()) { this.id = "node-canvas-context"; this.type = "node"; this.width = this.props.width; this.height = this.props.height; this.canvas = null; return; } if (!props.canvas) { const canvas2 = createCanvas(props); const container = getContainer(props?.container || null); container.insertBefore(canvas2, container.firstChild); this.canvas = canvas2; if (!props?.visible) { this.canvas.style.visibility = "hidden"; } } else if (typeof props.canvas === "string") { this.canvas = getCanvasFromDOM(props.canvas); } else { this.canvas = props.canvas; } if (this.canvas instanceof HTMLCanvasElement) { this.id = this.canvas.id; this.type = "html-canvas"; this.htmlCanvas = this.canvas; } else { this.id = "offscreen-canvas"; this.type = "offscreen-canvas"; this.offscreenCanvas = this.canvas; } if (this.canvas instanceof HTMLCanvasElement && props.autoResize) { this.resizeObserver = new ResizeObserver((entries) => { for (const entry of entries) { if (entry.target === this.canvas) { this.update(); } } }); this.resizeObserver.observe(this.canvas); } } getDevicePixelRatio(useDevicePixels) { if (typeof OffscreenCanvas !== "undefined" && this.canvas instanceof OffscreenCanvas) { return 1; } useDevicePixels = useDevicePixels === void 0 ? this.props.useDevicePixels : useDevicePixels; if (!useDevicePixels || useDevicePixels <= 0) { return 1; } if (useDevicePixels === true) { const dpr = typeof window !== "undefined" && window.devicePixelRatio; return dpr || 1; } return useDevicePixels; } getPixelSize() { switch (this.type) { case "node": return [this.width, this.height]; case "offscreen-canvas": return [this.canvas.width, this.canvas.height]; case "html-canvas": const dpr = this.getDevicePixelRatio(); const canvas2 = this.canvas; return canvas2.parentElement ? [canvas2.clientWidth * dpr, canvas2.clientHeight * dpr] : [this.canvas.width, this.canvas.height]; default: throw new Error(this.type); } } getAspect() { const [width, height] = this.getPixelSize(); return width / height; } cssToDeviceRatio() { try { const [drawingBufferWidth] = this.getDrawingBufferSize(); const { clientWidth } = this._canvasSizeInfo; return clientWidth ? drawingBufferWidth / clientWidth : 1; } catch { return 1; } } cssToDevicePixels(cssPixel, yInvert = true) { const ratio = this.cssToDeviceRatio(); const [width, height] = this.getDrawingBufferSize(); return scalePixels(cssPixel, ratio, width, height, yInvert); } setDevicePixelRatio(devicePixelRatio, options = {}) { if (!this.htmlCanvas) { return; } let clientWidth = "width" in options ? options.width : this.htmlCanvas.clientWidth; let clientHeight = "height" in options ? options.height : this.htmlCanvas.clientHeight; if (!clientWidth || !clientHeight) { log.log(1, "Canvas clientWidth/clientHeight is 0")(); devicePixelRatio = 1; clientWidth = this.htmlCanvas.width || 1; clientHeight = this.htmlCanvas.height || 1; } const cachedSize = this._canvasSizeInfo; if (cachedSize.clientWidth !== clientWidth || cachedSize.clientHeight !== clientHeight || cachedSize.devicePixelRatio !== devicePixelRatio) { let clampedPixelRatio = devicePixelRatio; const canvasWidth = Math.floor(clientWidth * clampedPixelRatio); const canvasHeight = Math.floor(clientHeight * clampedPixelRatio); this.htmlCanvas.width = canvasWidth; this.htmlCanvas.height = canvasHeight; const [drawingBufferWidth, drawingBufferHeight] = this.getDrawingBufferSize(); if (drawingBufferWidth !== canvasWidth || drawingBufferHeight !== canvasHeight) { clampedPixelRatio = Math.min(drawingBufferWidth / clientWidth, drawingBufferHeight / clientHeight); this.htmlCanvas.width = Math.floor(clientWidth * clampedPixelRatio); this.htmlCanvas.height = Math.floor(clientHeight * clampedPixelRatio); log.warn("Device pixel ratio clamped")(); } this._canvasSizeInfo.clientWidth = clientWidth; this._canvasSizeInfo.clientHeight = clientHeight; this._canvasSizeInfo.devicePixelRatio = devicePixelRatio; } } getDrawingBufferSize() { const gl = this.device.gl; if (!gl) { throw new Error("canvas size"); } return [gl.drawingBufferWidth, gl.drawingBufferHeight]; } _setAutoCreatedCanvasId(id) { if (this.htmlCanvas?.id === "lumagl-auto-created-canvas") { this.htmlCanvas.id = id; } } }; __publicField(CanvasContext, "pageLoaded", getPageLoadPromise()); function getPageLoadPromise() { if (isPageLoaded() || typeof window === "undefined") { return Promise.resolve(); } return new Promise((resolve2) => { window.addEventListener("load", () => resolve2()); }); } function getContainer(container) { if (typeof container === "string") { const element = document.getElementById(container); if (!element && !isPageLoaded()) { throw new Error(`Accessing '${container}' before page was loaded`); } if (!element) { throw new Error(`${container} is not an HTML element`); } return element; } else if (container) { return container; } return document.body; } function getCanvasFromDOM(canvasId) { const canvas2 = document.getElementById(canvasId); if (!canvas2 && !isPageLoaded()) { throw new Error(`Accessing '${canvasId}' before page was loaded`); } if (!(canvas2 instanceof HTMLCanvasElement)) { throw new Error("Object is not a canvas element"); } return canvas2; } function createCanvas(props) { const { width, height } = props; const targetCanvas = document.createElement("canvas"); targetCanvas.id = "lumagl-auto-created-canvas"; targetCanvas.width = width || 1; targetCanvas.height = height || 1; targetCanvas.style.width = Number.isFinite(width) ? `${width}px` : "100%"; targetCanvas.style.height = Number.isFinite(height) ? `${height}px` : "100%"; return targetCanvas; } function scalePixels(pixel, ratio, width, height, yInvert) { const point = pixel; const x = scaleX(point[0], ratio, width); let y = scaleY(point[1], ratio, height, yInvert); let t = scaleX(point[0] + 1, ratio, width); const xHigh = t === width - 1 ? t : t - 1; t = scaleY(point[1] + 1, ratio, height, yInvert); let yHigh; if (yInvert) { t = t === 0 ? t : t + 1; yHigh = y; y = t; } else { yHigh = t === height - 1 ? t : t - 1; } return { x, y, width: Math.max(xHigh - x + 1, 1), height: Math.max(yHigh - y + 1, 1) }; } function scaleX(x, ratio, width) { const r = Math.min(Math.round(x * ratio), width - 1); return r; } function scaleY(y, ratio, height, yInvert) { return yInvert ? Math.max(0, height - 1 - Math.round(y * ratio)) : Math.min(Math.round(y * ratio), height - 1); } // ../../node_modules/@luma.gl/core/dist/adapter/resources/texture.js var _Texture = class extends Resource { get [Symbol.toStringTag]() { return "Texture"; } dimension; format; width; height; depth; updateTimestamp; constructor(device, props, defaultProps3 = _Texture.defaultProps) { super(device, props, defaultProps3); this.dimension = this.props.dimension; this.format = this.props.format; this.width = this.props.width; this.height = this.props.height; this.depth = this.props.depth; this.updateTimestamp = device.incrementTimestamp(); } }; var Texture = _Texture; __publicField(Texture, "defaultProps", { ...Resource.defaultProps, data: null, dimension: "2d", format: "rgba8unorm", width: void 0, height: void 0, depth: 1, mipmaps: true, compressed: false, usage: 0, mipLevels: void 0, samples: void 0, type: void 0, sampler: {}, view: void 0 }); __publicField(Texture, "COPY_SRC", 1); __publicField(Texture, "COPY_DST", 2); __publicField(Texture, "TEXTURE_BINDING", 4); __publicField(Texture, "STORAGE_BINDING", 8); __publicField(Texture, "RENDER_ATTACHMENT", 16); // ../../node_modules/@luma.gl/core/dist/adapter/resources/texture-view.js var _TextureView = class extends Resource { get [Symbol.toStringTag]() { return "TextureView"; } constructor(device, props) { super(device, props, _TextureView.defaultProps); } }; var TextureView = _TextureView; __publicField(TextureView, "defaultProps", { ...Resource.defaultProps, format: void 0, dimension: void 0, aspect: "all", baseMipLevel: 0, mipLevelCount: void 0, baseArrayLayer: 0, arrayLayerCount: void 0 }); // ../../node_modules/@luma.gl/core/dist/lib/compiler-log/format-compiler-log.js function formatCompilerLog(shaderLog, source, options) { let formattedLog = ""; const lines = source.split(/\r?\n/); const log3 = shaderLog.slice().sort((a, b) => a.lineNum - b.lineNum); switch (options?.showSourceCode || "no") { case "all": let currentMessage = 0; for (let lineNum = 1; lineNum <= lines.length; lineNum++) { formattedLog += getNumberedLine(lines[lineNum - 1], lineNum, options); while (log3.length > currentMessage && log3[currentMessage].lineNum === lineNum) { const message2 = log3[currentMessage++]; formattedLog += formatCompilerMessage(message2, lines, message2.lineNum, { ...options, inlineSource: false }); } } return formattedLog; case "issues": case "no": for (const message2 of shaderLog) { formattedLog += formatCompilerMessage(message2, lines, message2.lineNum, { inlineSource: options?.showSourceCode !== "no" }); } return formattedLog; } } function formatCompilerMessage(message2, lines, lineNum, options) { if (options?.inlineSource) { const numberedLines = getNumberedLines(lines, lineNum); const positionIndicator = message2.linePos > 0 ? `${" ".repeat(message2.linePos + 5)}^^^ ` : ""; return ` ${numberedLines}${positionIndicator}${message2.type.toUpperCase()}: ${message2.message} `; } return options?.html ? `
${message2.type.toUpperCase()}: ${message2.message}
` : `${message2.type.toUpperCase()}: ${message2.message}`; } function getNumberedLines(lines, lineNum, options) { let numberedLines = ""; for (let lineIndex = lineNum - 2; lineIndex <= lineNum; lineIndex++) { const sourceLine = lines[lineIndex - 1]; if (sourceLine !== void 0) { numberedLines += getNumberedLine(sourceLine, lineNum, options); } } return numberedLines; } function getNumberedLine(line, lineNum, options) { const escapedLine = options?.html ? escapeHTML(line) : line; return `${padLeft(String(lineNum), 4)}: ${escapedLine}${options?.html ? "
" : "\n"}`; } function padLeft(string, paddedLength) { let result = ""; for (let i = string.length; i < paddedLength; ++i) { result += " "; } return result + string; } function escapeHTML(unsafe) { return unsafe.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'"); } // ../../node_modules/@luma.gl/core/dist/lib/compiler-log/get-shader-info.js function getShaderInfo(source, defaultName) { return { name: getShaderName(source, defaultName), language: "glsl", version: getShaderVersion(source) }; } function getShaderName(shader, defaultName = "unnamed") { const SHADER_NAME_REGEXP = /#define[\s*]SHADER_NAME[\s*]([A-Za-z0-9_-]+)[\s*]/; const match = SHADER_NAME_REGEXP.exec(shader); return match ? match[1] : defaultName; } function getShaderVersion(source) { let version = 100; const words = source.match(/[^\s]+/g); if (words && words.length >= 2 && words[0] === "#version") { const v = parseInt(words[1], 10); if (Number.isFinite(v)) { version = v; } } return version; } // ../../node_modules/@luma.gl/core/dist/adapter/resources/shader.js var _Shader = class extends Resource { get [Symbol.toStringTag]() { return "Shader"; } stage; source; compilationStatus = "pending"; constructor(device, props) { super(device, { id: getShaderIdFromProps(props), ...props }, _Shader.defaultProps); this.stage = this.props.stage; this.source = this.props.source; } getCompilationInfoSync() { return null; } getTranslatedSource() { return null; } async debugShader(trigger = this.props.debug) { switch (trigger) { case "never": return; case "errors": if (this.compilationStatus === "success") { return; } break; case "warnings": case "always": break; } const messages = await this.getCompilationInfo(); if (this.props.debug === "warnings" && messages?.length === 0) { return; } this._displayShaderLog(messages); } _displayShaderLog(messages) { if (typeof document === "undefined" || !document?.createElement) { return; } const shaderName = getShaderInfo(this.source).name; const shaderTitle = `${this.stage} ${shaderName}`; let htmlLog = formatCompilerLog(messages, this.source, { showSourceCode: "all", html: true }); const translatedSource = this.getTranslatedSource(); if (translatedSource) { htmlLog += `

Translated Source



${translatedSource}
`; } const button = document.createElement("Button"); button.innerHTML = `

Shader Compilation Error in ${shaderTitle}



${htmlLog}
`; button.style.top = "10px"; button.style.left = "10px"; button.style.position = "absolute"; button.style.zIndex = "9999"; button.style.width = "100%"; button.style.textAlign = "left"; document.body.appendChild(button); const errors = document.getElementsByClassName("luma-compiler-log-error"); if (errors[0]?.scrollIntoView) { errors[0].scrollIntoView(); } button.onclick = () => { const dataURI = `data:text/plain,${encodeURIComponent(this.source)}`; navigator.clipboard.writeText(dataURI); }; } }; var Shader = _Shader; __publicField(Shader, "defaultProps", { ...Resource.defaultProps, language: "auto", stage: void 0, source: "", sourceMap: null, entryPoint: "main", debug: "errors" }); function getShaderIdFromProps(props) { return getShaderInfo(props.source).name || props.id || uid(`unnamed ${props.stage}-shader`); } // ../../node_modules/@luma.gl/core/dist/adapter/resources/sampler.js var _Sampler = class extends Resource { get [Symbol.toStringTag]() { return "Sampler"; } constructor(device, props) { super(device, props, _Sampler.defaultProps); } }; var Sampler = _Sampler; __publicField(Sampler, "defaultProps", { ...Resource.defaultProps, type: "color-sampler", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge", addressModeW: "clamp-to-edge", magFilter: "nearest", minFilter: "nearest", mipmapFilter: "nearest", lodMinClamp: 0, lodMaxClamp: 32, compare: "less-equal", maxAnisotropy: 1 }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/framebuffer.js var _Framebuffer = class extends Resource { get [Symbol.toStringTag]() { return "Framebuffer"; } width; height; colorAttachments = []; depthStencilAttachment = null; constructor(device, props = {}) { super(device, props, _Framebuffer.defaultProps); this.width = this.props.width; this.height = this.props.height; } resize(size) { let updateSize = !size; if (size) { const [width, height] = Array.isArray(size) ? size : [size.width, size.height]; updateSize = updateSize || height !== this.height || width !== this.width; this.width = width; this.height = height; } if (updateSize) { log.log(2, `Resizing framebuffer ${this.id} to ${this.width}x${this.height}`)(); this.resizeAttachments(this.width, this.height); } } autoCreateAttachmentTextures() { if (this.props.colorAttachments.length === 0 && !this.props.depthStencilAttachment) { throw new Error("Framebuffer has noattachments"); } this.colorAttachments = this.props.colorAttachments.map((attachment2) => { if (typeof attachment2 === "string") { const texture = this.createColorTexture(attachment2); this.attachResource(texture); return texture.view; } if (attachment2 instanceof Texture) { return attachment2.view; } return attachment2; }); const attachment = this.props.depthStencilAttachment; if (attachment) { if (typeof attachment === "string") { const texture = this.createDepthStencilTexture(attachment); this.attachResource(texture); this.depthStencilAttachment = texture.view; } else if (attachment instanceof Texture) { this.depthStencilAttachment = attachment.view; } else { this.depthStencilAttachment = attachment; } } } createColorTexture(format) { return this.device.createTexture({ id: "color-attachment", usage: Texture.RENDER_ATTACHMENT, format, width: this.width, height: this.height }); } createDepthStencilTexture(format) { return this.device.createTexture({ id: "depth-stencil-attachment", usage: Texture.RENDER_ATTACHMENT, format, width: this.width, height: this.height }); } resizeAttachments(width, height) { for (let i = 0; i < this.colorAttachments.length; ++i) { if (this.colorAttachments[i]) { const resizedTexture = this.device._createTexture({ ...this.colorAttachments[i].props, width, height }); this.destroyAttachedResource(this.colorAttachments[i]); this.colorAttachments[i] = resizedTexture.view; this.attachResource(resizedTexture.view); } } if (this.depthStencilAttachment) { const resizedTexture = this.device._createTexture({ ...this.depthStencilAttachment.props, width, height }); this.destroyAttachedResource(this.depthStencilAttachment); this.depthStencilAttachment = resizedTexture.view; this.attachResource(resizedTexture); } } }; var Framebuffer = _Framebuffer; __publicField(Framebuffer, "defaultProps", { ...Resource.defaultProps, width: 1, height: 1, colorAttachments: [], depthStencilAttachment: null }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/render-pipeline.js var _RenderPipeline = class extends Resource { get [Symbol.toStringTag]() { return "RenderPipeline"; } shaderLayout; bufferLayout; linkStatus = "pending"; hash = ""; constructor(device, props) { super(device, props, _RenderPipeline.defaultProps); this.shaderLayout = this.props.shaderLayout; this.bufferLayout = this.props.bufferLayout || []; } setUniformsWebGL(uniforms) { throw new Error("Use uniform blocks"); } }; var RenderPipeline = _RenderPipeline; __publicField(RenderPipeline, "defaultProps", { ...Resource.defaultProps, vs: null, vertexEntryPoint: "vertexMain", vsConstants: {}, fs: null, fragmentEntryPoint: "fragmentMain", fsConstants: {}, shaderLayout: null, bufferLayout: [], topology: "triangle-list", parameters: {}, bindings: {}, uniforms: {} }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/render-pass.js var _RenderPass = class extends Resource { get [Symbol.toStringTag]() { return "RenderPass"; } constructor(device, props) { super(device, props, _RenderPass.defaultProps); } }; var RenderPass = _RenderPass; __publicField(RenderPass, "defaultProps", { ...Resource.defaultProps, framebuffer: null, parameters: void 0, clearColor: [0, 0, 0, 0], clearDepth: 1, clearStencil: 0, depthReadOnly: false, stencilReadOnly: false, discard: false, occlusionQuerySet: void 0, timestampQuerySet: void 0, beginTimestampIndex: void 0, endTimestampIndex: void 0 }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/compute-pipeline.js var _ComputePipeline = class extends Resource { get [Symbol.toStringTag]() { return "ComputePipeline"; } hash = ""; constructor(device, props) { super(device, props, _ComputePipeline.defaultProps); } }; var ComputePipeline = _ComputePipeline; __publicField(ComputePipeline, "defaultProps", { ...Resource.defaultProps, shader: void 0, entryPoint: void 0, constants: {}, shaderLayout: void 0 }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/command-encoder.js var _CommandEncoder = class extends Resource { get [Symbol.toStringTag]() { return "CommandEncoder"; } constructor(device, props) { super(device, props, _CommandEncoder.defaultProps); } }; var CommandEncoder = _CommandEncoder; __publicField(CommandEncoder, "defaultProps", { ...Resource.defaultProps, measureExecutionTime: void 0 }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/command-buffer.js var _CommandBuffer = class extends Resource { get [Symbol.toStringTag]() { return "CommandBuffer"; } constructor(device, props) { super(device, props, _CommandBuffer.defaultProps); } }; var CommandBuffer = _CommandBuffer; __publicField(CommandBuffer, "defaultProps", { ...Resource.defaultProps }); // ../../node_modules/@luma.gl/core/dist/adapter/type-utils/decode-attribute-type.js function decodeShaderAttributeType(attributeType) { const [dataType, components] = TYPE_INFO[attributeType]; const integer = dataType === "i32" || dataType === "u32"; const signed = dataType !== "u32"; const byteLength = TYPE_SIZES2[dataType] * components; const defaultVertexFormat = getCompatibleVertexFormat(dataType, components); return { dataType, components, defaultVertexFormat, byteLength, integer, signed }; } function getCompatibleVertexFormat(dataType, components) { let vertexType; switch (dataType) { case "f32": vertexType = "float32"; break; case "i32": vertexType = "sint32"; break; case "u32": vertexType = "uint32"; break; case "f16": return components <= 2 ? "float16x2" : "float16x4"; } if (components === 1) { return vertexType; } return `${vertexType}x${components}`; } var TYPE_INFO = { f32: ["f32", 1], "vec2": ["f32", 2], "vec3": ["f32", 3], "vec4": ["f32", 4], f16: ["f16", 1], "vec2": ["f16", 2], "vec3": ["f16", 3], "vec4": ["f16", 4], i32: ["i32", 1], "vec2": ["i32", 2], "vec3": ["i32", 3], "vec4": ["i32", 4], u32: ["u32", 1], "vec2": ["u32", 2], "vec3": ["u32", 3], "vec4": ["u32", 4] }; var TYPE_SIZES2 = { f32: 4, f16: 2, i32: 4, u32: 4 }; // ../../node_modules/@luma.gl/core/dist/adapter/type-utils/decode-vertex-format.js function decodeVertexFormat(format) { let webglOnly; if (format.endsWith("-webgl")) { format.replace("-webgl", ""); webglOnly = true; } const [type_, count2] = format.split("x"); const type = type_; const components = count2 ? parseInt(count2) : 1; const decodedType = decodeVertexType(type); const result = { type, components, byteLength: decodedType.byteLength * components, integer: decodedType.integer, signed: decodedType.signed, normalized: decodedType.normalized }; if (webglOnly) { result.webglOnly = true; } return result; } // ../../node_modules/@luma.gl/core/dist/adapter/attribute-utils/get-attribute-from-layouts.js function getAttributeInfosFromLayouts(shaderLayout, bufferLayout) { const attributeInfos = {}; for (const attribute of shaderLayout.attributes) { attributeInfos[attribute.name] = getAttributeInfoFromLayouts(shaderLayout, bufferLayout, attribute.name); } return attributeInfos; } function getAttributeInfosByLocation(shaderLayout, bufferLayout, maxVertexAttributes = 16) { const attributeInfos = getAttributeInfosFromLayouts(shaderLayout, bufferLayout); const locationInfos = new Array(maxVertexAttributes).fill(null); for (const attributeInfo of Object.values(attributeInfos)) { locationInfos[attributeInfo.location] = attributeInfo; } return locationInfos; } function getAttributeInfoFromLayouts(shaderLayout, bufferLayout, name2) { const shaderDeclaration = getAttributeFromShaderLayout(shaderLayout, name2); const bufferMapping = getAttributeFromBufferLayout(bufferLayout, name2); if (!shaderDeclaration) { return null; } const attributeTypeInfo = decodeShaderAttributeType(shaderDeclaration.type); const vertexFormat = bufferMapping?.vertexFormat || attributeTypeInfo.defaultVertexFormat; const vertexFormatInfo = decodeVertexFormat(vertexFormat); return { attributeName: bufferMapping?.attributeName || shaderDeclaration.name, bufferName: bufferMapping?.bufferName || shaderDeclaration.name, location: shaderDeclaration.location, shaderType: shaderDeclaration.type, shaderDataType: attributeTypeInfo.dataType, shaderComponents: attributeTypeInfo.components, vertexFormat, bufferDataType: vertexFormatInfo.type, bufferComponents: vertexFormatInfo.components, normalized: vertexFormatInfo.normalized, integer: attributeTypeInfo.integer, stepMode: bufferMapping?.stepMode || shaderDeclaration.stepMode, byteOffset: bufferMapping?.byteOffset || 0, byteStride: bufferMapping?.byteStride || 0 }; } function getAttributeFromShaderLayout(shaderLayout, name2) { const attribute = shaderLayout.attributes.find((attr) => attr.name === name2); if (!attribute) { log.warn(`shader layout attribute "${name2}" not present in shader`); } return attribute || null; } function getAttributeFromBufferLayout(bufferLayouts, name2) { checkBufferLayouts(bufferLayouts); let bufferLayoutInfo = getAttributeFromShortHand(bufferLayouts, name2); if (bufferLayoutInfo) { return bufferLayoutInfo; } bufferLayoutInfo = getAttributeFromAttributesList(bufferLayouts, name2); if (bufferLayoutInfo) { return bufferLayoutInfo; } log.warn(`layout for attribute "${name2}" not present in buffer layout`); return null; } function checkBufferLayouts(bufferLayouts) { for (const bufferLayout of bufferLayouts) { if (bufferLayout.attributes && bufferLayout.format || !bufferLayout.attributes && !bufferLayout.format) { log.warn(`BufferLayout ${name} must have either 'attributes' or 'format' field`); } } } function getAttributeFromShortHand(bufferLayouts, name2) { for (const bufferLayout of bufferLayouts) { if (bufferLayout.format && bufferLayout.name === name2) { return { attributeName: bufferLayout.name, bufferName: name2, stepMode: bufferLayout.stepMode, vertexFormat: bufferLayout.format, byteOffset: 0, byteStride: bufferLayout.byteStride || 0 }; } } return null; } function getAttributeFromAttributesList(bufferLayouts, name2) { for (const bufferLayout of bufferLayouts) { let byteStride = bufferLayout.byteStride; if (typeof bufferLayout.byteStride !== "number") { for (const attributeMapping2 of bufferLayout.attributes || []) { const info = decodeVertexFormat(attributeMapping2.format); byteStride += info.byteLength; } } const attributeMapping = bufferLayout.attributes?.find((mapping) => mapping.attribute === name2); if (attributeMapping) { return { attributeName: attributeMapping.attribute, bufferName: bufferLayout.name, stepMode: bufferLayout.stepMode, vertexFormat: attributeMapping.format, byteOffset: attributeMapping.byteOffset, byteStride }; } } return null; } function mergeShaderLayout(baseLayout, overrideLayout) { const mergedLayout = { ...baseLayout, attributes: baseLayout.attributes.map((attribute) => ({ ...attribute })) }; for (const attribute of overrideLayout?.attributes || []) { const baseAttribute = mergedLayout.attributes.find((attr) => attr.name === attribute.name); if (!baseAttribute) { log.warn(`shader layout attribute ${attribute.name} not present in shader`); } else { baseAttribute.type = attribute.type || baseAttribute.type; baseAttribute.stepMode = attribute.stepMode || baseAttribute.stepMode; } } return mergedLayout; } // ../../node_modules/@luma.gl/core/dist/adapter/resources/vertex-array.js var _VertexArray = class extends Resource { get [Symbol.toStringTag]() { return "VertexArray"; } maxVertexAttributes; attributeInfos; indexBuffer = null; attributes; constructor(device, props) { super(device, props, _VertexArray.defaultProps); this.maxVertexAttributes = device.limits.maxVertexAttributes; this.attributes = new Array(this.maxVertexAttributes).fill(null); this.attributeInfos = getAttributeInfosByLocation(props.renderPipeline.shaderLayout, props.renderPipeline.bufferLayout, this.maxVertexAttributes); } setConstantWebGL(location, value) { throw new Error("constant attributes not supported"); } }; var VertexArray = _VertexArray; __publicField(VertexArray, "defaultProps", { ...Resource.defaultProps, renderPipeline: null }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/transform-feedback.js var _TransformFeedback = class extends Resource { get [Symbol.toStringTag]() { return "TransformFeedback"; } constructor(device, props) { super(device, props, _TransformFeedback.defaultProps); } }; var TransformFeedback = _TransformFeedback; __publicField(TransformFeedback, "defaultProps", { ...Resource.defaultProps, layout: void 0, buffers: {} }); // ../../node_modules/@luma.gl/core/dist/adapter/resources/query-set.js var _QuerySet = class extends Resource { get [Symbol.toStringTag]() { return "QuerySet"; } constructor(device, props) { super(device, props, _QuerySet.defaultProps); } }; var QuerySet = _QuerySet; __publicField(QuerySet, "defaultProps", { ...Resource.defaultProps, type: void 0, count: void 0 }); // ../../node_modules/@luma.gl/core/dist/adapter/type-utils/decode-shader-types.js var UNIFORM_FORMATS = { f32: { type: "f32", components: 1 }, i32: { type: "i32", components: 1 }, u32: { type: "u32", components: 1 }, "vec2": { type: "f32", components: 2 }, "vec3": { type: "f32", components: 3 }, "vec4": { type: "f32", components: 4 }, "vec2": { type: "i32", components: 2 }, "vec3": { type: "i32", components: 3 }, "vec4": { type: "i32", components: 4 }, "vec2": { type: "u32", components: 2 }, "vec3": { type: "u32", components: 3 }, "vec4": { type: "u32", components: 4 }, "mat2x2": { type: "f32", components: 4 }, "mat2x3": { type: "f32", components: 6 }, "mat2x4": { type: "f32", components: 8 }, "mat3x2": { type: "f32", components: 6 }, "mat3x3": { type: "f32", components: 9 }, "mat3x4": { type: "f32", components: 12 }, "mat4x2": { type: "f32", components: 8 }, "mat4x3": { type: "f32", components: 12 }, "mat4x4": { type: "f32", components: 16 } }; function decodeShaderUniformType(format) { const decoded = UNIFORM_FORMATS[format]; assert2(format); return decoded; } function alignTo(size, count2) { switch (count2) { case 1: return size; case 2: return size + size % 2; default: return size + (4 - size % 4) % 4; } } // ../../node_modules/@luma.gl/core/dist/utils/array-utils-flat.js var arrayBuffer; function getScratchArrayBuffer(byteLength) { if (!arrayBuffer || arrayBuffer.byteLength < byteLength) { arrayBuffer = new ArrayBuffer(byteLength); } return arrayBuffer; } function getScratchArray(Type2, length4) { const scratchArrayBuffer = getScratchArrayBuffer(Type2.BYTES_PER_ELEMENT * length4); return new Type2(scratchArrayBuffer, 0, length4); } function fillArray(options) { const { target, source, start = 0, count: count2 = 1 } = options; const length4 = source.length; const total = count2 * length4; let copied = 0; for (let i = start; copied < length4; copied++) { target[i++] = source[copied]; } while (copied < total) { if (copied < total - copied) { target.copyWithin(start + copied, start, start + copied); copied *= 2; } else { target.copyWithin(start + copied, start, start + total - copied); copied = total; } } return options.target; } // ../../node_modules/@luma.gl/core/dist/lib/uniforms/uniform-buffer-layout.js var minBufferSize = 1024; var UniformBufferLayout = class { layout = {}; byteLength; constructor(uniformTypes) { let size = 0; for (const [key, uniformType] of Object.entries(uniformTypes)) { const typeAndComponents = decodeShaderUniformType(uniformType); const { type, components: count2 } = typeAndComponents; size = alignTo(size, count2); const offset = size; size += count2; this.layout[key] = { type, size: count2, offset }; } size += (4 - size % 4) % 4; const actualByteLength = size * 4; this.byteLength = Math.max(actualByteLength, minBufferSize); } getData(uniformValues) { const bufferSize = Math.max(this.byteLength, minBufferSize); const arrayBuffer2 = getScratchArrayBuffer(bufferSize); const typedArrays = { i32: new Int32Array(arrayBuffer2), u32: new Uint32Array(arrayBuffer2), f32: new Float32Array(arrayBuffer2), f16: new Uint16Array(arrayBuffer2) }; for (const [name2, value] of Object.entries(uniformValues)) { const uniformLayout = this.layout[name2]; if (!uniformLayout) { log.warn(`Supplied uniform value ${name2} not present in uniform block layout`)(); continue; } const { type, size, offset } = uniformLayout; const typedArray = typedArrays[type]; if (size === 1) { if (typeof value !== "number" && typeof value !== "boolean") { log.warn(`Supplied value for single component uniform ${name2} is not a number: ${value}`)(); continue; } typedArray[offset] = Number(value); } else { const numericArray = isNumberArray(value); if (!numericArray) { log.warn(`Supplied value for multi component / array uniform ${name2} is not a numeric array: ${value}`)(); continue; } typedArray.set(numericArray, offset); } } return new Uint8Array(arrayBuffer2); } has(name2) { return Boolean(this.layout[name2]); } get(name2) { const layout = this.layout[name2]; return layout; } }; // ../../node_modules/@luma.gl/core/dist/utils/array-equal.js function arrayEqual(a, b, limit = 16) { if (a !== b) { return false; } const arrayA = isNumberArray(a); if (!arrayA) { return false; } const arrayB = isNumberArray(b); if (arrayB && arrayA.length === arrayB.length) { for (let i = 0; i < arrayA.length; ++i) { if (arrayB[i] !== arrayA[i]) { return false; } } } return true; } function arrayCopy(a) { const numberArray = isNumberArray(a); if (numberArray) { return numberArray.slice(); } return a; } // ../../node_modules/@luma.gl/core/dist/lib/uniforms/uniform-block.js var UniformBlock = class { name; uniforms = {}; modifiedUniforms = {}; modified = true; bindingLayout = {}; needsRedraw = "initialized"; constructor(props) { this.name = props?.name; if (props?.name && props?.shaderLayout) { const binding = props?.shaderLayout.bindings?.find((binding2) => binding2.type === "uniform" && binding2.name === props?.name); if (!binding) { throw new Error(props?.name); } const uniformBlock = binding; for (const uniform of uniformBlock.uniforms || []) { this.bindingLayout[uniform.name] = uniform; } } } setUniforms(uniforms) { for (const [key, value] of Object.entries(uniforms)) { this._setUniform(key, value); if (!this.needsRedraw) { this.setNeedsRedraw(`${this.name}.${key}=${value}`); } } } setNeedsRedraw(reason) { this.needsRedraw = this.needsRedraw || reason; } getAllUniforms() { this.modifiedUniforms = {}; this.needsRedraw = false; return this.uniforms || {}; } _setUniform(key, value) { if (arrayEqual(this.uniforms[key], value)) { return; } this.uniforms[key] = arrayCopy(value); this.modifiedUniforms[key] = true; this.modified = true; } }; // ../../node_modules/@luma.gl/core/dist/lib/uniforms/uniform-store.js var UniformStore = class { uniformBlocks = /* @__PURE__ */ new Map(); uniformBufferLayouts = /* @__PURE__ */ new Map(); uniformBuffers = /* @__PURE__ */ new Map(); constructor(blocks) { for (const [bufferName, block] of Object.entries(blocks)) { const uniformBufferName = bufferName; const uniformBufferLayout = new UniformBufferLayout(block.uniformTypes || {}); this.uniformBufferLayouts.set(uniformBufferName, uniformBufferLayout); const uniformBlock = new UniformBlock({ name: bufferName }); uniformBlock.setUniforms(block.defaultUniforms || {}); this.uniformBlocks.set(uniformBufferName, uniformBlock); } } destroy() { for (const uniformBuffer of this.uniformBuffers.values()) { uniformBuffer.destroy(); } } setUniforms(uniforms) { for (const [blockName, uniformValues] of Object.entries(uniforms)) { this.uniformBlocks.get(blockName).setUniforms(uniformValues); } this.updateUniformBuffers(); } getUniformBufferByteLength(uniformBufferName) { return this.uniformBufferLayouts.get(uniformBufferName).byteLength; } getUniformBufferData(uniformBufferName) { const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms(); return this.uniformBufferLayouts.get(uniformBufferName).getData(uniformValues); } createUniformBuffer(device, uniformBufferName, uniforms) { if (uniforms) { this.setUniforms(uniforms); } const byteLength = this.getUniformBufferByteLength(uniformBufferName); const uniformBuffer = device.createBuffer({ usage: Buffer2.UNIFORM | Buffer2.COPY_DST, byteLength }); const uniformBufferData = this.getUniformBufferData(uniformBufferName); uniformBuffer.write(uniformBufferData); return uniformBuffer; } getManagedUniformBuffer(device, uniformBufferName) { if (!this.uniformBuffers.get(uniformBufferName)) { const byteLength = this.getUniformBufferByteLength(uniformBufferName); const uniformBuffer = device.createBuffer({ usage: Buffer2.UNIFORM | Buffer2.COPY_DST, byteLength }); this.uniformBuffers.set(uniformBufferName, uniformBuffer); } return this.uniformBuffers.get(uniformBufferName); } updateUniformBuffers() { let reason = false; for (const uniformBufferName of this.uniformBlocks.keys()) { const bufferReason = this.updateUniformBuffer(uniformBufferName); reason ||= bufferReason; } if (reason) { log.log(3, `UniformStore.updateUniformBuffers(): ${reason}`)(); } return reason; } updateUniformBuffer(uniformBufferName) { const uniformBlock = this.uniformBlocks.get(uniformBufferName); const uniformBuffer = this.uniformBuffers.get(uniformBufferName); let reason = false; if (uniformBuffer && uniformBlock.needsRedraw) { reason ||= uniformBlock.needsRedraw; const uniformBufferData = this.getUniformBufferData(uniformBufferName); const uniformBuffer2 = this.uniformBuffers.get(uniformBufferName); uniformBuffer2.write(uniformBufferData); const uniformValues = this.uniformBlocks.get(uniformBufferName).getAllUniforms(); log.log(4, `Writing to uniform buffer ${String(uniformBufferName)}`, uniformBufferData, uniformValues)(); } return reason; } }; // ../../node_modules/@luma.gl/core/dist/adapter/type-utils/vertex-format-from-attribute.js function getDataTypeFromTypedArray(arrayOrType) { const type = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType; switch (type) { case Float32Array: return "float32"; case Uint16Array: return "uint16"; case Uint32Array: return "uint32"; case Uint8Array: case Uint8ClampedArray: return "uint8"; case Int8Array: return "sint8"; case Int16Array: return "sint16"; case Int32Array: return "sint32"; default: throw new Error(type.constructor.name); } } function getTypedArrayFromDataType(dataType) { switch (dataType) { case "float32": return Float32Array; case "uint32": return Uint32Array; case "sint32": return Int32Array; case "uint16": case "unorm16": return Uint16Array; case "sint16": case "snorm16": return Int16Array; case "uint8": case "unorm8": return Uint8Array; case "sint8": case "snorm8": return Int8Array; default: throw new Error(dataType); } } function getVertexFormatFromAttribute(typedArray, size, normalized) { if (!size || size > 4) { throw new Error(`size ${size}`); } const components = size; let dataType = getDataTypeFromTypedArray(typedArray); if (dataType === "uint8" && normalized && components === 1) { return "unorm8-webgl"; } if (dataType === "uint8" && normalized && components === 3) { return "unorm8x3-webgl"; } if (dataType === "uint8" || dataType === "sint8") { if (components === 1 || components === 3) { throw new Error(`size: ${size}`); } if (normalized) { dataType = dataType.replace("int", "norm"); } return `${dataType}x${components}`; } if (dataType === "uint16" || dataType === "sint16") { if (components === 1 || components === 3) { throw new Error(`size: ${size}`); } if (normalized) { dataType = dataType.replace("int", "norm"); } return `${dataType}x${components}`; } if (components === 1) { return dataType; } return `${dataType}x${components}`; } // ../../node_modules/@luma.gl/core/dist/utils/cast.js function cast(value) { return value; } // ../../node_modules/@luma.gl/core/dist/lib/uniforms/uniform.js function isUniformValue(value) { return isNumberArray(value) !== null || typeof value === "number" || typeof value === "boolean"; } function splitUniformsAndBindings(uniforms) { const result = { bindings: {}, uniforms: {} }; Object.keys(uniforms).forEach((name2) => { const uniform = uniforms[name2]; if (isUniformValue(uniform)) { result.uniforms[name2] = uniform; } else { result.bindings[name2] = uniform; } }); return result; } // ../../node_modules/@luma.gl/core/dist/utils/check-props.js function checkProps(className, props, propChecks) { const { removedProps = {}, deprecatedProps = {}, replacedProps = {} } = propChecks; for (const propName in removedProps) { if (propName in props) { const replacementProp = removedProps[propName]; const replacement = replacementProp ? `${className}.${removedProps[propName]}` : "N/A"; log.removed(`${className}.${propName}`, replacement)(); } } for (const propName in deprecatedProps) { if (propName in props) { const replacementProp = deprecatedProps[propName]; log.deprecated(`${className}.${propName}`, `${className}.${replacementProp}`)(); } } let newProps = null; for (const [propName, replacementProp] of Object.entries(replacedProps)) { if (propName in props) { log.deprecated(`${className}.${propName}`, `${className}.${replacementProp}`)(); newProps = newProps || Object.assign({}, props); newProps[replacementProp] = props[propName]; delete newProps[propName]; } } return newProps || props; } // ../../node_modules/@luma.gl/core/dist/utils/load-file.js var pathPrefix = ""; async function loadImage(url, opts) { return await new Promise((resolve2, reject) => { try { const image = new Image(); image.onload = () => resolve2(image); image.onerror = () => reject(new Error(`Could not load image ${url}.`)); image.crossOrigin = opts?.crossOrigin || "anonymous"; image.src = url.startsWith("http") ? url : pathPrefix + url; } catch (error) { reject(error); } }); } async function loadScript(scriptUrl, scriptId) { const head = document.getElementsByTagName("head")[0]; if (!head) { throw new Error("loadScript"); } const script = document.createElement("script"); script.setAttribute("type", "text/javascript"); script.setAttribute("src", scriptUrl); if (scriptId) { script.id = scriptId; } return new Promise((resolve2, reject) => { script.onload = resolve2; script.onerror = (error) => reject(new Error(`Unable to load script '${scriptUrl}': ${error}`)); head.appendChild(script); }); } // ../../node_modules/@luma.gl/core/dist/utils/deep-equal.js function deepEqual(a, b, depth) { if (a === b) { return true; } if (!depth || !a || !b) { return false; } if (Array.isArray(a)) { if (!Array.isArray(b) || a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!deepEqual(a[i], b[i], depth - 1)) { return false; } } return true; } if (Array.isArray(b)) { return false; } if (typeof a === "object" && typeof b === "object") { const aKeys = Object.keys(a); const bKeys = Object.keys(b); if (aKeys.length !== bKeys.length) { return false; } for (const key of aKeys) { if (!b.hasOwnProperty(key)) { return false; } if (!deepEqual(a[key], b[key], depth - 1)) { return false; } } return true; } return false; } // ../../node_modules/@luma.gl/core/dist/utils/request-animation-frame.js function requestAnimationFrame2(callback) { return typeof window !== "undefined" && window.requestAnimationFrame ? window.requestAnimationFrame(callback) : setTimeout(callback, 1e3 / 60); } function cancelAnimationFrame(timerId) { return typeof window !== "undefined" && window.cancelAnimationFrame ? window.cancelAnimationFrame(timerId) : clearTimeout(timerId); } // ../../node_modules/@luma.gl/engine/dist/animation/timeline.js var channelHandles = 1; var animationHandles = 1; var Timeline = class { time = 0; channels = /* @__PURE__ */ new Map(); animations = /* @__PURE__ */ new Map(); playing = false; lastEngineTime = -1; constructor() { } addChannel(props) { const { delay = 0, duration = Number.POSITIVE_INFINITY, rate = 1, repeat = 1 } = props; const channelId = channelHandles++; const channel = { time: 0, delay, duration, rate, repeat }; this._setChannelTime(channel, this.time); this.channels.set(channelId, channel); return channelId; } removeChannel(channelId) { this.channels.delete(channelId); for (const [animationHandle, animation] of this.animations) { if (animation.channel === channelId) { this.detachAnimation(animationHandle); } } } isFinished(channelId) { const channel = this.channels.get(channelId); if (channel === void 0) { return false; } return this.time >= channel.delay + channel.duration * channel.repeat; } getTime(channelId) { if (channelId === void 0) { return this.time; } const channel = this.channels.get(channelId); if (channel === void 0) { return -1; } return channel.time; } setTime(time) { this.time = Math.max(0, time); const channels = this.channels.values(); for (const channel of channels) { this._setChannelTime(channel, this.time); } const animations = this.animations.values(); for (const animationData of animations) { const { animation, channel } = animationData; animation.setTime(this.getTime(channel)); } } play() { this.playing = true; } pause() { this.playing = false; this.lastEngineTime = -1; } reset() { this.setTime(0); } attachAnimation(animation, channelHandle) { const animationHandle = animationHandles++; this.animations.set(animationHandle, { animation, channel: channelHandle }); animation.setTime(this.getTime(channelHandle)); return animationHandle; } detachAnimation(channelId) { this.animations.delete(channelId); } update(engineTime) { if (this.playing) { if (this.lastEngineTime === -1) { this.lastEngineTime = engineTime; } this.setTime(this.time + (engineTime - this.lastEngineTime)); this.lastEngineTime = engineTime; } } _setChannelTime(channel, time) { const offsetTime = time - channel.delay; const totalDuration = channel.duration * channel.repeat; if (offsetTime >= totalDuration) { channel.time = channel.duration * channel.rate; } else { channel.time = Math.max(0, offsetTime) % channel.duration; channel.time *= channel.rate; } } }; // ../../node_modules/@luma.gl/engine/dist/animation-loop/animation-loop.js var statIdCounter = 0; var DEFAULT_ANIMATION_LOOP_PROPS = { device: null, onAddHTML: () => "", onInitialize: async () => { return null; }, onRender: () => { }, onFinalize: () => { }, onError: (error) => console.error(error), stats: luma.stats.get(`animation-loop-${statIdCounter++}`), useDevicePixels: true, autoResizeViewport: false, autoResizeDrawingBuffer: false }; var AnimationLoop = class { device = null; canvas = null; props; animationProps = null; timeline = null; stats; cpuTime; gpuTime; frameRate; display; needsRedraw = "initialized"; _initialized = false; _running = false; _animationFrameId = null; _nextFramePromise = null; _resolveNextFrame = null; _cpuStartTime = 0; constructor(props) { this.props = { ...DEFAULT_ANIMATION_LOOP_PROPS, ...props }; props = this.props; if (!props.device) { throw new Error("No device provided"); } const { useDevicePixels = true } = this.props; this.stats = props.stats || new Stats({ id: "animation-loop-stats" }); this.cpuTime = this.stats.get("CPU Time"); this.gpuTime = this.stats.get("GPU Time"); this.frameRate = this.stats.get("Frame Rate"); this.setProps({ autoResizeViewport: props.autoResizeViewport, autoResizeDrawingBuffer: props.autoResizeDrawingBuffer, useDevicePixels }); this.start = this.start.bind(this); this.stop = this.stop.bind(this); this._onMousemove = this._onMousemove.bind(this); this._onMouseleave = this._onMouseleave.bind(this); } destroy() { this.stop(); this._setDisplay(null); } delete() { this.destroy(); } setNeedsRedraw(reason) { this.needsRedraw = this.needsRedraw || reason; return this; } setProps(props) { if ("autoResizeViewport" in props) { this.props.autoResizeViewport = props.autoResizeViewport || false; } if ("autoResizeDrawingBuffer" in props) { this.props.autoResizeDrawingBuffer = props.autoResizeDrawingBuffer || false; } if ("useDevicePixels" in props) { this.props.useDevicePixels = props.useDevicePixels || false; } return this; } async start() { if (this._running) { return this; } this._running = true; try { let appContext; if (!this._initialized) { this._initialized = true; await this._initDevice(); this._initialize(); await this.props.onInitialize(this._getAnimationProps()); } if (!this._running) { return null; } if (appContext !== false) { this._cancelAnimationFrame(); this._requestAnimationFrame(); } return this; } catch (err) { const error = err instanceof Error ? err : new Error("Unknown error"); this.props.onError(error); throw error; } } stop() { if (this._running) { if (this.animationProps) { this.props.onFinalize(this.animationProps); } this._cancelAnimationFrame(); this._nextFramePromise = null; this._resolveNextFrame = null; this._running = false; } return this; } redraw() { if (this.device?.isLost) { return this; } this._beginFrameTimers(); this._setupFrame(); this._updateAnimationProps(); this._renderFrame(this._getAnimationProps()); this._clearNeedsRedraw(); if (this._resolveNextFrame) { this._resolveNextFrame(this); this._nextFramePromise = null; this._resolveNextFrame = null; } this._endFrameTimers(); return this; } attachTimeline(timeline) { this.timeline = timeline; return this.timeline; } detachTimeline() { this.timeline = null; } waitForRender() { this.setNeedsRedraw("waitForRender"); if (!this._nextFramePromise) { this._nextFramePromise = new Promise((resolve2) => { this._resolveNextFrame = resolve2; }); } return this._nextFramePromise; } async toDataURL() { this.setNeedsRedraw("toDataURL"); await this.waitForRender(); if (this.canvas instanceof HTMLCanvasElement) { return this.canvas.toDataURL(); } throw new Error("OffscreenCanvas"); } _initialize() { this._startEventHandling(); this._initializeAnimationProps(); this._updateAnimationProps(); this._resizeCanvasDrawingBuffer(); this._resizeViewport(); } _setDisplay(display) { if (this.display) { this.display.destroy(); this.display.animationLoop = null; } if (display) { display.animationLoop = this; } this.display = display; } _requestAnimationFrame() { if (!this._running) { return; } this._animationFrameId = requestAnimationFrame2(this._animationFrame.bind(this)); } _cancelAnimationFrame() { if (this._animationFrameId === null) { return; } cancelAnimationFrame(this._animationFrameId); this._animationFrameId = null; } _animationFrame() { if (!this._running) { return; } this.redraw(); this._requestAnimationFrame(); } _renderFrame(animationProps) { if (this.display) { this.display._renderFrame(animationProps); return; } this.props.onRender(this._getAnimationProps()); this.device.submit(); } _clearNeedsRedraw() { this.needsRedraw = false; } _setupFrame() { this._resizeCanvasDrawingBuffer(); this._resizeViewport(); } _initializeAnimationProps() { if (!this.device) { throw new Error("loop"); } this.animationProps = { animationLoop: this, device: this.device, canvas: this.device?.canvasContext?.canvas, timeline: this.timeline, useDevicePixels: this.props.useDevicePixels, needsRedraw: false, width: 1, height: 1, aspect: 1, time: 0, startTime: Date.now(), engineTime: 0, tick: 0, tock: 0, _mousePosition: null }; } _getAnimationProps() { if (!this.animationProps) { throw new Error("animationProps"); } return this.animationProps; } _updateAnimationProps() { if (!this.animationProps) { return; } const { width, height, aspect } = this._getSizeAndAspect(); if (width !== this.animationProps.width || height !== this.animationProps.height) { this.setNeedsRedraw("drawing buffer resized"); } if (aspect !== this.animationProps.aspect) { this.setNeedsRedraw("drawing buffer aspect changed"); } this.animationProps.width = width; this.animationProps.height = height; this.animationProps.aspect = aspect; this.animationProps.needsRedraw = this.needsRedraw; this.animationProps.engineTime = Date.now() - this.animationProps.startTime; if (this.timeline) { this.timeline.update(this.animationProps.engineTime); } this.animationProps.tick = Math.floor(this.animationProps.time / 1e3 * 60); this.animationProps.tock++; this.animationProps.time = this.timeline ? this.timeline.getTime() : this.animationProps.engineTime; } async _initDevice() { this.device = await this.props.device; if (!this.device) { throw new Error("No device provided"); } this.canvas = this.device.canvasContext?.canvas || null; } _createInfoDiv() { if (this.canvas && this.props.onAddHTML) { const wrapperDiv = document.createElement("div"); document.body.appendChild(wrapperDiv); wrapperDiv.style.position = "relative"; const div4 = document.createElement("div"); div4.style.position = "absolute"; div4.style.left = "10px"; div4.style.bottom = "10px"; div4.style.width = "300px"; div4.style.background = "white"; if (this.canvas instanceof HTMLCanvasElement) { wrapperDiv.appendChild(this.canvas); } wrapperDiv.appendChild(div4); const html = this.props.onAddHTML(div4); if (html) { div4.innerHTML = html; } } } _getSizeAndAspect() { if (!this.device) { return { width: 1, height: 1, aspect: 1 }; } const [width, height] = this.device?.canvasContext?.getPixelSize() || [1, 1]; let aspect = 1; const canvas2 = this.device?.canvasContext?.canvas; if (canvas2 && canvas2.clientHeight) { aspect = canvas2.clientWidth / canvas2.clientHeight; } else if (width > 0 && height > 0) { aspect = width / height; } return { width, height, aspect }; } _resizeViewport() { if (this.props.autoResizeViewport && this.device.gl) { this.device.gl.viewport( 0, 0, this.device.gl.drawingBufferWidth, this.device.gl.drawingBufferHeight ); } } _resizeCanvasDrawingBuffer() { if (this.props.autoResizeDrawingBuffer) { this.device?.canvasContext?.resize({ useDevicePixels: this.props.useDevicePixels }); } } _beginFrameTimers() { this.frameRate.timeEnd(); this.frameRate.timeStart(); this.cpuTime.timeStart(); } _endFrameTimers() { this.cpuTime.timeEnd(); } _startEventHandling() { if (this.canvas) { this.canvas.addEventListener("mousemove", this._onMousemove.bind(this)); this.canvas.addEventListener("mouseleave", this._onMouseleave.bind(this)); } } _onMousemove(event) { if (event instanceof MouseEvent) { this._getAnimationProps()._mousePosition = [event.offsetX, event.offsetY]; } } _onMouseleave(event) { this._getAnimationProps()._mousePosition = null; } }; // ../../node_modules/@luma.gl/shadertools/dist/lib/utils/assert.js function assert3(condition, message2) { if (!condition) { throw new Error(message2 || "shadertools: assertion failed."); } } // ../../node_modules/@luma.gl/shadertools/dist/lib/filters/prop-types.js var DEFAULT_PROP_VALIDATORS = { number: { type: "number", validate(value, propType) { return Number.isFinite(value) && typeof propType === "object" && (propType.max === void 0 || value <= propType.max) && (propType.min === void 0 || value >= propType.min); } }, array: { type: "array", validate(value, propType) { return Array.isArray(value) || ArrayBuffer.isView(value); } } }; function makePropValidators(propTypes) { const propValidators = {}; for (const [name2, propType] of Object.entries(propTypes)) { propValidators[name2] = makePropValidator(propType); } return propValidators; } function getValidatedProperties(properties, propValidators, errorMessage) { const validated = {}; for (const [key, propsValidator] of Object.entries(propValidators)) { if (properties && key in properties && !propsValidator.private) { if (propsValidator.validate) { assert3(propsValidator.validate(properties[key], propsValidator), `${errorMessage}: invalid ${key}`); } validated[key] = properties[key]; } else { validated[key] = propsValidator.value; } } return validated; } function makePropValidator(propType) { let type = getTypeOf(propType); if (type !== "object") { return { value: propType, ...DEFAULT_PROP_VALIDATORS[type], type }; } if (typeof propType === "object") { if (!propType) { return { type: "object", value: null }; } if (propType.type !== void 0) { return { ...propType, ...DEFAULT_PROP_VALIDATORS[propType.type], type: propType.type }; } if (propType.value === void 0) { return { type: "object", value: propType }; } type = getTypeOf(propType.value); return { ...propType, ...DEFAULT_PROP_VALIDATORS[type], type }; } throw new Error("props"); } function getTypeOf(value) { if (Array.isArray(value) || ArrayBuffer.isView(value)) { return "array"; } return typeof value; } // ../../node_modules/@luma.gl/shadertools/dist/module-injectors.js var MODULE_INJECTORS_VS = `#ifdef MODULE_LOGDEPTH logdepth_adjustPosition(gl_Position); #endif `; var MODULE_INJECTORS_FS = `#ifdef MODULE_MATERIAL gl_FragColor = material_filterColor(gl_FragColor); #endif #ifdef MODULE_LIGHTING gl_FragColor = lighting_filterColor(gl_FragColor); #endif #ifdef MODULE_FOG gl_FragColor = fog_filterColor(gl_FragColor); #endif #ifdef MODULE_PICKING gl_FragColor = picking_filterHighlightColor(gl_FragColor); gl_FragColor = picking_filterPickingColor(gl_FragColor); #endif #ifdef MODULE_LOGDEPTH logdepth_setFragDepth(); #endif `; // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembly/shader-injections.js var MODULE_INJECTORS = { vertex: MODULE_INJECTORS_VS, fragment: MODULE_INJECTORS_FS }; var REGEX_START_OF_MAIN = /void\s+main\s*\([^)]*\)\s*\{\n?/; var REGEX_END_OF_MAIN = /}\n?[^{}]*$/; var fragments = []; var DECLARATION_INJECT_MARKER = "__LUMA_INJECT_DECLARATIONS__"; function normalizeInjections(injections) { const result = { vertex: {}, fragment: {} }; for (const hook in injections) { let injection = injections[hook]; const stage = getHookStage(hook); if (typeof injection === "string") { injection = { order: 0, injection }; } result[stage][hook] = injection; } return result; } function getHookStage(hook) { const type = hook.slice(0, 2); switch (type) { case "vs": return "vertex"; case "fs": return "fragment"; default: throw new Error(type); } } function injectShader(source, stage, inject, injectStandardStubs = false) { const isVertex = stage === "vertex"; for (const key in inject) { const fragmentData = inject[key]; fragmentData.sort((a, b) => a.order - b.order); fragments.length = fragmentData.length; for (let i = 0, len4 = fragmentData.length; i < len4; ++i) { fragments[i] = fragmentData[i].injection; } const fragmentString = `${fragments.join("\n")} `; switch (key) { case "vs:#decl": if (isVertex) { source = source.replace(DECLARATION_INJECT_MARKER, fragmentString); } break; case "vs:#main-start": if (isVertex) { source = source.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString); } break; case "vs:#main-end": if (isVertex) { source = source.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match); } break; case "fs:#decl": if (!isVertex) { source = source.replace(DECLARATION_INJECT_MARKER, fragmentString); } break; case "fs:#main-start": if (!isVertex) { source = source.replace(REGEX_START_OF_MAIN, (match) => match + fragmentString); } break; case "fs:#main-end": if (!isVertex) { source = source.replace(REGEX_END_OF_MAIN, (match) => fragmentString + match); } break; default: source = source.replace(key, (match) => match + fragmentString); } } source = source.replace(DECLARATION_INJECT_MARKER, ""); if (injectStandardStubs) { source = source.replace(/\}\s*$/, (match) => match + MODULE_INJECTORS[stage]); } return source; } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-module/shader-module-instance.js var index = 1; var ShaderModuleInstance = class { name; vs; fs; getModuleUniforms; dependencies; deprecations; defines; injections; uniforms = {}; uniformTypes = {}; static instantiateModules(modules) { return modules.map((module) => { if (module instanceof ShaderModuleInstance) { return module; } assert3(typeof module !== "string", `Shader module use by name is deprecated. Import shader module '${JSON.stringify(module)}' and use it directly.`); if (!module.name) { console.warn("shader module has no name"); module.name = `shader-module-${index++}`; } const moduleObject = new ShaderModuleInstance(module); moduleObject.dependencies = ShaderModuleInstance.instantiateModules(module.dependencies || []); return moduleObject; }); } constructor(props) { const { name: name2, vs: vs7, fs: fs5, dependencies = [], uniformTypes = {}, uniformPropTypes = {}, getUniforms: getUniforms6, deprecations = [], defines: defines2 = {}, inject = {} } = props; assert3(typeof name2 === "string"); this.name = name2; this.vs = vs7; this.fs = fs5; this.getModuleUniforms = getUniforms6; this.dependencies = ShaderModuleInstance.instantiateModules(dependencies); this.deprecations = this._parseDeprecationDefinitions(deprecations); this.defines = defines2; this.injections = normalizeInjections(inject); this.uniformTypes = uniformTypes; if (uniformPropTypes) { this.uniforms = makePropValidators(uniformPropTypes); } } getModuleSource(stage) { let moduleSource; switch (stage) { case "vertex": moduleSource = this.vs || ""; break; case "fragment": moduleSource = this.fs || ""; break; default: assert3(false); } const moduleName = this.name.toUpperCase().replace(/[^0-9a-z]/gi, "_"); return `// ----- MODULE ${this.name} --------------- #define MODULE_${moduleName} ${moduleSource} `; } getUniforms(userProps, uniforms) { if (this.getModuleUniforms) { return this.getModuleUniforms(userProps, uniforms); } return getValidatedProperties(userProps, this.uniforms, this.name); } getDefines() { return this.defines; } checkDeprecations(shaderSource, log3) { this.deprecations.forEach((def) => { if (def.regex?.test(shaderSource)) { if (def.deprecated) { log3.deprecated(def.old, def.new)(); } else { log3.removed(def.old, def.new)(); } } }); } _parseDeprecationDefinitions(deprecations) { deprecations.forEach((def) => { switch (def.type) { case "function": def.regex = new RegExp(`\\b${def.old}\\(`); break; default: def.regex = new RegExp(`${def.type} ${def.old};`); } }); return deprecations; } _defaultGetUniforms(opts = {}) { const uniforms = {}; const propTypes = this.uniforms; for (const key in propTypes) { const propDef = propTypes[key]; if (key in opts && !propDef.private) { if (propDef.validate) { assert3(propDef.validate(opts[key], propDef), `${this.name}: invalid ${key}`); } uniforms[key] = opts[key]; } else { uniforms[key] = propDef.value; } } return uniforms; } }; // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembly/select-shaders.js function selectShaders(props) { if (props.source && props.platformInfo.type === "webgpu") { const propsCopy = { ...props, vs: void 0, fs: void 0 }; return propsCopy; } if (!props.vs) { throw new Error("no vertex shader"); } const vs7 = getShaderSource(props.platformInfo, props.vs); let fs5; if (props.fs) { fs5 = getShaderSource(props.platformInfo, props.fs); } return { ...props, vs: vs7, fs: fs5 }; } function getShaderSource(platformInfo, shader) { if (typeof shader === "string") { return shader; } switch (platformInfo.type) { case "webgpu": if (shader?.wgsl) { return shader.wgsl; } throw new Error("WebGPU does not support GLSL shaders"); default: if (shader?.glsl) { return shader.glsl; } throw new Error("WebGL does not support WGSL shaders"); } } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembly/resolve-modules.js function resolveModules(modules) { const instances = ShaderModuleInstance.instantiateModules(modules); return getShaderDependencies(instances); } function getShaderDependencies(modules) { const moduleMap = {}; const moduleDepth = {}; getDependencyGraph({ modules, level: 0, moduleMap, moduleDepth }); return Object.keys(moduleDepth).sort((a, b) => moduleDepth[b] - moduleDepth[a]).map((name2) => moduleMap[name2]); } function getDependencyGraph(options) { const { modules, level, moduleMap, moduleDepth } = options; if (level >= 5) { throw new Error("Possible loop in shader dependency graph"); } for (const module of modules) { moduleMap[module.name] = module; if (moduleDepth[module.name] === void 0 || moduleDepth[module.name] < level) { moduleDepth[module.name] = level; } } for (const module of modules) { if (module.dependencies) { getDependencyGraph({ modules: module.dependencies, level: level + 1, moduleMap, moduleDepth }); } } } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembly/platform-defines.js function getPlatformShaderDefines(platformInfo) { switch (platformInfo?.gpu.toLowerCase()) { case "apple": return `#define APPLE_GPU #define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 #define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 #define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 `; case "nvidia": return `#define NVIDIA_GPU #define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 `; case "intel": return `#define INTEL_GPU #define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 #define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 #define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 `; case "amd": return `#define AMD_GPU `; default: return `#define DEFAULT_GPU #define LUMA_FP64_CODE_ELIMINATION_WORKAROUND 1 #define LUMA_FP32_TAN_PRECISION_WORKAROUND 1 #define LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND 1 `; } } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-transpiler/transpile-glsl-shader.js function transpileGLSLShader(source, stage) { const sourceGLSLVersion = Number(source.match(/^#version[ \t]+(\d+)/m)?.[1] || 100); if (sourceGLSLVersion !== 300) { throw new Error("luma.gl v9 only supports GLSL 3.00 shader sources"); } switch (stage) { case "vertex": source = convertShader(source, ES300_VERTEX_REPLACEMENTS); return source; case "fragment": source = convertShader(source, ES300_FRAGMENT_REPLACEMENTS); return source; default: throw new Error(stage); } } var ES300_REPLACEMENTS = [ [/^(#version[ \t]+(100|300[ \t]+es))?[ \t]*\n/, "#version 300 es\n"], [/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g, "textureLod("], [/\btexture(2D|2DProj|Cube)(EXT)?\(/g, "texture("] ]; var ES300_VERTEX_REPLACEMENTS = [ ...ES300_REPLACEMENTS, [makeVariableTextRegExp("attribute"), "in $1"], [makeVariableTextRegExp("varying"), "out $1"] ]; var ES300_FRAGMENT_REPLACEMENTS = [ ...ES300_REPLACEMENTS, [makeVariableTextRegExp("varying"), "in $1"] ]; function convertShader(source, replacements) { for (const [pattern, replacement] of replacements) { source = source.replace(pattern, replacement); } return source; } function makeVariableTextRegExp(qualifier) { return new RegExp(`\\b${qualifier}[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)`, "g"); } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembly/shader-hooks.js function getShaderHooks(hookFunctions, hookInjections) { let result = ""; for (const hookName in hookFunctions) { const hookFunction = hookFunctions[hookName]; result += `void ${hookFunction.signature} { `; if (hookFunction.header) { result += ` ${hookFunction.header}`; } if (hookInjections[hookName]) { const injections = hookInjections[hookName]; injections.sort((a, b) => a.order - b.order); for (const injection of injections) { result += ` ${injection.injection} `; } } if (hookFunction.footer) { result += ` ${hookFunction.footer}`; } result += "}\n"; } return result; } function normalizeShaderHooks(hookFunctions) { const result = { vertex: {}, fragment: {} }; for (const hookFunction of hookFunctions) { let opts; let hook; if (typeof hookFunction !== "string") { opts = hookFunction; hook = opts.hook; } else { opts = {}; hook = hookFunction; } hook = hook.trim(); const [shaderStage, signature] = hook.split(":"); const name2 = hook.replace(/\(.+/, ""); const normalizedHook = Object.assign(opts, { signature }); switch (shaderStage) { case "vs": result.vertex[name2] = normalizedHook; break; case "fs": result.fragment[name2] = normalizedHook; break; default: throw new Error(shaderStage); } } return result; } // ../../node_modules/@luma.gl/shadertools/dist/lib/glsl-utils/get-shader-info.js function getShaderInfo2(source, defaultName) { return { name: getShaderName2(source, defaultName), language: "glsl", version: getShaderVersion2(source) }; } function getShaderName2(shader, defaultName = "unnamed") { const SHADER_NAME_REGEXP = /#define[^\S\r\n]*SHADER_NAME[^\S\r\n]*([A-Za-z0-9_-]+)\s*/; const match = SHADER_NAME_REGEXP.exec(shader); return match ? match[1] : defaultName; } function getShaderVersion2(source) { let version = 100; const words = source.match(/[^\s]+/g); if (words && words.length >= 2 && words[0] === "#version") { const parsedVersion = parseInt(words[1], 10); if (Number.isFinite(parsedVersion)) { version = parsedVersion; } } if (version !== 100 && version !== 300) { throw new Error(`Invalid GLSL version ${version}`); } return version; } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembly/assemble-shaders.js var INJECT_SHADER_DECLARATIONS = ` ${DECLARATION_INJECT_MARKER} `; var FRAGMENT_SHADER_PROLOGUE = `precision highp float; `; function assembleShaderWGSL(options) { const modules = resolveModules(options.modules || []); return { source: assembleWGSLShader(options.platformInfo, { ...options, source: options.source, stage: "vertex", modules }), getUniforms: assembleGetUniforms(modules) }; } function assembleShaderPairWGSL(options) { const modules = resolveModules(options.modules || []); return { vs: assembleWGSLShader(options.platformInfo, { ...options, source: options.vs, stage: "vertex", modules }), fs: assembleWGSLShader(options.platformInfo, { ...options, source: options.fs, stage: "fragment", modules }), getUniforms: assembleGetUniforms(modules) }; } function assembleShaderPairGLSL(options) { const { vs: vs7, fs: fs5 } = options; const modules = resolveModules(options.modules || []); return { vs: assembleGLSLShader(options.platformInfo, { ...options, source: vs7, stage: "vertex", modules }), fs: assembleGLSLShader(options.platformInfo, { ...options, source: fs5, stage: "fragment", modules }), getUniforms: assembleGetUniforms(modules) }; } function assembleWGSLShader(platformInfo, options) { const { source, stage, modules, hookFunctions = [], inject = {}, log: log3 } = options; assert3(typeof source === "string", "shader source must be a string"); const coreSource = source; let assembledSource = ""; const hookFunctionMap = normalizeShaderHooks(hookFunctions); const hookInjections = {}; const declInjections = {}; const mainInjections = {}; for (const key in inject) { const injection = typeof inject[key] === "string" ? { injection: inject[key], order: 0 } : inject[key]; const match = /^(v|f)s:(#)?([\w-]+)$/.exec(key); if (match) { const hash = match[2]; const name2 = match[3]; if (hash) { if (name2 === "decl") { declInjections[key] = [injection]; } else { mainInjections[key] = [injection]; } } else { hookInjections[key] = [injection]; } } else { mainInjections[key] = [injection]; } } const modulesToInject = platformInfo.type !== "webgpu" ? modules : []; for (const module of modulesToInject) { if (log3) { module.checkDeprecations(coreSource, log3); } const moduleSource = module.getModuleSource(stage, "wgsl"); assembledSource += moduleSource; const injections = module.injections[stage]; for (const key in injections) { const match = /^(v|f)s:#([\w-]+)$/.exec(key); if (match) { const name2 = match[2]; const injectionType = name2 === "decl" ? declInjections : mainInjections; injectionType[key] = injectionType[key] || []; injectionType[key].push(injections[key]); } else { hookInjections[key] = hookInjections[key] || []; hookInjections[key].push(injections[key]); } } } assembledSource += INJECT_SHADER_DECLARATIONS; assembledSource = injectShader(assembledSource, stage, declInjections); assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections); assembledSource += coreSource; assembledSource = injectShader(assembledSource, stage, mainInjections); return assembledSource; } function assembleGLSLShader(platformInfo, options) { const { id, source, stage, language = "glsl", modules, defines: defines2 = {}, hookFunctions = [], inject = {}, prologue = true, log: log3 } = options; assert3(typeof source === "string", "shader source must be a string"); const sourceVersion = language === "glsl" ? getShaderInfo2(source).version : -1; const targetVersion = platformInfo.shaderLanguageVersion; const sourceVersionDirective = sourceVersion === 100 ? "#version 100" : "#version 300 es"; const sourceLines = source.split("\n"); const coreSource = sourceLines.slice(1).join("\n"); const allDefines = {}; modules.forEach((module) => { Object.assign(allDefines, module.getDefines()); }); Object.assign(allDefines, defines2); let assembledSource = ""; switch (language) { case "wgsl": break; case "glsl": assembledSource = prologue ? `${sourceVersionDirective} // ----- PROLOGUE ------------------------- ${getShaderNameDefine({ id, source, stage })} ${`#define SHADER_TYPE_${stage.toUpperCase()}`} ${getPlatformShaderDefines(platformInfo)} ${stage === "fragment" ? FRAGMENT_SHADER_PROLOGUE : ""} // ----- APPLICATION DEFINES ------------------------- ${getApplicationDefines(allDefines)} ` : `${sourceVersionDirective} `; break; } const hookFunctionMap = normalizeShaderHooks(hookFunctions); const hookInjections = {}; const declInjections = {}; const mainInjections = {}; for (const key in inject) { const injection = typeof inject[key] === "string" ? { injection: inject[key], order: 0 } : inject[key]; const match = /^(v|f)s:(#)?([\w-]+)$/.exec(key); if (match) { const hash = match[2]; const name2 = match[3]; if (hash) { if (name2 === "decl") { declInjections[key] = [injection]; } else { mainInjections[key] = [injection]; } } else { hookInjections[key] = [injection]; } } else { mainInjections[key] = [injection]; } } for (const module of modules) { if (log3) { module.checkDeprecations(coreSource, log3); } const moduleSource = module.getModuleSource(stage); assembledSource += moduleSource; const injections = module.injections[stage]; for (const key in injections) { const match = /^(v|f)s:#([\w-]+)$/.exec(key); if (match) { const name2 = match[2]; const injectionType = name2 === "decl" ? declInjections : mainInjections; injectionType[key] = injectionType[key] || []; injectionType[key].push(injections[key]); } else { hookInjections[key] = hookInjections[key] || []; hookInjections[key].push(injections[key]); } } } assembledSource += "// ----- MAIN SHADER SOURCE -------------------------"; assembledSource += INJECT_SHADER_DECLARATIONS; assembledSource = injectShader(assembledSource, stage, declInjections); assembledSource += getShaderHooks(hookFunctionMap[stage], hookInjections); assembledSource += coreSource; assembledSource = injectShader(assembledSource, stage, mainInjections); if (language === "glsl" && sourceVersion !== targetVersion) { assembledSource = transpileGLSLShader(assembledSource, stage); } return assembledSource.trim(); } function assembleGetUniforms(modules) { return function getUniforms6(opts) { const uniforms = {}; for (const module of modules) { const moduleUniforms = module.getUniforms(opts, uniforms); Object.assign(uniforms, moduleUniforms); } return uniforms; }; } function getShaderNameDefine(options) { const { id, source, stage } = options; const injectShaderName = id && source.indexOf("SHADER_NAME") === -1; return injectShaderName ? ` #define SHADER_NAME ${id}_${stage} ` : ""; } function getApplicationDefines(defines2 = {}) { let sourceText = ""; for (const define2 in defines2) { const value = defines2[define2]; if (value || Number.isFinite(value)) { sourceText += `#define ${define2.toUpperCase()} ${defines2[define2]} `; } } return sourceText; } // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-assembler.js var _ShaderAssembler = class { _hookFunctions = []; _defaultModules = []; static getDefaultShaderAssembler() { _ShaderAssembler.defaultShaderAssembler = _ShaderAssembler.defaultShaderAssembler || new _ShaderAssembler(); return _ShaderAssembler.defaultShaderAssembler; } addDefaultModule(module) { if (!this._defaultModules.find((m) => m.name === (typeof module === "string" ? module : module.name))) { this._defaultModules.push(module); } } removeDefaultModule(module) { const moduleName = typeof module === "string" ? module : module.name; this._defaultModules = this._defaultModules.filter((m) => m.name !== moduleName); } addShaderHook(hook, opts) { if (opts) { hook = Object.assign(opts, { hook }); } this._hookFunctions.push(hook); } assembleShader(props) { const modules = this._getModuleList(props.modules); const hookFunctions = this._hookFunctions; const options = selectShaders(props); const assembled = assembleShaderWGSL({ platformInfo: props.platformInfo, ...options, modules, hookFunctions }); return { ...assembled, modules }; } assembleShaderPair(props) { const options = selectShaders(props); const modules = this._getModuleList(props.modules); const hookFunctions = this._hookFunctions; const { platformInfo } = props; const isWGSL = props.platformInfo.shaderLanguage === "wgsl"; const assembled = isWGSL ? assembleShaderPairWGSL({ platformInfo, ...options, modules, hookFunctions }) : assembleShaderPairGLSL({ platformInfo, ...options, modules, hookFunctions }); return { ...assembled, modules }; } _getModuleList(appModules = []) { const modules = new Array(this._defaultModules.length + appModules.length); const seen = {}; let count2 = 0; for (let i = 0, len4 = this._defaultModules.length; i < len4; ++i) { const module = this._defaultModules[i]; const name2 = module.name; modules[count2++] = module; seen[name2] = true; } for (let i = 0, len4 = appModules.length; i < len4; ++i) { const module = appModules[i]; const name2 = module.name; if (!seen[name2]) { modules[count2++] = module; seen[name2] = true; } } modules.length = count2; return ShaderModuleInstance.instantiateModules(modules); } }; var ShaderAssembler = _ShaderAssembler; __publicField(ShaderAssembler, "defaultShaderAssembler"); // ../../node_modules/@luma.gl/shadertools/dist/lib/shader-module/normalize-shader-module.js function normalizeShaderModule(module) { if (!module.normalized) { module.normalized = true; if (module.uniformPropTypes && !module.getUniforms) { const shaderModule = new ShaderModuleInstance(module); module.getUniforms = shaderModule.getUniforms.bind(shaderModule); } } return module; } // ../../node_modules/@luma.gl/shadertools/dist/lib/glsl-utils/shader-utils.js var FS_GLES = `out vec4 transform_output; void main() { transform_output = vec4(0); }`; var FS300 = `#version 300 es ${FS_GLES}`; function getPassthroughFS(options) { const { input, inputChannels, output } = options || {}; if (!input) { return FS300; } if (!inputChannels) { throw new Error("inputChannels"); } const inputType = channelCountToType(inputChannels); const outputValue = convertToVec4(input, inputChannels); return `#version 300 es in ${inputType} ${input}; out vec4 ${output}; void main() { ${output} = ${outputValue}; }`; } function channelCountToType(channels) { switch (channels) { case 1: return "float"; case 2: return "vec2"; case 3: return "vec3"; case 4: return "vec4"; default: throw new Error(`invalid channels: ${channels}`); } } function convertToVec4(variable, channels) { switch (channels) { case 1: return `vec4(${variable}, 0.0, 0.0, 1.0)`; case 2: return `vec4(${variable}, 0.0, 1.0)`; case 3: return `vec4(${variable}, 1.0)`; case 4: return variable; default: throw new Error(`invalid channels: ${channels}`); } } // ../../node_modules/wgsl_reflect/wgsl_reflect.module.js var ParseContext = class { constructor() { this.constants = /* @__PURE__ */ new Map(); this.aliases = /* @__PURE__ */ new Map(); this.structs = /* @__PURE__ */ new Map(); } }; var Node = class { constructor() { } get isAstNode() { return true; } get astNodeType() { return ""; } evaluate(context) { throw new Error("Cannot evaluate node"); } evaluateString(context) { return this.evaluate(context).toString(); } search(callback) { } searchBlock(block, callback) { if (block) { callback(_BlockStart.instance); for (const node of block) { if (node instanceof Array) { this.searchBlock(node, callback); } else { node.search(callback); } } callback(_BlockEnd.instance); } } }; var _BlockStart = class extends Node { }; _BlockStart.instance = new _BlockStart(); var _BlockEnd = class extends Node { }; _BlockEnd.instance = new _BlockEnd(); var Statement = class extends Node { constructor() { super(); } }; var Function = class extends Statement { constructor(name2, args, returnType, body, startLine, endLine) { super(); this.calls = /* @__PURE__ */ new Set(); this.name = name2; this.args = args; this.returnType = returnType; this.body = body; this.startLine = startLine; this.endLine = endLine; } get astNodeType() { return "function"; } search(callback) { this.searchBlock(this.body, callback); } }; var StaticAssert = class extends Statement { constructor(expression) { super(); this.expression = expression; } get astNodeType() { return "staticAssert"; } search(callback) { this.expression.search(callback); } }; var While = class extends Statement { constructor(condition, body) { super(); this.condition = condition; this.body = body; } get astNodeType() { return "while"; } search(callback) { this.condition.search(callback); this.searchBlock(this.body, callback); } }; var Continuing = class extends Statement { constructor(body) { super(); this.body = body; } get astNodeType() { return "continuing"; } search(callback) { this.searchBlock(this.body, callback); } }; var For = class extends Statement { constructor(init, condition, increment, body) { super(); this.init = init; this.condition = condition; this.increment = increment; this.body = body; } get astNodeType() { return "for"; } search(callback) { var _a2, _b, _c; (_a2 = this.init) === null || _a2 === void 0 ? void 0 : _a2.search(callback); (_b = this.condition) === null || _b === void 0 ? void 0 : _b.search(callback); (_c = this.increment) === null || _c === void 0 ? void 0 : _c.search(callback); this.searchBlock(this.body, callback); } }; var Var = class extends Statement { constructor(name2, type, storage, access, value) { super(); this.name = name2; this.type = type; this.storage = storage; this.access = access; this.value = value; } get astNodeType() { return "var"; } search(callback) { var _a2; callback(this); (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback); } }; var Override = class extends Statement { constructor(name2, type, value) { super(); this.name = name2; this.type = type; this.value = value; } get astNodeType() { return "override"; } search(callback) { var _a2; (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback); } }; var Let = class extends Statement { constructor(name2, type, storage, access, value) { super(); this.name = name2; this.type = type; this.storage = storage; this.access = access; this.value = value; } get astNodeType() { return "let"; } search(callback) { var _a2; callback(this); (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback); } }; var Const = class extends Statement { constructor(name2, type, storage, access, value) { super(); this.name = name2; this.type = type; this.storage = storage; this.access = access; this.value = value; } get astNodeType() { return "const"; } evaluate(context) { return this.value.evaluate(context); } search(callback) { var _a2; callback(this); (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback); } }; var IncrementOperator; (function(IncrementOperator2) { IncrementOperator2["increment"] = "++"; IncrementOperator2["decrement"] = "--"; })(IncrementOperator || (IncrementOperator = {})); (function(IncrementOperator2) { function parse2(val) { const key = val; if (key == "parse") throw new Error("Invalid value for IncrementOperator"); return IncrementOperator2[key]; } IncrementOperator2.parse = parse2; })(IncrementOperator || (IncrementOperator = {})); var Increment = class extends Statement { constructor(operator, variable) { super(); this.operator = operator; this.variable = variable; } get astNodeType() { return "increment"; } search(callback) { this.variable.search(callback); } }; var AssignOperator; (function(AssignOperator2) { AssignOperator2["assign"] = "="; AssignOperator2["addAssign"] = "+="; AssignOperator2["subtractAssin"] = "-="; AssignOperator2["multiplyAssign"] = "*="; AssignOperator2["divideAssign"] = "/="; AssignOperator2["moduloAssign"] = "%="; AssignOperator2["andAssign"] = "&="; AssignOperator2["orAssign"] = "|="; AssignOperator2["xorAssign"] = "^="; AssignOperator2["shiftLeftAssign"] = "<<="; AssignOperator2["shiftRightAssign"] = ">>="; })(AssignOperator || (AssignOperator = {})); (function(AssignOperator2) { function parse2(val) { const key = val; if (key == "parse") { throw new Error("Invalid value for AssignOperator"); } return key; } AssignOperator2.parse = parse2; })(AssignOperator || (AssignOperator = {})); var Assign = class extends Statement { constructor(operator, variable, value) { super(); this.operator = operator; this.variable = variable; this.value = value; } get astNodeType() { return "assign"; } search(callback) { this.variable.search(callback); this.value.search(callback); } }; var Call = class extends Statement { constructor(name2, args) { super(); this.name = name2; this.args = args; } get astNodeType() { return "call"; } search(callback) { for (const node of this.args) { node.search(callback); } callback(this); } }; var Loop = class extends Statement { constructor(body, continuing) { super(); this.body = body; this.continuing = continuing; } get astNodeType() { return "loop"; } }; var Switch = class extends Statement { constructor(condition, body) { super(); this.condition = condition; this.body = body; } get astNodeType() { return "body"; } }; var If = class extends Statement { constructor(condition, body, elseif, _else) { super(); this.condition = condition; this.body = body; this.elseif = elseif; this.else = _else; } get astNodeType() { return "if"; } search(callback) { this.condition.search(callback); this.searchBlock(this.body, callback); this.searchBlock(this.elseif, callback); this.searchBlock(this.else, callback); } }; var Return = class extends Statement { constructor(value) { super(); this.value = value; } get astNodeType() { return "return"; } search(callback) { var _a2; (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback); } }; var Enable = class extends Statement { constructor(name2) { super(); this.name = name2; } get astNodeType() { return "enable"; } }; var Requires = class extends Statement { constructor(extensions) { super(); this.extensions = extensions; } get astNodeType() { return "requires"; } }; var Diagnostic = class extends Statement { constructor(severity, rule) { super(); this.severity = severity; this.rule = rule; } get astNodeType() { return "diagnostic"; } }; var Alias = class extends Statement { constructor(name2, type) { super(); this.name = name2; this.type = type; } get astNodeType() { return "alias"; } }; var Discard = class extends Statement { constructor() { super(); } get astNodeType() { return "discard"; } }; var Break = class extends Statement { constructor() { super(); } get astNodeType() { return "break"; } }; var Continue = class extends Statement { constructor() { super(); } get astNodeType() { return "continue"; } }; var Type = class extends Statement { constructor(name2) { super(); this.name = name2; } get astNodeType() { return "type"; } get isStruct() { return false; } get isArray() { return false; } }; var Struct = class extends Type { constructor(name2, members, startLine, endLine) { super(name2); this.members = members; this.startLine = startLine; this.endLine = endLine; } get astNodeType() { return "struct"; } get isStruct() { return true; } getMemberIndex(name2) { for (let i = 0; i < this.members.length; i++) { if (this.members[i].name == name2) return i; } return -1; } }; var TemplateType = class extends Type { constructor(name2, format, access) { super(name2); this.format = format; this.access = access; } get astNodeType() { return "template"; } }; var PointerType = class extends Type { constructor(name2, storage, type, access) { super(name2); this.storage = storage; this.type = type; this.access = access; } get astNodeType() { return "pointer"; } }; var ArrayType = class extends Type { constructor(name2, attributes, format, count2) { super(name2); this.attributes = attributes; this.format = format; this.count = count2; } get astNodeType() { return "array"; } get isArray() { return true; } }; var SamplerType = class extends Type { constructor(name2, format, access) { super(name2); this.format = format; this.access = access; } get astNodeType() { return "sampler"; } }; var Expression = class extends Node { constructor() { super(); } }; var StringExpr = class extends Expression { constructor(value) { super(); this.value = value; } get astNodeType() { return "stringExpr"; } toString() { return this.value; } evaluateString() { return this.value; } }; var CreateExpr = class extends Expression { constructor(type, args) { super(); this.type = type; this.args = args; } get astNodeType() { return "createExpr"; } search(callback) { callback(this); for (const node of this.args) { node.search(callback); } } }; var CallExpr = class extends Expression { constructor(name2, args) { super(); this.name = name2; this.args = args; } get astNodeType() { return "callExpr"; } evaluate(context) { switch (this.name) { case "abs": return Math.abs(this.args[0].evaluate(context)); case "acos": return Math.acos(this.args[0].evaluate(context)); case "acosh": return Math.acosh(this.args[0].evaluate(context)); case "asin": return Math.asin(this.args[0].evaluate(context)); case "asinh": return Math.asinh(this.args[0].evaluate(context)); case "atan": return Math.atan(this.args[0].evaluate(context)); case "atan2": return Math.atan2(this.args[0].evaluate(context), this.args[1].evaluate(context)); case "atanh": return Math.atanh(this.args[0].evaluate(context)); case "ceil": return Math.ceil(this.args[0].evaluate(context)); case "clamp": return Math.min(Math.max(this.args[0].evaluate(context), this.args[1].evaluate(context)), this.args[2].evaluate(context)); case "cos": return Math.cos(this.args[0].evaluate(context)); case "degrees": return this.args[0].evaluate(context) * 180 / Math.PI; case "distance": return Math.sqrt(Math.pow(this.args[0].evaluate(context) - this.args[1].evaluate(context), 2)); case "dot": case "exp": return Math.exp(this.args[0].evaluate(context)); case "exp2": return Math.pow(2, this.args[0].evaluate(context)); case "floor": return Math.floor(this.args[0].evaluate(context)); case "fma": return this.args[0].evaluate(context) * this.args[1].evaluate(context) + this.args[2].evaluate(context); case "fract": return this.args[0].evaluate(context) - Math.floor(this.args[0].evaluate(context)); case "inverseSqrt": return 1 / Math.sqrt(this.args[0].evaluate(context)); case "log": return Math.log(this.args[0].evaluate(context)); case "log2": return Math.log2(this.args[0].evaluate(context)); case "max": return Math.max(this.args[0].evaluate(context), this.args[1].evaluate(context)); case "min": return Math.min(this.args[0].evaluate(context), this.args[1].evaluate(context)); case "mix": return this.args[0].evaluate(context) * (1 - this.args[2].evaluate(context)) + this.args[1].evaluate(context) * this.args[2].evaluate(context); case "modf": return this.args[0].evaluate(context) - Math.floor(this.args[0].evaluate(context)); case "pow": return Math.pow(this.args[0].evaluate(context), this.args[1].evaluate(context)); case "radians": return this.args[0].evaluate(context) * Math.PI / 180; case "round": return Math.round(this.args[0].evaluate(context)); case "sign": return Math.sign(this.args[0].evaluate(context)); case "sin": return Math.sin(this.args[0].evaluate(context)); case "sinh": return Math.sinh(this.args[0].evaluate(context)); case "saturate": return Math.min(Math.max(this.args[0].evaluate(context), 0), 1); case "smoothstep": return this.args[0].evaluate(context) * this.args[0].evaluate(context) * (3 - 2 * this.args[0].evaluate(context)); case "sqrt": return Math.sqrt(this.args[0].evaluate(context)); case "step": return this.args[0].evaluate(context) < this.args[1].evaluate(context) ? 0 : 1; case "tan": return Math.tan(this.args[0].evaluate(context)); case "tanh": return Math.tanh(this.args[0].evaluate(context)); case "trunc": return Math.trunc(this.args[0].evaluate(context)); default: throw new Error("Non const function: " + this.name); } } search(callback) { for (const node of this.args) { node.search(callback); } callback(this); } }; var VariableExpr = class extends Expression { constructor(name2) { super(); this.name = name2; } get astNodeType() { return "varExpr"; } search(callback) { callback(this); if (this.postfix) { this.postfix.search(callback); } } evaluate(context) { const constant = context.constants.get(this.name); if (!constant) { throw new Error("Cannot evaluate node"); } return constant.evaluate(context); } }; var ConstExpr = class extends Expression { constructor(name2, initializer) { super(); this.name = name2; this.initializer = initializer; } get astNodeType() { return "constExpr"; } evaluate(context) { var _a2, _b; if (this.initializer instanceof CreateExpr) { const property = (_a2 = this.postfix) === null || _a2 === void 0 ? void 0 : _a2.evaluateString(context); const type = (_b = this.initializer.type) === null || _b === void 0 ? void 0 : _b.name; const struct = context.structs.get(type); const memberIndex = struct === null || struct === void 0 ? void 0 : struct.getMemberIndex(property); if (memberIndex != -1) { const value = this.initializer.args[memberIndex].evaluate(context); return value; } console.log(memberIndex); } return this.initializer.evaluate(context); } search(callback) { this.initializer.search(callback); } }; var LiteralExpr = class extends Expression { constructor(value) { super(); this.value = value; } get astNodeType() { return "literalExpr"; } evaluate() { return this.value; } }; var BitcastExpr = class extends Expression { constructor(type, value) { super(); this.type = type; this.value = value; } get astNodeType() { return "bitcastExpr"; } search(callback) { this.value.search(callback); } }; var TypecastExpr = class extends Expression { constructor(type, args) { super(); this.type = type; this.args = args; } get astNodeType() { return "typecastExpr"; } evaluate(context) { return this.args[0].evaluate(context); } search(callback) { this.searchBlock(this.args, callback); } }; var GroupingExpr = class extends Expression { constructor(contents) { super(); this.contents = contents; } get astNodeType() { return "groupExpr"; } evaluate(context) { return this.contents[0].evaluate(context); } search(callback) { this.searchBlock(this.contents, callback); } }; var ArrayIndex = class extends Expression { constructor(index2) { super(); this.index = index2; } search(callback) { this.index.search(callback); } }; var Operator = class extends Expression { constructor() { super(); } }; var UnaryOperator = class extends Operator { constructor(operator, right) { super(); this.operator = operator; this.right = right; } get astNodeType() { return "unaryOp"; } evaluate(context) { switch (this.operator) { case "+": return this.right.evaluate(context); case "-": return -this.right.evaluate(context); case "!": return this.right.evaluate(context) ? 0 : 1; case "~": return ~this.right.evaluate(context); default: throw new Error("Unknown unary operator: " + this.operator); } } search(callback) { this.right.search(callback); } }; var BinaryOperator = class extends Operator { constructor(operator, left, right) { super(); this.operator = operator; this.left = left; this.right = right; } get astNodeType() { return "binaryOp"; } evaluate(context) { switch (this.operator) { case "+": return this.left.evaluate(context) + this.right.evaluate(context); case "-": return this.left.evaluate(context) - this.right.evaluate(context); case "*": return this.left.evaluate(context) * this.right.evaluate(context); case "/": return this.left.evaluate(context) / this.right.evaluate(context); case "%": return this.left.evaluate(context) % this.right.evaluate(context); case "==": return this.left.evaluate(context) == this.right.evaluate(context) ? 1 : 0; case "!=": return this.left.evaluate(context) != this.right.evaluate(context) ? 1 : 0; case "<": return this.left.evaluate(context) < this.right.evaluate(context) ? 1 : 0; case ">": return this.left.evaluate(context) > this.right.evaluate(context) ? 1 : 0; case "<=": return this.left.evaluate(context) <= this.right.evaluate(context) ? 1 : 0; case ">=": return this.left.evaluate(context) >= this.right.evaluate(context) ? 1 : 0; case "&&": return this.left.evaluate(context) && this.right.evaluate(context) ? 1 : 0; case "||": return this.left.evaluate(context) || this.right.evaluate(context) ? 1 : 0; default: throw new Error(`Unknown operator ${this.operator}`); } } search(callback) { this.left.search(callback); this.right.search(callback); } }; var SwitchCase = class extends Node { constructor() { super(); } }; var Case = class extends SwitchCase { constructor(selector, body) { super(); this.selector = selector; this.body = body; } get astNodeType() { return "case"; } search(callback) { this.searchBlock(this.body, callback); } }; var Default = class extends SwitchCase { constructor(body) { super(); this.body = body; } get astNodeType() { return "default"; } search(callback) { this.searchBlock(this.body, callback); } }; var Argument = class extends Node { constructor(name2, type, attributes) { super(); this.name = name2; this.type = type; this.attributes = attributes; } get astNodeType() { return "argument"; } }; var ElseIf = class extends Node { constructor(condition, body) { super(); this.condition = condition; this.body = body; } get astNodeType() { return "elseif"; } search(callback) { this.condition.search(callback); this.searchBlock(this.body, callback); } }; var Member = class extends Node { constructor(name2, type, attributes) { super(); this.name = name2; this.type = type; this.attributes = attributes; } get astNodeType() { return "member"; } }; var Attribute = class extends Node { constructor(name2, value) { super(); this.name = name2; this.value = value; } get astNodeType() { return "attribute"; } }; var _a; var TokenClass; (function(TokenClass2) { TokenClass2[TokenClass2["token"] = 0] = "token"; TokenClass2[TokenClass2["keyword"] = 1] = "keyword"; TokenClass2[TokenClass2["reserved"] = 2] = "reserved"; })(TokenClass || (TokenClass = {})); var TokenType = class { constructor(name2, type, rule) { this.name = name2; this.type = type; this.rule = rule; } toString() { return this.name; } }; var TokenTypes = class { }; _a = TokenTypes; TokenTypes.none = new TokenType("", TokenClass.reserved, ""); TokenTypes.eof = new TokenType("EOF", TokenClass.token, ""); TokenTypes.reserved = { asm: new TokenType("asm", TokenClass.reserved, "asm"), bf16: new TokenType("bf16", TokenClass.reserved, "bf16"), do: new TokenType("do", TokenClass.reserved, "do"), enum: new TokenType("enum", TokenClass.reserved, "enum"), f16: new TokenType("f16", TokenClass.reserved, "f16"), f64: new TokenType("f64", TokenClass.reserved, "f64"), handle: new TokenType("handle", TokenClass.reserved, "handle"), i8: new TokenType("i8", TokenClass.reserved, "i8"), i16: new TokenType("i16", TokenClass.reserved, "i16"), i64: new TokenType("i64", TokenClass.reserved, "i64"), mat: new TokenType("mat", TokenClass.reserved, "mat"), premerge: new TokenType("premerge", TokenClass.reserved, "premerge"), regardless: new TokenType("regardless", TokenClass.reserved, "regardless"), typedef: new TokenType("typedef", TokenClass.reserved, "typedef"), u8: new TokenType("u8", TokenClass.reserved, "u8"), u16: new TokenType("u16", TokenClass.reserved, "u16"), u64: new TokenType("u64", TokenClass.reserved, "u64"), unless: new TokenType("unless", TokenClass.reserved, "unless"), using: new TokenType("using", TokenClass.reserved, "using"), vec: new TokenType("vec", TokenClass.reserved, "vec"), void: new TokenType("void", TokenClass.reserved, "void") }; TokenTypes.keywords = { array: new TokenType("array", TokenClass.keyword, "array"), atomic: new TokenType("atomic", TokenClass.keyword, "atomic"), bool: new TokenType("bool", TokenClass.keyword, "bool"), f32: new TokenType("f32", TokenClass.keyword, "f32"), i32: new TokenType("i32", TokenClass.keyword, "i32"), mat2x2: new TokenType("mat2x2", TokenClass.keyword, "mat2x2"), mat2x3: new TokenType("mat2x3", TokenClass.keyword, "mat2x3"), mat2x4: new TokenType("mat2x4", TokenClass.keyword, "mat2x4"), mat3x2: new TokenType("mat3x2", TokenClass.keyword, "mat3x2"), mat3x3: new TokenType("mat3x3", TokenClass.keyword, "mat3x3"), mat3x4: new TokenType("mat3x4", TokenClass.keyword, "mat3x4"), mat4x2: new TokenType("mat4x2", TokenClass.keyword, "mat4x2"), mat4x3: new TokenType("mat4x3", TokenClass.keyword, "mat4x3"), mat4x4: new TokenType("mat4x4", TokenClass.keyword, "mat4x4"), ptr: new TokenType("ptr", TokenClass.keyword, "ptr"), sampler: new TokenType("sampler", TokenClass.keyword, "sampler"), sampler_comparison: new TokenType("sampler_comparison", TokenClass.keyword, "sampler_comparison"), struct: new TokenType("struct", TokenClass.keyword, "struct"), texture_1d: new TokenType("texture_1d", TokenClass.keyword, "texture_1d"), texture_2d: new TokenType("texture_2d", TokenClass.keyword, "texture_2d"), texture_2d_array: new TokenType("texture_2d_array", TokenClass.keyword, "texture_2d_array"), texture_3d: new TokenType("texture_3d", TokenClass.keyword, "texture_3d"), texture_cube: new TokenType("texture_cube", TokenClass.keyword, "texture_cube"), texture_cube_array: new TokenType("texture_cube_array", TokenClass.keyword, "texture_cube_array"), texture_multisampled_2d: new TokenType("texture_multisampled_2d", TokenClass.keyword, "texture_multisampled_2d"), texture_storage_1d: new TokenType("texture_storage_1d", TokenClass.keyword, "texture_storage_1d"), texture_storage_2d: new TokenType("texture_storage_2d", TokenClass.keyword, "texture_storage_2d"), texture_storage_2d_array: new TokenType("texture_storage_2d_array", TokenClass.keyword, "texture_storage_2d_array"), texture_storage_3d: new TokenType("texture_storage_3d", TokenClass.keyword, "texture_storage_3d"), texture_depth_2d: new TokenType("texture_depth_2d", TokenClass.keyword, "texture_depth_2d"), texture_depth_2d_array: new TokenType("texture_depth_2d_array", TokenClass.keyword, "texture_depth_2d_array"), texture_depth_cube: new TokenType("texture_depth_cube", TokenClass.keyword, "texture_depth_cube"), texture_depth_cube_array: new TokenType("texture_depth_cube_array", TokenClass.keyword, "texture_depth_cube_array"), texture_depth_multisampled_2d: new TokenType("texture_depth_multisampled_2d", TokenClass.keyword, "texture_depth_multisampled_2d"), texture_external: new TokenType("texture_external", TokenClass.keyword, "texture_external"), u32: new TokenType("u32", TokenClass.keyword, "u32"), vec2: new TokenType("vec2", TokenClass.keyword, "vec2"), vec3: new TokenType("vec3", TokenClass.keyword, "vec3"), vec4: new TokenType("vec4", TokenClass.keyword, "vec4"), bitcast: new TokenType("bitcast", TokenClass.keyword, "bitcast"), block: new TokenType("block", TokenClass.keyword, "block"), break: new TokenType("break", TokenClass.keyword, "break"), case: new TokenType("case", TokenClass.keyword, "case"), continue: new TokenType("continue", TokenClass.keyword, "continue"), continuing: new TokenType("continuing", TokenClass.keyword, "continuing"), default: new TokenType("default", TokenClass.keyword, "default"), diagnostic: new TokenType("diagnostic", TokenClass.keyword, "diagnostic"), discard: new TokenType("discard", TokenClass.keyword, "discard"), else: new TokenType("else", TokenClass.keyword, "else"), enable: new TokenType("enable", TokenClass.keyword, "enable"), fallthrough: new TokenType("fallthrough", TokenClass.keyword, "fallthrough"), false: new TokenType("false", TokenClass.keyword, "false"), fn: new TokenType("fn", TokenClass.keyword, "fn"), for: new TokenType("for", TokenClass.keyword, "for"), function: new TokenType("function", TokenClass.keyword, "function"), if: new TokenType("if", TokenClass.keyword, "if"), let: new TokenType("let", TokenClass.keyword, "let"), const: new TokenType("const", TokenClass.keyword, "const"), loop: new TokenType("loop", TokenClass.keyword, "loop"), while: new TokenType("while", TokenClass.keyword, "while"), private: new TokenType("private", TokenClass.keyword, "private"), read: new TokenType("read", TokenClass.keyword, "read"), read_write: new TokenType("read_write", TokenClass.keyword, "read_write"), return: new TokenType("return", TokenClass.keyword, "return"), requires: new TokenType("requires", TokenClass.keyword, "requires"), storage: new TokenType("storage", TokenClass.keyword, "storage"), switch: new TokenType("switch", TokenClass.keyword, "switch"), true: new TokenType("true", TokenClass.keyword, "true"), alias: new TokenType("alias", TokenClass.keyword, "alias"), type: new TokenType("type", TokenClass.keyword, "type"), uniform: new TokenType("uniform", TokenClass.keyword, "uniform"), var: new TokenType("var", TokenClass.keyword, "var"), override: new TokenType("override", TokenClass.keyword, "override"), workgroup: new TokenType("workgroup", TokenClass.keyword, "workgroup"), write: new TokenType("write", TokenClass.keyword, "write"), r8unorm: new TokenType("r8unorm", TokenClass.keyword, "r8unorm"), r8snorm: new TokenType("r8snorm", TokenClass.keyword, "r8snorm"), r8uint: new TokenType("r8uint", TokenClass.keyword, "r8uint"), r8sint: new TokenType("r8sint", TokenClass.keyword, "r8sint"), r16uint: new TokenType("r16uint", TokenClass.keyword, "r16uint"), r16sint: new TokenType("r16sint", TokenClass.keyword, "r16sint"), r16float: new TokenType("r16float", TokenClass.keyword, "r16float"), rg8unorm: new TokenType("rg8unorm", TokenClass.keyword, "rg8unorm"), rg8snorm: new TokenType("rg8snorm", TokenClass.keyword, "rg8snorm"), rg8uint: new TokenType("rg8uint", TokenClass.keyword, "rg8uint"), rg8sint: new TokenType("rg8sint", TokenClass.keyword, "rg8sint"), r32uint: new TokenType("r32uint", TokenClass.keyword, "r32uint"), r32sint: new TokenType("r32sint", TokenClass.keyword, "r32sint"), r32float: new TokenType("r32float", TokenClass.keyword, "r32float"), rg16uint: new TokenType("rg16uint", TokenClass.keyword, "rg16uint"), rg16sint: new TokenType("rg16sint", TokenClass.keyword, "rg16sint"), rg16float: new TokenType("rg16float", TokenClass.keyword, "rg16float"), rgba8unorm: new TokenType("rgba8unorm", TokenClass.keyword, "rgba8unorm"), rgba8unorm_srgb: new TokenType("rgba8unorm_srgb", TokenClass.keyword, "rgba8unorm_srgb"), rgba8snorm: new TokenType("rgba8snorm", TokenClass.keyword, "rgba8snorm"), rgba8uint: new TokenType("rgba8uint", TokenClass.keyword, "rgba8uint"), rgba8sint: new TokenType("rgba8sint", TokenClass.keyword, "rgba8sint"), bgra8unorm: new TokenType("bgra8unorm", TokenClass.keyword, "bgra8unorm"), bgra8unorm_srgb: new TokenType("bgra8unorm_srgb", TokenClass.keyword, "bgra8unorm_srgb"), rgb10a2unorm: new TokenType("rgb10a2unorm", TokenClass.keyword, "rgb10a2unorm"), rg11b10float: new TokenType("rg11b10float", TokenClass.keyword, "rg11b10float"), rg32uint: new TokenType("rg32uint", TokenClass.keyword, "rg32uint"), rg32sint: new TokenType("rg32sint", TokenClass.keyword, "rg32sint"), rg32float: new TokenType("rg32float", TokenClass.keyword, "rg32float"), rgba16uint: new TokenType("rgba16uint", TokenClass.keyword, "rgba16uint"), rgba16sint: new TokenType("rgba16sint", TokenClass.keyword, "rgba16sint"), rgba16float: new TokenType("rgba16float", TokenClass.keyword, "rgba16float"), rgba32uint: new TokenType("rgba32uint", TokenClass.keyword, "rgba32uint"), rgba32sint: new TokenType("rgba32sint", TokenClass.keyword, "rgba32sint"), rgba32float: new TokenType("rgba32float", TokenClass.keyword, "rgba32float"), static_assert: new TokenType("static_assert", TokenClass.keyword, "static_assert") }; TokenTypes.tokens = { decimal_float_literal: new TokenType("decimal_float_literal", TokenClass.token, /((-?[0-9]*\.[0-9]+|-?[0-9]+\.[0-9]*)((e|E)(\+|-)?[0-9]+)?f?)|(-?[0-9]+(e|E)(\+|-)?[0-9]+f?)|([0-9]+f)/), hex_float_literal: new TokenType("hex_float_literal", TokenClass.token, /-?0x((([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.[0-9a-fA-F]*)((p|P)(\+|-)?[0-9]+f?)?)|([0-9a-fA-F]+(p|P)(\+|-)?[0-9]+f?))/), int_literal: new TokenType("int_literal", TokenClass.token, /-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/), uint_literal: new TokenType("uint_literal", TokenClass.token, /0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/), ident: new TokenType("ident", TokenClass.token, /[_a-zA-Z][0-9a-zA-Z_]*/), and: new TokenType("and", TokenClass.token, "&"), and_and: new TokenType("and_and", TokenClass.token, "&&"), arrow: new TokenType("arrow ", TokenClass.token, "->"), attr: new TokenType("attr", TokenClass.token, "@"), forward_slash: new TokenType("forward_slash", TokenClass.token, "/"), bang: new TokenType("bang", TokenClass.token, "!"), bracket_left: new TokenType("bracket_left", TokenClass.token, "["), bracket_right: new TokenType("bracket_right", TokenClass.token, "]"), brace_left: new TokenType("brace_left", TokenClass.token, "{"), brace_right: new TokenType("brace_right", TokenClass.token, "}"), colon: new TokenType("colon", TokenClass.token, ":"), comma: new TokenType("comma", TokenClass.token, ","), equal: new TokenType("equal", TokenClass.token, "="), equal_equal: new TokenType("equal_equal", TokenClass.token, "=="), not_equal: new TokenType("not_equal", TokenClass.token, "!="), greater_than: new TokenType("greater_than", TokenClass.token, ">"), greater_than_equal: new TokenType("greater_than_equal", TokenClass.token, ">="), shift_right: new TokenType("shift_right", TokenClass.token, ">>"), less_than: new TokenType("less_than", TokenClass.token, "<"), less_than_equal: new TokenType("less_than_equal", TokenClass.token, "<="), shift_left: new TokenType("shift_left", TokenClass.token, "<<"), modulo: new TokenType("modulo", TokenClass.token, "%"), minus: new TokenType("minus", TokenClass.token, "-"), minus_minus: new TokenType("minus_minus", TokenClass.token, "--"), period: new TokenType("period", TokenClass.token, "."), plus: new TokenType("plus", TokenClass.token, "+"), plus_plus: new TokenType("plus_plus", TokenClass.token, "++"), or: new TokenType("or", TokenClass.token, "|"), or_or: new TokenType("or_or", TokenClass.token, "||"), paren_left: new TokenType("paren_left", TokenClass.token, "("), paren_right: new TokenType("paren_right", TokenClass.token, ")"), semicolon: new TokenType("semicolon", TokenClass.token, ";"), star: new TokenType("star", TokenClass.token, "*"), tilde: new TokenType("tilde", TokenClass.token, "~"), underscore: new TokenType("underscore", TokenClass.token, "_"), xor: new TokenType("xor", TokenClass.token, "^"), plus_equal: new TokenType("plus_equal", TokenClass.token, "+="), minus_equal: new TokenType("minus_equal", TokenClass.token, "-="), times_equal: new TokenType("times_equal", TokenClass.token, "*="), division_equal: new TokenType("division_equal", TokenClass.token, "/="), modulo_equal: new TokenType("modulo_equal", TokenClass.token, "%="), and_equal: new TokenType("and_equal", TokenClass.token, "&="), or_equal: new TokenType("or_equal", TokenClass.token, "|="), xor_equal: new TokenType("xor_equal", TokenClass.token, "^="), shift_right_equal: new TokenType("shift_right_equal", TokenClass.token, ">>="), shift_left_equal: new TokenType("shift_left_equal", TokenClass.token, "<<=") }; TokenTypes.simpleTokens = { "@": _a.tokens.attr, "{": _a.tokens.brace_left, "}": _a.tokens.brace_right, ":": _a.tokens.colon, ",": _a.tokens.comma, "(": _a.tokens.paren_left, ")": _a.tokens.paren_right, ";": _a.tokens.semicolon }; TokenTypes.literalTokens = { "&": _a.tokens.and, "&&": _a.tokens.and_and, "->": _a.tokens.arrow, "/": _a.tokens.forward_slash, "!": _a.tokens.bang, "[": _a.tokens.bracket_left, "]": _a.tokens.bracket_right, "=": _a.tokens.equal, "==": _a.tokens.equal_equal, "!=": _a.tokens.not_equal, ">": _a.tokens.greater_than, ">=": _a.tokens.greater_than_equal, ">>": _a.tokens.shift_right, "<": _a.tokens.less_than, "<=": _a.tokens.less_than_equal, "<<": _a.tokens.shift_left, "%": _a.tokens.modulo, "-": _a.tokens.minus, "--": _a.tokens.minus_minus, ".": _a.tokens.period, "+": _a.tokens.plus, "++": _a.tokens.plus_plus, "|": _a.tokens.or, "||": _a.tokens.or_or, "*": _a.tokens.star, "~": _a.tokens.tilde, "_": _a.tokens.underscore, "^": _a.tokens.xor, "+=": _a.tokens.plus_equal, "-=": _a.tokens.minus_equal, "*=": _a.tokens.times_equal, "/=": _a.tokens.division_equal, "%=": _a.tokens.modulo_equal, "&=": _a.tokens.and_equal, "|=": _a.tokens.or_equal, "^=": _a.tokens.xor_equal, ">>=": _a.tokens.shift_right_equal, "<<=": _a.tokens.shift_left_equal }; TokenTypes.regexTokens = { decimal_float_literal: _a.tokens.decimal_float_literal, hex_float_literal: _a.tokens.hex_float_literal, int_literal: _a.tokens.int_literal, uint_literal: _a.tokens.uint_literal, ident: _a.tokens.ident }; TokenTypes.storage_class = [ _a.keywords.function, _a.keywords.private, _a.keywords.workgroup, _a.keywords.uniform, _a.keywords.storage ]; TokenTypes.access_mode = [ _a.keywords.read, _a.keywords.write, _a.keywords.read_write ]; TokenTypes.sampler_type = [ _a.keywords.sampler, _a.keywords.sampler_comparison ]; TokenTypes.sampled_texture_type = [ _a.keywords.texture_1d, _a.keywords.texture_2d, _a.keywords.texture_2d_array, _a.keywords.texture_3d, _a.keywords.texture_cube, _a.keywords.texture_cube_array ]; TokenTypes.multisampled_texture_type = [ _a.keywords.texture_multisampled_2d ]; TokenTypes.storage_texture_type = [ _a.keywords.texture_storage_1d, _a.keywords.texture_storage_2d, _a.keywords.texture_storage_2d_array, _a.keywords.texture_storage_3d ]; TokenTypes.depth_texture_type = [ _a.keywords.texture_depth_2d, _a.keywords.texture_depth_2d_array, _a.keywords.texture_depth_cube, _a.keywords.texture_depth_cube_array, _a.keywords.texture_depth_multisampled_2d ]; TokenTypes.texture_external_type = [_a.keywords.texture_external]; TokenTypes.any_texture_type = [ ..._a.sampled_texture_type, ..._a.multisampled_texture_type, ..._a.storage_texture_type, ..._a.depth_texture_type, ..._a.texture_external_type ]; TokenTypes.texel_format = [ _a.keywords.r8unorm, _a.keywords.r8snorm, _a.keywords.r8uint, _a.keywords.r8sint, _a.keywords.r16uint, _a.keywords.r16sint, _a.keywords.r16float, _a.keywords.rg8unorm, _a.keywords.rg8snorm, _a.keywords.rg8uint, _a.keywords.rg8sint, _a.keywords.r32uint, _a.keywords.r32sint, _a.keywords.r32float, _a.keywords.rg16uint, _a.keywords.rg16sint, _a.keywords.rg16float, _a.keywords.rgba8unorm, _a.keywords.rgba8unorm_srgb, _a.keywords.rgba8snorm, _a.keywords.rgba8uint, _a.keywords.rgba8sint, _a.keywords.bgra8unorm, _a.keywords.bgra8unorm_srgb, _a.keywords.rgb10a2unorm, _a.keywords.rg11b10float, _a.keywords.rg32uint, _a.keywords.rg32sint, _a.keywords.rg32float, _a.keywords.rgba16uint, _a.keywords.rgba16sint, _a.keywords.rgba16float, _a.keywords.rgba32uint, _a.keywords.rgba32sint, _a.keywords.rgba32float ]; TokenTypes.const_literal = [ _a.tokens.int_literal, _a.tokens.uint_literal, _a.tokens.decimal_float_literal, _a.tokens.hex_float_literal, _a.keywords.true, _a.keywords.false ]; TokenTypes.literal_or_ident = [ _a.tokens.ident, _a.tokens.int_literal, _a.tokens.uint_literal, _a.tokens.decimal_float_literal, _a.tokens.hex_float_literal ]; TokenTypes.element_count_expression = [ _a.tokens.int_literal, _a.tokens.uint_literal, _a.tokens.ident ]; TokenTypes.template_types = [ _a.keywords.vec2, _a.keywords.vec3, _a.keywords.vec4, _a.keywords.mat2x2, _a.keywords.mat2x3, _a.keywords.mat2x4, _a.keywords.mat3x2, _a.keywords.mat3x3, _a.keywords.mat3x4, _a.keywords.mat4x2, _a.keywords.mat4x3, _a.keywords.mat4x4, _a.keywords.atomic, _a.keywords.bitcast, ..._a.any_texture_type ]; TokenTypes.attribute_name = [_a.tokens.ident, _a.keywords.block, _a.keywords.diagnostic]; TokenTypes.assignment_operators = [ _a.tokens.equal, _a.tokens.plus_equal, _a.tokens.minus_equal, _a.tokens.times_equal, _a.tokens.division_equal, _a.tokens.modulo_equal, _a.tokens.and_equal, _a.tokens.or_equal, _a.tokens.xor_equal, _a.tokens.shift_right_equal, _a.tokens.shift_left_equal ]; TokenTypes.increment_operators = [ _a.tokens.plus_plus, _a.tokens.minus_minus ]; var Token = class { constructor(type, lexeme, line) { this.type = type; this.lexeme = lexeme; this.line = line; } toString() { return this.lexeme; } isTemplateType() { return TokenTypes.template_types.indexOf(this.type) != -1; } isArrayType() { return this.type == TokenTypes.keywords.array; } isArrayOrTemplateType() { return this.isArrayType() || this.isTemplateType(); } }; var WgslScanner = class { constructor(source) { this._tokens = []; this._start = 0; this._current = 0; this._line = 1; this._source = source !== null && source !== void 0 ? source : ""; } scanTokens() { while (!this._isAtEnd()) { this._start = this._current; if (!this.scanToken()) { throw `Invalid syntax at line ${this._line}`; } } this._tokens.push(new Token(TokenTypes.eof, "", this._line)); return this._tokens; } scanToken() { let lexeme = this._advance(); if (lexeme == "\n") { this._line++; return true; } if (this._isWhitespace(lexeme)) { return true; } if (lexeme == "/") { if (this._peekAhead() == "/") { while (lexeme != "\n") { if (this._isAtEnd()) { return true; } lexeme = this._advance(); } this._line++; return true; } else if (this._peekAhead() == "*") { this._advance(); let commentLevel = 1; while (commentLevel > 0) { if (this._isAtEnd()) { return true; } lexeme = this._advance(); if (lexeme == "\n") { this._line++; } else if (lexeme == "*") { if (this._peekAhead() == "/") { this._advance(); commentLevel--; if (commentLevel == 0) { return true; } } } else if (lexeme == "/") { if (this._peekAhead() == "*") { this._advance(); commentLevel++; } } } return true; } } const simpleToken = TokenTypes.simpleTokens[lexeme]; if (simpleToken) { this._addToken(simpleToken); return true; } let matchType = TokenTypes.none; const isAlpha = this._isAlpha(lexeme); const isUnderscore = lexeme === "_"; if (this._isAlphaNumeric(lexeme)) { let nextChar = this._peekAhead(); while (this._isAlphaNumeric(nextChar)) { lexeme += this._advance(); nextChar = this._peekAhead(); } } if (isAlpha) { const matchedType = TokenTypes.keywords[lexeme]; if (matchedType) { this._addToken(matchedType); return true; } } if (isAlpha || isUnderscore) { this._addToken(TokenTypes.tokens.ident); return true; } for (; ; ) { let matchedType = this._findType(lexeme); const nextLexeme = this._peekAhead(); if (lexeme == "-" && this._tokens.length > 0) { if (nextLexeme == "=") { this._current++; lexeme += nextLexeme; this._addToken(TokenTypes.tokens.minus_equal); return true; } if (nextLexeme == "-") { this._current++; lexeme += nextLexeme; this._addToken(TokenTypes.tokens.minus_minus); return true; } const ti = this._tokens.length - 1; const isIdentOrLiteral = TokenTypes.literal_or_ident.indexOf(this._tokens[ti].type) != -1; if ((isIdentOrLiteral || this._tokens[ti].type == TokenTypes.tokens.paren_right) && nextLexeme != ">") { this._addToken(matchedType); return true; } } if (lexeme == ">" && (nextLexeme == ">" || nextLexeme == "=")) { let foundLessThan = false; let ti = this._tokens.length - 1; for (let count2 = 0; count2 < 5 && ti >= 0; ++count2, --ti) { if (TokenTypes.assignment_operators.indexOf(this._tokens[ti].type) !== -1) { break; } if (this._tokens[ti].type === TokenTypes.tokens.less_than) { if (ti > 0 && this._tokens[ti - 1].isArrayOrTemplateType()) { foundLessThan = true; } break; } } if (foundLessThan) { this._addToken(matchedType); return true; } } if (matchedType === TokenTypes.none) { let lookAheadLexeme = lexeme; let lookAhead = 0; const maxLookAhead = 2; for (let li = 0; li < maxLookAhead; ++li) { lookAheadLexeme += this._peekAhead(li); matchedType = this._findType(lookAheadLexeme); if (matchedType !== TokenTypes.none) { lookAhead = li; break; } } if (matchedType === TokenTypes.none) { if (matchType === TokenTypes.none) { return false; } this._current--; this._addToken(matchType); return true; } lexeme = lookAheadLexeme; this._current += lookAhead + 1; } matchType = matchedType; if (this._isAtEnd()) { break; } lexeme += this._advance(); } if (matchType === TokenTypes.none) { return false; } this._addToken(matchType); return true; } _findType(lexeme) { for (const name2 in TokenTypes.regexTokens) { const type2 = TokenTypes.regexTokens[name2]; if (this._match(lexeme, type2.rule)) { return type2; } } const type = TokenTypes.literalTokens[lexeme]; if (type) { return type; } return TokenTypes.none; } _match(lexeme, rule) { const match = rule.exec(lexeme); return match && match.index == 0 && match[0] == lexeme; } _isAtEnd() { return this._current >= this._source.length; } _isAlpha(c) { return c >= "a" && c <= "z" || c >= "A" && c <= "Z"; } _isAlphaNumeric(c) { return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c == "_" || c >= "0" && c <= "9"; } _isWhitespace(c) { return c == " " || c == " " || c == "\r"; } _advance(amount = 0) { let c = this._source[this._current]; amount = amount || 0; amount++; this._current += amount; return c; } _peekAhead(offset = 0) { offset = offset || 0; if (this._current + offset >= this._source.length) { return "\0"; } return this._source[this._current + offset]; } _addToken(type) { const text = this._source.substring(this._start, this._current); this._tokens.push(new Token(type, text, this._line)); } }; var WgslParser = class { constructor() { this._tokens = []; this._current = 0; this._currentLine = 0; this._context = new ParseContext(); this._deferArrayCountEval = []; } parse(tokensOrCode) { this._initialize(tokensOrCode); this._deferArrayCountEval.length = 0; const statements = []; while (!this._isAtEnd()) { const statement = this._global_decl_or_directive(); if (!statement) { break; } statements.push(statement); } if (this._deferArrayCountEval.length > 0) { for (const arrayDecl of this._deferArrayCountEval) { const arrayType = arrayDecl["arrayType"]; const countNode = arrayDecl["countNode"]; if (countNode instanceof VariableExpr) { const variable = countNode; const name2 = variable.name; const constant = this._context.constants.get(name2); if (constant) { try { const count2 = constant.evaluate(this._context); arrayType.count = count2; } catch (e2) { } } } } this._deferArrayCountEval.length = 0; } return statements; } _initialize(tokensOrCode) { if (tokensOrCode) { if (typeof tokensOrCode == "string") { const scanner = new WgslScanner(tokensOrCode); this._tokens = scanner.scanTokens(); } else { this._tokens = tokensOrCode; } } else { this._tokens = []; } this._current = 0; } _error(token, message2) { return { token, message: message2, toString: function() { return `${message2}`; } }; } _isAtEnd() { return this._current >= this._tokens.length || this._peek().type == TokenTypes.eof; } _match(types) { if (types instanceof TokenType) { if (this._check(types)) { this._advance(); return true; } return false; } for (let i = 0, l = types.length; i < l; ++i) { const type = types[i]; if (this._check(type)) { this._advance(); return true; } } return false; } _consume(types, message2) { if (this._check(types)) { return this._advance(); } throw this._error(this._peek(), message2); } _check(types) { if (this._isAtEnd()) { return false; } const tk = this._peek(); if (types instanceof Array) { const t = tk.type; const index2 = types.indexOf(t); return index2 != -1; } return tk.type == types; } _advance() { var _a2, _b; this._currentLine = (_b = (_a2 = this._peek()) === null || _a2 === void 0 ? void 0 : _a2.line) !== null && _b !== void 0 ? _b : -1; if (!this._isAtEnd()) { this._current++; } return this._previous(); } _peek() { return this._tokens[this._current]; } _previous() { return this._tokens[this._current - 1]; } _global_decl_or_directive() { while (this._match(TokenTypes.tokens.semicolon) && !this._isAtEnd()) ; if (this._match(TokenTypes.keywords.alias)) { const type = this._type_alias(); this._consume(TokenTypes.tokens.semicolon, "Expected ';'"); return type; } if (this._match(TokenTypes.keywords.diagnostic)) { const directive = this._diagnostic(); this._consume(TokenTypes.tokens.semicolon, "Expected ';'"); return directive; } if (this._match(TokenTypes.keywords.requires)) { const requires = this._requires_directive(); this._consume(TokenTypes.tokens.semicolon, "Expected ';'"); return requires; } if (this._match(TokenTypes.keywords.enable)) { const enable2 = this._enable_directive(); this._consume(TokenTypes.tokens.semicolon, "Expected ';'"); return enable2; } const attrs = this._attribute(); if (this._check(TokenTypes.keywords.var)) { const _var = this._global_variable_decl(); if (_var != null) { _var.attributes = attrs; } this._consume(TokenTypes.tokens.semicolon, "Expected ';'."); return _var; } if (this._check(TokenTypes.keywords.override)) { const _override = this._override_variable_decl(); if (_override != null) { _override.attributes = attrs; } this._consume(TokenTypes.tokens.semicolon, "Expected ';'."); return _override; } if (this._check(TokenTypes.keywords.let)) { const _let = this._global_let_decl(); if (_let != null) { _let.attributes = attrs; } this._consume(TokenTypes.tokens.semicolon, "Expected ';'."); return _let; } if (this._check(TokenTypes.keywords.const)) { const _const = this._global_const_decl(); if (_const != null) { _const.attributes = attrs; } this._consume(TokenTypes.tokens.semicolon, "Expected ';'."); return _const; } if (this._check(TokenTypes.keywords.struct)) { const _struct = this._struct_decl(); if (_struct != null) { _struct.attributes = attrs; } return _struct; } if (this._check(TokenTypes.keywords.fn)) { const _fn = this._function_decl(); if (_fn != null) { _fn.attributes = attrs; } return _fn; } return null; } _function_decl() { if (!this._match(TokenTypes.keywords.fn)) { return null; } const startLine = this._currentLine; const name2 = this._consume(TokenTypes.tokens.ident, "Expected function name.").toString(); this._consume(TokenTypes.tokens.paren_left, "Expected '(' for function arguments."); const args = []; if (!this._check(TokenTypes.tokens.paren_right)) { do { if (this._check(TokenTypes.tokens.paren_right)) { break; } const argAttrs = this._attribute(); const name3 = this._consume(TokenTypes.tokens.ident, "Expected argument name.").toString(); this._consume(TokenTypes.tokens.colon, "Expected ':' for argument type."); const typeAttrs = this._attribute(); const type = this._type_decl(); if (type != null) { type.attributes = typeAttrs; args.push(new Argument(name3, type, argAttrs)); } } while (this._match(TokenTypes.tokens.comma)); } this._consume(TokenTypes.tokens.paren_right, "Expected ')' after function arguments."); let _return = null; if (this._match(TokenTypes.tokens.arrow)) { const attrs = this._attribute(); _return = this._type_decl(); if (_return != null) { _return.attributes = attrs; } } const body = this._compound_statement(); const endLine = this._currentLine; return new Function(name2, args, _return, body, startLine, endLine); } _compound_statement() { const statements = []; this._consume(TokenTypes.tokens.brace_left, "Expected '{' for block."); while (!this._check(TokenTypes.tokens.brace_right)) { const statement = this._statement(); if (statement !== null) { statements.push(statement); } } this._consume(TokenTypes.tokens.brace_right, "Expected '}' for block."); return statements; } _statement() { while (this._match(TokenTypes.tokens.semicolon) && !this._isAtEnd()) ; if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } if (this._check(TokenTypes.keywords.if)) { return this._if_statement(); } if (this._check(TokenTypes.keywords.switch)) { return this._switch_statement(); } if (this._check(TokenTypes.keywords.loop)) { return this._loop_statement(); } if (this._check(TokenTypes.keywords.for)) { return this._for_statement(); } if (this._check(TokenTypes.keywords.while)) { return this._while_statement(); } if (this._check(TokenTypes.keywords.continuing)) { return this._continuing_statement(); } if (this._check(TokenTypes.keywords.static_assert)) { return this._static_assert_statement(); } if (this._check(TokenTypes.tokens.brace_left)) { return this._compound_statement(); } let result = null; if (this._check(TokenTypes.keywords.return)) { result = this._return_statement(); } else if (this._check([ TokenTypes.keywords.var, TokenTypes.keywords.let, TokenTypes.keywords.const ])) { result = this._variable_statement(); } else if (this._match(TokenTypes.keywords.discard)) { result = new Discard(); } else if (this._match(TokenTypes.keywords.break)) { result = new Break(); } else if (this._match(TokenTypes.keywords.continue)) { result = new Continue(); } else { result = this._increment_decrement_statement() || this._func_call_statement() || this._assignment_statement(); } if (result != null) { this._consume(TokenTypes.tokens.semicolon, "Expected ';' after statement."); } return result; } _static_assert_statement() { if (!this._match(TokenTypes.keywords.static_assert)) { return null; } const expression = this._optional_paren_expression(); return new StaticAssert(expression); } _while_statement() { if (!this._match(TokenTypes.keywords.while)) { return null; } const condition = this._optional_paren_expression(); if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } const block = this._compound_statement(); return new While(condition, block); } _continuing_statement() { if (!this._match(TokenTypes.keywords.continuing)) { return null; } const block = this._compound_statement(); return new Continuing(block); } _for_statement() { if (!this._match(TokenTypes.keywords.for)) { return null; } this._consume(TokenTypes.tokens.paren_left, "Expected '('."); const init = !this._check(TokenTypes.tokens.semicolon) ? this._for_init() : null; this._consume(TokenTypes.tokens.semicolon, "Expected ';'."); const condition = !this._check(TokenTypes.tokens.semicolon) ? this._short_circuit_or_expression() : null; this._consume(TokenTypes.tokens.semicolon, "Expected ';'."); const increment = !this._check(TokenTypes.tokens.paren_right) ? this._for_increment() : null; this._consume(TokenTypes.tokens.paren_right, "Expected ')'."); if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } const body = this._compound_statement(); return new For(init, condition, increment, body); } _for_init() { return this._variable_statement() || this._func_call_statement() || this._assignment_statement(); } _for_increment() { return this._func_call_statement() || this._increment_decrement_statement() || this._assignment_statement(); } _variable_statement() { if (this._check(TokenTypes.keywords.var)) { const _var = this._variable_decl(); if (_var === null) { throw this._error(this._peek(), "Variable declaration expected."); } let value = null; if (this._match(TokenTypes.tokens.equal)) { value = this._short_circuit_or_expression(); } return new Var(_var.name, _var.type, _var.storage, _var.access, value); } if (this._match(TokenTypes.keywords.let)) { const name2 = this._consume(TokenTypes.tokens.ident, "Expected name for let.").toString(); let type = null; if (this._match(TokenTypes.tokens.colon)) { const typeAttrs = this._attribute(); type = this._type_decl(); if (type != null) { type.attributes = typeAttrs; } } this._consume(TokenTypes.tokens.equal, "Expected '=' for let."); const value = this._short_circuit_or_expression(); return new Let(name2, type, null, null, value); } if (this._match(TokenTypes.keywords.const)) { const name2 = this._consume(TokenTypes.tokens.ident, "Expected name for const.").toString(); let type = null; if (this._match(TokenTypes.tokens.colon)) { const typeAttrs = this._attribute(); type = this._type_decl(); if (type != null) { type.attributes = typeAttrs; } } this._consume(TokenTypes.tokens.equal, "Expected '=' for const."); const value = this._short_circuit_or_expression(); return new Const(name2, type, null, null, value); } return null; } _increment_decrement_statement() { const savedPos = this._current; const _var = this._unary_expression(); if (_var == null) { return null; } if (!this._check(TokenTypes.increment_operators)) { this._current = savedPos; return null; } const token = this._consume(TokenTypes.increment_operators, "Expected increment operator"); return new Increment(token.type === TokenTypes.tokens.plus_plus ? IncrementOperator.increment : IncrementOperator.decrement, _var); } _assignment_statement() { let _var = null; if (this._check(TokenTypes.tokens.brace_right)) { return null; } let isUnderscore = this._match(TokenTypes.tokens.underscore); if (!isUnderscore) { _var = this._unary_expression(); } if (!isUnderscore && _var == null) { return null; } const type = this._consume(TokenTypes.assignment_operators, "Expected assignment operator."); const value = this._short_circuit_or_expression(); return new Assign(AssignOperator.parse(type.lexeme), _var, value); } _func_call_statement() { if (!this._check(TokenTypes.tokens.ident)) { return null; } const savedPos = this._current; const name2 = this._consume(TokenTypes.tokens.ident, "Expected function name."); const args = this._argument_expression_list(); if (args === null) { this._current = savedPos; return null; } return new Call(name2.lexeme, args); } _loop_statement() { if (!this._match(TokenTypes.keywords.loop)) { return null; } if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } this._consume(TokenTypes.tokens.brace_left, "Expected '{' for loop."); const statements = []; let statement = this._statement(); while (statement !== null) { if (Array.isArray(statement)) { for (let s of statement) { statements.push(s); } } else { statements.push(statement); } statement = this._statement(); } let continuing = null; if (this._match(TokenTypes.keywords.continuing)) { continuing = this._compound_statement(); } this._consume(TokenTypes.tokens.brace_right, "Expected '}' for loop."); return new Loop(statements, continuing); } _switch_statement() { if (!this._match(TokenTypes.keywords.switch)) { return null; } const condition = this._optional_paren_expression(); if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } this._consume(TokenTypes.tokens.brace_left, "Expected '{' for switch."); const body = this._switch_body(); if (body == null || body.length == 0) { throw this._error(this._previous(), "Expected 'case' or 'default'."); } this._consume(TokenTypes.tokens.brace_right, "Expected '}' for switch."); return new Switch(condition, body); } _switch_body() { const cases = []; if (this._match(TokenTypes.keywords.case)) { const selector = this._case_selectors(); this._match(TokenTypes.tokens.colon); if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch case."); const body = this._case_body(); this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch case."); cases.push(new Case(selector, body)); } if (this._match(TokenTypes.keywords.default)) { this._match(TokenTypes.tokens.colon); if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch default."); const body = this._case_body(); this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch default."); cases.push(new Default(body)); } if (this._check([TokenTypes.keywords.default, TokenTypes.keywords.case])) { const _cases = this._switch_body(); cases.push(_cases[0]); } return cases; } _case_selectors() { const selectors = [ this._shift_expression() ]; while (this._match(TokenTypes.tokens.comma)) { selectors.push(this._shift_expression()); } return selectors; } _case_body() { if (this._match(TokenTypes.keywords.fallthrough)) { this._consume(TokenTypes.tokens.semicolon, "Expected ';'"); return []; } let statement = this._statement(); if (statement == null) { return []; } if (!(statement instanceof Array)) { statement = [statement]; } const nextStatement = this._case_body(); if (nextStatement.length == 0) { return statement; } return [...statement, nextStatement[0]]; } _if_statement() { if (!this._match(TokenTypes.keywords.if)) { return null; } const condition = this._optional_paren_expression(); if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } const block = this._compound_statement(); let elseif = []; if (this._match_elseif()) { if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } elseif = this._elseif_statement(elseif); } let _else = null; if (this._match(TokenTypes.keywords.else)) { if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } _else = this._compound_statement(); } return new If(condition, block, elseif, _else); } _match_elseif() { if (this._tokens[this._current].type === TokenTypes.keywords.else && this._tokens[this._current + 1].type === TokenTypes.keywords.if) { this._advance(); this._advance(); return true; } return false; } _elseif_statement(elseif = []) { const condition = this._optional_paren_expression(); const block = this._compound_statement(); elseif.push(new ElseIf(condition, block)); if (this._match_elseif()) { if (this._check(TokenTypes.tokens.attr)) { this._attribute(); } this._elseif_statement(elseif); } return elseif; } _return_statement() { if (!this._match(TokenTypes.keywords.return)) { return null; } const value = this._short_circuit_or_expression(); return new Return(value); } _short_circuit_or_expression() { let expr = this._short_circuit_and_expr(); while (this._match(TokenTypes.tokens.or_or)) { expr = new BinaryOperator(this._previous().toString(), expr, this._short_circuit_and_expr()); } return expr; } _short_circuit_and_expr() { let expr = this._inclusive_or_expression(); while (this._match(TokenTypes.tokens.and_and)) { expr = new BinaryOperator(this._previous().toString(), expr, this._inclusive_or_expression()); } return expr; } _inclusive_or_expression() { let expr = this._exclusive_or_expression(); while (this._match(TokenTypes.tokens.or)) { expr = new BinaryOperator(this._previous().toString(), expr, this._exclusive_or_expression()); } return expr; } _exclusive_or_expression() { let expr = this._and_expression(); while (this._match(TokenTypes.tokens.xor)) { expr = new BinaryOperator(this._previous().toString(), expr, this._and_expression()); } return expr; } _and_expression() { let expr = this._equality_expression(); while (this._match(TokenTypes.tokens.and)) { expr = new BinaryOperator(this._previous().toString(), expr, this._equality_expression()); } return expr; } _equality_expression() { const expr = this._relational_expression(); if (this._match([TokenTypes.tokens.equal_equal, TokenTypes.tokens.not_equal])) { return new BinaryOperator(this._previous().toString(), expr, this._relational_expression()); } return expr; } _relational_expression() { let expr = this._shift_expression(); while (this._match([ TokenTypes.tokens.less_than, TokenTypes.tokens.greater_than, TokenTypes.tokens.less_than_equal, TokenTypes.tokens.greater_than_equal ])) { expr = new BinaryOperator(this._previous().toString(), expr, this._shift_expression()); } return expr; } _shift_expression() { let expr = this._additive_expression(); while (this._match([TokenTypes.tokens.shift_left, TokenTypes.tokens.shift_right])) { expr = new BinaryOperator(this._previous().toString(), expr, this._additive_expression()); } return expr; } _additive_expression() { let expr = this._multiplicative_expression(); while (this._match([TokenTypes.tokens.plus, TokenTypes.tokens.minus])) { expr = new BinaryOperator(this._previous().toString(), expr, this._multiplicative_expression()); } return expr; } _multiplicative_expression() { let expr = this._unary_expression(); while (this._match([ TokenTypes.tokens.star, TokenTypes.tokens.forward_slash, TokenTypes.tokens.modulo ])) { expr = new BinaryOperator(this._previous().toString(), expr, this._unary_expression()); } return expr; } _unary_expression() { if (this._match([ TokenTypes.tokens.minus, TokenTypes.tokens.bang, TokenTypes.tokens.tilde, TokenTypes.tokens.star, TokenTypes.tokens.and ])) { return new UnaryOperator(this._previous().toString(), this._unary_expression()); } return this._singular_expression(); } _singular_expression() { const expr = this._primary_expression(); const p = this._postfix_expression(); if (p) { expr.postfix = p; } return expr; } _postfix_expression() { if (this._match(TokenTypes.tokens.bracket_left)) { const expr = this._short_circuit_or_expression(); this._consume(TokenTypes.tokens.bracket_right, "Expected ']'."); const arrayIndex = new ArrayIndex(expr); const p = this._postfix_expression(); if (p) { arrayIndex.postfix = p; } return arrayIndex; } if (this._match(TokenTypes.tokens.period)) { const name2 = this._consume(TokenTypes.tokens.ident, "Expected member name."); const p = this._postfix_expression(); const expr = new StringExpr(name2.lexeme); if (p) { expr.postfix = p; } return expr; } return null; } _getStruct(name2) { if (this._context.aliases.has(name2)) { const alias = this._context.aliases.get(name2).type; return alias; } if (this._context.structs.has(name2)) { const struct = this._context.structs.get(name2); return struct; } return null; } _primary_expression() { if (this._match(TokenTypes.tokens.ident)) { const name2 = this._previous().toString(); if (this._check(TokenTypes.tokens.paren_left)) { const args2 = this._argument_expression_list(); const struct = this._getStruct(name2); if (struct != null) { return new CreateExpr(struct, args2); } return new CallExpr(name2, args2); } if (this._context.constants.has(name2)) { const c = this._context.constants.get(name2); return new ConstExpr(name2, c.value); } return new VariableExpr(name2); } if (this._match(TokenTypes.const_literal)) { return new LiteralExpr(parseFloat(this._previous().toString())); } if (this._check(TokenTypes.tokens.paren_left)) { return this._paren_expression(); } if (this._match(TokenTypes.keywords.bitcast)) { this._consume(TokenTypes.tokens.less_than, "Expected '<'."); const type2 = this._type_decl(); this._consume(TokenTypes.tokens.greater_than, "Expected '>'."); const value = this._paren_expression(); return new BitcastExpr(type2, value); } const type = this._type_decl(); const args = this._argument_expression_list(); return new TypecastExpr(type, args); } _argument_expression_list() { if (!this._match(TokenTypes.tokens.paren_left)) { return null; } const args = []; do { if (this._check(TokenTypes.tokens.paren_right)) { break; } const arg = this._short_circuit_or_expression(); args.push(arg); } while (this._match(TokenTypes.tokens.comma)); this._consume(TokenTypes.tokens.paren_right, "Expected ')' for agument list"); return args; } _optional_paren_expression() { this._match(TokenTypes.tokens.paren_left); const expr = this._short_circuit_or_expression(); this._match(TokenTypes.tokens.paren_right); return new GroupingExpr([expr]); } _paren_expression() { this._consume(TokenTypes.tokens.paren_left, "Expected '('."); const expr = this._short_circuit_or_expression(); this._consume(TokenTypes.tokens.paren_right, "Expected ')'."); return new GroupingExpr([expr]); } _struct_decl() { if (!this._match(TokenTypes.keywords.struct)) { return null; } const startLine = this._currentLine; const name2 = this._consume(TokenTypes.tokens.ident, "Expected name for struct.").toString(); this._consume(TokenTypes.tokens.brace_left, "Expected '{' for struct body."); const members = []; while (!this._check(TokenTypes.tokens.brace_right)) { const memberAttrs = this._attribute(); const memberName = this._consume(TokenTypes.tokens.ident, "Expected variable name.").toString(); this._consume(TokenTypes.tokens.colon, "Expected ':' for struct member type."); const typeAttrs = this._attribute(); const memberType = this._type_decl(); if (memberType != null) { memberType.attributes = typeAttrs; } if (!this._check(TokenTypes.tokens.brace_right)) this._consume(TokenTypes.tokens.comma, "Expected ',' for struct member."); else this._match(TokenTypes.tokens.comma); members.push(new Member(memberName, memberType, memberAttrs)); } this._consume(TokenTypes.tokens.brace_right, "Expected '}' after struct body."); const endLine = this._currentLine; const structNode = new Struct(name2, members, startLine, endLine); this._context.structs.set(name2, structNode); return structNode; } _global_variable_decl() { const _var = this._variable_decl(); if (_var && this._match(TokenTypes.tokens.equal)) { _var.value = this._const_expression(); } return _var; } _override_variable_decl() { const _override = this._override_decl(); if (_override && this._match(TokenTypes.tokens.equal)) { _override.value = this._const_expression(); } return _override; } _global_const_decl() { if (!this._match(TokenTypes.keywords.const)) { return null; } const name2 = this._consume(TokenTypes.tokens.ident, "Expected variable name"); let type = null; if (this._match(TokenTypes.tokens.colon)) { const attrs = this._attribute(); type = this._type_decl(); if (type != null) { type.attributes = attrs; } } let value = null; if (this._match(TokenTypes.tokens.equal)) { const valueExpr = this._short_circuit_or_expression(); if (valueExpr instanceof CreateExpr) { value = valueExpr; } else if (valueExpr instanceof ConstExpr && valueExpr.initializer instanceof CreateExpr) { value = valueExpr.initializer; } else { try { const constValue = valueExpr.evaluate(this._context); value = new LiteralExpr(constValue); } catch (_a2) { value = valueExpr; } } } const c = new Const(name2.toString(), type, "", "", value); this._context.constants.set(c.name, c); return c; } _global_let_decl() { if (!this._match(TokenTypes.keywords.let)) { return null; } const name2 = this._consume(TokenTypes.tokens.ident, "Expected variable name"); let type = null; if (this._match(TokenTypes.tokens.colon)) { const attrs = this._attribute(); type = this._type_decl(); if (type != null) { type.attributes = attrs; } } let value = null; if (this._match(TokenTypes.tokens.equal)) { value = this._const_expression(); } return new Let(name2.toString(), type, "", "", value); } _const_expression() { if (this._match(TokenTypes.const_literal)) { return new StringExpr(this._previous().toString()); } const type = this._type_decl(); this._consume(TokenTypes.tokens.paren_left, "Expected '('."); let args = []; while (!this._check(TokenTypes.tokens.paren_right)) { args.push(this._const_expression()); if (!this._check(TokenTypes.tokens.comma)) { break; } this._advance(); } this._consume(TokenTypes.tokens.paren_right, "Expected ')'."); return new CreateExpr(type, args); } _variable_decl() { if (!this._match(TokenTypes.keywords.var)) { return null; } let storage = ""; let access = ""; if (this._match(TokenTypes.tokens.less_than)) { storage = this._consume(TokenTypes.storage_class, "Expected storage_class.").toString(); if (this._match(TokenTypes.tokens.comma)) access = this._consume(TokenTypes.access_mode, "Expected access_mode.").toString(); this._consume(TokenTypes.tokens.greater_than, "Expected '>'."); } const name2 = this._consume(TokenTypes.tokens.ident, "Expected variable name"); let type = null; if (this._match(TokenTypes.tokens.colon)) { const attrs = this._attribute(); type = this._type_decl(); if (type != null) { type.attributes = attrs; } } return new Var(name2.toString(), type, storage, access, null); } _override_decl() { if (!this._match(TokenTypes.keywords.override)) { return null; } const name2 = this._consume(TokenTypes.tokens.ident, "Expected variable name"); let type = null; if (this._match(TokenTypes.tokens.colon)) { const attrs = this._attribute(); type = this._type_decl(); if (type != null) { type.attributes = attrs; } } return new Override(name2.toString(), type, null); } _diagnostic() { this._consume(TokenTypes.tokens.paren_left, "Expected '('"); const severity = this._consume(TokenTypes.tokens.ident, "Expected severity control name."); this._consume(TokenTypes.tokens.comma, "Expected ','"); const rule = this._consume(TokenTypes.tokens.ident, "Expected diagnostic rule name."); this._consume(TokenTypes.tokens.paren_right, "Expected ')'"); return new Diagnostic(severity.toString(), rule.toString()); } _enable_directive() { const name2 = this._consume(TokenTypes.tokens.ident, "identity expected."); return new Enable(name2.toString()); } _requires_directive() { const extensions = [this._consume(TokenTypes.tokens.ident, "identity expected.").toString()]; while (this._match(TokenTypes.tokens.comma)) { const name2 = this._consume(TokenTypes.tokens.ident, "identity expected."); extensions.push(name2.toString()); } return new Requires(extensions); } _type_alias() { const name2 = this._consume(TokenTypes.tokens.ident, "identity expected."); this._consume(TokenTypes.tokens.equal, "Expected '=' for type alias."); let aliasType = this._type_decl(); if (aliasType === null) { throw this._error(this._peek(), "Expected Type for Alias."); } if (this._context.aliases.has(aliasType.name)) { aliasType = this._context.aliases.get(aliasType.name).type; } const aliasNode = new Alias(name2.toString(), aliasType); this._context.aliases.set(aliasNode.name, aliasNode); return aliasNode; } _type_decl() { if (this._check([ TokenTypes.tokens.ident, ...TokenTypes.texel_format, TokenTypes.keywords.bool, TokenTypes.keywords.f32, TokenTypes.keywords.i32, TokenTypes.keywords.u32 ])) { const type2 = this._advance(); const typeName = type2.toString(); if (this._context.structs.has(typeName)) { return this._context.structs.get(typeName); } if (this._context.aliases.has(typeName)) { return this._context.aliases.get(typeName).type; } return new Type(type2.toString()); } let type = this._texture_sampler_types(); if (type) { return type; } if (this._check(TokenTypes.template_types)) { let type2 = this._advance().toString(); let format = null; let access = null; if (this._match(TokenTypes.tokens.less_than)) { format = this._type_decl(); access = null; if (this._match(TokenTypes.tokens.comma)) { access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString(); } this._consume(TokenTypes.tokens.greater_than, "Expected '>' for type."); } return new TemplateType(type2, format, access); } if (this._match(TokenTypes.keywords.ptr)) { let pointer = this._previous().toString(); this._consume(TokenTypes.tokens.less_than, "Expected '<' for pointer."); const storage = this._consume(TokenTypes.storage_class, "Expected storage_class for pointer"); this._consume(TokenTypes.tokens.comma, "Expected ',' for pointer."); const decl = this._type_decl(); let access = null; if (this._match(TokenTypes.tokens.comma)) { access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString(); } this._consume(TokenTypes.tokens.greater_than, "Expected '>' for pointer."); return new PointerType(pointer, storage.toString(), decl, access); } const attrs = this._attribute(); if (this._match(TokenTypes.keywords.array)) { let format = null; let countInt = -1; const array = this._previous(); let countNode = null; if (this._match(TokenTypes.tokens.less_than)) { format = this._type_decl(); if (this._context.aliases.has(format.name)) { format = this._context.aliases.get(format.name).type; } let count2 = ""; if (this._match(TokenTypes.tokens.comma)) { countNode = this._shift_expression(); try { count2 = countNode.evaluate(this._context).toString(); countNode = null; } catch (e2) { count2 = "1"; } } this._consume(TokenTypes.tokens.greater_than, "Expected '>' for array."); countInt = count2 ? parseInt(count2) : 0; } const arrayType = new ArrayType(array.toString(), attrs, format, countInt); if (countNode) { this._deferArrayCountEval.push({ arrayType, countNode }); } return arrayType; } return null; } _texture_sampler_types() { if (this._match(TokenTypes.sampler_type)) { return new SamplerType(this._previous().toString(), null, null); } if (this._match(TokenTypes.depth_texture_type)) { return new SamplerType(this._previous().toString(), null, null); } if (this._match(TokenTypes.sampled_texture_type) || this._match(TokenTypes.multisampled_texture_type)) { const sampler = this._previous(); this._consume(TokenTypes.tokens.less_than, "Expected '<' for sampler type."); const format = this._type_decl(); this._consume(TokenTypes.tokens.greater_than, "Expected '>' for sampler type."); return new SamplerType(sampler.toString(), format, null); } if (this._match(TokenTypes.storage_texture_type)) { const sampler = this._previous(); this._consume(TokenTypes.tokens.less_than, "Expected '<' for sampler type."); const format = this._consume(TokenTypes.texel_format, "Invalid texel format.").toString(); this._consume(TokenTypes.tokens.comma, "Expected ',' after texel format."); const access = this._consume(TokenTypes.access_mode, "Expected access mode for storage texture type.").toString(); this._consume(TokenTypes.tokens.greater_than, "Expected '>' for sampler type."); return new SamplerType(sampler.toString(), format, access); } return null; } _attribute() { let attributes = []; while (this._match(TokenTypes.tokens.attr)) { const name2 = this._consume(TokenTypes.attribute_name, "Expected attribute name"); const attr = new Attribute(name2.toString(), null); if (this._match(TokenTypes.tokens.paren_left)) { attr.value = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString(); if (this._check(TokenTypes.tokens.comma)) { this._advance(); do { const v = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString(); if (!(attr.value instanceof Array)) { attr.value = [attr.value]; } attr.value.push(v); } while (this._match(TokenTypes.tokens.comma)); } this._consume(TokenTypes.tokens.paren_right, "Expected ')'"); } attributes.push(attr); } if (attributes.length == 0) { return null; } return attributes; } }; var TypeInfo = class { constructor(name2, attributes) { this.name = name2; this.attributes = attributes; this.size = 0; } get isArray() { return false; } get isStruct() { return false; } get isTemplate() { return false; } }; var MemberInfo = class { constructor(name2, type, attributes) { this.name = name2; this.type = type; this.attributes = attributes; this.offset = 0; this.size = 0; } get isArray() { return this.type.isArray; } get isStruct() { return this.type.isStruct; } get isTemplate() { return this.type.isTemplate; } get align() { return this.type.isStruct ? this.type.align : 0; } get members() { return this.type.isStruct ? this.type.members : null; } get format() { return this.type.isArray ? this.type.format : this.type.isTemplate ? this.type.format : null; } get count() { return this.type.isArray ? this.type.count : 0; } get stride() { return this.type.isArray ? this.type.stride : this.size; } }; var StructInfo = class extends TypeInfo { constructor(name2, attributes) { super(name2, attributes); this.members = []; this.align = 0; this.startLine = -1; this.endLine = -1; this.inUse = false; } get isStruct() { return true; } }; var ArrayInfo = class extends TypeInfo { constructor(name2, attributes) { super(name2, attributes); this.count = 0; this.stride = 0; } get isArray() { return true; } }; var TemplateInfo = class extends TypeInfo { constructor(name2, format, attributes, access) { super(name2, attributes); this.format = format; this.access = access; } get isTemplate() { return true; } }; var ResourceType; (function(ResourceType2) { ResourceType2[ResourceType2["Uniform"] = 0] = "Uniform"; ResourceType2[ResourceType2["Storage"] = 1] = "Storage"; ResourceType2[ResourceType2["Texture"] = 2] = "Texture"; ResourceType2[ResourceType2["Sampler"] = 3] = "Sampler"; ResourceType2[ResourceType2["StorageTexture"] = 4] = "StorageTexture"; })(ResourceType || (ResourceType = {})); var VariableInfo = class { constructor(name2, type, group, binding, attributes, resourceType, access) { this.name = name2; this.type = type; this.group = group; this.binding = binding; this.attributes = attributes; this.resourceType = resourceType; this.access = access; } get isArray() { return this.type.isArray; } get isStruct() { return this.type.isStruct; } get isTemplate() { return this.type.isTemplate; } get size() { return this.type.size; } get align() { return this.type.isStruct ? this.type.align : 0; } get members() { return this.type.isStruct ? this.type.members : null; } get format() { return this.type.isArray ? this.type.format : this.type.isTemplate ? this.type.format : null; } get count() { return this.type.isArray ? this.type.count : 0; } get stride() { return this.type.isArray ? this.type.stride : this.size; } }; var AliasInfo = class { constructor(name2, type) { this.name = name2; this.type = type; } }; var _TypeSize = class { constructor(align, size) { this.align = align; this.size = size; } }; var InputInfo = class { constructor(name2, type, locationType, location) { this.name = name2; this.type = type; this.locationType = locationType; this.location = location; this.interpolation = null; } }; var OutputInfo = class { constructor(name2, type, locationType, location) { this.name = name2; this.type = type; this.locationType = locationType; this.location = location; } }; var FunctionInfo = class { constructor(name2, stage = null) { this.stage = null; this.inputs = []; this.outputs = []; this.resources = []; this.startLine = -1; this.endLine = -1; this.inUse = false; this.calls = /* @__PURE__ */ new Set(); this.name = name2; this.stage = stage; } }; var EntryFunctions = class { constructor() { this.vertex = []; this.fragment = []; this.compute = []; } }; var OverrideInfo = class { constructor(name2, type, attributes, id) { this.name = name2; this.type = type; this.attributes = attributes; this.id = id; } }; var _FunctionResources = class { constructor(node) { this.resources = null; this.inUse = false; this.info = null; this.node = node; } }; var WgslReflect = class { constructor(code) { this.uniforms = []; this.storage = []; this.textures = []; this.samplers = []; this.aliases = []; this.overrides = []; this.structs = []; this.entry = new EntryFunctions(); this.functions = []; this._types = /* @__PURE__ */ new Map(); this._functions = /* @__PURE__ */ new Map(); if (code) { this.update(code); } } _isStorageTexture(type) { return type.name == "texture_storage_1d" || type.name == "texture_storage_2d" || type.name == "texture_storage_2d_array" || type.name == "texture_storage_3d"; } update(code) { const parser = new WgslParser(); const ast = parser.parse(code); for (const node of ast) { if (node instanceof Function) { this._functions.set(node.name, new _FunctionResources(node)); } } for (const node of ast) { if (node instanceof Struct) { const info = this._getTypeInfo(node, null); if (info instanceof StructInfo) { this.structs.push(info); } } } for (const node of ast) { if (node instanceof Alias) { this.aliases.push(this._getAliasInfo(node)); continue; } if (node instanceof Override) { const v = node; const id = this._getAttributeNum(v.attributes, "id", 0); const type = v.type != null ? this._getTypeInfo(v.type, v.attributes) : null; this.overrides.push(new OverrideInfo(v.name, type, v.attributes, id)); continue; } if (this._isUniformVar(node)) { const v = node; const g = this._getAttributeNum(v.attributes, "group", 0); const b = this._getAttributeNum(v.attributes, "binding", 0); const type = this._getTypeInfo(v.type, v.attributes); const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, ResourceType.Uniform, v.access); this.uniforms.push(varInfo); continue; } if (this._isStorageVar(node)) { const v = node; const g = this._getAttributeNum(v.attributes, "group", 0); const b = this._getAttributeNum(v.attributes, "binding", 0); const type = this._getTypeInfo(v.type, v.attributes); const isStorageTexture = this._isStorageTexture(type); const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, isStorageTexture ? ResourceType.StorageTexture : ResourceType.Storage, v.access); this.storage.push(varInfo); continue; } if (this._isTextureVar(node)) { const v = node; const g = this._getAttributeNum(v.attributes, "group", 0); const b = this._getAttributeNum(v.attributes, "binding", 0); const type = this._getTypeInfo(v.type, v.attributes); const isStorageTexture = this._isStorageTexture(type); const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, isStorageTexture ? ResourceType.StorageTexture : ResourceType.Texture, v.access); if (isStorageTexture) { this.storage.push(varInfo); } else { this.textures.push(varInfo); } continue; } if (this._isSamplerVar(node)) { const v = node; const g = this._getAttributeNum(v.attributes, "group", 0); const b = this._getAttributeNum(v.attributes, "binding", 0); const type = this._getTypeInfo(v.type, v.attributes); const varInfo = new VariableInfo(v.name, type, g, b, v.attributes, ResourceType.Sampler, v.access); this.samplers.push(varInfo); continue; } if (node instanceof Function) { const vertexStage = this._getAttribute(node, "vertex"); const fragmentStage = this._getAttribute(node, "fragment"); const computeStage = this._getAttribute(node, "compute"); const stage = vertexStage || fragmentStage || computeStage; const fn = new FunctionInfo(node.name, stage === null || stage === void 0 ? void 0 : stage.name); fn.startLine = node.startLine; fn.endLine = node.endLine; this.functions.push(fn); this._functions.get(node.name).info = fn; if (stage) { this._functions.get(node.name).inUse = true; fn.inUse = true; fn.resources = this._findResources(node, !!stage); fn.inputs = this._getInputs(node.args); fn.outputs = this._getOutputs(node.returnType); this.entry[stage.name].push(fn); } continue; } } for (const fn of this._functions.values()) { if (fn.info) { fn.info.inUse = fn.inUse; this._addCalls(fn.node, fn.info.calls); } } for (const u of this.uniforms) { this._markStructsInUse(u.type); } for (const s of this.storage) { this._markStructsInUse(s.type); } } _markStructsInUse(type) { if (type.isStruct) { type.inUse = true; for (const m of type.members) { this._markStructsInUse(m.type); } } else if (type.isArray) { this._markStructsInUse(type.format); } else if (type.isTemplate) { this._markStructsInUse(type.format); } else { const alias = this._getAlias(type.name); if (alias) { this._markStructsInUse(alias); } } } _addCalls(fn, calls) { var _a2; for (const call of fn.calls) { const info = (_a2 = this._functions.get(call.name)) === null || _a2 === void 0 ? void 0 : _a2.info; if (info) { calls.add(info); } } } findResource(group, binding) { for (const u of this.uniforms) { if (u.group == group && u.binding == binding) { return u; } } for (const s of this.storage) { if (s.group == group && s.binding == binding) { return s; } } for (const t of this.textures) { if (t.group == group && t.binding == binding) { return t; } } for (const s of this.samplers) { if (s.group == group && s.binding == binding) { return s; } } return null; } _findResource(name2) { for (const u of this.uniforms) { if (u.name == name2) { return u; } } for (const s of this.storage) { if (s.name == name2) { return s; } } for (const t of this.textures) { if (t.name == name2) { return t; } } for (const s of this.samplers) { if (s.name == name2) { return s; } } return null; } _markStructsFromAST(type) { const info = this._getTypeInfo(type, null); this._markStructsInUse(info); } _findResources(fn, isEntry) { const resources = []; const self2 = this; const varStack = []; fn.search((node) => { if (node instanceof _BlockStart) { varStack.push({}); } else if (node instanceof _BlockEnd) { varStack.pop(); } else if (node instanceof Var) { const v = node; if (isEntry && v.type !== null) { this._markStructsFromAST(v.type); } if (varStack.length > 0) { varStack[varStack.length - 1][v.name] = v; } } else if (node instanceof CreateExpr) { const c = node; if (isEntry && c.type !== null) { this._markStructsFromAST(c.type); } } else if (node instanceof Let) { const v = node; if (isEntry && v.type !== null) { this._markStructsFromAST(v.type); } if (varStack.length > 0) { varStack[varStack.length - 1][v.name] = v; } } else if (node instanceof VariableExpr) { const v = node; if (varStack.length > 0) { const varInfo2 = varStack[varStack.length - 1][v.name]; if (varInfo2) { return; } } const varInfo = self2._findResource(v.name); if (varInfo) { resources.push(varInfo); } } else if (node instanceof CallExpr) { const c = node; const callFn = self2._functions.get(c.name); if (callFn) { if (isEntry) { callFn.inUse = true; } fn.calls.add(callFn.node); if (callFn.resources === null) { callFn.resources = self2._findResources(callFn.node, isEntry); } resources.push(...callFn.resources); } } else if (node instanceof Call) { const c = node; const callFn = self2._functions.get(c.name); if (callFn) { if (isEntry) { callFn.inUse = true; } fn.calls.add(callFn.node); if (callFn.resources === null) { callFn.resources = self2._findResources(callFn.node, isEntry); } resources.push(...callFn.resources); } } }); return [...new Map(resources.map((r) => [r.name, r])).values()]; } getBindGroups() { const groups = []; function _makeRoom(group, binding) { if (group >= groups.length) { groups.length = group + 1; } if (groups[group] === void 0) { groups[group] = []; } if (binding >= groups[group].length) { groups[group].length = binding + 1; } } for (const u of this.uniforms) { _makeRoom(u.group, u.binding); const group = groups[u.group]; group[u.binding] = u; } for (const u of this.storage) { _makeRoom(u.group, u.binding); const group = groups[u.group]; group[u.binding] = u; } for (const t of this.textures) { _makeRoom(t.group, t.binding); const group = groups[t.group]; group[t.binding] = t; } for (const t of this.samplers) { _makeRoom(t.group, t.binding); const group = groups[t.group]; group[t.binding] = t; } return groups; } _getOutputs(type, outputs = void 0) { if (outputs === void 0) { outputs = []; } if (type instanceof Struct) { this._getStructOutputs(type, outputs); } else { const output = this._getOutputInfo(type); if (output !== null) { outputs.push(output); } } return outputs; } _getStructOutputs(struct, outputs) { for (const m of struct.members) { if (m.type instanceof Struct) { this._getStructOutputs(m.type, outputs); } else { const location = this._getAttribute(m, "location") || this._getAttribute(m, "builtin"); if (location !== null) { const typeInfo = this._getTypeInfo(m.type, m.type.attributes); const locationValue = this._parseInt(location.value); const info = new OutputInfo(m.name, typeInfo, location.name, locationValue); outputs.push(info); } } } } _getOutputInfo(type) { const location = this._getAttribute(type, "location") || this._getAttribute(type, "builtin"); if (location !== null) { const typeInfo = this._getTypeInfo(type, type.attributes); const locationValue = this._parseInt(location.value); const info = new OutputInfo("", typeInfo, location.name, locationValue); return info; } return null; } _getInputs(args, inputs = void 0) { if (inputs === void 0) { inputs = []; } for (const arg of args) { if (arg.type instanceof Struct) { this._getStructInputs(arg.type, inputs); } else { const input = this._getInputInfo(arg); if (input !== null) { inputs.push(input); } } } return inputs; } _getStructInputs(struct, inputs) { for (const m of struct.members) { if (m.type instanceof Struct) { this._getStructInputs(m.type, inputs); } else { const input = this._getInputInfo(m); if (input !== null) { inputs.push(input); } } } } _getInputInfo(node) { const location = this._getAttribute(node, "location") || this._getAttribute(node, "builtin"); if (location !== null) { const interpolation = this._getAttribute(node, "interpolation"); const type = this._getTypeInfo(node.type, node.attributes); const locationValue = this._parseInt(location.value); const info = new InputInfo(node.name, type, location.name, locationValue); if (interpolation !== null) { info.interpolation = this._parseString(interpolation.value); } return info; } return null; } _parseString(s) { if (s instanceof Array) { s = s[0]; } return s; } _parseInt(s) { if (s instanceof Array) { s = s[0]; } const n = parseInt(s); return isNaN(n) ? s : n; } _getAlias(name2) { for (const a of this.aliases) { if (a.name == name2) { return a.type; } } return null; } _getAliasInfo(node) { return new AliasInfo(node.name, this._getTypeInfo(node.type, null)); } _getTypeInfo(type, attributes) { if (this._types.has(type)) { return this._types.get(type); } if (type instanceof ArrayType) { const a = type; const t = this._getTypeInfo(a.format, a.attributes); const info2 = new ArrayInfo(a.name, attributes); info2.format = t; info2.count = a.count; this._types.set(type, info2); this._updateTypeInfo(info2); return info2; } if (type instanceof Struct) { const s = type; const info2 = new StructInfo(s.name, attributes); info2.startLine = s.startLine; info2.endLine = s.endLine; for (const m of s.members) { const t = this._getTypeInfo(m.type, m.attributes); info2.members.push(new MemberInfo(m.name, t, m.attributes)); } this._types.set(type, info2); this._updateTypeInfo(info2); return info2; } if (type instanceof SamplerType) { const s = type; const formatIsType = s.format instanceof Type; const format = s.format ? formatIsType ? this._getTypeInfo(s.format, null) : new TypeInfo(s.format, null) : null; const info2 = new TemplateInfo(s.name, format, attributes, s.access); this._types.set(type, info2); this._updateTypeInfo(info2); return info2; } if (type instanceof TemplateType) { const t = type; const format = t.format ? this._getTypeInfo(t.format, null) : null; const info2 = new TemplateInfo(t.name, format, attributes, t.access); this._types.set(type, info2); this._updateTypeInfo(info2); return info2; } const info = new TypeInfo(type.name, attributes); this._types.set(type, info); this._updateTypeInfo(info); return info; } _updateTypeInfo(type) { var _a2, _b; const typeSize = this._getTypeSize(type); type.size = (_a2 = typeSize === null || typeSize === void 0 ? void 0 : typeSize.size) !== null && _a2 !== void 0 ? _a2 : 0; if (type instanceof ArrayInfo) { const formatInfo = this._getTypeSize(type["format"]); type.stride = (_b = formatInfo === null || formatInfo === void 0 ? void 0 : formatInfo.size) !== null && _b !== void 0 ? _b : 0; this._updateTypeInfo(type["format"]); } if (type instanceof StructInfo) { this._updateStructInfo(type); } } _updateStructInfo(struct) { var _a2; let offset = 0; let lastSize = 0; let lastOffset = 0; let structAlign = 0; for (let mi = 0, ml = struct.members.length; mi < ml; ++mi) { const member = struct.members[mi]; const sizeInfo = this._getTypeSize(member); if (!sizeInfo) { continue; } (_a2 = this._getAlias(member.type.name)) !== null && _a2 !== void 0 ? _a2 : member.type; const align = sizeInfo.align; const size = sizeInfo.size; offset = this._roundUp(align, offset + lastSize); lastSize = size; lastOffset = offset; structAlign = Math.max(structAlign, align); member.offset = offset; member.size = size; this._updateTypeInfo(member.type); } struct.size = this._roundUp(structAlign, lastOffset + lastSize); struct.align = structAlign; } _getTypeSize(type) { var _a2; if (type === null || type === void 0) { return null; } const explicitSize = this._getAttributeNum(type.attributes, "size", 0); const explicitAlign = this._getAttributeNum(type.attributes, "align", 0); if (type instanceof MemberInfo) { type = type.type; } if (type instanceof TypeInfo) { const alias = this._getAlias(type.name); if (alias !== null) { type = alias; } } { const info = WgslReflect._typeInfo[type.name]; if (info !== void 0) { const divisor = type["format"] === "f16" ? 2 : 1; return new _TypeSize(Math.max(explicitAlign, info.align / divisor), Math.max(explicitSize, info.size / divisor)); } } { const info = WgslReflect._typeInfo[type.name.substring(0, type.name.length - 1)]; if (info) { const divisor = type.name[type.name.length - 1] === "h" ? 2 : 1; return new _TypeSize(Math.max(explicitAlign, info.align / divisor), Math.max(explicitSize, info.size / divisor)); } } if (type instanceof ArrayInfo) { let arrayType = type; let align = 8; let size = 8; const E = this._getTypeSize(arrayType.format); if (E !== null) { size = E.size; align = E.align; } const N = arrayType.count; const stride = this._getAttributeNum((_a2 = type === null || type === void 0 ? void 0 : type.attributes) !== null && _a2 !== void 0 ? _a2 : null, "stride", this._roundUp(align, size)); size = N * stride; if (explicitSize) { size = explicitSize; } return new _TypeSize(Math.max(explicitAlign, align), Math.max(explicitSize, size)); } if (type instanceof StructInfo) { let align = 0; let size = 0; let offset = 0; let lastSize = 0; let lastOffset = 0; for (const m of type.members) { const mi = this._getTypeSize(m.type); if (mi !== null) { align = Math.max(mi.align, align); offset = this._roundUp(mi.align, offset + lastSize); lastSize = mi.size; lastOffset = offset; } } size = this._roundUp(align, lastOffset + lastSize); return new _TypeSize(Math.max(explicitAlign, align), Math.max(explicitSize, size)); } return null; } _isUniformVar(node) { return node instanceof Var && node.storage == "uniform"; } _isStorageVar(node) { return node instanceof Var && node.storage == "storage"; } _isTextureVar(node) { return node instanceof Var && node.type !== null && WgslReflect._textureTypes.indexOf(node.type.name) != -1; } _isSamplerVar(node) { return node instanceof Var && node.type !== null && WgslReflect._samplerTypes.indexOf(node.type.name) != -1; } _getAttribute(node, name2) { const obj = node; if (!obj || !obj["attributes"]) { return null; } const attrs = obj["attributes"]; for (let a of attrs) { if (a.name == name2) { return a; } } return null; } _getAttributeNum(attributes, name2, defaultValue) { if (attributes === null) { return defaultValue; } for (let a of attributes) { if (a.name == name2) { let v = a !== null && a.value !== null ? a.value : defaultValue; if (v instanceof Array) { v = v[0]; } if (typeof v === "number") { return v; } if (typeof v === "string") { return parseInt(v); } return defaultValue; } } return defaultValue; } _roundUp(k, n) { return Math.ceil(n / k) * k; } }; WgslReflect._typeInfo = { f16: { align: 2, size: 2 }, i32: { align: 4, size: 4 }, u32: { align: 4, size: 4 }, f32: { align: 4, size: 4 }, atomic: { align: 4, size: 4 }, vec2: { align: 8, size: 8 }, vec3: { align: 16, size: 12 }, vec4: { align: 16, size: 16 }, mat2x2: { align: 8, size: 16 }, mat3x2: { align: 8, size: 24 }, mat4x2: { align: 8, size: 32 }, mat2x3: { align: 16, size: 32 }, mat3x3: { align: 16, size: 48 }, mat4x3: { align: 16, size: 64 }, mat2x4: { align: 16, size: 32 }, mat3x4: { align: 16, size: 48 }, mat4x4: { align: 16, size: 64 } }; WgslReflect._textureTypes = TokenTypes.any_texture_type.map((t) => { return t.name; }); WgslReflect._samplerTypes = TokenTypes.sampler_type.map((t) => { return t.name; }); // ../../node_modules/@luma.gl/shadertools/dist/lib/wgsl/get-shader-layout-wgsl.js function getShaderLayoutFromWGSL(source) { const shaderLayout = { attributes: [], bindings: [] }; let parsedWGSL; try { parsedWGSL = parseWGSL(source); } catch (error) { log.error(error.message)(); return shaderLayout; } for (const uniform of parsedWGSL.uniforms) { const members = []; for (const attribute of uniform.type?.members || []) { members.push({ name: attribute.name, type: getType(attribute.type) }); } shaderLayout.bindings.push({ type: "uniform", name: uniform.name, location: uniform.binding, group: uniform.group, members }); } const vertex = parsedWGSL.entry.vertex[0]; const attributeCount = vertex?.inputs.length || 0; for (let i = 0; i < attributeCount; i++) { const wgslAttribute = vertex.inputs[i]; if (wgslAttribute.locationType === "location") { const type = getType(wgslAttribute.type); shaderLayout.attributes.push({ name: wgslAttribute.name, location: Number(wgslAttribute.location), type }); } } return shaderLayout; } function getType(type) { return type.format ? `${type.name}<${type.format.name}>` : type.name; } function parseWGSL(source) { try { return new WgslReflect(source); } catch (error) { if (error instanceof Error) { throw error; } let message2 = "WGSL parse error"; if (typeof error === "object" && error?.message) { message2 += `: ${error.message} `; } if (typeof error === "object" && error?.token) { message2 += error.token.line || ""; } throw new Error(message2, { cause: error }); } } // ../../node_modules/@luma.gl/shadertools/dist/modules/math/fp32/fp32.js var fp32shader = `#ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND const float TWO_PI = 6.2831854820251465; const float PI_2 = 1.5707963705062866; const float PI_16 = 0.1963495463132858; const float SIN_TABLE_0 = 0.19509032368659973; const float SIN_TABLE_1 = 0.3826834261417389; const float SIN_TABLE_2 = 0.5555702447891235; const float SIN_TABLE_3 = 0.7071067690849304; const float COS_TABLE_0 = 0.9807852506637573; const float COS_TABLE_1 = 0.9238795042037964; const float COS_TABLE_2 = 0.8314695954322815; const float COS_TABLE_3 = 0.7071067690849304; const float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; const float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; const float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; const float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; float sin_taylor_fp32(float a) { float r, s, t, x; if (a == 0.0) { return 0.0; } x = -a * a; s = a; r = a; r = r * x; t = r * INVERSE_FACTORIAL_3; s = s + t; r = r * x; t = r * INVERSE_FACTORIAL_5; s = s + t; r = r * x; t = r * INVERSE_FACTORIAL_7; s = s + t; r = r * x; t = r * INVERSE_FACTORIAL_9; s = s + t; return s; } void sincos_taylor_fp32(float a, out float sin_t, out float cos_t) { if (a == 0.0) { sin_t = 0.0; cos_t = 1.0; } sin_t = sin_taylor_fp32(a); cos_t = sqrt(1.0 - sin_t * sin_t); } float tan_taylor_fp32(float a) { float sin_a; float cos_a; if (a == 0.0) { return 0.0; } float z = floor(a / TWO_PI); float r = a - TWO_PI * z; float t; float q = floor(r / PI_2 + 0.5); int j = int(q); if (j < -2 || j > 2) { return 1.0 / 0.0; } t = r - PI_2 * q; q = floor(t / PI_16 + 0.5); int k = int(q); int abs_k = int(abs(float(k))); if (abs_k > 4) { return 1.0 / 0.0; } else { t = t - PI_16 * q; } float u = 0.0; float v = 0.0; float sin_t, cos_t; float s, c; sincos_taylor_fp32(t, sin_t, cos_t); if (k == 0) { s = sin_t; c = cos_t; } else { if (abs(float(abs_k) - 1.0) < 0.5) { u = COS_TABLE_0; v = SIN_TABLE_0; } else if (abs(float(abs_k) - 2.0) < 0.5) { u = COS_TABLE_1; v = SIN_TABLE_1; } else if (abs(float(abs_k) - 3.0) < 0.5) { u = COS_TABLE_2; v = SIN_TABLE_2; } else if (abs(float(abs_k) - 4.0) < 0.5) { u = COS_TABLE_3; v = SIN_TABLE_3; } if (k > 0) { s = u * sin_t + v * cos_t; c = u * cos_t - v * sin_t; } else { s = u * sin_t - v * cos_t; c = u * cos_t + v * sin_t; } } if (j == 0) { sin_a = s; cos_a = c; } else if (j == 1) { sin_a = c; cos_a = -s; } else if (j == -1) { sin_a = -c; cos_a = s; } else { sin_a = -s; cos_a = -c; } return sin_a / cos_a; } #endif float tan_fp32(float a) { #ifdef LUMA_FP32_TAN_PRECISION_WORKAROUND return tan_taylor_fp32(a); #else return tan(a); #endif } `; var fp32 = { name: "fp32", vs: fp32shader }; // ../../node_modules/@luma.gl/shadertools/dist/modules/engine/picking/picking.js var DEFAULT_HIGHLIGHT_COLOR = [0, 1, 1, 1]; var vs = `uniform pickingUniforms { float isActive; float isAttribute; float isHighlightActive; float useFloatColors; vec3 highlightedObjectColor; vec4 highlightColor; } picking; out vec4 picking_vRGBcolor_Avalid; vec3 picking_normalizeColor(vec3 color) { return picking.useFloatColors > 0.5 ? color : color / 255.0; } vec4 picking_normalizeColor(vec4 color) { return picking.useFloatColors > 0.5 ? color : color / 255.0; } bool picking_isColorZero(vec3 color) { return dot(color, vec3(1.0)) < 0.00001; } bool picking_isColorValid(vec3 color) { return dot(color, vec3(1.0)) > 0.00001; } bool isVertexHighlighted(vec3 vertexColor) { vec3 highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor); return bool(picking.isHighlightActive) && picking_isColorZero(abs(vertexColor - highlightedObjectColor)); } void picking_setPickingColor(vec3 pickingColor) { pickingColor = picking_normalizeColor(pickingColor); if (bool(picking.isActive)) { picking_vRGBcolor_Avalid.a = float(picking_isColorValid(pickingColor)); if (!bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.rgb = pickingColor; } } else { picking_vRGBcolor_Avalid.a = float(isVertexHighlighted(pickingColor)); } } void picking_setPickingAttribute(float value) { if (bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.r = value; } } void picking_setPickingAttribute(vec2 value) { if (bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.rg = value; } } void picking_setPickingAttribute(vec3 value) { if (bool(picking.isAttribute)) { picking_vRGBcolor_Avalid.rgb = value; } } `; var fs = `uniform pickingUniforms { float isActive; float isAttribute; float isHighlightActive; float useFloatColors; vec3 highlightedObjectColor; vec4 highlightColor; } picking; in vec4 picking_vRGBcolor_Avalid; vec4 picking_filterHighlightColor(vec4 color) { if (picking.isActive > 0.5) { return color; } bool selected = bool(picking_vRGBcolor_Avalid.a); if (selected) { float highLightAlpha = picking.highlightColor.a; float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha); float highLightRatio = highLightAlpha / blendedAlpha; vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio); return vec4(blendedRGB, blendedAlpha); } else { return color; } } vec4 picking_filterPickingColor(vec4 color) { if (bool(picking.isActive)) { if (picking_vRGBcolor_Avalid.a == 0.0) { discard; } return picking_vRGBcolor_Avalid; } return color; } vec4 picking_filterColor(vec4 color) { vec4 highlightColor = picking_filterHighlightColor(color); return picking_filterPickingColor(highlightColor); } `; var picking = { name: "picking", vs, fs, uniformTypes: { isActive: "f32", isAttribute: "f32", isHighlightActive: "f32", useFloatColors: "f32", highlightedObjectColor: "vec3", highlightColor: "vec4" }, defaultUniforms: { isActive: false, isAttribute: false, isHighlightActive: false, useFloatColors: true, highlightedObjectColor: [0, 0, 0], highlightColor: DEFAULT_HIGHLIGHT_COLOR }, getUniforms }; function getUniforms(opts = {}, prevUniforms) { const uniforms = {}; if (opts.highlightedObjectColor === void 0) { } else if (opts.highlightedObjectColor === null) { uniforms.isHighlightActive = false; } else { uniforms.isHighlightActive = true; const highlightedObjectColor = opts.highlightedObjectColor.slice(0, 3); uniforms.highlightedObjectColor = highlightedObjectColor; } if (opts.highlightColor) { const color = Array.from(opts.highlightColor, (x) => x / 255); if (!Number.isFinite(color[3])) { color[3] = 1; } uniforms.highlightColor = color; } if (opts.isActive !== void 0) { uniforms.isActive = Boolean(opts.isActive); uniforms.isAttribute = Boolean(opts.isAttribute); } if (opts.useFloatColors !== void 0) { uniforms.useFloatColors = Boolean(opts.useFloatColors); } return uniforms; } // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/math/fp64/fp64-utils.js function fp64ify(a, out = [], startIndex = 0) { const hiPart = Math.fround(a); const loPart = a - hiPart; out[startIndex] = hiPart; out[startIndex + 1] = loPart; return out; } function fp64LowPart(a) { return a - Math.fround(a); } function fp64ifyMatrix4(matrix) { const matrixFP64 = new Float32Array(32); for (let i = 0; i < 4; ++i) { for (let j = 0; j < 4; ++j) { const index2 = i * 4 + j; fp64ify(matrix[j * 4 + i], matrixFP64, index2 * 2); } } return matrixFP64; } // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/math/fp64/fp64-arithmetic-glsl.js var fp64arithmeticShader = `uniform float ONE; vec2 split(float a) { const float SPLIT = 4097.0; float t = a * SPLIT; #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float a_hi = t * ONE - (t - a); float a_lo = a * ONE - a_hi; #else float a_hi = t - (t - a); float a_lo = a - a_hi; #endif return vec2(a_hi, a_lo); } vec2 split2(vec2 a) { vec2 b = split(a.x); b.y += a.y; return b; } vec2 quickTwoSum(float a, float b) { #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float sum = (a + b) * ONE; float err = b - (sum - a) * ONE; #else float sum = a + b; float err = b - (sum - a); #endif return vec2(sum, err); } vec2 twoSum(float a, float b) { float s = (a + b); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float v = (s * ONE - a) * ONE; float err = (a - (s - v) * ONE) * ONE * ONE * ONE + (b - v); #else float v = s - a; float err = (a - (s - v)) + (b - v); #endif return vec2(s, err); } vec2 twoSub(float a, float b) { float s = (a - b); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float v = (s * ONE - a) * ONE; float err = (a - (s - v) * ONE) * ONE * ONE * ONE - (b + v); #else float v = s - a; float err = (a - (s - v)) - (b + v); #endif return vec2(s, err); } vec2 twoSqr(float a) { float prod = a * a; vec2 a_fp64 = split(a); #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) float err = ((a_fp64.x * a_fp64.x - prod) * ONE + 2.0 * a_fp64.x * a_fp64.y * ONE * ONE) + a_fp64.y * a_fp64.y * ONE * ONE * ONE; #else float err = ((a_fp64.x * a_fp64.x - prod) + 2.0 * a_fp64.x * a_fp64.y) + a_fp64.y * a_fp64.y; #endif return vec2(prod, err); } vec2 twoProd(float a, float b) { float prod = a * b; vec2 a_fp64 = split(a); vec2 b_fp64 = split(b); float err = ((a_fp64.x * b_fp64.x - prod) + a_fp64.x * b_fp64.y + a_fp64.y * b_fp64.x) + a_fp64.y * b_fp64.y; return vec2(prod, err); } vec2 sum_fp64(vec2 a, vec2 b) { vec2 s, t; s = twoSum(a.x, b.x); t = twoSum(a.y, b.y); s.y += t.x; s = quickTwoSum(s.x, s.y); s.y += t.y; s = quickTwoSum(s.x, s.y); return s; } vec2 sub_fp64(vec2 a, vec2 b) { vec2 s, t; s = twoSub(a.x, b.x); t = twoSub(a.y, b.y); s.y += t.x; s = quickTwoSum(s.x, s.y); s.y += t.y; s = quickTwoSum(s.x, s.y); return s; } vec2 mul_fp64(vec2 a, vec2 b) { vec2 prod = twoProd(a.x, b.x); prod.y += a.x * b.y; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) prod = split2(prod); #endif prod = quickTwoSum(prod.x, prod.y); prod.y += a.y * b.x; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) prod = split2(prod); #endif prod = quickTwoSum(prod.x, prod.y); return prod; } vec2 div_fp64(vec2 a, vec2 b) { float xn = 1.0 / b.x; #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) vec2 yn = mul_fp64(a, vec2(xn, 0)); #else vec2 yn = a * xn; #endif float diff = (sub_fp64(a, mul_fp64(b, yn))).x; vec2 prod = twoProd(xn, diff); return sum_fp64(yn, prod); } vec2 sqrt_fp64(vec2 a) { if (a.x == 0.0 && a.y == 0.0) return vec2(0.0, 0.0); if (a.x < 0.0) return vec2(0.0 / 0.0, 0.0 / 0.0); float x = 1.0 / sqrt(a.x); float yn = a.x * x; #if defined(LUMA_FP64_CODE_ELIMINATION_WORKAROUND) vec2 yn_sqr = twoSqr(yn) * ONE; #else vec2 yn_sqr = twoSqr(yn); #endif float diff = sub_fp64(a, yn_sqr).x; vec2 prod = twoProd(x * 0.5, diff); #if defined(LUMA_FP64_HIGH_BITS_OVERFLOW_WORKAROUND) return sum_fp64(split(yn), prod); #else return sum_fp64(vec2(yn, 0.0), prod); #endif } `; // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/math/fp64/fp64.js var CONST_UNIFORMS = { ONE: 1 }; function getUniforms2() { return CONST_UNIFORMS; } var fp64arithmetic = { name: "fp64-arithmetic", vs: fp64arithmeticShader, getUniforms: getUniforms2, fp64ify, fp64LowPart, fp64ifyMatrix4 }; // ../../node_modules/@math.gl/core/dist/lib/common.js var RADIANS_TO_DEGREES = 1 / Math.PI * 180; var DEGREES_TO_RADIANS = 1 / 180 * Math.PI; var DEFAULT_CONFIG = { EPSILON: 1e-12, debug: false, precision: 4, printTypes: false, printDegrees: false, printRowMajor: true, _cartographicRadians: false }; globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } }; var config = globalThis.mathgl.config; function formatValue(value, { precision = config.precision } = {}) { value = round(value); return `${parseFloat(value.toPrecision(precision))}`; } function isArray(value) { return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView); } function radians(degrees2, result) { return map(degrees2, (degrees3) => degrees3 * DEGREES_TO_RADIANS, result); } function degrees(radians2, result) { return map(radians2, (radians3) => radians3 * RADIANS_TO_DEGREES, result); } function clamp(value, min4, max4) { return map(value, (value2) => Math.max(min4, Math.min(max4, value2))); } function lerp(a, b, t) { if (isArray(a)) { return a.map((ai, i) => lerp(ai, b[i], t)); } return t * b + (1 - t) * a; } function equals(a, b, epsilon) { const oldEpsilon = config.EPSILON; if (epsilon) { config.EPSILON = epsilon; } try { if (a === b) { return true; } if (isArray(a) && isArray(b)) { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; ++i) { if (!equals(a[i], b[i])) { return false; } } return true; } if (a && a.equals) { return a.equals(b); } if (b && b.equals) { return b.equals(a); } if (typeof a === "number" && typeof b === "number") { return Math.abs(a - b) <= config.EPSILON * Math.max(1, Math.abs(a), Math.abs(b)); } return false; } finally { config.EPSILON = oldEpsilon; } } function round(value) { return Math.round(value / config.EPSILON) * config.EPSILON; } function duplicateArray(array) { return array.clone ? array.clone() : new Array(array.length); } function map(value, func, result) { if (isArray(value)) { const array = value; result = result || duplicateArray(array); for (let i = 0; i < result.length && i < array.length; ++i) { const val = typeof value === "number" ? value : value[i]; result[i] = func(val, i, result); } return result; } return func(value); } // ../../node_modules/@math.gl/core/dist/classes/base/math-array.js var MathArray = class extends Array { clone() { return new this.constructor().copy(this); } fromArray(array, offset = 0) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = array[i + offset]; } return this.check(); } toArray(targetArray = [], offset = 0) { for (let i = 0; i < this.ELEMENTS; ++i) { targetArray[offset + i] = this[i]; } return targetArray; } toObject(targetObject) { return targetObject; } from(arrayOrObject) { return Array.isArray(arrayOrObject) ? this.copy(arrayOrObject) : this.fromObject(arrayOrObject); } to(arrayOrObject) { if (arrayOrObject === this) { return this; } return isArray(arrayOrObject) ? this.toArray(arrayOrObject) : this.toObject(arrayOrObject); } toTarget(target) { return target ? this.to(target) : this; } toFloat32Array() { return new Float32Array(this); } toString() { return this.formatString(config); } formatString(opts) { let string = ""; for (let i = 0; i < this.ELEMENTS; ++i) { string += (i > 0 ? ", " : "") + formatValue(this[i], opts); } return `${opts.printTypes ? this.constructor.name : ""}[${string}]`; } equals(array) { if (!array || this.length !== array.length) { return false; } for (let i = 0; i < this.ELEMENTS; ++i) { if (!equals(this[i], array[i])) { return false; } } return true; } exactEquals(array) { if (!array || this.length !== array.length) { return false; } for (let i = 0; i < this.ELEMENTS; ++i) { if (this[i] !== array[i]) { return false; } } return true; } negate() { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = -this[i]; } return this.check(); } lerp(a, b, t) { if (t === void 0) { return this.lerp(this, a, b); } for (let i = 0; i < this.ELEMENTS; ++i) { const ai = a[i]; const endValue = typeof b === "number" ? b : b[i]; this[i] = ai + t * (endValue - ai); } return this.check(); } min(vector) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.min(vector[i], this[i]); } return this.check(); } max(vector) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.max(vector[i], this[i]); } return this.check(); } clamp(minVector, maxVector) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.min(Math.max(this[i], minVector[i]), maxVector[i]); } return this.check(); } add(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] += vector[i]; } } return this.check(); } subtract(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] -= vector[i]; } } return this.check(); } scale(scale5) { if (typeof scale5 === "number") { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= scale5; } } else { for (let i = 0; i < this.ELEMENTS && i < scale5.length; ++i) { this[i] *= scale5[i]; } } return this.check(); } multiplyByScalar(scalar) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= scalar; } return this.check(); } check() { if (config.debug && !this.validate()) { throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`); } return this; } validate() { let valid = this.length === this.ELEMENTS; for (let i = 0; i < this.ELEMENTS; ++i) { valid = valid && Number.isFinite(this[i]); } return valid; } sub(a) { return this.subtract(a); } setScalar(a) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = a; } return this.check(); } addScalar(a) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] += a; } return this.check(); } subScalar(a) { return this.addScalar(-a); } multiplyScalar(scalar) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= scalar; } return this.check(); } divideScalar(a) { return this.multiplyByScalar(1 / a); } clampScalar(min4, max4) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] = Math.min(Math.max(this[i], min4), max4); } return this.check(); } get elements() { return this; } }; // ../../node_modules/@math.gl/core/dist/lib/validators.js function validateVector(v, length4) { if (v.length !== length4) { return false; } for (let i = 0; i < v.length; ++i) { if (!Number.isFinite(v[i])) { return false; } } return true; } function checkNumber(value) { if (!Number.isFinite(value)) { throw new Error(`Invalid number ${JSON.stringify(value)}`); } return value; } function checkVector(v, length4, callerName = "") { if (config.debug && !validateVector(v, length4)) { throw new Error(`math.gl: ${callerName} some fields set to invalid numbers'`); } return v; } // ../../node_modules/@math.gl/core/dist/lib/assert.js function assert4(condition, message2) { if (!condition) { throw new Error(`math.gl assertion ${message2}`); } } // ../../node_modules/@math.gl/core/dist/classes/base/vector.js var Vector = class extends MathArray { get x() { return this[0]; } set x(value) { this[0] = checkNumber(value); } get y() { return this[1]; } set y(value) { this[1] = checkNumber(value); } len() { return Math.sqrt(this.lengthSquared()); } magnitude() { return this.len(); } lengthSquared() { let length4 = 0; for (let i = 0; i < this.ELEMENTS; ++i) { length4 += this[i] * this[i]; } return length4; } magnitudeSquared() { return this.lengthSquared(); } distance(mathArray) { return Math.sqrt(this.distanceSquared(mathArray)); } distanceSquared(mathArray) { let length4 = 0; for (let i = 0; i < this.ELEMENTS; ++i) { const dist4 = this[i] - mathArray[i]; length4 += dist4 * dist4; } return checkNumber(length4); } dot(mathArray) { let product = 0; for (let i = 0; i < this.ELEMENTS; ++i) { product += this[i] * mathArray[i]; } return checkNumber(product); } normalize() { const length4 = this.magnitude(); if (length4 !== 0) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] /= length4; } } return this.check(); } multiply(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] *= vector[i]; } } return this.check(); } divide(...vectors) { for (const vector of vectors) { for (let i = 0; i < this.ELEMENTS; ++i) { this[i] /= vector[i]; } } return this.check(); } lengthSq() { return this.lengthSquared(); } distanceTo(vector) { return this.distance(vector); } distanceToSquared(vector) { return this.distanceSquared(vector); } getComponent(i) { assert4(i >= 0 && i < this.ELEMENTS, "index is out of range"); return checkNumber(this[i]); } setComponent(i, value) { assert4(i >= 0 && i < this.ELEMENTS, "index is out of range"); this[i] = value; return this.check(); } addVectors(a, b) { return this.copy(a).add(b); } subVectors(a, b) { return this.copy(a).subtract(b); } multiplyVectors(a, b) { return this.copy(a).multiply(b); } addScaledVector(a, b) { return this.add(new this.constructor(a).multiplyScalar(b)); } }; // ../../node_modules/@math.gl/core/dist/gl-matrix/vec2.js var vec2_exports = {}; __export(vec2_exports, { add: () => add, angle: () => angle, ceil: () => ceil, clone: () => clone, copy: () => copy, create: () => create, cross: () => cross, dist: () => dist, distance: () => distance, div: () => div, divide: () => divide, dot: () => dot, equals: () => equals2, exactEquals: () => exactEquals, floor: () => floor, forEach: () => forEach, fromValues: () => fromValues, inverse: () => inverse, len: () => len, length: () => length, lerp: () => lerp2, max: () => max, min: () => min, mul: () => mul, multiply: () => multiply, negate: () => negate, normalize: () => normalize, random: () => random, rotate: () => rotate, round: () => round3, scale: () => scale, scaleAndAdd: () => scaleAndAdd, set: () => set, sqrDist: () => sqrDist, sqrLen: () => sqrLen, squaredDistance: () => squaredDistance, squaredLength: () => squaredLength, str: () => str, sub: () => sub, subtract: () => subtract, transformMat2: () => transformMat2, transformMat2d: () => transformMat2d, transformMat3: () => transformMat3, transformMat4: () => transformMat4, zero: () => zero }); // ../../node_modules/@math.gl/core/dist/gl-matrix/common.js var EPSILON = 1e-6; var ARRAY_TYPE = typeof Float32Array !== "undefined" ? Float32Array : Array; var RANDOM = Math.random; function round2(a) { if (a >= 0) return Math.round(a); return a % 0.5 === 0 ? Math.floor(a) : Math.round(a); } var degree = Math.PI / 180; // ../../node_modules/@math.gl/core/dist/gl-matrix/vec2.js function create() { const out = new ARRAY_TYPE(2); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; } return out; } function clone(a) { const out = new ARRAY_TYPE(2); out[0] = a[0]; out[1] = a[1]; return out; } function fromValues(x, y) { const out = new ARRAY_TYPE(2); out[0] = x; out[1] = y; return out; } function copy(out, a) { out[0] = a[0]; out[1] = a[1]; return out; } function set(out, x, y) { out[0] = x; out[1] = y; return out; } function add(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; return out; } function subtract(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; return out; } function multiply(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; return out; } function divide(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; return out; } function ceil(out, a) { out[0] = Math.ceil(a[0]); out[1] = Math.ceil(a[1]); return out; } function floor(out, a) { out[0] = Math.floor(a[0]); out[1] = Math.floor(a[1]); return out; } function min(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); return out; } function max(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); return out; } function round3(out, a) { out[0] = round2(a[0]); out[1] = round2(a[1]); return out; } function scale(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; return out; } function scaleAndAdd(out, a, b, scale5) { out[0] = a[0] + b[0] * scale5; out[1] = a[1] + b[1] * scale5; return out; } function distance(a, b) { const x = b[0] - a[0]; const y = b[1] - a[1]; return Math.sqrt(x * x + y * y); } function squaredDistance(a, b) { const x = b[0] - a[0]; const y = b[1] - a[1]; return x * x + y * y; } function length(a) { const x = a[0]; const y = a[1]; return Math.sqrt(x * x + y * y); } function squaredLength(a) { const x = a[0]; const y = a[1]; return x * x + y * y; } function negate(out, a) { out[0] = -a[0]; out[1] = -a[1]; return out; } function inverse(out, a) { out[0] = 1 / a[0]; out[1] = 1 / a[1]; return out; } function normalize(out, a) { const x = a[0]; const y = a[1]; let len4 = x * x + y * y; if (len4 > 0) { len4 = 1 / Math.sqrt(len4); } out[0] = a[0] * len4; out[1] = a[1] * len4; return out; } function dot(a, b) { return a[0] * b[0] + a[1] * b[1]; } function cross(out, a, b) { const z = a[0] * b[1] - a[1] * b[0]; out[0] = out[1] = 0; out[2] = z; return out; } function lerp2(out, a, b, t) { const ax = a[0]; const ay = a[1]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); return out; } function random(out, scale5) { scale5 = scale5 === void 0 ? 1 : scale5; const r = RANDOM() * 2 * Math.PI; out[0] = Math.cos(r) * scale5; out[1] = Math.sin(r) * scale5; return out; } function transformMat2(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[2] * y; out[1] = m[1] * x + m[3] * y; return out; } function transformMat2d(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[2] * y + m[4]; out[1] = m[1] * x + m[3] * y + m[5]; return out; } function transformMat3(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[3] * y + m[6]; out[1] = m[1] * x + m[4] * y + m[7]; return out; } function transformMat4(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[4] * y + m[12]; out[1] = m[1] * x + m[5] * y + m[13]; return out; } function rotate(out, a, b, rad) { const p0 = a[0] - b[0]; const p1 = a[1] - b[1]; const sinC = Math.sin(rad); const cosC = Math.cos(rad); out[0] = p0 * cosC - p1 * sinC + b[0]; out[1] = p0 * sinC + p1 * cosC + b[1]; return out; } function angle(a, b) { const x1 = a[0]; const y1 = a[1]; const x2 = b[0]; const y2 = b[1]; const mag = Math.sqrt((x1 * x1 + y1 * y1) * (x2 * x2 + y2 * y2)); const cosine = mag && (x1 * x2 + y1 * y2) / mag; return Math.acos(Math.min(Math.max(cosine, -1), 1)); } function zero(out) { out[0] = 0; out[1] = 0; return out; } function str(a) { return `vec2(${a[0]}, ${a[1]})`; } function exactEquals(a, b) { return a[0] === b[0] && a[1] === b[1]; } function equals2(a, b) { const a0 = a[0]; const a1 = a[1]; const b0 = b[0]; const b1 = b[1]; return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)); } var len = length; var sub = subtract; var mul = multiply; var div = divide; var dist = distance; var sqrDist = squaredDistance; var sqrLen = squaredLength; var forEach = function() { const vec = create(); return function(a, stride, offset, count2, fn, arg) { let i; let l; if (!stride) { stride = 2; } if (!offset) { offset = 0; } if (count2) { l = Math.min(count2 * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; } return a; }; }(); // ../../node_modules/@math.gl/core/dist/lib/gl-matrix-extras.js function vec2_transformMat4AsVector(out, a, m) { const x = a[0]; const y = a[1]; const w = m[3] * x + m[7] * y || 1; out[0] = (m[0] * x + m[4] * y) / w; out[1] = (m[1] * x + m[5] * y) / w; return out; } function vec3_transformMat4AsVector(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; const w = m[3] * x + m[7] * y + m[11] * z || 1; out[0] = (m[0] * x + m[4] * y + m[8] * z) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z) / w; return out; } function vec3_transformMat2(out, a, m) { const x = a[0]; const y = a[1]; out[0] = m[0] * x + m[2] * y; out[1] = m[1] * x + m[3] * y; out[2] = a[2]; return out; } // ../../node_modules/@math.gl/core/dist/gl-matrix/vec3.js var vec3_exports = {}; __export(vec3_exports, { add: () => add2, angle: () => angle2, bezier: () => bezier, ceil: () => ceil2, clone: () => clone2, copy: () => copy2, create: () => create2, cross: () => cross2, dist: () => dist2, distance: () => distance2, div: () => div2, divide: () => divide2, dot: () => dot2, equals: () => equals3, exactEquals: () => exactEquals2, floor: () => floor2, forEach: () => forEach2, fromValues: () => fromValues2, hermite: () => hermite, inverse: () => inverse2, len: () => len2, length: () => length2, lerp: () => lerp3, max: () => max2, min: () => min2, mul: () => mul2, multiply: () => multiply2, negate: () => negate2, normalize: () => normalize2, random: () => random2, rotateX: () => rotateX, rotateY: () => rotateY, rotateZ: () => rotateZ, round: () => round4, scale: () => scale2, scaleAndAdd: () => scaleAndAdd2, set: () => set2, slerp: () => slerp, sqrDist: () => sqrDist2, sqrLen: () => sqrLen2, squaredDistance: () => squaredDistance2, squaredLength: () => squaredLength2, str: () => str2, sub: () => sub2, subtract: () => subtract2, transformMat3: () => transformMat32, transformMat4: () => transformMat42, transformQuat: () => transformQuat, zero: () => zero2 }); function create2() { const out = new ARRAY_TYPE(3); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; } return out; } function clone2(a) { const out = new ARRAY_TYPE(3); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } function length2(a) { const x = a[0]; const y = a[1]; const z = a[2]; return Math.sqrt(x * x + y * y + z * z); } function fromValues2(x, y, z) { const out = new ARRAY_TYPE(3); out[0] = x; out[1] = y; out[2] = z; return out; } function copy2(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; return out; } function set2(out, x, y, z) { out[0] = x; out[1] = y; out[2] = z; return out; } function add2(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; return out; } function subtract2(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; return out; } function multiply2(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; return out; } function divide2(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; out[2] = a[2] / b[2]; return out; } function ceil2(out, a) { out[0] = Math.ceil(a[0]); out[1] = Math.ceil(a[1]); out[2] = Math.ceil(a[2]); return out; } function floor2(out, a) { out[0] = Math.floor(a[0]); out[1] = Math.floor(a[1]); out[2] = Math.floor(a[2]); return out; } function min2(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); out[2] = Math.min(a[2], b[2]); return out; } function max2(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); out[2] = Math.max(a[2], b[2]); return out; } function round4(out, a) { out[0] = round2(a[0]); out[1] = round2(a[1]); out[2] = round2(a[2]); return out; } function scale2(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; return out; } function scaleAndAdd2(out, a, b, scale5) { out[0] = a[0] + b[0] * scale5; out[1] = a[1] + b[1] * scale5; out[2] = a[2] + b[2] * scale5; return out; } function distance2(a, b) { const x = b[0] - a[0]; const y = b[1] - a[1]; const z = b[2] - a[2]; return Math.sqrt(x * x + y * y + z * z); } function squaredDistance2(a, b) { const x = b[0] - a[0]; const y = b[1] - a[1]; const z = b[2] - a[2]; return x * x + y * y + z * z; } function squaredLength2(a) { const x = a[0]; const y = a[1]; const z = a[2]; return x * x + y * y + z * z; } function negate2(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; return out; } function inverse2(out, a) { out[0] = 1 / a[0]; out[1] = 1 / a[1]; out[2] = 1 / a[2]; return out; } function normalize2(out, a) { const x = a[0]; const y = a[1]; const z = a[2]; let len4 = x * x + y * y + z * z; if (len4 > 0) { len4 = 1 / Math.sqrt(len4); } out[0] = a[0] * len4; out[1] = a[1] * len4; out[2] = a[2] * len4; return out; } function dot2(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } function cross2(out, a, b) { const ax = a[0]; const ay = a[1]; const az = a[2]; const bx = b[0]; const by = b[1]; const bz = b[2]; out[0] = ay * bz - az * by; out[1] = az * bx - ax * bz; out[2] = ax * by - ay * bx; return out; } function lerp3(out, a, b, t) { const ax = a[0]; const ay = a[1]; const az = a[2]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); return out; } function slerp(out, a, b, t) { const angle3 = Math.acos(Math.min(Math.max(dot2(a, b), -1), 1)); const sinTotal = Math.sin(angle3); const ratioA = Math.sin((1 - t) * angle3) / sinTotal; const ratioB = Math.sin(t * angle3) / sinTotal; out[0] = ratioA * a[0] + ratioB * b[0]; out[1] = ratioA * a[1] + ratioB * b[1]; out[2] = ratioA * a[2] + ratioB * b[2]; return out; } function hermite(out, a, b, c, d, t) { const factorTimes2 = t * t; const factor1 = factorTimes2 * (2 * t - 3) + 1; const factor2 = factorTimes2 * (t - 2) + t; const factor3 = factorTimes2 * (t - 1); const factor4 = factorTimes2 * (3 - 2 * t); out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; return out; } function bezier(out, a, b, c, d, t) { const inverseFactor = 1 - t; const inverseFactorTimesTwo = inverseFactor * inverseFactor; const factorTimes2 = t * t; const factor1 = inverseFactorTimesTwo * inverseFactor; const factor2 = 3 * t * inverseFactorTimesTwo; const factor3 = 3 * factorTimes2 * inverseFactor; const factor4 = factorTimes2 * t; out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4; out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4; out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4; return out; } function random2(out, scale5) { scale5 = scale5 === void 0 ? 1 : scale5; const r = RANDOM() * 2 * Math.PI; const z = RANDOM() * 2 - 1; const zScale = Math.sqrt(1 - z * z) * scale5; out[0] = Math.cos(r) * zScale; out[1] = Math.sin(r) * zScale; out[2] = z * scale5; return out; } function transformMat42(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; let w = m[3] * x + m[7] * y + m[11] * z + m[15]; w = w || 1; out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w; out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w; out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w; return out; } function transformMat32(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; out[0] = x * m[0] + y * m[3] + z * m[6]; out[1] = x * m[1] + y * m[4] + z * m[7]; out[2] = x * m[2] + y * m[5] + z * m[8]; return out; } function transformQuat(out, a, q) { const qx = q[0]; const qy = q[1]; const qz = q[2]; const qw = q[3]; const x = a[0]; const y = a[1]; const z = a[2]; let uvx = qy * z - qz * y; let uvy = qz * x - qx * z; let uvz = qx * y - qy * x; let uuvx = qy * uvz - qz * uvy; let uuvy = qz * uvx - qx * uvz; let uuvz = qx * uvy - qy * uvx; const w2 = qw * 2; uvx *= w2; uvy *= w2; uvz *= w2; uuvx *= 2; uuvy *= 2; uuvz *= 2; out[0] = x + uvx + uuvx; out[1] = y + uvy + uuvy; out[2] = z + uvz + uuvz; return out; } function rotateX(out, a, b, rad) { const p = []; const r = []; p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; r[0] = p[0]; r[1] = p[1] * Math.cos(rad) - p[2] * Math.sin(rad); r[2] = p[1] * Math.sin(rad) + p[2] * Math.cos(rad); out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } function rotateY(out, a, b, rad) { const p = []; const r = []; p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; r[0] = p[2] * Math.sin(rad) + p[0] * Math.cos(rad); r[1] = p[1]; r[2] = p[2] * Math.cos(rad) - p[0] * Math.sin(rad); out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } function rotateZ(out, a, b, rad) { const p = []; const r = []; p[0] = a[0] - b[0]; p[1] = a[1] - b[1]; p[2] = a[2] - b[2]; r[0] = p[0] * Math.cos(rad) - p[1] * Math.sin(rad); r[1] = p[0] * Math.sin(rad) + p[1] * Math.cos(rad); r[2] = p[2]; out[0] = r[0] + b[0]; out[1] = r[1] + b[1]; out[2] = r[2] + b[2]; return out; } function angle2(a, b) { const ax = a[0]; const ay = a[1]; const az = a[2]; const bx = b[0]; const by = b[1]; const bz = b[2]; const mag = Math.sqrt((ax * ax + ay * ay + az * az) * (bx * bx + by * by + bz * bz)); const cosine = mag && dot2(a, b) / mag; return Math.acos(Math.min(Math.max(cosine, -1), 1)); } function zero2(out) { out[0] = 0; out[1] = 0; out[2] = 0; return out; } function str2(a) { return `vec3(${a[0]}, ${a[1]}, ${a[2]})`; } function exactEquals2(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2]; } function equals3(a, b) { const a0 = a[0]; const a1 = a[1]; const a2 = a[2]; const b0 = b[0]; const b1 = b[1]; const b2 = b[2]; return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)); } var sub2 = subtract2; var mul2 = multiply2; var div2 = divide2; var dist2 = distance2; var sqrDist2 = squaredDistance2; var len2 = length2; var sqrLen2 = squaredLength2; var forEach2 = function() { const vec = create2(); return function(a, stride, offset, count2, fn, arg) { let i; let l; if (!stride) { stride = 3; } if (!offset) { offset = 0; } if (count2) { l = Math.min(count2 * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; } return a; }; }(); // ../../node_modules/@math.gl/core/dist/classes/vector3.js var ORIGIN = [0, 0, 0]; var ZERO; var Vector3 = class extends Vector { static get ZERO() { if (!ZERO) { ZERO = new Vector3(0, 0, 0); Object.freeze(ZERO); } return ZERO; } constructor(x = 0, y = 0, z = 0) { super(-0, -0, -0); if (arguments.length === 1 && isArray(x)) { this.copy(x); } else { if (config.debug) { checkNumber(x); checkNumber(y); checkNumber(z); } this[0] = x; this[1] = y; this[2] = z; } } set(x, y, z) { this[0] = x; this[1] = y; this[2] = z; return this.check(); } copy(array) { this[0] = array[0]; this[1] = array[1]; this[2] = array[2]; return this.check(); } fromObject(object) { if (config.debug) { checkNumber(object.x); checkNumber(object.y); checkNumber(object.z); } this[0] = object.x; this[1] = object.y; this[2] = object.z; return this.check(); } toObject(object) { object.x = this[0]; object.y = this[1]; object.z = this[2]; return object; } get ELEMENTS() { return 3; } get z() { return this[2]; } set z(value) { this[2] = checkNumber(value); } angle(vector) { return angle2(this, vector); } cross(vector) { cross2(this, this, vector); return this.check(); } rotateX({ radians: radians2, origin = ORIGIN }) { rotateX(this, this, origin, radians2); return this.check(); } rotateY({ radians: radians2, origin = ORIGIN }) { rotateY(this, this, origin, radians2); return this.check(); } rotateZ({ radians: radians2, origin = ORIGIN }) { rotateZ(this, this, origin, radians2); return this.check(); } transform(matrix4) { return this.transformAsPoint(matrix4); } transformAsPoint(matrix4) { transformMat42(this, this, matrix4); return this.check(); } transformAsVector(matrix4) { vec3_transformMat4AsVector(this, this, matrix4); return this.check(); } transformByMatrix3(matrix3) { transformMat32(this, this, matrix3); return this.check(); } transformByMatrix2(matrix2) { vec3_transformMat2(this, this, matrix2); return this.check(); } transformByQuaternion(quaternion) { transformQuat(this, this, quaternion); return this.check(); } }; // ../../node_modules/@math.gl/core/dist/classes/base/matrix.js var Matrix = class extends MathArray { toString() { let string = "["; if (config.printRowMajor) { string += "row-major:"; for (let row = 0; row < this.RANK; ++row) { for (let col = 0; col < this.RANK; ++col) { string += ` ${this[col * this.RANK + row]}`; } } } else { string += "column-major:"; for (let i = 0; i < this.ELEMENTS; ++i) { string += ` ${this[i]}`; } } string += "]"; return string; } getElementIndex(row, col) { return col * this.RANK + row; } getElement(row, col) { return this[col * this.RANK + row]; } setElement(row, col, value) { this[col * this.RANK + row] = checkNumber(value); return this; } getColumn(columnIndex, result = new Array(this.RANK).fill(-0)) { const firstIndex = columnIndex * this.RANK; for (let i = 0; i < this.RANK; ++i) { result[i] = this[firstIndex + i]; } return result; } setColumn(columnIndex, columnVector) { const firstIndex = columnIndex * this.RANK; for (let i = 0; i < this.RANK; ++i) { this[firstIndex + i] = columnVector[i]; } return this; } }; // ../../node_modules/@math.gl/core/dist/gl-matrix/mat4.js var mat4_exports = {}; __export(mat4_exports, { add: () => add3, adjoint: () => adjoint, clone: () => clone3, copy: () => copy3, create: () => create3, decompose: () => decompose, determinant: () => determinant, equals: () => equals4, exactEquals: () => exactEquals3, frob: () => frob, fromQuat: () => fromQuat, fromQuat2: () => fromQuat2, fromRotation: () => fromRotation, fromRotationTranslation: () => fromRotationTranslation, fromRotationTranslationScale: () => fromRotationTranslationScale, fromRotationTranslationScaleOrigin: () => fromRotationTranslationScaleOrigin, fromScaling: () => fromScaling, fromTranslation: () => fromTranslation, fromValues: () => fromValues3, fromXRotation: () => fromXRotation, fromYRotation: () => fromYRotation, fromZRotation: () => fromZRotation, frustum: () => frustum, getRotation: () => getRotation, getScaling: () => getScaling, getTranslation: () => getTranslation, identity: () => identity, invert: () => invert, lookAt: () => lookAt, mul: () => mul3, multiply: () => multiply3, multiplyScalar: () => multiplyScalar, multiplyScalarAndAdd: () => multiplyScalarAndAdd, ortho: () => ortho, orthoNO: () => orthoNO, orthoZO: () => orthoZO, perspective: () => perspective, perspectiveFromFieldOfView: () => perspectiveFromFieldOfView, perspectiveNO: () => perspectiveNO, perspectiveZO: () => perspectiveZO, rotate: () => rotate2, rotateX: () => rotateX2, rotateY: () => rotateY2, rotateZ: () => rotateZ2, scale: () => scale3, set: () => set3, str: () => str3, sub: () => sub3, subtract: () => subtract3, targetTo: () => targetTo, translate: () => translate, transpose: () => transpose }); function create3() { const out = new ARRAY_TYPE(16); if (ARRAY_TYPE != Float32Array) { out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; } out[0] = 1; out[5] = 1; out[10] = 1; out[15] = 1; return out; } function clone3(a) { const out = new ARRAY_TYPE(16); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } function copy3(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } function fromValues3(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { const out = new ARRAY_TYPE(16); out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m03; out[4] = m10; out[5] = m11; out[6] = m12; out[7] = m13; out[8] = m20; out[9] = m21; out[10] = m22; out[11] = m23; out[12] = m30; out[13] = m31; out[14] = m32; out[15] = m33; return out; } function set3(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { out[0] = m00; out[1] = m01; out[2] = m02; out[3] = m03; out[4] = m10; out[5] = m11; out[6] = m12; out[7] = m13; out[8] = m20; out[9] = m21; out[10] = m22; out[11] = m23; out[12] = m30; out[13] = m31; out[14] = m32; out[15] = m33; return out; } function identity(out) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function transpose(out, a) { if (out === a) { const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a12 = a[6]; const a13 = a[7]; const a23 = a[11]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a01; out[6] = a[9]; out[7] = a[13]; out[8] = a02; out[9] = a12; out[11] = a[14]; out[12] = a03; out[13] = a13; out[14] = a23; } else { out[0] = a[0]; out[1] = a[4]; out[2] = a[8]; out[3] = a[12]; out[4] = a[1]; out[5] = a[5]; out[6] = a[9]; out[7] = a[13]; out[8] = a[2]; out[9] = a[6]; out[10] = a[10]; out[11] = a[14]; out[12] = a[3]; out[13] = a[7]; out[14] = a[11]; out[15] = a[15]; } return out; } function invert(out, a) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a10 = a[4]; const a11 = a[5]; const a12 = a[6]; const a13 = a[7]; const a20 = a[8]; const a21 = a[9]; const a22 = a[10]; const a23 = a[11]; const a30 = a[12]; const a31 = a[13]; const a32 = a[14]; const a33 = a[15]; const b00 = a00 * a11 - a01 * a10; const b01 = a00 * a12 - a02 * a10; const b02 = a00 * a13 - a03 * a10; const b03 = a01 * a12 - a02 * a11; const b04 = a01 * a13 - a03 * a11; const b05 = a02 * a13 - a03 * a12; const b06 = a20 * a31 - a21 * a30; const b07 = a20 * a32 - a22 * a30; const b08 = a20 * a33 - a23 * a30; const b09 = a21 * a32 - a22 * a31; const b10 = a21 * a33 - a23 * a31; const b11 = a22 * a33 - a23 * a32; let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06; if (!det) { return null; } det = 1 / det; out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det; out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det; out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det; out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det; out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det; out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det; out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det; out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det; out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det; out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det; out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det; out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det; out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det; out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det; out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det; out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det; return out; } function adjoint(out, a) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a10 = a[4]; const a11 = a[5]; const a12 = a[6]; const a13 = a[7]; const a20 = a[8]; const a21 = a[9]; const a22 = a[10]; const a23 = a[11]; const a30 = a[12]; const a31 = a[13]; const a32 = a[14]; const a33 = a[15]; const b00 = a00 * a11 - a01 * a10; const b01 = a00 * a12 - a02 * a10; const b02 = a00 * a13 - a03 * a10; const b03 = a01 * a12 - a02 * a11; const b04 = a01 * a13 - a03 * a11; const b05 = a02 * a13 - a03 * a12; const b06 = a20 * a31 - a21 * a30; const b07 = a20 * a32 - a22 * a30; const b08 = a20 * a33 - a23 * a30; const b09 = a21 * a32 - a22 * a31; const b10 = a21 * a33 - a23 * a31; const b11 = a22 * a33 - a23 * a32; out[0] = a11 * b11 - a12 * b10 + a13 * b09; out[1] = a02 * b10 - a01 * b11 - a03 * b09; out[2] = a31 * b05 - a32 * b04 + a33 * b03; out[3] = a22 * b04 - a21 * b05 - a23 * b03; out[4] = a12 * b08 - a10 * b11 - a13 * b07; out[5] = a00 * b11 - a02 * b08 + a03 * b07; out[6] = a32 * b02 - a30 * b05 - a33 * b01; out[7] = a20 * b05 - a22 * b02 + a23 * b01; out[8] = a10 * b10 - a11 * b08 + a13 * b06; out[9] = a01 * b08 - a00 * b10 - a03 * b06; out[10] = a30 * b04 - a31 * b02 + a33 * b00; out[11] = a21 * b02 - a20 * b04 - a23 * b00; out[12] = a11 * b07 - a10 * b09 - a12 * b06; out[13] = a00 * b09 - a01 * b07 + a02 * b06; out[14] = a31 * b01 - a30 * b03 - a32 * b00; out[15] = a20 * b03 - a21 * b01 + a22 * b00; return out; } function determinant(a) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a10 = a[4]; const a11 = a[5]; const a12 = a[6]; const a13 = a[7]; const a20 = a[8]; const a21 = a[9]; const a22 = a[10]; const a23 = a[11]; const a30 = a[12]; const a31 = a[13]; const a32 = a[14]; const a33 = a[15]; const b0 = a00 * a11 - a01 * a10; const b1 = a00 * a12 - a02 * a10; const b2 = a01 * a12 - a02 * a11; const b3 = a20 * a31 - a21 * a30; const b4 = a20 * a32 - a22 * a30; const b5 = a21 * a32 - a22 * a31; const b6 = a00 * b5 - a01 * b4 + a02 * b3; const b7 = a10 * b5 - a11 * b4 + a12 * b3; const b8 = a20 * b2 - a21 * b1 + a22 * b0; const b9 = a30 * b2 - a31 * b1 + a32 * b0; return a13 * b6 - a03 * b7 + a33 * b8 - a23 * b9; } function multiply3(out, a, b) { const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a10 = a[4]; const a11 = a[5]; const a12 = a[6]; const a13 = a[7]; const a20 = a[8]; const a21 = a[9]; const a22 = a[10]; const a23 = a[11]; const a30 = a[12]; const a31 = a[13]; const a32 = a[14]; const a33 = a[15]; let b0 = b[0]; let b1 = b[1]; let b2 = b[2]; let b3 = b[3]; out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b[7]; out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[8]; b1 = b[9]; b2 = b[10]; b3 = b[11]; out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; b0 = b[12]; b1 = b[13]; b2 = b[14]; b3 = b[15]; out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30; out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31; out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32; out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33; return out; } function translate(out, a, v) { const x = v[0]; const y = v[1]; const z = v[2]; let a00; let a01; let a02; let a03; let a10; let a11; let a12; let a13; let a20; let a21; let a22; let a23; if (a === out) { out[12] = a[0] * x + a[4] * y + a[8] * z + a[12]; out[13] = a[1] * x + a[5] * y + a[9] * z + a[13]; out[14] = a[2] * x + a[6] * y + a[10] * z + a[14]; out[15] = a[3] * x + a[7] * y + a[11] * z + a[15]; } else { a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03; out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13; out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23; out[12] = a00 * x + a10 * y + a20 * z + a[12]; out[13] = a01 * x + a11 * y + a21 * z + a[13]; out[14] = a02 * x + a12 * y + a22 * z + a[14]; out[15] = a03 * x + a13 * y + a23 * z + a[15]; } return out; } function scale3(out, a, v) { const x = v[0]; const y = v[1]; const z = v[2]; out[0] = a[0] * x; out[1] = a[1] * x; out[2] = a[2] * x; out[3] = a[3] * x; out[4] = a[4] * y; out[5] = a[5] * y; out[6] = a[6] * y; out[7] = a[7] * y; out[8] = a[8] * z; out[9] = a[9] * z; out[10] = a[10] * z; out[11] = a[11] * z; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; return out; } function rotate2(out, a, rad, axis) { let x = axis[0]; let y = axis[1]; let z = axis[2]; let len4 = Math.sqrt(x * x + y * y + z * z); let c; let s; let t; let a00; let a01; let a02; let a03; let a10; let a11; let a12; let a13; let a20; let a21; let a22; let a23; let b00; let b01; let b02; let b10; let b11; let b12; let b20; let b21; let b22; if (len4 < EPSILON) { return null; } len4 = 1 / len4; x *= len4; y *= len4; z *= len4; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; out[0] = a00 * b00 + a10 * b01 + a20 * b02; out[1] = a01 * b00 + a11 * b01 + a21 * b02; out[2] = a02 * b00 + a12 * b01 + a22 * b02; out[3] = a03 * b00 + a13 * b01 + a23 * b02; out[4] = a00 * b10 + a10 * b11 + a20 * b12; out[5] = a01 * b10 + a11 * b11 + a21 * b12; out[6] = a02 * b10 + a12 * b11 + a22 * b12; out[7] = a03 * b10 + a13 * b11 + a23 * b12; out[8] = a00 * b20 + a10 * b21 + a20 * b22; out[9] = a01 * b20 + a11 * b21 + a21 * b22; out[10] = a02 * b20 + a12 * b21 + a22 * b22; out[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a !== out) { out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } return out; } function rotateX2(out, a, rad) { const s = Math.sin(rad); const c = Math.cos(rad); const a10 = a[4]; const a11 = a[5]; const a12 = a[6]; const a13 = a[7]; const a20 = a[8]; const a21 = a[9]; const a22 = a[10]; const a23 = a[11]; if (a !== out) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } out[4] = a10 * c + a20 * s; out[5] = a11 * c + a21 * s; out[6] = a12 * c + a22 * s; out[7] = a13 * c + a23 * s; out[8] = a20 * c - a10 * s; out[9] = a21 * c - a11 * s; out[10] = a22 * c - a12 * s; out[11] = a23 * c - a13 * s; return out; } function rotateY2(out, a, rad) { const s = Math.sin(rad); const c = Math.cos(rad); const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a20 = a[8]; const a21 = a[9]; const a22 = a[10]; const a23 = a[11]; if (a !== out) { out[4] = a[4]; out[5] = a[5]; out[6] = a[6]; out[7] = a[7]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } out[0] = a00 * c - a20 * s; out[1] = a01 * c - a21 * s; out[2] = a02 * c - a22 * s; out[3] = a03 * c - a23 * s; out[8] = a00 * s + a20 * c; out[9] = a01 * s + a21 * c; out[10] = a02 * s + a22 * c; out[11] = a03 * s + a23 * c; return out; } function rotateZ2(out, a, rad) { const s = Math.sin(rad); const c = Math.cos(rad); const a00 = a[0]; const a01 = a[1]; const a02 = a[2]; const a03 = a[3]; const a10 = a[4]; const a11 = a[5]; const a12 = a[6]; const a13 = a[7]; if (a !== out) { out[8] = a[8]; out[9] = a[9]; out[10] = a[10]; out[11] = a[11]; out[12] = a[12]; out[13] = a[13]; out[14] = a[14]; out[15] = a[15]; } out[0] = a00 * c + a10 * s; out[1] = a01 * c + a11 * s; out[2] = a02 * c + a12 * s; out[3] = a03 * c + a13 * s; out[4] = a10 * c - a00 * s; out[5] = a11 * c - a01 * s; out[6] = a12 * c - a02 * s; out[7] = a13 * c - a03 * s; return out; } function fromTranslation(out, v) { out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } function fromScaling(out, v) { out[0] = v[0]; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = v[1]; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = v[2]; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function fromRotation(out, rad, axis) { let x = axis[0]; let y = axis[1]; let z = axis[2]; let len4 = Math.sqrt(x * x + y * y + z * z); let c; let s; let t; if (len4 < EPSILON) { return null; } len4 = 1 / len4; x *= len4; y *= len4; z *= len4; s = Math.sin(rad); c = Math.cos(rad); t = 1 - c; out[0] = x * x * t + c; out[1] = y * x * t + z * s; out[2] = z * x * t - y * s; out[3] = 0; out[4] = x * y * t - z * s; out[5] = y * y * t + c; out[6] = z * y * t + x * s; out[7] = 0; out[8] = x * z * t + y * s; out[9] = y * z * t - x * s; out[10] = z * z * t + c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function fromXRotation(out, rad) { const s = Math.sin(rad); const c = Math.cos(rad); out[0] = 1; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = c; out[6] = s; out[7] = 0; out[8] = 0; out[9] = -s; out[10] = c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function fromYRotation(out, rad) { const s = Math.sin(rad); const c = Math.cos(rad); out[0] = c; out[1] = 0; out[2] = -s; out[3] = 0; out[4] = 0; out[5] = 1; out[6] = 0; out[7] = 0; out[8] = s; out[9] = 0; out[10] = c; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function fromZRotation(out, rad) { const s = Math.sin(rad); const c = Math.cos(rad); out[0] = c; out[1] = s; out[2] = 0; out[3] = 0; out[4] = -s; out[5] = c; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 1; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function fromRotationTranslation(out, q, v) { const x = q[0]; const y = q[1]; const z = q[2]; const w = q[3]; const x2 = x + x; const y2 = y + y; const z2 = z + z; const xx = x * x2; const xy = x * y2; const xz = x * z2; const yy = y * y2; const yz = y * z2; const zz = z * z2; const wx = w * x2; const wy = w * y2; const wz = w * z2; out[0] = 1 - (yy + zz); out[1] = xy + wz; out[2] = xz - wy; out[3] = 0; out[4] = xy - wz; out[5] = 1 - (xx + zz); out[6] = yz + wx; out[7] = 0; out[8] = xz + wy; out[9] = yz - wx; out[10] = 1 - (xx + yy); out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } function fromQuat2(out, a) { const translation = new ARRAY_TYPE(3); const bx = -a[0]; const by = -a[1]; const bz = -a[2]; const bw = a[3]; const ax = a[4]; const ay = a[5]; const az = a[6]; const aw = a[7]; const magnitude = bx * bx + by * by + bz * bz + bw * bw; if (magnitude > 0) { translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude; translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude; translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude; } else { translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2; translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2; translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2; } fromRotationTranslation(out, a, translation); return out; } function getTranslation(out, mat) { out[0] = mat[12]; out[1] = mat[13]; out[2] = mat[14]; return out; } function getScaling(out, mat) { const m11 = mat[0]; const m12 = mat[1]; const m13 = mat[2]; const m21 = mat[4]; const m22 = mat[5]; const m23 = mat[6]; const m31 = mat[8]; const m32 = mat[9]; const m33 = mat[10]; out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13); out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23); out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33); return out; } function getRotation(out, mat) { const scaling = new ARRAY_TYPE(3); getScaling(scaling, mat); const is1 = 1 / scaling[0]; const is2 = 1 / scaling[1]; const is3 = 1 / scaling[2]; const sm11 = mat[0] * is1; const sm12 = mat[1] * is2; const sm13 = mat[2] * is3; const sm21 = mat[4] * is1; const sm22 = mat[5] * is2; const sm23 = mat[6] * is3; const sm31 = mat[8] * is1; const sm32 = mat[9] * is2; const sm33 = mat[10] * is3; const trace = sm11 + sm22 + sm33; let S = 0; if (trace > 0) { S = Math.sqrt(trace + 1) * 2; out[3] = 0.25 * S; out[0] = (sm23 - sm32) / S; out[1] = (sm31 - sm13) / S; out[2] = (sm12 - sm21) / S; } else if (sm11 > sm22 && sm11 > sm33) { S = Math.sqrt(1 + sm11 - sm22 - sm33) * 2; out[3] = (sm23 - sm32) / S; out[0] = 0.25 * S; out[1] = (sm12 + sm21) / S; out[2] = (sm31 + sm13) / S; } else if (sm22 > sm33) { S = Math.sqrt(1 + sm22 - sm11 - sm33) * 2; out[3] = (sm31 - sm13) / S; out[0] = (sm12 + sm21) / S; out[1] = 0.25 * S; out[2] = (sm23 + sm32) / S; } else { S = Math.sqrt(1 + sm33 - sm11 - sm22) * 2; out[3] = (sm12 - sm21) / S; out[0] = (sm31 + sm13) / S; out[1] = (sm23 + sm32) / S; out[2] = 0.25 * S; } return out; } function decompose(out_r, out_t, out_s, mat) { out_t[0] = mat[12]; out_t[1] = mat[13]; out_t[2] = mat[14]; const m11 = mat[0]; const m12 = mat[1]; const m13 = mat[2]; const m21 = mat[4]; const m22 = mat[5]; const m23 = mat[6]; const m31 = mat[8]; const m32 = mat[9]; const m33 = mat[10]; out_s[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13); out_s[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23); out_s[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33); const is1 = 1 / out_s[0]; const is2 = 1 / out_s[1]; const is3 = 1 / out_s[2]; const sm11 = m11 * is1; const sm12 = m12 * is2; const sm13 = m13 * is3; const sm21 = m21 * is1; const sm22 = m22 * is2; const sm23 = m23 * is3; const sm31 = m31 * is1; const sm32 = m32 * is2; const sm33 = m33 * is3; const trace = sm11 + sm22 + sm33; let S = 0; if (trace > 0) { S = Math.sqrt(trace + 1) * 2; out_r[3] = 0.25 * S; out_r[0] = (sm23 - sm32) / S; out_r[1] = (sm31 - sm13) / S; out_r[2] = (sm12 - sm21) / S; } else if (sm11 > sm22 && sm11 > sm33) { S = Math.sqrt(1 + sm11 - sm22 - sm33) * 2; out_r[3] = (sm23 - sm32) / S; out_r[0] = 0.25 * S; out_r[1] = (sm12 + sm21) / S; out_r[2] = (sm31 + sm13) / S; } else if (sm22 > sm33) { S = Math.sqrt(1 + sm22 - sm11 - sm33) * 2; out_r[3] = (sm31 - sm13) / S; out_r[0] = (sm12 + sm21) / S; out_r[1] = 0.25 * S; out_r[2] = (sm23 + sm32) / S; } else { S = Math.sqrt(1 + sm33 - sm11 - sm22) * 2; out_r[3] = (sm12 - sm21) / S; out_r[0] = (sm31 + sm13) / S; out_r[1] = (sm23 + sm32) / S; out_r[2] = 0.25 * S; } return out_r; } function fromRotationTranslationScale(out, q, v, s) { const x = q[0]; const y = q[1]; const z = q[2]; const w = q[3]; const x2 = x + x; const y2 = y + y; const z2 = z + z; const xx = x * x2; const xy = x * y2; const xz = x * z2; const yy = y * y2; const yz = y * z2; const zz = z * z2; const wx = w * x2; const wy = w * y2; const wz = w * z2; const sx = s[0]; const sy = s[1]; const sz = s[2]; out[0] = (1 - (yy + zz)) * sx; out[1] = (xy + wz) * sx; out[2] = (xz - wy) * sx; out[3] = 0; out[4] = (xy - wz) * sy; out[5] = (1 - (xx + zz)) * sy; out[6] = (yz + wx) * sy; out[7] = 0; out[8] = (xz + wy) * sz; out[9] = (yz - wx) * sz; out[10] = (1 - (xx + yy)) * sz; out[11] = 0; out[12] = v[0]; out[13] = v[1]; out[14] = v[2]; out[15] = 1; return out; } function fromRotationTranslationScaleOrigin(out, q, v, s, o) { const x = q[0]; const y = q[1]; const z = q[2]; const w = q[3]; const x2 = x + x; const y2 = y + y; const z2 = z + z; const xx = x * x2; const xy = x * y2; const xz = x * z2; const yy = y * y2; const yz = y * z2; const zz = z * z2; const wx = w * x2; const wy = w * y2; const wz = w * z2; const sx = s[0]; const sy = s[1]; const sz = s[2]; const ox = o[0]; const oy = o[1]; const oz = o[2]; const out0 = (1 - (yy + zz)) * sx; const out1 = (xy + wz) * sx; const out2 = (xz - wy) * sx; const out4 = (xy - wz) * sy; const out5 = (1 - (xx + zz)) * sy; const out6 = (yz + wx) * sy; const out8 = (xz + wy) * sz; const out9 = (yz - wx) * sz; const out10 = (1 - (xx + yy)) * sz; out[0] = out0; out[1] = out1; out[2] = out2; out[3] = 0; out[4] = out4; out[5] = out5; out[6] = out6; out[7] = 0; out[8] = out8; out[9] = out9; out[10] = out10; out[11] = 0; out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz); out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz); out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz); out[15] = 1; return out; } function fromQuat(out, q) { const x = q[0]; const y = q[1]; const z = q[2]; const w = q[3]; const x2 = x + x; const y2 = y + y; const z2 = z + z; const xx = x * x2; const yx = y * x2; const yy = y * y2; const zx = z * x2; const zy = z * y2; const zz = z * z2; const wx = w * x2; const wy = w * y2; const wz = w * z2; out[0] = 1 - yy - zz; out[1] = yx + wz; out[2] = zx - wy; out[3] = 0; out[4] = yx - wz; out[5] = 1 - xx - zz; out[6] = zy + wx; out[7] = 0; out[8] = zx + wy; out[9] = zy - wx; out[10] = 1 - xx - yy; out[11] = 0; out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; return out; } function frustum(out, left, right, bottom, top, near, far) { const rl = 1 / (right - left); const tb = 1 / (top - bottom); const nf = 1 / (near - far); out[0] = near * 2 * rl; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = near * 2 * tb; out[6] = 0; out[7] = 0; out[8] = (right + left) * rl; out[9] = (top + bottom) * tb; out[10] = (far + near) * nf; out[11] = -1; out[12] = 0; out[13] = 0; out[14] = far * near * 2 * nf; out[15] = 0; return out; } function perspectiveNO(out, fovy, aspect, near, far) { const f = 1 / Math.tan(fovy / 2); out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { const nf = 1 / (near - far); out[10] = (far + near) * nf; out[14] = 2 * far * near * nf; } else { out[10] = -1; out[14] = -2 * near; } return out; } var perspective = perspectiveNO; function perspectiveZO(out, fovy, aspect, near, far) { const f = 1 / Math.tan(fovy / 2); out[0] = f / aspect; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = f; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[11] = -1; out[12] = 0; out[13] = 0; out[15] = 0; if (far != null && far !== Infinity) { const nf = 1 / (near - far); out[10] = far * nf; out[14] = far * near * nf; } else { out[10] = -1; out[14] = -near; } return out; } function perspectiveFromFieldOfView(out, fov, near, far) { const upTan = Math.tan(fov.upDegrees * Math.PI / 180); const downTan = Math.tan(fov.downDegrees * Math.PI / 180); const leftTan = Math.tan(fov.leftDegrees * Math.PI / 180); const rightTan = Math.tan(fov.rightDegrees * Math.PI / 180); const xScale = 2 / (leftTan + rightTan); const yScale = 2 / (upTan + downTan); out[0] = xScale; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = yScale; out[6] = 0; out[7] = 0; out[8] = -((leftTan - rightTan) * xScale * 0.5); out[9] = (upTan - downTan) * yScale * 0.5; out[10] = far / (near - far); out[11] = -1; out[12] = 0; out[13] = 0; out[14] = far * near / (near - far); out[15] = 0; return out; } function orthoNO(out, left, right, bottom, top, near, far) { const lr = 1 / (left - right); const bt = 1 / (bottom - top); const nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = 2 * nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = (far + near) * nf; out[15] = 1; return out; } var ortho = orthoNO; function orthoZO(out, left, right, bottom, top, near, far) { const lr = 1 / (left - right); const bt = 1 / (bottom - top); const nf = 1 / (near - far); out[0] = -2 * lr; out[1] = 0; out[2] = 0; out[3] = 0; out[4] = 0; out[5] = -2 * bt; out[6] = 0; out[7] = 0; out[8] = 0; out[9] = 0; out[10] = nf; out[11] = 0; out[12] = (left + right) * lr; out[13] = (top + bottom) * bt; out[14] = near * nf; out[15] = 1; return out; } function lookAt(out, eye, center, up) { let len4; let x0; let x1; let x2; let y0; let y1; let y2; let z0; let z1; let z2; const eyex = eye[0]; const eyey = eye[1]; const eyez = eye[2]; const upx = up[0]; const upy = up[1]; const upz = up[2]; const centerx = center[0]; const centery = center[1]; const centerz = center[2]; if (Math.abs(eyex - centerx) < EPSILON && Math.abs(eyey - centery) < EPSILON && Math.abs(eyez - centerz) < EPSILON) { return identity(out); } z0 = eyex - centerx; z1 = eyey - centery; z2 = eyez - centerz; len4 = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2); z0 *= len4; z1 *= len4; z2 *= len4; x0 = upy * z2 - upz * z1; x1 = upz * z0 - upx * z2; x2 = upx * z1 - upy * z0; len4 = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2); if (!len4) { x0 = 0; x1 = 0; x2 = 0; } else { len4 = 1 / len4; x0 *= len4; x1 *= len4; x2 *= len4; } y0 = z1 * x2 - z2 * x1; y1 = z2 * x0 - z0 * x2; y2 = z0 * x1 - z1 * x0; len4 = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2); if (!len4) { y0 = 0; y1 = 0; y2 = 0; } else { len4 = 1 / len4; y0 *= len4; y1 *= len4; y2 *= len4; } out[0] = x0; out[1] = y0; out[2] = z0; out[3] = 0; out[4] = x1; out[5] = y1; out[6] = z1; out[7] = 0; out[8] = x2; out[9] = y2; out[10] = z2; out[11] = 0; out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); out[15] = 1; return out; } function targetTo(out, eye, target, up) { const eyex = eye[0]; const eyey = eye[1]; const eyez = eye[2]; const upx = up[0]; const upy = up[1]; const upz = up[2]; let z0 = eyex - target[0]; let z1 = eyey - target[1]; let z2 = eyez - target[2]; let len4 = z0 * z0 + z1 * z1 + z2 * z2; if (len4 > 0) { len4 = 1 / Math.sqrt(len4); z0 *= len4; z1 *= len4; z2 *= len4; } let x0 = upy * z2 - upz * z1; let x1 = upz * z0 - upx * z2; let x2 = upx * z1 - upy * z0; len4 = x0 * x0 + x1 * x1 + x2 * x2; if (len4 > 0) { len4 = 1 / Math.sqrt(len4); x0 *= len4; x1 *= len4; x2 *= len4; } out[0] = x0; out[1] = x1; out[2] = x2; out[3] = 0; out[4] = z1 * x2 - z2 * x1; out[5] = z2 * x0 - z0 * x2; out[6] = z0 * x1 - z1 * x0; out[7] = 0; out[8] = z0; out[9] = z1; out[10] = z2; out[11] = 0; out[12] = eyex; out[13] = eyey; out[14] = eyez; out[15] = 1; return out; } function str3(a) { return `mat4(${a[0]}, ${a[1]}, ${a[2]}, ${a[3]}, ${a[4]}, ${a[5]}, ${a[6]}, ${a[7]}, ${a[8]}, ${a[9]}, ${a[10]}, ${a[11]}, ${a[12]}, ${a[13]}, ${a[14]}, ${a[15]})`; } function frob(a) { return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3] + a[4] * a[4] + a[5] * a[5] + a[6] * a[6] + a[7] * a[7] + a[8] * a[8] + a[9] * a[9] + a[10] * a[10] + a[11] * a[11] + a[12] * a[12] + a[13] * a[13] + a[14] * a[14] + a[15] * a[15]); } function add3(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; out[4] = a[4] + b[4]; out[5] = a[5] + b[5]; out[6] = a[6] + b[6]; out[7] = a[7] + b[7]; out[8] = a[8] + b[8]; out[9] = a[9] + b[9]; out[10] = a[10] + b[10]; out[11] = a[11] + b[11]; out[12] = a[12] + b[12]; out[13] = a[13] + b[13]; out[14] = a[14] + b[14]; out[15] = a[15] + b[15]; return out; } function subtract3(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; out[4] = a[4] - b[4]; out[5] = a[5] - b[5]; out[6] = a[6] - b[6]; out[7] = a[7] - b[7]; out[8] = a[8] - b[8]; out[9] = a[9] - b[9]; out[10] = a[10] - b[10]; out[11] = a[11] - b[11]; out[12] = a[12] - b[12]; out[13] = a[13] - b[13]; out[14] = a[14] - b[14]; out[15] = a[15] - b[15]; return out; } function multiplyScalar(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; out[4] = a[4] * b; out[5] = a[5] * b; out[6] = a[6] * b; out[7] = a[7] * b; out[8] = a[8] * b; out[9] = a[9] * b; out[10] = a[10] * b; out[11] = a[11] * b; out[12] = a[12] * b; out[13] = a[13] * b; out[14] = a[14] * b; out[15] = a[15] * b; return out; } function multiplyScalarAndAdd(out, a, b, scale5) { out[0] = a[0] + b[0] * scale5; out[1] = a[1] + b[1] * scale5; out[2] = a[2] + b[2] * scale5; out[3] = a[3] + b[3] * scale5; out[4] = a[4] + b[4] * scale5; out[5] = a[5] + b[5] * scale5; out[6] = a[6] + b[6] * scale5; out[7] = a[7] + b[7] * scale5; out[8] = a[8] + b[8] * scale5; out[9] = a[9] + b[9] * scale5; out[10] = a[10] + b[10] * scale5; out[11] = a[11] + b[11] * scale5; out[12] = a[12] + b[12] * scale5; out[13] = a[13] + b[13] * scale5; out[14] = a[14] + b[14] * scale5; out[15] = a[15] + b[15] * scale5; return out; } function exactEquals3(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15]; } function equals4(a, b) { const a0 = a[0]; const a1 = a[1]; const a2 = a[2]; const a3 = a[3]; const a4 = a[4]; const a5 = a[5]; const a6 = a[6]; const a7 = a[7]; const a8 = a[8]; const a9 = a[9]; const a10 = a[10]; const a11 = a[11]; const a12 = a[12]; const a13 = a[13]; const a14 = a[14]; const a15 = a[15]; const b0 = b[0]; const b1 = b[1]; const b2 = b[2]; const b3 = b[3]; const b4 = b[4]; const b5 = b[5]; const b6 = b[6]; const b7 = b[7]; const b8 = b[8]; const b9 = b[9]; const b10 = b[10]; const b11 = b[11]; const b12 = b[12]; const b13 = b[13]; const b14 = b[14]; const b15 = b[15]; return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1, Math.abs(a15), Math.abs(b15)); } var mul3 = multiply3; var sub3 = subtract3; // ../../node_modules/@math.gl/core/dist/gl-matrix/vec4.js var vec4_exports = {}; __export(vec4_exports, { add: () => add4, ceil: () => ceil3, clone: () => clone4, copy: () => copy4, create: () => create4, cross: () => cross3, dist: () => dist3, distance: () => distance3, div: () => div3, divide: () => divide3, dot: () => dot3, equals: () => equals5, exactEquals: () => exactEquals4, floor: () => floor3, forEach: () => forEach3, fromValues: () => fromValues4, inverse: () => inverse3, len: () => len3, length: () => length3, lerp: () => lerp4, max: () => max3, min: () => min3, mul: () => mul4, multiply: () => multiply4, negate: () => negate3, normalize: () => normalize3, random: () => random3, round: () => round5, scale: () => scale4, scaleAndAdd: () => scaleAndAdd3, set: () => set4, sqrDist: () => sqrDist3, sqrLen: () => sqrLen3, squaredDistance: () => squaredDistance3, squaredLength: () => squaredLength3, str: () => str4, sub: () => sub4, subtract: () => subtract4, transformMat4: () => transformMat43, transformQuat: () => transformQuat2, zero: () => zero3 }); function create4() { const out = new ARRAY_TYPE(4); if (ARRAY_TYPE != Float32Array) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; } return out; } function clone4(a) { const out = new ARRAY_TYPE(4); out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } function fromValues4(x, y, z, w) { const out = new ARRAY_TYPE(4); out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; } function copy4(out, a) { out[0] = a[0]; out[1] = a[1]; out[2] = a[2]; out[3] = a[3]; return out; } function set4(out, x, y, z, w) { out[0] = x; out[1] = y; out[2] = z; out[3] = w; return out; } function add4(out, a, b) { out[0] = a[0] + b[0]; out[1] = a[1] + b[1]; out[2] = a[2] + b[2]; out[3] = a[3] + b[3]; return out; } function subtract4(out, a, b) { out[0] = a[0] - b[0]; out[1] = a[1] - b[1]; out[2] = a[2] - b[2]; out[3] = a[3] - b[3]; return out; } function multiply4(out, a, b) { out[0] = a[0] * b[0]; out[1] = a[1] * b[1]; out[2] = a[2] * b[2]; out[3] = a[3] * b[3]; return out; } function divide3(out, a, b) { out[0] = a[0] / b[0]; out[1] = a[1] / b[1]; out[2] = a[2] / b[2]; out[3] = a[3] / b[3]; return out; } function ceil3(out, a) { out[0] = Math.ceil(a[0]); out[1] = Math.ceil(a[1]); out[2] = Math.ceil(a[2]); out[3] = Math.ceil(a[3]); return out; } function floor3(out, a) { out[0] = Math.floor(a[0]); out[1] = Math.floor(a[1]); out[2] = Math.floor(a[2]); out[3] = Math.floor(a[3]); return out; } function min3(out, a, b) { out[0] = Math.min(a[0], b[0]); out[1] = Math.min(a[1], b[1]); out[2] = Math.min(a[2], b[2]); out[3] = Math.min(a[3], b[3]); return out; } function max3(out, a, b) { out[0] = Math.max(a[0], b[0]); out[1] = Math.max(a[1], b[1]); out[2] = Math.max(a[2], b[2]); out[3] = Math.max(a[3], b[3]); return out; } function round5(out, a) { out[0] = round2(a[0]); out[1] = round2(a[1]); out[2] = round2(a[2]); out[3] = round2(a[3]); return out; } function scale4(out, a, b) { out[0] = a[0] * b; out[1] = a[1] * b; out[2] = a[2] * b; out[3] = a[3] * b; return out; } function scaleAndAdd3(out, a, b, scale5) { out[0] = a[0] + b[0] * scale5; out[1] = a[1] + b[1] * scale5; out[2] = a[2] + b[2] * scale5; out[3] = a[3] + b[3] * scale5; return out; } function distance3(a, b) { const x = b[0] - a[0]; const y = b[1] - a[1]; const z = b[2] - a[2]; const w = b[3] - a[3]; return Math.sqrt(x * x + y * y + z * z + w * w); } function squaredDistance3(a, b) { const x = b[0] - a[0]; const y = b[1] - a[1]; const z = b[2] - a[2]; const w = b[3] - a[3]; return x * x + y * y + z * z + w * w; } function length3(a) { const x = a[0]; const y = a[1]; const z = a[2]; const w = a[3]; return Math.sqrt(x * x + y * y + z * z + w * w); } function squaredLength3(a) { const x = a[0]; const y = a[1]; const z = a[2]; const w = a[3]; return x * x + y * y + z * z + w * w; } function negate3(out, a) { out[0] = -a[0]; out[1] = -a[1]; out[2] = -a[2]; out[3] = -a[3]; return out; } function inverse3(out, a) { out[0] = 1 / a[0]; out[1] = 1 / a[1]; out[2] = 1 / a[2]; out[3] = 1 / a[3]; return out; } function normalize3(out, a) { const x = a[0]; const y = a[1]; const z = a[2]; const w = a[3]; let len4 = x * x + y * y + z * z + w * w; if (len4 > 0) { len4 = 1 / Math.sqrt(len4); } out[0] = x * len4; out[1] = y * len4; out[2] = z * len4; out[3] = w * len4; return out; } function dot3(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; } function cross3(out, u, v, w) { const A = v[0] * w[1] - v[1] * w[0]; const B = v[0] * w[2] - v[2] * w[0]; const C = v[0] * w[3] - v[3] * w[0]; const D = v[1] * w[2] - v[2] * w[1]; const E = v[1] * w[3] - v[3] * w[1]; const F = v[2] * w[3] - v[3] * w[2]; const G = u[0]; const H = u[1]; const I = u[2]; const J = u[3]; out[0] = H * F - I * E + J * D; out[1] = -(G * F) + I * C - J * B; out[2] = G * E - H * C + J * A; out[3] = -(G * D) + H * B - I * A; return out; } function lerp4(out, a, b, t) { const ax = a[0]; const ay = a[1]; const az = a[2]; const aw = a[3]; out[0] = ax + t * (b[0] - ax); out[1] = ay + t * (b[1] - ay); out[2] = az + t * (b[2] - az); out[3] = aw + t * (b[3] - aw); return out; } function random3(out, scale5) { scale5 = scale5 === void 0 ? 1 : scale5; let v1; let v2; let v3; let v4; let s1; let s2; do { v1 = RANDOM() * 2 - 1; v2 = RANDOM() * 2 - 1; s1 = v1 * v1 + v2 * v2; } while (s1 >= 1); do { v3 = RANDOM() * 2 - 1; v4 = RANDOM() * 2 - 1; s2 = v3 * v3 + v4 * v4; } while (s2 >= 1); const d = Math.sqrt((1 - s1) / s2); out[0] = scale5 * v1; out[1] = scale5 * v2; out[2] = scale5 * v3 * d; out[3] = scale5 * v4 * d; return out; } function transformMat43(out, a, m) { const x = a[0]; const y = a[1]; const z = a[2]; const w = a[3]; out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w; out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w; out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w; out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w; return out; } function transformQuat2(out, a, q) { const x = a[0]; const y = a[1]; const z = a[2]; const qx = q[0]; const qy = q[1]; const qz = q[2]; const qw = q[3]; const ix = qw * x + qy * z - qz * y; const iy = qw * y + qz * x - qx * z; const iz = qw * z + qx * y - qy * x; const iw = -qx * x - qy * y - qz * z; out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy; out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz; out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx; out[3] = a[3]; return out; } function zero3(out) { out[0] = 0; out[1] = 0; out[2] = 0; out[3] = 0; return out; } function str4(a) { return `vec4(${a[0]}, ${a[1]}, ${a[2]}, ${a[3]})`; } function exactEquals4(a, b) { return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3]; } function equals5(a, b) { const a0 = a[0]; const a1 = a[1]; const a2 = a[2]; const a3 = a[3]; const b0 = b[0]; const b1 = b[1]; const b2 = b[2]; const b3 = b[3]; return Math.abs(a0 - b0) <= EPSILON * Math.max(1, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1, Math.abs(a3), Math.abs(b3)); } var sub4 = subtract4; var mul4 = multiply4; var div3 = divide3; var dist3 = distance3; var sqrDist3 = squaredDistance3; var len3 = length3; var sqrLen3 = squaredLength3; var forEach3 = function() { const vec = create4(); return function(a, stride, offset, count2, fn, arg) { let i; let l; if (!stride) { stride = 4; } if (!offset) { offset = 0; } if (count2) { l = Math.min(count2 * stride + offset, a.length); } else { l = a.length; } for (i = offset; i < l; i += stride) { vec[0] = a[i]; vec[1] = a[i + 1]; vec[2] = a[i + 2]; vec[3] = a[i + 3]; fn(vec, vec, arg); a[i] = vec[0]; a[i + 1] = vec[1]; a[i + 2] = vec[2]; a[i + 3] = vec[3]; } return a; }; }(); // ../../node_modules/@math.gl/core/dist/classes/matrix4.js var INDICES; (function(INDICES2) { INDICES2[INDICES2["COL0ROW0"] = 0] = "COL0ROW0"; INDICES2[INDICES2["COL0ROW1"] = 1] = "COL0ROW1"; INDICES2[INDICES2["COL0ROW2"] = 2] = "COL0ROW2"; INDICES2[INDICES2["COL0ROW3"] = 3] = "COL0ROW3"; INDICES2[INDICES2["COL1ROW0"] = 4] = "COL1ROW0"; INDICES2[INDICES2["COL1ROW1"] = 5] = "COL1ROW1"; INDICES2[INDICES2["COL1ROW2"] = 6] = "COL1ROW2"; INDICES2[INDICES2["COL1ROW3"] = 7] = "COL1ROW3"; INDICES2[INDICES2["COL2ROW0"] = 8] = "COL2ROW0"; INDICES2[INDICES2["COL2ROW1"] = 9] = "COL2ROW1"; INDICES2[INDICES2["COL2ROW2"] = 10] = "COL2ROW2"; INDICES2[INDICES2["COL2ROW3"] = 11] = "COL2ROW3"; INDICES2[INDICES2["COL3ROW0"] = 12] = "COL3ROW0"; INDICES2[INDICES2["COL3ROW1"] = 13] = "COL3ROW1"; INDICES2[INDICES2["COL3ROW2"] = 14] = "COL3ROW2"; INDICES2[INDICES2["COL3ROW3"] = 15] = "COL3ROW3"; })(INDICES || (INDICES = {})); var DEFAULT_FOVY = 45 * Math.PI / 180; var DEFAULT_ASPECT = 1; var DEFAULT_NEAR = 0.1; var DEFAULT_FAR = 500; var IDENTITY_MATRIX = Object.freeze([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); var Matrix4 = class extends Matrix { static get IDENTITY() { return getIdentityMatrix(); } static get ZERO() { return getZeroMatrix(); } get ELEMENTS() { return 16; } get RANK() { return 4; } get INDICES() { return INDICES; } constructor(array) { super(-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0); if (arguments.length === 1 && Array.isArray(array)) { this.copy(array); } else { this.identity(); } } copy(array) { this[0] = array[0]; this[1] = array[1]; this[2] = array[2]; this[3] = array[3]; this[4] = array[4]; this[5] = array[5]; this[6] = array[6]; this[7] = array[7]; this[8] = array[8]; this[9] = array[9]; this[10] = array[10]; this[11] = array[11]; this[12] = array[12]; this[13] = array[13]; this[14] = array[14]; this[15] = array[15]; return this.check(); } set(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33) { this[0] = m00; this[1] = m10; this[2] = m20; this[3] = m30; this[4] = m01; this[5] = m11; this[6] = m21; this[7] = m31; this[8] = m02; this[9] = m12; this[10] = m22; this[11] = m32; this[12] = m03; this[13] = m13; this[14] = m23; this[15] = m33; return this.check(); } setRowMajor(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) { this[0] = m00; this[1] = m10; this[2] = m20; this[3] = m30; this[4] = m01; this[5] = m11; this[6] = m21; this[7] = m31; this[8] = m02; this[9] = m12; this[10] = m22; this[11] = m32; this[12] = m03; this[13] = m13; this[14] = m23; this[15] = m33; return this.check(); } toRowMajor(result) { result[0] = this[0]; result[1] = this[4]; result[2] = this[8]; result[3] = this[12]; result[4] = this[1]; result[5] = this[5]; result[6] = this[9]; result[7] = this[13]; result[8] = this[2]; result[9] = this[6]; result[10] = this[10]; result[11] = this[14]; result[12] = this[3]; result[13] = this[7]; result[14] = this[11]; result[15] = this[15]; return result; } identity() { return this.copy(IDENTITY_MATRIX); } fromObject(object) { return this.check(); } fromQuaternion(quaternion) { fromQuat(this, quaternion); return this.check(); } frustum(view) { const { left, right, bottom, top, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view; if (far === Infinity) { computeInfinitePerspectiveOffCenter(this, left, right, bottom, top, near); } else { frustum(this, left, right, bottom, top, near, far); } return this.check(); } lookAt(view) { const { eye, center = [0, 0, 0], up = [0, 1, 0] } = view; lookAt(this, eye, center, up); return this.check(); } ortho(view) { const { left, right, bottom, top, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view; ortho(this, left, right, bottom, top, near, far); return this.check(); } orthographic(view) { const { fovy = DEFAULT_FOVY, aspect = DEFAULT_ASPECT, focalDistance = 1, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view; checkRadians(fovy); const halfY = fovy / 2; const top = focalDistance * Math.tan(halfY); const right = top * aspect; return this.ortho({ left: -right, right, bottom: -top, top, near, far }); } perspective(view) { const { fovy = 45 * Math.PI / 180, aspect = 1, near = 0.1, far = 500 } = view; checkRadians(fovy); perspective(this, fovy, aspect, near, far); return this.check(); } determinant() { return determinant(this); } getScale(result = [-0, -0, -0]) { result[0] = Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2]); result[1] = Math.sqrt(this[4] * this[4] + this[5] * this[5] + this[6] * this[6]); result[2] = Math.sqrt(this[8] * this[8] + this[9] * this[9] + this[10] * this[10]); return result; } getTranslation(result = [-0, -0, -0]) { result[0] = this[12]; result[1] = this[13]; result[2] = this[14]; return result; } getRotation(result, scaleResult) { result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0]; scaleResult = scaleResult || [-0, -0, -0]; const scale5 = this.getScale(scaleResult); const inverseScale0 = 1 / scale5[0]; const inverseScale1 = 1 / scale5[1]; const inverseScale2 = 1 / scale5[2]; result[0] = this[0] * inverseScale0; result[1] = this[1] * inverseScale1; result[2] = this[2] * inverseScale2; result[3] = 0; result[4] = this[4] * inverseScale0; result[5] = this[5] * inverseScale1; result[6] = this[6] * inverseScale2; result[7] = 0; result[8] = this[8] * inverseScale0; result[9] = this[9] * inverseScale1; result[10] = this[10] * inverseScale2; result[11] = 0; result[12] = 0; result[13] = 0; result[14] = 0; result[15] = 1; return result; } getRotationMatrix3(result, scaleResult) { result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0]; scaleResult = scaleResult || [-0, -0, -0]; const scale5 = this.getScale(scaleResult); const inverseScale0 = 1 / scale5[0]; const inverseScale1 = 1 / scale5[1]; const inverseScale2 = 1 / scale5[2]; result[0] = this[0] * inverseScale0; result[1] = this[1] * inverseScale1; result[2] = this[2] * inverseScale2; result[3] = this[4] * inverseScale0; result[4] = this[5] * inverseScale1; result[5] = this[6] * inverseScale2; result[6] = this[8] * inverseScale0; result[7] = this[9] * inverseScale1; result[8] = this[10] * inverseScale2; return result; } transpose() { transpose(this, this); return this.check(); } invert() { invert(this, this); return this.check(); } multiplyLeft(a) { multiply3(this, a, this); return this.check(); } multiplyRight(a) { multiply3(this, this, a); return this.check(); } rotateX(radians2) { rotateX2(this, this, radians2); return this.check(); } rotateY(radians2) { rotateY2(this, this, radians2); return this.check(); } rotateZ(radians2) { rotateZ2(this, this, radians2); return this.check(); } rotateXYZ(angleXYZ) { return this.rotateX(angleXYZ[0]).rotateY(angleXYZ[1]).rotateZ(angleXYZ[2]); } rotateAxis(radians2, axis) { rotate2(this, this, radians2, axis); return this.check(); } scale(factor) { scale3(this, this, Array.isArray(factor) ? factor : [factor, factor, factor]); return this.check(); } translate(vector) { translate(this, this, vector); return this.check(); } transform(vector, result) { if (vector.length === 4) { result = transformMat43(result || [-0, -0, -0, -0], vector, this); checkVector(result, 4); return result; } return this.transformAsPoint(vector, result); } transformAsPoint(vector, result) { const { length: length4 } = vector; let out; switch (length4) { case 2: out = transformMat4(result || [-0, -0], vector, this); break; case 3: out = transformMat42(result || [-0, -0, -0], vector, this); break; default: throw new Error("Illegal vector"); } checkVector(out, vector.length); return out; } transformAsVector(vector, result) { let out; switch (vector.length) { case 2: out = vec2_transformMat4AsVector(result || [-0, -0], vector, this); break; case 3: out = vec3_transformMat4AsVector(result || [-0, -0, -0], vector, this); break; default: throw new Error("Illegal vector"); } checkVector(out, vector.length); return out; } transformPoint(vector, result) { return this.transformAsPoint(vector, result); } transformVector(vector, result) { return this.transformAsPoint(vector, result); } transformDirection(vector, result) { return this.transformAsVector(vector, result); } makeRotationX(radians2) { return this.identity().rotateX(radians2); } makeTranslation(x, y, z) { return this.identity().translate([x, y, z]); } }; var ZERO2; var IDENTITY; function getZeroMatrix() { if (!ZERO2) { ZERO2 = new Matrix4([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); Object.freeze(ZERO2); } return ZERO2; } function getIdentityMatrix() { if (!IDENTITY) { IDENTITY = new Matrix4(); Object.freeze(IDENTITY); } return IDENTITY; } function checkRadians(possiblyDegrees) { if (possiblyDegrees > Math.PI * 2) { throw Error("expected radians"); } } function computeInfinitePerspectiveOffCenter(result, left, right, bottom, top, near) { const column0Row0 = 2 * near / (right - left); const column1Row1 = 2 * near / (top - bottom); const column2Row0 = (right + left) / (right - left); const column2Row1 = (top + bottom) / (top - bottom); const column2Row2 = -1; const column2Row3 = -1; const column3Row2 = -2 * near; result[0] = column0Row0; result[1] = 0; result[2] = 0; result[3] = 0; result[4] = 0; result[5] = column1Row1; result[6] = 0; result[7] = 0; result[8] = column2Row0; result[9] = column2Row1; result[10] = column2Row2; result[11] = column2Row3; result[12] = 0; result[13] = 0; result[14] = column3Row2; result[15] = 0; return result; } // ../../node_modules/@math.gl/core/dist/classes/spherical-coordinates.js var EPSILON2 = 1e-6; var EARTH_RADIUS_METERS = 6371e3; var SphericalCoordinates = class { constructor({ phi = 0, theta = 0, radius = 1, bearing, pitch, altitude, radiusScale = EARTH_RADIUS_METERS } = {}) { this.phi = phi; this.theta = theta; this.radius = radius || altitude || 1; this.radiusScale = radiusScale || 1; if (bearing !== void 0) { this.bearing = bearing; } if (pitch !== void 0) { this.pitch = pitch; } this.check(); } toString() { return this.formatString(config); } formatString({ printTypes = false }) { const f = formatValue; return `${printTypes ? "Spherical" : ""}[rho:${f(this.radius)},theta:${f(this.theta)},phi:${f(this.phi)}]`; } equals(other) { return equals(this.radius, other.radius) && equals(this.theta, other.theta) && equals(this.phi, other.phi); } exactEquals(other) { return this.radius === other.radius && this.theta === other.theta && this.phi === other.phi; } get bearing() { return 180 - degrees(this.phi); } set bearing(v) { this.phi = Math.PI - radians(v); } get pitch() { return degrees(this.theta); } set pitch(v) { this.theta = radians(v); } get longitude() { return degrees(this.phi); } get latitude() { return degrees(this.theta); } get lng() { return degrees(this.phi); } get lat() { return degrees(this.theta); } get z() { return (this.radius - 1) * this.radiusScale; } set(radius, phi, theta) { this.radius = radius; this.phi = phi; this.theta = theta; return this.check(); } clone() { return new SphericalCoordinates().copy(this); } copy(other) { this.radius = other.radius; this.phi = other.phi; this.theta = other.theta; return this.check(); } fromLngLatZ([lng, lat, z]) { this.radius = 1 + z / this.radiusScale; this.phi = radians(lat); this.theta = radians(lng); return this.check(); } fromVector3(v) { this.radius = length2(v); if (this.radius > 0) { this.theta = Math.atan2(v[0], v[1]); this.phi = Math.acos(clamp(v[2] / this.radius, -1, 1)); } return this.check(); } toVector3() { return new Vector3(0, 0, this.radius).rotateX({ radians: this.theta }).rotateZ({ radians: this.phi }); } makeSafe() { this.phi = Math.max(EPSILON2, Math.min(Math.PI - EPSILON2, this.phi)); return this; } check() { if (!Number.isFinite(this.phi) || !Number.isFinite(this.theta) || !(this.radius > 0)) { throw new Error("SphericalCoordinates: some fields set to invalid numbers"); } return this; } }; // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/lighting/lights/lights-glsl.js var lightingShader = `#if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX)) struct AmbientLight { vec3 color; }; struct PointLight { vec3 color; vec3 position; vec3 attenuation; }; struct DirectionalLight { vec3 color; vec3 direction; }; uniform AmbientLight lighting_uAmbientLight; uniform PointLight lighting_uPointLight[MAX_LIGHTS]; uniform DirectionalLight lighting_uDirectionalLight[MAX_LIGHTS]; uniform int lighting_uPointLightCount; uniform int lighting_uDirectionalLightCount; uniform bool lighting_uEnabled; float getPointLightAttenuation(PointLight pointLight, float distance) { return pointLight.attenuation.x + pointLight.attenuation.y * distance + pointLight.attenuation.z * distance * distance; } #endif `; // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/lighting/lights/lights.js var INITIAL_MODULE_OPTIONS = { lightSources: {} }; function convertColor(colorDef = {}) { const { color = [0, 0, 0], intensity = 1 } = colorDef; return color.map((component) => component * intensity / 255); } function getLightSourceUniforms({ ambientLight, pointLights = [], directionalLights = [] }) { const lightSourceUniforms = {}; if (ambientLight) { lightSourceUniforms["lighting_uAmbientLight.color"] = convertColor(ambientLight); } else { lightSourceUniforms["lighting_uAmbientLight.color"] = [0, 0, 0]; } pointLights.forEach((pointLight, index2) => { lightSourceUniforms[`lighting_uPointLight[${index2}].color`] = convertColor(pointLight); lightSourceUniforms[`lighting_uPointLight[${index2}].position`] = pointLight.position; lightSourceUniforms[`lighting_uPointLight[${index2}].attenuation`] = pointLight.attenuation || [ 1, 0, 0 ]; }); lightSourceUniforms.lighting_uPointLightCount = pointLights.length; directionalLights.forEach((directionalLight, index2) => { lightSourceUniforms[`lighting_uDirectionalLight[${index2}].color`] = convertColor(directionalLight); lightSourceUniforms[`lighting_uDirectionalLight[${index2}].direction`] = directionalLight.direction; }); lightSourceUniforms.lighting_uDirectionalLightCount = directionalLights.length; return lightSourceUniforms; } function getUniforms3(opts = INITIAL_MODULE_OPTIONS) { if ("lightSources" in opts) { const { ambientLight, pointLights, directionalLights } = opts.lightSources || {}; const hasLights = ambientLight || pointLights && pointLights.length > 0 || directionalLights && directionalLights.length > 0; if (!hasLights) { return { lighting_uEnabled: false }; } return Object.assign({}, getLightSourceUniforms({ ambientLight, pointLights, directionalLights }), { lighting_uEnabled: true }); } if ("lights" in opts) { const lightSources = { pointLights: [], directionalLights: [] }; for (const light of opts.lights || []) { switch (light.type) { case "ambient": lightSources.ambientLight = light; break; case "directional": lightSources.directionalLights?.push(light); break; case "point": lightSources.pointLights?.push(light); break; default: } } return getUniforms3({ lightSources }); } return {}; } var lights = { name: "lights", vs: lightingShader, fs: lightingShader, getUniforms: getUniforms3, defines: { MAX_LIGHTS: 3 } }; // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/lighting/phong-lighting/phong-lighting-glsl.js var lightingShader2 = `uniform float lighting_uAmbient; uniform float lighting_uDiffuse; uniform float lighting_uShininess; uniform vec3 lighting_uSpecularColor; vec3 lighting_getLightColor(vec3 surfaceColor, vec3 light_direction, vec3 view_direction, vec3 normal_worldspace, vec3 color) { vec3 halfway_direction = normalize(light_direction + view_direction); float lambertian = dot(light_direction, normal_worldspace); float specular = 0.0; if (lambertian > 0.0) { float specular_angle = max(dot(normal_worldspace, halfway_direction), 0.0); specular = pow(specular_angle, lighting_uShininess); } lambertian = max(lambertian, 0.0); return (lambertian * lighting_uDiffuse * surfaceColor + specular * lighting_uSpecularColor) * color; } vec3 lighting_getLightColor(vec3 surfaceColor, vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) { vec3 lightColor = surfaceColor; if (lighting_uEnabled) { vec3 view_direction = normalize(cameraPosition - position_worldspace); lightColor = lighting_uAmbient * surfaceColor * lighting_uAmbientLight.color; for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uPointLightCount) { break; } PointLight pointLight = lighting_uPointLight[i]; vec3 light_position_worldspace = pointLight.position; vec3 light_direction = normalize(light_position_worldspace - position_worldspace); lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color); } for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uDirectionalLightCount) { break; } DirectionalLight directionalLight = lighting_uDirectionalLight[i]; lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); } } return lightColor; } vec3 lighting_getSpecularLightColor(vec3 cameraPosition, vec3 position_worldspace, vec3 normal_worldspace) { vec3 lightColor = vec3(0, 0, 0); vec3 surfaceColor = vec3(0, 0, 0); if (lighting_uEnabled) { vec3 view_direction = normalize(cameraPosition - position_worldspace); for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uPointLightCount) { break; } PointLight pointLight = lighting_uPointLight[i]; vec3 light_position_worldspace = pointLight.position; vec3 light_direction = normalize(light_position_worldspace - position_worldspace); lightColor += lighting_getLightColor(surfaceColor, light_direction, view_direction, normal_worldspace, pointLight.color); } for (int i = 0; i < MAX_LIGHTS; i++) { if (i >= lighting_uDirectionalLightCount) { break; } DirectionalLight directionalLight = lighting_uDirectionalLight[i]; lightColor += lighting_getLightColor(surfaceColor, -directionalLight.direction, view_direction, normal_worldspace, directionalLight.color); } } return lightColor; } `; // ../../node_modules/@luma.gl/shadertools/dist/modules-webgl1/lighting/phong-lighting/phong-lighting.js var INITIAL_MODULE_OPTIONS2 = {}; function getMaterialUniforms(material) { const { ambient = 0.35, diffuse = 0.6, shininess = 32, specularColor = [30, 30, 30] } = material; return { lighting_uAmbient: ambient, lighting_uDiffuse: diffuse, lighting_uShininess: shininess, lighting_uSpecularColor: specularColor.map((x) => x / 255) }; } function getUniforms4(opts = INITIAL_MODULE_OPTIONS2) { if (!("material" in opts)) { return {}; } const { material } = opts; if (!material) { return { lighting_uEnabled: false }; } return getMaterialUniforms(material); } var gouraudLighting = { name: "gouraud-lighting", dependencies: [lights], vs: lightingShader2, defines: { LIGHTING_VERTEX: 1 }, getUniforms: getUniforms4 }; var phongLighting = { name: "phong-lighting", dependencies: [lights], fs: lightingShader2, defines: { LIGHTING_FRAGMENT: 1 }, getUniforms: getUniforms4 }; // ../../node_modules/@luma.gl/engine/dist/geometry/gpu-geometry.js var GPUGeometry = class { id; userData = {}; topology; bufferLayout = []; vertexCount; indices; attributes; constructor(props) { this.id = props.id || uid("geometry"); this.topology = props.topology; this.indices = props.indices || null; this.attributes = props.attributes; this.vertexCount = props.vertexCount; this.bufferLayout = props.bufferLayout || []; if (this.indices) { assert2(this.indices.usage === Buffer2.INDEX); } } destroy() { this.indices?.destroy(); for (const attribute of Object.values(this.attributes)) { attribute.destroy(); } } getVertexCount() { return this.vertexCount; } getAttributes() { return this.attributes; } getIndexes() { return this.indices; } _calculateVertexCount(positions) { const vertexCount = positions.byteLength / 12; return vertexCount; } }; function makeGPUGeometry(device, geometry) { if (geometry instanceof GPUGeometry) { return geometry; } const indices = getIndexBufferFromGeometry(device, geometry); const { attributes, bufferLayout } = getAttributeBuffersFromGeometry(device, geometry); return new GPUGeometry({ topology: geometry.topology || "triangle-list", bufferLayout, vertexCount: geometry.vertexCount, indices, attributes }); } function getIndexBufferFromGeometry(device, geometry) { if (!geometry.indices) { return void 0; } const data = geometry.indices.value; return device.createBuffer({ usage: Buffer2.INDEX, data }); } function getAttributeBuffersFromGeometry(device, geometry) { const bufferLayout = []; const attributes = {}; for (const [attributeName, attribute] of Object.entries(geometry.attributes)) { let name2 = attributeName; switch (attributeName) { case "POSITION": name2 = "positions"; break; case "NORMAL": name2 = "normals"; break; case "TEXCOORD_0": name2 = "texCoords"; break; case "COLOR_0": name2 = "colors"; break; } attributes[name2] = device.createBuffer({ data: attribute.value, id: `${attributeName}-buffer` }); const { value, size, normalized } = attribute; bufferLayout.push({ name: name2, format: getVertexFormatFromAttribute(value, size, normalized) }); } const vertexCount = geometry._calculateVertexCount(geometry.attributes, geometry.indices); return { attributes, bufferLayout, vertexCount }; } // ../../node_modules/@luma.gl/engine/dist/shader-inputs.js var ShaderInputs = class { modules; moduleUniforms; moduleBindings; moduleUniformsChanged; constructor(modules) { const resolvedModules = resolveModules(Object.values(modules).filter((module) => module.dependencies)); for (const resolvedModule of resolvedModules) { modules[resolvedModule.name] = resolvedModule; } log.log(1, "Creating ShaderInputs with modules", Object.keys(modules))(); this.modules = modules; this.moduleUniforms = {}; this.moduleBindings = {}; for (const [name2, module] of Object.entries(modules)) { const moduleName = name2; this.moduleUniforms[moduleName] = module.defaultUniforms || {}; this.moduleBindings[moduleName] = {}; } } destroy() { } setProps(props) { for (const name2 of Object.keys(props)) { const moduleName = name2; const moduleProps = props[moduleName]; const module = this.modules[moduleName]; if (!module) { log.warn(`Module ${name2} not found`)(); continue; } const oldUniforms = this.moduleUniforms[moduleName]; const oldBindings = this.moduleBindings[moduleName]; const uniformsAndBindings = module.getUniforms?.(moduleProps, oldUniforms) || moduleProps; const { uniforms, bindings } = splitUniformsAndBindings(uniformsAndBindings); this.moduleUniforms[moduleName] = { ...oldUniforms, ...uniforms }; this.moduleBindings[moduleName] = { ...oldBindings, ...bindings }; } } getModules() { return Object.values(this.modules); } getUniformValues() { return this.moduleUniforms; } getBindings() { const bindings = {}; for (const moduleBindings of Object.values(this.moduleBindings)) { Object.assign(bindings, moduleBindings); } return bindings; } getDebugTable() { const table = {}; for (const [moduleName, module] of Object.entries(this.moduleUniforms)) { for (const [key, value] of Object.entries(module)) { table[`${moduleName}.${key}`] = { type: this.modules[moduleName].uniformTypes?.[key], value: String(value) }; } } return table; } }; // ../../node_modules/@luma.gl/engine/dist/lib/pipeline-factory.js var _PipelineFactory = class { device; _hashCounter = 0; _hashes = {}; _renderPipelineCache = {}; _computePipelineCache = {}; static getDefaultPipelineFactory(device) { device._lumaData.defaultPipelineFactory = device._lumaData.defaultPipelineFactory || new _PipelineFactory(device); return device._lumaData.defaultPipelineFactory; } constructor(device) { this.device = device; } createRenderPipeline(props) { const allProps = { ...RenderPipeline.defaultProps, ...props }; const hash = this._hashRenderPipeline(allProps); if (!this._renderPipelineCache[hash]) { const pipeline = this.device.createRenderPipeline({ ...allProps, id: allProps.id ? `${allProps.id}-cached` : void 0 }); pipeline.hash = hash; this._renderPipelineCache[hash] = { pipeline, useCount: 0 }; } this._renderPipelineCache[hash].useCount++; return this._renderPipelineCache[hash].pipeline; } createComputePipeline(props) { const allProps = { ...ComputePipeline.defaultProps, ...props }; const hash = this._hashComputePipeline(allProps); if (!this._computePipelineCache[hash]) { const pipeline = this.device.createComputePipeline({ ...allProps, id: allProps.id ? `${allProps.id}-cached` : void 0 }); pipeline.hash = hash; this._computePipelineCache[hash] = { pipeline, useCount: 0 }; } this._computePipelineCache[hash].useCount++; return this._computePipelineCache[hash].pipeline; } release(pipeline) { const hash = pipeline.hash; const cache2 = pipeline instanceof ComputePipeline ? this._computePipelineCache : this._renderPipelineCache; cache2[hash].useCount--; if (cache2[hash].useCount === 0) { cache2[hash].pipeline.destroy(); delete cache2[hash]; } } _hashComputePipeline(props) { const shaderHash = this._getHash(props.shader.source); return `${shaderHash}`; } _hashRenderPipeline(props) { const vsHash = this._getHash(props.vs.source); const fsHash = props.fs ? this._getHash(props.fs.source) : 0; const varyingHash = "-"; const bufferLayoutHash = this._getHash(JSON.stringify(props.bufferLayout)); switch (this.device.type) { case "webgl": return `${vsHash}/${fsHash}V${varyingHash}BL${bufferLayoutHash}`; default: const parameterHash = this._getHash(JSON.stringify(props.parameters)); return `${vsHash}/${fsHash}V${varyingHash}T${props.topology}P${parameterHash}BL${bufferLayoutHash}`; } } _getHash(key) { if (this._hashes[key] === void 0) { this._hashes[key] = this._hashCounter++; } return this._hashes[key]; } }; var PipelineFactory = _PipelineFactory; __publicField(PipelineFactory, "defaultProps", { ...RenderPipeline.defaultProps }); // ../../node_modules/@luma.gl/engine/dist/lib/shader-factory.js var _ShaderFactory = class { device; _cache = {}; static getDefaultShaderFactory(device) { device._lumaData.defaultShaderFactory ||= new _ShaderFactory(device); return device._lumaData.defaultShaderFactory; } constructor(device) { this.device = device; } createShader(props) { const key = this._hashShader(props); let cacheEntry = this._cache[key]; if (!cacheEntry) { const shader = this.device.createShader({ ...props, id: props.id ? `${props.id}-cached` : void 0 }); this._cache[key] = cacheEntry = { shader, useCount: 0 }; } cacheEntry.useCount++; return cacheEntry.shader; } release(shader) { const key = this._hashShader(shader); const cacheEntry = this._cache[key]; if (cacheEntry) { cacheEntry.useCount--; if (cacheEntry.useCount === 0) { delete this._cache[key]; cacheEntry.shader.destroy(); } } } _hashShader(value) { return `${value.stage}:${value.source}`; } }; var ShaderFactory = _ShaderFactory; __publicField(ShaderFactory, "defaultProps", { ...Shader.defaultProps }); // ../../node_modules/@luma.gl/engine/dist/debug/debug-shader-layout.js function getDebugTableForShaderLayout(layout, name2) { const table = {}; const header = "Values"; if (layout.attributes.length === 0 && !layout.varyings?.length) { return { "No attributes or varyings": { [header]: "N/A" } }; } for (const attributeDeclaration of layout.attributes) { if (attributeDeclaration) { const glslDeclaration = `${attributeDeclaration.location} ${attributeDeclaration.name}: ${attributeDeclaration.type}`; table[`in ${glslDeclaration}`] = { [header]: attributeDeclaration.stepMode || "vertex" }; } } for (const varyingDeclaration of layout.varyings || []) { const glslDeclaration = `${varyingDeclaration.location} ${varyingDeclaration.name}`; table[`out ${glslDeclaration}`] = { [header]: JSON.stringify(varyingDeclaration.accessor) }; } return table; } // ../../node_modules/@luma.gl/engine/dist/debug/debug-framebuffer.js var canvas = null; var ctx = null; function debugFramebuffer(fbo, { id, minimap, opaque, top = "0", left = "0", rgbaScale = 1 }) { if (!canvas) { canvas = document.createElement("canvas"); canvas.id = id; canvas.title = id; canvas.style.zIndex = "100"; canvas.style.position = "absolute"; canvas.style.top = top; canvas.style.left = left; canvas.style.border = "blue 1px solid"; canvas.style.transform = "scaleY(-1)"; document.body.appendChild(canvas); ctx = canvas.getContext("2d"); } if (canvas.width !== fbo.width || canvas.height !== fbo.height) { canvas.width = fbo.width / 2; canvas.height = fbo.height / 2; canvas.style.width = "400px"; canvas.style.height = "400px"; } const color = fbo.device.readPixelsToArrayWebGL(fbo); const imageData = ctx.createImageData(fbo.width, fbo.height); const offset = 0; for (let i = 0; i < color.length; i += 4) { imageData.data[offset + i + 0] = color[i + 0] * rgbaScale; imageData.data[offset + i + 1] = color[i + 1] * rgbaScale; imageData.data[offset + i + 2] = color[i + 2] * rgbaScale; imageData.data[offset + i + 3] = opaque ? 255 : color[i + 3] * rgbaScale; } ctx.putImageData(imageData, 0, 0); } // ../../node_modules/@luma.gl/engine/dist/model/model.js var LOG_DRAW_PRIORITY = 2; var LOG_DRAW_TIMEOUT = 1e4; var _Model = class { device; id; source; vs; fs; pipelineFactory; shaderFactory; userData = {}; parameters; topology; bufferLayout; isInstanced = void 0; instanceCount = 0; vertexCount; indexBuffer = null; bufferAttributes = {}; constantAttributes = {}; bindings = {}; uniforms = {}; vertexArray; transformFeedback = null; pipeline; shaderInputs; _uniformStore; _attributeInfos = {}; _gpuGeometry = null; _getModuleUniforms; props; _pipelineNeedsUpdate = "newly created"; _needsRedraw = "initializing"; _destroyed = false; _lastDrawTimestamp = -1; constructor(device, props) { this.props = { ..._Model.defaultProps, ...props }; props = this.props; this.id = props.id || uid("model"); this.device = device; Object.assign(this.userData, props.userData); const moduleMap = Object.fromEntries(this.props.modules?.map((module) => [module.name, module]) || []); this.setShaderInputs(props.shaderInputs || new ShaderInputs(moduleMap)); const platformInfo = getPlatformInfo(device); const modules = (this.props.modules?.length > 0 ? this.props.modules : this.shaderInputs?.getModules()) || []; const isWebGPU = this.device.type === "webgpu"; if (isWebGPU && this.props.source) { this.props.shaderLayout ||= getShaderLayoutFromWGSL(this.props.source); const { source, getUniforms: getUniforms6 } = this.props.shaderAssembler.assembleShader({ platformInfo, ...this.props, modules }); this.source = source; this._getModuleUniforms = getUniforms6; } else { const { vs: vs7, fs: fs5, getUniforms: getUniforms6 } = this.props.shaderAssembler.assembleShaderPair({ platformInfo, ...this.props, modules }); this.vs = vs7; this.fs = fs5; this._getModuleUniforms = getUniforms6; } this.vertexCount = this.props.vertexCount; this.instanceCount = this.props.instanceCount; this.topology = this.props.topology; this.bufferLayout = this.props.bufferLayout; this.parameters = this.props.parameters; if (props.geometry) { this.setGeometry(props.geometry); } this.pipelineFactory = props.pipelineFactory || PipelineFactory.getDefaultPipelineFactory(this.device); this.shaderFactory = props.shaderFactory || ShaderFactory.getDefaultShaderFactory(this.device); this.pipeline = this._updatePipeline(); this.vertexArray = device.createVertexArray({ renderPipeline: this.pipeline }); if (this._gpuGeometry) { this._setGeometryAttributes(this._gpuGeometry); } if ("isInstanced" in props) { this.isInstanced = props.isInstanced; } if (props.instanceCount) { this.setInstanceCount(props.instanceCount); } if (props.vertexCount) { this.setVertexCount(props.vertexCount); } if (props.indexBuffer) { this.setIndexBuffer(props.indexBuffer); } if (props.attributes) { this.setAttributes(props.attributes); } if (props.constantAttributes) { this.setConstantAttributes(props.constantAttributes); } if (props.bindings) { this.setBindings(props.bindings); } if (props.uniforms) { this.setUniforms(props.uniforms); } if (props.moduleSettings) { this.updateModuleSettings(props.moduleSettings); } if (props.transformFeedback) { this.transformFeedback = props.transformFeedback; } Object.seal(this); } destroy() { if (this._destroyed) return; this.pipelineFactory.release(this.pipeline); this.shaderFactory.release(this.pipeline.vs); if (this.pipeline.fs) { this.shaderFactory.release(this.pipeline.fs); } this._uniformStore.destroy(); this._gpuGeometry?.destroy(); this._destroyed = true; } needsRedraw() { if (this._getBindingsUpdateTimestamp() > this._lastDrawTimestamp) { this.setNeedsRedraw("contents of bound textures or buffers updated"); } const needsRedraw = this._needsRedraw; this._needsRedraw = false; return needsRedraw; } setNeedsRedraw(reason) { this._needsRedraw ||= reason; } predraw() { this.updateShaderInputs(); this.pipeline = this._updatePipeline(); } draw(renderPass) { this.predraw(); let drawSuccess; try { this._logDrawCallStart(); this.pipeline = this._updatePipeline(); this.pipeline.setBindings(this.bindings, { disableWarnings: this.props.disableWarnings }); if (!isObjectEmpty(this.uniforms)) { this.pipeline.setUniformsWebGL(this.uniforms); } const { indexBuffer } = this.vertexArray; const indexCount = indexBuffer ? indexBuffer.byteLength / (indexBuffer.indexType === "uint32" ? 4 : 2) : void 0; drawSuccess = this.pipeline.draw({ renderPass, vertexArray: this.vertexArray, isInstanced: this.isInstanced, vertexCount: this.vertexCount, instanceCount: this.instanceCount, indexCount, transformFeedback: this.transformFeedback || void 0, parameters: this.parameters, topology: this.topology }); } finally { this._logDrawCallEnd(); } this._logFramebuffer(renderPass); if (drawSuccess) { this._lastDrawTimestamp = this.device.timestamp; this._needsRedraw = false; } else { this._needsRedraw = "waiting for resource initialization"; } return drawSuccess; } setGeometry(geometry) { this._gpuGeometry?.destroy(); const gpuGeometry = geometry && makeGPUGeometry(this.device, geometry); if (gpuGeometry) { this.setTopology(gpuGeometry.topology || "triangle-list"); this.bufferLayout = mergeBufferLayouts(gpuGeometry.bufferLayout, this.bufferLayout); if (this.vertexArray) { this._setGeometryAttributes(gpuGeometry); } } this._gpuGeometry = gpuGeometry; } setTopology(topology) { if (topology !== this.topology) { this.topology = topology; this._setPipelineNeedsUpdate("topology"); } } setBufferLayout(bufferLayout) { this.bufferLayout = this._gpuGeometry ? mergeBufferLayouts(bufferLayout, this._gpuGeometry.bufferLayout) : bufferLayout; this._setPipelineNeedsUpdate("bufferLayout"); this.pipeline = this._updatePipeline(); this.vertexArray = this.device.createVertexArray({ renderPipeline: this.pipeline }); if (this._gpuGeometry) { this._setGeometryAttributes(this._gpuGeometry); } } setParameters(parameters) { if (!deepEqual(parameters, this.parameters, 2)) { this.parameters = parameters; this._setPipelineNeedsUpdate("parameters"); } } setInstanceCount(instanceCount) { this.instanceCount = instanceCount; if (this.isInstanced === void 0 && instanceCount > 0) { this.isInstanced = true; } this.setNeedsRedraw("instanceCount"); } setVertexCount(vertexCount) { this.vertexCount = vertexCount; this.setNeedsRedraw("vertexCount"); } setShaderInputs(shaderInputs) { this.shaderInputs = shaderInputs; this._uniformStore = new UniformStore(this.shaderInputs.modules); for (const moduleName of Object.keys(this.shaderInputs.modules)) { const uniformBuffer = this._uniformStore.getManagedUniformBuffer(this.device, moduleName); this.bindings[`${moduleName}Uniforms`] = uniformBuffer; } this.setNeedsRedraw("shaderInputs"); } updateShaderInputs() { this._uniformStore.setUniforms(this.shaderInputs.getUniformValues()); this.setBindings(this.shaderInputs.getBindings()); this.setNeedsRedraw("shaderInputs"); } setBindings(bindings) { Object.assign(this.bindings, bindings); this.setNeedsRedraw("bindings"); } setTransformFeedback(transformFeedback) { this.transformFeedback = transformFeedback; this.setNeedsRedraw("transformFeedback"); } setIndexBuffer(indexBuffer) { this.vertexArray.setIndexBuffer(indexBuffer); this.setNeedsRedraw("indexBuffer"); } setAttributes(buffers, options) { if (buffers.indices) { log.warn(`Model:${this.id} setAttributes() - indexBuffer should be set using setIndexBuffer()`)(); } for (const [bufferName, buffer] of Object.entries(buffers)) { const bufferLayout = this.bufferLayout.find((layout) => getAttributeNames(layout).includes(bufferName)); if (!bufferLayout) { log.warn(`Model(${this.id}): Missing layout for buffer "${bufferName}".`)(); continue; } const attributeNames = getAttributeNames(bufferLayout); let set5 = false; for (const attributeName of attributeNames) { const attributeInfo = this._attributeInfos[attributeName]; if (attributeInfo) { this.vertexArray.setBuffer(attributeInfo.location, buffer); set5 = true; } } if (!set5 && !(options?.disableWarnings ?? this.props.disableWarnings)) { log.warn(`Model(${this.id}): Ignoring buffer "${buffer.id}" for unknown attribute "${bufferName}"`)(); } } this.setNeedsRedraw("attributes"); } setConstantAttributes(attributes, options) { for (const [attributeName, value] of Object.entries(attributes)) { const attributeInfo = this._attributeInfos[attributeName]; if (attributeInfo) { this.vertexArray.setConstantWebGL(attributeInfo.location, value); } else if (!(options?.disableWarnings ?? this.props.disableWarnings)) { log.warn(`Model "${this.id}: Ignoring constant supplied for unknown attribute "${attributeName}"`)(); } } this.setNeedsRedraw("constants"); } setUniforms(uniforms) { if (!isObjectEmpty(uniforms)) { this.pipeline.setUniformsWebGL(uniforms); Object.assign(this.uniforms, uniforms); } this.setNeedsRedraw("uniforms"); } updateModuleSettings(props) { const { bindings, uniforms } = splitUniformsAndBindings(this._getModuleUniforms(props)); Object.assign(this.bindings, bindings); Object.assign(this.uniforms, uniforms); this.setNeedsRedraw("moduleSettings"); } _getBindingsUpdateTimestamp() { let timestamp = 0; for (const binding of Object.values(this.bindings)) { if (binding instanceof TextureView) { timestamp = Math.max(timestamp, binding.texture.updateTimestamp); } else if (binding instanceof Buffer2 || binding instanceof Texture) { timestamp = Math.max(timestamp, binding.updateTimestamp); } else if (!(binding instanceof Sampler)) { timestamp = Math.max(timestamp, binding.buffer.updateTimestamp); } } return timestamp; } _setGeometryAttributes(gpuGeometry) { const attributes = { ...gpuGeometry.attributes }; for (const [attributeName] of Object.entries(attributes)) { if (!this.pipeline.shaderLayout.attributes.find((layout) => layout.name === attributeName) && attributeName !== "positions") { delete attributes[attributeName]; } } this.vertexCount = gpuGeometry.vertexCount; this.setIndexBuffer(gpuGeometry.indices || null); this.setAttributes(gpuGeometry.attributes, { disableWarnings: true }); this.setAttributes(attributes, { disableWarnings: this.props.disableWarnings }); this.setNeedsRedraw("geometry attributes"); } _setPipelineNeedsUpdate(reason) { this._pipelineNeedsUpdate ||= reason; this.setNeedsRedraw(reason); } _updatePipeline() { if (this._pipelineNeedsUpdate) { let prevShaderVs = null; let prevShaderFs = null; if (this.pipeline) { log.log(1, `Model ${this.id}: Recreating pipeline because "${this._pipelineNeedsUpdate}".`)(); prevShaderVs = this.pipeline.vs; prevShaderFs = this.pipeline.fs; } this._pipelineNeedsUpdate = false; const vs7 = this.shaderFactory.createShader({ id: `${this.id}-vertex`, stage: "vertex", source: this.source || this.vs, debug: this.props.debugShaders }); let fs5 = null; if (this.source) { fs5 = vs7; } else if (this.fs) { fs5 = this.shaderFactory.createShader({ id: `${this.id}-fragment`, stage: "fragment", source: this.source || this.fs, debug: this.props.debugShaders }); } this.pipeline = this.pipelineFactory.createRenderPipeline({ ...this.props, bufferLayout: this.bufferLayout, topology: this.topology, parameters: this.parameters, vs: vs7, fs: fs5 }); this._attributeInfos = getAttributeInfosFromLayouts(this.pipeline.shaderLayout, this.bufferLayout); if (prevShaderVs) this.shaderFactory.release(prevShaderVs); if (prevShaderFs) this.shaderFactory.release(prevShaderFs); } return this.pipeline; } _lastLogTime = 0; _logOpen = false; _logDrawCallStart() { const logDrawTimeout = log.level > 3 ? 0 : LOG_DRAW_TIMEOUT; if (log.level < 2 || Date.now() - this._lastLogTime < logDrawTimeout) { return; } this._lastLogTime = Date.now(); this._logOpen = true; log.group(LOG_DRAW_PRIORITY, `>>> DRAWING MODEL ${this.id}`, { collapsed: log.level <= 2 })(); } _logDrawCallEnd() { if (this._logOpen) { const shaderLayoutTable = getDebugTableForShaderLayout(this.pipeline.shaderLayout, this.id); log.table(LOG_DRAW_PRIORITY, shaderLayoutTable)(); const uniformTable = this.shaderInputs.getDebugTable(); for (const [name2, value] of Object.entries(this.uniforms)) { uniformTable[name2] = { value }; } log.table(LOG_DRAW_PRIORITY, uniformTable)(); const attributeTable = this._getAttributeDebugTable(); log.table(LOG_DRAW_PRIORITY, this._attributeInfos)(); log.table(LOG_DRAW_PRIORITY, attributeTable)(); log.groupEnd(LOG_DRAW_PRIORITY)(); this._logOpen = false; } } _drawCount = 0; _logFramebuffer(renderPass) { const debugFramebuffers = log.get("framebuffer"); this._drawCount++; if (!debugFramebuffers || this._drawCount++ > 3 && this._drawCount % 60) { return; } const framebuffer = renderPass.props.framebuffer; if (framebuffer) { debugFramebuffer(framebuffer, { id: framebuffer.id, minimap: true }); } } _getAttributeDebugTable() { const table = {}; for (const [name2, attributeInfo] of Object.entries(this._attributeInfos)) { table[attributeInfo.location] = { name: name2, type: attributeInfo.shaderType, values: this._getBufferOrConstantValues(this.vertexArray.attributes[attributeInfo.location], attributeInfo.bufferDataType) }; } if (this.vertexArray.indexBuffer) { const { indexBuffer } = this.vertexArray; const values = indexBuffer.indexType === "uint32" ? new Uint32Array(indexBuffer.debugData) : new Uint16Array(indexBuffer.debugData); table.indices = { name: "indices", type: indexBuffer.indexType, values: values.toString() }; } return table; } _getBufferOrConstantValues(attribute, dataType) { const TypedArrayConstructor = getTypedArrayFromDataType(dataType); const typedArray = attribute instanceof Buffer2 ? new TypedArrayConstructor(attribute.debugData) : attribute; return typedArray.toString(); } }; var Model = _Model; __publicField(Model, "defaultProps", { ...RenderPipeline.defaultProps, source: null, vs: null, fs: null, id: "unnamed", handle: void 0, userData: {}, defines: {}, modules: [], moduleSettings: void 0, geometry: null, indexBuffer: null, attributes: {}, constantAttributes: {}, varyings: [], isInstanced: void 0, instanceCount: 0, vertexCount: 0, shaderInputs: void 0, pipelineFactory: void 0, shaderFactory: void 0, transformFeedback: void 0, shaderAssembler: ShaderAssembler.getDefaultShaderAssembler(), debugShaders: void 0, disableWarnings: void 0 }); function mergeBufferLayouts(layouts1, layouts2) { const layouts = [...layouts1]; for (const attribute of layouts2) { const index2 = layouts.findIndex((attribute2) => attribute2.name === attribute.name); if (index2 < 0) { layouts.push(attribute); } else { layouts[index2] = attribute; } } return layouts; } function getPlatformInfo(device) { return { type: device.type, shaderLanguage: device.info.shadingLanguage, shaderLanguageVersion: device.info.shadingLanguageVersion, gpu: device.info.gpu, features: device.features }; } function getAttributeNames(bufferLayout) { return bufferLayout.attributes ? bufferLayout.attributes?.map((layout) => layout.attribute) : [bufferLayout.name]; } // ../../node_modules/@luma.gl/engine/dist/transform/buffer-transform.js var BufferTransform = class { device; model; transformFeedback; static isSupported(device) { return device?.info?.type === "webgl"; } constructor(device, props = Model.defaultProps) { assert2(BufferTransform.isSupported(device), "BufferTransform not yet implemented on WebGPU"); this.device = device; this.model = new Model(this.device, { id: props.id || "buffer-transform-model", fs: props.fs || getPassthroughFS(), topology: props.topology || "point-list", ...props }); this.transformFeedback = this.device.createTransformFeedback({ layout: this.model.pipeline.shaderLayout, buffers: props.feedbackBuffers }); this.model.setTransformFeedback(this.transformFeedback); Object.seal(this); } destroy() { if (this.model) { this.model.destroy(); } } delete() { this.destroy(); } run(options) { const renderPass = this.device.beginRenderPass(options); this.model.draw(renderPass); renderPass.end(); } update(...args) { console.warn("TextureTransform#update() not implemented"); } getBuffer(varyingName) { return this.transformFeedback.getBuffer(varyingName); } readAsync(varyingName) { const result = this.getBuffer(varyingName); if (result instanceof Buffer2) { return result.readAsync(); } const { buffer, byteOffset = 0, byteLength = buffer.byteLength } = result; return buffer.readAsync(byteOffset, byteLength); } }; // ../../node_modules/@luma.gl/engine/dist/transform/texture-transform.js var FS_OUTPUT_VARIABLE = "transform_output"; var TextureTransform = class { device; model; sampler; currentIndex = 0; samplerTextureMap = null; bindings = []; resources = {}; constructor(device, props) { this.device = device; this.sampler = device.createSampler({ addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge", minFilter: "nearest", magFilter: "nearest", mipmapFilter: "nearest" }); this.model = new Model(this.device, { id: props.id || "texture-transform-model", fs: props.fs || getPassthroughFS({ input: props.targetTextureVarying, inputChannels: props.targetTextureChannels, output: FS_OUTPUT_VARIABLE }), vertexCount: props.vertexCount, ...props }); this._initialize(props); Object.seal(this); } destroy() { } delete() { this.destroy(); } run(options) { const { framebuffer } = this.bindings[this.currentIndex]; const renderPass = this.device.beginRenderPass({ framebuffer, ...options }); this.model.draw(renderPass); renderPass.end(); } update(...args) { console.warn("TextureTransform#update() not implemented"); } getData({ packed = false } = {}) { throw new Error("getData() not implemented"); } getTargetTexture() { const { targetTexture } = this.bindings[this.currentIndex]; return targetTexture; } getFramebuffer() { const currentResources = this.bindings[this.currentIndex]; return currentResources.framebuffer; } _initialize(props) { this._updateBindings(props); } _updateBindings(props) { this.bindings[this.currentIndex] = this._updateBinding(this.bindings[this.currentIndex], props); } _updateBinding(binding, { sourceBuffers, sourceTextures, targetTexture }) { if (!binding) { binding = { sourceBuffers: {}, sourceTextures: {}, targetTexture: null }; } Object.assign(binding.sourceTextures, sourceTextures); Object.assign(binding.sourceBuffers, sourceBuffers); if (targetTexture) { binding.targetTexture = targetTexture; const { width, height } = targetTexture; if (binding.framebuffer) { binding.framebuffer.destroy(); } binding.framebuffer = this.device.createFramebuffer({ id: "transform-framebuffer", width, height, colorAttachments: [targetTexture] }); binding.framebuffer.resize({ width, height }); } return binding; } _setSourceTextureParameters() { const index2 = this.currentIndex; const { sourceTextures } = this.bindings[index2]; for (const name2 in sourceTextures) { sourceTextures[name2].sampler = this.sampler; } } }; // ../../node_modules/@luma.gl/engine/dist/geometry/geometry.js var Geometry = class { id; topology; vertexCount; indices; attributes; userData = {}; constructor(props) { const { attributes = {}, indices = null, vertexCount = null } = props; this.id = props.id || uid("geometry"); this.topology = props.topology; if (indices) { this.indices = ArrayBuffer.isView(indices) ? { value: indices, size: 1 } : indices; } this.attributes = {}; for (const [attributeName, attributeValue] of Object.entries(attributes)) { const attribute = ArrayBuffer.isView(attributeValue) ? { value: attributeValue } : attributeValue; assert2(ArrayBuffer.isView(attribute.value), `${this._print(attributeName)}: must be typed array or object with value as typed array`); if ((attributeName === "POSITION" || attributeName === "positions") && !attribute.size) { attribute.size = 3; } if (attributeName === "indices") { assert2(!this.indices); this.indices = attribute; } else { this.attributes[attributeName] = attribute; } } if (this.indices && this.indices.isIndexed !== void 0) { this.indices = Object.assign({}, this.indices); delete this.indices.isIndexed; } this.vertexCount = vertexCount || this._calculateVertexCount(this.attributes, this.indices); } getVertexCount() { return this.vertexCount; } getAttributes() { return this.indices ? { indices: this.indices, ...this.attributes } : this.attributes; } _print(attributeName) { return `Geometry ${this.id} attribute ${attributeName}`; } _setAttributes(attributes, indices) { return this; } _calculateVertexCount(attributes, indices) { if (indices) { return indices.value.length; } let vertexCount = Infinity; for (const attribute of Object.values(attributes)) { const { value, size, constant } = attribute; if (!constant && value && size >= 1) { vertexCount = Math.min(vertexCount, value.length / size); } } assert2(Number.isFinite(vertexCount)); return vertexCount; } }; // ../../node_modules/@luma.gl/engine/dist/lib/clip-space.js var CLIPSPACE_VERTEX_SHADER = `#version 300 es in vec2 aClipSpacePosition; in vec2 aTexCoord; in vec2 aCoordinate; out vec2 position; out vec2 coordinate; out vec2 uv; void main(void) { gl_Position = vec4(aClipSpacePosition, 0., 1.); position = aClipSpacePosition; coordinate = aCoordinate; uv = aTexCoord; } `; var POSITIONS = [-1, -1, 1, -1, -1, 1, 1, 1]; var ClipSpace = class extends Model { constructor(device, opts) { const TEX_COORDS = POSITIONS.map((coord) => coord === -1 ? 0 : coord); super(device, { ...opts, vs: CLIPSPACE_VERTEX_SHADER, vertexCount: 4, geometry: new Geometry({ topology: "triangle-strip", vertexCount: 4, attributes: { aClipSpacePosition: { size: 2, value: new Float32Array(POSITIONS) }, aTexCoord: { size: 2, value: new Float32Array(TEX_COORDS) }, aCoordinate: { size: 2, value: new Float32Array(TEX_COORDS) } } }) }); } }; // ../../node_modules/@luma.gl/engine/dist/scenegraph/scenegraph-node.js var ScenegraphNode = class { id; matrix = new Matrix4(); display = true; position = new Vector3(); rotation = new Vector3(); scale = new Vector3(1, 1, 1); userData = {}; props = {}; constructor(props = {}) { const { id } = props; this.id = id || uid(this.constructor.name); this._setScenegraphNodeProps(props); } getBounds() { return null; } destroy() { } delete() { this.destroy(); } setProps(props) { this._setScenegraphNodeProps(props); return this; } toString() { return `{type: ScenegraphNode, id: ${this.id})}`; } setPosition(position) { assert2(position.length === 3, "setPosition requires vector argument"); this.position = position; return this; } setRotation(rotation) { assert2(rotation.length === 3, "setRotation requires vector argument"); this.rotation = rotation; return this; } setScale(scale5) { assert2(scale5.length === 3, "setScale requires vector argument"); this.scale = scale5; return this; } setMatrix(matrix, copyMatrix = true) { if (copyMatrix) { this.matrix.copy(matrix); } else { this.matrix = matrix; } } setMatrixComponents(components) { const { position, rotation, scale: scale5, update = true } = components; if (position) { this.setPosition(position); } if (rotation) { this.setRotation(rotation); } if (scale5) { this.setScale(scale5); } if (update) { this.updateMatrix(); } return this; } updateMatrix() { const pos = this.position; const rot = this.rotation; const scale5 = this.scale; this.matrix.identity(); this.matrix.translate(pos); this.matrix.rotateXYZ(rot); this.matrix.scale(scale5); return this; } update(options = {}) { const { position, rotation, scale: scale5 } = options; if (position) { this.setPosition(position); } if (rotation) { this.setRotation(rotation); } if (scale5) { this.setScale(scale5); } this.updateMatrix(); return this; } getCoordinateUniforms(viewMatrix2, modelMatrix) { assert2(viewMatrix2); modelMatrix = modelMatrix || this.matrix; const worldMatrix = new Matrix4(viewMatrix2).multiplyRight(modelMatrix); const worldInverse = worldMatrix.invert(); const worldInverseTranspose = worldInverse.transpose(); return { viewMatrix: viewMatrix2, modelMatrix, objectMatrix: modelMatrix, worldMatrix, worldInverseMatrix: worldInverse, worldInverseTransposeMatrix: worldInverseTranspose }; } _setScenegraphNodeProps(props) { if ("display" in props) { this.display = props.display; } if ("position" in props) { this.setPosition(props.position); } if ("rotation" in props) { this.setRotation(props.rotation); } if ("scale" in props) { this.setScale(props.scale); } if ("matrix" in props) { this.setMatrix(props.matrix); } Object.assign(this.props, props); } }; // ../../node_modules/@luma.gl/engine/dist/scenegraph/group-node.js var GroupNode = class extends ScenegraphNode { children; constructor(props = {}) { props = Array.isArray(props) ? { children: props } : props; const { children = [] } = props; log.assert(children.every((child) => child instanceof ScenegraphNode), "every child must an instance of ScenegraphNode"); super(props); this.children = children; } getBounds() { const result = [ [Infinity, Infinity, Infinity], [-Infinity, -Infinity, -Infinity] ]; this.traverse((node, { worldMatrix }) => { const bounds = node.getBounds(); if (!bounds) { return; } const [min4, max4] = bounds; const center = new Vector3(min4).add(max4).divide([2, 2, 2]); worldMatrix.transformAsPoint(center, center); const halfSize = new Vector3(max4).subtract(min4).divide([2, 2, 2]); worldMatrix.transformAsVector(halfSize, halfSize); for (let v = 0; v < 8; v++) { const position = new Vector3(v & 1 ? -1 : 1, v & 2 ? -1 : 1, v & 4 ? -1 : 1).multiply(halfSize).add(center); for (let i = 0; i < 3; i++) { result[0][i] = Math.min(result[0][i], position[i]); result[1][i] = Math.max(result[1][i], position[i]); } } }); if (!Number.isFinite(result[0][0])) { return null; } return result; } destroy() { this.children.forEach((child) => child.destroy()); this.removeAll(); super.destroy(); } add(...children) { for (const child of children) { if (Array.isArray(child)) { this.add(...child); } else { this.children.push(child); } } return this; } remove(child) { const children = this.children; const indexOf = children.indexOf(child); if (indexOf > -1) { children.splice(indexOf, 1); } return this; } removeAll() { this.children = []; return this; } traverse(visitor, { worldMatrix = new Matrix4() } = {}) { const modelMatrix = new Matrix4(worldMatrix).multiplyRight(this.matrix); for (const child of this.children) { if (child instanceof GroupNode) { child.traverse(visitor, { worldMatrix: modelMatrix }); } else { visitor(child, { worldMatrix: modelMatrix }); } } } }; // ../../node_modules/@luma.gl/engine/dist/scenegraph/model-node.js var ModelNode = class extends ScenegraphNode { model; bounds = null; managedResources; constructor(props) { super(props); this.model = props.model; this.managedResources = props.managedResources || []; this.bounds = props.bounds || null; this.setProps(props); } getBounds() { return this.bounds; } destroy() { if (this.model) { this.model.destroy(); this.model = null; } this.managedResources.forEach((resource) => resource.destroy()); this.managedResources = []; } draw(renderPass) { return this.model.draw(renderPass); } }; // ../../node_modules/@luma.gl/engine/dist/geometries/cube-geometry.js var CubeGeometry = class extends Geometry { constructor(props = {}) { const { id = uid("cube-geometry"), indices = true } = props; super(indices ? { ...props, id, topology: "triangle-list", indices: { size: 1, value: CUBE_INDICES }, attributes: { ...ATTRIBUTES, ...props.attributes } } : { ...props, id, topology: "triangle-list", indices: void 0, attributes: { ...NON_INDEXED_ATTRIBUTES, ...props.attributes } }); } }; var CUBE_INDICES = new Uint16Array([ 0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23 ]); var CUBE_POSITIONS = new Float32Array([ -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1 ]); var CUBE_NORMALS = new Float32Array([ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0 ]); var CUBE_TEX_COORDS = new Float32Array([ 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1 ]); var CUBE_NON_INDEXED_POSITIONS = new Float32Array([ 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1 ]); var CUBE_NON_INDEXED_TEX_COORDS = new Float32Array([ 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0 ]); var CUBE_NON_INDEXED_COLORS = new Float32Array([ 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1 ]); var ATTRIBUTES = { POSITION: { size: 3, value: CUBE_POSITIONS }, NORMAL: { size: 3, value: CUBE_NORMALS }, TEXCOORD_0: { size: 2, value: CUBE_TEX_COORDS } }; var NON_INDEXED_ATTRIBUTES = { POSITION: { size: 3, value: CUBE_NON_INDEXED_POSITIONS }, TEXCOORD_0: { size: 2, value: CUBE_NON_INDEXED_TEX_COORDS }, COLOR_0: { size: 3, value: CUBE_NON_INDEXED_COLORS } }; // ../../node_modules/@luma.gl/engine/dist/geometries/sphere-geometry.js var SphereGeometry = class extends Geometry { constructor(props = {}) { const { id = uid("sphere-geometry") } = props; const { indices, attributes } = tesselateSphere(props); super({ ...props, id, topology: "triangle-list", indices, attributes: { ...attributes, ...props.attributes } }); } }; function tesselateSphere(props) { const { nlat = 10, nlong = 10 } = props; const startLat = 0; const endLat = Math.PI; const latRange = endLat - startLat; const startLong = 0; const endLong = 2 * Math.PI; const longRange = endLong - startLong; const numVertices = (nlat + 1) * (nlong + 1); const radius = (n1, n2, n3, u, v) => props.radius || 1; const positions = new Float32Array(numVertices * 3); const normals = new Float32Array(numVertices * 3); const texCoords = new Float32Array(numVertices * 2); const IndexType = numVertices > 65535 ? Uint32Array : Uint16Array; const indices = new IndexType(nlat * nlong * 6); for (let y = 0; y <= nlat; y++) { for (let x = 0; x <= nlong; x++) { const u = x / nlong; const v = y / nlat; const index2 = x + y * (nlong + 1); const i2 = index2 * 2; const i3 = index2 * 3; const theta = longRange * u; const phi = latRange * v; const sinTheta = Math.sin(theta); const cosTheta = Math.cos(theta); const sinPhi = Math.sin(phi); const cosPhi = Math.cos(phi); const ux = cosTheta * sinPhi; const uy = cosPhi; const uz = sinTheta * sinPhi; const r = radius(ux, uy, uz, u, v); positions[i3 + 0] = r * ux; positions[i3 + 1] = r * uy; positions[i3 + 2] = r * uz; normals[i3 + 0] = ux; normals[i3 + 1] = uy; normals[i3 + 2] = uz; texCoords[i2 + 0] = u; texCoords[i2 + 1] = 1 - v; } } const numVertsAround = nlong + 1; for (let x = 0; x < nlong; x++) { for (let y = 0; y < nlat; y++) { const index2 = (x * nlat + y) * 6; indices[index2 + 0] = y * numVertsAround + x; indices[index2 + 1] = y * numVertsAround + x + 1; indices[index2 + 2] = (y + 1) * numVertsAround + x; indices[index2 + 3] = (y + 1) * numVertsAround + x; indices[index2 + 4] = y * numVertsAround + x + 1; indices[index2 + 5] = (y + 1) * numVertsAround + x + 1; } } return { indices: { size: 1, value: indices }, attributes: { POSITION: { size: 3, value: positions }, NORMAL: { size: 3, value: normals }, TEXCOORD_0: { size: 2, value: texCoords } } }; } // src/scripting/lumagl.ts var { stats, registerDevices, getAvailableDevices, getSupportedDevices, setDefaultDeviceProps, attachDevice, createDevice, enforceWebGL2 } = luma; // src/scripting/loadersgl.ts var loadersgl_exports = {}; __export(loadersgl_exports, { fetchFile: () => fetchFile, load: () => load, parse: () => parse, registerLoaders: () => registerLoaders }); // ../../node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/assert.js function assert5(condition, message2) { if (!condition) { throw new Error(message2 || "loader assertion failed."); } } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/env-utils/globals.js var globals = { self: typeof self !== "undefined" && self, window: typeof window !== "undefined" && window, global: typeof global !== "undefined" && global, document: typeof document !== "undefined" && document }; var self_ = globals.self || globals.window || globals.global || {}; var window_2 = globals.window || globals.self || globals.global || {}; var global_2 = globals.global || globals.self || globals.window || {}; var document_2 = globals.document || {}; var isBrowser2 = Boolean(typeof process !== "object" || String(process) !== "[object process]" || process.browser); var matches = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version); var nodeVersion = matches && parseFloat(matches[1]) || 0; // ../../node_modules/@loaders.gl/loader-utils/dist/lib/option-utils/merge-loader-options.js function mergeLoaderOptions(baseOptions, newOptions) { return mergeOptionsRecursively(baseOptions || {}, newOptions); } function mergeOptionsRecursively(baseOptions, newOptions, level = 0) { if (level > 3) { return newOptions; } const options = { ...baseOptions }; for (const [key, newValue] of Object.entries(newOptions)) { if (newValue && typeof newValue === "object" && !Array.isArray(newValue)) { options[key] = mergeOptionsRecursively(options[key] || {}, newOptions[key], level + 1); } else { options[key] = newOptions[key]; } } return options; } // ../../node_modules/@loaders.gl/worker-utils/dist/lib/env-utils/version.js var NPM_TAG = "latest"; function getVersion() { if (!globalThis._loadersgl_?.version) { globalThis._loadersgl_ = globalThis._loadersgl_ || {}; if (false) { console.warn("loaders.gl: The __VERSION__ variable is not injected using babel plugin. Latest unstable workers would be fetched from the CDN."); globalThis._loadersgl_.version = NPM_TAG; } else { globalThis._loadersgl_.version = "4.2.0-beta.2"; } } return globalThis._loadersgl_.version; } var VERSION3 = getVersion(); // ../../node_modules/@loaders.gl/worker-utils/dist/lib/env-utils/assert.js function assert6(condition, message2) { if (!condition) { throw new Error(message2 || "loaders.gl assertion failed."); } } // ../../node_modules/@loaders.gl/worker-utils/dist/lib/env-utils/globals.js var globals2 = { self: typeof self !== "undefined" && self, window: typeof window !== "undefined" && window, global: typeof global !== "undefined" && global, document: typeof document !== "undefined" && document }; var self_2 = globals2.self || globals2.window || globals2.global || {}; var window_3 = globals2.window || globals2.self || globals2.global || {}; var global_3 = globals2.global || globals2.self || globals2.window || {}; var document_3 = globals2.document || {}; var isBrowser3 = typeof process !== "object" || String(process) !== "[object process]" || process.browser; var isMobile2 = typeof window !== "undefined" && typeof window.orientation !== "undefined"; var matches2 = typeof process !== "undefined" && process.version && /v([0-9]*)/.exec(process.version); var nodeVersion2 = matches2 && parseFloat(matches2[1]) || 0; // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-farm/worker-job.js var WorkerJob = class { name; workerThread; isRunning = true; result; _resolve = () => { }; _reject = () => { }; constructor(jobName, workerThread) { this.name = jobName; this.workerThread = workerThread; this.result = new Promise((resolve2, reject) => { this._resolve = resolve2; this._reject = reject; }); } postMessage(type, payload) { this.workerThread.postMessage({ source: "loaders.gl", type, payload }); } done(value) { assert6(this.isRunning); this.isRunning = false; this._resolve(value); } error(error) { assert6(this.isRunning); this.isRunning = false; this._reject(error); } }; // ../../node_modules/@loaders.gl/worker-utils/dist/lib/node/worker_threads-browser.js var NodeWorker = class { terminate() { } }; // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-utils/get-loadable-worker-url.js var workerURLCache = /* @__PURE__ */ new Map(); function getLoadableWorkerURL(props) { assert6(props.source && !props.url || !props.source && props.url); let workerURL = workerURLCache.get(props.source || props.url); if (!workerURL) { if (props.url) { workerURL = getLoadableWorkerURLFromURL(props.url); workerURLCache.set(props.url, workerURL); } if (props.source) { workerURL = getLoadableWorkerURLFromSource(props.source); workerURLCache.set(props.source, workerURL); } } assert6(workerURL); return workerURL; } function getLoadableWorkerURLFromURL(url) { if (!url.startsWith("http")) { return url; } const workerSource = buildScriptSource(url); return getLoadableWorkerURLFromSource(workerSource); } function getLoadableWorkerURLFromSource(workerSource) { const blob = new Blob([workerSource], { type: "application/javascript" }); return URL.createObjectURL(blob); } function buildScriptSource(workerUrl) { return `try { importScripts('${workerUrl}'); } catch (error) { console.error(error); throw error; }`; } // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-utils/get-transfer-list.js function getTransferList(object, recursive = true, transfers) { const transfersSet = transfers || /* @__PURE__ */ new Set(); if (!object) { } else if (isTransferable(object)) { transfersSet.add(object); } else if (isTransferable(object.buffer)) { transfersSet.add(object.buffer); } else if (ArrayBuffer.isView(object)) { } else if (recursive && typeof object === "object") { for (const key in object) { getTransferList(object[key], recursive, transfersSet); } } return transfers === void 0 ? Array.from(transfersSet) : []; } function isTransferable(object) { if (!object) { return false; } if (object instanceof ArrayBuffer) { return true; } if (typeof MessagePort !== "undefined" && object instanceof MessagePort) { return true; } if (typeof ImageBitmap !== "undefined" && object instanceof ImageBitmap) { return true; } if (typeof OffscreenCanvas !== "undefined" && object instanceof OffscreenCanvas) { return true; } return false; } // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-farm/worker-thread.js var NOOP = () => { }; var WorkerThread = class { name; source; url; terminated = false; worker; onMessage; onError; _loadableURL = ""; static isSupported() { return typeof Worker !== "undefined" && isBrowser3 || typeof NodeWorker !== "undefined" && !isBrowser3; } constructor(props) { const { name: name2, source, url } = props; assert6(source || url); this.name = name2; this.source = source; this.url = url; this.onMessage = NOOP; this.onError = (error) => console.log(error); this.worker = isBrowser3 ? this._createBrowserWorker() : this._createNodeWorker(); } destroy() { this.onMessage = NOOP; this.onError = NOOP; this.worker.terminate(); this.terminated = true; } get isRunning() { return Boolean(this.onMessage); } postMessage(data, transferList) { transferList = transferList || getTransferList(data); this.worker.postMessage(data, transferList); } _getErrorFromErrorEvent(event) { let message2 = "Failed to load "; message2 += `worker ${this.name} from ${this.url}. `; if (event.message) { message2 += `${event.message} in `; } if (event.lineno) { message2 += `:${event.lineno}:${event.colno}`; } return new Error(message2); } _createBrowserWorker() { this._loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url }); const worker = new Worker(this._loadableURL, { name: this.name }); worker.onmessage = (event) => { if (!event.data) { this.onError(new Error("No data received")); } else { this.onMessage(event.data); } }; worker.onerror = (error) => { this.onError(this._getErrorFromErrorEvent(error)); this.terminated = true; }; worker.onmessageerror = (event) => console.error(event); return worker; } _createNodeWorker() { let worker; if (this.url) { const absolute = this.url.includes(":/") || this.url.startsWith("/"); const url = absolute ? this.url : `./${this.url}`; worker = new NodeWorker(url, { eval: false }); } else if (this.source) { worker = new NodeWorker(this.source, { eval: true }); } else { throw new Error("no worker"); } worker.on("message", (data) => { this.onMessage(data); }); worker.on("error", (error) => { this.onError(error); }); worker.on("exit", (code) => { }); return worker; } }; // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-farm/worker-pool.js var WorkerPool = class { name = "unnamed"; source; url; maxConcurrency = 1; maxMobileConcurrency = 1; onDebug = () => { }; reuseWorkers = true; props = {}; jobQueue = []; idleQueue = []; count = 0; isDestroyed = false; static isSupported() { return WorkerThread.isSupported(); } constructor(props) { this.source = props.source; this.url = props.url; this.setProps(props); } destroy() { this.idleQueue.forEach((worker) => worker.destroy()); this.isDestroyed = true; } setProps(props) { this.props = { ...this.props, ...props }; if (props.name !== void 0) { this.name = props.name; } if (props.maxConcurrency !== void 0) { this.maxConcurrency = props.maxConcurrency; } if (props.maxMobileConcurrency !== void 0) { this.maxMobileConcurrency = props.maxMobileConcurrency; } if (props.reuseWorkers !== void 0) { this.reuseWorkers = props.reuseWorkers; } if (props.onDebug !== void 0) { this.onDebug = props.onDebug; } } async startJob(name2, onMessage2 = (job, type, data) => job.done(data), onError = (job, error) => job.error(error)) { const startPromise = new Promise((onStart) => { this.jobQueue.push({ name: name2, onMessage: onMessage2, onError, onStart }); return this; }); this._startQueuedJob(); return await startPromise; } async _startQueuedJob() { if (!this.jobQueue.length) { return; } const workerThread = this._getAvailableWorker(); if (!workerThread) { return; } const queuedJob = this.jobQueue.shift(); if (queuedJob) { this.onDebug({ message: "Starting job", name: queuedJob.name, workerThread, backlog: this.jobQueue.length }); const job = new WorkerJob(queuedJob.name, workerThread); workerThread.onMessage = (data) => queuedJob.onMessage(job, data.type, data.payload); workerThread.onError = (error) => queuedJob.onError(job, error); queuedJob.onStart(job); try { await job.result; } catch (error) { console.error(`Worker exception: ${error}`); } finally { this.returnWorkerToQueue(workerThread); } } } returnWorkerToQueue(worker) { const shouldDestroyWorker = !isBrowser3 || this.isDestroyed || !this.reuseWorkers || this.count > this._getMaxConcurrency(); if (shouldDestroyWorker) { worker.destroy(); this.count--; } else { this.idleQueue.push(worker); } if (!this.isDestroyed) { this._startQueuedJob(); } } _getAvailableWorker() { if (this.idleQueue.length > 0) { return this.idleQueue.shift() || null; } if (this.count < this._getMaxConcurrency()) { this.count++; const name2 = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`; return new WorkerThread({ name: name2, source: this.source, url: this.url }); } return null; } _getMaxConcurrency() { return isMobile2 ? this.maxMobileConcurrency : this.maxConcurrency; } }; // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-farm/worker-farm.js var DEFAULT_PROPS = { maxConcurrency: 3, maxMobileConcurrency: 1, reuseWorkers: true, onDebug: () => { } }; var _WorkerFarm = class { props; workerPools = /* @__PURE__ */ new Map(); static isSupported() { return WorkerThread.isSupported(); } static getWorkerFarm(props = {}) { _WorkerFarm._workerFarm = _WorkerFarm._workerFarm || new _WorkerFarm({}); _WorkerFarm._workerFarm.setProps(props); return _WorkerFarm._workerFarm; } constructor(props) { this.props = { ...DEFAULT_PROPS }; this.setProps(props); this.workerPools = /* @__PURE__ */ new Map(); } destroy() { for (const workerPool of this.workerPools.values()) { workerPool.destroy(); } this.workerPools = /* @__PURE__ */ new Map(); } setProps(props) { this.props = { ...this.props, ...props }; for (const workerPool of this.workerPools.values()) { workerPool.setProps(this._getWorkerPoolProps()); } } getWorkerPool(options) { const { name: name2, source, url } = options; let workerPool = this.workerPools.get(name2); if (!workerPool) { workerPool = new WorkerPool({ name: name2, source, url }); workerPool.setProps(this._getWorkerPoolProps()); this.workerPools.set(name2, workerPool); } return workerPool; } _getWorkerPoolProps() { return { maxConcurrency: this.props.maxConcurrency, maxMobileConcurrency: this.props.maxMobileConcurrency, reuseWorkers: this.props.reuseWorkers, onDebug: this.props.onDebug }; } }; var WorkerFarm = _WorkerFarm; __publicField(WorkerFarm, "_workerFarm"); // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-api/get-worker-url.js function getWorkerURL(worker, options = {}) { const workerOptions = options[worker.id] || {}; const workerFile = isBrowser3 ? `${worker.id}-worker.js` : `${worker.id}-worker-node.js`; let url = workerOptions.workerUrl; if (!url && worker.id === "compression") { url = options.workerUrl; } if (options._workerType === "test") { if (isBrowser3) { url = `modules/${worker.module}/dist/${workerFile}`; } else { url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`; } } if (!url) { let version = worker.version; if (version === "latest") { version = NPM_TAG; } const versionTag = version ? `@${version}` : ""; url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`; } assert6(url); return url; } // ../../node_modules/@loaders.gl/worker-utils/dist/lib/worker-api/validate-worker-version.js function validateWorkerVersion(worker, coreVersion = VERSION3) { assert6(worker, "no worker provided"); const workerVersion = worker.version; if (!coreVersion || !workerVersion) { return false; } return true; } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/worker-loader-utils/parse-with-worker.js function canParseWithWorker(loader, options) { if (!WorkerFarm.isSupported()) { return false; } if (!isBrowser3 && !options?._nodeWorkers) { return false; } return loader.worker && options?.worker; } async function parseWithWorker(loader, data, options, context, parseOnMainThread) { const name2 = loader.id; const url = getWorkerURL(loader, options); const workerFarm = WorkerFarm.getWorkerFarm(options); const workerPool = workerFarm.getWorkerPool({ name: name2, url }); options = JSON.parse(JSON.stringify(options)); context = JSON.parse(JSON.stringify(context || {})); const job = await workerPool.startJob( "process-on-worker", onMessage.bind(null, parseOnMainThread) ); job.postMessage("process", { input: data, options, context }); const result = await job.result; return await result.result; } async function onMessage(parseOnMainThread, job, type, payload) { switch (type) { case "done": job.done(payload); break; case "error": job.error(new Error(payload.error)); break; case "process": const { id, input, options } = payload; try { const result = await parseOnMainThread(input, options); job.postMessage("done", { id, result }); } catch (error) { const message2 = error instanceof Error ? error.message : "unknown error"; job.postMessage("error", { id, error: message2 }); } break; default: console.warn(`parse-with-worker unknown message ${type}`); } } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/binary-utils/array-buffer-utils.js function compareArrayBuffers(arrayBuffer1, arrayBuffer2, byteLength) { byteLength = byteLength || arrayBuffer1.byteLength; if (arrayBuffer1.byteLength < byteLength || arrayBuffer2.byteLength < byteLength) { return false; } const array1 = new Uint8Array(arrayBuffer1); const array2 = new Uint8Array(arrayBuffer2); for (let i = 0; i < array1.length; ++i) { if (array1[i] !== array2[i]) { return false; } } return true; } function concatenateArrayBuffers(...sources) { return concatenateArrayBuffersFromArray(sources); } function concatenateArrayBuffersFromArray(sources) { const sourceArrays = sources.map((source2) => source2 instanceof ArrayBuffer ? new Uint8Array(source2) : source2); const byteLength = sourceArrays.reduce((length4, typedArray) => length4 + typedArray.byteLength, 0); const result = new Uint8Array(byteLength); let offset = 0; for (const sourceArray of sourceArrays) { result.set(sourceArray, offset); offset += sourceArray.byteLength; } return result.buffer; } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/iterators/async-iteration.js async function concatenateArrayBuffersAsync(asyncIterator) { const arrayBuffers = []; for await (const chunk of asyncIterator) { arrayBuffers.push(chunk); } return concatenateArrayBuffers(...arrayBuffers); } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/path-utils/file-aliases.js var pathPrefix2 = ""; var fileAliases = {}; function resolvePath(filename2) { for (const alias in fileAliases) { if (filename2.startsWith(alias)) { const replacement = fileAliases[alias]; filename2 = filename2.replace(alias, replacement); } } if (!filename2.startsWith("http://") && !filename2.startsWith("https://")) { filename2 = `${pathPrefix2}${filename2}`; } return filename2; } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/node/buffer.browser.js function toArrayBuffer(buffer) { return buffer; } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/binary-utils/memory-conversion-utils.js function isBuffer(value) { return value && typeof value === "object" && value.isBuffer; } function toArrayBuffer2(data) { if (isBuffer(data)) { return toArrayBuffer(data); } if (data instanceof ArrayBuffer) { return data; } if (ArrayBuffer.isView(data)) { if (data.byteOffset === 0 && data.byteLength === data.buffer.byteLength) { return data.buffer; } return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength); } if (typeof data === "string") { const text = data; const uint8Array = new TextEncoder().encode(text); return uint8Array.buffer; } if (data && typeof data === "object" && data._toArrayBuffer) { return data._toArrayBuffer(); } throw new Error("toArrayBuffer"); } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/path-utils/path.js var path_exports = {}; __export(path_exports, { dirname: () => dirname, filename: () => filename, join: () => join, resolve: () => resolve }); // ../../node_modules/@loaders.gl/loader-utils/dist/lib/path-utils/get-cwd.js function getCWD() { if (typeof process !== "undefined" && typeof process.cwd !== "undefined") { return process.cwd(); } const pathname = window.location?.pathname; return pathname?.slice(0, pathname.lastIndexOf("/") + 1) || ""; } // ../../node_modules/@loaders.gl/loader-utils/dist/lib/path-utils/path.js function filename(url) { const slashIndex = url ? url.lastIndexOf("/") : -1; return slashIndex >= 0 ? url.substr(slashIndex + 1) : ""; } function dirname(url) { const slashIndex = url ? url.lastIndexOf("/") : -1; return slashIndex >= 0 ? url.substr(0, slashIndex) : ""; } function join(...parts) { const separator = "/"; parts = parts.map((part, index2) => { if (index2) { part = part.replace(new RegExp(`^${separator}`), ""); } if (index2 !== parts.length - 1) { part = part.replace(new RegExp(`${separator}$`), ""); } return part; }); return parts.join(separator); } function resolve(...components) { const paths = []; for (let _i = 0; _i < components.length; _i++) { paths[_i] = components[_i]; } let resolvedPath = ""; let resolvedAbsolute = false; let cwd; for (let i = paths.length - 1; i >= -1 && !resolvedAbsolute; i--) { let path; if (i >= 0) { path = paths[i]; } else { if (cwd === void 0) { cwd = getCWD(); } path = cwd; } if (path.length === 0) { continue; } resolvedPath = `${path}/${resolvedPath}`; resolvedAbsolute = path.charCodeAt(0) === SLASH; } resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute); if (resolvedAbsolute) { return `/${resolvedPath}`; } else if (resolvedPath.length > 0) { return resolvedPath; } return "."; } var SLASH = 47; var DOT = 46; function normalizeStringPosix(path, allowAboveRoot) { let res = ""; let lastSlash = -1; let dots = 0; let code; let isAboveRoot = false; for (let i = 0; i <= path.length; ++i) { if (i < path.length) { code = path.charCodeAt(i); } else if (code === SLASH) { break; } else { code = SLASH; } if (code === SLASH) { if (lastSlash === i - 1 || dots === 1) { } else if (lastSlash !== i - 1 && dots === 2) { if (res.length < 2 || !isAboveRoot || res.charCodeAt(res.length - 1) !== DOT || res.charCodeAt(res.length - 2) !== DOT) { if (res.length > 2) { const start = res.length - 1; let j = start; for (; j >= 0; --j) { if (res.charCodeAt(j) === SLASH) { break; } } if (j !== start) { res = j === -1 ? "" : res.slice(0, j); lastSlash = i; dots = 0; isAboveRoot = false; continue; } } else if (res.length === 2 || res.length === 1) { res = ""; lastSlash = i; dots = 0; isAboveRoot = false; continue; } } if (allowAboveRoot) { if (res.length > 0) { res += "/.."; } else { res = ".."; } isAboveRoot = true; } } else { const slice = path.slice(lastSlash + 1, i); if (res.length > 0) { res += `/${slice}`; } else { res = slice; } isAboveRoot = false; } lastSlash = i; dots = 0; } else if (code === DOT && dots !== -1) { ++dots; } else { dots = -1; } } return res; } // ../../node_modules/@loaders.gl/core/dist/javascript-utils/is-type.js var isBoolean = (x) => typeof x === "boolean"; var isFunction = (x) => typeof x === "function"; var isObject = (x) => x !== null && typeof x === "object"; var isPureObject = (x) => isObject(x) && x.constructor === {}.constructor; var isIterable = (x) => Boolean(x) && typeof x[Symbol.iterator] === "function"; var isAsyncIterable = (x) => x && typeof x[Symbol.asyncIterator] === "function"; var isResponse = (x) => typeof Response !== "undefined" && x instanceof Response || x && x.arrayBuffer && x.text && x.json; var isBlob = (x) => typeof Blob !== "undefined" && x instanceof Blob; var isBuffer2 = (x) => x && typeof x === "object" && x.isBuffer; var isReadableDOMStream = (x) => typeof ReadableStream !== "undefined" && x instanceof ReadableStream || isObject(x) && isFunction(x.tee) && isFunction(x.cancel) && isFunction(x.getReader); var isReadableNodeStream = (x) => isObject(x) && isFunction(x.read) && isFunction(x.pipe) && isBoolean(x.readable); var isReadableStream = (x) => isReadableDOMStream(x) || isReadableNodeStream(x); // ../../node_modules/@loaders.gl/core/dist/lib/fetch/fetch-error.js var FetchError = class extends Error { constructor(message2, info) { super(message2); this.reason = info.reason; this.url = info.url; this.response = info.response; } reason; url; response; }; // ../../node_modules/@loaders.gl/core/dist/lib/utils/mime-type-utils.js var DATA_URL_PATTERN = /^data:([-\w.]+\/[-\w.+]+)(;|,)/; var MIME_TYPE_PATTERN = /^([-\w.]+\/[-\w.+]+)/; function compareMIMETypes(mimeType1, mimeType2) { if (mimeType1.toLowerCase() === mimeType2.toLowerCase()) { return true; } return false; } function parseMIMEType(mimeString) { const matches3 = MIME_TYPE_PATTERN.exec(mimeString); if (matches3) { return matches3[1]; } return mimeString; } function parseMIMETypeFromURL(url) { const matches3 = DATA_URL_PATTERN.exec(url); if (matches3) { return matches3[1]; } return ""; } // ../../node_modules/@loaders.gl/core/dist/lib/utils/url-utils.js var QUERY_STRING_PATTERN = /\?.*/; function extractQueryString(url) { const matches3 = url.match(QUERY_STRING_PATTERN); return matches3 && matches3[0]; } function stripQueryString(url) { return url.replace(QUERY_STRING_PATTERN, ""); } function shortenUrlForDisplay(url) { if (url.length < 50) { return url; } const urlEnd = url.slice(url.length - 15); const urlStart = url.substr(0, 32); return `${urlStart}...${urlEnd}`; } // ../../node_modules/@loaders.gl/core/dist/lib/utils/resource-utils.js function getResourceUrl(resource) { if (isResponse(resource)) { const response = resource; return response.url; } if (isBlob(resource)) { const blob = resource; return blob.name || ""; } if (typeof resource === "string") { return resource; } return ""; } function getResourceMIMEType(resource) { if (isResponse(resource)) { const response = resource; const contentTypeHeader = response.headers.get("content-type") || ""; const noQueryUrl = stripQueryString(response.url); return parseMIMEType(contentTypeHeader) || parseMIMETypeFromURL(noQueryUrl); } if (isBlob(resource)) { const blob = resource; return blob.type || ""; } if (typeof resource === "string") { return parseMIMETypeFromURL(resource); } return ""; } function getResourceContentLength(resource) { if (isResponse(resource)) { const response = resource; return response.headers["content-length"] || -1; } if (isBlob(resource)) { const blob = resource; return blob.size; } if (typeof resource === "string") { return resource.length; } if (resource instanceof ArrayBuffer) { return resource.byteLength; } if (ArrayBuffer.isView(resource)) { return resource.byteLength; } return -1; } // ../../node_modules/@loaders.gl/core/dist/lib/utils/response-utils.js async function makeResponse(resource) { if (isResponse(resource)) { return resource; } const headers = {}; const contentLength = getResourceContentLength(resource); if (contentLength >= 0) { headers["content-length"] = String(contentLength); } const url = getResourceUrl(resource); const type = getResourceMIMEType(resource); if (type) { headers["content-type"] = type; } const initialDataUrl = await getInitialDataUrl(resource); if (initialDataUrl) { headers["x-first-bytes"] = initialDataUrl; } if (typeof resource === "string") { resource = new TextEncoder().encode(resource); } const response = new Response(resource, { headers }); Object.defineProperty(response, "url", { value: url }); return response; } async function checkResponse(response) { if (!response.ok) { const error = await getResponseError(response); throw error; } } async function getResponseError(response) { const shortUrl = shortenUrlForDisplay(response.url); let message2 = `Failed to fetch resource (${response.status}) ${response.statusText}: ${shortUrl}`; message2 = message2.length > 100 ? `${message2.slice(0, 100)}...` : message2; const info = { reason: response.statusText, url: response.url, response }; try { const contentType = response.headers.get("Content-Type"); info.reason = contentType?.includes("application/json") ? await response.json() : response.text(); } catch (error) { } return new FetchError(message2, info); } async function getInitialDataUrl(resource) { const INITIAL_DATA_LENGTH = 5; if (typeof resource === "string") { return `data:,${resource.slice(0, INITIAL_DATA_LENGTH)}`; } if (resource instanceof Blob) { const blobSlice = resource.slice(0, 5); return await new Promise((resolve2) => { const reader = new FileReader(); reader.onload = (event) => resolve2(event?.target?.result); reader.readAsDataURL(blobSlice); }); } if (resource instanceof ArrayBuffer) { const slice = resource.slice(0, INITIAL_DATA_LENGTH); const base64 = arrayBufferToBase64(slice); return `data:base64,${base64}`; } return null; } function arrayBufferToBase64(buffer) { let binary = ""; const bytes = new Uint8Array(buffer); for (let i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); } return btoa(binary); } // ../../node_modules/@loaders.gl/core/dist/lib/fetch/fetch-file.js function isNodePath(url) { return !isRequestURL(url) && !isDataURL(url); } function isRequestURL(url) { return url.startsWith("http:") || url.startsWith("https:"); } function isDataURL(url) { return url.startsWith("data:"); } async function fetchFile(urlOrData, fetchOptions) { if (typeof urlOrData === "string") { const url = resolvePath(urlOrData); if (isNodePath(url)) { if (globalThis.loaders?.fetchNode) { return globalThis.loaders?.fetchNode(url, fetchOptions); } } return await fetch(url, fetchOptions); } return await makeResponse(urlOrData); } // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/loggers.js var probeLog = new Log({ id: "loaders.gl" }); var NullLog = class { log() { return () => { }; } info() { return () => { }; } warn() { return () => { }; } error() { return () => { }; } }; var ConsoleLog = class { console; constructor() { this.console = console; } log(...args) { return this.console.log.bind(this.console, ...args); } info(...args) { return this.console.info.bind(this.console, ...args); } warn(...args) { return this.console.warn.bind(this.console, ...args); } error(...args) { return this.console.error.bind(this.console, ...args); } }; // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/option-defaults.js var DEFAULT_LOADER_OPTIONS = { fetch: null, mimeType: void 0, nothrow: false, log: new ConsoleLog(), useLocalLibraries: false, CDN: "https://unpkg.com/@loaders.gl", worker: true, maxConcurrency: 3, maxMobileConcurrency: 1, reuseWorkers: isBrowser2, _nodeWorkers: false, _workerType: "", limit: 0, _limitMB: 0, batchSize: "auto", batchDebounceMs: 0, metadata: false, transforms: [] }; var REMOVED_LOADER_OPTIONS = { throws: "nothrow", dataType: "(no longer used)", uri: "baseUri", method: "fetch.method", headers: "fetch.headers", body: "fetch.body", mode: "fetch.mode", credentials: "fetch.credentials", cache: "fetch.cache", redirect: "fetch.redirect", referrer: "fetch.referrer", referrerPolicy: "fetch.referrerPolicy", integrity: "fetch.integrity", keepalive: "fetch.keepalive", signal: "fetch.signal" }; // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/option-utils.js function getGlobalLoaderState() { globalThis.loaders = globalThis.loaders || {}; const { loaders } = globalThis; if (!loaders._state) { loaders._state = {}; } return loaders._state; } function getGlobalLoaderOptions() { const state = getGlobalLoaderState(); state.globalOptions = state.globalOptions || { ...DEFAULT_LOADER_OPTIONS }; return state.globalOptions; } function normalizeOptions(options, loader, loaders, url) { loaders = loaders || []; loaders = Array.isArray(loaders) ? loaders : [loaders]; validateOptions(options, loaders); return normalizeOptionsInternal(loader, options, url); } function validateOptions(options, loaders) { validateOptionsObject(options, null, DEFAULT_LOADER_OPTIONS, REMOVED_LOADER_OPTIONS, loaders); for (const loader of loaders) { const idOptions = options && options[loader.id] || {}; const loaderOptions = loader.options && loader.options[loader.id] || {}; const deprecatedOptions = loader.deprecatedOptions && loader.deprecatedOptions[loader.id] || {}; validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders); } } function validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) { const loaderName = id || "Top level"; const prefix = id ? `${id}.` : ""; for (const key in options) { const isSubOptions = !id && isObject(options[key]); const isBaseUriOption = key === "baseUri" && !id; const isWorkerUrlOption = key === "workerUrl" && id; if (!(key in defaultOptions) && !isBaseUriOption && !isWorkerUrlOption) { if (key in deprecatedOptions) { probeLog.warn(`${loaderName} loader option '${prefix}${key}' no longer supported, use '${deprecatedOptions[key]}'`)(); } else if (!isSubOptions) { const suggestion = findSimilarOption(key, loaders); probeLog.warn(`${loaderName} loader option '${prefix}${key}' not recognized. ${suggestion}`)(); } } } } function findSimilarOption(optionKey, loaders) { const lowerCaseOptionKey = optionKey.toLowerCase(); let bestSuggestion = ""; for (const loader of loaders) { for (const key in loader.options) { if (optionKey === key) { return `Did you mean '${loader.id}.${key}'?`; } const lowerCaseKey = key.toLowerCase(); const isPartialMatch = lowerCaseOptionKey.startsWith(lowerCaseKey) || lowerCaseKey.startsWith(lowerCaseOptionKey); if (isPartialMatch) { bestSuggestion = bestSuggestion || `Did you mean '${loader.id}.${key}'?`; } } } return bestSuggestion; } function normalizeOptionsInternal(loader, options, url) { const loaderDefaultOptions = loader.options || {}; const mergedOptions = { ...loaderDefaultOptions }; addUrlOptions(mergedOptions, url); if (mergedOptions.log === null) { mergedOptions.log = new NullLog(); } mergeNestedFields(mergedOptions, getGlobalLoaderOptions()); mergeNestedFields(mergedOptions, options); return mergedOptions; } function mergeNestedFields(mergedOptions, options) { for (const key in options) { if (key in options) { const value = options[key]; if (isPureObject(value) && isPureObject(mergedOptions[key])) { mergedOptions[key] = { ...mergedOptions[key], ...options[key] }; } else { mergedOptions[key] = options[key]; } } } } function addUrlOptions(options, url) { if (url && !("baseUri" in options)) { options.baseUri = url; } } // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/normalize-loader.js function isLoaderObject(loader) { if (!loader) { return false; } if (Array.isArray(loader)) { loader = loader[0]; } const hasExtensions = Array.isArray(loader?.extensions); return hasExtensions; } function normalizeLoader(loader) { assert5(loader, "null loader"); assert5(isLoaderObject(loader), "invalid loader"); let options; if (Array.isArray(loader)) { options = loader[1]; loader = loader[0]; loader = { ...loader, options: { ...loader.options, ...options } }; } if (loader?.parseTextSync || loader?.parseText) { loader.text = true; } if (!loader.text) { loader.binary = true; } return loader; } // ../../node_modules/@loaders.gl/core/dist/lib/api/register-loaders.js var getGlobalLoaderRegistry = () => { const state = getGlobalLoaderState(); state.loaderRegistry = state.loaderRegistry || []; return state.loaderRegistry; }; function registerLoaders(loaders) { const loaderRegistry = getGlobalLoaderRegistry(); loaders = Array.isArray(loaders) ? loaders : [loaders]; for (const loader of loaders) { const normalizedLoader = normalizeLoader(loader); if (!loaderRegistry.find((registeredLoader) => normalizedLoader === registeredLoader)) { loaderRegistry.unshift(normalizedLoader); } } } function getRegisteredLoaders() { return getGlobalLoaderRegistry(); } // ../../node_modules/@loaders.gl/core/dist/lib/utils/log.js var log2 = new Log({ id: "loaders.gl" }); // ../../node_modules/@loaders.gl/core/dist/lib/api/select-loader.js var EXT_PATTERN = /\.([^.]+)$/; async function selectLoader(data, loaders = [], options, context) { if (!validHTTPResponse(data)) { return null; } let loader = selectLoaderSync(data, loaders, { ...options, nothrow: true }, context); if (loader) { return loader; } if (isBlob(data)) { data = await data.slice(0, 10).arrayBuffer(); loader = selectLoaderSync(data, loaders, options, context); } if (!loader && !options?.nothrow) { throw new Error(getNoValidLoaderMessage(data)); } return loader; } function selectLoaderSync(data, loaders = [], options, context) { if (!validHTTPResponse(data)) { return null; } if (loaders && !Array.isArray(loaders)) { return normalizeLoader(loaders); } let candidateLoaders = []; if (loaders) { candidateLoaders = candidateLoaders.concat(loaders); } if (!options?.ignoreRegisteredLoaders) { candidateLoaders.push(...getRegisteredLoaders()); } normalizeLoaders(candidateLoaders); const loader = selectLoaderInternal(data, candidateLoaders, options, context); if (!loader && !options?.nothrow) { throw new Error(getNoValidLoaderMessage(data)); } return loader; } function selectLoaderInternal(data, loaders, options, context) { const url = getResourceUrl(data); const type = getResourceMIMEType(data); const testUrl = stripQueryString(url) || context?.url; let loader = null; let reason = ""; if (options?.mimeType) { loader = findLoaderByMIMEType(loaders, options?.mimeType); reason = `match forced by supplied MIME type ${options?.mimeType}`; } loader = loader || findLoaderByUrl(loaders, testUrl); reason = reason || (loader ? `matched url ${testUrl}` : ""); loader = loader || findLoaderByMIMEType(loaders, type); reason = reason || (loader ? `matched MIME type ${type}` : ""); loader = loader || findLoaderByInitialBytes(loaders, data); reason = reason || (loader ? `matched initial data ${getFirstCharacters(data)}` : ""); if (options?.fallbackMimeType) { loader = loader || findLoaderByMIMEType(loaders, options?.fallbackMimeType); reason = reason || (loader ? `matched fallback MIME type ${type}` : ""); } if (reason) { log2.log(1, `selectLoader selected ${loader?.name}: ${reason}.`); } return loader; } function validHTTPResponse(data) { if (data instanceof Response) { if (data.status === 204) { return false; } } return true; } function getNoValidLoaderMessage(data) { const url = getResourceUrl(data); const type = getResourceMIMEType(data); let message2 = "No valid loader found ("; message2 += url ? `${path_exports.filename(url)}, ` : "no url provided, "; message2 += `MIME type: ${type ? `"${type}"` : "not provided"}, `; const firstCharacters = data ? getFirstCharacters(data) : ""; message2 += firstCharacters ? ` first bytes: "${firstCharacters}"` : "first bytes: not available"; message2 += ")"; return message2; } function normalizeLoaders(loaders) { for (const loader of loaders) { normalizeLoader(loader); } } function findLoaderByUrl(loaders, url) { const match = url && EXT_PATTERN.exec(url); const extension = match && match[1]; return extension ? findLoaderByExtension(loaders, extension) : null; } function findLoaderByExtension(loaders, extension) { extension = extension.toLowerCase(); for (const loader of loaders) { for (const loaderExtension of loader.extensions) { if (loaderExtension.toLowerCase() === extension) { return loader; } } } return null; } function findLoaderByMIMEType(loaders, mimeType) { for (const loader of loaders) { if (loader.mimeTypes?.some((mimeType1) => compareMIMETypes(mimeType, mimeType1))) { return loader; } if (compareMIMETypes(mimeType, `application/x.${loader.id}`)) { return loader; } } return null; } function findLoaderByInitialBytes(loaders, data) { if (!data) { return null; } for (const loader of loaders) { if (typeof data === "string") { if (testDataAgainstText(data, loader)) { return loader; } } else if (ArrayBuffer.isView(data)) { if (testDataAgainstBinary(data.buffer, data.byteOffset, loader)) { return loader; } } else if (data instanceof ArrayBuffer) { const byteOffset = 0; if (testDataAgainstBinary(data, byteOffset, loader)) { return loader; } } } return null; } function testDataAgainstText(data, loader) { if (loader.testText) { return loader.testText(data); } const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests]; return tests.some((test) => data.startsWith(test)); } function testDataAgainstBinary(data, byteOffset, loader) { const tests = Array.isArray(loader.tests) ? loader.tests : [loader.tests]; return tests.some((test) => testBinary(data, byteOffset, loader, test)); } function testBinary(data, byteOffset, loader, test) { if (test instanceof ArrayBuffer) { return compareArrayBuffers(test, data, test.byteLength); } switch (typeof test) { case "function": return test(data); case "string": const magic = getMagicString(data, byteOffset, test.length); return test === magic; default: return false; } } function getFirstCharacters(data, length4 = 5) { if (typeof data === "string") { return data.slice(0, length4); } else if (ArrayBuffer.isView(data)) { return getMagicString(data.buffer, data.byteOffset, length4); } else if (data instanceof ArrayBuffer) { const byteOffset = 0; return getMagicString(data, byteOffset, length4); } return ""; } function getMagicString(arrayBuffer2, byteOffset, length4) { if (arrayBuffer2.byteLength < byteOffset + length4) { return ""; } const dataView = new DataView(arrayBuffer2); let magic = ""; for (let i = 0; i < length4; i++) { magic += String.fromCharCode(dataView.getUint8(byteOffset + i)); } return magic; } // ../../node_modules/@loaders.gl/core/dist/iterators/make-iterator/make-string-iterator.js var DEFAULT_CHUNK_SIZE = 256 * 1024; function* makeStringIterator(string, options) { const chunkSize = options?.chunkSize || DEFAULT_CHUNK_SIZE; let offset = 0; const textEncoder = new TextEncoder(); while (offset < string.length) { const chunkLength = Math.min(string.length - offset, chunkSize); const chunk = string.slice(offset, offset + chunkLength); offset += chunkLength; yield textEncoder.encode(chunk); } } // ../../node_modules/@loaders.gl/core/dist/iterators/make-iterator/make-array-buffer-iterator.js var DEFAULT_CHUNK_SIZE2 = 256 * 1024; function* makeArrayBufferIterator(arrayBuffer2, options = {}) { const { chunkSize = DEFAULT_CHUNK_SIZE2 } = options; let byteOffset = 0; while (byteOffset < arrayBuffer2.byteLength) { const chunkByteLength = Math.min(arrayBuffer2.byteLength - byteOffset, chunkSize); const chunk = new ArrayBuffer(chunkByteLength); const sourceArray = new Uint8Array(arrayBuffer2, byteOffset, chunkByteLength); const chunkArray = new Uint8Array(chunk); chunkArray.set(sourceArray); byteOffset += chunkByteLength; yield chunk; } } // ../../node_modules/@loaders.gl/core/dist/iterators/make-iterator/make-blob-iterator.js var DEFAULT_CHUNK_SIZE3 = 1024 * 1024; async function* makeBlobIterator(blob, options) { const chunkSize = options?.chunkSize || DEFAULT_CHUNK_SIZE3; let offset = 0; while (offset < blob.size) { const end = offset + chunkSize; const chunk = await blob.slice(offset, end).arrayBuffer(); offset = end; yield chunk; } } // ../../node_modules/@loaders.gl/core/dist/iterators/make-iterator/make-stream-iterator.js function makeStreamIterator(stream, options) { return isBrowser2 ? makeBrowserStreamIterator(stream, options) : makeNodeStreamIterator(stream, options); } async function* makeBrowserStreamIterator(stream, options) { const reader = stream.getReader(); let nextBatchPromise; try { while (true) { const currentBatchPromise = nextBatchPromise || reader.read(); if (options?._streamReadAhead) { nextBatchPromise = reader.read(); } const { done, value } = await currentBatchPromise; if (done) { return; } yield toArrayBuffer2(value); } } catch (error) { reader.releaseLock(); } } async function* makeNodeStreamIterator(stream, options) { for await (const chunk of stream) { yield toArrayBuffer2(chunk); } } // ../../node_modules/@loaders.gl/core/dist/iterators/make-iterator/make-iterator.js function makeIterator(data, options) { if (typeof data === "string") { return makeStringIterator(data, options); } if (data instanceof ArrayBuffer) { return makeArrayBufferIterator(data, options); } if (isBlob(data)) { return makeBlobIterator(data, options); } if (isReadableStream(data)) { return makeStreamIterator(data, options); } if (isResponse(data)) { const response = data; return makeStreamIterator(response.body, options); } throw new Error("makeIterator"); } // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/get-data.js var ERR_DATA = "Cannot convert supplied data type"; function getArrayBufferOrStringFromDataSync(data, loader, options) { if (loader.text && typeof data === "string") { return data; } if (isBuffer2(data)) { data = data.buffer; } if (data instanceof ArrayBuffer) { const arrayBuffer2 = data; if (loader.text && !loader.binary) { const textDecoder = new TextDecoder("utf8"); return textDecoder.decode(arrayBuffer2); } return arrayBuffer2; } if (ArrayBuffer.isView(data)) { if (loader.text && !loader.binary) { const textDecoder = new TextDecoder("utf8"); return textDecoder.decode(data); } let arrayBuffer2 = data.buffer; const byteLength = data.byteLength || data.length; if (data.byteOffset !== 0 || byteLength !== arrayBuffer2.byteLength) { arrayBuffer2 = arrayBuffer2.slice(data.byteOffset, data.byteOffset + byteLength); } return arrayBuffer2; } throw new Error(ERR_DATA); } async function getArrayBufferOrStringFromData(data, loader, options) { const isArrayBuffer = data instanceof ArrayBuffer || ArrayBuffer.isView(data); if (typeof data === "string" || isArrayBuffer) { return getArrayBufferOrStringFromDataSync(data, loader, options); } if (isBlob(data)) { data = await makeResponse(data); } if (isResponse(data)) { const response = data; await checkResponse(response); return loader.binary ? await response.arrayBuffer() : await response.text(); } if (isReadableStream(data)) { data = makeIterator(data, options); } if (isIterable(data) || isAsyncIterable(data)) { return concatenateArrayBuffersAsync(data); } throw new Error(ERR_DATA); } // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/get-fetch-function.js function getFetchFunction(options, context) { const globalOptions = getGlobalLoaderOptions(); const loaderOptions = options || globalOptions; if (typeof loaderOptions.fetch === "function") { return loaderOptions.fetch; } if (isObject(loaderOptions.fetch)) { return (url) => fetchFile(url, loaderOptions.fetch); } if (context?.fetch) { return context?.fetch; } return fetchFile; } // ../../node_modules/@loaders.gl/core/dist/lib/loader-utils/loader-context.js function getLoaderContext(context, options, parentContext) { if (parentContext) { return parentContext; } const newContext = { fetch: getFetchFunction(options, context), ...context }; if (newContext.url) { const baseUrl = stripQueryString(newContext.url); newContext.baseUrl = baseUrl; newContext.queryString = extractQueryString(newContext.url); newContext.filename = path_exports.filename(baseUrl); newContext.baseUrl = path_exports.dirname(baseUrl); } if (!Array.isArray(newContext.loaders)) { newContext.loaders = null; } return newContext; } function getLoadersFromContext(loaders, context) { if (loaders && !Array.isArray(loaders)) { return loaders; } let candidateLoaders; if (loaders) { candidateLoaders = Array.isArray(loaders) ? loaders : [loaders]; } if (context && context.loaders) { const contextLoaders = Array.isArray(context.loaders) ? context.loaders : [context.loaders]; candidateLoaders = candidateLoaders ? [...candidateLoaders, ...contextLoaders] : contextLoaders; } return candidateLoaders && candidateLoaders.length ? candidateLoaders : void 0; } // ../../node_modules/@loaders.gl/core/dist/lib/api/parse.js async function parse(data, loaders, options, context) { if (loaders && !Array.isArray(loaders) && !isLoaderObject(loaders)) { context = void 0; options = loaders; loaders = void 0; } data = await data; options = options || {}; const url = getResourceUrl(data); const typedLoaders = loaders; const candidateLoaders = getLoadersFromContext(typedLoaders, context); const loader = await selectLoader(data, candidateLoaders, options); if (!loader) { return null; } options = normalizeOptions(options, loader, candidateLoaders, url); context = getLoaderContext( { url, _parse: parse, loaders: candidateLoaders }, options, context || null ); return await parseWithLoader(loader, data, options, context); } async function parseWithLoader(loader, data, options, context) { validateWorkerVersion(loader); options = mergeLoaderOptions(loader.options, options); if (isResponse(data)) { const response = data; const { ok, redirected, status, statusText, type, url } = response; const headers = Object.fromEntries(response.headers.entries()); context.response = { headers, ok, redirected, status, statusText, type, url }; } data = await getArrayBufferOrStringFromData(data, loader, options); const loaderWithParser = loader; if (loaderWithParser.parseTextSync && typeof data === "string") { return loaderWithParser.parseTextSync(data, options, context); } if (canParseWithWorker(loader, options)) { return await parseWithWorker(loader, data, options, context, parse); } if (loaderWithParser.parseText && typeof data === "string") { return await loaderWithParser.parseText(data, options, context); } if (loaderWithParser.parse) { return await loaderWithParser.parse(data, options, context); } assert6(!loaderWithParser.parseSync); throw new Error(`${loader.id} loader - no parser found and worker is disabled`); } // ../../node_modules/@loaders.gl/core/dist/lib/api/load.js async function load(url, loaders, options, context) { let resolvedLoaders; let resolvedOptions; if (!Array.isArray(loaders) && !isLoaderObject(loaders)) { resolvedLoaders = []; resolvedOptions = loaders; context = void 0; } else { resolvedLoaders = loaders; resolvedOptions = options; } const fetch2 = getFetchFunction(resolvedOptions); let data = url; if (typeof url === "string") { data = await fetch2(url); } if (isBlob(url)) { data = await fetch2(url); } return Array.isArray(resolvedLoaders) ? await parse(data, resolvedLoaders, resolvedOptions) : await parse(data, resolvedLoaders, resolvedOptions); } // ../../node_modules/@loaders.gl/images/dist/lib/utils/version.js var VERSION4 = true ? "4.2.0-beta.2" : "latest"; // ../../node_modules/@loaders.gl/images/dist/lib/category-api/image-type.js var parseImageNode = globalThis.loaders?.parseImageNode; var IMAGE_SUPPORTED = typeof Image !== "undefined"; var IMAGE_BITMAP_SUPPORTED = typeof ImageBitmap !== "undefined"; var NODE_IMAGE_SUPPORTED = Boolean(parseImageNode); var DATA_SUPPORTED = isBrowser2 ? true : NODE_IMAGE_SUPPORTED; function isImageTypeSupported(type) { switch (type) { case "auto": return IMAGE_BITMAP_SUPPORTED || IMAGE_SUPPORTED || DATA_SUPPORTED; case "imagebitmap": return IMAGE_BITMAP_SUPPORTED; case "image": return IMAGE_SUPPORTED; case "data": return DATA_SUPPORTED; default: throw new Error(`@loaders.gl/images: image ${type} not supported in this environment`); } } function getDefaultImageType() { if (IMAGE_BITMAP_SUPPORTED) { return "imagebitmap"; } if (IMAGE_SUPPORTED) { return "image"; } if (DATA_SUPPORTED) { return "data"; } throw new Error("Install '@loaders.gl/polyfills' to parse images under Node.js"); } // ../../node_modules/@loaders.gl/images/dist/lib/category-api/parsed-image-api.js function getImageType(image) { const format = getImageTypeOrNull(image); if (!format) { throw new Error("Not an image"); } return format; } function getImageData(image) { switch (getImageType(image)) { case "data": return image; case "image": case "imagebitmap": const canvas2 = document.createElement("canvas"); const context = canvas2.getContext("2d"); if (!context) { throw new Error("getImageData"); } canvas2.width = image.width; canvas2.height = image.height; context.drawImage(image, 0, 0); return context.getImageData(0, 0, image.width, image.height); default: throw new Error("getImageData"); } } function getImageTypeOrNull(image) { if (typeof ImageBitmap !== "undefined" && image instanceof ImageBitmap) { return "imagebitmap"; } if (typeof Image !== "undefined" && image instanceof Image) { return "image"; } if (image && typeof image === "object" && image.data && image.width && image.height) { return "data"; } return null; } // ../../node_modules/@loaders.gl/images/dist/lib/parsers/svg-utils.js var SVG_DATA_URL_PATTERN = /^data:image\/svg\+xml/; var SVG_URL_PATTERN = /\.svg((\?|#).*)?$/; function isSVG(url) { return url && (SVG_DATA_URL_PATTERN.test(url) || SVG_URL_PATTERN.test(url)); } function getBlobOrSVGDataUrl(arrayBuffer2, url) { if (isSVG(url)) { const textDecoder = new TextDecoder(); let xmlText = textDecoder.decode(arrayBuffer2); try { if (typeof unescape === "function" && typeof encodeURIComponent === "function") { xmlText = unescape(encodeURIComponent(xmlText)); } } catch (error) { throw new Error(error.message); } const src = `data:image/svg+xml;base64,${btoa(xmlText)}`; return src; } return getBlob(arrayBuffer2, url); } function getBlob(arrayBuffer2, url) { if (isSVG(url)) { throw new Error("SVG cannot be parsed directly to imagebitmap"); } return new Blob([new Uint8Array(arrayBuffer2)]); } // ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-to-image.js async function parseToImage(arrayBuffer2, options, url) { const blobOrDataUrl = getBlobOrSVGDataUrl(arrayBuffer2, url); const URL2 = self.URL || self.webkitURL; const objectUrl = typeof blobOrDataUrl !== "string" && URL2.createObjectURL(blobOrDataUrl); try { return await loadToImage(objectUrl || blobOrDataUrl, options); } finally { if (objectUrl) { URL2.revokeObjectURL(objectUrl); } } } async function loadToImage(url, options) { const image = new Image(); image.src = url; if (options.image && options.image.decode && image.decode) { await image.decode(); return image; } return await new Promise((resolve2, reject) => { try { image.onload = () => resolve2(image); image.onerror = (error) => { const message2 = error instanceof Error ? error.message : "error"; reject(new Error(message2)); }; } catch (error) { reject(error); } }); } // ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-to-image-bitmap.js var EMPTY_OBJECT = {}; var imagebitmapOptionsSupported = true; async function parseToImageBitmap(arrayBuffer2, options, url) { let blob; if (isSVG(url)) { const image = await parseToImage(arrayBuffer2, options, url); blob = image; } else { blob = getBlob(arrayBuffer2, url); } const imagebitmapOptions = options && options.imagebitmap; return await safeCreateImageBitmap(blob, imagebitmapOptions); } async function safeCreateImageBitmap(blob, imagebitmapOptions = null) { if (isEmptyObject(imagebitmapOptions) || !imagebitmapOptionsSupported) { imagebitmapOptions = null; } if (imagebitmapOptions) { try { return await createImageBitmap(blob, imagebitmapOptions); } catch (error) { console.warn(error); imagebitmapOptionsSupported = false; } } return await createImageBitmap(blob); } function isEmptyObject(object) { for (const key in object || EMPTY_OBJECT) { return false; } return true; } // ../../node_modules/@loaders.gl/images/dist/lib/category-api/parse-isobmff-binary.js function getISOBMFFMediaType(buffer) { if (!checkString(buffer, "ftyp", 4)) { return null; } if ((buffer[8] & 96) === 0) { return null; } return decodeMajorBrand(buffer); } function decodeMajorBrand(buffer) { const brandMajor = getUTF8String(buffer, 8, 12).replace("\0", " ").trim(); switch (brandMajor) { case "avif": case "avis": return { extension: "avif", mimeType: "image/avif" }; default: return null; } } function getUTF8String(array, start, end) { return String.fromCharCode(...array.slice(start, end)); } function stringToBytes(string) { return [...string].map((character) => character.charCodeAt(0)); } function checkString(buffer, header, offset = 0) { const headerBytes = stringToBytes(header); for (let i = 0; i < headerBytes.length; ++i) { if (headerBytes[i] !== buffer[i + offset]) { return false; } } return true; } // ../../node_modules/@loaders.gl/images/dist/lib/category-api/binary-image-api.js var BIG_ENDIAN = false; var LITTLE_ENDIAN = true; function getBinaryImageMetadata(binaryData) { const dataView = toDataView(binaryData); return getPngMetadata(dataView) || getJpegMetadata(dataView) || getGifMetadata(dataView) || getBmpMetadata(dataView) || getISOBMFFMetadata(dataView); } function getISOBMFFMetadata(binaryData) { const buffer = new Uint8Array(binaryData instanceof DataView ? binaryData.buffer : binaryData); const mediaType = getISOBMFFMediaType(buffer); if (!mediaType) { return null; } return { mimeType: mediaType.mimeType, width: 0, height: 0 }; } function getPngMetadata(binaryData) { const dataView = toDataView(binaryData); const isPng = dataView.byteLength >= 24 && dataView.getUint32(0, BIG_ENDIAN) === 2303741511; if (!isPng) { return null; } return { mimeType: "image/png", width: dataView.getUint32(16, BIG_ENDIAN), height: dataView.getUint32(20, BIG_ENDIAN) }; } function getGifMetadata(binaryData) { const dataView = toDataView(binaryData); const isGif = dataView.byteLength >= 10 && dataView.getUint32(0, BIG_ENDIAN) === 1195984440; if (!isGif) { return null; } return { mimeType: "image/gif", width: dataView.getUint16(6, LITTLE_ENDIAN), height: dataView.getUint16(8, LITTLE_ENDIAN) }; } function getBmpMetadata(binaryData) { const dataView = toDataView(binaryData); const isBmp = dataView.byteLength >= 14 && dataView.getUint16(0, BIG_ENDIAN) === 16973 && dataView.getUint32(2, LITTLE_ENDIAN) === dataView.byteLength; if (!isBmp) { return null; } return { mimeType: "image/bmp", width: dataView.getUint32(18, LITTLE_ENDIAN), height: dataView.getUint32(22, LITTLE_ENDIAN) }; } function getJpegMetadata(binaryData) { const dataView = toDataView(binaryData); const isJpeg = dataView.byteLength >= 3 && dataView.getUint16(0, BIG_ENDIAN) === 65496 && dataView.getUint8(2) === 255; if (!isJpeg) { return null; } const { tableMarkers, sofMarkers } = getJpegMarkers(); let i = 2; while (i + 9 < dataView.byteLength) { const marker = dataView.getUint16(i, BIG_ENDIAN); if (sofMarkers.has(marker)) { return { mimeType: "image/jpeg", height: dataView.getUint16(i + 5, BIG_ENDIAN), width: dataView.getUint16(i + 7, BIG_ENDIAN) }; } if (!tableMarkers.has(marker)) { return null; } i += 2; i += dataView.getUint16(i, BIG_ENDIAN); } return null; } function getJpegMarkers() { const tableMarkers = /* @__PURE__ */ new Set([65499, 65476, 65484, 65501, 65534]); for (let i = 65504; i < 65520; ++i) { tableMarkers.add(i); } const sofMarkers = /* @__PURE__ */ new Set([ 65472, 65473, 65474, 65475, 65477, 65478, 65479, 65481, 65482, 65483, 65485, 65486, 65487, 65502 ]); return { tableMarkers, sofMarkers }; } function toDataView(data) { if (data instanceof DataView) { return data; } if (ArrayBuffer.isView(data)) { return new DataView(data.buffer); } if (data instanceof ArrayBuffer) { return new DataView(data); } throw new Error("toDataView"); } // ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-to-node-image.js async function parseToNodeImage(arrayBuffer2, options) { const { mimeType } = getBinaryImageMetadata(arrayBuffer2) || {}; const parseImageNode2 = globalThis.loaders?.parseImageNode; assert5(parseImageNode2); return await parseImageNode2(arrayBuffer2, mimeType); } // ../../node_modules/@loaders.gl/images/dist/lib/parsers/parse-image.js async function parseImage(arrayBuffer2, options, context) { options = options || {}; const imageOptions = options.image || {}; const imageType = imageOptions.type || "auto"; const { url } = context || {}; const loadType = getLoadableImageType(imageType); let image; switch (loadType) { case "imagebitmap": image = await parseToImageBitmap(arrayBuffer2, options, url); break; case "image": image = await parseToImage(arrayBuffer2, options, url); break; case "data": image = await parseToNodeImage(arrayBuffer2, options); break; default: assert5(false); } if (imageType === "data") { image = getImageData(image); } return image; } function getLoadableImageType(type) { switch (type) { case "auto": case "data": return getDefaultImageType(); default: isImageTypeSupported(type); return type; } } // ../../node_modules/@loaders.gl/images/dist/image-loader.js var EXTENSIONS = ["png", "jpg", "jpeg", "gif", "webp", "bmp", "ico", "svg", "avif"]; var MIME_TYPES = [ "image/png", "image/jpeg", "image/gif", "image/webp", "image/avif", "image/bmp", "image/vnd.microsoft.icon", "image/svg+xml" ]; var DEFAULT_IMAGE_LOADER_OPTIONS = { image: { type: "auto", decode: true } }; var ImageLoader = { dataType: null, batchType: null, id: "image", module: "images", name: "Images", version: VERSION4, mimeTypes: MIME_TYPES, extensions: EXTENSIONS, parse: parseImage, tests: [(arrayBuffer2) => Boolean(getBinaryImageMetadata(new DataView(arrayBuffer2)))], options: DEFAULT_IMAGE_LOADER_OPTIONS }; // src/utils/log.ts var defaultLogger = new Log({ id: "deck" }); var log_default = defaultLogger; // src/debug/loggers.ts var logState = { attributeUpdateStart: -1, attributeManagerUpdateStart: -1, attributeUpdateMessages: [] }; var LOG_LEVEL_MAJOR_UPDATE = 1; var LOG_LEVEL_MINOR_UPDATE = 2; var LOG_LEVEL_UPDATE_DETAIL = 3; var LOG_LEVEL_INFO = 4; var LOG_LEVEL_DRAW = 2; var getLoggers = (log3) => ({ "layer.changeFlag": (layer, key, flags) => { log3.log(LOG_LEVEL_UPDATE_DETAIL, `${layer.id} ${key}: `, flags[key])(); }, "layer.initialize": (layer) => { log3.log(LOG_LEVEL_MAJOR_UPDATE, `Initializing ${layer}`)(); }, "layer.update": (layer, needsUpdate) => { if (needsUpdate) { const flags = layer.getChangeFlags(); log3.log( LOG_LEVEL_MINOR_UPDATE, `Updating ${layer} because: ${Object.keys(flags).filter((key) => flags[key]).join(", ")}` )(); } else { log3.log(LOG_LEVEL_INFO, `${layer} does not need update`)(); } }, "layer.matched": (layer, changed) => { if (changed) { log3.log(LOG_LEVEL_INFO, `Matched ${layer}, state transfered`)(); } }, "layer.finalize": (layer) => { log3.log(LOG_LEVEL_MAJOR_UPDATE, `Finalizing ${layer}`)(); }, "compositeLayer.renderLayers": (layer, updated, subLayers) => { if (updated) { log3.log( LOG_LEVEL_MINOR_UPDATE, `Composite layer rendered new subLayers ${layer}`, subLayers )(); } else { log3.log(LOG_LEVEL_INFO, `Composite layer reused subLayers ${layer}`, subLayers)(); } }, "layerManager.setLayers": (layerManager, updated, layers) => { if (updated) { log3.log(LOG_LEVEL_MINOR_UPDATE, `Updating ${layers.length} deck layers`)(); } }, "layerManager.activateViewport": (layerManager, viewport) => { log3.log(LOG_LEVEL_UPDATE_DETAIL, "Viewport changed", viewport)(); }, "attributeManager.invalidate": (attributeManager, trigger, attributeNames) => { log3.log( LOG_LEVEL_MAJOR_UPDATE, attributeNames ? `invalidated attributes ${attributeNames} (${trigger}) for ${attributeManager.id}` : `invalidated all attributes for ${attributeManager.id}` )(); }, "attributeManager.updateStart": (attributeManager) => { logState.attributeUpdateMessages.length = 0; logState.attributeManagerUpdateStart = Date.now(); }, "attributeManager.updateEnd": (attributeManager, numInstances) => { const timeMs = Math.round(Date.now() - logState.attributeManagerUpdateStart); log3.groupCollapsed( LOG_LEVEL_MINOR_UPDATE, `Updated attributes for ${numInstances} instances in ${attributeManager.id} in ${timeMs}ms` )(); for (const updateMessage of logState.attributeUpdateMessages) { log3.log(LOG_LEVEL_UPDATE_DETAIL, updateMessage)(); } log3.groupEnd(LOG_LEVEL_MINOR_UPDATE)(); }, "attribute.updateStart": (attribute) => { logState.attributeUpdateStart = Date.now(); }, "attribute.allocate": (attribute, numInstances) => { const message2 = `${attribute.id} allocated ${numInstances}`; logState.attributeUpdateMessages.push(message2); }, "attribute.updateEnd": (attribute, numInstances) => { const timeMs = Math.round(Date.now() - logState.attributeUpdateStart); const message2 = `${attribute.id} updated ${numInstances} in ${timeMs}ms`; logState.attributeUpdateMessages.push(message2); }, "deckRenderer.renderLayers": (deckRenderer, renderStats, opts) => { const { pass, redrawReason, stats: stats2 } = opts; for (const status of renderStats) { const { totalCount, visibleCount, compositeCount, pickableCount } = status; const primitiveCount = totalCount - compositeCount; const hiddenCount = primitiveCount - visibleCount; log3.log( LOG_LEVEL_DRAW, `RENDER #${deckRenderer.renderCount} ${visibleCount} (of ${totalCount} layers) to ${pass} because ${redrawReason} (${hiddenCount} hidden, ${compositeCount} composite ${pickableCount} pickable)` )(); if (stats2) { stats2.get("Redraw Layers").add(visibleCount); } } } }); // src/debug/index.ts var loggers = {}; if (true) { loggers = getLoggers(log_default); } function register(handlers) { loggers = handlers; } function debug(eventType, arg1, arg2, arg3) { if (log_default.level > 0 && loggers[eventType]) { loggers[eventType].call(null, arg1, arg2, arg3); } } // src/utils/json-loader.ts function isJSON(text) { const firstChar = text[0]; const lastChar = text[text.length - 1]; return firstChar === "{" && lastChar === "}" || firstChar === "[" && lastChar === "]"; } var json_loader_default = { dataType: null, batchType: null, id: "JSON", name: "JSON", module: "", version: "", options: {}, extensions: ["json", "geojson"], mimeTypes: ["application/json", "application/geo+json"], testText: isJSON, parseTextSync: JSON.parse }; // src/lib/init.ts function checkVersion() { const version = typeof __VERSION__ !== "undefined" ? __VERSION__ : globalThis.DECK_VERSION || "untranspiled source"; const existingVersion = globalThis.deck && globalThis.deck.VERSION; if (existingVersion && existingVersion !== version) { throw new Error(`deck.gl - multiple versions detected: ${existingVersion} vs ${version}`); } if (!existingVersion) { log_default.log(1, `deck.gl ${version}`)(); globalThis.deck = { ...globalThis.deck, VERSION: version, version, log: log_default, _registerLoggers: register }; registerLoaders([ json_loader_default, [ImageLoader, { imagebitmap: { premultiplyAlpha: "none" } }] ]); } return version; } var VERSION5 = checkVersion(); // src/shaderlib/misc/geometry.ts var defines = "#define SMOOTH_EDGE_RADIUS 0.5"; var vs2 = ` ${defines} struct VertexGeometry { vec4 position; vec3 worldPosition; vec3 worldPositionAlt; vec3 normal; vec2 uv; vec3 pickingColor; } geometry = VertexGeometry( vec4(0.0, 0.0, 1.0, 0.0), vec3(0.0), vec3(0.0), vec3(0.0), vec2(0.0), vec3(0.0) ); `; var fs2 = ` ${defines} struct FragmentGeometry { vec2 uv; } geometry; float smoothedge(float edge, float x) { return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x); } `; var geometry_default = { name: "geometry", vs: vs2, fs: fs2 }; // src/lib/constants.ts var COORDINATE_SYSTEM = { DEFAULT: -1, LNGLAT: 1, METER_OFFSETS: 2, LNGLAT_OFFSETS: 3, CARTESIAN: 0 }; Object.defineProperty(COORDINATE_SYSTEM, "IDENTITY", { get: () => { log_default.deprecated("COORDINATE_SYSTEM.IDENTITY", "COORDINATE_SYSTEM.CARTESIAN")(); return 0; } }); var PROJECTION_MODE = { WEB_MERCATOR: 1, GLOBE: 2, WEB_MERCATOR_AUTO_OFFSET: 4, IDENTITY: 0 }; var UNIT = { common: 0, meters: 1, pixels: 2 }; var EVENTS = { click: { handler: "onClick" }, panstart: { handler: "onDragStart" }, panmove: { handler: "onDrag" }, panend: { handler: "onDragEnd" } }; var OPERATION = { DRAW: "draw", MASK: "mask", TERRAIN: "terrain" }; // src/shaderlib/project/project.glsl.ts var COORDINATE_SYSTEM_GLSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const int COORDINATE_SYSTEM_${key} = ${COORDINATE_SYSTEM[key]};`).join(""); var PROJECTION_MODE_GLSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const int PROJECTION_MODE_${key} = ${PROJECTION_MODE[key]};`).join(""); var UNIT_GLSL_CONSTANTS = Object.keys(UNIT).map((key) => `const int UNIT_${key.toUpperCase()} = ${UNIT[key]};`).join(""); var project_glsl_default = `${COORDINATE_SYSTEM_GLSL_CONSTANTS} ${PROJECTION_MODE_GLSL_CONSTANTS} ${UNIT_GLSL_CONSTANTS} uniform int project_uCoordinateSystem; uniform int project_uProjectionMode; uniform float project_uScale; uniform bool project_uWrapLongitude; uniform vec3 project_uCommonUnitsPerMeter; uniform vec3 project_uCommonUnitsPerWorldUnit; uniform vec3 project_uCommonUnitsPerWorldUnit2; uniform vec4 project_uCenter; uniform mat4 project_uModelMatrix; uniform mat4 project_uViewProjectionMatrix; uniform vec2 project_uViewportSize; uniform float project_uDevicePixelRatio; uniform float project_uFocalDistance; uniform vec3 project_uCameraPosition; uniform vec3 project_uCoordinateOrigin; uniform vec3 project_uCommonOrigin; uniform bool project_uPseudoMeters; const float TILE_SIZE = 512.0; const float PI = 3.1415926536; const float WORLD_SCALE = TILE_SIZE / (PI * 2.0); const vec3 ZERO_64_LOW = vec3(0.0); const float EARTH_RADIUS = 6370972.0; // meters const float GLOBE_RADIUS = 256.0; // returns an adjustment factor for uCommonUnitsPerMeter float project_size_at_latitude(float lat) { float y = clamp(lat, -89.9, 89.9); return 1.0 / cos(radians(y)); } float project_size() { if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR && project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT && project_uPseudoMeters == false) { // uCommonUnitsPerMeter in low-zoom Web Mercator is non-linear // Adjust by 1 / cos(latitude) // If geometry.position (vertex in common space) is populated, use it // Otherwise use geometry.worldPosition (anchor in world space) if (geometry.position.w == 0.0) { return project_size_at_latitude(geometry.worldPosition.y); } // latitude from common y: 2.0 * (atan(exp(y / TILE_SIZE * 2.0 * PI - PI)) - PI / 4.0) // Taylor series of 1 / cos(latitude) // Max error < 0.003 float y = geometry.position.y / TILE_SIZE * 2.0 - 1.0; float y2 = y * y; float y4 = y2 * y2; float y6 = y4 * y2; return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6; } return 1.0; } float project_size_at_latitude(float meters, float lat) { return meters * project_uCommonUnitsPerMeter.z * project_size_at_latitude(lat); } // // Scaling offsets - scales meters to "world distance" // Note the scalar version of project_size is for scaling the z component only // float project_size(float meters) { return meters * project_uCommonUnitsPerMeter.z * project_size(); } vec2 project_size(vec2 meters) { return meters * project_uCommonUnitsPerMeter.xy * project_size(); } vec3 project_size(vec3 meters) { return meters * project_uCommonUnitsPerMeter * project_size(); } vec4 project_size(vec4 meters) { return vec4(meters.xyz * project_uCommonUnitsPerMeter, meters.w); } // Get rotation matrix that aligns the z axis with the given up vector // Find 3 unit vectors ux, uy, uz that are perpendicular to each other and uz == up mat3 project_get_orientation_matrix(vec3 up) { vec3 uz = normalize(up); // Tangent on XY plane vec3 ux = abs(uz.z) == 1.0 ? vec3(1.0, 0.0, 0.0) : normalize(vec3(uz.y, -uz.x, 0)); vec3 uy = cross(uz, ux); return mat3(ux, uy, uz); } bool project_needs_rotation(vec3 commonPosition, out mat3 transform) { if (project_uProjectionMode == PROJECTION_MODE_GLOBE) { transform = project_get_orientation_matrix(commonPosition); return true; } return false; } // // Projecting normal - transform deltas from current coordinate system to // normals in the worldspace // vec3 project_normal(vec3 vector) { // Apply model matrix vec4 normal_modelspace = project_uModelMatrix * vec4(vector, 0.0); vec3 n = normalize(normal_modelspace.xyz * project_uCommonUnitsPerMeter); mat3 rotation; if (project_needs_rotation(geometry.position.xyz, rotation)) { n = rotation * n; } return n; } vec4 project_offset_(vec4 offset) { float dy = offset.y; vec3 commonUnitsPerWorldUnit = project_uCommonUnitsPerWorldUnit + project_uCommonUnitsPerWorldUnit2 * dy; return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w); } // // Projecting positions - non-linear projection: lnglats => unit tile [0-1, 0-1] // vec2 project_mercator_(vec2 lnglat) { float x = lnglat.x; if (project_uWrapLongitude) { x = mod(x + 180., 360.0) - 180.; } float y = clamp(lnglat.y, -89.9, 89.9); return vec2( radians(x) + PI, PI + log(tan_fp32(PI * 0.25 + radians(y) * 0.5)) ) * WORLD_SCALE; } vec3 project_globe_(vec3 lnglatz) { float lambda = radians(lnglatz.x); float phi = radians(lnglatz.y); float cosPhi = cos(phi); float D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS; return vec3( sin(lambda) * cosPhi, -cos(lambda) * cosPhi, sin(phi) ) * D; } // // Projects positions (defined by project_uCoordinateSystem) to common space (defined by project_uProjectionMode) // vec4 project_position(vec4 position, vec3 position64Low) { vec4 position_world = project_uModelMatrix * position; // Work around for a Mac+NVIDIA bug https://github.com/visgl/deck.gl/issues/4145 if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR) { if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) { return vec4( project_mercator_(position_world.xy), project_size_at_latitude(position_world.z, position_world.y), position_world.w ); } if (project_uCoordinateSystem == COORDINATE_SYSTEM_CARTESIAN) { position_world.xyz += project_uCoordinateOrigin; } } if (project_uProjectionMode == PROJECTION_MODE_GLOBE) { if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) { return vec4( project_globe_(position_world.xyz), position_world.w ); } } if (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) { if (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT) { if (abs(position_world.y - project_uCoordinateOrigin.y) > 0.25) { // Too far from the projection center for offset mode to be accurate // Only use high parts return vec4( project_mercator_(position_world.xy) - project_uCommonOrigin.xy, project_size(position_world.z), position_world.w ); } } } if (project_uProjectionMode == PROJECTION_MODE_IDENTITY || (project_uProjectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET && (project_uCoordinateSystem == COORDINATE_SYSTEM_LNGLAT || project_uCoordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) { // Subtract high part of 64 bit value. Convert remainder to float32, preserving precision. position_world.xyz -= project_uCoordinateOrigin; } // Translation is already added to the high parts return project_offset_(position_world) + project_offset_(project_uModelMatrix * vec4(position64Low, 0.0)); } vec4 project_position(vec4 position) { return project_position(position, ZERO_64_LOW); } vec3 project_position(vec3 position, vec3 position64Low) { vec4 projected_position = project_position(vec4(position, 1.0), position64Low); return projected_position.xyz; } vec3 project_position(vec3 position) { vec4 projected_position = project_position(vec4(position, 1.0), ZERO_64_LOW); return projected_position.xyz; } vec2 project_position(vec2 position) { vec4 projected_position = project_position(vec4(position, 0.0, 1.0), ZERO_64_LOW); return projected_position.xy; } vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) { return viewProjectionMatrix * position + center; } // // Projects from common space coordinates to clip space. // Uses project_uViewProjectionMatrix // vec4 project_common_position_to_clipspace(vec4 position) { return project_common_position_to_clipspace(position, project_uViewProjectionMatrix, project_uCenter); } // Returns a clip space offset that corresponds to a given number of screen pixels vec2 project_pixel_size_to_clipspace(vec2 pixels) { vec2 offset = pixels / project_uViewportSize * project_uDevicePixelRatio * 2.0; return offset * project_uFocalDistance; } float project_size_to_pixel(float meters) { return project_size(meters) * project_uScale; } float project_size_to_pixel(float size, int unit) { if (unit == UNIT_METERS) return project_size_to_pixel(size); if (unit == UNIT_COMMON) return size * project_uScale; // UNIT_PIXELS return size; } float project_pixel_size(float pixels) { return pixels / project_uScale; } vec2 project_pixel_size(vec2 pixels) { return pixels / project_uScale; } `; // src/utils/memoize.ts function isEqual(a, b) { if (a === b) { return true; } if (Array.isArray(a)) { const len4 = a.length; if (!b || b.length !== len4) { return false; } for (let i = 0; i < len4; i++) { if (a[i] !== b[i]) { return false; } } return true; } return false; } function memoize(compute) { let cachedArgs = {}; let cachedResult; return (args) => { for (const key in args) { if (!isEqual(args[key], cachedArgs[key])) { cachedResult = compute(args); cachedArgs = args; break; } } return cachedResult; }; } // src/shaderlib/project/viewport-uniforms.ts var ZERO_VECTOR = [0, 0, 0, 0]; var VECTOR_TO_POINT_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]; var IDENTITY_MATRIX2 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; var DEFAULT_PIXELS_PER_UNIT2 = [0, 0, 0]; var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0]; var getMemoizedViewportUniforms = memoize(calculateViewportUniforms); function getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin = DEFAULT_COORDINATE_ORIGIN) { if (coordinateOrigin.length < 3) { coordinateOrigin = [coordinateOrigin[0], coordinateOrigin[1], 0]; } let shaderCoordinateOrigin = coordinateOrigin; let geospatialOrigin; let offsetMode = true; if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) { geospatialOrigin = coordinateOrigin; } else { geospatialOrigin = viewport.isGeospatial ? [Math.fround(viewport.longitude), Math.fround(viewport.latitude), 0] : null; } switch (viewport.projectionMode) { case PROJECTION_MODE.WEB_MERCATOR: if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) { geospatialOrigin = [0, 0, 0]; offsetMode = false; } break; case PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET: if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) { shaderCoordinateOrigin = geospatialOrigin; } else if (coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) { shaderCoordinateOrigin = [ Math.fround(viewport.center[0]), Math.fround(viewport.center[1]), 0 ]; geospatialOrigin = viewport.unprojectPosition(shaderCoordinateOrigin); shaderCoordinateOrigin[0] -= coordinateOrigin[0]; shaderCoordinateOrigin[1] -= coordinateOrigin[1]; shaderCoordinateOrigin[2] -= coordinateOrigin[2]; } break; case PROJECTION_MODE.IDENTITY: shaderCoordinateOrigin = viewport.position.map(Math.fround); shaderCoordinateOrigin[2] = shaderCoordinateOrigin[2] || 0; break; case PROJECTION_MODE.GLOBE: offsetMode = false; geospatialOrigin = null; break; default: offsetMode = false; } return { geospatialOrigin, shaderCoordinateOrigin, offsetMode }; } function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin) { const { viewMatrixUncentered, projectionMatrix } = viewport; let { viewMatrix: viewMatrix2, viewProjectionMatrix } = viewport; let projectionCenter = ZERO_VECTOR; let originCommon = ZERO_VECTOR; let cameraPosCommon = viewport.cameraPosition; const { geospatialOrigin, shaderCoordinateOrigin, offsetMode } = getOffsetOrigin( viewport, coordinateSystem, coordinateOrigin ); if (offsetMode) { originCommon = viewport.projectPosition(geospatialOrigin || shaderCoordinateOrigin); cameraPosCommon = [ cameraPosCommon[0] - originCommon[0], cameraPosCommon[1] - originCommon[1], cameraPosCommon[2] - originCommon[2] ]; originCommon[3] = 1; projectionCenter = vec4_exports.transformMat4([], originCommon, viewProjectionMatrix); viewMatrix2 = viewMatrixUncentered || viewMatrix2; viewProjectionMatrix = mat4_exports.multiply([], projectionMatrix, viewMatrix2); viewProjectionMatrix = mat4_exports.multiply([], viewProjectionMatrix, VECTOR_TO_POINT_MATRIX); } return { viewMatrix: viewMatrix2, viewProjectionMatrix, projectionCenter, originCommon, cameraPosCommon, shaderCoordinateOrigin, geospatialOrigin }; } function getUniformsFromViewport({ viewport, devicePixelRatio = 1, modelMatrix = null, coordinateSystem = COORDINATE_SYSTEM.DEFAULT, coordinateOrigin = DEFAULT_COORDINATE_ORIGIN, autoWrapLongitude = false }) { if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) { coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN; } const uniforms = getMemoizedViewportUniforms({ viewport, devicePixelRatio, coordinateSystem, coordinateOrigin }); uniforms.project_uWrapLongitude = autoWrapLongitude; uniforms.project_uModelMatrix = modelMatrix || IDENTITY_MATRIX2; return uniforms; } function calculateViewportUniforms({ viewport, devicePixelRatio, coordinateSystem, coordinateOrigin }) { const { projectionCenter, viewProjectionMatrix, originCommon, cameraPosCommon, shaderCoordinateOrigin, geospatialOrigin } = calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin); const distanceScales = viewport.getDistanceScales(); const viewportSize = [ viewport.width * devicePixelRatio, viewport.height * devicePixelRatio ]; const focalDistance = vec4_exports.transformMat4([], [0, 0, -viewport.focalDistance, 1], viewport.projectionMatrix)[3] || 1; const uniforms = { project_uCoordinateSystem: coordinateSystem, project_uProjectionMode: viewport.projectionMode, project_uCoordinateOrigin: shaderCoordinateOrigin, project_uCommonOrigin: originCommon.slice(0, 3), project_uCenter: projectionCenter, project_uPseudoMeters: Boolean(viewport._pseudoMeters), project_uViewportSize: viewportSize, project_uDevicePixelRatio: devicePixelRatio, project_uFocalDistance: focalDistance, project_uCommonUnitsPerMeter: distanceScales.unitsPerMeter, project_uCommonUnitsPerWorldUnit: distanceScales.unitsPerMeter, project_uCommonUnitsPerWorldUnit2: DEFAULT_PIXELS_PER_UNIT2, project_uScale: viewport.scale, project_uWrapLongitude: false, project_uViewProjectionMatrix: viewProjectionMatrix, project_uModelMatrix: IDENTITY_MATRIX2, project_uCameraPosition: cameraPosCommon }; if (geospatialOrigin) { const distanceScalesAtOrigin = viewport.getDistanceScales(geospatialOrigin); switch (coordinateSystem) { case COORDINATE_SYSTEM.METER_OFFSETS: uniforms.project_uCommonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter; uniforms.project_uCommonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2; break; case COORDINATE_SYSTEM.LNGLAT: case COORDINATE_SYSTEM.LNGLAT_OFFSETS: if (!viewport._pseudoMeters) { uniforms.project_uCommonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter; } uniforms.project_uCommonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerDegree; uniforms.project_uCommonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerDegree2; break; case COORDINATE_SYSTEM.CARTESIAN: uniforms.project_uCommonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]]; uniforms.project_uCommonUnitsPerWorldUnit2 = [ 0, 0, distanceScalesAtOrigin.unitsPerMeter2[2] ]; break; default: break; } } return uniforms; } // src/shaderlib/project/project.ts var INITIAL_MODULE_OPTIONS3 = {}; function getUniforms5(opts = INITIAL_MODULE_OPTIONS3) { if ("viewport" in opts) { return getUniformsFromViewport(opts); } return {}; } var project_default = { name: "project", dependencies: [fp32, geometry_default], vs: project_glsl_default, getUniforms: getUniforms5 }; // src/shaderlib/project32/project32.ts var vs3 = ` vec4 project_position_to_clipspace( vec3 position, vec3 position64Low, vec3 offset, out vec4 commonPosition ) { vec3 projectedPosition = project_position(position, position64Low); mat3 rotation; if (project_needs_rotation(projectedPosition, rotation)) { // offset is specified as ENU // when in globe projection, rotate offset so that the ground alighs with the surface of the globe offset = rotation * offset; } commonPosition = vec4(projectedPosition + offset, 1.0); return project_common_position_to_clipspace(commonPosition); } vec4 project_position_to_clipspace( vec3 position, vec3 position64Low, vec3 offset ) { vec4 commonPosition; return project_position_to_clipspace(position, position64Low, offset, commonPosition); } `; var project32_default = { name: "project32", dependencies: [project_default], vs: vs3 }; // ../../node_modules/@math.gl/web-mercator/dist/math-utils.js function createMat4() { return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } function transformVector(matrix, vector) { const result = vec4_exports.transformMat4([], vector, matrix); vec4_exports.scale(result, result, 1 / result[3]); return result; } function mod(value, divisor) { const modulus = value % divisor; return modulus < 0 ? divisor + modulus : modulus; } function lerp5(start, end, step) { return step * end + (1 - step) * start; } function clamp2(x, min4, max4) { return x < min4 ? min4 : x > max4 ? max4 : x; } function ieLog2(x) { return Math.log(x) * Math.LOG2E; } var log22 = Math.log2 || ieLog2; // ../../node_modules/@math.gl/web-mercator/dist/assert.js function assert7(condition, message2) { if (!condition) { throw new Error(message2 || "@math.gl/web-mercator: assertion failed."); } } // ../../node_modules/@math.gl/web-mercator/dist/web-mercator-utils.js var PI = Math.PI; var PI_4 = PI / 4; var DEGREES_TO_RADIANS2 = PI / 180; var RADIANS_TO_DEGREES2 = 180 / PI; var TILE_SIZE = 512; var EARTH_CIRCUMFERENCE = 4003e4; var MAX_LATITUDE = 85.051129; var DEFAULT_ALTITUDE = 1.5; function zoomToScale(zoom) { return Math.pow(2, zoom); } function scaleToZoom(scale5) { return log22(scale5); } function lngLatToWorld(lngLat) { const [lng, lat] = lngLat; assert7(Number.isFinite(lng)); assert7(Number.isFinite(lat) && lat >= -90 && lat <= 90, "invalid latitude"); const lambda2 = lng * DEGREES_TO_RADIANS2; const phi2 = lat * DEGREES_TO_RADIANS2; const x = TILE_SIZE * (lambda2 + PI) / (2 * PI); const y = TILE_SIZE * (PI + Math.log(Math.tan(PI_4 + phi2 * 0.5))) / (2 * PI); return [x, y]; } function worldToLngLat(xy) { const [x, y] = xy; const lambda2 = x / TILE_SIZE * (2 * PI) - PI; const phi2 = 2 * (Math.atan(Math.exp(y / TILE_SIZE * (2 * PI) - PI)) - PI_4); return [lambda2 * RADIANS_TO_DEGREES2, phi2 * RADIANS_TO_DEGREES2]; } function getMeterZoom(options) { const { latitude } = options; assert7(Number.isFinite(latitude)); const latCosine = Math.cos(latitude * DEGREES_TO_RADIANS2); return scaleToZoom(EARTH_CIRCUMFERENCE * latCosine) - 9; } function unitsPerMeter(latitude) { const latCosine = Math.cos(latitude * DEGREES_TO_RADIANS2); return TILE_SIZE / EARTH_CIRCUMFERENCE / latCosine; } function getDistanceScales(options) { const { latitude, longitude, highPrecision = false } = options; assert7(Number.isFinite(latitude) && Number.isFinite(longitude)); const worldSize = TILE_SIZE; const latCosine = Math.cos(latitude * DEGREES_TO_RADIANS2); const unitsPerDegreeX = worldSize / 360; const unitsPerDegreeY = unitsPerDegreeX / latCosine; const altUnitsPerMeter = worldSize / EARTH_CIRCUMFERENCE / latCosine; const result = { unitsPerMeter: [altUnitsPerMeter, altUnitsPerMeter, altUnitsPerMeter], metersPerUnit: [1 / altUnitsPerMeter, 1 / altUnitsPerMeter, 1 / altUnitsPerMeter], unitsPerDegree: [unitsPerDegreeX, unitsPerDegreeY, altUnitsPerMeter], degreesPerUnit: [1 / unitsPerDegreeX, 1 / unitsPerDegreeY, 1 / altUnitsPerMeter] }; if (highPrecision) { const latCosine2 = DEGREES_TO_RADIANS2 * Math.tan(latitude * DEGREES_TO_RADIANS2) / latCosine; const unitsPerDegreeY2 = unitsPerDegreeX * latCosine2 / 2; const altUnitsPerDegree2 = worldSize / EARTH_CIRCUMFERENCE * latCosine2; const altUnitsPerMeter2 = altUnitsPerDegree2 / unitsPerDegreeY * altUnitsPerMeter; result.unitsPerDegree2 = [0, unitsPerDegreeY2, altUnitsPerDegree2]; result.unitsPerMeter2 = [altUnitsPerMeter2, 0, altUnitsPerMeter2]; } return result; } function addMetersToLngLat(lngLatZ, xyz) { const [longitude, latitude, z0] = lngLatZ; const [x, y, z] = xyz; const { unitsPerMeter: unitsPerMeter2, unitsPerMeter2: unitsPerMeter22 } = getDistanceScales({ longitude, latitude, highPrecision: true }); const worldspace = lngLatToWorld(lngLatZ); worldspace[0] += x * (unitsPerMeter2[0] + unitsPerMeter22[0] * y); worldspace[1] += y * (unitsPerMeter2[1] + unitsPerMeter22[1] * y); const newLngLat = worldToLngLat(worldspace); const newZ = (z0 || 0) + (z || 0); return Number.isFinite(z0) || Number.isFinite(z) ? [newLngLat[0], newLngLat[1], newZ] : newLngLat; } function getViewMatrix(options) { const { height, pitch, bearing, altitude, scale: scale5, center } = options; const vm = createMat4(); mat4_exports.translate(vm, vm, [0, 0, -altitude]); mat4_exports.rotateX(vm, vm, -pitch * DEGREES_TO_RADIANS2); mat4_exports.rotateZ(vm, vm, bearing * DEGREES_TO_RADIANS2); const relativeScale = scale5 / height; mat4_exports.scale(vm, vm, [relativeScale, relativeScale, relativeScale]); if (center) { mat4_exports.translate(vm, vm, vec3_exports.negate([], center)); } return vm; } function getProjectionParameters(options) { const { width, height, altitude, pitch = 0, offset, center, scale: scale5, nearZMultiplier = 1, farZMultiplier = 1 } = options; let { fovy = altitudeToFovy(DEFAULT_ALTITUDE) } = options; if (altitude !== void 0) { fovy = altitudeToFovy(altitude); } const fovRadians = fovy * DEGREES_TO_RADIANS2; const pitchRadians = pitch * DEGREES_TO_RADIANS2; const focalDistance = fovyToAltitude(fovy); let cameraToSeaLevelDistance = focalDistance; if (center) { cameraToSeaLevelDistance += center[2] * scale5 / Math.cos(pitchRadians) / height; } const fovAboveCenter = fovRadians * (0.5 + (offset ? offset[1] : 0) / height); const topHalfSurfaceDistance = Math.sin(fovAboveCenter) * cameraToSeaLevelDistance / Math.sin(clamp2(Math.PI / 2 - pitchRadians - fovAboveCenter, 0.01, Math.PI - 0.01)); const furthestDistance = Math.sin(pitchRadians) * topHalfSurfaceDistance + cameraToSeaLevelDistance; const horizonDistance = cameraToSeaLevelDistance * 10; const farZ = Math.min(furthestDistance * farZMultiplier, horizonDistance); return { fov: fovRadians, aspect: width / height, focalDistance, near: nearZMultiplier, far: farZ }; } function altitudeToFovy(altitude) { return 2 * Math.atan(0.5 / altitude) * RADIANS_TO_DEGREES2; } function fovyToAltitude(fovy) { return 0.5 / Math.tan(0.5 * fovy * DEGREES_TO_RADIANS2); } function worldToPixels(xyz, pixelProjectionMatrix) { const [x, y, z = 0] = xyz; assert7(Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(z)); return transformVector(pixelProjectionMatrix, [x, y, z, 1]); } function pixelsToWorld(xyz, pixelUnprojectionMatrix, targetZ = 0) { const [x, y, z] = xyz; assert7(Number.isFinite(x) && Number.isFinite(y), "invalid pixel coordinate"); if (Number.isFinite(z)) { const coord = transformVector(pixelUnprojectionMatrix, [x, y, z, 1]); return coord; } const coord0 = transformVector(pixelUnprojectionMatrix, [x, y, 0, 1]); const coord1 = transformVector(pixelUnprojectionMatrix, [x, y, 1, 1]); const z0 = coord0[2]; const z1 = coord1[2]; const t = z0 === z1 ? 0 : ((targetZ || 0) - z0) / (z1 - z0); return vec2_exports.lerp([], coord0, coord1, t); } // ../../node_modules/@math.gl/web-mercator/dist/fit-bounds.js function fitBounds(options) { const { width, height, bounds, minExtent = 0, maxZoom = 24, offset = [0, 0] } = options; const [[west, south], [east, north]] = bounds; const padding = getPaddingObject(options.padding); const nw = lngLatToWorld([west, clamp2(north, -MAX_LATITUDE, MAX_LATITUDE)]); const se = lngLatToWorld([east, clamp2(south, -MAX_LATITUDE, MAX_LATITUDE)]); const size = [ Math.max(Math.abs(se[0] - nw[0]), minExtent), Math.max(Math.abs(se[1] - nw[1]), minExtent) ]; const targetSize = [ width - padding.left - padding.right - Math.abs(offset[0]) * 2, height - padding.top - padding.bottom - Math.abs(offset[1]) * 2 ]; assert7(targetSize[0] > 0 && targetSize[1] > 0); const scaleX2 = targetSize[0] / size[0]; const scaleY2 = targetSize[1] / size[1]; const offsetX = (padding.right - padding.left) / 2 / scaleX2; const offsetY = (padding.top - padding.bottom) / 2 / scaleY2; const center = [(se[0] + nw[0]) / 2 + offsetX, (se[1] + nw[1]) / 2 + offsetY]; const centerLngLat = worldToLngLat(center); const zoom = Math.min(maxZoom, log22(Math.abs(Math.min(scaleX2, scaleY2)))); assert7(Number.isFinite(zoom)); return { longitude: centerLngLat[0], latitude: centerLngLat[1], zoom }; } function getPaddingObject(padding = 0) { if (typeof padding === "number") { return { top: padding, bottom: padding, left: padding, right: padding }; } assert7(Number.isFinite(padding.top) && Number.isFinite(padding.bottom) && Number.isFinite(padding.left) && Number.isFinite(padding.right)); return padding; } // ../../node_modules/@math.gl/web-mercator/dist/get-bounds.js var DEGREES_TO_RADIANS3 = Math.PI / 180; function getBounds(viewport, z = 0) { const { width, height, unproject } = viewport; const unprojectOps = { targetZ: z }; const bottomLeft = unproject([0, height], unprojectOps); const bottomRight = unproject([width, height], unprojectOps); let topLeft; let topRight; const halfFov = viewport.fovy ? 0.5 * viewport.fovy * DEGREES_TO_RADIANS3 : Math.atan(0.5 / viewport.altitude); const angleToGround = (90 - viewport.pitch) * DEGREES_TO_RADIANS3; if (halfFov > angleToGround - 0.01) { topLeft = unprojectOnFarPlane(viewport, 0, z); topRight = unprojectOnFarPlane(viewport, width, z); } else { topLeft = unproject([0, 0], unprojectOps); topRight = unproject([width, 0], unprojectOps); } return [bottomLeft, bottomRight, topRight, topLeft]; } function unprojectOnFarPlane(viewport, x, targetZ) { const { pixelUnprojectionMatrix } = viewport; const coord0 = transformVector(pixelUnprojectionMatrix, [x, 0, 1, 1]); const coord1 = transformVector(pixelUnprojectionMatrix, [x, viewport.height, 1, 1]); const z = targetZ * viewport.distanceScales.unitsPerMeter[2]; const t = (z - coord0[2]) / (coord1[2] - coord0[2]); const coord = vec2_exports.lerp([], coord0, coord1, t); const result = worldToLngLat(coord); result.push(targetZ); return result; } // ../../node_modules/@math.gl/web-mercator/dist/normalize-viewport-props.js var TILE_SIZE2 = 512; function normalizeViewportProps(props) { const { width, height, pitch = 0 } = props; let { longitude, latitude, zoom, bearing = 0 } = props; if (longitude < -180 || longitude > 180) { longitude = mod(longitude + 180, 360) - 180; } if (bearing < -180 || bearing > 180) { bearing = mod(bearing + 180, 360) - 180; } const minZoom = log22(height / TILE_SIZE2); if (zoom <= minZoom) { zoom = minZoom; latitude = 0; } else { const halfHeightPixels = height / 2 / Math.pow(2, zoom); const minLatitude = worldToLngLat([0, halfHeightPixels])[1]; if (latitude < minLatitude) { latitude = minLatitude; } else { const maxLatitude = worldToLngLat([0, TILE_SIZE2 - halfHeightPixels])[1]; if (latitude > maxLatitude) { latitude = maxLatitude; } } } return { width, height, longitude, latitude, zoom, pitch, bearing }; } // ../../node_modules/@math.gl/web-mercator/dist/fly-to-viewport.js var EPSILON3 = 0.01; var VIEWPORT_TRANSITION_PROPS = ["longitude", "latitude", "zoom"]; var DEFAULT_OPTS = { curve: 1.414, speed: 1.2 }; function flyToViewport(startProps, endProps, t, options) { const { startZoom, startCenterXY, uDelta, w0, u1, S, rho, rho2, r0 } = getFlyToTransitionParams(startProps, endProps, options); if (u1 < EPSILON3) { const viewport = {}; for (const key of VIEWPORT_TRANSITION_PROPS) { const startValue = startProps[key]; const endValue = endProps[key]; viewport[key] = lerp5(startValue, endValue, t); } return viewport; } const s = t * S; const w = Math.cosh(r0) / Math.cosh(r0 + rho * s); const u = w0 * ((Math.cosh(r0) * Math.tanh(r0 + rho * s) - Math.sinh(r0)) / rho2) / u1; const scaleIncrement = 1 / w; const newZoom = startZoom + scaleToZoom(scaleIncrement); const newCenterWorld = vec2_exports.scale([], uDelta, u); vec2_exports.add(newCenterWorld, newCenterWorld, startCenterXY); const newCenter = worldToLngLat(newCenterWorld); return { longitude: newCenter[0], latitude: newCenter[1], zoom: newZoom }; } function getFlyToDuration(startProps, endProps, options) { const opts = { ...DEFAULT_OPTS, ...options }; const { screenSpeed, speed, maxDuration } = opts; const { S, rho } = getFlyToTransitionParams(startProps, endProps, opts); const length4 = 1e3 * S; let duration; if (Number.isFinite(screenSpeed)) { duration = length4 / (screenSpeed / rho); } else { duration = length4 / speed; } return Number.isFinite(maxDuration) && duration > maxDuration ? 0 : duration; } function getFlyToTransitionParams(startProps, endProps, opts) { opts = Object.assign({}, DEFAULT_OPTS, opts); const rho = opts.curve; const startZoom = startProps.zoom; const startCenter = [startProps.longitude, startProps.latitude]; const startScale = zoomToScale(startZoom); const endZoom = endProps.zoom; const endCenter = [endProps.longitude, endProps.latitude]; const scale5 = zoomToScale(endZoom - startZoom); const startCenterXY = lngLatToWorld(startCenter); const endCenterXY = lngLatToWorld(endCenter); const uDelta = vec2_exports.sub([], endCenterXY, startCenterXY); const w0 = Math.max(startProps.width, startProps.height); const w1 = w0 / scale5; const u1 = vec2_exports.length(uDelta) * startScale; const _u1 = Math.max(u1, EPSILON3); const rho2 = rho * rho; const b0 = (w1 * w1 - w0 * w0 + rho2 * rho2 * _u1 * _u1) / (2 * w0 * rho2 * _u1); const b1 = (w1 * w1 - w0 * w0 - rho2 * rho2 * _u1 * _u1) / (2 * w1 * rho2 * _u1); const r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0); const r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); const S = (r1 - r0) / rho; return { startZoom, startCenterXY, uDelta, w0, u1, S, rho, rho2, r0, r1 }; } // src/shaderlib/shadow/shadow.ts var vs4 = ` const int max_lights = 2; uniform mat4 shadow_uViewProjectionMatrices[max_lights]; uniform vec4 shadow_uProjectCenters[max_lights]; uniform bool shadow_uDrawShadowMap; uniform bool shadow_uUseShadowMap; uniform int shadow_uLightId; uniform float shadow_uLightCount; out vec3 shadow_vPosition[max_lights]; vec4 shadow_setVertexPosition(vec4 position_commonspace) { if (shadow_uDrawShadowMap) { return project_common_position_to_clipspace(position_commonspace, shadow_uViewProjectionMatrices[shadow_uLightId], shadow_uProjectCenters[shadow_uLightId]); } if (shadow_uUseShadowMap) { for (int i = 0; i < max_lights; i++) { if(i < int(shadow_uLightCount)) { vec4 shadowMap_position = project_common_position_to_clipspace(position_commonspace, shadow_uViewProjectionMatrices[i], shadow_uProjectCenters[i]); shadow_vPosition[i] = (shadowMap_position.xyz / shadowMap_position.w + 1.0) / 2.0; } } } return gl_Position; } `; var fs3 = ` const int max_lights = 2; uniform bool shadow_uDrawShadowMap; uniform bool shadow_uUseShadowMap; uniform sampler2D shadow_uShadowMap0; uniform sampler2D shadow_uShadowMap1; uniform vec4 shadow_uColor; uniform float shadow_uLightCount; in vec3 shadow_vPosition[max_lights]; const vec4 bitPackShift = vec4(1.0, 255.0, 65025.0, 16581375.0); const vec4 bitUnpackShift = 1.0 / bitPackShift; const vec4 bitMask = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0); float shadow_getShadowWeight(vec3 position, sampler2D shadowMap) { vec4 rgbaDepth = texture(shadowMap, position.xy); float z = dot(rgbaDepth, bitUnpackShift); return smoothstep(0.001, 0.01, position.z - z); } vec4 shadow_filterShadowColor(vec4 color) { if (shadow_uDrawShadowMap) { vec4 rgbaDepth = fract(gl_FragCoord.z * bitPackShift); rgbaDepth -= rgbaDepth.gbaa * bitMask; return rgbaDepth; } if (shadow_uUseShadowMap) { float shadowAlpha = 0.0; shadowAlpha += shadow_getShadowWeight(shadow_vPosition[0], shadow_uShadowMap0); if(shadow_uLightCount > 1.0) { shadowAlpha += shadow_getShadowWeight(shadow_vPosition[1], shadow_uShadowMap1); } shadowAlpha *= shadow_uColor.a / shadow_uLightCount; float blendedAlpha = shadowAlpha + color.a * (1.0 - shadowAlpha); return vec4( mix(color.rgb, shadow_uColor.rgb, shadowAlpha / blendedAlpha), blendedAlpha ); } return color; } `; var getMemoizedViewportCenterPosition = memoize(getViewportCenterPosition); var getMemoizedViewProjectionMatrices = memoize(getViewProjectionMatrices); var DEFAULT_SHADOW_COLOR = [0, 0, 0, 1]; var VECTOR_TO_POINT_MATRIX2 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]; function screenToCommonSpace(xyz, pixelUnprojectionMatrix) { const [x, y, z] = xyz; const coord = pixelsToWorld([x, y, z], pixelUnprojectionMatrix); if (Number.isFinite(z)) { return coord; } return [coord[0], coord[1], 0]; } function getViewportCenterPosition({ viewport, center }) { return new Matrix4(viewport.viewProjectionMatrix).invert().transform(center); } function getViewProjectionMatrices({ viewport, shadowMatrices }) { const projectionMatrices = []; const pixelUnprojectionMatrix = viewport.pixelUnprojectionMatrix; const farZ = viewport.isGeospatial ? void 0 : 1; const corners = [ [0, 0, farZ], [viewport.width, 0, farZ], [0, viewport.height, farZ], [viewport.width, viewport.height, farZ], [0, 0, -1], [viewport.width, 0, -1], [0, viewport.height, -1], [viewport.width, viewport.height, -1] ].map( (pixel) => screenToCommonSpace(pixel, pixelUnprojectionMatrix) ); for (const shadowMatrix of shadowMatrices) { const viewMatrix2 = shadowMatrix.clone().translate(new Vector3(viewport.center).negate()); const positions = corners.map((corner) => viewMatrix2.transform(corner)); const projectionMatrix = new Matrix4().ortho({ left: Math.min(...positions.map((position) => position[0])), right: Math.max(...positions.map((position) => position[0])), bottom: Math.min(...positions.map((position) => position[1])), top: Math.max(...positions.map((position) => position[1])), near: Math.min(...positions.map((position) => -position[2])), far: Math.max(...positions.map((position) => -position[2])) }); projectionMatrices.push(projectionMatrix.multiplyRight(shadowMatrix)); } return projectionMatrices; } function createShadowUniforms(opts, context) { const { shadowEnabled = true } = opts; if (!shadowEnabled || !opts.shadowMatrices || !opts.shadowMatrices.length) { return { shadow_uDrawShadowMap: false, shadow_uUseShadowMap: false, shadow_uShadowMap0: opts.dummyShadowMap, shadow_uShadowMap1: opts.dummyShadowMap }; } const uniforms = { shadow_uDrawShadowMap: Boolean(opts.drawToShadowMap), shadow_uUseShadowMap: opts.shadowMaps ? opts.shadowMaps.length > 0 : false, shadow_uColor: opts.shadowColor || DEFAULT_SHADOW_COLOR, shadow_uLightId: opts.shadowLightId || 0, shadow_uLightCount: opts.shadowMatrices.length }; const center = getMemoizedViewportCenterPosition({ viewport: opts.viewport, center: context.project_uCenter }); const projectCenters = []; const viewProjectionMatrices = getMemoizedViewProjectionMatrices({ shadowMatrices: opts.shadowMatrices, viewport: opts.viewport }).slice(); for (let i = 0; i < opts.shadowMatrices.length; i++) { const viewProjectionMatrix = viewProjectionMatrices[i]; const viewProjectionMatrixCentered = viewProjectionMatrix.clone().translate(new Vector3(opts.viewport.center).negate()); if (context.project_uCoordinateSystem === COORDINATE_SYSTEM.LNGLAT && context.project_uProjectionMode === PROJECTION_MODE.WEB_MERCATOR) { viewProjectionMatrices[i] = viewProjectionMatrixCentered; projectCenters[i] = center; } else { viewProjectionMatrices[i] = viewProjectionMatrix.clone().multiplyRight(VECTOR_TO_POINT_MATRIX2); projectCenters[i] = viewProjectionMatrixCentered.transform(center); } } for (let i = 0; i < viewProjectionMatrices.length; i++) { uniforms[`shadow_uViewProjectionMatrices[${i}]`] = viewProjectionMatrices[i]; uniforms[`shadow_uProjectCenters[${i}]`] = projectCenters[i]; } for (let i = 0; i < 2; i++) { uniforms[`shadow_uShadowMap${i}`] = opts.shadowMaps && opts.shadowMaps[i] || opts.dummyShadowMap; } return uniforms; } var shadow_default = { name: "shadow", dependencies: [project_default], vs: vs4, fs: fs3, inject: { "vs:DECKGL_FILTER_GL_POSITION": ` position = shadow_setVertexPosition(geometry.position); `, "fs:DECKGL_FILTER_COLOR": ` color = shadow_filterShadowColor(color); ` }, getUniforms: (opts = {}, context = {}) => { if ("viewport" in opts && (opts.drawToShadowMap || opts.shadowMaps && opts.shadowMaps.length > 0)) { return createShadowUniforms(opts, context); } return {}; } }; // src/shaderlib/picking/picking.ts var picking_default = { ...picking, defaultUniforms: { ...picking.defaultUniforms, useFloatColors: false }, inject: { "vs:DECKGL_FILTER_GL_POSITION": ` // for picking depth values picking_setPickingAttribute(position.z / position.w); `, "vs:DECKGL_FILTER_COLOR": ` picking_setPickingColor(geometry.pickingColor); `, "fs:DECKGL_FILTER_COLOR": { order: 99, injection: ` // use highlight color if this fragment belongs to the selected object. color = picking_filterHighlightColor(color); // use picking color if rendering to picking FBO. color = picking_filterPickingColor(color); ` } } }; // src/shaderlib/index.ts var DEFAULT_MODULES = [project_default]; var SHADER_HOOKS = [ "vs:DECKGL_FILTER_SIZE(inout vec3 size, VertexGeometry geometry)", "vs:DECKGL_FILTER_GL_POSITION(inout vec4 position, VertexGeometry geometry)", "vs:DECKGL_FILTER_COLOR(inout vec4 color, VertexGeometry geometry)", "fs:DECKGL_FILTER_COLOR(inout vec4 color, FragmentGeometry geometry)" ]; function getShaderAssembler() { const shaderAssembler = ShaderAssembler.getDefaultShaderAssembler(); for (const shaderModule of DEFAULT_MODULES) { shaderAssembler.addDefaultModule(shaderModule); } for (const shaderHook of SHADER_HOOKS) { shaderAssembler.addShaderHook(shaderHook); } return shaderAssembler; } // src/effects/lighting/ambient-light.ts var DEFAULT_LIGHT_COLOR = [255, 255, 255]; var DEFAULT_LIGHT_INTENSITY = 1; var idCount = 0; var AmbientLight = class { constructor(props = {}) { this.type = "ambient"; const { color = DEFAULT_LIGHT_COLOR } = props; const { intensity = DEFAULT_LIGHT_INTENSITY } = props; this.id = props.id || `ambient-${idCount++}`; this.color = color; this.intensity = intensity; } }; // src/effects/lighting/directional-light.ts var DEFAULT_LIGHT_COLOR2 = [255, 255, 255]; var DEFAULT_LIGHT_INTENSITY2 = 1; var DEFAULT_LIGHT_DIRECTION = [0, 0, -1]; var idCount2 = 0; var DirectionalLight = class { constructor(props = {}) { this.type = "directional"; const { color = DEFAULT_LIGHT_COLOR2 } = props; const { intensity = DEFAULT_LIGHT_INTENSITY2 } = props; const { direction = DEFAULT_LIGHT_DIRECTION } = props; const { _shadow = false } = props; this.id = props.id || `directional-${idCount2++}`; this.color = color; this.intensity = intensity; this.type = "directional"; this.direction = new Vector3(direction).normalize().toArray(); this.shadow = _shadow; } getProjectedLight(opts) { return this; } }; // src/passes/pass.ts var Pass = class { constructor(device, props = { id: "pass" }) { const { id } = props; this.id = id; this.device = device; this.props = { ...props }; } setProps(props) { Object.assign(this.props, props); } render(params) { } cleanup() { } }; // src/passes/layers-pass.ts var LayersPass = class extends Pass { constructor() { super(...arguments); this._lastRenderIndex = -1; } render(options) { const [width, height] = this.device.canvasContext.getDrawingBufferSize(); const clearCanvas = options.clearCanvas ?? true; const clearColor = options.clearColor ?? (clearCanvas ? [0, 0, 0, 0] : false); const clearDepth = clearCanvas ? 1 : false; const clearStencil = clearCanvas ? 0 : false; const colorMask = options.colorMask ?? 15; const parameters = { viewport: [0, 0, width, height] }; if (options.colorMask) { parameters.colorMask = colorMask; } if (options.scissorRect) { parameters.scissorRect = options.scissorRect; } const renderPass = this.device.beginRenderPass({ framebuffer: options.target, parameters, clearColor, clearDepth, clearStencil }); try { return this._drawLayers(renderPass, options); } finally { renderPass.end(); } } _drawLayers(renderPass, options) { const { target, moduleParameters, viewports, views, onViewportActive, clearStack = true } = options; options.pass = options.pass || "unknown"; if (clearStack) { this._lastRenderIndex = -1; } const renderStats = []; for (const viewport of viewports) { const view = views && views[viewport.id]; onViewportActive?.(viewport); const drawLayerParams = this._getDrawLayerParams(viewport, options); const subViewports = viewport.subViewports || [viewport]; for (const subViewport of subViewports) { const stats2 = this._drawLayersInViewport( renderPass, { target, moduleParameters, viewport: subViewport, view, pass: options.pass, layers: options.layers }, drawLayerParams ); renderStats.push(stats2); } } return renderStats; } _getDrawLayerParams(viewport, { layers, pass, isPicking = false, layerFilter, cullRect, effects, moduleParameters }, evaluateShouldDrawOnly = false) { const drawLayerParams = []; const indexResolver = layerIndexResolver(this._lastRenderIndex + 1); const drawContext = { layer: layers[0], viewport, isPicking, renderPass: pass, cullRect }; const layerFilterCache = {}; for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) { const layer = layers[layerIndex]; const shouldDrawLayer = this._shouldDrawLayer( layer, drawContext, layerFilter, layerFilterCache ); const layerParam = { shouldDrawLayer }; if (shouldDrawLayer && !evaluateShouldDrawOnly) { layerParam.layerRenderIndex = indexResolver(layer, shouldDrawLayer); layerParam.moduleParameters = this._getModuleParameters( layer, effects, pass, moduleParameters ); layerParam.layerParameters = { ...layer.context.deck?.props.parameters, ...this.getLayerParameters(layer, layerIndex, viewport) }; } drawLayerParams[layerIndex] = layerParam; } return drawLayerParams; } _drawLayersInViewport(renderPass, { layers, moduleParameters: globalModuleParameters, pass, target, viewport, view }, drawLayerParams) { const glViewport = getGLViewport(this.device, { moduleParameters: globalModuleParameters, target, viewport }); if (view && view.props.clear) { const clearOpts = view.props.clear === true ? { color: true, depth: true } : view.props.clear; this.device.withParametersWebGL( { scissorTest: true, scissor: glViewport }, () => this.device.clearWebGL(clearOpts) ); } const renderStatus = { totalCount: layers.length, visibleCount: 0, compositeCount: 0, pickableCount: 0 }; renderPass.setParameters({ viewport: glViewport }); for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) { const layer = layers[layerIndex]; const { shouldDrawLayer, layerRenderIndex, moduleParameters, layerParameters } = drawLayerParams[layerIndex]; if (shouldDrawLayer && layer.props.pickable) { renderStatus.pickableCount++; } if (layer.isComposite) { renderStatus.compositeCount++; } else if (shouldDrawLayer) { renderStatus.visibleCount++; this._lastRenderIndex = Math.max(this._lastRenderIndex, layerRenderIndex); moduleParameters.viewport = viewport; layer.context.renderPass = renderPass; try { layer._drawLayer({ renderPass, moduleParameters, uniforms: { layerIndex: layerRenderIndex }, parameters: layerParameters }); } catch (err) { layer.raiseError(err, `drawing ${layer} to ${pass}`); } } } return renderStatus; } shouldDrawLayer(layer) { return true; } getModuleParameters(layer, effects) { return null; } getLayerParameters(layer, layerIndex, viewport) { return layer.props.parameters; } _shouldDrawLayer(layer, drawContext, layerFilter, layerFilterCache) { const shouldDrawLayer = layer.props.visible && this.shouldDrawLayer(layer); if (!shouldDrawLayer) { return false; } drawContext.layer = layer; let parent = layer.parent; while (parent) { if (!parent.props.visible || !parent.filterSubLayer(drawContext)) { return false; } drawContext.layer = parent; parent = parent.parent; } if (layerFilter) { const rootLayerId = drawContext.layer.id; if (!(rootLayerId in layerFilterCache)) { layerFilterCache[rootLayerId] = layerFilter(drawContext); } if (!layerFilterCache[rootLayerId]) { return false; } } layer.activateViewport(drawContext.viewport); return true; } _getModuleParameters(layer, effects, pass, overrides) { const devicePixelRatio = this.device.canvasContext.cssToDeviceRatio(); const moduleParameters = Object.assign( Object.create(layer.internalState?.propsInTransition || layer.props), { autoWrapLongitude: layer.wrapLongitude, viewport: layer.context.viewport, mousePosition: layer.context.mousePosition, picking: { isActive: 0 }, devicePixelRatio } ); if (effects) { for (const effect of effects) { Object.assign(moduleParameters, effect.getModuleParameters?.(layer)); } } return Object.assign(moduleParameters, this.getModuleParameters(layer, effects), overrides); } }; function layerIndexResolver(startIndex = 0, layerIndices = {}) { const resolvers = {}; const resolveLayerIndex = (layer, isDrawn) => { const indexOverride = layer.props._offset; const layerId = layer.id; const parentId = layer.parent && layer.parent.id; let index2; if (parentId && !(parentId in layerIndices)) { resolveLayerIndex(layer.parent, false); } if (parentId in resolvers) { const resolver = resolvers[parentId] = resolvers[parentId] || layerIndexResolver(layerIndices[parentId], layerIndices); index2 = resolver(layer, isDrawn); resolvers[layerId] = resolver; } else if (Number.isFinite(indexOverride)) { index2 = indexOverride + (layerIndices[parentId] || 0); resolvers[layerId] = null; } else { index2 = startIndex; } if (isDrawn && index2 >= startIndex) { startIndex = index2 + 1; } layerIndices[layerId] = index2; return index2; }; return resolveLayerIndex; } function getGLViewport(device, { moduleParameters, target, viewport }) { const pixelRatio = moduleParameters && moduleParameters.devicePixelRatio || device.canvasContext.cssToDeviceRatio(); const [, drawingBufferHeight] = device.canvasContext.getDrawingBufferSize(); const height = target ? target.height : drawingBufferHeight; const dimensions = viewport; return [ dimensions.x * pixelRatio, height - (dimensions.y + dimensions.height) * pixelRatio, dimensions.width * pixelRatio, dimensions.height * pixelRatio ]; } // src/passes/shadow-pass.ts var ShadowPass = class extends LayersPass { constructor(device, props) { super(device, props); this.shadowMap = device.createTexture({ width: 1, height: 1, sampler: { minFilter: "linear", magFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" } }); this.depthBuffer = device.createTexture({ format: "depth16unorm", width: 1, height: 1, mipmaps: false, dataFormat: 6402, type: 5125 }); this.fbo = device.createFramebuffer({ id: "shadowmap", width: 1, height: 1, colorAttachments: [this.shadowMap], depthStencilAttachment: this.depthBuffer }); } render(params) { const target = this.fbo; const pixelRatio = this.device.canvasContext.cssToDeviceRatio(); const viewport = params.viewports[0]; const width = viewport.width * pixelRatio; const height = viewport.height * pixelRatio; const clearColor = [1, 1, 1, 1]; if (width !== target.width || height !== target.height) { target.resize({ width, height }); } super.render({ ...params, clearColor, target, pass: "shadow" }); } getLayerParameters(layer, layerIndex, viewport) { return { ...layer.props.parameters, blend: false, depthRange: [0, 1], depthTest: true }; } shouldDrawLayer(layer) { return layer.props.shadowEnabled !== false; } getModuleParameters() { return { drawToShadowMap: true }; } delete() { if (this.fbo) { this.fbo.destroy(); this.fbo = null; } if (this.shadowMap) { this.shadowMap.destroy(); this.shadowMap = null; } if (this.depthBuffer) { this.depthBuffer.destroy(); this.depthBuffer = null; } } }; // src/effects/lighting/lighting-effect.ts var DEFAULT_AMBIENT_LIGHT_PROPS = { color: [255, 255, 255], intensity: 1 }; var DEFAULT_DIRECTIONAL_LIGHT_PROPS = [ { color: [255, 255, 255], intensity: 1, direction: [-1, 3, -1] }, { color: [255, 255, 255], intensity: 0.9, direction: [1, -8, -2.5] } ]; var DEFAULT_SHADOW_COLOR2 = [0, 0, 0, 200 / 255]; var LightingEffect = class { constructor(props = {}) { this.id = "lighting-effect"; this.shadowColor = DEFAULT_SHADOW_COLOR2; this.shadow = false; this.ambientLight = null; this.directionalLights = []; this.pointLights = []; this.shadowPasses = []; this.shadowMaps = []; this.dummyShadowMap = null; this.setProps(props); } setup(context) { this.context = context; const { device, deck } = context; if (this.shadow && !this.dummyShadowMap) { this._createShadowPasses(device); deck._addDefaultShaderModule(shadow_default); this.dummyShadowMap = device.createTexture({ width: 1, height: 1 }); } } setProps(props) { this.ambientLight = null; this.directionalLights = []; this.pointLights = []; for (const key in props) { const lightSource = props[key]; switch (lightSource.type) { case "ambient": this.ambientLight = lightSource; break; case "directional": this.directionalLights.push(lightSource); break; case "point": this.pointLights.push(lightSource); break; default: } } this._applyDefaultLights(); this.shadow = this.directionalLights.some((light) => light.shadow); if (this.context) { this.setup(this.context); } this.props = props; } preRender({ layers, layerFilter, viewports, onViewportActive, views }) { if (!this.shadow) return; this.shadowMatrices = this._calculateMatrices(); for (let i = 0; i < this.shadowPasses.length; i++) { const shadowPass = this.shadowPasses[i]; shadowPass.render({ layers, layerFilter, viewports, onViewportActive, views, moduleParameters: { shadowLightId: i, dummyShadowMap: this.dummyShadowMap, shadowMatrices: this.shadowMatrices } }); } } getModuleParameters(layer) { const parameters = this.shadow ? { shadowMaps: this.shadowMaps, dummyShadowMap: this.dummyShadowMap, shadowColor: this.shadowColor, shadowMatrices: this.shadowMatrices } : {}; parameters.lightSources = { ambientLight: this.ambientLight, directionalLights: this.directionalLights.map( (directionalLight) => directionalLight.getProjectedLight({ layer }) ), pointLights: this.pointLights.map((pointLight) => pointLight.getProjectedLight({ layer })) }; return parameters; } cleanup(context) { for (const shadowPass of this.shadowPasses) { shadowPass.delete(); } this.shadowPasses.length = 0; this.shadowMaps.length = 0; if (this.dummyShadowMap) { this.dummyShadowMap.destroy(); this.dummyShadowMap = null; context.deck._removeDefaultShaderModule(shadow_default); } } _calculateMatrices() { const lightMatrices = []; for (const light of this.directionalLights) { const viewMatrix2 = new Matrix4().lookAt({ eye: new Vector3(light.direction).negate() }); lightMatrices.push(viewMatrix2); } return lightMatrices; } _createShadowPasses(device) { for (let i = 0; i < this.directionalLights.length; i++) { const shadowPass = new ShadowPass(device); this.shadowPasses[i] = shadowPass; this.shadowMaps[i] = shadowPass.shadowMap; } } _applyDefaultLights() { const { ambientLight, pointLights, directionalLights } = this; if (!ambientLight && pointLights.length === 0 && directionalLights.length === 0) { this.ambientLight = new AmbientLight(DEFAULT_AMBIENT_LIGHT_PROPS); this.directionalLights.push( new DirectionalLight(DEFAULT_DIRECTIONAL_LIGHT_PROPS[0]), new DirectionalLight(DEFAULT_DIRECTIONAL_LIGHT_PROPS[1]) ); } } }; // src/utils/typed-array-manager.ts var TypedArrayManager = class { constructor(options = {}) { this._pool = []; this.opts = { overAlloc: 2, poolSize: 100 }; this.setOptions(options); } setOptions(options) { Object.assign(this.opts, options); } allocate(typedArray, count2, { size = 1, type, padding = 0, copy: copy5 = false, initialize = false, maxCount }) { const Type2 = type || typedArray && typedArray.constructor || Float32Array; const newSize = count2 * size + padding; if (ArrayBuffer.isView(typedArray)) { if (newSize <= typedArray.length) { return typedArray; } if (newSize * typedArray.BYTES_PER_ELEMENT <= typedArray.buffer.byteLength) { return new Type2(typedArray.buffer, 0, newSize); } } let maxSize = Infinity; if (maxCount) { maxSize = maxCount * size + padding; } const newArray = this._allocate(Type2, newSize, initialize, maxSize); if (typedArray && copy5) { newArray.set(typedArray); } else if (!initialize) { newArray.fill(0, 0, 4); } this._release(typedArray); return newArray; } release(typedArray) { this._release(typedArray); } _allocate(Type2, size, initialize, maxSize) { let sizeToAllocate = Math.max(Math.ceil(size * this.opts.overAlloc), 1); if (sizeToAllocate > maxSize) { sizeToAllocate = maxSize; } const pool = this._pool; const byteLength = Type2.BYTES_PER_ELEMENT * sizeToAllocate; const i = pool.findIndex((b) => b.byteLength >= byteLength); if (i >= 0) { const array = new Type2(pool.splice(i, 1)[0], 0, sizeToAllocate); if (initialize) { array.fill(0); } return array; } return new Type2(sizeToAllocate); } _release(typedArray) { if (!ArrayBuffer.isView(typedArray)) { return; } const pool = this._pool; const { buffer } = typedArray; const { byteLength } = buffer; const i = pool.findIndex((b) => b.byteLength >= byteLength); if (i < 0) { pool.push(buffer); } else if (i > 0 || pool.length < this.opts.poolSize) { pool.splice(i, 0, buffer); } if (pool.length > this.opts.poolSize) { pool.shift(); } } }; var typed_array_manager_default = new TypedArrayManager(); // src/utils/math-utils.ts function createMat42() { return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; } function mod2(value, divisor) { const modulus = value % divisor; return modulus < 0 ? divisor + modulus : modulus; } function getCameraPosition(viewMatrixInverse) { return [viewMatrixInverse[12], viewMatrixInverse[13], viewMatrixInverse[14]]; } function getFrustumPlanes(viewProjectionMatrix) { return { left: getFrustumPlane( viewProjectionMatrix[3] + viewProjectionMatrix[0], viewProjectionMatrix[7] + viewProjectionMatrix[4], viewProjectionMatrix[11] + viewProjectionMatrix[8], viewProjectionMatrix[15] + viewProjectionMatrix[12] ), right: getFrustumPlane( viewProjectionMatrix[3] - viewProjectionMatrix[0], viewProjectionMatrix[7] - viewProjectionMatrix[4], viewProjectionMatrix[11] - viewProjectionMatrix[8], viewProjectionMatrix[15] - viewProjectionMatrix[12] ), bottom: getFrustumPlane( viewProjectionMatrix[3] + viewProjectionMatrix[1], viewProjectionMatrix[7] + viewProjectionMatrix[5], viewProjectionMatrix[11] + viewProjectionMatrix[9], viewProjectionMatrix[15] + viewProjectionMatrix[13] ), top: getFrustumPlane( viewProjectionMatrix[3] - viewProjectionMatrix[1], viewProjectionMatrix[7] - viewProjectionMatrix[5], viewProjectionMatrix[11] - viewProjectionMatrix[9], viewProjectionMatrix[15] - viewProjectionMatrix[13] ), near: getFrustumPlane( viewProjectionMatrix[3] + viewProjectionMatrix[2], viewProjectionMatrix[7] + viewProjectionMatrix[6], viewProjectionMatrix[11] + viewProjectionMatrix[10], viewProjectionMatrix[15] + viewProjectionMatrix[14] ), far: getFrustumPlane( viewProjectionMatrix[3] - viewProjectionMatrix[2], viewProjectionMatrix[7] - viewProjectionMatrix[6], viewProjectionMatrix[11] - viewProjectionMatrix[10], viewProjectionMatrix[15] - viewProjectionMatrix[14] ) }; } var scratchVector = new Vector3(); function getFrustumPlane(a, b, c, d) { scratchVector.set(a, b, c); const L = scratchVector.len(); return { distance: d / L, normal: new Vector3(-a / L, -b / L, -c / L) }; } function fp64LowPart2(x) { return x - Math.fround(x); } var scratchArray; function toDoublePrecisionArray(typedArray, options) { const { size = 1, startIndex = 0 } = options; const endIndex = options.endIndex !== void 0 ? options.endIndex : typedArray.length; const count2 = (endIndex - startIndex) / size; scratchArray = typed_array_manager_default.allocate(scratchArray, count2, { type: Float32Array, size: size * 2 }); let sourceIndex = startIndex; let targetIndex = 0; while (sourceIndex < endIndex) { for (let j = 0; j < size; j++) { const value = typedArray[sourceIndex++]; scratchArray[targetIndex + j] = value; scratchArray[targetIndex + j + size] = fp64LowPart2(value); } targetIndex += size * 2; } return scratchArray.subarray(0, count2 * size * 2); } function mergeBounds(boundsList) { let mergedBounds = null; let isMerged = false; for (const bounds of boundsList) { if (!bounds) continue; if (!mergedBounds) { mergedBounds = bounds; } else { if (!isMerged) { mergedBounds = [ [mergedBounds[0][0], mergedBounds[0][1]], [mergedBounds[1][0], mergedBounds[1][1]] ]; isMerged = true; } mergedBounds[0][0] = Math.min(mergedBounds[0][0], bounds[0][0]); mergedBounds[0][1] = Math.min(mergedBounds[0][1], bounds[0][1]); mergedBounds[1][0] = Math.max(mergedBounds[1][0], bounds[1][0]); mergedBounds[1][1] = Math.max(mergedBounds[1][1], bounds[1][1]); } } return mergedBounds; } // src/viewports/viewport.ts var DEGREES_TO_RADIANS4 = Math.PI / 180; var IDENTITY2 = createMat42(); var ZERO_VECTOR2 = [0, 0, 0]; var DEFAULT_DISTANCE_SCALES = { unitsPerMeter: [1, 1, 1], metersPerUnit: [1, 1, 1] }; function createProjectionMatrix({ width, height, orthographic, fovyRadians, focalDistance, padding, near, far }) { const aspect = width / height; const matrix = orthographic ? new Matrix4().orthographic({ fovy: fovyRadians, aspect, focalDistance, near, far }) : new Matrix4().perspective({ fovy: fovyRadians, aspect, near, far }); if (padding) { const { left = 0, right = 0, top = 0, bottom = 0 } = padding; const offsetX = clamp((left + width - right) / 2, 0, width) - width / 2; const offsetY = clamp((top + height - bottom) / 2, 0, height) - height / 2; matrix[8] -= offsetX * 2 / width; matrix[9] += offsetY * 2 / height; } return matrix; } var _Viewport = class { constructor(opts = {}) { this._frustumPlanes = {}; this.id = opts.id || this.constructor.displayName || "viewport"; this.x = opts.x || 0; this.y = opts.y || 0; this.width = opts.width || 1; this.height = opts.height || 1; this.zoom = opts.zoom || 0; this.padding = opts.padding; this.distanceScales = opts.distanceScales || DEFAULT_DISTANCE_SCALES; this.focalDistance = opts.focalDistance || 1; this.position = opts.position || ZERO_VECTOR2; this.modelMatrix = opts.modelMatrix || null; const { longitude, latitude } = opts; this.isGeospatial = Number.isFinite(latitude) && Number.isFinite(longitude); this._initProps(opts); this._initMatrices(opts); this.equals = this.equals.bind(this); this.project = this.project.bind(this); this.unproject = this.unproject.bind(this); this.projectPosition = this.projectPosition.bind(this); this.unprojectPosition = this.unprojectPosition.bind(this); this.projectFlat = this.projectFlat.bind(this); this.unprojectFlat = this.unprojectFlat.bind(this); } get subViewports() { return null; } get metersPerPixel() { return this.distanceScales.metersPerUnit[2] / this.scale; } get projectionMode() { if (this.isGeospatial) { return this.zoom < 12 ? PROJECTION_MODE.WEB_MERCATOR : PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET; } return PROJECTION_MODE.IDENTITY; } equals(viewport) { if (!(viewport instanceof _Viewport)) { return false; } if (this === viewport) { return true; } return viewport.width === this.width && viewport.height === this.height && viewport.scale === this.scale && equals(viewport.projectionMatrix, this.projectionMatrix) && equals(viewport.viewMatrix, this.viewMatrix); } project(xyz, { topLeft = true } = {}) { const worldPosition = this.projectPosition(xyz); const coord = worldToPixels(worldPosition, this.pixelProjectionMatrix); const [x, y] = coord; const y2 = topLeft ? y : this.height - y; return xyz.length === 2 ? [x, y2] : [x, y2, coord[2]]; } unproject(xyz, { topLeft = true, targetZ } = {}) { const [x, y, z] = xyz; const y2 = topLeft ? y : this.height - y; const targetZWorld = targetZ && targetZ * this.distanceScales.unitsPerMeter[2]; const coord = pixelsToWorld([x, y2, z], this.pixelUnprojectionMatrix, targetZWorld); const [X, Y, Z] = this.unprojectPosition(coord); if (Number.isFinite(z)) { return [X, Y, Z]; } return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y]; } projectPosition(xyz) { const [X, Y] = this.projectFlat(xyz); const Z = (xyz[2] || 0) * this.distanceScales.unitsPerMeter[2]; return [X, Y, Z]; } unprojectPosition(xyz) { const [X, Y] = this.unprojectFlat(xyz); const Z = (xyz[2] || 0) * this.distanceScales.metersPerUnit[2]; return [X, Y, Z]; } projectFlat(xyz) { if (this.isGeospatial) { const result = lngLatToWorld(xyz); result[1] = clamp(result[1], -318, 830); return result; } return xyz; } unprojectFlat(xyz) { if (this.isGeospatial) { return worldToLngLat(xyz); } return xyz; } getBounds(options = {}) { const unprojectOption = { targetZ: options.z || 0 }; const topLeft = this.unproject([0, 0], unprojectOption); const topRight = this.unproject([this.width, 0], unprojectOption); const bottomLeft = this.unproject([0, this.height], unprojectOption); const bottomRight = this.unproject([this.width, this.height], unprojectOption); return [ Math.min(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]), Math.min(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]), Math.max(topLeft[0], topRight[0], bottomLeft[0], bottomRight[0]), Math.max(topLeft[1], topRight[1], bottomLeft[1], bottomRight[1]) ]; } getDistanceScales(coordinateOrigin) { if (coordinateOrigin) { return getDistanceScales({ longitude: coordinateOrigin[0], latitude: coordinateOrigin[1], highPrecision: true }); } return this.distanceScales; } containsPixel({ x, y, width = 1, height = 1 }) { return x < this.x + this.width && this.x < x + width && y < this.y + this.height && this.y < y + height; } getFrustumPlanes() { if (this._frustumPlanes.near) { return this._frustumPlanes; } Object.assign(this._frustumPlanes, getFrustumPlanes(this.viewProjectionMatrix)); return this._frustumPlanes; } panByPosition(coords, pixel) { return null; } _initProps(opts) { const longitude = opts.longitude; const latitude = opts.latitude; if (this.isGeospatial) { if (!Number.isFinite(opts.zoom)) { this.zoom = getMeterZoom({ latitude }) + Math.log2(this.focalDistance); } this.distanceScales = opts.distanceScales || getDistanceScales({ latitude, longitude }); } const scale5 = Math.pow(2, this.zoom); this.scale = scale5; const { position, modelMatrix } = opts; let meterOffset = ZERO_VECTOR2; if (position) { meterOffset = modelMatrix ? new Matrix4(modelMatrix).transformAsVector(position, []) : position; } if (this.isGeospatial) { const center = this.projectPosition([longitude, latitude, 0]); this.center = new Vector3(meterOffset).scale(this.distanceScales.unitsPerMeter).add(center); } else { this.center = this.projectPosition(meterOffset); } } _initMatrices(opts) { const { viewMatrix: viewMatrix2 = IDENTITY2, projectionMatrix = null, orthographic = false, fovyRadians, fovy = 75, near = 0.1, far = 1e3, padding = null, focalDistance = 1 } = opts; this.viewMatrixUncentered = viewMatrix2; this.viewMatrix = new Matrix4().multiplyRight(viewMatrix2).translate(new Vector3(this.center).negate()); this.projectionMatrix = projectionMatrix || createProjectionMatrix({ width: this.width, height: this.height, orthographic, fovyRadians: fovyRadians || fovy * DEGREES_TO_RADIANS4, focalDistance, padding, near, far }); const vpm = createMat42(); mat4_exports.multiply(vpm, vpm, this.projectionMatrix); mat4_exports.multiply(vpm, vpm, this.viewMatrix); this.viewProjectionMatrix = vpm; this.viewMatrixInverse = mat4_exports.invert([], this.viewMatrix) || this.viewMatrix; this.cameraPosition = getCameraPosition(this.viewMatrixInverse); const viewportMatrix = createMat42(); const pixelProjectionMatrix = createMat42(); mat4_exports.scale(viewportMatrix, viewportMatrix, [this.width / 2, -this.height / 2, 1]); mat4_exports.translate(viewportMatrix, viewportMatrix, [1, -1, 0]); mat4_exports.multiply(pixelProjectionMatrix, viewportMatrix, this.viewProjectionMatrix); this.pixelProjectionMatrix = pixelProjectionMatrix; this.pixelUnprojectionMatrix = mat4_exports.invert(createMat42(), this.pixelProjectionMatrix); if (!this.pixelUnprojectionMatrix) { log_default.warn("Pixel project matrix not invertible")(); } } }; var Viewport = _Viewport; Viewport.displayName = "Viewport"; // src/viewports/web-mercator-viewport.ts var _WebMercatorViewport = class extends Viewport { constructor(opts = {}) { const { latitude = 0, longitude = 0, zoom = 0, pitch = 0, bearing = 0, nearZMultiplier = 0.1, farZMultiplier = 1.01, nearZ, farZ, orthographic = false, projectionMatrix, repeat = false, worldOffset = 0, position, padding, legacyMeterSizes = false } = opts; let { width, height, altitude = 1.5 } = opts; const scale5 = Math.pow(2, zoom); width = width || 1; height = height || 1; let fovy; let projectionParameters = null; if (projectionMatrix) { altitude = projectionMatrix[5] / 2; fovy = altitudeToFovy(altitude); } else { if (opts.fovy) { fovy = opts.fovy; altitude = fovyToAltitude(fovy); } else { fovy = altitudeToFovy(altitude); } let offset; if (padding) { const { top = 0, bottom = 0 } = padding; offset = [0, clamp((top + height - bottom) / 2, 0, height) - height / 2]; } projectionParameters = getProjectionParameters({ width, height, scale: scale5, center: position && [0, 0, position[2] * unitsPerMeter(latitude)], offset, pitch, fovy, nearZMultiplier, farZMultiplier }); if (Number.isFinite(nearZ)) { projectionParameters.near = nearZ; } if (Number.isFinite(farZ)) { projectionParameters.far = farZ; } } let viewMatrixUncentered = getViewMatrix({ height, pitch, bearing, scale: scale5, altitude }); if (worldOffset) { const viewOffset = new Matrix4().translate([512 * worldOffset, 0, 0]); viewMatrixUncentered = viewOffset.multiplyLeft(viewMatrixUncentered); } super({ ...opts, width, height, viewMatrix: viewMatrixUncentered, longitude, latitude, zoom, ...projectionParameters, fovy, focalDistance: altitude }); this.latitude = latitude; this.longitude = longitude; this.zoom = zoom; this.pitch = pitch; this.bearing = bearing; this.altitude = altitude; this.fovy = fovy; this.orthographic = orthographic; this._subViewports = repeat ? [] : null; this._pseudoMeters = legacyMeterSizes; Object.freeze(this); } get subViewports() { if (this._subViewports && !this._subViewports.length) { const bounds = this.getBounds(); const minOffset = Math.floor((bounds[0] + 180) / 360); const maxOffset = Math.ceil((bounds[2] - 180) / 360); for (let x = minOffset; x <= maxOffset; x++) { const offsetViewport = x ? new _WebMercatorViewport({ ...this, worldOffset: x }) : this; this._subViewports.push(offsetViewport); } } return this._subViewports; } projectPosition(xyz) { if (this._pseudoMeters) { return super.projectPosition(xyz); } const [X, Y] = this.projectFlat(xyz); const Z = (xyz[2] || 0) * unitsPerMeter(xyz[1]); return [X, Y, Z]; } unprojectPosition(xyz) { if (this._pseudoMeters) { return super.unprojectPosition(xyz); } const [X, Y] = this.unprojectFlat(xyz); const Z = (xyz[2] || 0) / unitsPerMeter(Y); return [X, Y, Z]; } addMetersToLngLat(lngLatZ, xyz) { return addMetersToLngLat(lngLatZ, xyz); } panByPosition(coords, pixel) { const fromLocation = pixelsToWorld(pixel, this.pixelUnprojectionMatrix); const toLocation = this.projectFlat(coords); const translate2 = vec2_exports.add([], toLocation, vec2_exports.negate([], fromLocation)); const newCenter = vec2_exports.add([], this.center, translate2); const [longitude, latitude] = this.unprojectFlat(newCenter); return { longitude, latitude }; } getBounds(options = {}) { const corners = getBounds(this, options.z || 0); return [ Math.min(corners[0][0], corners[1][0], corners[2][0], corners[3][0]), Math.min(corners[0][1], corners[1][1], corners[2][1], corners[3][1]), Math.max(corners[0][0], corners[1][0], corners[2][0], corners[3][0]), Math.max(corners[0][1], corners[1][1], corners[2][1], corners[3][1]) ]; } fitBounds(bounds, options = {}) { const { width, height } = this; const { longitude, latitude, zoom } = fitBounds({ width, height, bounds, ...options }); return new _WebMercatorViewport({ width, height, longitude, latitude, zoom }); } }; var WebMercatorViewport2 = _WebMercatorViewport; WebMercatorViewport2.displayName = "WebMercatorViewport"; // src/shaderlib/project/project-functions.ts var DEFAULT_COORDINATE_ORIGIN2 = [0, 0, 0]; function lngLatZToWorldPosition(lngLatZ, viewport, offsetMode = false) { const p = viewport.projectPosition(lngLatZ); if (offsetMode && viewport instanceof WebMercatorViewport2) { const [longitude, latitude, z = 0] = lngLatZ; const distanceScales = viewport.getDistanceScales([longitude, latitude]); p[2] = z * distanceScales.unitsPerMeter[2]; } return p; } function normalizeParameters(opts) { const { viewport, modelMatrix, coordinateOrigin } = opts; let { coordinateSystem, fromCoordinateSystem, fromCoordinateOrigin } = opts; if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) { coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN; } if (fromCoordinateSystem === void 0) { fromCoordinateSystem = coordinateSystem; } if (fromCoordinateOrigin === void 0) { fromCoordinateOrigin = coordinateOrigin; } return { viewport, coordinateSystem, coordinateOrigin, modelMatrix, fromCoordinateSystem, fromCoordinateOrigin }; } function getWorldPosition(position, { viewport, modelMatrix, coordinateSystem, coordinateOrigin, offsetMode }) { let [x, y, z = 0] = position; if (modelMatrix) { [x, y, z] = vec4_exports.transformMat4([], [x, y, z, 1], modelMatrix); } switch (coordinateSystem) { case COORDINATE_SYSTEM.LNGLAT: return lngLatZToWorldPosition([x, y, z], viewport, offsetMode); case COORDINATE_SYSTEM.LNGLAT_OFFSETS: return lngLatZToWorldPosition( [x + coordinateOrigin[0], y + coordinateOrigin[1], z + (coordinateOrigin[2] || 0)], viewport, offsetMode ); case COORDINATE_SYSTEM.METER_OFFSETS: return lngLatZToWorldPosition( addMetersToLngLat(coordinateOrigin, [x, y, z]), viewport, offsetMode ); case COORDINATE_SYSTEM.CARTESIAN: default: return viewport.isGeospatial ? [x + coordinateOrigin[0], y + coordinateOrigin[1], z + coordinateOrigin[2]] : viewport.projectPosition([x, y, z]); } } function projectPosition(position, params) { const { viewport, coordinateSystem, coordinateOrigin, modelMatrix, fromCoordinateSystem, fromCoordinateOrigin } = normalizeParameters(params); const { autoOffset = true } = params; const { geospatialOrigin = DEFAULT_COORDINATE_ORIGIN2, shaderCoordinateOrigin = DEFAULT_COORDINATE_ORIGIN2, offsetMode = false } = autoOffset ? getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin) : {}; const worldPosition = getWorldPosition(position, { viewport, modelMatrix, coordinateSystem: fromCoordinateSystem, coordinateOrigin: fromCoordinateOrigin, offsetMode }); if (offsetMode) { const positionCommonSpace = viewport.projectPosition( geospatialOrigin || shaderCoordinateOrigin ); vec3_exports.sub(worldPosition, worldPosition, positionCommonSpace); } return worldPosition; } // src/effects/lighting/point-light.ts var DEFAULT_LIGHT_COLOR3 = [255, 255, 255]; var DEFAULT_LIGHT_INTENSITY3 = 1; var DEFAULT_ATTENUATION = [0, 0, 1]; var DEFAULT_LIGHT_POSITION = [0, 0, 1]; var idCount3 = 0; var PointLight = class { constructor(props = {}) { this.type = "point"; const { color = DEFAULT_LIGHT_COLOR3 } = props; const { intensity = DEFAULT_LIGHT_INTENSITY3 } = props; const { position = DEFAULT_LIGHT_POSITION } = props; this.id = props.id || `point-${idCount3++}`; this.color = color; this.intensity = intensity; this.type = "point"; this.position = position; this.attenuation = getAttenuation(props); this.projectedLight = { ...this }; } getProjectedLight({ layer }) { const { projectedLight } = this; const viewport = layer.context.viewport; const { coordinateSystem, coordinateOrigin } = layer.props; const position = projectPosition(this.position, { viewport, coordinateSystem, coordinateOrigin, fromCoordinateSystem: viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN, fromCoordinateOrigin: [0, 0, 0] }); projectedLight.color = this.color; projectedLight.intensity = this.intensity; projectedLight.position = position; return projectedLight; } }; function getAttenuation(props) { if (props.attenuation) { return props.attenuation; } if ("intensity" in props) { return [0, 0, props.intensity || 0]; } return DEFAULT_ATTENUATION; } // src/effects/lighting/camera-light.ts var CameraLight = class extends PointLight { getProjectedLight({ layer }) { const { projectedLight } = this; const viewport = layer.context.viewport; const { coordinateSystem, coordinateOrigin, modelMatrix } = layer.props; const { project_uCameraPosition } = getUniformsFromViewport({ viewport, modelMatrix, coordinateSystem, coordinateOrigin }); projectedLight.color = this.color; projectedLight.intensity = this.intensity; projectedLight.position = project_uCameraPosition; return projectedLight; } }; // ../../node_modules/@math.gl/sun/dist/suncalc.js var DEGREES_TO_RADIANS5 = Math.PI / 180; var DAY_IN_MS = 1e3 * 60 * 60 * 24; var JD1970 = 2440588; var JD2000 = 2451545; var e = DEGREES_TO_RADIANS5 * 23.4397; var M0 = 357.5291; var M1 = 0.98560028; var THETA0 = 280.147; var THETA1 = 360.9856235; function getSunPosition(timestamp, latitude, longitude) { const longitudeWestInRadians = DEGREES_TO_RADIANS5 * -longitude; const phi = DEGREES_TO_RADIANS5 * latitude; const d = toDays(timestamp); const c = getSunCoords(d); const H = getSiderealTime(d, longitudeWestInRadians) - c.rightAscension; return { azimuth: getAzimuth(H, phi, c.declination), altitude: getAltitude(H, phi, c.declination) }; } function getSunDirection(timestamp, latitude, longitude) { const { azimuth, altitude } = getSunPosition(timestamp, latitude, longitude); return [ Math.sin(azimuth) * Math.cos(altitude), Math.cos(azimuth) * Math.cos(altitude), -Math.sin(altitude) ]; } function toJulianDay(timestamp) { const ts = typeof timestamp === "number" ? timestamp : timestamp.getTime(); return ts / DAY_IN_MS - 0.5 + JD1970; } function toDays(timestamp) { return toJulianDay(timestamp) - JD2000; } function getRightAscension(eclipticLongitude, b) { const lambda = eclipticLongitude; return Math.atan2(Math.sin(lambda) * Math.cos(e) - Math.tan(b) * Math.sin(e), Math.cos(lambda)); } function getDeclination(eclipticLongitude, b) { const lambda = eclipticLongitude; return Math.asin(Math.sin(b) * Math.cos(e) + Math.cos(b) * Math.sin(e) * Math.sin(lambda)); } function getAzimuth(hourAngle, latitudeInRadians, declination) { const H = hourAngle; const phi = latitudeInRadians; const delta = declination; return Math.atan2(Math.sin(H), Math.cos(H) * Math.sin(phi) - Math.tan(delta) * Math.cos(phi)); } function getAltitude(hourAngle, latitudeInRadians, declination) { const H = hourAngle; const phi = latitudeInRadians; const delta = declination; return Math.asin(Math.sin(phi) * Math.sin(delta) + Math.cos(phi) * Math.cos(delta) * Math.cos(H)); } function getSiderealTime(dates, longitudeWestInRadians) { return DEGREES_TO_RADIANS5 * (THETA0 + THETA1 * dates) - longitudeWestInRadians; } function getSolarMeanAnomaly(days) { return DEGREES_TO_RADIANS5 * (M0 + M1 * days); } function getEclipticLongitude(meanAnomaly) { const M = meanAnomaly; const C = DEGREES_TO_RADIANS5 * (1.9148 * Math.sin(M) + 0.02 * Math.sin(2 * M) + 3e-4 * Math.sin(3 * M)); const P = DEGREES_TO_RADIANS5 * 102.9372; return M + C + P + Math.PI; } function getSunCoords(dates) { const M = getSolarMeanAnomaly(dates); const L = getEclipticLongitude(M); return { declination: getDeclination(L, 0), rightAscension: getRightAscension(L, 0) }; } // src/effects/lighting/sun-light.ts var SunLight = class extends DirectionalLight { constructor(opts) { super(opts); this.timestamp = opts.timestamp; } getProjectedLight({ layer }) { const { viewport } = layer.context; const isGlobe = viewport.resolution && viewport.resolution > 0; if (isGlobe) { const [x, y, z] = getSunDirection(this.timestamp, 0, 0); this.direction = [x, -z, y]; } else { const { latitude, longitude } = viewport; this.direction = getSunDirection(this.timestamp, latitude, longitude); } return this; } }; // src/passes/screen-pass.ts var ScreenPass = class extends Pass { constructor(device, props) { super(device, props); const { module, fs: fs5, id } = props; const parameters = { depthWriteEnabled: false, depthCompare: "always" }; this.model = new ClipSpace(device, { id, fs: fs5, modules: [module], parameters }); } render(params) { this._renderPass(this.device, params); } delete() { this.model.destroy(); this.model = null; } _renderPass(device, options) { const { clearCanvas, inputBuffer, outputBuffer } = options; const texSize = [inputBuffer.width, inputBuffer.height]; this.model.shaderInputs.setProps(options.moduleSettings); this.model.setBindings({ texSrc: inputBuffer.colorAttachments[0] }); this.model.setUniforms({ texSize }); const renderPass = this.device.beginRenderPass({ framebuffer: outputBuffer, parameters: { viewport: [0, 0, ...texSize] }, clearColor: clearCanvas ? [0, 0, 0, 0] : false, clearDepth: 1 }); this.model.draw(renderPass); renderPass.end(); } }; // src/effects/post-process-effect.ts var PostProcessEffect = class { constructor(module, props) { this.id = `${module.name}-pass`; this.props = props; normalizeShaderModule(module); this.module = module; } setup({ device }) { this.passes = createPasses(device, this.module, this.id); } setProps(props) { this.props = props; } preRender() { } postRender(params) { const passes = this.passes; const { target } = params; let inputBuffer = params.inputBuffer; let outputBuffer = params.swapBuffer; for (let index2 = 0; index2 < passes.length; index2++) { const isLastPass = index2 === passes.length - 1; const renderToTarget = target !== void 0 && isLastPass; if (renderToTarget) { outputBuffer = target; } const clearCanvas = !renderToTarget || Boolean(params.clearCanvas); const moduleSettings = {}; const uniforms = this.module.passes[index2].uniforms; moduleSettings[this.module.name] = { ...this.props, ...uniforms }; passes[index2].render({ clearCanvas, inputBuffer, outputBuffer, moduleSettings }); const switchBuffer = outputBuffer; outputBuffer = inputBuffer; inputBuffer = switchBuffer; } return inputBuffer; } cleanup() { if (this.passes) { for (const pass of this.passes) { pass.delete(); } this.passes = void 0; } } }; function createPasses(device, module, id) { return module.passes.map((pass, index2) => { const fs5 = getFragmentShaderForRenderPass(module, pass); const idn = `${id}-${index2}`; return new ScreenPass(device, { id: idn, module, fs: fs5 }); }); } var FS_TEMPLATE_INPUTS = `#version 300 es uniform sampler2D texSrc; uniform vec2 texSize; in vec2 position; in vec2 coordinate; in vec2 uv; out vec4 fragColor; `; var FILTER_FS_TEMPLATE = (func) => `${FS_TEMPLATE_INPUTS} void main() { fragColor = texture(texSrc, coordinate); fragColor = ${func}(fragColor, texSize, coordinate); } `; var SAMPLER_FS_TEMPLATE = (func) => `${FS_TEMPLATE_INPUTS} void main() { fragColor = ${func}(texSrc, texSize, coordinate); } `; function getFragmentShaderForRenderPass(module, pass) { if (pass.filter) { const func = typeof pass.filter === "string" ? pass.filter : `${module.name}_filterColor`; return FILTER_FS_TEMPLATE(func); } if (pass.sampler) { const func = typeof pass.sampler === "string" ? pass.sampler : `${module.name}_sampleColor`; return SAMPLER_FS_TEMPLATE(func); } return ""; } // src/passes/pick-layers-pass.ts var PICKING_BLENDING = { blendColorOperation: "add", blendColorSrcFactor: "one", blendColorDstFactor: "zero", blendAlphaOperation: "add", blendAlphaSrcFactor: "constant-alpha", blendAlphaDstFactor: "zero" }; var PickLayersPass = class extends LayersPass { constructor() { super(...arguments); this._colorEncoderState = null; } render(props) { if ("pickingFBO" in props) { return this._drawPickingBuffer(props); } return super.render(props); } _drawPickingBuffer({ layers, layerFilter, views, viewports, onViewportActive, pickingFBO, deviceRect: { x, y, width, height }, cullRect, effects, pass = "picking", pickZ, moduleParameters }) { this.pickZ = pickZ; const colorEncoderState = this._resetColorEncoder(pickZ); const scissorRect = [x, y, width, height]; const renderStatus = super.render({ target: pickingFBO, layers, layerFilter, views, viewports, onViewportActive, cullRect, effects: effects?.filter((e2) => e2.useInPicking), pass, isPicking: true, moduleParameters, clearColor: [0, 0, 0, 0], colorMask: 15, scissorRect }); this._colorEncoderState = null; const decodePickingColor = colorEncoderState && decodeColor.bind(null, colorEncoderState); return { decodePickingColor, stats: renderStatus }; } shouldDrawLayer(layer) { const { pickable, operation } = layer.props; return pickable && operation.includes("draw") || operation.includes("terrain") || operation.includes("mask"); } getModuleParameters() { return { picking: { isActive: 1, isAttribute: this.pickZ }, lightSources: {} }; } getLayerParameters(layer, layerIndex, viewport) { const pickParameters = { depthMask: true, depthTest: true, depthRange: [0, 1], ...layer.props.parameters }; const { pickable, operation } = layer.props; if (!this._colorEncoderState || operation.includes("terrain")) { pickParameters.blend = false; } else if (pickable && operation.includes("draw")) { Object.assign(pickParameters, PICKING_BLENDING); pickParameters.blend = true; pickParameters.blendColor = encodeColor(this._colorEncoderState, layer, viewport); } return pickParameters; } _resetColorEncoder(pickZ) { this._colorEncoderState = pickZ ? null : { byLayer: /* @__PURE__ */ new Map(), byAlpha: [] }; return this._colorEncoderState; } }; function encodeColor(encoded, layer, viewport) { const { byLayer, byAlpha } = encoded; let a; let entry = byLayer.get(layer); if (entry) { entry.viewports.push(viewport); a = entry.a; } else { a = byLayer.size + 1; if (a <= 255) { entry = { a, layer, viewports: [viewport] }; byLayer.set(layer, entry); byAlpha[a] = entry; } else { log_default.warn("Too many pickable layers, only picking the first 255")(); a = 0; } } return [0, 0, 0, a / 255]; } function decodeColor(encoded, pickedColor) { const entry = encoded.byAlpha[pickedColor[3]]; return entry && { pickedLayer: entry.layer, pickedViewports: entry.viewports, pickedObjectIndex: entry.layer.decodePickingColor(pickedColor) }; } // src/lifecycle/constants.ts var LIFECYCLE = { NO_STATE: "Awaiting state", MATCHED: "Matched. State transferred from previous layer", INITIALIZED: "Initialized", AWAITING_GC: "Discarded. Awaiting garbage collection", AWAITING_FINALIZATION: "No longer matched. Awaiting garbage collection", FINALIZED: "Finalized! Awaiting garbage collection" }; var COMPONENT_SYMBOL = Symbol.for("component"); var PROP_TYPES_SYMBOL = Symbol.for("propTypes"); var DEPRECATED_PROPS_SYMBOL = Symbol.for("deprecatedProps"); var ASYNC_DEFAULTS_SYMBOL = Symbol.for("asyncPropDefaults"); var ASYNC_ORIGINAL_SYMBOL = Symbol.for("asyncPropOriginal"); var ASYNC_RESOLVED_SYMBOL = Symbol.for("asyncPropResolved"); // src/utils/flatten.ts function flatten(array, filter = () => true) { if (!Array.isArray(array)) { return filter(array) ? [array] : []; } return flattenArray(array, filter, []); } function flattenArray(array, filter, result) { let index2 = -1; while (++index2 < array.length) { const value = array[index2]; if (Array.isArray(value)) { flattenArray(value, filter, result); } else if (filter(value)) { result.push(value); } } return result; } function fillArray2({ target, source, start = 0, count: count2 = 1 }) { const length4 = source.length; const total = count2 * length4; let copied = 0; for (let i = start; copied < length4; copied++) { target[i++] = source[copied]; } while (copied < total) { if (copied < total - copied) { target.copyWithin(start + copied, start, start + copied); copied *= 2; } else { target.copyWithin(start + copied, start, start + total - copied); copied = total; } } return target; } // src/lib/resource/resource.ts var Resource2 = class { constructor(id, data, context) { this._loadCount = 0; this._subscribers = /* @__PURE__ */ new Set(); this.id = id; this.context = context; this.setData(data); } subscribe(consumer) { this._subscribers.add(consumer); } unsubscribe(consumer) { this._subscribers.delete(consumer); } inUse() { return this._subscribers.size > 0; } delete() { } getData() { return this.isLoaded ? this._error ? Promise.reject(this._error) : this._content : this._loader.then(() => this.getData()); } setData(data, forceUpdate) { if (data === this._data && !forceUpdate) { return; } this._data = data; const loadCount = ++this._loadCount; let loader = data; if (typeof data === "string") { loader = load(data); } if (loader instanceof Promise) { this.isLoaded = false; this._loader = loader.then((result) => { if (this._loadCount === loadCount) { this.isLoaded = true; this._error = void 0; this._content = result; } }).catch((error) => { if (this._loadCount === loadCount) { this.isLoaded = true; this._error = error || true; } }); } else { this.isLoaded = true; this._error = void 0; this._content = data; } for (const subscriber of this._subscribers) { subscriber.onChange(this.getData()); } } }; // src/lib/resource/resource-manager.ts var ResourceManager = class { constructor(props) { this.protocol = props.protocol || "resource://"; this._context = { device: props.device, gl: props.device?.gl, resourceManager: this }; this._resources = {}; this._consumers = {}; this._pruneRequest = null; } contains(resourceId) { if (resourceId.startsWith(this.protocol)) { return true; } return resourceId in this._resources; } add({ resourceId, data, forceUpdate = false, persistent = true }) { let res = this._resources[resourceId]; if (res) { res.setData(data, forceUpdate); } else { res = new Resource2(resourceId, data, this._context); this._resources[resourceId] = res; } res.persistent = persistent; } remove(resourceId) { const res = this._resources[resourceId]; if (res) { res.delete(); delete this._resources[resourceId]; } } unsubscribe({ consumerId }) { const consumer = this._consumers[consumerId]; if (consumer) { for (const requestId in consumer) { const request = consumer[requestId]; const resource = this._resources[request.resourceId]; if (resource) { resource.unsubscribe(request); } } delete this._consumers[consumerId]; this.prune(); } } subscribe({ resourceId, onChange, consumerId, requestId = "default" }) { const { _resources: resources, protocol } = this; if (resourceId.startsWith(protocol)) { resourceId = resourceId.replace(protocol, ""); if (!resources[resourceId]) { this.add({ resourceId, data: null, persistent: false }); } } const res = resources[resourceId]; this._track(consumerId, requestId, res, onChange); if (res) { return res.getData(); } return void 0; } prune() { if (!this._pruneRequest) { this._pruneRequest = setTimeout(() => this._prune(), 0); } } finalize() { for (const key in this._resources) { this._resources[key].delete(); } } _track(consumerId, requestId, resource, onChange) { const consumers = this._consumers; const consumer = consumers[consumerId] = consumers[consumerId] || {}; let request = consumer[requestId]; const oldResource = request && request.resourceId && this._resources[request.resourceId]; if (oldResource) { oldResource.unsubscribe(request); this.prune(); } if (resource) { if (request) { request.onChange = onChange; request.resourceId = resource.id; } else { request = { onChange, resourceId: resource.id }; } consumer[requestId] = request; resource.subscribe(request); } } _prune() { this._pruneRequest = null; for (const key of Object.keys(this._resources)) { const res = this._resources[key]; if (!res.persistent && !res.inUse()) { res.delete(); delete this._resources[key]; } } } }; // src/lib/layer-manager.ts var TRACE_SET_LAYERS = "layerManager.setLayers"; var TRACE_ACTIVATE_VIEWPORT = "layerManager.activateViewport"; var LayerManager = class { constructor(device, props) { this._lastRenderedLayers = []; this._needsRedraw = false; this._needsUpdate = false; this._nextLayers = null; this._debug = false; this._defaultShaderModulesChanged = false; this.activateViewport = (viewport) => { debug(TRACE_ACTIVATE_VIEWPORT, this, viewport); if (viewport) { this.context.viewport = viewport; } }; const { deck, stats: stats2, viewport, timeline } = props || {}; this.layers = []; this.resourceManager = new ResourceManager({ device, protocol: "deck://" }); this.context = { mousePosition: null, userData: {}, layerManager: this, device, gl: device?.gl, deck, shaderAssembler: getShaderAssembler(), defaultShaderModules: [], renderPass: void 0, stats: stats2 || new Stats({ id: "deck.gl" }), viewport: viewport || new Viewport({ id: "DEFAULT-INITIAL-VIEWPORT" }), timeline: timeline || new Timeline(), resourceManager: this.resourceManager, onError: void 0 }; Object.seal(this); } finalize() { this.resourceManager.finalize(); for (const layer of this.layers) { this._finalizeLayer(layer); } } needsRedraw(opts = { clearRedrawFlags: false }) { let redraw = this._needsRedraw; if (opts.clearRedrawFlags) { this._needsRedraw = false; } for (const layer of this.layers) { const layerNeedsRedraw = layer.getNeedsRedraw(opts); redraw = redraw || layerNeedsRedraw; } return redraw; } needsUpdate() { if (this._nextLayers && this._nextLayers !== this._lastRenderedLayers) { return "layers changed"; } if (this._defaultShaderModulesChanged) { return "shader modules changed"; } return this._needsUpdate; } setNeedsRedraw(reason) { this._needsRedraw = this._needsRedraw || reason; } setNeedsUpdate(reason) { this._needsUpdate = this._needsUpdate || reason; } getLayers({ layerIds } = {}) { return layerIds ? this.layers.filter((layer) => layerIds.find((layerId) => layer.id.indexOf(layerId) === 0)) : this.layers; } setProps(props) { if ("debug" in props) { this._debug = props.debug; } if ("userData" in props) { this.context.userData = props.userData; } if ("layers" in props) { this._nextLayers = props.layers; } if ("onError" in props) { this.context.onError = props.onError; } } setLayers(newLayers, reason) { debug(TRACE_SET_LAYERS, this, reason, newLayers); this._lastRenderedLayers = newLayers; const flatLayers = flatten(newLayers, Boolean); for (const layer of flatLayers) { layer.context = this.context; } this._updateLayers(this.layers, flatLayers); } updateLayers() { const reason = this.needsUpdate(); if (reason) { this.setNeedsRedraw(`updating layers: ${reason}`); this.setLayers(this._nextLayers || this._lastRenderedLayers, reason); } this._nextLayers = null; } addDefaultShaderModule(module) { const { defaultShaderModules } = this.context; if (!defaultShaderModules.find((m) => m.name === module.name)) { defaultShaderModules.push(module); this._defaultShaderModulesChanged = true; } } removeDefaultShaderModule(module) { const { defaultShaderModules } = this.context; const i = defaultShaderModules.findIndex((m) => m.name === module.name); if (i >= 0) { defaultShaderModules.splice(i, 1); this._defaultShaderModulesChanged = true; } } _handleError(stage, error, layer) { layer.raiseError(error, `${stage} of ${layer}`); } _updateLayers(oldLayers, newLayers) { const oldLayerMap = {}; for (const oldLayer of oldLayers) { if (oldLayerMap[oldLayer.id]) { log_default.warn(`Multiple old layers with same id ${oldLayer.id}`)(); } else { oldLayerMap[oldLayer.id] = oldLayer; } } if (this._defaultShaderModulesChanged) { for (const layer of oldLayers) { layer.setNeedsUpdate(); layer.setChangeFlags({ extensionsChanged: true }); } this._defaultShaderModulesChanged = false; } const generatedLayers = []; this._updateSublayersRecursively(newLayers, oldLayerMap, generatedLayers); this._finalizeOldLayers(oldLayerMap); let needsUpdate = false; for (const layer of generatedLayers) { if (layer.hasUniformTransition()) { needsUpdate = `Uniform transition in ${layer}`; break; } } this._needsUpdate = needsUpdate; this.layers = generatedLayers; } _updateSublayersRecursively(newLayers, oldLayerMap, generatedLayers) { for (const newLayer of newLayers) { newLayer.context = this.context; const oldLayer = oldLayerMap[newLayer.id]; if (oldLayer === null) { log_default.warn(`Multiple new layers with same id ${newLayer.id}`)(); } oldLayerMap[newLayer.id] = null; let sublayers = null; try { if (this._debug && oldLayer !== newLayer) { newLayer.validateProps(); } if (!oldLayer) { this._initializeLayer(newLayer); } else { this._transferLayerState(oldLayer, newLayer); this._updateLayer(newLayer); } generatedLayers.push(newLayer); sublayers = newLayer.isComposite ? newLayer.getSubLayers() : null; } catch (err) { this._handleError("matching", err, newLayer); } if (sublayers) { this._updateSublayersRecursively(sublayers, oldLayerMap, generatedLayers); } } } _finalizeOldLayers(oldLayerMap) { for (const layerId in oldLayerMap) { const layer = oldLayerMap[layerId]; if (layer) { this._finalizeLayer(layer); } } } _initializeLayer(layer) { try { layer._initialize(); layer.lifecycle = LIFECYCLE.INITIALIZED; } catch (err) { this._handleError("initialization", err, layer); } } _transferLayerState(oldLayer, newLayer) { newLayer._transferState(oldLayer); newLayer.lifecycle = LIFECYCLE.MATCHED; if (newLayer !== oldLayer) { oldLayer.lifecycle = LIFECYCLE.AWAITING_GC; } } _updateLayer(layer) { try { layer._update(); } catch (err) { this._handleError("update", err, layer); } } _finalizeLayer(layer) { this._needsRedraw = this._needsRedraw || `finalized ${layer}`; layer.lifecycle = LIFECYCLE.AWAITING_FINALIZATION; try { layer._finalize(); layer.lifecycle = LIFECYCLE.FINALIZED; } catch (err) { this._handleError("finalization", err, layer); } } }; // src/utils/deep-equal.ts function deepEqual2(a, b, depth) { if (a === b) { return true; } if (!depth || !a || !b) { return false; } if (Array.isArray(a)) { if (!Array.isArray(b) || a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (!deepEqual2(a[i], b[i], depth - 1)) { return false; } } return true; } if (Array.isArray(b)) { return false; } if (typeof a === "object" && typeof b === "object") { const aKeys = Object.keys(a); const bKeys = Object.keys(b); if (aKeys.length !== bKeys.length) { return false; } for (const key of aKeys) { if (!b.hasOwnProperty(key)) { return false; } if (!deepEqual2(a[key], b[key], depth - 1)) { return false; } } return true; } return false; } // src/lib/view-manager.ts var ViewManager = class { constructor(props) { this.views = []; this.width = 100; this.height = 100; this.viewState = {}; this.controllers = {}; this.timeline = props.timeline; this._viewports = []; this._viewportMap = {}; this._isUpdating = false; this._needsRedraw = "First render"; this._needsUpdate = "Initialize"; this._eventManager = props.eventManager; this._eventCallbacks = { onViewStateChange: props.onViewStateChange, onInteractionStateChange: props.onInteractionStateChange }; Object.seal(this); this.setProps(props); } finalize() { for (const key in this.controllers) { const controller = this.controllers[key]; if (controller) { controller.finalize(); } } this.controllers = {}; } needsRedraw(opts = { clearRedrawFlags: false }) { const redraw = this._needsRedraw; if (opts.clearRedrawFlags) { this._needsRedraw = false; } return redraw; } setNeedsUpdate(reason) { this._needsUpdate = this._needsUpdate || reason; this._needsRedraw = this._needsRedraw || reason; } updateViewStates() { for (const viewId in this.controllers) { const controller = this.controllers[viewId]; if (controller) { controller.updateTransition(); } } } getViewports(rect) { if (rect) { return this._viewports.filter((viewport) => viewport.containsPixel(rect)); } return this._viewports; } getViews() { const viewMap = {}; this.views.forEach((view) => { viewMap[view.id] = view; }); return viewMap; } getView(viewId) { return this.views.find((view) => view.id === viewId); } getViewState(viewOrViewId) { const view = typeof viewOrViewId === "string" ? this.getView(viewOrViewId) : viewOrViewId; const viewState = view && this.viewState[view.getViewStateId()] || this.viewState; return view ? view.filterViewState(viewState) : viewState; } getViewport(viewId) { return this._viewportMap[viewId]; } unproject(xyz, opts) { const viewports = this.getViewports(); const pixel = { x: xyz[0], y: xyz[1] }; for (let i = viewports.length - 1; i >= 0; --i) { const viewport = viewports[i]; if (viewport.containsPixel(pixel)) { const p = xyz.slice(); p[0] -= viewport.x; p[1] -= viewport.y; return viewport.unproject(p, opts); } } return null; } setProps(props) { if (props.views) { this._setViews(props.views); } if (props.viewState) { this._setViewState(props.viewState); } if ("width" in props || "height" in props) { this._setSize(props.width, props.height); } if (!this._isUpdating) { this._update(); } } _update() { this._isUpdating = true; if (this._needsUpdate) { this._needsUpdate = false; this._rebuildViewports(); } if (this._needsUpdate) { this._needsUpdate = false; this._rebuildViewports(); } this._isUpdating = false; } _setSize(width, height) { if (width !== this.width || height !== this.height) { this.width = width; this.height = height; this.setNeedsUpdate("Size changed"); } } _setViews(views) { views = flatten(views, Boolean); const viewsChanged = this._diffViews(views, this.views); if (viewsChanged) { this.setNeedsUpdate("views changed"); } this.views = views; } _setViewState(viewState) { if (viewState) { const viewStateChanged = !deepEqual2(viewState, this.viewState, 3); if (viewStateChanged) { this.setNeedsUpdate("viewState changed"); } this.viewState = viewState; } else { log_default.warn("missing `viewState` or `initialViewState`")(); } } _createController(view, props) { const Controller2 = props.type; const controller = new Controller2({ timeline: this.timeline, eventManager: this._eventManager, onViewStateChange: this._eventCallbacks.onViewStateChange, onStateChange: this._eventCallbacks.onInteractionStateChange, makeViewport: (viewState) => this.getView(view.id)?.makeViewport({ viewState, width: this.width, height: this.height }) }); return controller; } _updateController(view, viewState, viewport, controller) { const controllerProps = view.controller; if (controllerProps && viewport) { const resolvedProps = { ...viewState, ...controllerProps, id: view.id, x: viewport.x, y: viewport.y, width: viewport.width, height: viewport.height }; if (!controller || controller.constructor !== controllerProps.type) { controller = this._createController(view, resolvedProps); } if (controller) { controller.setProps(resolvedProps); } return controller; } return null; } _rebuildViewports() { const { views } = this; const oldControllers = this.controllers; this._viewports = []; this.controllers = {}; let invalidateControllers = false; for (let i = views.length; i--; ) { const view = views[i]; const viewState = this.getViewState(view); const viewport = view.makeViewport({ viewState, width: this.width, height: this.height }); let oldController = oldControllers[view.id]; const hasController = Boolean(view.controller); if (hasController && !oldController) { invalidateControllers = true; } if ((invalidateControllers || !hasController) && oldController) { oldController.finalize(); oldController = null; } this.controllers[view.id] = this._updateController(view, viewState, viewport, oldController); if (viewport) { this._viewports.unshift(viewport); } } for (const id in oldControllers) { const oldController = oldControllers[id]; if (oldController && !this.controllers[id]) { oldController.finalize(); } } this._buildViewportMap(); } _buildViewportMap() { this._viewportMap = {}; this._viewports.forEach((viewport) => { if (viewport.id) { this._viewportMap[viewport.id] = this._viewportMap[viewport.id] || viewport; } }); } _diffViews(newViews, oldViews) { if (newViews.length !== oldViews.length) { return true; } return newViews.some((_, i) => !newViews[i].equals(oldViews[i])); } }; // src/utils/positions.ts var PERCENT_OR_PIXELS_REGEX = /([0-9]+\.?[0-9]*)(%|px)/; function parsePosition(value) { switch (typeof value) { case "number": return { position: value, relative: false }; case "string": const match = PERCENT_OR_PIXELS_REGEX.exec(value); if (match && match.length >= 3) { const relative = match[2] === "%"; const position = parseFloat(match[1]); return { position: relative ? position / 100 : position, relative }; } default: throw new Error(`Could not parse position string ${value}`); } } function getPosition(position, extent) { return position.relative ? Math.round(position.position * extent) : position.position; } // src/views/view.ts var View = class { constructor(props) { const { id, x = 0, y = 0, width = "100%", height = "100%", padding = null } = props; this.id = id || this.constructor.displayName || "view"; this.props = { ...props, id: this.id }; this._x = parsePosition(x); this._y = parsePosition(y); this._width = parsePosition(width); this._height = parsePosition(height); this._padding = padding && { left: parsePosition(padding.left || 0), right: parsePosition(padding.right || 0), top: parsePosition(padding.top || 0), bottom: parsePosition(padding.bottom || 0) }; this.equals = this.equals.bind(this); Object.seal(this); } equals(view) { if (this === view) { return true; } return this.ViewportType === view.ViewportType && deepEqual2(this.props, view.props, 2); } makeViewport({ width, height, viewState }) { viewState = this.filterViewState(viewState); const viewportDimensions = this.getDimensions({ width, height }); if (!viewportDimensions.height || !viewportDimensions.width) { return null; } return new this.ViewportType({ ...viewState, ...this.props, ...viewportDimensions }); } getViewStateId() { const { viewState } = this.props; if (typeof viewState === "string") { return viewState; } return viewState?.id || this.id; } filterViewState(viewState) { if (this.props.viewState && typeof this.props.viewState === "object") { if (!this.props.viewState.id) { return this.props.viewState; } const newViewState = { ...viewState }; for (const key in this.props.viewState) { if (key !== "id") { newViewState[key] = this.props.viewState[key]; } } return newViewState; } return viewState; } getDimensions({ width, height }) { const dimensions = { x: getPosition(this._x, width), y: getPosition(this._y, height), width: getPosition(this._width, width), height: getPosition(this._height, height) }; if (this._padding) { dimensions.padding = { left: getPosition(this._padding.left, width), top: getPosition(this._padding.top, height), right: getPosition(this._padding.right, width), bottom: getPosition(this._padding.bottom, height) }; } return dimensions; } get controller() { const opts = this.props.controller; if (!opts) { return null; } if (opts === true) { return { type: this.ControllerType }; } if (typeof opts === "function") { return { type: opts }; } return { type: this.ControllerType, ...opts }; } }; // src/transitions/transition.ts var Transition = class { constructor(timeline) { this._inProgress = false; this._handle = null; this.time = 0; this.settings = { duration: 0 }; this._timeline = timeline; } get inProgress() { return this._inProgress; } start(settings) { this.cancel(); this.settings = settings; this._inProgress = true; this.settings.onStart?.(this); } end() { if (this._inProgress) { this._timeline.removeChannel(this._handle); this._handle = null; this._inProgress = false; this.settings.onEnd?.(this); } } cancel() { if (this._inProgress) { this.settings.onInterrupt?.(this); this._timeline.removeChannel(this._handle); this._handle = null; this._inProgress = false; } } update() { if (!this._inProgress) { return false; } if (this._handle === null) { const { _timeline: timeline, settings } = this; this._handle = timeline.addChannel({ delay: timeline.getTime(), duration: settings.duration }); } this.time = this._timeline.getTime(this._handle); this._onUpdate(); this.settings.onUpdate?.(this); if (this._timeline.isFinished(this._handle)) { this.end(); } return true; } _onUpdate() { } }; // src/controllers/transition-manager.ts var noop2 = () => { }; var TRANSITION_EVENTS = { BREAK: 1, SNAP_TO_END: 2, IGNORE: 3 }; var DEFAULT_EASING = (t) => t; var DEFAULT_INTERRUPTION = TRANSITION_EVENTS.BREAK; var TransitionManager = class { constructor(opts) { this._onTransitionUpdate = (transition) => { const { time, settings: { interpolator, startProps, endProps, duration, easing } } = transition; const t = easing(time / duration); const viewport = interpolator.interpolateProps(startProps, endProps, t); this.propsInTransition = this.getControllerState({ ...this.props, ...viewport }).getViewportProps(); this.onViewStateChange({ viewState: this.propsInTransition, oldViewState: this.props }); }; this.getControllerState = opts.getControllerState; this.propsInTransition = null; this.transition = new Transition(opts.timeline); this.onViewStateChange = opts.onViewStateChange || noop2; this.onStateChange = opts.onStateChange || noop2; } finalize() { this.transition.cancel(); } getViewportInTransition() { return this.propsInTransition; } processViewStateChange(nextProps) { let transitionTriggered = false; const currentProps = this.props; this.props = nextProps; if (!currentProps || this._shouldIgnoreViewportChange(currentProps, nextProps)) { return false; } if (this._isTransitionEnabled(nextProps)) { let startProps = currentProps; if (this.transition.inProgress) { const { interruption, endProps } = this.transition.settings; startProps = { ...currentProps, ...interruption === TRANSITION_EVENTS.SNAP_TO_END ? endProps : this.propsInTransition || currentProps }; } this._triggerTransition(startProps, nextProps); transitionTriggered = true; } else { this.transition.cancel(); } return transitionTriggered; } updateTransition() { this.transition.update(); } _isTransitionEnabled(props) { const { transitionDuration, transitionInterpolator } = props; return (transitionDuration > 0 || transitionDuration === "auto") && Boolean(transitionInterpolator); } _isUpdateDueToCurrentTransition(props) { if (this.transition.inProgress && this.propsInTransition) { return this.transition.settings.interpolator.arePropsEqual( props, this.propsInTransition ); } return false; } _shouldIgnoreViewportChange(currentProps, nextProps) { if (this.transition.inProgress) { const transitionSettings = this.transition.settings; return transitionSettings.interruption === TRANSITION_EVENTS.IGNORE || this._isUpdateDueToCurrentTransition(nextProps); } if (this._isTransitionEnabled(nextProps)) { return nextProps.transitionInterpolator.arePropsEqual( currentProps, nextProps ); } return true; } _triggerTransition(startProps, endProps) { const startViewstate = this.getControllerState(startProps); const endViewStateProps = this.getControllerState(endProps).shortestPathFrom(startViewstate); const transitionInterpolator = endProps.transitionInterpolator; const duration = transitionInterpolator.getDuration ? transitionInterpolator.getDuration(startProps, endProps) : endProps.transitionDuration; if (duration === 0) { return; } const initialProps = transitionInterpolator.initializeProps(startProps, endViewStateProps); this.propsInTransition = {}; const transitionSettings = { duration, easing: endProps.transitionEasing || DEFAULT_EASING, interpolator: transitionInterpolator, interruption: endProps.transitionInterruption || DEFAULT_INTERRUPTION, startProps: initialProps.start, endProps: initialProps.end, onStart: endProps.onTransitionStart, onUpdate: this._onTransitionUpdate, onInterrupt: this._onTransitionEnd(endProps.onTransitionInterrupt), onEnd: this._onTransitionEnd(endProps.onTransitionEnd) }; this.transition.start(transitionSettings); this.onStateChange({ inTransition: true }); this.updateTransition(); } _onTransitionEnd(callback) { return (transition) => { this.propsInTransition = null; this.onStateChange({ inTransition: false, isZooming: false, isPanning: false, isRotating: false }); callback?.(transition); }; } }; // src/utils/assert.ts function assert8(condition, message2) { if (!condition) { throw new Error(message2 || "deck.gl: assertion failed."); } } // src/transitions/transition-interpolator.ts var TransitionInterpolator = class { constructor(opts) { const { compare, extract, required } = opts; this._propsToCompare = compare; this._propsToExtract = extract || compare; this._requiredProps = required; } arePropsEqual(currentProps, nextProps) { for (const key of this._propsToCompare) { if (!(key in currentProps) || !(key in nextProps) || !equals(currentProps[key], nextProps[key])) { return false; } } return true; } initializeProps(startProps, endProps) { const startViewStateProps = {}; const endViewStateProps = {}; for (const key of this._propsToExtract) { if (key in startProps || key in endProps) { startViewStateProps[key] = startProps[key]; endViewStateProps[key] = endProps[key]; } } this._checkRequiredProps(startViewStateProps); this._checkRequiredProps(endViewStateProps); return { start: startViewStateProps, end: endViewStateProps }; } getDuration(startProps, endProps) { return endProps.transitionDuration; } _checkRequiredProps(props) { if (!this._requiredProps) { return; } this._requiredProps.forEach((propName) => { const value = props[propName]; assert8( Number.isFinite(value) || Array.isArray(value), `${propName} is required for transition` ); }); } }; // src/transitions/linear-interpolator.ts var DEFAULT_PROPS2 = ["longitude", "latitude", "zoom", "bearing", "pitch"]; var DEFAULT_REQUIRED_PROPS = ["longitude", "latitude", "zoom"]; var LinearInterpolator = class extends TransitionInterpolator { constructor(opts = {}) { const transitionProps = Array.isArray(opts) ? opts : opts.transitionProps; const normalizedOpts = Array.isArray(opts) ? {} : opts; normalizedOpts.transitionProps = Array.isArray(transitionProps) ? { compare: transitionProps, required: transitionProps } : transitionProps || { compare: DEFAULT_PROPS2, required: DEFAULT_REQUIRED_PROPS }; super(normalizedOpts.transitionProps); this.opts = normalizedOpts; } initializeProps(startProps, endProps) { const result = super.initializeProps(startProps, endProps); const { makeViewport, around } = this.opts; if (makeViewport && around) { const startViewport = makeViewport(startProps); const endViewport = makeViewport(endProps); const aroundPosition = startViewport.unproject(around); result.start.around = around; Object.assign(result.end, { around: endViewport.project(aroundPosition), aroundPosition, width: endProps.width, height: endProps.height }); } return result; } interpolateProps(startProps, endProps, t) { const propsInTransition = {}; for (const key of this._propsToExtract) { propsInTransition[key] = lerp(startProps[key] || 0, endProps[key] || 0, t); } if (endProps.aroundPosition && this.opts.makeViewport) { const viewport = this.opts.makeViewport({ ...endProps, ...propsInTransition }); Object.assign( propsInTransition, viewport.panByPosition( endProps.aroundPosition, lerp(startProps.around, endProps.around, t) ) ); } return propsInTransition; } }; // src/controllers/controller.ts var NO_TRANSITION_PROPS = { transitionDuration: 0 }; var DEFAULT_INERTIA = 300; var INERTIA_EASING = (t) => 1 - (1 - t) * (1 - t); var EVENT_TYPES = { WHEEL: ["wheel"], PAN: ["panstart", "panmove", "panend"], PINCH: ["pinchstart", "pinchmove", "pinchend"], TRIPLE_PAN: ["tripanstart", "tripanmove", "tripanend"], DOUBLE_TAP: ["doubletap"], KEYBOARD: ["keydown"] }; var pinchEventWorkaround = {}; var Controller = class { constructor(opts) { this.state = {}; this._events = {}; this._interactionState = { isDragging: false }; this._customEvents = []; this._eventStartBlocked = null; this._panMove = false; this.invertPan = false; this.dragMode = "rotate"; this.inertia = 0; this.scrollZoom = true; this.dragPan = true; this.dragRotate = true; this.doubleClickZoom = true; this.touchZoom = true; this.touchRotate = false; this.keyboard = true; this.transitionManager = new TransitionManager({ ...opts, getControllerState: (props) => new this.ControllerState(props), onViewStateChange: this._onTransition.bind(this), onStateChange: this._setInteractionState.bind(this) }); this.handleEvent = this.handleEvent.bind(this); this.eventManager = opts.eventManager; this.onViewStateChange = opts.onViewStateChange || (() => { }); this.onStateChange = opts.onStateChange || (() => { }); this.makeViewport = opts.makeViewport; } set events(customEvents) { this.toggleEvents(this._customEvents, false); this.toggleEvents(customEvents, true); this._customEvents = customEvents; if (this.props) { this.setProps(this.props); } } finalize() { for (const eventName in this._events) { if (this._events[eventName]) { this.eventManager?.off(eventName, this.handleEvent); } } this.transitionManager.finalize(); } handleEvent(event) { this._controllerState = void 0; const eventStartBlocked = this._eventStartBlocked; switch (event.type) { case "panstart": return eventStartBlocked ? false : this._onPanStart(event); case "panmove": return this._onPan(event); case "panend": return this._onPanEnd(event); case "pinchstart": return eventStartBlocked ? false : this._onPinchStart(event); case "pinchmove": return this._onPinch(event); case "pinchend": return this._onPinchEnd(event); case "tripanstart": return eventStartBlocked ? false : this._onTriplePanStart(event); case "tripanmove": return this._onTriplePan(event); case "tripanend": return this._onTriplePanEnd(event); case "doubletap": return this._onDoubleTap(event); case "wheel": return this._onWheel(event); case "keydown": return this._onKeyDown(event); default: return false; } } get controllerState() { this._controllerState = this._controllerState || new this.ControllerState({ makeViewport: this.makeViewport, ...this.props, ...this.state }); return this._controllerState; } getCenter(event) { const { x, y } = this.props; const { offsetCenter } = event; return [offsetCenter.x - x, offsetCenter.y - y]; } isPointInBounds(pos, event) { const { width, height } = this.props; if (event && event.handled) { return false; } const inside = pos[0] >= 0 && pos[0] <= width && pos[1] >= 0 && pos[1] <= height; if (inside && event) { event.stopPropagation(); } return inside; } isFunctionKeyPressed(event) { const { srcEvent } = event; return Boolean(srcEvent.metaKey || srcEvent.altKey || srcEvent.ctrlKey || srcEvent.shiftKey); } isDragging() { return this._interactionState.isDragging || false; } blockEvents(timeout) { const timer = setTimeout(() => { if (this._eventStartBlocked === timer) { this._eventStartBlocked = null; } }, timeout); this._eventStartBlocked = timer; } setProps(props) { if (props.dragMode) { this.dragMode = props.dragMode; } this.props = props; if (!("transitionInterpolator" in props)) { props.transitionInterpolator = this._getTransitionProps().transitionInterpolator; } this.transitionManager.processViewStateChange(props); const { inertia } = props; this.inertia = Number.isFinite(inertia) ? inertia : inertia === true ? DEFAULT_INERTIA : 0; const { scrollZoom = true, dragPan = true, dragRotate = true, doubleClickZoom = true, touchZoom = true, touchRotate = false, keyboard = true } = props; const isInteractive = Boolean(this.onViewStateChange); this.toggleEvents(EVENT_TYPES.WHEEL, isInteractive && scrollZoom); this.toggleEvents(EVENT_TYPES.PAN, isInteractive); this.toggleEvents(EVENT_TYPES.PINCH, isInteractive && (touchZoom || touchRotate)); this.toggleEvents(EVENT_TYPES.TRIPLE_PAN, isInteractive && touchRotate); this.toggleEvents(EVENT_TYPES.DOUBLE_TAP, isInteractive && doubleClickZoom); this.toggleEvents(EVENT_TYPES.KEYBOARD, isInteractive && keyboard); this.scrollZoom = scrollZoom; this.dragPan = dragPan; this.dragRotate = dragRotate; this.doubleClickZoom = doubleClickZoom; this.touchZoom = touchZoom; this.touchRotate = touchRotate; this.keyboard = keyboard; } updateTransition() { this.transitionManager.updateTransition(); } toggleEvents(eventNames, enabled) { if (this.eventManager) { eventNames.forEach((eventName) => { if (this._events[eventName] !== enabled) { this._events[eventName] = enabled; if (enabled) { this.eventManager.on(eventName, this.handleEvent); } else { this.eventManager.off(eventName, this.handleEvent); } } }); } } updateViewport(newControllerState, extraProps = null, interactionState = {}) { const viewState = { ...newControllerState.getViewportProps(), ...extraProps }; const changed = this.controllerState !== newControllerState; this.state = newControllerState.getState(); this._setInteractionState(interactionState); if (changed) { const oldViewState = this.controllerState && this.controllerState.getViewportProps(); if (this.onViewStateChange) { this.onViewStateChange({ viewState, interactionState: this._interactionState, oldViewState, viewId: this.props.id }); } } } _onTransition(params) { this.onViewStateChange({ ...params, interactionState: this._interactionState, viewId: this.props.id }); } _setInteractionState(newStates) { Object.assign(this._interactionState, newStates); this.onStateChange(this._interactionState); } _onPanStart(event) { const pos = this.getCenter(event); if (!this.isPointInBounds(pos, event)) { return false; } let alternateMode = this.isFunctionKeyPressed(event) || event.rightButton || false; if (this.invertPan || this.dragMode === "pan") { alternateMode = !alternateMode; } const newControllerState = this.controllerState[alternateMode ? "panStart" : "rotateStart"]({ pos }); this._panMove = alternateMode; this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true }); return true; } _onPan(event) { if (!this.isDragging()) { return false; } return this._panMove ? this._onPanMove(event) : this._onPanRotate(event); } _onPanEnd(event) { if (!this.isDragging()) { return false; } return this._panMove ? this._onPanMoveEnd(event) : this._onPanRotateEnd(event); } _onPanMove(event) { if (!this.dragPan) { return false; } const pos = this.getCenter(event); const newControllerState = this.controllerState.pan({ pos }); this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true, isPanning: true }); return true; } _onPanMoveEnd(event) { const { inertia } = this; if (this.dragPan && inertia && event.velocity) { const pos = this.getCenter(event); const endPos = [ pos[0] + event.velocityX * inertia / 2, pos[1] + event.velocityY * inertia / 2 ]; const newControllerState = this.controllerState.pan({ pos: endPos }).panEnd(); this.updateViewport( newControllerState, { ...this._getTransitionProps(), transitionDuration: inertia, transitionEasing: INERTIA_EASING }, { isDragging: false, isPanning: true } ); } else { const newControllerState = this.controllerState.panEnd(); this.updateViewport(newControllerState, null, { isDragging: false, isPanning: false }); } return true; } _onPanRotate(event) { if (!this.dragRotate) { return false; } const pos = this.getCenter(event); const newControllerState = this.controllerState.rotate({ pos }); this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true, isRotating: true }); return true; } _onPanRotateEnd(event) { const { inertia } = this; if (this.dragRotate && inertia && event.velocity) { const pos = this.getCenter(event); const endPos = [ pos[0] + event.velocityX * inertia / 2, pos[1] + event.velocityY * inertia / 2 ]; const newControllerState = this.controllerState.rotate({ pos: endPos }).rotateEnd(); this.updateViewport( newControllerState, { ...this._getTransitionProps(), transitionDuration: inertia, transitionEasing: INERTIA_EASING }, { isDragging: false, isRotating: true } ); } else { const newControllerState = this.controllerState.rotateEnd(); this.updateViewport(newControllerState, null, { isDragging: false, isRotating: false }); } return true; } _onWheel(event) { if (!this.scrollZoom) { return false; } const pos = this.getCenter(event); if (!this.isPointInBounds(pos, event)) { return false; } event.srcEvent.preventDefault(); const { speed = 0.01, smooth = false } = this.scrollZoom === true ? {} : this.scrollZoom; const { delta } = event; let scale5 = 2 / (1 + Math.exp(-Math.abs(delta * speed))); if (delta < 0 && scale5 !== 0) { scale5 = 1 / scale5; } const newControllerState = this.controllerState.zoom({ pos, scale: scale5 }); this.updateViewport( newControllerState, { ...this._getTransitionProps({ around: pos }), transitionDuration: smooth ? 250 : 1 }, { isZooming: true, isPanning: true } ); return true; } _onTriplePanStart(event) { const pos = this.getCenter(event); if (!this.isPointInBounds(pos, event)) { return false; } const newControllerState = this.controllerState.rotateStart({ pos }); this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true }); return true; } _onTriplePan(event) { if (!this.touchRotate) { return false; } if (!this.isDragging()) { return false; } const pos = this.getCenter(event); pos[0] -= event.deltaX; const newControllerState = this.controllerState.rotate({ pos }); this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true, isRotating: true }); return true; } _onTriplePanEnd(event) { if (!this.isDragging()) { return false; } const { inertia } = this; if (this.touchRotate && inertia && event.velocityY) { const pos = this.getCenter(event); const endPos = [pos[0], pos[1] += event.velocityY * inertia / 2]; const newControllerState = this.controllerState.rotate({ pos: endPos }); this.updateViewport( newControllerState, { ...this._getTransitionProps(), transitionDuration: inertia, transitionEasing: INERTIA_EASING }, { isDragging: false, isRotating: true } ); this.blockEvents(inertia); } else { const newControllerState = this.controllerState.rotateEnd(); this.updateViewport(newControllerState, null, { isDragging: false, isRotating: false }); } return true; } _onPinchStart(event) { const pos = this.getCenter(event); if (!this.isPointInBounds(pos, event)) { return false; } const newControllerState = this.controllerState.zoomStart({ pos }).rotateStart({ pos }); pinchEventWorkaround._startPinchRotation = event.rotation; pinchEventWorkaround._lastPinchEvent = event; this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true }); return true; } _onPinch(event) { if (!this.touchZoom && !this.touchRotate) { return false; } if (!this.isDragging()) { return false; } let newControllerState = this.controllerState; if (this.touchZoom) { const { scale: scale5 } = event; const pos = this.getCenter(event); newControllerState = newControllerState.zoom({ pos, scale: scale5 }); } if (this.touchRotate) { const { rotation } = event; newControllerState = newControllerState.rotate({ deltaAngleX: pinchEventWorkaround._startPinchRotation - rotation }); } this.updateViewport(newControllerState, NO_TRANSITION_PROPS, { isDragging: true, isPanning: this.touchZoom, isZooming: this.touchZoom, isRotating: this.touchRotate }); pinchEventWorkaround._lastPinchEvent = event; return true; } _onPinchEnd(event) { if (!this.isDragging()) { return false; } const { inertia } = this; const { _lastPinchEvent } = pinchEventWorkaround; if (this.touchZoom && inertia && _lastPinchEvent && event.scale !== _lastPinchEvent.scale) { const pos = this.getCenter(event); let newControllerState = this.controllerState.rotateEnd(); const z = Math.log2(event.scale); const velocityZ = (z - Math.log2(_lastPinchEvent.scale)) / (event.deltaTime - _lastPinchEvent.deltaTime); const endScale = Math.pow(2, z + velocityZ * inertia / 2); newControllerState = newControllerState.zoom({ pos, scale: endScale }).zoomEnd(); this.updateViewport( newControllerState, { ...this._getTransitionProps({ around: pos }), transitionDuration: inertia, transitionEasing: INERTIA_EASING }, { isDragging: false, isPanning: this.touchZoom, isZooming: this.touchZoom, isRotating: false } ); this.blockEvents(inertia); } else { const newControllerState = this.controllerState.zoomEnd().rotateEnd(); this.updateViewport(newControllerState, null, { isDragging: false, isPanning: false, isZooming: false, isRotating: false }); } pinchEventWorkaround._startPinchRotation = null; pinchEventWorkaround._lastPinchEvent = null; return true; } _onDoubleTap(event) { if (!this.doubleClickZoom) { return false; } const pos = this.getCenter(event); if (!this.isPointInBounds(pos, event)) { return false; } const isZoomOut = this.isFunctionKeyPressed(event); const newControllerState = this.controllerState.zoom({ pos, scale: isZoomOut ? 0.5 : 2 }); this.updateViewport(newControllerState, this._getTransitionProps({ around: pos }), { isZooming: true, isPanning: true }); this.blockEvents(100); return true; } _onKeyDown(event) { if (!this.keyboard) { return false; } const funcKey = this.isFunctionKeyPressed(event); const { zoomSpeed, moveSpeed, rotateSpeedX, rotateSpeedY } = this.keyboard === true ? {} : this.keyboard; const { controllerState } = this; let newControllerState; const interactionState = {}; switch (event.srcEvent.code) { case "Minus": newControllerState = funcKey ? controllerState.zoomOut(zoomSpeed).zoomOut(zoomSpeed) : controllerState.zoomOut(zoomSpeed); interactionState.isZooming = true; break; case "Equal": newControllerState = funcKey ? controllerState.zoomIn(zoomSpeed).zoomIn(zoomSpeed) : controllerState.zoomIn(zoomSpeed); interactionState.isZooming = true; break; case "ArrowLeft": if (funcKey) { newControllerState = controllerState.rotateLeft(rotateSpeedX); interactionState.isRotating = true; } else { newControllerState = controllerState.moveLeft(moveSpeed); interactionState.isPanning = true; } break; case "ArrowRight": if (funcKey) { newControllerState = controllerState.rotateRight(rotateSpeedX); interactionState.isRotating = true; } else { newControllerState = controllerState.moveRight(moveSpeed); interactionState.isPanning = true; } break; case "ArrowUp": if (funcKey) { newControllerState = controllerState.rotateUp(rotateSpeedY); interactionState.isRotating = true; } else { newControllerState = controllerState.moveUp(moveSpeed); interactionState.isPanning = true; } break; case "ArrowDown": if (funcKey) { newControllerState = controllerState.rotateDown(rotateSpeedY); interactionState.isRotating = true; } else { newControllerState = controllerState.moveDown(moveSpeed); interactionState.isPanning = true; } break; default: return false; } this.updateViewport(newControllerState, this._getTransitionProps(), interactionState); return true; } _getTransitionProps(opts) { const { transition } = this; if (!transition || !transition.transitionInterpolator) { return NO_TRANSITION_PROPS; } return opts ? { ...transition, transitionInterpolator: new LinearInterpolator({ ...opts, ...transition.transitionInterpolator.opts, makeViewport: this.controllerState.makeViewport }) } : transition; } }; // src/controllers/view-state.ts var ViewState = class { constructor(props, state) { this._viewportProps = this.applyConstraints(props); this._state = state; } getViewportProps() { return this._viewportProps; } getState() { return this._state; } }; // src/controllers/map-controller.ts var PITCH_MOUSE_THRESHOLD = 5; var PITCH_ACCEL = 1.2; var MapState = class extends ViewState { constructor(options) { const { width, height, latitude, longitude, zoom, bearing = 0, pitch = 0, altitude = 1.5, position = [0, 0, 0], maxZoom = 20, minZoom = 0, maxPitch = 60, minPitch = 0, startPanLngLat, startZoomLngLat, startRotatePos, startBearing, startPitch, startZoom, normalize: normalize4 = true } = options; assert8(Number.isFinite(longitude)); assert8(Number.isFinite(latitude)); assert8(Number.isFinite(zoom)); super( { width, height, latitude, longitude, zoom, bearing, pitch, altitude, maxZoom, minZoom, maxPitch, minPitch, normalize: normalize4, position }, { startPanLngLat, startZoomLngLat, startRotatePos, startBearing, startPitch, startZoom } ); this.makeViewport = options.makeViewport; } panStart({ pos }) { return this._getUpdatedState({ startPanLngLat: this._unproject(pos) }); } pan({ pos, startPos }) { const startPanLngLat = this.getState().startPanLngLat || this._unproject(startPos); if (!startPanLngLat) { return this; } const viewport = this.makeViewport(this.getViewportProps()); const newProps = viewport.panByPosition(startPanLngLat, pos); return this._getUpdatedState(newProps); } panEnd() { return this._getUpdatedState({ startPanLngLat: null }); } rotateStart({ pos }) { return this._getUpdatedState({ startRotatePos: pos, startBearing: this.getViewportProps().bearing, startPitch: this.getViewportProps().pitch }); } rotate({ pos, deltaAngleX = 0, deltaAngleY = 0 }) { const { startRotatePos, startBearing, startPitch } = this.getState(); if (!startRotatePos || startBearing === void 0 || startPitch === void 0) { return this; } let newRotation; if (pos) { newRotation = this._getNewRotation(pos, startRotatePos, startPitch, startBearing); } else { newRotation = { bearing: startBearing + deltaAngleX, pitch: startPitch + deltaAngleY }; } return this._getUpdatedState(newRotation); } rotateEnd() { return this._getUpdatedState({ startBearing: null, startPitch: null }); } zoomStart({ pos }) { return this._getUpdatedState({ startZoomLngLat: this._unproject(pos), startZoom: this.getViewportProps().zoom }); } zoom({ pos, startPos, scale: scale5 }) { let { startZoom, startZoomLngLat } = this.getState(); if (!startZoomLngLat) { startZoom = this.getViewportProps().zoom; startZoomLngLat = this._unproject(startPos) || this._unproject(pos); } if (!startZoomLngLat) { return this; } const { maxZoom, minZoom } = this.getViewportProps(); let zoom = startZoom + Math.log2(scale5); zoom = clamp(zoom, minZoom, maxZoom); const zoomedViewport = this.makeViewport({ ...this.getViewportProps(), zoom }); return this._getUpdatedState({ zoom, ...zoomedViewport.panByPosition(startZoomLngLat, pos) }); } zoomEnd() { return this._getUpdatedState({ startZoomLngLat: null, startZoom: null }); } zoomIn(speed = 2) { return this._zoomFromCenter(speed); } zoomOut(speed = 2) { return this._zoomFromCenter(1 / speed); } moveLeft(speed = 100) { return this._panFromCenter([speed, 0]); } moveRight(speed = 100) { return this._panFromCenter([-speed, 0]); } moveUp(speed = 100) { return this._panFromCenter([0, speed]); } moveDown(speed = 100) { return this._panFromCenter([0, -speed]); } rotateLeft(speed = 15) { return this._getUpdatedState({ bearing: this.getViewportProps().bearing - speed }); } rotateRight(speed = 15) { return this._getUpdatedState({ bearing: this.getViewportProps().bearing + speed }); } rotateUp(speed = 10) { return this._getUpdatedState({ pitch: this.getViewportProps().pitch + speed }); } rotateDown(speed = 10) { return this._getUpdatedState({ pitch: this.getViewportProps().pitch - speed }); } shortestPathFrom(viewState) { const fromProps = viewState.getViewportProps(); const props = { ...this.getViewportProps() }; const { bearing, longitude } = props; if (Math.abs(bearing - fromProps.bearing) > 180) { props.bearing = bearing < 0 ? bearing + 360 : bearing - 360; } if (Math.abs(longitude - fromProps.longitude) > 180) { props.longitude = longitude < 0 ? longitude + 360 : longitude - 360; } return props; } applyConstraints(props) { const { maxZoom, minZoom, zoom } = props; props.zoom = clamp(zoom, minZoom, maxZoom); const { maxPitch, minPitch, pitch } = props; props.pitch = clamp(pitch, minPitch, maxPitch); const { normalize: normalize4 = true } = props; if (normalize4) { Object.assign(props, normalizeViewportProps(props)); } return props; } _zoomFromCenter(scale5) { const { width, height } = this.getViewportProps(); return this.zoom({ pos: [width / 2, height / 2], scale: scale5 }); } _panFromCenter(offset) { const { width, height } = this.getViewportProps(); return this.pan({ startPos: [width / 2, height / 2], pos: [width / 2 + offset[0], height / 2 + offset[1]] }); } _getUpdatedState(newProps) { return new this.constructor({ makeViewport: this.makeViewport, ...this.getViewportProps(), ...this.getState(), ...newProps }); } _unproject(pos) { const viewport = this.makeViewport(this.getViewportProps()); return pos && viewport.unproject(pos); } _getNewRotation(pos, startPos, startPitch, startBearing) { const deltaX = pos[0] - startPos[0]; const deltaY = pos[1] - startPos[1]; const centerY = pos[1]; const startY = startPos[1]; const { width, height } = this.getViewportProps(); const deltaScaleX = deltaX / width; let deltaScaleY = 0; if (deltaY > 0) { if (Math.abs(height - startY) > PITCH_MOUSE_THRESHOLD) { deltaScaleY = deltaY / (startY - height) * PITCH_ACCEL; } } else if (deltaY < 0) { if (startY > PITCH_MOUSE_THRESHOLD) { deltaScaleY = 1 - centerY / startY; } } deltaScaleY = clamp(deltaScaleY, -1, 1); const { minPitch, maxPitch } = this.getViewportProps(); const bearing = startBearing + 180 * deltaScaleX; let pitch = startPitch; if (deltaScaleY > 0) { pitch = startPitch + deltaScaleY * (maxPitch - startPitch); } else if (deltaScaleY < 0) { pitch = startPitch - deltaScaleY * (minPitch - startPitch); } return { pitch, bearing }; } }; var MapController = class extends Controller { constructor() { super(...arguments); this.ControllerState = MapState; this.transition = { transitionDuration: 300, transitionInterpolator: new LinearInterpolator({ transitionProps: { compare: ["longitude", "latitude", "zoom", "bearing", "pitch", "position"], required: ["longitude", "latitude", "zoom"] } }) }; this.dragMode = "pan"; } setProps(props) { props.position = props.position || [0, 0, 0]; const oldProps = this.props; super.setProps(props); const dimensionChanged = !oldProps || oldProps.height !== props.height; if (dimensionChanged) { this.updateViewport( new this.ControllerState({ makeViewport: this.makeViewport, ...props, ...this.state }) ); } } }; // src/views/map-view.ts var MapView = class extends View { constructor(props = {}) { super(props); } get ViewportType() { return WebMercatorViewport2; } get ControllerType() { return MapController; } }; MapView.displayName = "MapView"; // src/lib/effect-manager.ts var DEFAULT_LIGHTING_EFFECT = new LightingEffect(); function compareEffects(e1, e2) { const o1 = e1.order ?? Infinity; const o2 = e2.order ?? Infinity; return o1 - o2; } var EffectManager = class { constructor(context) { this._resolvedEffects = []; this._defaultEffects = []; this.effects = []; this._context = context; this._needsRedraw = "Initial render"; this._setEffects([]); } addDefaultEffect(effect) { const defaultEffects = this._defaultEffects; if (!defaultEffects.find((e2) => e2.id === effect.id)) { const index2 = defaultEffects.findIndex((e2) => compareEffects(e2, effect) > 0); if (index2 < 0) { defaultEffects.push(effect); } else { defaultEffects.splice(index2, 0, effect); } effect.setup(this._context); this._setEffects(this.effects); } } setProps(props) { if ("effects" in props) { if (!deepEqual2(props.effects, this.effects, 1)) { this._setEffects(props.effects); } } } needsRedraw(opts = { clearRedrawFlags: false }) { const redraw = this._needsRedraw; if (opts.clearRedrawFlags) { this._needsRedraw = false; } return redraw; } getEffects() { return this._resolvedEffects; } _setEffects(effects) { const oldEffectsMap = {}; for (const effect of this.effects) { oldEffectsMap[effect.id] = effect; } const nextEffects = []; for (const effect of effects) { const oldEffect = oldEffectsMap[effect.id]; let effectToAdd = effect; if (oldEffect && oldEffect !== effect) { if (oldEffect.setProps) { oldEffect.setProps(effect.props); effectToAdd = oldEffect; } else { oldEffect.cleanup(this._context); } } else if (!oldEffect) { effect.setup(this._context); } nextEffects.push(effectToAdd); delete oldEffectsMap[effect.id]; } for (const removedEffectId in oldEffectsMap) { oldEffectsMap[removedEffectId].cleanup(this._context); } this.effects = nextEffects; this._resolvedEffects = nextEffects.concat(this._defaultEffects); if (!effects.some((effect) => effect instanceof LightingEffect)) { this._resolvedEffects.push(DEFAULT_LIGHTING_EFFECT); } this._needsRedraw = "effects changed"; } finalize() { for (const effect of this._resolvedEffects) { effect.cleanup(this._context); } this.effects.length = 0; this._resolvedEffects.length = 0; this._defaultEffects.length = 0; } }; // src/passes/draw-layers-pass.ts var DrawLayersPass = class extends LayersPass { shouldDrawLayer(layer) { const { operation } = layer.props; return operation.includes("draw") || operation.includes("terrain"); } }; // src/lib/deck-renderer.ts var TRACE_RENDER_LAYERS = "deckRenderer.renderLayers"; var DeckRenderer = class { constructor(device) { this.device = device; this.layerFilter = null; this.drawPickingColors = false; this.drawLayersPass = new DrawLayersPass(device); this.pickLayersPass = new PickLayersPass(device); this.renderCount = 0; this._needsRedraw = "Initial render"; this.renderBuffers = []; this.lastPostProcessEffect = null; } setProps(props) { if (this.layerFilter !== props.layerFilter) { this.layerFilter = props.layerFilter; this._needsRedraw = "layerFilter changed"; } if (this.drawPickingColors !== props.drawPickingColors) { this.drawPickingColors = props.drawPickingColors; this._needsRedraw = "drawPickingColors changed"; } } renderLayers(opts) { if (!opts.viewports.length) { return; } const layerPass = this.drawPickingColors ? this.pickLayersPass : this.drawLayersPass; const renderOpts = { layerFilter: this.layerFilter, isPicking: this.drawPickingColors, ...opts }; if (renderOpts.effects) { this._preRender(renderOpts.effects, renderOpts); } const outputBuffer = this.lastPostProcessEffect ? this.renderBuffers[0] : renderOpts.target; if (this.lastPostProcessEffect) { renderOpts.clearColor = [0, 0, 0, 0]; renderOpts.clearCanvas = true; } const renderStats = layerPass.render({ ...renderOpts, target: outputBuffer }); if (renderOpts.effects) { this._postRender(renderOpts.effects, renderOpts); } this.renderCount++; debug(TRACE_RENDER_LAYERS, this, renderStats, opts); } needsRedraw(opts = { clearRedrawFlags: false }) { const redraw = this._needsRedraw; if (opts.clearRedrawFlags) { this._needsRedraw = false; } return redraw; } finalize() { const { renderBuffers } = this; for (const buffer of renderBuffers) { buffer.delete(); } renderBuffers.length = 0; } _preRender(effects, opts) { this.lastPostProcessEffect = null; opts.preRenderStats = opts.preRenderStats || {}; for (const effect of effects) { opts.preRenderStats[effect.id] = effect.preRender(opts); if (effect.postRender) { this.lastPostProcessEffect = effect.id; } } if (this.lastPostProcessEffect) { this._resizeRenderBuffers(); } } _resizeRenderBuffers() { const { renderBuffers } = this; const size = this.device.canvasContext.getDrawingBufferSize(); if (renderBuffers.length === 0) { [0, 1].map((i) => { const texture = this.device.createTexture({ sampler: { minFilter: "linear", magFilter: "linear" } }); renderBuffers.push( this.device.createFramebuffer({ id: `deck-renderbuffer-${i}`, colorAttachments: [texture] }) ); }); } for (const buffer of renderBuffers) { buffer.resize(size); } } _postRender(effects, opts) { const { renderBuffers } = this; const params = { ...opts, inputBuffer: renderBuffers[0], swapBuffer: renderBuffers[1] }; for (const effect of effects) { if (effect.postRender) { params.target = effect.id === this.lastPostProcessEffect ? opts.target : void 0; const buffer = effect.postRender(params); params.inputBuffer = buffer; params.swapBuffer = buffer === renderBuffers[0] ? renderBuffers[1] : renderBuffers[0]; } } } }; // src/lib/picking/query-object.ts var NO_PICKED_OBJECT = { pickedColor: null, pickedObjectIndex: -1 }; function getClosestObject({ pickedColors, decodePickingColor, deviceX, deviceY, deviceRadius, deviceRect }) { const { x, y, width, height } = deviceRect; let minSquareDistanceToCenter = deviceRadius * deviceRadius; let closestPixelIndex = -1; let i = 0; for (let row = 0; row < height; row++) { const dy = row + y - deviceY; const dy2 = dy * dy; if (dy2 > minSquareDistanceToCenter) { i += 4 * width; } else { for (let col = 0; col < width; col++) { const pickedLayerIndex = pickedColors[i + 3] - 1; if (pickedLayerIndex >= 0) { const dx = col + x - deviceX; const d2 = dx * dx + dy2; if (d2 <= minSquareDistanceToCenter) { minSquareDistanceToCenter = d2; closestPixelIndex = i; } } i += 4; } } } if (closestPixelIndex >= 0) { const pickedColor = pickedColors.slice(closestPixelIndex, closestPixelIndex + 4); const pickedObject = decodePickingColor(pickedColor); if (pickedObject) { const dy = Math.floor(closestPixelIndex / 4 / width); const dx = closestPixelIndex / 4 - dy * width; return { ...pickedObject, pickedColor, pickedX: x + dx, pickedY: y + dy }; } log_default.error("Picked non-existent layer. Is picking buffer corrupt?")(); } return NO_PICKED_OBJECT; } function getUniqueObjects({ pickedColors, decodePickingColor }) { const uniqueColors = /* @__PURE__ */ new Map(); if (pickedColors) { for (let i = 0; i < pickedColors.length; i += 4) { const pickedLayerIndex = pickedColors[i + 3] - 1; if (pickedLayerIndex >= 0) { const pickedColor = pickedColors.slice(i, i + 4); const colorKey = pickedColor.join(","); if (!uniqueColors.has(colorKey)) { const pickedObject = decodePickingColor(pickedColor); if (pickedObject) { uniqueColors.set(colorKey, { ...pickedObject, color: pickedColor }); } else { log_default.error("Picked non-existent layer. Is picking buffer corrupt?")(); } } } } } return Array.from(uniqueColors.values()); } // src/lib/picking/pick-info.ts function getEmptyPickingInfo({ pickInfo, viewports, pixelRatio, x, y, z }) { let pickedViewport = viewports[0]; if (viewports.length > 1) { pickedViewport = getViewportFromCoordinates(pickInfo?.pickedViewports || viewports, { x, y }); } let coordinate; if (pickedViewport) { const point = [x - pickedViewport.x, y - pickedViewport.y]; if (z !== void 0) { point[2] = z; } coordinate = pickedViewport.unproject(point); } return { color: null, layer: null, viewport: pickedViewport, index: -1, picked: false, x, y, pixel: [x, y], coordinate, devicePixel: pickInfo && "pickedX" in pickInfo ? [pickInfo.pickedX, pickInfo.pickedY] : void 0, pixelRatio }; } function processPickInfo(opts) { const { pickInfo, lastPickedInfo, mode, layers } = opts; const { pickedColor, pickedLayer, pickedObjectIndex } = pickInfo; const affectedLayers = pickedLayer ? [pickedLayer] : []; if (mode === "hover") { const lastPickedPixelIndex = lastPickedInfo.index; const lastPickedLayerId = lastPickedInfo.layerId; const pickedLayerId = pickedLayer ? pickedLayer.props.id : null; if (pickedLayerId !== lastPickedLayerId || pickedObjectIndex !== lastPickedPixelIndex) { if (pickedLayerId !== lastPickedLayerId) { const lastPickedLayer = layers.find((layer) => layer.props.id === lastPickedLayerId); if (lastPickedLayer) { affectedLayers.unshift(lastPickedLayer); } } lastPickedInfo.layerId = pickedLayerId; lastPickedInfo.index = pickedObjectIndex; lastPickedInfo.info = null; } } const baseInfo = getEmptyPickingInfo(opts); const infos = /* @__PURE__ */ new Map(); infos.set(null, baseInfo); affectedLayers.forEach((layer) => { let info = { ...baseInfo }; if (layer === pickedLayer) { info.color = pickedColor; info.index = pickedObjectIndex; info.picked = true; } info = getLayerPickingInfo({ layer, info, mode }); const rootLayer = info.layer; if (layer === pickedLayer && mode === "hover") { lastPickedInfo.info = info; } infos.set(rootLayer.id, info); if (mode === "hover") { rootLayer.updateAutoHighlight(info); } }); return infos; } function getLayerPickingInfo({ layer, info, mode }) { while (layer && info) { const sourceLayer = info.layer || null; info.sourceLayer = sourceLayer; info.layer = layer; info = layer.getPickingInfo({ info, mode, sourceLayer }); layer = layer.parent; } return info; } function getViewportFromCoordinates(viewports, pixel) { for (let i = viewports.length - 1; i >= 0; i--) { const viewport = viewports[i]; if (viewport.containsPixel(pixel)) { return viewport; } } return viewports[0]; } // src/lib/deck-picker.ts var DeckPicker = class { constructor(device) { this._pickable = true; this.device = device; this.pickLayersPass = new PickLayersPass(device); this.lastPickedInfo = { index: -1, layerId: null, info: null }; } setProps(props) { if ("layerFilter" in props) { this.layerFilter = props.layerFilter; } if ("_pickable" in props) { this._pickable = props._pickable; } } finalize() { if (this.pickingFBO) { this.pickingFBO.destroy(); } if (this.depthFBO) { this.depthFBO.destroy(); } } pickObject(opts) { return this._pickClosestObject(opts); } pickObjects(opts) { return this._pickVisibleObjects(opts); } getLastPickedObject({ x, y, layers, viewports }, lastPickedInfo = this.lastPickedInfo.info) { const lastPickedLayerId = lastPickedInfo && lastPickedInfo.layer && lastPickedInfo.layer.id; const lastPickedViewportId = lastPickedInfo && lastPickedInfo.viewport && lastPickedInfo.viewport.id; const layer = lastPickedLayerId ? layers.find((l) => l.id === lastPickedLayerId) : null; const viewport = lastPickedViewportId && viewports.find((v) => v.id === lastPickedViewportId) || viewports[0]; const coordinate = viewport && viewport.unproject([x - viewport.x, y - viewport.y]); const info = { x, y, viewport, coordinate, layer }; return { ...lastPickedInfo, ...info }; } _resizeBuffer() { if (!this.pickingFBO) { this.pickingFBO = this.device.createFramebuffer({ colorAttachments: ["rgba8unorm"], depthStencilAttachment: "depth16unorm" }); if (this.device.isTextureFormatRenderable("rgba32float")) { const depthFBO = this.device.createFramebuffer({ colorAttachments: ["rgba32float"], depthStencilAttachment: "depth16unorm" }); this.depthFBO = depthFBO; } } const { canvas: canvas2 } = this.device.getCanvasContext(); this.pickingFBO?.resize({ width: canvas2.width, height: canvas2.height }); this.depthFBO?.resize({ width: canvas2.width, height: canvas2.height }); } _getPickable(layers) { if (this._pickable === false) { return null; } const pickableLayers = layers.filter( (layer) => this.pickLayersPass.shouldDrawLayer(layer) && !layer.isComposite ); return pickableLayers.length ? pickableLayers : null; } _pickClosestObject({ layers, views, viewports, x, y, radius = 0, depth = 1, mode = "query", unproject3D, onViewportActive, effects }) { const pixelRatio = this.device.canvasContext.cssToDeviceRatio(); const pickableLayers = this._getPickable(layers); if (!pickableLayers || viewports.length === 0) { return { result: [], emptyInfo: getEmptyPickingInfo({ viewports, x, y, pixelRatio }) }; } this._resizeBuffer(); const devicePixelRange = this.device.canvasContext.cssToDevicePixels([x, y], true); const devicePixel = [ devicePixelRange.x + Math.floor(devicePixelRange.width / 2), devicePixelRange.y + Math.floor(devicePixelRange.height / 2) ]; const deviceRadius = Math.round(radius * pixelRatio); const { width, height } = this.pickingFBO; const deviceRect = this._getPickingRect({ deviceX: devicePixel[0], deviceY: devicePixel[1], deviceRadius, deviceWidth: width, deviceHeight: height }); const cullRect = { x: x - radius, y: y - radius, width: radius * 2 + 1, height: radius * 2 + 1 }; let infos; const result = []; const affectedLayers = /* @__PURE__ */ new Set(); for (let i = 0; i < depth; i++) { let pickInfo; if (deviceRect) { const pickedResult = this._drawAndSample({ layers: pickableLayers, views, viewports, onViewportActive, deviceRect, cullRect, effects, pass: `picking:${mode}` }); pickInfo = getClosestObject({ ...pickedResult, deviceX: devicePixel[0], deviceY: devicePixel[1], deviceRadius, deviceRect }); } else { pickInfo = { pickedColor: null, pickedObjectIndex: -1 }; } let z; if (pickInfo.pickedLayer && unproject3D && this.depthFBO) { const { pickedColors: pickedColors2 } = this._drawAndSample( { layers: [pickInfo.pickedLayer], views, viewports, onViewportActive, deviceRect: { x: pickInfo.pickedX, y: pickInfo.pickedY, width: 1, height: 1 }, cullRect, effects, pass: `picking:${mode}:z` }, true ); if (pickedColors2[3]) { z = pickedColors2[0]; } } if (pickInfo.pickedLayer && i + 1 < depth) { affectedLayers.add(pickInfo.pickedLayer); pickInfo.pickedLayer.disablePickingIndex(pickInfo.pickedObjectIndex); } infos = processPickInfo({ pickInfo, lastPickedInfo: this.lastPickedInfo, mode, layers: pickableLayers, viewports, x, y, z, pixelRatio }); for (const info of infos.values()) { if (info.layer) { result.push(info); } } if (!pickInfo.pickedColor) { break; } } for (const layer of affectedLayers) { layer.restorePickingColors(); } return { result, emptyInfo: infos.get(null) }; } _pickVisibleObjects({ layers, views, viewports, x, y, width = 1, height = 1, mode = "query", maxObjects = null, onViewportActive, effects }) { const pickableLayers = this._getPickable(layers); if (!pickableLayers || viewports.length === 0) { return []; } this._resizeBuffer(); const pixelRatio = this.device.canvasContext.cssToDeviceRatio(); const leftTop = this.device.canvasContext.cssToDevicePixels([x, y], true); const deviceLeft = leftTop.x; const deviceTop = leftTop.y + leftTop.height; const rightBottom = this.device.canvasContext.cssToDevicePixels([x + width, y + height], true); const deviceRight = rightBottom.x + rightBottom.width; const deviceBottom = rightBottom.y; const deviceRect = { x: deviceLeft, y: deviceBottom, width: deviceRight - deviceLeft, height: deviceTop - deviceBottom }; const pickedResult = this._drawAndSample({ layers: pickableLayers, views, viewports, onViewportActive, deviceRect, cullRect: { x, y, width, height }, effects, pass: `picking:${mode}` }); const pickInfos = getUniqueObjects(pickedResult); const uniquePickedObjects = /* @__PURE__ */ new Map(); const uniqueInfos = []; const limitMaxObjects = Number.isFinite(maxObjects); for (let i = 0; i < pickInfos.length; i++) { if (limitMaxObjects && uniqueInfos.length >= maxObjects) { break; } const pickInfo = pickInfos[i]; let info = { color: pickInfo.pickedColor, layer: null, index: pickInfo.pickedObjectIndex, picked: true, x, y, pixelRatio }; info = getLayerPickingInfo({ layer: pickInfo.pickedLayer, info, mode }); const pickedLayerId = info.layer.id; if (!uniquePickedObjects.has(pickedLayerId)) { uniquePickedObjects.set(pickedLayerId, /* @__PURE__ */ new Set()); } const uniqueObjectsInLayer = uniquePickedObjects.get(pickedLayerId); const pickedObjectKey = info.object ?? info.index; if (!uniqueObjectsInLayer.has(pickedObjectKey)) { uniqueObjectsInLayer.add(pickedObjectKey); uniqueInfos.push(info); } } return uniqueInfos; } _drawAndSample({ layers, views, viewports, onViewportActive, deviceRect, cullRect, effects, pass }, pickZ = false) { const pickingFBO = pickZ ? this.depthFBO : this.pickingFBO; const opts = { layers, layerFilter: this.layerFilter, views, viewports, onViewportActive, pickingFBO, deviceRect, cullRect, effects, pass, pickZ, preRenderStats: {} }; for (const effect of effects) { if (effect.useInPicking) { opts.preRenderStats[effect.id] = effect.preRender(opts); } } const { decodePickingColor } = this.pickLayersPass.render(opts); const { x, y, width, height } = deviceRect; const pickedColors = new (pickZ ? Float32Array : Uint8Array)(width * height * 4); this.device.readPixelsToArrayWebGL(pickingFBO, { sourceX: x, sourceY: y, sourceWidth: width, sourceHeight: height, target: pickedColors }); return { pickedColors, decodePickingColor }; } _getPickingRect({ deviceX, deviceY, deviceRadius, deviceWidth, deviceHeight }) { const x = Math.max(0, deviceX - deviceRadius); const y = Math.max(0, deviceY - deviceRadius); const width = Math.min(deviceWidth, deviceX + deviceRadius + 1) - x; const height = Math.min(deviceHeight, deviceY + deviceRadius + 1) - y; if (width <= 0 || height <= 0) { return null; } return { x, y, width, height }; } }; // src/lib/widget-manager.ts var PLACEMENTS = { "top-left": { top: 0, left: 0 }, "top-right": { top: 0, right: 0 }, "bottom-left": { bottom: 0, left: 0 }, "bottom-right": { bottom: 0, right: 0 }, fill: { top: 0, left: 0, bottom: 0, right: 0 } }; var DEFAULT_PLACEMENT = "top-left"; var ROOT_CONTAINER_ID = "__root"; var WidgetManager = class { constructor({ deck, parentElement }) { this.defaultWidgets = []; this.widgets = []; this.resolvedWidgets = []; this.containers = {}; this.lastViewports = {}; this.deck = deck; this.parentElement = parentElement; } getWidgets() { return this.resolvedWidgets; } setProps(props) { if (props.widgets && !deepEqual2(props.widgets, this.widgets, 1)) { this._setWidgets(props.widgets); } } finalize() { for (const widget of this.getWidgets()) { this._remove(widget); } this.defaultWidgets.length = 0; this.resolvedWidgets.length = 0; for (const id in this.containers) { this.containers[id].remove(); } } addDefault(widget) { if (!this.defaultWidgets.find((w) => w.id === widget.id)) { this._add(widget); this.defaultWidgets.push(widget); this._setWidgets(this.widgets); } } _setWidgets(nextWidgets) { const oldWidgetMap = {}; for (const widget of this.resolvedWidgets) { oldWidgetMap[widget.id] = widget; } this.resolvedWidgets.length = 0; for (const widget of this.defaultWidgets) { oldWidgetMap[widget.id] = null; this.resolvedWidgets.push(widget); } for (let widget of nextWidgets) { const oldWidget = oldWidgetMap[widget.id]; if (!oldWidget) { this._add(widget); } else if (oldWidget.viewId !== widget.viewId || oldWidget.placement !== widget.placement) { this._remove(oldWidget); this._add(widget); } else if (widget !== oldWidget) { oldWidget.setProps(widget.props); widget = oldWidget; } oldWidgetMap[widget.id] = null; this.resolvedWidgets.push(widget); } for (const id in oldWidgetMap) { const oldWidget = oldWidgetMap[id]; if (oldWidget) { this._remove(oldWidget); } } this.widgets = nextWidgets; } _add(widget) { const { viewId = null, placement = DEFAULT_PLACEMENT } = widget; const element = widget.onAdd({ deck: this.deck, viewId }); if (element) { this._getContainer(viewId, placement).append(element); } widget._element = element; } _remove(widget) { widget.onRemove(); if (widget._element) { widget._element.remove(); } widget._element = void 0; } _getContainer(viewId, placement) { const containerId = viewId || ROOT_CONTAINER_ID; let viewContainer = this.containers[containerId]; if (!viewContainer) { viewContainer = document.createElement("div"); viewContainer.style.pointerEvents = "none"; viewContainer.style.position = "absolute"; viewContainer.style.overflow = "hidden"; this.parentElement?.append(viewContainer); this.containers[containerId] = viewContainer; } let container = viewContainer.querySelector(`.${placement}`); if (!container) { container = document.createElement("div"); container.className = placement; container.style.position = "absolute"; container.style.zIndex = "2"; Object.assign(container.style, PLACEMENTS[placement]); viewContainer.append(container); } return container; } _updateContainers() { const canvasWidth = this.deck.width; const canvasHeight = this.deck.height; for (const id in this.containers) { const viewport = this.lastViewports[id] || null; const visible = id === ROOT_CONTAINER_ID || viewport; const container = this.containers[id]; if (visible) { container.style.display = "block"; container.style.left = `${viewport ? viewport.x : 0}px`; container.style.top = `${viewport ? viewport.y : 0}px`; container.style.width = `${viewport ? viewport.width : canvasWidth}px`; container.style.height = `${viewport ? viewport.height : canvasHeight}px`; } else { container.style.display = "none"; } } } onRedraw({ viewports, layers }) { const viewportsById = viewports.reduce((acc, v) => { acc[v.id] = v; return acc; }, {}); const { lastViewports } = this; for (const widget of this.getWidgets()) { const { viewId } = widget; if (viewId) { const viewport = viewportsById[viewId]; if (viewport) { if (widget.onViewportChange && !viewport.equals(lastViewports[viewId])) { widget.onViewportChange(viewport); } widget.onRedraw?.({ viewports: [viewport], layers }); } } else { if (widget.onViewportChange) { for (const viewport of viewports) { if (!viewport.equals(lastViewports[viewport.id])) { widget.onViewportChange(viewport); } } } widget.onRedraw?.({ viewports, layers }); } } this.lastViewports = viewportsById; this._updateContainers(); } onHover(info, event) { for (const widget of this.getWidgets()) { const { viewId } = widget; if (!viewId || viewId === info.viewport?.id) { widget.onHover?.(info, event); } } } onEvent(info, event) { const eventOptions = EVENTS[event.type]; if (!eventOptions) { return; } for (const widget of this.getWidgets()) { const { viewId } = widget; if (!viewId || viewId === info.viewport?.id) { widget[eventOptions.handler]?.(info, event); } } } }; // src/lib/tooltip.ts var defaultStyle = { zIndex: "1", position: "absolute", pointerEvents: "none", color: "#a0a7b4", backgroundColor: "#29323c", padding: "10px", top: "0", left: "0", display: "none" }; var Tooltip = class { constructor() { this.id = "default-tooltip"; this.placement = "fill"; this.props = {}; this.isVisible = false; } onAdd({ deck }) { const el = document.createElement("div"); el.className = "deck-tooltip"; Object.assign(el.style, defaultStyle); this.deck = deck; this.element = el; return el; } onRemove() { this.deck = void 0; this.element = void 0; } setProps() { } onViewportChange(viewport) { if (this.isVisible && viewport.id === this.lastViewport?.id && viewport !== this.lastViewport) { this.setTooltip(null); } } onHover(info) { const { deck } = this; const getTooltip = deck && deck.props.getTooltip; if (!getTooltip) { return; } const displayInfo = getTooltip(info); this.lastViewport = info.viewport; this.setTooltip(displayInfo, info.x, info.y); } setTooltip(displayInfo, x, y) { const el = this.element; if (!el) { return; } if (typeof displayInfo === "string") { el.innerText = displayInfo; } else if (!displayInfo) { this.isVisible = false; el.style.display = "none"; return; } else { if (displayInfo.text) { el.innerText = displayInfo.text; } if (displayInfo.html) { el.innerHTML = displayInfo.html; } if (displayInfo.className) { el.className = displayInfo.className; } } this.isVisible = true; el.style.display = "block"; el.style.transform = `translate(${x}px, ${y}px)`; if (displayInfo && typeof displayInfo === "object" && "style" in displayInfo) { Object.assign(el.style, displayInfo.style); } } }; // ../../node_modules/@luma.gl/constants/dist/webgl-constants.js var GLEnum; (function(GLEnum2) { GLEnum2[GLEnum2["DEPTH_BUFFER_BIT"] = 256] = "DEPTH_BUFFER_BIT"; GLEnum2[GLEnum2["STENCIL_BUFFER_BIT"] = 1024] = "STENCIL_BUFFER_BIT"; GLEnum2[GLEnum2["COLOR_BUFFER_BIT"] = 16384] = "COLOR_BUFFER_BIT"; GLEnum2[GLEnum2["POINTS"] = 0] = "POINTS"; GLEnum2[GLEnum2["LINES"] = 1] = "LINES"; GLEnum2[GLEnum2["LINE_LOOP"] = 2] = "LINE_LOOP"; GLEnum2[GLEnum2["LINE_STRIP"] = 3] = "LINE_STRIP"; GLEnum2[GLEnum2["TRIANGLES"] = 4] = "TRIANGLES"; GLEnum2[GLEnum2["TRIANGLE_STRIP"] = 5] = "TRIANGLE_STRIP"; GLEnum2[GLEnum2["TRIANGLE_FAN"] = 6] = "TRIANGLE_FAN"; GLEnum2[GLEnum2["ZERO"] = 0] = "ZERO"; GLEnum2[GLEnum2["ONE"] = 1] = "ONE"; GLEnum2[GLEnum2["SRC_COLOR"] = 768] = "SRC_COLOR"; GLEnum2[GLEnum2["ONE_MINUS_SRC_COLOR"] = 769] = "ONE_MINUS_SRC_COLOR"; GLEnum2[GLEnum2["SRC_ALPHA"] = 770] = "SRC_ALPHA"; GLEnum2[GLEnum2["ONE_MINUS_SRC_ALPHA"] = 771] = "ONE_MINUS_SRC_ALPHA"; GLEnum2[GLEnum2["DST_ALPHA"] = 772] = "DST_ALPHA"; GLEnum2[GLEnum2["ONE_MINUS_DST_ALPHA"] = 773] = "ONE_MINUS_DST_ALPHA"; GLEnum2[GLEnum2["DST_COLOR"] = 774] = "DST_COLOR"; GLEnum2[GLEnum2["ONE_MINUS_DST_COLOR"] = 775] = "ONE_MINUS_DST_COLOR"; GLEnum2[GLEnum2["SRC_ALPHA_SATURATE"] = 776] = "SRC_ALPHA_SATURATE"; GLEnum2[GLEnum2["CONSTANT_COLOR"] = 32769] = "CONSTANT_COLOR"; GLEnum2[GLEnum2["ONE_MINUS_CONSTANT_COLOR"] = 32770] = "ONE_MINUS_CONSTANT_COLOR"; GLEnum2[GLEnum2["CONSTANT_ALPHA"] = 32771] = "CONSTANT_ALPHA"; GLEnum2[GLEnum2["ONE_MINUS_CONSTANT_ALPHA"] = 32772] = "ONE_MINUS_CONSTANT_ALPHA"; GLEnum2[GLEnum2["FUNC_ADD"] = 32774] = "FUNC_ADD"; GLEnum2[GLEnum2["FUNC_SUBTRACT"] = 32778] = "FUNC_SUBTRACT"; GLEnum2[GLEnum2["FUNC_REVERSE_SUBTRACT"] = 32779] = "FUNC_REVERSE_SUBTRACT"; GLEnum2[GLEnum2["BLEND_EQUATION"] = 32777] = "BLEND_EQUATION"; GLEnum2[GLEnum2["BLEND_EQUATION_RGB"] = 32777] = "BLEND_EQUATION_RGB"; GLEnum2[GLEnum2["BLEND_EQUATION_ALPHA"] = 34877] = "BLEND_EQUATION_ALPHA"; GLEnum2[GLEnum2["BLEND_DST_RGB"] = 32968] = "BLEND_DST_RGB"; GLEnum2[GLEnum2["BLEND_SRC_RGB"] = 32969] = "BLEND_SRC_RGB"; GLEnum2[GLEnum2["BLEND_DST_ALPHA"] = 32970] = "BLEND_DST_ALPHA"; GLEnum2[GLEnum2["BLEND_SRC_ALPHA"] = 32971] = "BLEND_SRC_ALPHA"; GLEnum2[GLEnum2["BLEND_COLOR"] = 32773] = "BLEND_COLOR"; GLEnum2[GLEnum2["ARRAY_BUFFER_BINDING"] = 34964] = "ARRAY_BUFFER_BINDING"; GLEnum2[GLEnum2["ELEMENT_ARRAY_BUFFER_BINDING"] = 34965] = "ELEMENT_ARRAY_BUFFER_BINDING"; GLEnum2[GLEnum2["LINE_WIDTH"] = 2849] = "LINE_WIDTH"; GLEnum2[GLEnum2["ALIASED_POINT_SIZE_RANGE"] = 33901] = "ALIASED_POINT_SIZE_RANGE"; GLEnum2[GLEnum2["ALIASED_LINE_WIDTH_RANGE"] = 33902] = "ALIASED_LINE_WIDTH_RANGE"; GLEnum2[GLEnum2["CULL_FACE_MODE"] = 2885] = "CULL_FACE_MODE"; GLEnum2[GLEnum2["FRONT_FACE"] = 2886] = "FRONT_FACE"; GLEnum2[GLEnum2["DEPTH_RANGE"] = 2928] = "DEPTH_RANGE"; GLEnum2[GLEnum2["DEPTH_WRITEMASK"] = 2930] = "DEPTH_WRITEMASK"; GLEnum2[GLEnum2["DEPTH_CLEAR_VALUE"] = 2931] = "DEPTH_CLEAR_VALUE"; GLEnum2[GLEnum2["DEPTH_FUNC"] = 2932] = "DEPTH_FUNC"; GLEnum2[GLEnum2["STENCIL_CLEAR_VALUE"] = 2961] = "STENCIL_CLEAR_VALUE"; GLEnum2[GLEnum2["STENCIL_FUNC"] = 2962] = "STENCIL_FUNC"; GLEnum2[GLEnum2["STENCIL_FAIL"] = 2964] = "STENCIL_FAIL"; GLEnum2[GLEnum2["STENCIL_PASS_DEPTH_FAIL"] = 2965] = "STENCIL_PASS_DEPTH_FAIL"; GLEnum2[GLEnum2["STENCIL_PASS_DEPTH_PASS"] = 2966] = "STENCIL_PASS_DEPTH_PASS"; GLEnum2[GLEnum2["STENCIL_REF"] = 2967] = "STENCIL_REF"; GLEnum2[GLEnum2["STENCIL_VALUE_MASK"] = 2963] = "STENCIL_VALUE_MASK"; GLEnum2[GLEnum2["STENCIL_WRITEMASK"] = 2968] = "STENCIL_WRITEMASK"; GLEnum2[GLEnum2["STENCIL_BACK_FUNC"] = 34816] = "STENCIL_BACK_FUNC"; GLEnum2[GLEnum2["STENCIL_BACK_FAIL"] = 34817] = "STENCIL_BACK_FAIL"; GLEnum2[GLEnum2["STENCIL_BACK_PASS_DEPTH_FAIL"] = 34818] = "STENCIL_BACK_PASS_DEPTH_FAIL"; GLEnum2[GLEnum2["STENCIL_BACK_PASS_DEPTH_PASS"] = 34819] = "STENCIL_BACK_PASS_DEPTH_PASS"; GLEnum2[GLEnum2["STENCIL_BACK_REF"] = 36003] = "STENCIL_BACK_REF"; GLEnum2[GLEnum2["STENCIL_BACK_VALUE_MASK"] = 36004] = "STENCIL_BACK_VALUE_MASK"; GLEnum2[GLEnum2["STENCIL_BACK_WRITEMASK"] = 36005] = "STENCIL_BACK_WRITEMASK"; GLEnum2[GLEnum2["VIEWPORT"] = 2978] = "VIEWPORT"; GLEnum2[GLEnum2["SCISSOR_BOX"] = 3088] = "SCISSOR_BOX"; GLEnum2[GLEnum2["COLOR_CLEAR_VALUE"] = 3106] = "COLOR_CLEAR_VALUE"; GLEnum2[GLEnum2["COLOR_WRITEMASK"] = 3107] = "COLOR_WRITEMASK"; GLEnum2[GLEnum2["UNPACK_ALIGNMENT"] = 3317] = "UNPACK_ALIGNMENT"; GLEnum2[GLEnum2["PACK_ALIGNMENT"] = 3333] = "PACK_ALIGNMENT"; GLEnum2[GLEnum2["MAX_TEXTURE_SIZE"] = 3379] = "MAX_TEXTURE_SIZE"; GLEnum2[GLEnum2["MAX_VIEWPORT_DIMS"] = 3386] = "MAX_VIEWPORT_DIMS"; GLEnum2[GLEnum2["SUBPIXEL_BITS"] = 3408] = "SUBPIXEL_BITS"; GLEnum2[GLEnum2["RED_BITS"] = 3410] = "RED_BITS"; GLEnum2[GLEnum2["GREEN_BITS"] = 3411] = "GREEN_BITS"; GLEnum2[GLEnum2["BLUE_BITS"] = 3412] = "BLUE_BITS"; GLEnum2[GLEnum2["ALPHA_BITS"] = 3413] = "ALPHA_BITS"; GLEnum2[GLEnum2["DEPTH_BITS"] = 3414] = "DEPTH_BITS"; GLEnum2[GLEnum2["STENCIL_BITS"] = 3415] = "STENCIL_BITS"; GLEnum2[GLEnum2["POLYGON_OFFSET_UNITS"] = 10752] = "POLYGON_OFFSET_UNITS"; GLEnum2[GLEnum2["POLYGON_OFFSET_FACTOR"] = 32824] = "POLYGON_OFFSET_FACTOR"; GLEnum2[GLEnum2["TEXTURE_BINDING_2D"] = 32873] = "TEXTURE_BINDING_2D"; GLEnum2[GLEnum2["SAMPLE_BUFFERS"] = 32936] = "SAMPLE_BUFFERS"; GLEnum2[GLEnum2["SAMPLES"] = 32937] = "SAMPLES"; GLEnum2[GLEnum2["SAMPLE_COVERAGE_VALUE"] = 32938] = "SAMPLE_COVERAGE_VALUE"; GLEnum2[GLEnum2["SAMPLE_COVERAGE_INVERT"] = 32939] = "SAMPLE_COVERAGE_INVERT"; GLEnum2[GLEnum2["COMPRESSED_TEXTURE_FORMATS"] = 34467] = "COMPRESSED_TEXTURE_FORMATS"; GLEnum2[GLEnum2["VENDOR"] = 7936] = "VENDOR"; GLEnum2[GLEnum2["RENDERER"] = 7937] = "RENDERER"; GLEnum2[GLEnum2["VERSION"] = 7938] = "VERSION"; GLEnum2[GLEnum2["IMPLEMENTATION_COLOR_READ_TYPE"] = 35738] = "IMPLEMENTATION_COLOR_READ_TYPE"; GLEnum2[GLEnum2["IMPLEMENTATION_COLOR_READ_FORMAT"] = 35739] = "IMPLEMENTATION_COLOR_READ_FORMAT"; GLEnum2[GLEnum2["BROWSER_DEFAULT_WEBGL"] = 37444] = "BROWSER_DEFAULT_WEBGL"; GLEnum2[GLEnum2["STATIC_DRAW"] = 35044] = "STATIC_DRAW"; GLEnum2[GLEnum2["STREAM_DRAW"] = 35040] = "STREAM_DRAW"; GLEnum2[GLEnum2["DYNAMIC_DRAW"] = 35048] = "DYNAMIC_DRAW"; GLEnum2[GLEnum2["ARRAY_BUFFER"] = 34962] = "ARRAY_BUFFER"; GLEnum2[GLEnum2["ELEMENT_ARRAY_BUFFER"] = 34963] = "ELEMENT_ARRAY_BUFFER"; GLEnum2[GLEnum2["BUFFER_SIZE"] = 34660] = "BUFFER_SIZE"; GLEnum2[GLEnum2["BUFFER_USAGE"] = 34661] = "BUFFER_USAGE"; GLEnum2[GLEnum2["CURRENT_VERTEX_ATTRIB"] = 34342] = "CURRENT_VERTEX_ATTRIB"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_ENABLED"] = 34338] = "VERTEX_ATTRIB_ARRAY_ENABLED"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_SIZE"] = 34339] = "VERTEX_ATTRIB_ARRAY_SIZE"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_STRIDE"] = 34340] = "VERTEX_ATTRIB_ARRAY_STRIDE"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_TYPE"] = 34341] = "VERTEX_ATTRIB_ARRAY_TYPE"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_NORMALIZED"] = 34922] = "VERTEX_ATTRIB_ARRAY_NORMALIZED"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_POINTER"] = 34373] = "VERTEX_ATTRIB_ARRAY_POINTER"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"] = 34975] = "VERTEX_ATTRIB_ARRAY_BUFFER_BINDING"; GLEnum2[GLEnum2["CULL_FACE"] = 2884] = "CULL_FACE"; GLEnum2[GLEnum2["FRONT"] = 1028] = "FRONT"; GLEnum2[GLEnum2["BACK"] = 1029] = "BACK"; GLEnum2[GLEnum2["FRONT_AND_BACK"] = 1032] = "FRONT_AND_BACK"; GLEnum2[GLEnum2["BLEND"] = 3042] = "BLEND"; GLEnum2[GLEnum2["DEPTH_TEST"] = 2929] = "DEPTH_TEST"; GLEnum2[GLEnum2["DITHER"] = 3024] = "DITHER"; GLEnum2[GLEnum2["POLYGON_OFFSET_FILL"] = 32823] = "POLYGON_OFFSET_FILL"; GLEnum2[GLEnum2["SAMPLE_ALPHA_TO_COVERAGE"] = 32926] = "SAMPLE_ALPHA_TO_COVERAGE"; GLEnum2[GLEnum2["SAMPLE_COVERAGE"] = 32928] = "SAMPLE_COVERAGE"; GLEnum2[GLEnum2["SCISSOR_TEST"] = 3089] = "SCISSOR_TEST"; GLEnum2[GLEnum2["STENCIL_TEST"] = 2960] = "STENCIL_TEST"; GLEnum2[GLEnum2["NO_ERROR"] = 0] = "NO_ERROR"; GLEnum2[GLEnum2["INVALID_ENUM"] = 1280] = "INVALID_ENUM"; GLEnum2[GLEnum2["INVALID_VALUE"] = 1281] = "INVALID_VALUE"; GLEnum2[GLEnum2["INVALID_OPERATION"] = 1282] = "INVALID_OPERATION"; GLEnum2[GLEnum2["OUT_OF_MEMORY"] = 1285] = "OUT_OF_MEMORY"; GLEnum2[GLEnum2["CONTEXT_LOST_WEBGL"] = 37442] = "CONTEXT_LOST_WEBGL"; GLEnum2[GLEnum2["CW"] = 2304] = "CW"; GLEnum2[GLEnum2["CCW"] = 2305] = "CCW"; GLEnum2[GLEnum2["DONT_CARE"] = 4352] = "DONT_CARE"; GLEnum2[GLEnum2["FASTEST"] = 4353] = "FASTEST"; GLEnum2[GLEnum2["NICEST"] = 4354] = "NICEST"; GLEnum2[GLEnum2["GENERATE_MIPMAP_HINT"] = 33170] = "GENERATE_MIPMAP_HINT"; GLEnum2[GLEnum2["BYTE"] = 5120] = "BYTE"; GLEnum2[GLEnum2["UNSIGNED_BYTE"] = 5121] = "UNSIGNED_BYTE"; GLEnum2[GLEnum2["SHORT"] = 5122] = "SHORT"; GLEnum2[GLEnum2["UNSIGNED_SHORT"] = 5123] = "UNSIGNED_SHORT"; GLEnum2[GLEnum2["INT"] = 5124] = "INT"; GLEnum2[GLEnum2["UNSIGNED_INT"] = 5125] = "UNSIGNED_INT"; GLEnum2[GLEnum2["FLOAT"] = 5126] = "FLOAT"; GLEnum2[GLEnum2["DOUBLE"] = 5130] = "DOUBLE"; GLEnum2[GLEnum2["DEPTH_COMPONENT"] = 6402] = "DEPTH_COMPONENT"; GLEnum2[GLEnum2["ALPHA"] = 6406] = "ALPHA"; GLEnum2[GLEnum2["RGB"] = 6407] = "RGB"; GLEnum2[GLEnum2["RGBA"] = 6408] = "RGBA"; GLEnum2[GLEnum2["LUMINANCE"] = 6409] = "LUMINANCE"; GLEnum2[GLEnum2["LUMINANCE_ALPHA"] = 6410] = "LUMINANCE_ALPHA"; GLEnum2[GLEnum2["UNSIGNED_SHORT_4_4_4_4"] = 32819] = "UNSIGNED_SHORT_4_4_4_4"; GLEnum2[GLEnum2["UNSIGNED_SHORT_5_5_5_1"] = 32820] = "UNSIGNED_SHORT_5_5_5_1"; GLEnum2[GLEnum2["UNSIGNED_SHORT_5_6_5"] = 33635] = "UNSIGNED_SHORT_5_6_5"; GLEnum2[GLEnum2["FRAGMENT_SHADER"] = 35632] = "FRAGMENT_SHADER"; GLEnum2[GLEnum2["VERTEX_SHADER"] = 35633] = "VERTEX_SHADER"; GLEnum2[GLEnum2["COMPILE_STATUS"] = 35713] = "COMPILE_STATUS"; GLEnum2[GLEnum2["DELETE_STATUS"] = 35712] = "DELETE_STATUS"; GLEnum2[GLEnum2["LINK_STATUS"] = 35714] = "LINK_STATUS"; GLEnum2[GLEnum2["VALIDATE_STATUS"] = 35715] = "VALIDATE_STATUS"; GLEnum2[GLEnum2["ATTACHED_SHADERS"] = 35717] = "ATTACHED_SHADERS"; GLEnum2[GLEnum2["ACTIVE_ATTRIBUTES"] = 35721] = "ACTIVE_ATTRIBUTES"; GLEnum2[GLEnum2["ACTIVE_UNIFORMS"] = 35718] = "ACTIVE_UNIFORMS"; GLEnum2[GLEnum2["MAX_VERTEX_ATTRIBS"] = 34921] = "MAX_VERTEX_ATTRIBS"; GLEnum2[GLEnum2["MAX_VERTEX_UNIFORM_VECTORS"] = 36347] = "MAX_VERTEX_UNIFORM_VECTORS"; GLEnum2[GLEnum2["MAX_VARYING_VECTORS"] = 36348] = "MAX_VARYING_VECTORS"; GLEnum2[GLEnum2["MAX_COMBINED_TEXTURE_IMAGE_UNITS"] = 35661] = "MAX_COMBINED_TEXTURE_IMAGE_UNITS"; GLEnum2[GLEnum2["MAX_VERTEX_TEXTURE_IMAGE_UNITS"] = 35660] = "MAX_VERTEX_TEXTURE_IMAGE_UNITS"; GLEnum2[GLEnum2["MAX_TEXTURE_IMAGE_UNITS"] = 34930] = "MAX_TEXTURE_IMAGE_UNITS"; GLEnum2[GLEnum2["MAX_FRAGMENT_UNIFORM_VECTORS"] = 36349] = "MAX_FRAGMENT_UNIFORM_VECTORS"; GLEnum2[GLEnum2["SHADER_TYPE"] = 35663] = "SHADER_TYPE"; GLEnum2[GLEnum2["SHADING_LANGUAGE_VERSION"] = 35724] = "SHADING_LANGUAGE_VERSION"; GLEnum2[GLEnum2["CURRENT_PROGRAM"] = 35725] = "CURRENT_PROGRAM"; GLEnum2[GLEnum2["NEVER"] = 512] = "NEVER"; GLEnum2[GLEnum2["LESS"] = 513] = "LESS"; GLEnum2[GLEnum2["EQUAL"] = 514] = "EQUAL"; GLEnum2[GLEnum2["LEQUAL"] = 515] = "LEQUAL"; GLEnum2[GLEnum2["GREATER"] = 516] = "GREATER"; GLEnum2[GLEnum2["NOTEQUAL"] = 517] = "NOTEQUAL"; GLEnum2[GLEnum2["GEQUAL"] = 518] = "GEQUAL"; GLEnum2[GLEnum2["ALWAYS"] = 519] = "ALWAYS"; GLEnum2[GLEnum2["KEEP"] = 7680] = "KEEP"; GLEnum2[GLEnum2["REPLACE"] = 7681] = "REPLACE"; GLEnum2[GLEnum2["INCR"] = 7682] = "INCR"; GLEnum2[GLEnum2["DECR"] = 7683] = "DECR"; GLEnum2[GLEnum2["INVERT"] = 5386] = "INVERT"; GLEnum2[GLEnum2["INCR_WRAP"] = 34055] = "INCR_WRAP"; GLEnum2[GLEnum2["DECR_WRAP"] = 34056] = "DECR_WRAP"; GLEnum2[GLEnum2["NEAREST"] = 9728] = "NEAREST"; GLEnum2[GLEnum2["LINEAR"] = 9729] = "LINEAR"; GLEnum2[GLEnum2["NEAREST_MIPMAP_NEAREST"] = 9984] = "NEAREST_MIPMAP_NEAREST"; GLEnum2[GLEnum2["LINEAR_MIPMAP_NEAREST"] = 9985] = "LINEAR_MIPMAP_NEAREST"; GLEnum2[GLEnum2["NEAREST_MIPMAP_LINEAR"] = 9986] = "NEAREST_MIPMAP_LINEAR"; GLEnum2[GLEnum2["LINEAR_MIPMAP_LINEAR"] = 9987] = "LINEAR_MIPMAP_LINEAR"; GLEnum2[GLEnum2["TEXTURE_MAG_FILTER"] = 10240] = "TEXTURE_MAG_FILTER"; GLEnum2[GLEnum2["TEXTURE_MIN_FILTER"] = 10241] = "TEXTURE_MIN_FILTER"; GLEnum2[GLEnum2["TEXTURE_WRAP_S"] = 10242] = "TEXTURE_WRAP_S"; GLEnum2[GLEnum2["TEXTURE_WRAP_T"] = 10243] = "TEXTURE_WRAP_T"; GLEnum2[GLEnum2["TEXTURE_2D"] = 3553] = "TEXTURE_2D"; GLEnum2[GLEnum2["TEXTURE"] = 5890] = "TEXTURE"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP"] = 34067] = "TEXTURE_CUBE_MAP"; GLEnum2[GLEnum2["TEXTURE_BINDING_CUBE_MAP"] = 34068] = "TEXTURE_BINDING_CUBE_MAP"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP_POSITIVE_X"] = 34069] = "TEXTURE_CUBE_MAP_POSITIVE_X"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP_NEGATIVE_X"] = 34070] = "TEXTURE_CUBE_MAP_NEGATIVE_X"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP_POSITIVE_Y"] = 34071] = "TEXTURE_CUBE_MAP_POSITIVE_Y"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP_NEGATIVE_Y"] = 34072] = "TEXTURE_CUBE_MAP_NEGATIVE_Y"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP_POSITIVE_Z"] = 34073] = "TEXTURE_CUBE_MAP_POSITIVE_Z"; GLEnum2[GLEnum2["TEXTURE_CUBE_MAP_NEGATIVE_Z"] = 34074] = "TEXTURE_CUBE_MAP_NEGATIVE_Z"; GLEnum2[GLEnum2["MAX_CUBE_MAP_TEXTURE_SIZE"] = 34076] = "MAX_CUBE_MAP_TEXTURE_SIZE"; GLEnum2[GLEnum2["TEXTURE0"] = 33984] = "TEXTURE0"; GLEnum2[GLEnum2["ACTIVE_TEXTURE"] = 34016] = "ACTIVE_TEXTURE"; GLEnum2[GLEnum2["REPEAT"] = 10497] = "REPEAT"; GLEnum2[GLEnum2["CLAMP_TO_EDGE"] = 33071] = "CLAMP_TO_EDGE"; GLEnum2[GLEnum2["MIRRORED_REPEAT"] = 33648] = "MIRRORED_REPEAT"; GLEnum2[GLEnum2["TEXTURE_WIDTH"] = 4096] = "TEXTURE_WIDTH"; GLEnum2[GLEnum2["TEXTURE_HEIGHT"] = 4097] = "TEXTURE_HEIGHT"; GLEnum2[GLEnum2["FLOAT_VEC2"] = 35664] = "FLOAT_VEC2"; GLEnum2[GLEnum2["FLOAT_VEC3"] = 35665] = "FLOAT_VEC3"; GLEnum2[GLEnum2["FLOAT_VEC4"] = 35666] = "FLOAT_VEC4"; GLEnum2[GLEnum2["INT_VEC2"] = 35667] = "INT_VEC2"; GLEnum2[GLEnum2["INT_VEC3"] = 35668] = "INT_VEC3"; GLEnum2[GLEnum2["INT_VEC4"] = 35669] = "INT_VEC4"; GLEnum2[GLEnum2["BOOL"] = 35670] = "BOOL"; GLEnum2[GLEnum2["BOOL_VEC2"] = 35671] = "BOOL_VEC2"; GLEnum2[GLEnum2["BOOL_VEC3"] = 35672] = "BOOL_VEC3"; GLEnum2[GLEnum2["BOOL_VEC4"] = 35673] = "BOOL_VEC4"; GLEnum2[GLEnum2["FLOAT_MAT2"] = 35674] = "FLOAT_MAT2"; GLEnum2[GLEnum2["FLOAT_MAT3"] = 35675] = "FLOAT_MAT3"; GLEnum2[GLEnum2["FLOAT_MAT4"] = 35676] = "FLOAT_MAT4"; GLEnum2[GLEnum2["SAMPLER_2D"] = 35678] = "SAMPLER_2D"; GLEnum2[GLEnum2["SAMPLER_CUBE"] = 35680] = "SAMPLER_CUBE"; GLEnum2[GLEnum2["LOW_FLOAT"] = 36336] = "LOW_FLOAT"; GLEnum2[GLEnum2["MEDIUM_FLOAT"] = 36337] = "MEDIUM_FLOAT"; GLEnum2[GLEnum2["HIGH_FLOAT"] = 36338] = "HIGH_FLOAT"; GLEnum2[GLEnum2["LOW_INT"] = 36339] = "LOW_INT"; GLEnum2[GLEnum2["MEDIUM_INT"] = 36340] = "MEDIUM_INT"; GLEnum2[GLEnum2["HIGH_INT"] = 36341] = "HIGH_INT"; GLEnum2[GLEnum2["FRAMEBUFFER"] = 36160] = "FRAMEBUFFER"; GLEnum2[GLEnum2["RENDERBUFFER"] = 36161] = "RENDERBUFFER"; GLEnum2[GLEnum2["RGBA4"] = 32854] = "RGBA4"; GLEnum2[GLEnum2["RGB5_A1"] = 32855] = "RGB5_A1"; GLEnum2[GLEnum2["RGB565"] = 36194] = "RGB565"; GLEnum2[GLEnum2["DEPTH_COMPONENT16"] = 33189] = "DEPTH_COMPONENT16"; GLEnum2[GLEnum2["STENCIL_INDEX"] = 6401] = "STENCIL_INDEX"; GLEnum2[GLEnum2["STENCIL_INDEX8"] = 36168] = "STENCIL_INDEX8"; GLEnum2[GLEnum2["DEPTH_STENCIL"] = 34041] = "DEPTH_STENCIL"; GLEnum2[GLEnum2["RENDERBUFFER_WIDTH"] = 36162] = "RENDERBUFFER_WIDTH"; GLEnum2[GLEnum2["RENDERBUFFER_HEIGHT"] = 36163] = "RENDERBUFFER_HEIGHT"; GLEnum2[GLEnum2["RENDERBUFFER_INTERNAL_FORMAT"] = 36164] = "RENDERBUFFER_INTERNAL_FORMAT"; GLEnum2[GLEnum2["RENDERBUFFER_RED_SIZE"] = 36176] = "RENDERBUFFER_RED_SIZE"; GLEnum2[GLEnum2["RENDERBUFFER_GREEN_SIZE"] = 36177] = "RENDERBUFFER_GREEN_SIZE"; GLEnum2[GLEnum2["RENDERBUFFER_BLUE_SIZE"] = 36178] = "RENDERBUFFER_BLUE_SIZE"; GLEnum2[GLEnum2["RENDERBUFFER_ALPHA_SIZE"] = 36179] = "RENDERBUFFER_ALPHA_SIZE"; GLEnum2[GLEnum2["RENDERBUFFER_DEPTH_SIZE"] = 36180] = "RENDERBUFFER_DEPTH_SIZE"; GLEnum2[GLEnum2["RENDERBUFFER_STENCIL_SIZE"] = 36181] = "RENDERBUFFER_STENCIL_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE"] = 36048] = "FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_OBJECT_NAME"] = 36049] = "FRAMEBUFFER_ATTACHMENT_OBJECT_NAME"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL"] = 36050] = "FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE"] = 36051] = "FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE"; GLEnum2[GLEnum2["COLOR_ATTACHMENT0"] = 36064] = "COLOR_ATTACHMENT0"; GLEnum2[GLEnum2["DEPTH_ATTACHMENT"] = 36096] = "DEPTH_ATTACHMENT"; GLEnum2[GLEnum2["STENCIL_ATTACHMENT"] = 36128] = "STENCIL_ATTACHMENT"; GLEnum2[GLEnum2["DEPTH_STENCIL_ATTACHMENT"] = 33306] = "DEPTH_STENCIL_ATTACHMENT"; GLEnum2[GLEnum2["NONE"] = 0] = "NONE"; GLEnum2[GLEnum2["FRAMEBUFFER_COMPLETE"] = 36053] = "FRAMEBUFFER_COMPLETE"; GLEnum2[GLEnum2["FRAMEBUFFER_INCOMPLETE_ATTACHMENT"] = 36054] = "FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; GLEnum2[GLEnum2["FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"] = 36055] = "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; GLEnum2[GLEnum2["FRAMEBUFFER_INCOMPLETE_DIMENSIONS"] = 36057] = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; GLEnum2[GLEnum2["FRAMEBUFFER_UNSUPPORTED"] = 36061] = "FRAMEBUFFER_UNSUPPORTED"; GLEnum2[GLEnum2["FRAMEBUFFER_BINDING"] = 36006] = "FRAMEBUFFER_BINDING"; GLEnum2[GLEnum2["RENDERBUFFER_BINDING"] = 36007] = "RENDERBUFFER_BINDING"; GLEnum2[GLEnum2["READ_FRAMEBUFFER"] = 36008] = "READ_FRAMEBUFFER"; GLEnum2[GLEnum2["DRAW_FRAMEBUFFER"] = 36009] = "DRAW_FRAMEBUFFER"; GLEnum2[GLEnum2["MAX_RENDERBUFFER_SIZE"] = 34024] = "MAX_RENDERBUFFER_SIZE"; GLEnum2[GLEnum2["INVALID_FRAMEBUFFER_OPERATION"] = 1286] = "INVALID_FRAMEBUFFER_OPERATION"; GLEnum2[GLEnum2["UNPACK_FLIP_Y_WEBGL"] = 37440] = "UNPACK_FLIP_Y_WEBGL"; GLEnum2[GLEnum2["UNPACK_PREMULTIPLY_ALPHA_WEBGL"] = 37441] = "UNPACK_PREMULTIPLY_ALPHA_WEBGL"; GLEnum2[GLEnum2["UNPACK_COLORSPACE_CONVERSION_WEBGL"] = 37443] = "UNPACK_COLORSPACE_CONVERSION_WEBGL"; GLEnum2[GLEnum2["READ_BUFFER"] = 3074] = "READ_BUFFER"; GLEnum2[GLEnum2["UNPACK_ROW_LENGTH"] = 3314] = "UNPACK_ROW_LENGTH"; GLEnum2[GLEnum2["UNPACK_SKIP_ROWS"] = 3315] = "UNPACK_SKIP_ROWS"; GLEnum2[GLEnum2["UNPACK_SKIP_PIXELS"] = 3316] = "UNPACK_SKIP_PIXELS"; GLEnum2[GLEnum2["PACK_ROW_LENGTH"] = 3330] = "PACK_ROW_LENGTH"; GLEnum2[GLEnum2["PACK_SKIP_ROWS"] = 3331] = "PACK_SKIP_ROWS"; GLEnum2[GLEnum2["PACK_SKIP_PIXELS"] = 3332] = "PACK_SKIP_PIXELS"; GLEnum2[GLEnum2["TEXTURE_BINDING_3D"] = 32874] = "TEXTURE_BINDING_3D"; GLEnum2[GLEnum2["UNPACK_SKIP_IMAGES"] = 32877] = "UNPACK_SKIP_IMAGES"; GLEnum2[GLEnum2["UNPACK_IMAGE_HEIGHT"] = 32878] = "UNPACK_IMAGE_HEIGHT"; GLEnum2[GLEnum2["MAX_3D_TEXTURE_SIZE"] = 32883] = "MAX_3D_TEXTURE_SIZE"; GLEnum2[GLEnum2["MAX_ELEMENTS_VERTICES"] = 33e3] = "MAX_ELEMENTS_VERTICES"; GLEnum2[GLEnum2["MAX_ELEMENTS_INDICES"] = 33001] = "MAX_ELEMENTS_INDICES"; GLEnum2[GLEnum2["MAX_TEXTURE_LOD_BIAS"] = 34045] = "MAX_TEXTURE_LOD_BIAS"; GLEnum2[GLEnum2["MAX_FRAGMENT_UNIFORM_COMPONENTS"] = 35657] = "MAX_FRAGMENT_UNIFORM_COMPONENTS"; GLEnum2[GLEnum2["MAX_VERTEX_UNIFORM_COMPONENTS"] = 35658] = "MAX_VERTEX_UNIFORM_COMPONENTS"; GLEnum2[GLEnum2["MAX_ARRAY_TEXTURE_LAYERS"] = 35071] = "MAX_ARRAY_TEXTURE_LAYERS"; GLEnum2[GLEnum2["MIN_PROGRAM_TEXEL_OFFSET"] = 35076] = "MIN_PROGRAM_TEXEL_OFFSET"; GLEnum2[GLEnum2["MAX_PROGRAM_TEXEL_OFFSET"] = 35077] = "MAX_PROGRAM_TEXEL_OFFSET"; GLEnum2[GLEnum2["MAX_VARYING_COMPONENTS"] = 35659] = "MAX_VARYING_COMPONENTS"; GLEnum2[GLEnum2["FRAGMENT_SHADER_DERIVATIVE_HINT"] = 35723] = "FRAGMENT_SHADER_DERIVATIVE_HINT"; GLEnum2[GLEnum2["RASTERIZER_DISCARD"] = 35977] = "RASTERIZER_DISCARD"; GLEnum2[GLEnum2["VERTEX_ARRAY_BINDING"] = 34229] = "VERTEX_ARRAY_BINDING"; GLEnum2[GLEnum2["MAX_VERTEX_OUTPUT_COMPONENTS"] = 37154] = "MAX_VERTEX_OUTPUT_COMPONENTS"; GLEnum2[GLEnum2["MAX_FRAGMENT_INPUT_COMPONENTS"] = 37157] = "MAX_FRAGMENT_INPUT_COMPONENTS"; GLEnum2[GLEnum2["MAX_SERVER_WAIT_TIMEOUT"] = 37137] = "MAX_SERVER_WAIT_TIMEOUT"; GLEnum2[GLEnum2["MAX_ELEMENT_INDEX"] = 36203] = "MAX_ELEMENT_INDEX"; GLEnum2[GLEnum2["RED"] = 6403] = "RED"; GLEnum2[GLEnum2["RGB8"] = 32849] = "RGB8"; GLEnum2[GLEnum2["RGBA8"] = 32856] = "RGBA8"; GLEnum2[GLEnum2["RGB10_A2"] = 32857] = "RGB10_A2"; GLEnum2[GLEnum2["TEXTURE_3D"] = 32879] = "TEXTURE_3D"; GLEnum2[GLEnum2["TEXTURE_WRAP_R"] = 32882] = "TEXTURE_WRAP_R"; GLEnum2[GLEnum2["TEXTURE_MIN_LOD"] = 33082] = "TEXTURE_MIN_LOD"; GLEnum2[GLEnum2["TEXTURE_MAX_LOD"] = 33083] = "TEXTURE_MAX_LOD"; GLEnum2[GLEnum2["TEXTURE_BASE_LEVEL"] = 33084] = "TEXTURE_BASE_LEVEL"; GLEnum2[GLEnum2["TEXTURE_MAX_LEVEL"] = 33085] = "TEXTURE_MAX_LEVEL"; GLEnum2[GLEnum2["TEXTURE_COMPARE_MODE"] = 34892] = "TEXTURE_COMPARE_MODE"; GLEnum2[GLEnum2["TEXTURE_COMPARE_FUNC"] = 34893] = "TEXTURE_COMPARE_FUNC"; GLEnum2[GLEnum2["SRGB"] = 35904] = "SRGB"; GLEnum2[GLEnum2["SRGB8"] = 35905] = "SRGB8"; GLEnum2[GLEnum2["SRGB8_ALPHA8"] = 35907] = "SRGB8_ALPHA8"; GLEnum2[GLEnum2["COMPARE_REF_TO_TEXTURE"] = 34894] = "COMPARE_REF_TO_TEXTURE"; GLEnum2[GLEnum2["RGBA32F"] = 34836] = "RGBA32F"; GLEnum2[GLEnum2["RGB32F"] = 34837] = "RGB32F"; GLEnum2[GLEnum2["RGBA16F"] = 34842] = "RGBA16F"; GLEnum2[GLEnum2["RGB16F"] = 34843] = "RGB16F"; GLEnum2[GLEnum2["TEXTURE_2D_ARRAY"] = 35866] = "TEXTURE_2D_ARRAY"; GLEnum2[GLEnum2["TEXTURE_BINDING_2D_ARRAY"] = 35869] = "TEXTURE_BINDING_2D_ARRAY"; GLEnum2[GLEnum2["R11F_G11F_B10F"] = 35898] = "R11F_G11F_B10F"; GLEnum2[GLEnum2["RGB9_E5"] = 35901] = "RGB9_E5"; GLEnum2[GLEnum2["RGBA32UI"] = 36208] = "RGBA32UI"; GLEnum2[GLEnum2["RGB32UI"] = 36209] = "RGB32UI"; GLEnum2[GLEnum2["RGBA16UI"] = 36214] = "RGBA16UI"; GLEnum2[GLEnum2["RGB16UI"] = 36215] = "RGB16UI"; GLEnum2[GLEnum2["RGBA8UI"] = 36220] = "RGBA8UI"; GLEnum2[GLEnum2["RGB8UI"] = 36221] = "RGB8UI"; GLEnum2[GLEnum2["RGBA32I"] = 36226] = "RGBA32I"; GLEnum2[GLEnum2["RGB32I"] = 36227] = "RGB32I"; GLEnum2[GLEnum2["RGBA16I"] = 36232] = "RGBA16I"; GLEnum2[GLEnum2["RGB16I"] = 36233] = "RGB16I"; GLEnum2[GLEnum2["RGBA8I"] = 36238] = "RGBA8I"; GLEnum2[GLEnum2["RGB8I"] = 36239] = "RGB8I"; GLEnum2[GLEnum2["RED_INTEGER"] = 36244] = "RED_INTEGER"; GLEnum2[GLEnum2["RGB_INTEGER"] = 36248] = "RGB_INTEGER"; GLEnum2[GLEnum2["RGBA_INTEGER"] = 36249] = "RGBA_INTEGER"; GLEnum2[GLEnum2["R8"] = 33321] = "R8"; GLEnum2[GLEnum2["RG8"] = 33323] = "RG8"; GLEnum2[GLEnum2["R16F"] = 33325] = "R16F"; GLEnum2[GLEnum2["R32F"] = 33326] = "R32F"; GLEnum2[GLEnum2["RG16F"] = 33327] = "RG16F"; GLEnum2[GLEnum2["RG32F"] = 33328] = "RG32F"; GLEnum2[GLEnum2["R8I"] = 33329] = "R8I"; GLEnum2[GLEnum2["R8UI"] = 33330] = "R8UI"; GLEnum2[GLEnum2["R16I"] = 33331] = "R16I"; GLEnum2[GLEnum2["R16UI"] = 33332] = "R16UI"; GLEnum2[GLEnum2["R32I"] = 33333] = "R32I"; GLEnum2[GLEnum2["R32UI"] = 33334] = "R32UI"; GLEnum2[GLEnum2["RG8I"] = 33335] = "RG8I"; GLEnum2[GLEnum2["RG8UI"] = 33336] = "RG8UI"; GLEnum2[GLEnum2["RG16I"] = 33337] = "RG16I"; GLEnum2[GLEnum2["RG16UI"] = 33338] = "RG16UI"; GLEnum2[GLEnum2["RG32I"] = 33339] = "RG32I"; GLEnum2[GLEnum2["RG32UI"] = 33340] = "RG32UI"; GLEnum2[GLEnum2["R8_SNORM"] = 36756] = "R8_SNORM"; GLEnum2[GLEnum2["RG8_SNORM"] = 36757] = "RG8_SNORM"; GLEnum2[GLEnum2["RGB8_SNORM"] = 36758] = "RGB8_SNORM"; GLEnum2[GLEnum2["RGBA8_SNORM"] = 36759] = "RGBA8_SNORM"; GLEnum2[GLEnum2["RGB10_A2UI"] = 36975] = "RGB10_A2UI"; GLEnum2[GLEnum2["TEXTURE_IMMUTABLE_FORMAT"] = 37167] = "TEXTURE_IMMUTABLE_FORMAT"; GLEnum2[GLEnum2["TEXTURE_IMMUTABLE_LEVELS"] = 33503] = "TEXTURE_IMMUTABLE_LEVELS"; GLEnum2[GLEnum2["UNSIGNED_INT_2_10_10_10_REV"] = 33640] = "UNSIGNED_INT_2_10_10_10_REV"; GLEnum2[GLEnum2["UNSIGNED_INT_10F_11F_11F_REV"] = 35899] = "UNSIGNED_INT_10F_11F_11F_REV"; GLEnum2[GLEnum2["UNSIGNED_INT_5_9_9_9_REV"] = 35902] = "UNSIGNED_INT_5_9_9_9_REV"; GLEnum2[GLEnum2["FLOAT_32_UNSIGNED_INT_24_8_REV"] = 36269] = "FLOAT_32_UNSIGNED_INT_24_8_REV"; GLEnum2[GLEnum2["UNSIGNED_INT_24_8"] = 34042] = "UNSIGNED_INT_24_8"; GLEnum2[GLEnum2["HALF_FLOAT"] = 5131] = "HALF_FLOAT"; GLEnum2[GLEnum2["RG"] = 33319] = "RG"; GLEnum2[GLEnum2["RG_INTEGER"] = 33320] = "RG_INTEGER"; GLEnum2[GLEnum2["INT_2_10_10_10_REV"] = 36255] = "INT_2_10_10_10_REV"; GLEnum2[GLEnum2["CURRENT_QUERY"] = 34917] = "CURRENT_QUERY"; GLEnum2[GLEnum2["QUERY_RESULT"] = 34918] = "QUERY_RESULT"; GLEnum2[GLEnum2["QUERY_RESULT_AVAILABLE"] = 34919] = "QUERY_RESULT_AVAILABLE"; GLEnum2[GLEnum2["ANY_SAMPLES_PASSED"] = 35887] = "ANY_SAMPLES_PASSED"; GLEnum2[GLEnum2["ANY_SAMPLES_PASSED_CONSERVATIVE"] = 36202] = "ANY_SAMPLES_PASSED_CONSERVATIVE"; GLEnum2[GLEnum2["MAX_DRAW_BUFFERS"] = 34852] = "MAX_DRAW_BUFFERS"; GLEnum2[GLEnum2["DRAW_BUFFER0"] = 34853] = "DRAW_BUFFER0"; GLEnum2[GLEnum2["DRAW_BUFFER1"] = 34854] = "DRAW_BUFFER1"; GLEnum2[GLEnum2["DRAW_BUFFER2"] = 34855] = "DRAW_BUFFER2"; GLEnum2[GLEnum2["DRAW_BUFFER3"] = 34856] = "DRAW_BUFFER3"; GLEnum2[GLEnum2["DRAW_BUFFER4"] = 34857] = "DRAW_BUFFER4"; GLEnum2[GLEnum2["DRAW_BUFFER5"] = 34858] = "DRAW_BUFFER5"; GLEnum2[GLEnum2["DRAW_BUFFER6"] = 34859] = "DRAW_BUFFER6"; GLEnum2[GLEnum2["DRAW_BUFFER7"] = 34860] = "DRAW_BUFFER7"; GLEnum2[GLEnum2["DRAW_BUFFER8"] = 34861] = "DRAW_BUFFER8"; GLEnum2[GLEnum2["DRAW_BUFFER9"] = 34862] = "DRAW_BUFFER9"; GLEnum2[GLEnum2["DRAW_BUFFER10"] = 34863] = "DRAW_BUFFER10"; GLEnum2[GLEnum2["DRAW_BUFFER11"] = 34864] = "DRAW_BUFFER11"; GLEnum2[GLEnum2["DRAW_BUFFER12"] = 34865] = "DRAW_BUFFER12"; GLEnum2[GLEnum2["DRAW_BUFFER13"] = 34866] = "DRAW_BUFFER13"; GLEnum2[GLEnum2["DRAW_BUFFER14"] = 34867] = "DRAW_BUFFER14"; GLEnum2[GLEnum2["DRAW_BUFFER15"] = 34868] = "DRAW_BUFFER15"; GLEnum2[GLEnum2["MAX_COLOR_ATTACHMENTS"] = 36063] = "MAX_COLOR_ATTACHMENTS"; GLEnum2[GLEnum2["COLOR_ATTACHMENT1"] = 36065] = "COLOR_ATTACHMENT1"; GLEnum2[GLEnum2["COLOR_ATTACHMENT2"] = 36066] = "COLOR_ATTACHMENT2"; GLEnum2[GLEnum2["COLOR_ATTACHMENT3"] = 36067] = "COLOR_ATTACHMENT3"; GLEnum2[GLEnum2["COLOR_ATTACHMENT4"] = 36068] = "COLOR_ATTACHMENT4"; GLEnum2[GLEnum2["COLOR_ATTACHMENT5"] = 36069] = "COLOR_ATTACHMENT5"; GLEnum2[GLEnum2["COLOR_ATTACHMENT6"] = 36070] = "COLOR_ATTACHMENT6"; GLEnum2[GLEnum2["COLOR_ATTACHMENT7"] = 36071] = "COLOR_ATTACHMENT7"; GLEnum2[GLEnum2["COLOR_ATTACHMENT8"] = 36072] = "COLOR_ATTACHMENT8"; GLEnum2[GLEnum2["COLOR_ATTACHMENT9"] = 36073] = "COLOR_ATTACHMENT9"; GLEnum2[GLEnum2["COLOR_ATTACHMENT10"] = 36074] = "COLOR_ATTACHMENT10"; GLEnum2[GLEnum2["COLOR_ATTACHMENT11"] = 36075] = "COLOR_ATTACHMENT11"; GLEnum2[GLEnum2["COLOR_ATTACHMENT12"] = 36076] = "COLOR_ATTACHMENT12"; GLEnum2[GLEnum2["COLOR_ATTACHMENT13"] = 36077] = "COLOR_ATTACHMENT13"; GLEnum2[GLEnum2["COLOR_ATTACHMENT14"] = 36078] = "COLOR_ATTACHMENT14"; GLEnum2[GLEnum2["COLOR_ATTACHMENT15"] = 36079] = "COLOR_ATTACHMENT15"; GLEnum2[GLEnum2["SAMPLER_3D"] = 35679] = "SAMPLER_3D"; GLEnum2[GLEnum2["SAMPLER_2D_SHADOW"] = 35682] = "SAMPLER_2D_SHADOW"; GLEnum2[GLEnum2["SAMPLER_2D_ARRAY"] = 36289] = "SAMPLER_2D_ARRAY"; GLEnum2[GLEnum2["SAMPLER_2D_ARRAY_SHADOW"] = 36292] = "SAMPLER_2D_ARRAY_SHADOW"; GLEnum2[GLEnum2["SAMPLER_CUBE_SHADOW"] = 36293] = "SAMPLER_CUBE_SHADOW"; GLEnum2[GLEnum2["INT_SAMPLER_2D"] = 36298] = "INT_SAMPLER_2D"; GLEnum2[GLEnum2["INT_SAMPLER_3D"] = 36299] = "INT_SAMPLER_3D"; GLEnum2[GLEnum2["INT_SAMPLER_CUBE"] = 36300] = "INT_SAMPLER_CUBE"; GLEnum2[GLEnum2["INT_SAMPLER_2D_ARRAY"] = 36303] = "INT_SAMPLER_2D_ARRAY"; GLEnum2[GLEnum2["UNSIGNED_INT_SAMPLER_2D"] = 36306] = "UNSIGNED_INT_SAMPLER_2D"; GLEnum2[GLEnum2["UNSIGNED_INT_SAMPLER_3D"] = 36307] = "UNSIGNED_INT_SAMPLER_3D"; GLEnum2[GLEnum2["UNSIGNED_INT_SAMPLER_CUBE"] = 36308] = "UNSIGNED_INT_SAMPLER_CUBE"; GLEnum2[GLEnum2["UNSIGNED_INT_SAMPLER_2D_ARRAY"] = 36311] = "UNSIGNED_INT_SAMPLER_2D_ARRAY"; GLEnum2[GLEnum2["MAX_SAMPLES"] = 36183] = "MAX_SAMPLES"; GLEnum2[GLEnum2["SAMPLER_BINDING"] = 35097] = "SAMPLER_BINDING"; GLEnum2[GLEnum2["PIXEL_PACK_BUFFER"] = 35051] = "PIXEL_PACK_BUFFER"; GLEnum2[GLEnum2["PIXEL_UNPACK_BUFFER"] = 35052] = "PIXEL_UNPACK_BUFFER"; GLEnum2[GLEnum2["PIXEL_PACK_BUFFER_BINDING"] = 35053] = "PIXEL_PACK_BUFFER_BINDING"; GLEnum2[GLEnum2["PIXEL_UNPACK_BUFFER_BINDING"] = 35055] = "PIXEL_UNPACK_BUFFER_BINDING"; GLEnum2[GLEnum2["COPY_READ_BUFFER"] = 36662] = "COPY_READ_BUFFER"; GLEnum2[GLEnum2["COPY_WRITE_BUFFER"] = 36663] = "COPY_WRITE_BUFFER"; GLEnum2[GLEnum2["COPY_READ_BUFFER_BINDING"] = 36662] = "COPY_READ_BUFFER_BINDING"; GLEnum2[GLEnum2["COPY_WRITE_BUFFER_BINDING"] = 36663] = "COPY_WRITE_BUFFER_BINDING"; GLEnum2[GLEnum2["FLOAT_MAT2x3"] = 35685] = "FLOAT_MAT2x3"; GLEnum2[GLEnum2["FLOAT_MAT2x4"] = 35686] = "FLOAT_MAT2x4"; GLEnum2[GLEnum2["FLOAT_MAT3x2"] = 35687] = "FLOAT_MAT3x2"; GLEnum2[GLEnum2["FLOAT_MAT3x4"] = 35688] = "FLOAT_MAT3x4"; GLEnum2[GLEnum2["FLOAT_MAT4x2"] = 35689] = "FLOAT_MAT4x2"; GLEnum2[GLEnum2["FLOAT_MAT4x3"] = 35690] = "FLOAT_MAT4x3"; GLEnum2[GLEnum2["UNSIGNED_INT_VEC2"] = 36294] = "UNSIGNED_INT_VEC2"; GLEnum2[GLEnum2["UNSIGNED_INT_VEC3"] = 36295] = "UNSIGNED_INT_VEC3"; GLEnum2[GLEnum2["UNSIGNED_INT_VEC4"] = 36296] = "UNSIGNED_INT_VEC4"; GLEnum2[GLEnum2["UNSIGNED_NORMALIZED"] = 35863] = "UNSIGNED_NORMALIZED"; GLEnum2[GLEnum2["SIGNED_NORMALIZED"] = 36764] = "SIGNED_NORMALIZED"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_INTEGER"] = 35069] = "VERTEX_ATTRIB_ARRAY_INTEGER"; GLEnum2[GLEnum2["VERTEX_ATTRIB_ARRAY_DIVISOR"] = 35070] = "VERTEX_ATTRIB_ARRAY_DIVISOR"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_BUFFER_MODE"] = 35967] = "TRANSFORM_FEEDBACK_BUFFER_MODE"; GLEnum2[GLEnum2["MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS"] = 35968] = "MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_VARYINGS"] = 35971] = "TRANSFORM_FEEDBACK_VARYINGS"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_BUFFER_START"] = 35972] = "TRANSFORM_FEEDBACK_BUFFER_START"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_BUFFER_SIZE"] = 35973] = "TRANSFORM_FEEDBACK_BUFFER_SIZE"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"] = 35976] = "TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN"; GLEnum2[GLEnum2["MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS"] = 35978] = "MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS"; GLEnum2[GLEnum2["MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"] = 35979] = "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"; GLEnum2[GLEnum2["INTERLEAVED_ATTRIBS"] = 35980] = "INTERLEAVED_ATTRIBS"; GLEnum2[GLEnum2["SEPARATE_ATTRIBS"] = 35981] = "SEPARATE_ATTRIBS"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_BUFFER"] = 35982] = "TRANSFORM_FEEDBACK_BUFFER"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_BUFFER_BINDING"] = 35983] = "TRANSFORM_FEEDBACK_BUFFER_BINDING"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK"] = 36386] = "TRANSFORM_FEEDBACK"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_PAUSED"] = 36387] = "TRANSFORM_FEEDBACK_PAUSED"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_ACTIVE"] = 36388] = "TRANSFORM_FEEDBACK_ACTIVE"; GLEnum2[GLEnum2["TRANSFORM_FEEDBACK_BINDING"] = 36389] = "TRANSFORM_FEEDBACK_BINDING"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"] = 33296] = "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"] = 33297] = "FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_RED_SIZE"] = 33298] = "FRAMEBUFFER_ATTACHMENT_RED_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_GREEN_SIZE"] = 33299] = "FRAMEBUFFER_ATTACHMENT_GREEN_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_BLUE_SIZE"] = 33300] = "FRAMEBUFFER_ATTACHMENT_BLUE_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE"] = 33301] = "FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE"] = 33302] = "FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE"] = 33303] = "FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE"; GLEnum2[GLEnum2["FRAMEBUFFER_DEFAULT"] = 33304] = "FRAMEBUFFER_DEFAULT"; GLEnum2[GLEnum2["DEPTH24_STENCIL8"] = 35056] = "DEPTH24_STENCIL8"; GLEnum2[GLEnum2["DRAW_FRAMEBUFFER_BINDING"] = 36006] = "DRAW_FRAMEBUFFER_BINDING"; GLEnum2[GLEnum2["READ_FRAMEBUFFER_BINDING"] = 36010] = "READ_FRAMEBUFFER_BINDING"; GLEnum2[GLEnum2["RENDERBUFFER_SAMPLES"] = 36011] = "RENDERBUFFER_SAMPLES"; GLEnum2[GLEnum2["FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER"] = 36052] = "FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER"; GLEnum2[GLEnum2["FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"] = 36182] = "FRAMEBUFFER_INCOMPLETE_MULTISAMPLE"; GLEnum2[GLEnum2["UNIFORM_BUFFER"] = 35345] = "UNIFORM_BUFFER"; GLEnum2[GLEnum2["UNIFORM_BUFFER_BINDING"] = 35368] = "UNIFORM_BUFFER_BINDING"; GLEnum2[GLEnum2["UNIFORM_BUFFER_START"] = 35369] = "UNIFORM_BUFFER_START"; GLEnum2[GLEnum2["UNIFORM_BUFFER_SIZE"] = 35370] = "UNIFORM_BUFFER_SIZE"; GLEnum2[GLEnum2["MAX_VERTEX_UNIFORM_BLOCKS"] = 35371] = "MAX_VERTEX_UNIFORM_BLOCKS"; GLEnum2[GLEnum2["MAX_FRAGMENT_UNIFORM_BLOCKS"] = 35373] = "MAX_FRAGMENT_UNIFORM_BLOCKS"; GLEnum2[GLEnum2["MAX_COMBINED_UNIFORM_BLOCKS"] = 35374] = "MAX_COMBINED_UNIFORM_BLOCKS"; GLEnum2[GLEnum2["MAX_UNIFORM_BUFFER_BINDINGS"] = 35375] = "MAX_UNIFORM_BUFFER_BINDINGS"; GLEnum2[GLEnum2["MAX_UNIFORM_BLOCK_SIZE"] = 35376] = "MAX_UNIFORM_BLOCK_SIZE"; GLEnum2[GLEnum2["MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS"] = 35377] = "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS"; GLEnum2[GLEnum2["MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS"] = 35379] = "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS"; GLEnum2[GLEnum2["UNIFORM_BUFFER_OFFSET_ALIGNMENT"] = 35380] = "UNIFORM_BUFFER_OFFSET_ALIGNMENT"; GLEnum2[GLEnum2["ACTIVE_UNIFORM_BLOCKS"] = 35382] = "ACTIVE_UNIFORM_BLOCKS"; GLEnum2[GLEnum2["UNIFORM_TYPE"] = 35383] = "UNIFORM_TYPE"; GLEnum2[GLEnum2["UNIFORM_SIZE"] = 35384] = "UNIFORM_SIZE"; GLEnum2[GLEnum2["UNIFORM_BLOCK_INDEX"] = 35386] = "UNIFORM_BLOCK_INDEX"; GLEnum2[GLEnum2["UNIFORM_OFFSET"] = 35387] = "UNIFORM_OFFSET"; GLEnum2[GLEnum2["UNIFORM_ARRAY_STRIDE"] = 35388] = "UNIFORM_ARRAY_STRIDE"; GLEnum2[GLEnum2["UNIFORM_MATRIX_STRIDE"] = 35389] = "UNIFORM_MATRIX_STRIDE"; GLEnum2[GLEnum2["UNIFORM_IS_ROW_MAJOR"] = 35390] = "UNIFORM_IS_ROW_MAJOR"; GLEnum2[GLEnum2["UNIFORM_BLOCK_BINDING"] = 35391] = "UNIFORM_BLOCK_BINDING"; GLEnum2[GLEnum2["UNIFORM_BLOCK_DATA_SIZE"] = 35392] = "UNIFORM_BLOCK_DATA_SIZE"; GLEnum2[GLEnum2["UNIFORM_BLOCK_ACTIVE_UNIFORMS"] = 35394] = "UNIFORM_BLOCK_ACTIVE_UNIFORMS"; GLEnum2[GLEnum2["UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES"] = 35395] = "UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES"; GLEnum2[GLEnum2["UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER"] = 35396] = "UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER"; GLEnum2[GLEnum2["UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER"] = 35398] = "UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER"; GLEnum2[GLEnum2["OBJECT_TYPE"] = 37138] = "OBJECT_TYPE"; GLEnum2[GLEnum2["SYNC_CONDITION"] = 37139] = "SYNC_CONDITION"; GLEnum2[GLEnum2["SYNC_STATUS"] = 37140] = "SYNC_STATUS"; GLEnum2[GLEnum2["SYNC_FLAGS"] = 37141] = "SYNC_FLAGS"; GLEnum2[GLEnum2["SYNC_FENCE"] = 37142] = "SYNC_FENCE"; GLEnum2[GLEnum2["SYNC_GPU_COMMANDS_COMPLETE"] = 37143] = "SYNC_GPU_COMMANDS_COMPLETE"; GLEnum2[GLEnum2["UNSIGNALED"] = 37144] = "UNSIGNALED"; GLEnum2[GLEnum2["SIGNALED"] = 37145] = "SIGNALED"; GLEnum2[GLEnum2["ALREADY_SIGNALED"] = 37146] = "ALREADY_SIGNALED"; GLEnum2[GLEnum2["TIMEOUT_EXPIRED"] = 37147] = "TIMEOUT_EXPIRED"; GLEnum2[GLEnum2["CONDITION_SATISFIED"] = 37148] = "CONDITION_SATISFIED"; GLEnum2[GLEnum2["WAIT_FAILED"] = 37149] = "WAIT_FAILED"; GLEnum2[GLEnum2["SYNC_FLUSH_COMMANDS_BIT"] = 1] = "SYNC_FLUSH_COMMANDS_BIT"; GLEnum2[GLEnum2["COLOR"] = 6144] = "COLOR"; GLEnum2[GLEnum2["DEPTH"] = 6145] = "DEPTH"; GLEnum2[GLEnum2["STENCIL"] = 6146] = "STENCIL"; GLEnum2[GLEnum2["MIN"] = 32775] = "MIN"; GLEnum2[GLEnum2["MAX"] = 32776] = "MAX"; GLEnum2[GLEnum2["DEPTH_COMPONENT24"] = 33190] = "DEPTH_COMPONENT24"; GLEnum2[GLEnum2["STREAM_READ"] = 35041] = "STREAM_READ"; GLEnum2[GLEnum2["STREAM_COPY"] = 35042] = "STREAM_COPY"; GLEnum2[GLEnum2["STATIC_READ"] = 35045] = "STATIC_READ"; GLEnum2[GLEnum2["STATIC_COPY"] = 35046] = "STATIC_COPY"; GLEnum2[GLEnum2["DYNAMIC_READ"] = 35049] = "DYNAMIC_READ"; GLEnum2[GLEnum2["DYNAMIC_COPY"] = 35050] = "DYNAMIC_COPY"; GLEnum2[GLEnum2["DEPTH_COMPONENT32F"] = 36012] = "DEPTH_COMPONENT32F"; GLEnum2[GLEnum2["DEPTH32F_STENCIL8"] = 36013] = "DEPTH32F_STENCIL8"; GLEnum2[GLEnum2["INVALID_INDEX"] = 4294967295] = "INVALID_INDEX"; GLEnum2[GLEnum2["TIMEOUT_IGNORED"] = -1] = "TIMEOUT_IGNORED"; GLEnum2[GLEnum2["MAX_CLIENT_WAIT_TIMEOUT_WEBGL"] = 37447] = "MAX_CLIENT_WAIT_TIMEOUT_WEBGL"; GLEnum2[GLEnum2["UNMASKED_VENDOR_WEBGL"] = 37445] = "UNMASKED_VENDOR_WEBGL"; GLEnum2[GLEnum2["UNMASKED_RENDERER_WEBGL"] = 37446] = "UNMASKED_RENDERER_WEBGL"; GLEnum2[GLEnum2["MAX_TEXTURE_MAX_ANISOTROPY_EXT"] = 34047] = "MAX_TEXTURE_MAX_ANISOTROPY_EXT"; GLEnum2[GLEnum2["TEXTURE_MAX_ANISOTROPY_EXT"] = 34046] = "TEXTURE_MAX_ANISOTROPY_EXT"; GLEnum2[GLEnum2["R16_EXT"] = 33322] = "R16_EXT"; GLEnum2[GLEnum2["RG16_EXT"] = 33324] = "RG16_EXT"; GLEnum2[GLEnum2["RGB16_EXT"] = 32852] = "RGB16_EXT"; GLEnum2[GLEnum2["RGBA16_EXT"] = 32859] = "RGBA16_EXT"; GLEnum2[GLEnum2["R16_SNORM_EXT"] = 36760] = "R16_SNORM_EXT"; GLEnum2[GLEnum2["RG16_SNORM_EXT"] = 36761] = "RG16_SNORM_EXT"; GLEnum2[GLEnum2["RGB16_SNORM_EXT"] = 36762] = "RGB16_SNORM_EXT"; GLEnum2[GLEnum2["RGBA16_SNORM_EXT"] = 36763] = "RGBA16_SNORM_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGB_S3TC_DXT1_EXT"] = 33776] = "COMPRESSED_RGB_S3TC_DXT1_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGBA_S3TC_DXT1_EXT"] = 33777] = "COMPRESSED_RGBA_S3TC_DXT1_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGBA_S3TC_DXT3_EXT"] = 33778] = "COMPRESSED_RGBA_S3TC_DXT3_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGBA_S3TC_DXT5_EXT"] = 33779] = "COMPRESSED_RGBA_S3TC_DXT5_EXT"; GLEnum2[GLEnum2["COMPRESSED_SRGB_S3TC_DXT1_EXT"] = 35916] = "COMPRESSED_SRGB_S3TC_DXT1_EXT"; GLEnum2[GLEnum2["COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"] = 35917] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT"; GLEnum2[GLEnum2["COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"] = 35918] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT"; GLEnum2[GLEnum2["COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"] = 35919] = "COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT"; GLEnum2[GLEnum2["COMPRESSED_RED_RGTC1_EXT"] = 36283] = "COMPRESSED_RED_RGTC1_EXT"; GLEnum2[GLEnum2["COMPRESSED_SIGNED_RED_RGTC1_EXT"] = 36284] = "COMPRESSED_SIGNED_RED_RGTC1_EXT"; GLEnum2[GLEnum2["COMPRESSED_RED_GREEN_RGTC2_EXT"] = 36285] = "COMPRESSED_RED_GREEN_RGTC2_EXT"; GLEnum2[GLEnum2["COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT"] = 36286] = "COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGBA_BPTC_UNORM_EXT"] = 36492] = "COMPRESSED_RGBA_BPTC_UNORM_EXT"; GLEnum2[GLEnum2["COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT"] = 36493] = "COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT"] = 36494] = "COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT"; GLEnum2[GLEnum2["COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT"] = 36495] = "COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT"; GLEnum2[GLEnum2["COMPRESSED_R11_EAC"] = 37488] = "COMPRESSED_R11_EAC"; GLEnum2[GLEnum2["COMPRESSED_SIGNED_R11_EAC"] = 37489] = "COMPRESSED_SIGNED_R11_EAC"; GLEnum2[GLEnum2["COMPRESSED_RG11_EAC"] = 37490] = "COMPRESSED_RG11_EAC"; GLEnum2[GLEnum2["COMPRESSED_SIGNED_RG11_EAC"] = 37491] = "COMPRESSED_SIGNED_RG11_EAC"; GLEnum2[GLEnum2["COMPRESSED_RGB8_ETC2"] = 37492] = "COMPRESSED_RGB8_ETC2"; GLEnum2[GLEnum2["COMPRESSED_RGBA8_ETC2_EAC"] = 37493] = "COMPRESSED_RGBA8_ETC2_EAC"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ETC2"] = 37494] = "COMPRESSED_SRGB8_ETC2"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"] = 37495] = "COMPRESSED_SRGB8_ALPHA8_ETC2_EAC"; GLEnum2[GLEnum2["COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"] = 37496] = "COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"] = 37497] = "COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2"; GLEnum2[GLEnum2["COMPRESSED_RGB_PVRTC_4BPPV1_IMG"] = 35840] = "COMPRESSED_RGB_PVRTC_4BPPV1_IMG"; GLEnum2[GLEnum2["COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"] = 35842] = "COMPRESSED_RGBA_PVRTC_4BPPV1_IMG"; GLEnum2[GLEnum2["COMPRESSED_RGB_PVRTC_2BPPV1_IMG"] = 35841] = "COMPRESSED_RGB_PVRTC_2BPPV1_IMG"; GLEnum2[GLEnum2["COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"] = 35843] = "COMPRESSED_RGBA_PVRTC_2BPPV1_IMG"; GLEnum2[GLEnum2["COMPRESSED_RGB_ETC1_WEBGL"] = 36196] = "COMPRESSED_RGB_ETC1_WEBGL"; GLEnum2[GLEnum2["COMPRESSED_RGB_ATC_WEBGL"] = 35986] = "COMPRESSED_RGB_ATC_WEBGL"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL"] = 35986] = "COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL"] = 34798] = "COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_4x4_KHR"] = 37808] = "COMPRESSED_RGBA_ASTC_4x4_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_5x4_KHR"] = 37809] = "COMPRESSED_RGBA_ASTC_5x4_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_5x5_KHR"] = 37810] = "COMPRESSED_RGBA_ASTC_5x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_6x5_KHR"] = 37811] = "COMPRESSED_RGBA_ASTC_6x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_6x6_KHR"] = 37812] = "COMPRESSED_RGBA_ASTC_6x6_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_8x5_KHR"] = 37813] = "COMPRESSED_RGBA_ASTC_8x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_8x6_KHR"] = 37814] = "COMPRESSED_RGBA_ASTC_8x6_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_8x8_KHR"] = 37815] = "COMPRESSED_RGBA_ASTC_8x8_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_10x5_KHR"] = 37816] = "COMPRESSED_RGBA_ASTC_10x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_10x6_KHR"] = 37817] = "COMPRESSED_RGBA_ASTC_10x6_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_10x8_KHR"] = 37818] = "COMPRESSED_RGBA_ASTC_10x8_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_10x10_KHR"] = 37819] = "COMPRESSED_RGBA_ASTC_10x10_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_12x10_KHR"] = 37820] = "COMPRESSED_RGBA_ASTC_12x10_KHR"; GLEnum2[GLEnum2["COMPRESSED_RGBA_ASTC_12x12_KHR"] = 37821] = "COMPRESSED_RGBA_ASTC_12x12_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"] = 37840] = "COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"] = 37841] = "COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"] = 37842] = "COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"] = 37843] = "COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"] = 37844] = "COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"] = 37845] = "COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"] = 37846] = "COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"] = 37847] = "COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"] = 37848] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"] = 37849] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"] = 37850] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"] = 37851] = "COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"] = 37852] = "COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR"; GLEnum2[GLEnum2["COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"] = 37853] = "COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR"; GLEnum2[GLEnum2["QUERY_COUNTER_BITS_EXT"] = 34916] = "QUERY_COUNTER_BITS_EXT"; GLEnum2[GLEnum2["CURRENT_QUERY_EXT"] = 34917] = "CURRENT_QUERY_EXT"; GLEnum2[GLEnum2["QUERY_RESULT_EXT"] = 34918] = "QUERY_RESULT_EXT"; GLEnum2[GLEnum2["QUERY_RESULT_AVAILABLE_EXT"] = 34919] = "QUERY_RESULT_AVAILABLE_EXT"; GLEnum2[GLEnum2["TIME_ELAPSED_EXT"] = 35007] = "TIME_ELAPSED_EXT"; GLEnum2[GLEnum2["TIMESTAMP_EXT"] = 36392] = "TIMESTAMP_EXT"; GLEnum2[GLEnum2["GPU_DISJOINT_EXT"] = 36795] = "GPU_DISJOINT_EXT"; GLEnum2[GLEnum2["COMPLETION_STATUS_KHR"] = 37297] = "COMPLETION_STATUS_KHR"; GLEnum2[GLEnum2["DEPTH_CLAMP_EXT"] = 34383] = "DEPTH_CLAMP_EXT"; GLEnum2[GLEnum2["FIRST_VERTEX_CONVENTION_WEBGL"] = 36429] = "FIRST_VERTEX_CONVENTION_WEBGL"; GLEnum2[GLEnum2["LAST_VERTEX_CONVENTION_WEBGL"] = 36430] = "LAST_VERTEX_CONVENTION_WEBGL"; GLEnum2[GLEnum2["PROVOKING_VERTEX_WEBL"] = 36431] = "PROVOKING_VERTEX_WEBL"; GLEnum2[GLEnum2["POLYGON_MODE_WEBGL"] = 2880] = "POLYGON_MODE_WEBGL"; GLEnum2[GLEnum2["POLYGON_OFFSET_LINE_WEBGL"] = 10754] = "POLYGON_OFFSET_LINE_WEBGL"; GLEnum2[GLEnum2["LINE_WEBGL"] = 6913] = "LINE_WEBGL"; GLEnum2[GLEnum2["FILL_WEBGL"] = 6914] = "FILL_WEBGL"; GLEnum2[GLEnum2["MAX_CLIP_DISTANCES_WEBGL"] = 3378] = "MAX_CLIP_DISTANCES_WEBGL"; GLEnum2[GLEnum2["MAX_CULL_DISTANCES_WEBGL"] = 33529] = "MAX_CULL_DISTANCES_WEBGL"; GLEnum2[GLEnum2["MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL"] = 33530] = "MAX_COMBINED_CLIP_AND_CULL_DISTANCES_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE0_WEBGL"] = 12288] = "CLIP_DISTANCE0_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE1_WEBGL"] = 12289] = "CLIP_DISTANCE1_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE2_WEBGL"] = 12290] = "CLIP_DISTANCE2_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE3_WEBGL"] = 12291] = "CLIP_DISTANCE3_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE4_WEBGL"] = 12292] = "CLIP_DISTANCE4_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE5_WEBGL"] = 12293] = "CLIP_DISTANCE5_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE6_WEBGL"] = 12294] = "CLIP_DISTANCE6_WEBGL"; GLEnum2[GLEnum2["CLIP_DISTANCE7_WEBGL"] = 12295] = "CLIP_DISTANCE7_WEBGL"; GLEnum2[GLEnum2["POLYGON_OFFSET_CLAMP_EXT"] = 36379] = "POLYGON_OFFSET_CLAMP_EXT"; GLEnum2[GLEnum2["LOWER_LEFT_EXT"] = 36001] = "LOWER_LEFT_EXT"; GLEnum2[GLEnum2["UPPER_LEFT_EXT"] = 36002] = "UPPER_LEFT_EXT"; GLEnum2[GLEnum2["NEGATIVE_ONE_TO_ONE_EXT"] = 37726] = "NEGATIVE_ONE_TO_ONE_EXT"; GLEnum2[GLEnum2["ZERO_TO_ONE_EXT"] = 37727] = "ZERO_TO_ONE_EXT"; GLEnum2[GLEnum2["CLIP_ORIGIN_EXT"] = 37724] = "CLIP_ORIGIN_EXT"; GLEnum2[GLEnum2["CLIP_DEPTH_MODE_EXT"] = 37725] = "CLIP_DEPTH_MODE_EXT"; GLEnum2[GLEnum2["SRC1_COLOR_WEBGL"] = 35065] = "SRC1_COLOR_WEBGL"; GLEnum2[GLEnum2["SRC1_ALPHA_WEBGL"] = 34185] = "SRC1_ALPHA_WEBGL"; GLEnum2[GLEnum2["ONE_MINUS_SRC1_COLOR_WEBGL"] = 35066] = "ONE_MINUS_SRC1_COLOR_WEBGL"; GLEnum2[GLEnum2["ONE_MINUS_SRC1_ALPHA_WEBGL"] = 35067] = "ONE_MINUS_SRC1_ALPHA_WEBGL"; GLEnum2[GLEnum2["MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL"] = 35068] = "MAX_DUAL_SOURCE_DRAW_BUFFERS_WEBGL"; GLEnum2[GLEnum2["MIRROR_CLAMP_TO_EDGE_EXT"] = 34627] = "MIRROR_CLAMP_TO_EDGE_EXT"; })(GLEnum || (GLEnum = {})); // ../../node_modules/@luma.gl/webgl/dist/context/parameters/webgl-parameter-tables.js var GL_PARAMETER_DEFAULTS = { [3042]: false, [32773]: new Float32Array([0, 0, 0, 0]), [32777]: 32774, [34877]: 32774, [32969]: 1, [32968]: 0, [32971]: 1, [32970]: 0, [3106]: new Float32Array([0, 0, 0, 0]), [3107]: [true, true, true, true], [2884]: false, [2885]: 1029, [2929]: false, [2931]: 1, [2932]: 513, [2928]: new Float32Array([0, 1]), [2930]: true, [3024]: true, [35725]: null, [36006]: null, [36007]: null, [34229]: null, [34964]: null, [2886]: 2305, [33170]: 4352, [2849]: 1, [32823]: false, [32824]: 0, [10752]: 0, [32926]: false, [32928]: false, [32938]: 1, [32939]: false, [3089]: false, [3088]: new Int32Array([0, 0, 1024, 1024]), [2960]: false, [2961]: 0, [2968]: 4294967295, [36005]: 4294967295, [2962]: 519, [2967]: 0, [2963]: 4294967295, [34816]: 519, [36003]: 0, [36004]: 4294967295, [2964]: 7680, [2965]: 7680, [2966]: 7680, [34817]: 7680, [34818]: 7680, [34819]: 7680, [2978]: [0, 0, 1024, 1024], [36389]: null, [36662]: null, [36663]: null, [35053]: null, [35055]: null, [35723]: 4352, [36010]: null, [35977]: false, [3333]: 4, [3317]: 4, [37440]: false, [37441]: false, [37443]: 37444, [3330]: 0, [3332]: 0, [3331]: 0, [3314]: 0, [32878]: 0, [3316]: 0, [3315]: 0, [32877]: 0 }; var enable = (gl, value, key) => value ? gl.enable(key) : gl.disable(key); var hint = (gl, value, key) => gl.hint(key, value); var pixelStorei = (gl, value, key) => gl.pixelStorei(key, value); var bindFramebuffer = (gl, value, key) => { const target = key === 36006 ? 36009 : 36008; return gl.bindFramebuffer(target, value); }; var bindBuffer = (gl, value, key) => { const bindingMap = { [34964]: 34962, [36662]: 36662, [36663]: 36663, [35053]: 35051, [35055]: 35052 }; const glTarget = bindingMap[key]; gl.bindBuffer(glTarget, value); }; function isArray2(array) { return Array.isArray(array) || ArrayBuffer.isView(array) && !(array instanceof DataView); } var GL_PARAMETER_SETTERS = { [3042]: enable, [32773]: (gl, value) => gl.blendColor(...value), [32777]: "blendEquation", [34877]: "blendEquation", [32969]: "blendFunc", [32968]: "blendFunc", [32971]: "blendFunc", [32970]: "blendFunc", [3106]: (gl, value) => gl.clearColor(...value), [3107]: (gl, value) => gl.colorMask(...value), [2884]: enable, [2885]: (gl, value) => gl.cullFace(value), [2929]: enable, [2931]: (gl, value) => gl.clearDepth(value), [2932]: (gl, value) => gl.depthFunc(value), [2928]: (gl, value) => gl.depthRange(...value), [2930]: (gl, value) => gl.depthMask(value), [3024]: enable, [35723]: hint, [35725]: (gl, value) => gl.useProgram(value), [36007]: (gl, value) => gl.bindRenderbuffer(36161, value), [36389]: (gl, value) => gl.bindTransformFeedback?.(36386, value), [34229]: (gl, value) => gl.bindVertexArray(value), [36006]: bindFramebuffer, [36010]: bindFramebuffer, [34964]: bindBuffer, [36662]: bindBuffer, [36663]: bindBuffer, [35053]: bindBuffer, [35055]: bindBuffer, [2886]: (gl, value) => gl.frontFace(value), [33170]: hint, [2849]: (gl, value) => gl.lineWidth(value), [32823]: enable, [32824]: "polygonOffset", [10752]: "polygonOffset", [35977]: enable, [32926]: enable, [32928]: enable, [32938]: "sampleCoverage", [32939]: "sampleCoverage", [3089]: enable, [3088]: (gl, value) => gl.scissor(...value), [2960]: enable, [2961]: (gl, value) => gl.clearStencil(value), [2968]: (gl, value) => gl.stencilMaskSeparate(1028, value), [36005]: (gl, value) => gl.stencilMaskSeparate(1029, value), [2962]: "stencilFuncFront", [2967]: "stencilFuncFront", [2963]: "stencilFuncFront", [34816]: "stencilFuncBack", [36003]: "stencilFuncBack", [36004]: "stencilFuncBack", [2964]: "stencilOpFront", [2965]: "stencilOpFront", [2966]: "stencilOpFront", [34817]: "stencilOpBack", [34818]: "stencilOpBack", [34819]: "stencilOpBack", [2978]: (gl, value) => gl.viewport(...value), [34383]: enable, [10754]: enable, [12288]: enable, [12289]: enable, [12290]: enable, [12291]: enable, [12292]: enable, [12293]: enable, [12294]: enable, [12295]: enable, [3333]: pixelStorei, [3317]: pixelStorei, [37440]: pixelStorei, [37441]: pixelStorei, [37443]: pixelStorei, [3330]: pixelStorei, [3332]: pixelStorei, [3331]: pixelStorei, [3314]: pixelStorei, [32878]: pixelStorei, [3316]: pixelStorei, [3315]: pixelStorei, [32877]: pixelStorei, framebuffer: (gl, framebuffer) => { const handle = framebuffer && "handle" in framebuffer ? framebuffer.handle : framebuffer; return gl.bindFramebuffer(36160, handle); }, blend: (gl, value) => value ? gl.enable(3042) : gl.disable(3042), blendColor: (gl, value) => gl.blendColor(...value), blendEquation: (gl, args) => { const separateModes = typeof args === "number" ? [args, args] : args; gl.blendEquationSeparate(...separateModes); }, blendFunc: (gl, args) => { const separateFuncs = args?.length === 2 ? [...args, ...args] : args; gl.blendFuncSeparate(...separateFuncs); }, clearColor: (gl, value) => gl.clearColor(...value), clearDepth: (gl, value) => gl.clearDepth(value), clearStencil: (gl, value) => gl.clearStencil(value), colorMask: (gl, value) => gl.colorMask(...value), cull: (gl, value) => value ? gl.enable(2884) : gl.disable(2884), cullFace: (gl, value) => gl.cullFace(value), depthTest: (gl, value) => value ? gl.enable(2929) : gl.disable(2929), depthFunc: (gl, value) => gl.depthFunc(value), depthMask: (gl, value) => gl.depthMask(value), depthRange: (gl, value) => gl.depthRange(...value), dither: (gl, value) => value ? gl.enable(3024) : gl.disable(3024), derivativeHint: (gl, value) => { gl.hint(35723, value); }, frontFace: (gl, value) => gl.frontFace(value), mipmapHint: (gl, value) => gl.hint(33170, value), lineWidth: (gl, value) => gl.lineWidth(value), polygonOffsetFill: (gl, value) => value ? gl.enable(32823) : gl.disable(32823), polygonOffset: (gl, value) => gl.polygonOffset(...value), sampleCoverage: (gl, value) => gl.sampleCoverage(...value), scissorTest: (gl, value) => value ? gl.enable(3089) : gl.disable(3089), scissor: (gl, value) => gl.scissor(...value), stencilTest: (gl, value) => value ? gl.enable(2960) : gl.disable(2960), stencilMask: (gl, value) => { value = isArray2(value) ? value : [value, value]; const [mask, backMask] = value; gl.stencilMaskSeparate(1028, mask); gl.stencilMaskSeparate(1029, backMask); }, stencilFunc: (gl, args) => { args = isArray2(args) && args.length === 3 ? [...args, ...args] : args; const [func, ref, mask, backFunc, backRef, backMask] = args; gl.stencilFuncSeparate(1028, func, ref, mask); gl.stencilFuncSeparate(1029, backFunc, backRef, backMask); }, stencilOp: (gl, args) => { args = isArray2(args) && args.length === 3 ? [...args, ...args] : args; const [sfail, dpfail, dppass, backSfail, backDpfail, backDppass] = args; gl.stencilOpSeparate(1028, sfail, dpfail, dppass); gl.stencilOpSeparate(1029, backSfail, backDpfail, backDppass); }, viewport: (gl, value) => gl.viewport(...value) }; function getValue(glEnum, values, cache2) { return values[glEnum] !== void 0 ? values[glEnum] : cache2[glEnum]; } var GL_COMPOSITE_PARAMETER_SETTERS = { blendEquation: (gl, values, cache2) => gl.blendEquationSeparate(getValue(32777, values, cache2), getValue(34877, values, cache2)), blendFunc: (gl, values, cache2) => gl.blendFuncSeparate(getValue(32969, values, cache2), getValue(32968, values, cache2), getValue(32971, values, cache2), getValue(32970, values, cache2)), polygonOffset: (gl, values, cache2) => gl.polygonOffset(getValue(32824, values, cache2), getValue(10752, values, cache2)), sampleCoverage: (gl, values, cache2) => gl.sampleCoverage(getValue(32938, values, cache2), getValue(32939, values, cache2)), stencilFuncFront: (gl, values, cache2) => gl.stencilFuncSeparate(1028, getValue(2962, values, cache2), getValue(2967, values, cache2), getValue(2963, values, cache2)), stencilFuncBack: (gl, values, cache2) => gl.stencilFuncSeparate(1029, getValue(34816, values, cache2), getValue(36003, values, cache2), getValue(36004, values, cache2)), stencilOpFront: (gl, values, cache2) => gl.stencilOpSeparate(1028, getValue(2964, values, cache2), getValue(2965, values, cache2), getValue(2966, values, cache2)), stencilOpBack: (gl, values, cache2) => gl.stencilOpSeparate(1029, getValue(34817, values, cache2), getValue(34818, values, cache2), getValue(34819, values, cache2)) }; var GL_HOOKED_SETTERS = { enable: (update, capability) => update({ [capability]: true }), disable: (update, capability) => update({ [capability]: false }), pixelStorei: (update, pname, value) => update({ [pname]: value }), hint: (update, pname, hint2) => update({ [pname]: hint2 }), useProgram: (update, value) => update({ [35725]: value }), bindRenderbuffer: (update, target, value) => update({ [36007]: value }), bindTransformFeedback: (update, target, value) => update({ [36389]: value }), bindVertexArray: (update, value) => update({ [34229]: value }), bindFramebuffer: (update, target, framebuffer) => { switch (target) { case 36160: return update({ [36006]: framebuffer, [36010]: framebuffer }); case 36009: return update({ [36006]: framebuffer }); case 36008: return update({ [36010]: framebuffer }); default: return null; } }, bindBuffer: (update, target, buffer) => { const pname = { [34962]: [34964], [36662]: [36662], [36663]: [36663], [35051]: [35053], [35052]: [35055] }[target]; if (pname) { return update({ [pname]: buffer }); } return { valueChanged: true }; }, blendColor: (update, r, g, b, a) => update({ [32773]: new Float32Array([r, g, b, a]) }), blendEquation: (update, mode) => update({ [32777]: mode, [34877]: mode }), blendEquationSeparate: (update, modeRGB, modeAlpha) => update({ [32777]: modeRGB, [34877]: modeAlpha }), blendFunc: (update, src, dst) => update({ [32969]: src, [32968]: dst, [32971]: src, [32970]: dst }), blendFuncSeparate: (update, srcRGB, dstRGB, srcAlpha, dstAlpha) => update({ [32969]: srcRGB, [32968]: dstRGB, [32971]: srcAlpha, [32970]: dstAlpha }), clearColor: (update, r, g, b, a) => update({ [3106]: new Float32Array([r, g, b, a]) }), clearDepth: (update, depth) => update({ [2931]: depth }), clearStencil: (update, s) => update({ [2961]: s }), colorMask: (update, r, g, b, a) => update({ [3107]: [r, g, b, a] }), cullFace: (update, mode) => update({ [2885]: mode }), depthFunc: (update, func) => update({ [2932]: func }), depthRange: (update, zNear, zFar) => update({ [2928]: new Float32Array([zNear, zFar]) }), depthMask: (update, mask) => update({ [2930]: mask }), frontFace: (update, face) => update({ [2886]: face }), lineWidth: (update, width) => update({ [2849]: width }), polygonOffset: (update, factor, units) => update({ [32824]: factor, [10752]: units }), sampleCoverage: (update, value, invert2) => update({ [32938]: value, [32939]: invert2 }), scissor: (update, x, y, width, height) => update({ [3088]: new Int32Array([x, y, width, height]) }), stencilMask: (update, mask) => update({ [2968]: mask, [36005]: mask }), stencilMaskSeparate: (update, face, mask) => update({ [face === 1028 ? 2968 : 36005]: mask }), stencilFunc: (update, func, ref, mask) => update({ [2962]: func, [2967]: ref, [2963]: mask, [34816]: func, [36003]: ref, [36004]: mask }), stencilFuncSeparate: (update, face, func, ref, mask) => update({ [face === 1028 ? 2962 : 34816]: func, [face === 1028 ? 2967 : 36003]: ref, [face === 1028 ? 2963 : 36004]: mask }), stencilOp: (update, fail, zfail, zpass) => update({ [2964]: fail, [2965]: zfail, [2966]: zpass, [34817]: fail, [34818]: zfail, [34819]: zpass }), stencilOpSeparate: (update, face, fail, zfail, zpass) => update({ [face === 1028 ? 2964 : 34817]: fail, [face === 1028 ? 2965 : 34818]: zfail, [face === 1028 ? 2966 : 34819]: zpass }), viewport: (update, x, y, width, height) => update({ [2978]: [x, y, width, height] }) }; var isEnabled = (gl, key) => gl.isEnabled(key); var GL_PARAMETER_GETTERS = { [3042]: isEnabled, [2884]: isEnabled, [2929]: isEnabled, [3024]: isEnabled, [32823]: isEnabled, [32926]: isEnabled, [32928]: isEnabled, [3089]: isEnabled, [2960]: isEnabled, [35977]: isEnabled }; var NON_CACHE_PARAMETERS = /* @__PURE__ */ new Set([ 34016, 36388, 36387, 35983, 35368, 34965, 35739, 35738, 3074, 34853, 34854, 34855, 34856, 34857, 34858, 34859, 34860, 34861, 34862, 34863, 34864, 34865, 34866, 34867, 34868, 35097, 32873, 35869, 32874, 34068 ]); // ../../node_modules/@luma.gl/webgl/dist/context/parameters/unified-parameter-api.js function setGLParameters(gl, parameters) { if (isObjectEmpty2(parameters)) { return; } const compositeSetters = {}; for (const key in parameters) { const glConstant = Number(key); const setter = GL_PARAMETER_SETTERS[key]; if (setter) { if (typeof setter === "string") { compositeSetters[setter] = true; } else { setter(gl, parameters[key], glConstant); } } } const cache2 = gl.state && gl.state.cache; if (cache2) { for (const key in compositeSetters) { const compositeSetter = GL_COMPOSITE_PARAMETER_SETTERS[key]; compositeSetter(gl, parameters, cache2); } } } function getGLParameters(gl, parameters = GL_PARAMETER_DEFAULTS) { if (typeof parameters === "number") { const key = parameters; const getter = GL_PARAMETER_GETTERS[key]; return getter ? getter(gl, key) : gl.getParameter(key); } const parameterKeys = Array.isArray(parameters) ? parameters : Object.keys(parameters); const state = {}; for (const key of parameterKeys) { const getter = GL_PARAMETER_GETTERS[key]; state[key] = getter ? getter(gl, Number(key)) : gl.getParameter(Number(key)); } return state; } function resetGLParameters(gl) { setGLParameters(gl, GL_PARAMETER_DEFAULTS); } function isObjectEmpty2(object) { for (const key in object) { return false; } return true; } // ../../node_modules/@luma.gl/webgl/dist/context/state-tracker/deep-array-equal.js function deepArrayEqual(x, y) { if (x === y) { return true; } const isArrayX = Array.isArray(x) || ArrayBuffer.isView(x); const isArrayY = Array.isArray(y) || ArrayBuffer.isView(y); if (isArrayX && isArrayY && x.length === y.length) { for (let i = 0; i < x.length; ++i) { if (x[i] !== y[i]) { return false; } } return true; } return false; } // ../../node_modules/@luma.gl/webgl/dist/context/state-tracker/track-context-state.js var GLState = class { gl; program = null; stateStack = []; enable = true; cache; log; constructor(gl, { copyState = false, log: log3 = () => { } } = {}) { this.gl = gl; this.cache = copyState ? getGLParameters(gl) : Object.assign({}, GL_PARAMETER_DEFAULTS); this.log = log3; this._updateCache = this._updateCache.bind(this); Object.seal(this); } push(values = {}) { this.stateStack.push({}); } pop() { assert2(this.stateStack.length > 0); const oldValues = this.stateStack[this.stateStack.length - 1]; setGLParameters(this.gl, oldValues); this.stateStack.pop(); } _updateCache(values) { let valueChanged = false; let oldValue; const oldValues = this.stateStack.length > 0 ? this.stateStack[this.stateStack.length - 1] : null; for (const key in values) { assert2(key !== void 0); const value = values[key]; const cached = this.cache[key]; if (!deepArrayEqual(value, cached)) { valueChanged = true; oldValue = cached; if (oldValues && !(key in oldValues)) { oldValues[key] = cached; } this.cache[key] = value; } } return { valueChanged, oldValue }; } }; function getContextState(gl) { return gl.state; } function trackContextState(gl, options) { const { enable: enable2 = true, copyState } = options; assert2(copyState !== void 0); if (!gl.state) { gl.state = new GLState(gl, { copyState }); installProgramSpy(gl); for (const key in GL_HOOKED_SETTERS) { const setter = GL_HOOKED_SETTERS[key]; installSetterSpy(gl, key, setter); } installGetterOverride(gl, "getParameter"); installGetterOverride(gl, "isEnabled"); } const glState = getContextState(gl); glState.enable = enable2; return gl; } function pushContextState(gl) { let glState = getContextState(gl); if (!glState) { trackContextState(gl, { copyState: false }); glState = getContextState(gl); } glState.push(); } function popContextState(gl) { const glState = getContextState(gl); assert2(glState); glState.pop(); } function installGetterOverride(gl, functionName) { const originalGetterFunc = gl[functionName].bind(gl); gl[functionName] = function get(pname) { if (pname === void 0 || NON_CACHE_PARAMETERS.has(pname)) { return originalGetterFunc(pname); } const glState = getContextState(gl); if (!(pname in glState.cache)) { glState.cache[pname] = originalGetterFunc(pname); } return glState.enable ? glState.cache[pname] : originalGetterFunc(pname); }; Object.defineProperty(gl[functionName], "name", { value: `${functionName}-from-cache`, configurable: false }); } function installSetterSpy(gl, functionName, setter) { if (!gl[functionName]) { return; } const originalSetterFunc = gl[functionName].bind(gl); gl[functionName] = function set5(...params) { const glState = getContextState(gl); const { valueChanged, oldValue } = setter(glState._updateCache, ...params); if (valueChanged) { originalSetterFunc(...params); } return oldValue; }; Object.defineProperty(gl[functionName], "name", { value: `${functionName}-to-cache`, configurable: false }); } function installProgramSpy(gl) { const originalUseProgram = gl.useProgram.bind(gl); gl.useProgram = function useProgramLuma(handle) { const glState = getContextState(gl); if (glState.program !== handle) { originalUseProgram(handle); glState.program = handle; } }; } // ../../node_modules/@luma.gl/webgl/dist/context/helpers/create-browser-context.js var DEFAULT_CONTEXT_PROPS = { powerPreference: "high-performance", onContextLost: () => console.error("WebGL context lost"), onContextRestored: () => console.info("WebGL context restored") }; function createBrowserContext(canvas2, props) { props = { ...DEFAULT_CONTEXT_PROPS, ...props }; let errorMessage = null; const onCreateError = (error) => errorMessage = error.statusMessage || errorMessage; canvas2.addEventListener("webglcontextcreationerror", onCreateError, false); let gl = null; gl ||= canvas2.getContext("webgl2", props); canvas2.removeEventListener("webglcontextcreationerror", onCreateError, false); if (!gl) { throw new Error(`Failed to create WebGL context: ${errorMessage || "Unknown error"}`); } if (props.onContextLost) { const { onContextLost } = props; canvas2.addEventListener("webglcontextlost", (event) => onContextLost(event), false); } if (props.onContextRestored) { const { onContextRestored } = props; canvas2.addEventListener("webglcontextrestored", (event) => onContextRestored(event), false); } return gl; } // ../../node_modules/@luma.gl/webgl/dist/context/helpers/webgl-extensions.js function getWebGLExtension(gl, name2, extensions) { if (extensions[name2] === void 0) { extensions[name2] = gl.getExtension(name2) || null; } return extensions[name2]; } // ../../node_modules/@luma.gl/webgl/dist/adapter/device-helpers/webgl-device-info.js function getDeviceInfo(gl, extensions) { const vendorMasked = gl.getParameter(7936); const rendererMasked = gl.getParameter(7937); getWebGLExtension(gl, "WEBGL_debug_renderer_info", extensions); const ext = extensions.WEBGL_debug_renderer_info; const vendorUnmasked = gl.getParameter(ext ? ext.UNMASKED_VENDOR_WEBGL : 7936); const rendererUnmasked = gl.getParameter(ext ? ext.UNMASKED_RENDERER_WEBGL : 7937); const vendor = vendorUnmasked || vendorMasked; const renderer = rendererUnmasked || rendererMasked; const version = gl.getParameter(7938); const gpu = identifyGPUVendor(vendor, renderer); const gpuBackend = identifyGPUBackend(vendor, renderer); const gpuType = identifyGPUType(vendor, renderer); const shadingLanguage = "glsl"; const shadingLanguageVersion = 300; return { type: "webgl", gpu, gpuType, gpuBackend, vendor, renderer, version, shadingLanguage, shadingLanguageVersion }; } function identifyGPUVendor(vendor, renderer) { if (/NVIDIA/i.exec(vendor) || /NVIDIA/i.exec(renderer)) { return "nvidia"; } if (/INTEL/i.exec(vendor) || /INTEL/i.exec(renderer)) { return "intel"; } if (/Apple/i.exec(vendor) || /Apple/i.exec(renderer)) { return "apple"; } if (/AMD/i.exec(vendor) || /AMD/i.exec(renderer) || /ATI/i.exec(vendor) || /ATI/i.exec(renderer)) { return "amd"; } if (/SwiftShader/i.exec(vendor) || /SwiftShader/i.exec(renderer)) { return "software"; } return "unknown"; } function identifyGPUBackend(vendor, renderer) { if (/Metal/i.exec(vendor) || /Metal/i.exec(renderer)) { return "metal"; } if (/ANGLE/i.exec(vendor) || /ANGLE/i.exec(renderer)) { return "opengl"; } return "unknown"; } function identifyGPUType(vendor, renderer) { if (/SwiftShader/i.exec(vendor) || /SwiftShader/i.exec(renderer)) { return "cpu"; } const gpuVendor = identifyGPUVendor(vendor, renderer); switch (gpuVendor) { case "intel": return "integrated"; case "software": return "cpu"; case "unknown": return "unknown"; default: return "discrete"; } } // ../../node_modules/@luma.gl/webgl/dist/adapter/converters/vertex-formats.js function getGLFromVertexType(dataType) { switch (dataType) { case "uint8": return 5121; case "sint8": return 5120; case "unorm8": return 5121; case "snorm8": return 5120; case "uint16": return 5123; case "sint16": return 5122; case "unorm16": return 5123; case "snorm16": return 5122; case "uint32": return 5125; case "sint32": return 5124; case "float16": return 5131; case "float32": return 5126; } throw new Error(String(dataType)); } // ../../node_modules/@luma.gl/webgl/dist/adapter/converters/texture-formats.js var texture_compression_bc = "texture-compression-bc"; var texture_compression_astc = "texture-compression-astc"; var texture_compression_etc2 = "texture-compression-etc2"; var texture_compression_etc1_webgl = "texture-compression-etc1-webgl"; var texture_compression_pvrtc_webgl = "texture-compression-pvrtc-webgl"; var texture_compression_atc_webgl = "texture-compression-atc-webgl"; var float32_renderable = "float32-renderable-webgl"; var float16_renderable = "float16-renderable-webgl"; var rgb9e5ufloat_renderable = "rgb9e5ufloat_renderable-webgl"; var snorm8_renderable = "snorm8-renderable-webgl"; var norm16_renderable = "norm16-renderable-webgl"; var snorm16_renderable = "snorm16-renderable-webgl"; var float32_filterable = "float32-filterable"; var float16_filterable = "float16-filterable-webgl"; var X_S3TC = "WEBGL_compressed_texture_s3tc"; var X_S3TC_SRGB = "WEBGL_compressed_texture_s3tc_srgb"; var X_RGTC = "EXT_texture_compression_rgtc"; var X_BPTC = "EXT_texture_compression_bptc"; var X_ETC2 = "WEBGL_compressed_texture_etc"; var X_ASTC = "WEBGL_compressed_texture_astc"; var X_ETC1 = "WEBGL_compressed_texture_etc1"; var X_PVRTC = "WEBGL_compressed_texture_pvrtc"; var X_ATC = "WEBGL_compressed_texture_atc"; var EXT_texture_norm16 = "EXT_texture_norm16"; var EXT_render_snorm = "EXT_render_snorm"; var EXT_color_buffer_float = "EXT_color_buffer_float"; var TEXTURE_FEATURES = { "float32-renderable-webgl": ["EXT_color_buffer_float"], "float16-renderable-webgl": ["EXT_color_buffer_half_float"], "rgb9e5ufloat_renderable-webgl": ["WEBGL_render_shared_exponent"], "snorm8-renderable-webgl": [EXT_render_snorm], "norm16-renderable-webgl": [EXT_texture_norm16], "snorm16-renderable-webgl": [EXT_texture_norm16, EXT_render_snorm], "float32-filterable": ["OES_texture_float_linear"], "float16-filterable-webgl": ["OES_texture_half_float_linear"], "texture-filterable-anisotropic-webgl": ["EXT_texture_filter_anisotropic"], "texture-blend-float-webgl": ["EXT_float_blend"], "texture-compression-bc": [X_S3TC, X_S3TC_SRGB, X_RGTC, X_BPTC], "texture-compression-bc5-webgl": [X_RGTC], "texture-compression-bc7-webgl": [X_BPTC], "texture-compression-etc2": [X_ETC2], "texture-compression-astc": [X_ASTC], "texture-compression-etc1-webgl": [X_ETC1], "texture-compression-pvrtc-webgl": [X_PVRTC], "texture-compression-atc-webgl": [X_ATC] }; function isTextureFeature(feature) { return feature in TEXTURE_FEATURES; } function checkTextureFeature(gl, feature, extensions) { const textureExtensions = TEXTURE_FEATURES[feature] || []; return textureExtensions.every((extension) => getWebGLExtension(gl, extension, extensions)); } var TEXTURE_FORMATS = { "rgb8unorm-unsized": { gl: 6407, b: 4, c: 2, bpp: 4, dataFormat: 6407, types: [5121, 33635] }, "rgba8unorm-unsized": { gl: 6408, b: 4, c: 2, bpp: 4, dataFormat: 6408, types: [5121, 32819, 32820] }, "r8unorm": { gl: 33321, b: 1, c: 1, rb: true }, "r8snorm": { gl: 36756, b: 1, c: 1, render: snorm8_renderable }, "r8uint": { gl: 33330, b: 1, c: 1, rb: true }, "r8sint": { gl: 33329, b: 1, c: 1, rb: true }, "rg8unorm": { gl: 33323, b: 2, c: 2, rb: true }, "rg8snorm": { gl: 36757, b: 2, c: 2, render: snorm8_renderable }, "rg8uint": { gl: 33336, b: 2, c: 2, rb: true }, "rg8sint": { gl: 33335, b: 2, c: 2, rb: true }, "r16uint": { gl: 33332, b: 2, c: 1, rb: true }, "r16sint": { gl: 33331, b: 2, c: 1, rb: true }, "r16float": { gl: 33325, b: 2, c: 1, render: float16_renderable, filter: "float16-filterable-webgl", rb: true }, "r16unorm-webgl": { gl: 33322, b: 2, c: 1, f: norm16_renderable, rb: true }, "r16snorm-webgl": { gl: 36760, b: 2, c: 1, f: snorm16_renderable }, "rgba4unorm-webgl": { gl: 32854, b: 2, c: 4, wgpu: false, rb: true }, "rgb565unorm-webgl": { gl: 36194, b: 2, c: 4, wgpu: false, rb: true }, "rgb5a1unorm-webgl": { gl: 32855, b: 2, c: 4, wgpu: false, rb: true }, "rgb8unorm-webgl": { gl: 32849, b: 3, c: 3, wgpu: false }, "rgb8snorm-webgl": { gl: 36758, b: 3, c: 3, wgpu: false }, "rgba8unorm": { gl: 32856, b: 4, c: 2, bpp: 4 }, "rgba8unorm-srgb": { gl: 35907, b: 4, c: 4, bpp: 4 }, "rgba8snorm": { gl: 36759, b: 4, c: 4, render: snorm8_renderable }, "rgba8uint": { gl: 36220, b: 4, c: 4, bpp: 4 }, "rgba8sint": { gl: 36238, b: 4, c: 4, bpp: 4 }, "bgra8unorm": { b: 4, c: 4 }, "bgra8unorm-srgb": { b: 4, c: 4 }, "rg16uint": { gl: 33338, b: 4, c: 1, bpp: 4 }, "rg16sint": { gl: 33337, b: 4, c: 2, bpp: 4 }, "rg16float": { gl: 33327, bpp: 4, b: 4, c: 2, render: float16_renderable, filter: float16_filterable, rb: true }, "rg16unorm-webgl": { gl: 33324, b: 2, c: 2, render: norm16_renderable }, "rg16snorm-webgl": { gl: 36761, b: 2, c: 2, render: snorm16_renderable }, "r32uint": { gl: 33334, b: 4, c: 1, bpp: 4, rb: true }, "r32sint": { gl: 33333, b: 4, c: 1, bpp: 4, rb: true }, "r32float": { gl: 33326, bpp: 4, b: 4, c: 1, render: float32_renderable, filter: float32_filterable }, "rgb9e5ufloat": { gl: 35901, b: 4, c: 3, p: 1, render: rgb9e5ufloat_renderable }, "rg11b10ufloat": { gl: 35898, b: 4, c: 3, p: 1, render: float32_renderable, rb: true }, "rgb10a2unorm": { gl: 32857, b: 4, c: 4, p: 1, rb: true }, "rgb10a2uint-webgl": { b: 4, c: 4, gl: 36975, p: 1, wgpu: false, bpp: 4, rb: true }, "rgb16unorm-webgl": { gl: 32852, b: 2, c: 3, f: norm16_renderable }, "rgb16snorm-webgl": { gl: 36762, b: 2, c: 3, f: norm16_renderable }, "rg32uint": { gl: 33340, b: 8, c: 2, rb: true }, "rg32sint": { gl: 33339, b: 8, c: 2, rb: true }, "rg32float": { gl: 33328, b: 8, c: 2, render: float32_renderable, filter: float32_filterable, rb: true }, "rgba16uint": { gl: 36214, b: 8, c: 4, rb: true }, "rgba16sint": { gl: 36232, b: 8, c: 4, rb: true }, "rgba16float": { gl: 34842, b: 8, c: 4, render: float16_renderable, filter: float16_filterable }, "rgba16unorm-webgl": { gl: 32859, b: 2, c: 4, render: norm16_renderable, rb: true }, "rgba16snorm-webgl": { gl: 36763, b: 2, c: 4, render: snorm16_renderable }, "rgb32float-webgl": { gl: 34837, render: float32_renderable, filter: float32_filterable, gl2ext: EXT_color_buffer_float, dataFormat: 6407, types: [5126] }, "rgba32uint": { gl: 36208, b: 16, c: 4, rb: true }, "rgba32sint": { gl: 36226, b: 16, c: 4, rb: true }, "rgba32float": { gl: 34836, b: 16, c: 4, render: float32_renderable, filter: float32_filterable, rb: true }, "stencil8": { gl: 36168, b: 1, c: 1, attachment: 36128, rb: true }, "depth16unorm": { gl: 33189, b: 2, c: 1, attachment: 36096, dataFormat: 6402, types: [5123], rb: true }, "depth24plus": { gl: 33190, b: 3, c: 1, attachment: 36096, dataFormat: 6402, types: [5125] }, "depth32float": { gl: 36012, b: 4, c: 1, attachment: 36096, dataFormat: 6402, types: [5126], rb: true }, "depth24plus-stencil8": { gl: 35056, b: 4, c: 2, p: 1, attachment: 33306, rb: true, depthTexture: true, dataFormat: 34041, types: [34042] }, "depth24unorm-stencil8": { gl: 35056, b: 4, c: 2, p: 1, attachment: 33306, dataFormat: 34041, types: [34042], rb: true }, "depth32float-stencil8": { gl: 36013, b: 5, c: 2, p: 1, attachment: 33306, dataFormat: 34041, types: [36269], rb: true }, "bc1-rgb-unorm-webgl": { gl: 33776, x: X_S3TC, f: texture_compression_bc }, "bc1-rgb-unorm-srgb-webgl": { gl: 35916, x: X_S3TC_SRGB, f: texture_compression_bc }, "bc1-rgba-unorm": { gl: 33777, x: X_S3TC, f: texture_compression_bc }, "bc1-rgba-unorm-srgb": { gl: 35916, x: X_S3TC_SRGB, f: texture_compression_bc }, "bc2-rgba-unorm": { gl: 33778, x: X_S3TC, f: texture_compression_bc }, "bc2-rgba-unorm-srgb": { gl: 35918, x: X_S3TC_SRGB, f: texture_compression_bc }, "bc3-rgba-unorm": { gl: 33779, x: X_S3TC, f: texture_compression_bc }, "bc3-rgba-unorm-srgb": { gl: 35919, x: X_S3TC_SRGB, f: texture_compression_bc }, "bc4-r-unorm": { gl: 36283, x: X_RGTC, f: texture_compression_bc }, "bc4-r-snorm": { gl: 36284, x: X_RGTC, f: texture_compression_bc }, "bc5-rg-unorm": { gl: 36285, x: X_RGTC, f: texture_compression_bc }, "bc5-rg-snorm": { gl: 36286, x: X_RGTC, f: texture_compression_bc }, "bc6h-rgb-ufloat": { gl: 36495, x: X_BPTC, f: texture_compression_bc }, "bc6h-rgb-float": { gl: 36494, x: X_BPTC, f: texture_compression_bc }, "bc7-rgba-unorm": { gl: 36492, x: X_BPTC, f: texture_compression_bc }, "bc7-rgba-unorm-srgb": { gl: 36493, x: X_BPTC, f: texture_compression_bc }, "etc2-rgb8unorm": { gl: 37492, f: texture_compression_etc2 }, "etc2-rgb8unorm-srgb": { gl: 37494, f: texture_compression_etc2 }, "etc2-rgb8a1unorm": { gl: 37496, f: texture_compression_etc2 }, "etc2-rgb8a1unorm-srgb": { gl: 37497, f: texture_compression_etc2 }, "etc2-rgba8unorm": { gl: 37493, f: texture_compression_etc2 }, "etc2-rgba8unorm-srgb": { gl: 37495, f: texture_compression_etc2 }, "eac-r11unorm": { gl: 37488, f: texture_compression_etc2 }, "eac-r11snorm": { gl: 37489, f: texture_compression_etc2 }, "eac-rg11unorm": { gl: 37490, f: texture_compression_etc2 }, "eac-rg11snorm": { gl: 37491, f: texture_compression_etc2 }, "astc-4x4-unorm": { gl: 37808, f: texture_compression_astc }, "astc-4x4-unorm-srgb": { gl: 37840, f: texture_compression_astc }, "astc-5x4-unorm": { gl: 37809, f: texture_compression_astc }, "astc-5x4-unorm-srgb": { gl: 37841, f: texture_compression_astc }, "astc-5x5-unorm": { gl: 37810, f: texture_compression_astc }, "astc-5x5-unorm-srgb": { gl: 37842, f: texture_compression_astc }, "astc-6x5-unorm": { gl: 37811, f: texture_compression_astc }, "astc-6x5-unorm-srgb": { gl: 37843, f: texture_compression_astc }, "astc-6x6-unorm": { gl: 37812, f: texture_compression_astc }, "astc-6x6-unorm-srgb": { gl: 37844, f: texture_compression_astc }, "astc-8x5-unorm": { gl: 37813, f: texture_compression_astc }, "astc-8x5-unorm-srgb": { gl: 37845, f: texture_compression_astc }, "astc-8x6-unorm": { gl: 37814, f: texture_compression_astc }, "astc-8x6-unorm-srgb": { gl: 37846, f: texture_compression_astc }, "astc-8x8-unorm": { gl: 37815, f: texture_compression_astc }, "astc-8x8-unorm-srgb": { gl: 37847, f: texture_compression_astc }, "astc-10x5-unorm": { gl: 37819, f: texture_compression_astc }, "astc-10x5-unorm-srgb": { gl: 37851, f: texture_compression_astc }, "astc-10x6-unorm": { gl: 37817, f: texture_compression_astc }, "astc-10x6-unorm-srgb": { gl: 37849, f: texture_compression_astc }, "astc-10x8-unorm": { gl: 37818, f: texture_compression_astc }, "astc-10x8-unorm-srgb": { gl: 37850, f: texture_compression_astc }, "astc-10x10-unorm": { gl: 37819, f: texture_compression_astc }, "astc-10x10-unorm-srgb": { gl: 37851, f: texture_compression_astc }, "astc-12x10-unorm": { gl: 37820, f: texture_compression_astc }, "astc-12x10-unorm-srgb": { gl: 37852, f: texture_compression_astc }, "astc-12x12-unorm": { gl: 37821, f: texture_compression_astc }, "astc-12x12-unorm-srgb": { gl: 37853, f: texture_compression_astc }, "pvrtc-rgb4unorm-webgl": { gl: 35840, f: texture_compression_pvrtc_webgl }, "pvrtc-rgba4unorm-webgl": { gl: 35842, f: texture_compression_pvrtc_webgl }, "pvrtc-rbg2unorm-webgl": { gl: 35841, f: texture_compression_pvrtc_webgl }, "pvrtc-rgba2unorm-webgl": { gl: 35843, f: texture_compression_pvrtc_webgl }, "etc1-rbg-unorm-webgl": { gl: 36196, f: texture_compression_etc1_webgl }, "atc-rgb-unorm-webgl": { gl: 35986, f: texture_compression_atc_webgl }, "atc-rgba-unorm-webgl": { gl: 35986, f: texture_compression_atc_webgl }, "atc-rgbai-unorm-webgl": { gl: 34798, f: texture_compression_atc_webgl } }; var DATA_FORMAT_CHANNELS = { [6403]: 1, [36244]: 1, [33319]: 2, [33320]: 2, [6407]: 3, [36248]: 3, [6408]: 4, [36249]: 4, [6402]: 1, [34041]: 1, [6406]: 1, [6409]: 1, [6410]: 2 }; var TYPE_SIZES3 = { [5126]: 4, [5125]: 4, [5124]: 4, [5123]: 2, [5122]: 2, [5131]: 2, [5120]: 1, [5121]: 1 }; function isTextureFormatSupported(gl, format, extensions) { const info = TEXTURE_FORMATS[format]; if (!info) { return false; } if (info.gl === void 0) { return false; } const extension = info.x || info.gl2ext; if (extension) { return Boolean(getWebGLExtension(gl, extension, extensions)); } return true; } function convertTextureFormatToGL(format) { const formatInfo = TEXTURE_FORMATS[format]; const webglFormat = formatInfo?.gl; if (webglFormat === void 0) { throw new Error(`Unsupported texture format ${format}`); } return webglFormat; } function isTextureFormatFilterable(gl, format, extensions) { if (!isTextureFormatSupported(gl, format, extensions)) { return false; } if (format.startsWith("depth") || format.startsWith("stencil")) { return false; } try { const decoded = decodeTextureFormat(format); if (decoded.signed) { return false; } } catch { return false; } if (format.endsWith("32float")) { return Boolean(getWebGLExtension(gl, "OES_texture_float_linear, extensions", extensions)); } if (format.endsWith("16float")) { return Boolean(getWebGLExtension(gl, "OES_texture_half_float_linear, extensions", extensions)); } return true; } function isTextureFormatRenderable(gl, format, extensions) { if (!isTextureFormatSupported(gl, format, extensions)) { return false; } if (typeof format === "number") { return false; } return true; } function getWebGLTextureParameters(format) { const formatData = TEXTURE_FORMATS[format]; const webglFormat = convertTextureFormatToGL(format); const decoded = decodeTextureFormat(format); return { format: webglFormat, dataFormat: formatData?.dataFormat || getWebGLPixelDataFormat(decoded.format, decoded.integer, decoded.normalized, webglFormat), type: decoded.dataType ? getGLFromVertexType(decoded.dataType) : formatData?.types?.[0] || 5121, compressed: decoded.compressed }; } function getDepthStencilAttachmentWebGL(format) { const info = TEXTURE_FORMATS[format]; if (!info?.attachment) { throw new Error(`${format} is not a depth stencil format`); } return info.attachment; } function getTextureFormatBytesPerPixel(format) { const params = getWebGLTextureParameters(format); const channels = DATA_FORMAT_CHANNELS[params.dataFormat] || 4; const channelSize = TYPE_SIZES3[params.type] || 1; return channels * channelSize; } function getWebGLPixelDataFormat(dataFormat, integer, normalized, format) { if (format === 6408 || format === 6407) { return format; } switch (dataFormat) { case "r": return integer && !normalized ? 36244 : 6403; case "rg": return integer && !normalized ? 33320 : 33319; case "rgb": return integer && !normalized ? 36248 : 6407; case "rgba": return integer && !normalized ? 36249 : 6408; default: return 6408; } } // ../../node_modules/@luma.gl/webgl/dist/adapter/device-helpers/webgl-device-features.js var WEBGL_FEATURES = { "depth-clip-control": "EXT_depth_clamp", "timer-query-webgl": "EXT_disjoint_timer_query_webgl2", "compilation-status-async-webgl": "KHR_parallel_shader_compile", "polygon-mode-webgl": "WEBGL_polygon_mode", "provoking-vertex-webgl": "WEBGL_provoking_vertex", "shader-clip-cull-distance-webgl": "WEBGL_clip_cull_distance", "shader-noperspective-interpolation-webgl": "NV_shader_noperspective_interpolation", "shader-conservative-depth-webgl": "EXT_conservative_depth" }; var WebGLDeviceFeatures = class extends DeviceFeatures { gl; extensions; testedFeatures = /* @__PURE__ */ new Set(); constructor(gl, extensions, disabledFeatures) { super([], disabledFeatures); this.gl = gl; this.extensions = extensions; getWebGLExtension(gl, "EXT_color_buffer_float", extensions); } *[Symbol.iterator]() { const features = this.getFeatures(); for (const feature of features) { if (this.has(feature)) { yield feature; } } return []; } has(feature) { if (this.disabledFeatures[feature]) { return false; } if (!this.testedFeatures.has(feature)) { this.testedFeatures.add(feature); if (isTextureFeature(feature) && checkTextureFeature(this.gl, feature, this.extensions)) { this.features.add(feature); } if (this.getWebGLFeature(feature)) { this.features.add(feature); } } return this.features.has(feature); } initializeFeatures() { const features = this.getFeatures().filter((feature) => feature !== "polygon-mode-webgl"); for (const feature of features) { this.has(feature); } } getFeatures() { return [...Object.keys(WEBGL_FEATURES), ...Object.keys(TEXTURE_FEATURES)]; } getWebGLFeature(feature) { const featureInfo = WEBGL_FEATURES[feature]; const isSupported = typeof featureInfo === "string" ? Boolean(getWebGLExtension(this.gl, featureInfo, this.extensions)) : Boolean(featureInfo); return isSupported; } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/device-helpers/webgl-device-limits.js var WebGLDeviceLimits = class extends DeviceLimits { get maxTextureDimension1D() { return 0; } get maxTextureDimension2D() { return this.getParameter(3379); } get maxTextureDimension3D() { return this.getParameter(32883); } get maxTextureArrayLayers() { return this.getParameter(35071); } get maxBindGroups() { return 0; } get maxDynamicUniformBuffersPerPipelineLayout() { return 0; } get maxDynamicStorageBuffersPerPipelineLayout() { return 0; } get maxSampledTexturesPerShaderStage() { return this.getParameter(35660); } get maxSamplersPerShaderStage() { return this.getParameter(35661); } get maxStorageBuffersPerShaderStage() { return 0; } get maxStorageTexturesPerShaderStage() { return 0; } get maxUniformBuffersPerShaderStage() { return this.getParameter(35375); } get maxUniformBufferBindingSize() { return this.getParameter(35376); } get maxStorageBufferBindingSize() { return 0; } get minUniformBufferOffsetAlignment() { return this.getParameter(35380); } get minStorageBufferOffsetAlignment() { return 0; } get maxVertexBuffers() { return 16; } get maxVertexAttributes() { return this.getParameter(34921); } get maxVertexBufferArrayStride() { return 2048; } get maxInterStageShaderComponents() { return this.getParameter(35659); } get maxComputeWorkgroupStorageSize() { return 0; } get maxComputeInvocationsPerWorkgroup() { return 0; } get maxComputeWorkgroupSizeX() { return 0; } get maxComputeWorkgroupSizeY() { return 0; } get maxComputeWorkgroupSizeZ() { return 0; } get maxComputeWorkgroupsPerDimension() { return 0; } gl; limits = {}; constructor(gl) { super(); this.gl = gl; } getParameter(parameter) { if (this.limits[parameter] === void 0) { this.limits[parameter] = this.gl.getParameter(parameter); } return this.limits[parameter]; } }; // ../../node_modules/@luma.gl/webgl/dist/context/state-tracker/with-parameters.js function withGLParameters(gl, parameters, func) { if (isObjectEmpty3(parameters)) { return func(gl); } const { nocatch = true } = parameters; pushContextState(gl); setGLParameters(gl, parameters); let value; if (nocatch) { value = func(gl); popContextState(gl); } else { try { value = func(gl); } finally { popContextState(gl); } } return value; } function isObjectEmpty3(object) { for (const key in object) { return false; } return true; } // ../../node_modules/@luma.gl/webgl/dist/adapter/converters/device-parameters.js function withDeviceAndGLParameters(device, parameters, glParameters, func) { if (isObjectEmpty(parameters)) { return func(device); } const webglDevice = device; pushContextState(webglDevice.gl); try { setDeviceParameters(device, parameters); setGLParameters(webglDevice.gl, glParameters); return func(device); } finally { popContextState(webglDevice.gl); } } function setDeviceParameters(device, parameters) { const webglDevice = device; const { gl } = webglDevice; if (parameters.cullMode) { switch (parameters.cullMode) { case "none": gl.disable(2884); break; case "front": gl.enable(2884); gl.cullFace(1028); break; case "back": gl.enable(2884); gl.cullFace(1029); break; } } if (parameters.frontFace) { gl.frontFace(map2("frontFace", parameters.frontFace, { ccw: 2305, cw: 2304 })); } if (parameters.unclippedDepth) { if (device.features.has("depth-clip-control")) { gl.enable(34383); } } if (parameters.depthBias !== void 0) { gl.enable(32823); gl.polygonOffset(parameters.depthBias, parameters.depthBiasSlopeScale || 0); } if (parameters.provokingVertex) { if (device.features.has("provoking-vertex-webgl")) { const extensions = webglDevice.getExtension("WEBGL_provoking_vertex"); const ext = extensions.WEBGL_provoking_vertex; const vertex = map2("provokingVertex", parameters.provokingVertex, { first: 36429, last: 36430 }); ext?.provokingVertexWEBGL(vertex); } } if (parameters.polygonMode || parameters.polygonOffsetLine) { if (device.features.has("polygon-mode-webgl")) { if (parameters.polygonMode) { const extensions = webglDevice.getExtension("WEBGL_polygon_mode"); const ext = extensions.WEBGL_polygon_mode; const mode = map2("polygonMode", parameters.polygonMode, { fill: 6914, line: 6913 }); ext?.polygonModeWEBGL(1028, mode); ext?.polygonModeWEBGL(1029, mode); } if (parameters.polygonOffsetLine) { gl.enable(10754); } } } if (device.features.has("shader-clip-cull-distance-webgl")) { if (parameters.clipDistance0) { gl.enable(12288); } if (parameters.clipDistance1) { gl.enable(12289); } if (parameters.clipDistance2) { gl.enable(12290); } if (parameters.clipDistance3) { gl.enable(12291); } if (parameters.clipDistance4) { gl.enable(12292); } if (parameters.clipDistance5) { gl.enable(12293); } if (parameters.clipDistance6) { gl.enable(12294); } if (parameters.clipDistance7) { gl.enable(12295); } } if (parameters.depthWriteEnabled !== void 0) { gl.depthMask(mapBoolean("depthWriteEnabled", parameters.depthWriteEnabled)); } if (parameters.depthCompare) { parameters.depthCompare !== "always" ? gl.enable(2929) : gl.disable(2929); gl.depthFunc(convertCompareFunction("depthCompare", parameters.depthCompare)); } if (parameters.stencilWriteMask) { const mask = parameters.stencilWriteMask; gl.stencilMaskSeparate(1028, mask); gl.stencilMaskSeparate(1029, mask); } if (parameters.stencilReadMask) { log.warn("stencilReadMask not supported under WebGL"); } if (parameters.stencilCompare) { const mask = parameters.stencilReadMask || 4294967295; const glValue = convertCompareFunction("depthCompare", parameters.stencilCompare); parameters.stencilCompare !== "always" ? gl.enable(2960) : gl.disable(2960); gl.stencilFuncSeparate(1028, glValue, 0, mask); gl.stencilFuncSeparate(1029, glValue, 0, mask); } if (parameters.stencilPassOperation && parameters.stencilFailOperation && parameters.stencilDepthFailOperation) { const dppass = convertStencilOperation("stencilPassOperation", parameters.stencilPassOperation); const sfail = convertStencilOperation("stencilFailOperation", parameters.stencilFailOperation); const dpfail = convertStencilOperation("stencilDepthFailOperation", parameters.stencilDepthFailOperation); gl.stencilOpSeparate(1028, sfail, dpfail, dppass); gl.stencilOpSeparate(1029, sfail, dpfail, dppass); } if (parameters.blendColorOperation || parameters.blendAlphaOperation) { gl.enable(3042); const colorEquation = convertBlendOperationToEquation("blendColorOperation", parameters.blendColorOperation || "add"); const alphaEquation = convertBlendOperationToEquation("blendAlphaOperation", parameters.blendAlphaOperation || "add"); gl.blendEquationSeparate(colorEquation, alphaEquation); const colorSrcFactor = convertBlendFactorToFunction("blendColorSrcFactor", parameters.blendColorSrcFactor || "one"); const colorDstFactor = convertBlendFactorToFunction("blendColorDstFactor", parameters.blendColorDstFactor || "zero"); const alphaSrcFactor = convertBlendFactorToFunction("blendAlphaSrcFactor", parameters.blendAlphaSrcFactor || "one"); const alphaDstFactor = convertBlendFactorToFunction("blendAlphaDstFactor", parameters.blendAlphaDstFactor || "zero"); gl.blendFuncSeparate(colorSrcFactor, colorDstFactor, alphaSrcFactor, alphaDstFactor); } } function convertCompareFunction(parameter, value) { return map2(parameter, value, { never: 512, less: 513, equal: 514, "less-equal": 515, greater: 516, "not-equal": 517, "greater-equal": 518, always: 519 }); } function convertStencilOperation(parameter, value) { return map2(parameter, value, { keep: 7680, zero: 0, replace: 7681, invert: 5386, "increment-clamp": 7682, "decrement-clamp": 7683, "increment-wrap": 34055, "decrement-wrap": 34056 }); } function convertBlendOperationToEquation(parameter, value) { return map2(parameter, value, { add: 32774, subtract: 32778, "reverse-subtract": 32779, min: 32775, max: 32776 }); } function convertBlendFactorToFunction(parameter, value) { return map2(parameter, value, { one: 1, zero: 0, "src-color": 768, "one-minus-src-color": 769, "dst-color": 774, "one-minus-dst-color": 775, "src-alpha": 770, "one-minus-src-alpha": 771, "dst-alpha": 772, "one-minus-dst-alpha": 773, "src-alpha-saturated": 776, "constant-color": 32769, "one-minus-constant-color": 32770, "constant-alpha": 32771, "one-minus-constant-alpha": 32772 }); } function message(parameter, value) { return `Illegal parameter ${value} for ${parameter}`; } function map2(parameter, value, valueMap) { if (!(value in valueMap)) { throw new Error(message(parameter, value)); } return valueMap[value]; } function mapBoolean(parameter, value) { return value; } // ../../node_modules/@luma.gl/webgl/dist/adapter/converters/sampler-parameters.js function convertSamplerParametersToWebGL(props) { const params = {}; if (props.addressModeU) { params[10242] = convertAddressMode(props.addressModeU); } if (props.addressModeV) { params[10243] = convertAddressMode(props.addressModeV); } if (props.addressModeW) { params[32882] = convertAddressMode(props.addressModeW); } if (props.magFilter) { params[10240] = convertMaxFilterMode(props.magFilter); } if (props.minFilter || props.mipmapFilter) { params[10241] = convertMinFilterMode(props.minFilter || "linear", props.mipmapFilter); } if (props.lodMinClamp !== void 0) { params[33082] = props.lodMinClamp; } if (props.lodMaxClamp !== void 0) { params[33083] = props.lodMaxClamp; } if (props.type === "comparison-sampler") { params[34892] = 34894; } if (props.compare) { params[34893] = convertCompareFunction("compare", props.compare); } if (props.maxAnisotropy) { params[34046] = props.maxAnisotropy; } return params; } function convertAddressMode(addressMode) { switch (addressMode) { case "clamp-to-edge": return 33071; case "repeat": return 10497; case "mirror-repeat": return 33648; } } function convertMaxFilterMode(maxFilter) { switch (maxFilter) { case "nearest": return 9728; case "linear": return 9729; } } function convertMinFilterMode(minFilter, mipmapFilter) { if (!mipmapFilter) { return convertMaxFilterMode(minFilter); } switch (minFilter) { case "nearest": return mipmapFilter === "nearest" ? 9984 : 9986; case "linear": return mipmapFilter === "nearest" ? 9985 : 9987; } } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-buffer.js var WEBGLBuffer = class extends Buffer2 { device; gl; handle; glTarget; glUsage; glIndexType = 5123; byteLength; bytesUsed; constructor(device, props = {}) { super(device, props); this.device = device; this.gl = this.device.gl; const handle = typeof props === "object" ? props.handle : void 0; this.handle = handle || this.gl.createBuffer(); device.setSpectorMetadata(this.handle, { ...this.props, data: typeof this.props.data }); this.glTarget = getWebGLTarget(this.props.usage); this.glUsage = getWebGLUsage(this.props.usage); this.glIndexType = this.props.indexType === "uint32" ? 5125 : 5123; if (props.data) { this._initWithData(props.data, props.byteOffset, props.byteLength); } else { this._initWithByteLength(props.byteLength || 0); } } _initWithData(data, byteOffset = 0, byteLength = data.byteLength + byteOffset) { const glTarget = this.glTarget; this.gl.bindBuffer(glTarget, this.handle); this.gl.bufferData(glTarget, byteLength, this.glUsage); this.gl.bufferSubData(glTarget, byteOffset, data); this.gl.bindBuffer(glTarget, null); this.bytesUsed = byteLength; this.byteLength = byteLength; this._setDebugData(data, byteOffset, byteLength); this.trackAllocatedMemory(byteLength); } _initWithByteLength(byteLength) { assert2(byteLength >= 0); let data = byteLength; if (byteLength === 0) { data = new Float32Array(0); } const glTarget = this.glTarget; this.gl.bindBuffer(glTarget, this.handle); this.gl.bufferData(glTarget, data, this.glUsage); this.gl.bindBuffer(glTarget, null); this.bytesUsed = byteLength; this.byteLength = byteLength; this._setDebugData(null, 0, byteLength); this.trackAllocatedMemory(byteLength); return this; } destroy() { if (!this.destroyed && this.handle) { this.removeStats(); this.trackDeallocatedMemory(); this.gl.deleteBuffer(this.handle); this.destroyed = true; this.handle = null; } } write(data, byteOffset = 0) { const srcOffset = 0; const byteLength = void 0; const glTarget = 36663; this.gl.bindBuffer(glTarget, this.handle); if (srcOffset !== 0 || byteLength !== void 0) { this.gl.bufferSubData(glTarget, byteOffset, data, srcOffset, byteLength); } else { this.gl.bufferSubData(glTarget, byteOffset, data); } this.gl.bindBuffer(glTarget, null); this._setDebugData(data, byteOffset, data.byteLength); } async readAsync(byteOffset = 0, byteLength) { return this.readSyncWebGL(byteOffset, byteLength); } readSyncWebGL(byteOffset = 0, byteLength) { byteLength = byteLength ?? this.byteLength - byteOffset; const data = new Uint8Array(byteLength); const dstOffset = 0; this.gl.bindBuffer(36662, this.handle); this.gl.getBufferSubData(36662, byteOffset, data, dstOffset, byteLength); this.gl.bindBuffer(36662, null); this._setDebugData(data, byteOffset, byteLength); return data; } }; function getWebGLTarget(usage) { if (usage & Buffer2.INDEX) { return 34963; } if (usage & Buffer2.VERTEX) { return 34962; } if (usage & Buffer2.UNIFORM) { return 35345; } return 34962; } function getWebGLUsage(usage) { if (usage & Buffer2.INDEX) { return 35044; } if (usage & Buffer2.VERTEX) { return 35044; } if (usage & Buffer2.UNIFORM) { return 35048; } return 35044; } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-sampler.js var WEBGLSampler = class extends Sampler { device; handle; parameters; constructor(device, props) { super(device, props); this.device = device; this.parameters = convertSamplerParametersToWebGL(props); this.handle = this.handle || this.device.gl.createSampler(); this._setSamplerParameters(this.parameters); } destroy() { if (this.handle) { this.device.gl.deleteSampler(this.handle); this.handle = void 0; } } toString() { return `Sampler(${this.id},${JSON.stringify(this.props)})`; } _setSamplerParameters(parameters) { for (const [pname, value] of Object.entries(parameters)) { const param = Number(pname); switch (param) { case 33082: case 33083: this.device.gl.samplerParameterf(this.handle, param, value); break; default: this.device.gl.samplerParameteri(this.handle, param, value); break; } } } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-texture-view.js var WEBGLTextureView = class extends TextureView { device; gl; handle; texture; constructor(device, props) { super(device, { ...Texture.defaultProps, ...props }); this.device = device; this.gl = this.device.gl; this.handle = null; this.texture = props.texture; } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-texture.js var DEFAULT_WEBGL_TEXTURE_PROPS = { parameters: {}, pixelStore: {}, pixels: null, border: 0, dataFormat: void 0, textureUnit: void 0, target: void 0 }; var _WEBGLTexture = class extends Texture { MAX_ATTRIBUTES; device; gl; handle; sampler = void 0; view = void 0; glFormat = void 0; type = void 0; dataFormat = void 0; mipmaps = void 0; target; textureUnit = void 0; loaded = false; _video; constructor(device, props) { super(device, { ...DEFAULT_WEBGL_TEXTURE_PROPS, format: "rgba8unorm", ...props }); this.device = device; this.gl = this.device.gl; this.handle = this.props.handle || this.gl.createTexture(); this.device.setSpectorMetadata(this.handle, { ...this.props, data: typeof this.props.data }); this.glFormat = 6408; this.target = getWebGLTextureTarget(this.props); this.loaded = false; if (typeof this.props?.data === "string") { Object.assign(this.props, { data: loadImage(this.props.data) }); } this.initialize(this.props); Object.seal(this); } destroy() { if (this.handle) { this.gl.deleteTexture(this.handle); this.removeStats(); this.trackDeallocatedMemory("Texture"); this.destroyed = true; } } toString() { return `Texture(${this.id},${this.width}x${this.height})`; } createView(props) { return new WEBGLTextureView(this.device, { ...props, texture: this }); } initialize(props = {}) { if (this.props.dimension === "cube") { return this.initializeCube(props); } let data = props.data; if (data instanceof Promise) { data.then((resolvedImageData) => this.initialize(Object.assign({}, props, { pixels: resolvedImageData, data: resolvedImageData }))); return this; } const isVideo = typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement; if (isVideo && data.readyState < HTMLVideoElement.HAVE_METADATA) { this._video = null; data.addEventListener("loadeddata", () => this.initialize(props)); return this; } const { parameters = {} } = props; const { pixels = null, pixelStore = {}, textureUnit = void 0, mipmaps = true } = props; if (!data) { data = pixels; } let { width, height, dataFormat, type, compressed = false } = props; const { depth = 0 } = props; const glFormat = convertTextureFormatToGL(props.format); ({ width, height, compressed, dataFormat, type } = this._deduceParameters({ format: props.format, type, dataFormat, compressed, data, width, height })); this.width = width; this.height = height; this.glFormat = glFormat; this.type = type; this.dataFormat = dataFormat; this.textureUnit = textureUnit; if (Number.isFinite(this.textureUnit)) { this.gl.activeTexture(33984 + this.textureUnit); this.gl.bindTexture(this.target, this.handle); } this.mipmaps = mipmaps; this.setImageData({ data, width, height, depth, format: props.format, type, dataFormat, parameters: pixelStore, compressed }); this.setSampler(props.sampler); this._setSamplerParameters(parameters); this.view = this.createView({ ...this.props, mipLevelCount: 1, arrayLayerCount: 1 }); if (mipmaps && this.device.isTextureFormatFilterable(props.format)) { this.generateMipmap(); } if (isVideo) { this._video = { video: data, parameters, lastTime: data.readyState >= HTMLVideoElement.HAVE_CURRENT_DATA ? data.currentTime : -1 }; } return this; } initializeCube(props) { const { mipmaps = true, parameters = {} } = props; this.setCubeMapImageData(props).then(() => { this.loaded = true; if (mipmaps) { this.generateMipmap(props); } this.setSampler(props.sampler); this._setSamplerParameters(parameters); }); return this; } setSampler(sampler = {}) { let samplerProps; if (sampler instanceof WEBGLSampler) { this.sampler = sampler; samplerProps = sampler.props; } else { this.sampler = new WEBGLSampler(this.device, sampler); samplerProps = sampler; } const parameters = convertSamplerParametersToWebGL(samplerProps); this._setSamplerParameters(parameters); return this; } resize(options) { const { height, width, mipmaps = false } = options; if (width !== this.width || height !== this.height) { return this.initialize({ width, height, format: this.format, type: this.type, dataFormat: this.dataFormat, mipmaps }); } return this; } update() { if (this._video) { const { video, parameters, lastTime } = this._video; if (lastTime === video.currentTime || video.readyState < HTMLVideoElement.HAVE_CURRENT_DATA) { return; } this.setSubImageData({ data: video, parameters }); if (this.mipmaps) { this.generateMipmap(); } this._video.lastTime = video.currentTime; } } generateMipmap(params = {}) { this.mipmaps = true; this.gl.bindTexture(this.target, this.handle); withGLParameters(this.gl, params, () => { this.gl.generateMipmap(this.target); }); this.gl.bindTexture(this.target, null); return this; } setImageData(options) { if (this.props.dimension === "3d" || this.props.dimension === "2d-array") { return this.setImageData3D(options); } this.trackDeallocatedMemory("Texture"); const { target = this.target, pixels = null, level = 0, glFormat = this.glFormat, offset = 0, parameters = {} } = options; let { data = null, type = this.type, width = this.width, height = this.height, dataFormat = this.dataFormat, compressed = false } = options; if (!data) { data = pixels; } ({ type, dataFormat, compressed, width, height } = this._deduceParameters({ format: this.props.format, type, dataFormat, compressed, data, width, height })); const { gl } = this; gl.bindTexture(this.target, this.handle); let dataType = null; ({ data, dataType } = this._getDataType({ data, compressed })); withGLParameters(this.gl, parameters, () => { switch (dataType) { case "null": gl.texImage2D(target, level, glFormat, width, height, 0, dataFormat, type, data); break; case "typed-array": gl.texImage2D( target, level, glFormat, width, height, 0, dataFormat, type, data, offset ); break; case "buffer": this.device.gl.bindBuffer(35052, data.handle || data); this.device.gl.texImage2D(target, level, glFormat, width, height, 0, dataFormat, type, offset); this.device.gl.bindBuffer(35052, null); break; case "browser-object": gl.texImage2D(target, level, glFormat, width, height, 0, dataFormat, type, data); break; case "compressed": for (const [levelIndex, levelData] of data.entries()) { gl.compressedTexImage2D(target, levelIndex, levelData.format, levelData.width, levelData.height, 0, levelData.data); } break; default: assert2(false, "Unknown image data type"); } }); if (data && data.byteLength) { this.trackAllocatedMemory(data.byteLength, "Texture"); } else { const bytesPerPixel = getTextureFormatBytesPerPixel(this.props.format); this.trackAllocatedMemory(this.width * this.height * bytesPerPixel, "Texture"); } this.loaded = true; return this; } setSubImageData({ target = this.target, pixels = null, data = null, x = 0, y = 0, width = this.width, height = this.height, level = 0, glFormat = this.glFormat, type = this.type, dataFormat = this.dataFormat, compressed = false, offset = 0, parameters = {} }) { ({ type, dataFormat, compressed, width, height } = this._deduceParameters({ format: this.props.format, type, dataFormat, compressed, data, width, height })); assert2(this.depth === 1, "texSubImage not supported for 3D textures"); if (!data) { data = pixels; } if (data && data.data) { const ndarray = data; data = ndarray.data; width = ndarray.shape[0]; height = ndarray.shape[1]; } if (data instanceof WEBGLBuffer) { data = data.handle; } this.gl.bindTexture(this.target, this.handle); withGLParameters(this.gl, parameters, () => { if (compressed) { this.gl.compressedTexSubImage2D(target, level, x, y, width, height, glFormat, data); } else if (data === null) { this.gl.texSubImage2D(target, level, x, y, width, height, dataFormat, type, null); } else if (ArrayBuffer.isView(data)) { this.gl.texSubImage2D(target, level, x, y, width, height, dataFormat, type, data, offset); } else if (typeof WebGLBuffer !== "undefined" && data instanceof WebGLBuffer) { this.device.gl.bindBuffer(35052, data); this.device.gl.texSubImage2D(target, level, x, y, width, height, dataFormat, type, offset); this.device.gl.bindBuffer(35052, null); } else { this.device.gl.texSubImage2D(target, level, x, y, width, height, dataFormat, type, data); } }); this.gl.bindTexture(this.target, null); } copyFramebuffer(opts = {}) { log.error("Texture.copyFramebuffer({...}) is no logner supported, use copyToTexture(source, target, opts})")(); return null; } getActiveUnit() { return this.gl.getParameter(34016) - 33984; } bind(textureUnit = this.textureUnit) { const { gl } = this; if (textureUnit !== void 0) { this.textureUnit = textureUnit; gl.activeTexture(33984 + textureUnit); } gl.bindTexture(this.target, this.handle); return textureUnit; } unbind(textureUnit = this.textureUnit) { const { gl } = this; if (textureUnit !== void 0) { this.textureUnit = textureUnit; gl.activeTexture(33984 + textureUnit); } gl.bindTexture(this.target, null); return textureUnit; } _getDataType({ data, compressed = false }) { if (compressed) { return { data, dataType: "compressed" }; } if (data === null) { return { data, dataType: "null" }; } if (ArrayBuffer.isView(data)) { return { data, dataType: "typed-array" }; } if (data instanceof WEBGLBuffer) { return { data: data.handle, dataType: "buffer" }; } if (typeof WebGLBuffer !== "undefined" && data instanceof WebGLBuffer) { return { data, dataType: "buffer" }; } return { data, dataType: "browser-object" }; } _deduceParameters(opts) { const { format, data } = opts; let { width, height, dataFormat, type, compressed } = opts; const parameters = getWebGLTextureParameters(format); dataFormat = dataFormat || parameters.dataFormat; type = type || parameters.type; compressed = compressed || parameters.compressed; ({ width, height } = this._deduceImageSize(data, width, height)); return { dataFormat, type, compressed, width, height, format, data }; } _deduceImageSize(data, width, height) { let size; if (typeof ImageData !== "undefined" && data instanceof ImageData) { size = { width: data.width, height: data.height }; } else if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement) { size = { width: data.naturalWidth, height: data.naturalHeight }; } else if (typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement) { size = { width: data.width, height: data.height }; } else if (typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap) { size = { width: data.width, height: data.height }; } else if (typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement) { size = { width: data.videoWidth, height: data.videoHeight }; } else if (!data) { size = { width: width >= 0 ? width : 1, height: height >= 0 ? height : 1 }; } else { size = { width, height }; } assert2(size, "Could not deduced texture size"); assert2(width === void 0 || size.width === width, "Deduced texture width does not match supplied width"); assert2(height === void 0 || size.height === height, "Deduced texture height does not match supplied height"); return size; } async setCubeMapImageData(options) { const { gl } = this; const { width, height, pixels, data, format = 6408, type = 5121 } = options; const imageDataMap = pixels || data; const resolvedFaces = await Promise.all(_WEBGLTexture.FACES.map((face) => { const facePixels = imageDataMap[face]; return Promise.all(Array.isArray(facePixels) ? facePixels : [facePixels]); })); this.bind(); _WEBGLTexture.FACES.forEach((face, index2) => { if (resolvedFaces[index2].length > 1 && this.props.mipmaps !== false) { log.warn(`${this.id} has mipmap and multiple LODs.`)(); } resolvedFaces[index2].forEach((image, lodLevel) => { if (width && height) { gl.texImage2D(face, lodLevel, format, width, height, 0, format, type, image); } else { gl.texImage2D(face, lodLevel, format, format, type, image); } }); }); this.unbind(); } setImageDataForFace(options) { const { face, width, height, pixels, data, format = 6408, type = 5121 } = options; const { gl } = this; const imageData = pixels || data; this.bind(); if (imageData instanceof Promise) { imageData.then((resolvedImageData) => this.setImageDataForFace(Object.assign({}, options, { face, data: resolvedImageData, pixels: resolvedImageData }))); } else if (this.width || this.height) { gl.texImage2D(face, 0, format, width, height, 0, format, type, imageData); } else { gl.texImage2D(face, 0, format, format, type, imageData); } return this; } setImageData3D(options) { const { level = 0, dataFormat, format, type, width, height, depth = 1, offset = 0, data, parameters = {} } = options; this.trackDeallocatedMemory("Texture"); this.gl.bindTexture(this.target, this.handle); const webglTextureFormat = getWebGLTextureParameters(format); withGLParameters(this.gl, parameters, () => { if (ArrayBuffer.isView(data)) { this.gl.texImage3D( this.target, level, webglTextureFormat.format, width, height, depth, 0, webglTextureFormat.dataFormat, webglTextureFormat.type, data ); } if (data instanceof WEBGLBuffer) { this.gl.bindBuffer(35052, data.handle); this.gl.texImage3D(this.target, level, dataFormat, width, height, depth, 0, format, type, offset); } }); if (data && data.byteLength) { this.trackAllocatedMemory(data.byteLength, "Texture"); } else { const bytesPerPixel = getTextureFormatBytesPerPixel(this.props.format); this.trackAllocatedMemory(this.width * this.height * this.depth * bytesPerPixel, "Texture"); } this.loaded = true; return this; } _setSamplerParameters(parameters) { if (isObjectEmpty(parameters)) { return; } logParameters(parameters); this.gl.bindTexture(this.target, this.handle); for (const [pname, pvalue] of Object.entries(parameters)) { const param = Number(pname); const value = pvalue; switch (param) { case 33082: case 33083: this.gl.texParameterf(this.target, param, value); break; default: this.gl.texParameteri(this.target, param, value); break; } } this.gl.bindTexture(this.target, null); return; } }; var WEBGLTexture = _WEBGLTexture; __publicField(WEBGLTexture, "FACES", [ 34069, 34070, 34071, 34072, 34073, 34074 ]); function getWebGLTextureTarget(props) { switch (props.dimension) { case "2d": return 3553; case "cube": return 34067; case "2d-array": return 35866; case "3d": return 32879; case "1d": case "cube-array": default: throw new Error(props.dimension); } } function logParameters(parameters) { log.log(1, "texture sampler parameters", parameters)(); } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-framebuffer.js var WEBGLFramebuffer = class extends Framebuffer { device; gl; handle; get texture() { return this.colorAttachments[0]; } constructor(device, props) { super(device, props); const isDefaultFramebuffer = props.handle === null; this.device = device; this.gl = device.gl; this.handle = this.props.handle || isDefaultFramebuffer ? this.props.handle : this.gl.createFramebuffer(); if (!isDefaultFramebuffer) { device.setSpectorMetadata(this.handle, { id: this.props.id, props: this.props }); this.autoCreateAttachmentTextures(); const prevHandle = this.gl.bindFramebuffer(36160, this.handle); for (let i = 0; i < this.colorAttachments.length; ++i) { const attachment = this.colorAttachments[i]; const attachmentPoint = 36064 + i; if (attachment) { this._attachOne(attachmentPoint, attachment); } } if (this.depthStencilAttachment) { this._attachOne(getDepthStencilAttachmentWebGL(this.depthStencilAttachment.props.format), this.depthStencilAttachment); } if (props.check !== false) { const status = this.gl.checkFramebufferStatus(36160); if (status !== 36053) { throw new Error(`Framebuffer ${_getFrameBufferStatus(status)}`); } } this.gl.bindFramebuffer(36160, prevHandle); } } destroy() { super.destroy(); if (!this.destroyed && this.handle !== null) { this.gl.deleteFramebuffer(this.handle); } } createDepthStencilTexture(format) { return new WEBGLTexture(this.device, { id: `${this.id}-depth-stencil`, format, width: this.width, height: this.height, mipmaps: false }); } resizeAttachments(width, height) { if (this.handle === null) { this.width = this.gl.drawingBufferWidth; this.height = this.gl.drawingBufferHeight; return this; } if (width === void 0) { width = this.gl.drawingBufferWidth; } if (height === void 0) { height = this.gl.drawingBufferHeight; } for (const colorAttachment of this.colorAttachments) { colorAttachment.texture.resize({ width, height }); } if (this.depthStencilAttachment) { this.depthStencilAttachment.texture.resize({ width, height }); } return this; } _attachOne(attachmentPoint, attachment) { if (Array.isArray(attachment)) { const [texture, layer = 0, level = 0] = attachment; this._attachTexture(attachmentPoint, texture, layer, level); return texture; } if (attachment instanceof WEBGLTexture) { this._attachTexture(attachmentPoint, attachment, 0, 0); return attachment; } if (attachment instanceof WEBGLTextureView) { const textureView = attachment; this._attachTexture(attachmentPoint, textureView.texture, textureView.props.baseMipLevel, textureView.props.baseArrayLayer); return attachment.texture; } throw new Error("attach"); } _attachTexture(attachment, texture, layer, level) { const { gl } = this.device; gl.bindTexture(texture.target, texture.handle); switch (texture.target) { case 35866: case 32879: gl.framebufferTextureLayer(36160, attachment, texture.target, level, layer); break; case 34067: const face = mapIndexToCubeMapFace(layer); gl.framebufferTexture2D(36160, attachment, face, texture.handle, level); break; case 3553: gl.framebufferTexture2D(36160, attachment, 3553, texture.handle, level); break; default: assert2(false, "Illegal texture type"); } gl.bindTexture(texture.target, null); } }; function mapIndexToCubeMapFace(layer) { return layer < 34069 ? layer + 34069 : layer; } function _getFrameBufferStatus(status) { switch (status) { case 36053: return "success"; case 36054: return "Mismatched attachments"; case 36055: return "No attachments"; case 36057: return "Height/width mismatch"; case 36061: return "Unsupported or split attachments"; case 36182: return "Samples mismatch"; default: return `${status}`; } } // ../../node_modules/@luma.gl/webgl/dist/adapter/webgl-canvas-context.js var WebGLCanvasContext = class extends CanvasContext { device; presentationSize; _framebuffer = null; constructor(device, props) { super(props); this.device = device; this.presentationSize = [-1, -1]; this._setAutoCreatedCanvasId(`${this.device.id}-canvas`); this.update(); } getCurrentFramebuffer() { this.update(); this._framebuffer = this._framebuffer || new WEBGLFramebuffer(this.device, { handle: null }); return this._framebuffer; } update() { const size = this.getPixelSize(); const sizeChanged = size[0] !== this.presentationSize[0] || size[1] !== this.presentationSize[1]; if (sizeChanged) { this.presentationSize = size; this.resize(); } } resize(options) { if (!this.device.gl) return; if (this.canvas) { const devicePixelRatio = this.getDevicePixelRatio(options?.useDevicePixels); this.setDevicePixelRatio(devicePixelRatio, options); return; } } commit() { } }; // ../../node_modules/@luma.gl/webgl/dist/context/debug/spector.js var DEFAULT_SPECTOR_PROPS = { spector: log.get("spector") || log.get("spectorjs") }; var SPECTOR_CDN_URL = "https://cdn.jsdelivr.net/npm/spectorjs@0.9.30/dist/spector.bundle.js"; var LOG_LEVEL = 1; var spector = null; var initialized = false; async function loadSpectorJS(props) { if (!globalThis.SPECTOR) { try { await loadScript(SPECTOR_CDN_URL); } catch (error) { log.warn(String(error)); } } } function initializeSpectorJS(props) { props = { ...DEFAULT_SPECTOR_PROPS, ...props }; if (!props?.spector) { return null; } if (!spector && globalThis.SPECTOR) { log.probe(LOG_LEVEL, "SPECTOR found and initialized")(); spector = new globalThis.SPECTOR.Spector(); if (globalThis.luma) { globalThis.luma.spector = spector; } } if (!spector) { return null; } if (!initialized) { initialized = true; spector.spyCanvases(); spector?.onCaptureStarted.add((capture) => log.info("Spector capture started:", capture)()); spector?.onCapture.add((capture) => { log.info("Spector capture complete:", capture)(); spector?.getResultUI(); spector?.resultView.display(); spector?.resultView.addCapture(capture); }); } if (props?.canvas) { if (typeof props.spector === "string" && props.spector !== props.canvas.id) { return spector; } spector?.startCapture(props?.canvas, 500); new Promise((resolve2) => setTimeout(resolve2, 2e3)).then((_) => { log.info("Spector capture stopped after 2 seconds")(); spector?.stopCapture(); }); } return spector; } // ../../node_modules/@luma.gl/webgl/dist/context/debug/webgl-developer-tools.js var WEBGL_DEBUG_CDN_URL = "https://unpkg.com/webgl-debug@2.0.1/index.js"; function getWebGLContextData(gl) { gl.luma = gl.luma || {}; return gl.luma; } async function loadWebGLDeveloperTools() { if (isBrowser() && !globalThis.WebGLDebugUtils) { globalThis.global = globalThis.global || globalThis; globalThis.global.module = {}; await loadScript(WEBGL_DEBUG_CDN_URL); } } function makeDebugContext(gl, props = {}) { if (!gl) { return null; } return props.debug ? getDebugContext(gl, props) : getRealContext(gl); } function getRealContext(gl) { const data = getWebGLContextData(gl); return data.realContext ? data.realContext : gl; } function getDebugContext(gl, props) { if (!globalThis.WebGLDebugUtils) { log.warn("webgl-debug not loaded")(); return gl; } const data = getWebGLContextData(gl); if (data.debugContext) { return data.debugContext; } globalThis.WebGLDebugUtils.init({ ...GLEnum, ...gl }); const glDebug = globalThis.WebGLDebugUtils.makeDebugContext(gl, onGLError.bind(null, props), onValidateGLFunc.bind(null, props)); for (const key in GLEnum) { if (!(key in glDebug) && typeof GLEnum[key] === "number") { glDebug[key] = GLEnum[key]; } } class WebGLDebugContext { } Object.setPrototypeOf(glDebug, Object.getPrototypeOf(gl)); Object.setPrototypeOf(WebGLDebugContext, glDebug); const debugContext = Object.create(WebGLDebugContext); data.realContext = gl; data.debugContext = debugContext; debugContext.debug = true; return debugContext; } function getFunctionString(functionName, functionArgs) { functionArgs = Array.from(functionArgs).map((arg) => arg === void 0 ? "undefined" : arg); let args = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, functionArgs); args = `${args.slice(0, 100)}${args.length > 100 ? "..." : ""}`; return `gl.${functionName}(${args})`; } function onGLError(props, err, functionName, args) { args = Array.from(args).map((arg) => arg === void 0 ? "undefined" : arg); const errorMessage = globalThis.WebGLDebugUtils.glEnumToString(err); const functionArgs = globalThis.WebGLDebugUtils.glFunctionArgsToString(functionName, args); const message2 = `${errorMessage} in gl.${functionName}(${functionArgs})`; log.error(message2)(); debugger; if (props.throwOnError) { throw new Error(message2); } } function onValidateGLFunc(props, functionName, functionArgs) { let functionString = ""; if (log.level >= 1) { functionString = getFunctionString(functionName, functionArgs); log.log(1, functionString)(); } if (props.break && props.break.length > 0) { functionString = functionString || getFunctionString(functionName, functionArgs); const isBreakpoint = props.break.every((breakOn) => functionString.indexOf(breakOn) !== -1); if (isBreakpoint) { debugger; } } for (const arg of functionArgs) { if (arg === void 0) { functionString = functionString || getFunctionString(functionName, functionArgs); if (props.throwOnError) { throw new Error(`Undefined argument: ${functionString}`); } else { log.error(`Undefined argument: ${functionString}`)(); debugger; } } } } // ../../node_modules/@luma.gl/webgl/dist/adapter/helpers/parse-shader-compiler-log.js function parseShaderCompilerLog(errLog) { const lines = errLog.split(/\r?\n/); const messages = []; for (const line of lines) { if (line.length <= 1) { continue; } const segments = line.split(":"); if (segments.length === 2) { const [messageType2, message2] = segments; messages.push({ message: message2.trim(), type: getMessageType(messageType2), lineNum: 0, linePos: 0 }); continue; } const [messageType, linePosition, lineNumber, ...rest] = segments; let lineNum = parseInt(lineNumber, 10); if (isNaN(lineNum)) { lineNum = 0; } let linePos = parseInt(linePosition, 10); if (isNaN(linePos)) { linePos = 0; } messages.push({ message: rest.join(":").trim(), type: getMessageType(messageType), lineNum, linePos }); } return messages; } function getMessageType(messageType) { const MESSAGE_TYPES = ["warning", "error", "info"]; const lowerCaseType = messageType.toLowerCase(); return MESSAGE_TYPES.includes(lowerCaseType) ? lowerCaseType : "info"; } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-shader.js var WEBGLShader = class extends Shader { device; handle; constructor(device, props) { super(device, props); this.device = device; switch (this.props.stage) { case "vertex": this.handle = this.props.handle || this.device.gl.createShader(35633); break; case "fragment": this.handle = this.props.handle || this.device.gl.createShader(35632); break; default: throw new Error(this.props.stage); } this._compile(this.source); } destroy() { if (this.handle) { this.removeStats(); this.device.gl.deleteShader(this.handle); this.destroyed = true; } } async getCompilationInfo() { await this._waitForCompilationComplete(); return this.getCompilationInfoSync(); } getCompilationInfoSync() { const log3 = this.device.gl.getShaderInfoLog(this.handle); return parseShaderCompilerLog(log3); } getTranslatedSource() { const extensions = this.device.getExtension("WEBGL_debug_shaders"); const ext = extensions.WEBGL_debug_shaders; return ext?.getTranslatedShaderSource(this.handle); } async _compile(source) { const addGLSLVersion = (source2) => source2.startsWith("#version ") ? source2 : `#version 100 ${source2}`; source = addGLSLVersion(source); const { gl } = this.device; gl.shaderSource(this.handle, source); gl.compileShader(this.handle); if (log.level === 0) { this.compilationStatus = "pending"; return; } if (!this.device.features.has("compilation-status-async-webgl")) { this._getCompilationStatus(); this.debugShader(); if (this.compilationStatus === "error") { throw new Error(`GLSL compilation errors in ${this.props.stage} shader ${this.props.id}`); } return; } log.once(1, "Shader compilation is asynchronous")(); await this._waitForCompilationComplete(); log.info(2, `Shader ${this.id} - async compilation complete: ${this.compilationStatus}`)(); this._getCompilationStatus(); this.debugShader(); } async _waitForCompilationComplete() { const waitMs = async (ms) => await new Promise((resolve2) => setTimeout(resolve2, ms)); const DELAY_MS = 10; if (!this.device.features.has("compilation-status-async-webgl")) { await waitMs(DELAY_MS); return; } const { gl } = this.device; for (; ; ) { const complete = gl.getShaderParameter(this.handle, 37297); if (complete) { return; } await waitMs(DELAY_MS); } } _getCompilationStatus() { this.compilationStatus = this.device.gl.getShaderParameter(this.handle, 35713) ? "success" : "error"; } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-render-pass.js var GL_DEPTH_BUFFER_BIT = 256; var GL_STENCIL_BUFFER_BIT = 1024; var GL_COLOR_BUFFER_BIT = 16384; var GL_COLOR = 6144; var COLOR_CHANNELS = [1, 2, 4, 8]; var WEBGLRenderPass = class extends RenderPass { device; glParameters; constructor(device, props) { super(device, props); this.device = device; pushContextState(this.device.gl); this.setParameters(this.props.parameters); this.clear(); } end() { popContextState(this.device.gl); } pushDebugGroup(groupLabel) { } popDebugGroup() { } insertDebugMarker(markerLabel) { } setParameters(parameters = {}) { const glParameters = { ...this.glParameters }; if (this.props.framebuffer) { glParameters.framebuffer = this.props.framebuffer; } if (this.props.depthReadOnly) { glParameters.depthMask = !this.props.depthReadOnly; } glParameters.stencilMask = this.props.stencilReadOnly ? 0 : 1; glParameters[35977] = this.props.discard; if (parameters.viewport) { if (parameters.viewport.length >= 6) { glParameters.viewport = parameters.viewport.slice(0, 4); glParameters.depthRange = [parameters.viewport[4], parameters.viewport[5]]; } else { glParameters.viewport = parameters.viewport; } } if (parameters.scissorRect) { glParameters.scissorTest = true; glParameters.scissor = parameters.scissorRect; } if (parameters.blendConstant) { glParameters.blendColor = parameters.blendConstant; } if (parameters.stencilReference) { console.warn("RenderPassParameters.stencilReference not yet implemented in WebGL"); parameters[2967] = parameters.stencilReference; } if (parameters.colorMask) { glParameters.colorMask = COLOR_CHANNELS.map((channel) => Boolean(channel & parameters.colorMask)); } this.glParameters = glParameters; setGLParameters(this.device.gl, glParameters); } beginOcclusionQuery(queryIndex) { const webglQuerySet = this.props.occlusionQuerySet; webglQuerySet?.beginOcclusionQuery(); } endOcclusionQuery() { const webglQuerySet = this.props.occlusionQuerySet; webglQuerySet?.endOcclusionQuery(); } clear() { const glParameters = { ...this.glParameters }; let clearMask = 0; if (this.props.clearColor !== false) { clearMask |= GL_COLOR_BUFFER_BIT; glParameters.clearColor = this.props.clearColor; } if (this.props.clearDepth !== false) { clearMask |= GL_DEPTH_BUFFER_BIT; glParameters.clearDepth = this.props.clearDepth; } if (this.props.clearStencil !== false) { clearMask |= GL_STENCIL_BUFFER_BIT; glParameters.clearStencil = this.props.clearStencil; } if (clearMask !== 0) { withGLParameters(this.device.gl, glParameters, () => { this.device.gl.clear(clearMask); }); } } clearColorBuffer(drawBuffer = 0, value = [0, 0, 0, 0]) { withGLParameters(this.device.gl, { framebuffer: this.props.framebuffer }, () => { switch (value.constructor) { case Int32Array: this.device.gl.clearBufferiv(GL_COLOR, drawBuffer, value); break; case Uint32Array: this.device.gl.clearBufferuiv(GL_COLOR, drawBuffer, value); break; case Float32Array: default: this.device.gl.clearBufferfv(GL_COLOR, drawBuffer, value); break; } }); } }; // ../../node_modules/@luma.gl/webgl/dist/classic/typed-array-utils.js var ERR_TYPE_DEDUCTION = "Failed to deduce GL constant from typed array"; function getGLTypeFromTypedArray(arrayOrType) { const type = ArrayBuffer.isView(arrayOrType) ? arrayOrType.constructor : arrayOrType; switch (type) { case Float32Array: return 5126; case Uint16Array: return 5123; case Uint32Array: return 5125; case Uint8Array: return 5121; case Uint8ClampedArray: return 5121; case Int8Array: return 5120; case Int16Array: return 5122; case Int32Array: return 5124; default: throw new Error(ERR_TYPE_DEDUCTION); } } function getTypedArrayFromGLType(glType, options) { const { clamped = true } = options || {}; switch (glType) { case 5126: return Float32Array; case 5123: case 33635: case 32819: case 32820: return Uint16Array; case 5125: return Uint32Array; case 5121: return clamped ? Uint8ClampedArray : Uint8Array; case 5120: return Int8Array; case 5122: return Int16Array; case 5124: return Int32Array; default: throw new Error("Failed to deduce typed array type from GL constant"); } } // ../../node_modules/@luma.gl/webgl/dist/classic/accessor.js var DEFAULT_ACCESSOR_VALUES = { offset: 0, stride: 0, type: 5126, size: 1, divisor: 0, normalized: false, integer: false }; var PROP_CHECKS = { deprecatedProps: { instanced: "divisor", isInstanced: "divisor" } }; var Accessor = class { offset; stride; type; size; divisor; normalized; integer; buffer; index; static getBytesPerElement(accessor) { const ArrayType2 = getTypedArrayFromGLType(accessor.type || 5126); return ArrayType2.BYTES_PER_ELEMENT; } static getBytesPerVertex(accessor) { assert2(accessor.size); const ArrayType2 = getTypedArrayFromGLType(accessor.type || 5126); return ArrayType2.BYTES_PER_ELEMENT * accessor.size; } static resolve(...accessors) { return new Accessor(...[DEFAULT_ACCESSOR_VALUES, ...accessors]); } constructor(...accessors) { accessors.forEach((accessor) => this._assign(accessor)); Object.freeze(this); } toString() { return JSON.stringify(this); } get BYTES_PER_ELEMENT() { return Accessor.getBytesPerElement(this); } get BYTES_PER_VERTEX() { return Accessor.getBytesPerVertex(this); } _assign(props = {}) { props = checkProps("Accessor", props, PROP_CHECKS); if (props.type !== void 0) { this.type = props.type; if (props.type === 5124 || props.type === 5125) { this.integer = true; } } if (props.size !== void 0) { this.size = props.size; } if (props.offset !== void 0) { this.offset = props.offset; } if (props.stride !== void 0) { this.stride = props.stride; } if (props.normalize !== void 0) { this.normalized = props.normalize; } if (props.normalized !== void 0) { this.normalized = props.normalized; } if (props.integer !== void 0) { this.integer = props.integer; } if (props.divisor !== void 0) { this.divisor = props.divisor; } if (props.buffer !== void 0) { this.buffer = props.buffer; } if (props.index !== void 0) { if (typeof props.index === "boolean") { this.index = props.index ? 1 : 0; } else { this.index = props.index; } } if (props.instanced !== void 0) { this.divisor = props.instanced ? 1 : 0; } if (props.isInstanced !== void 0) { this.divisor = props.isInstanced ? 1 : 0; } if (this.offset === void 0) delete this.offset; if (this.stride === void 0) delete this.stride; if (this.type === void 0) delete this.type; if (this.size === void 0) delete this.size; if (this.divisor === void 0) delete this.divisor; if (this.normalized === void 0) delete this.normalized; if (this.integer === void 0) delete this.integer; if (this.buffer === void 0) delete this.buffer; if (this.index === void 0) delete this.index; return this; } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/helpers/decode-webgl-types.js function isSamplerUniform(type) { return SAMPLER_TYPES.includes(type); } var SAMPLER_TYPES = [ 35678, 35680, 35679, 35682, 36289, 36292, 36293, 36298, 36299, 36300, 36303, 36306, 36307, 36308, 36311 ]; var COMPOSITE_GL_TYPES = { [5126]: [5126, 1, "float", "f32", "float32"], [35664]: [5126, 2, "vec2", "vec2", "float32x2"], [35665]: [5126, 3, "vec3", "vec3", "float32x3"], [35666]: [5126, 4, "vec4", "vec4", "float32x4"], [5124]: [5124, 1, "int", "i32", "sint32"], [35667]: [5124, 2, "ivec2", "vec2", "sint32x2"], [35668]: [5124, 3, "ivec3", "vec3", "sint32x3"], [35669]: [5124, 4, "ivec4", "vec4", "sint32x4"], [5125]: [5125, 1, "uint", "u32", "uint32"], [36294]: [5125, 2, "uvec2", "vec2", "uint32x2"], [36295]: [5125, 3, "uvec3", "vec3", "uint32x3"], [36296]: [5125, 4, "uvec4", "vec4", "uint32x4"], [35670]: [5126, 1, "bool", "f32", "float32"], [35671]: [5126, 2, "bvec2", "vec2", "float32x2"], [35672]: [5126, 3, "bvec3", "vec3", "float32x3"], [35673]: [5126, 4, "bvec4", "vec4", "float32x4"], [35674]: [5126, 8, "mat2", "mat2x2"], [35685]: [5126, 8, "mat2x3", "mat2x3"], [35686]: [5126, 8, "mat2x4", "mat2x4"], [35687]: [5126, 12, "mat3x2", "mat3x2"], [35675]: [5126, 12, "mat3", "mat3x3"], [35688]: [5126, 12, "mat3x4", "mat3x4"], [35689]: [5126, 16, "mat4x2", "mat4x2"], [35690]: [5126, 16, "mat4x3", "mat4x3"], [35676]: [5126, 16, "mat4", "mat4x4"] }; function decodeGLUniformType(glUniformType) { const typeAndSize = COMPOSITE_GL_TYPES[glUniformType]; if (!typeAndSize) { throw new Error("uniform"); } const [glType, components, , format] = typeAndSize; return { format, components, glType }; } function decodeGLAttributeType(glAttributeType) { const typeAndSize = COMPOSITE_GL_TYPES[glAttributeType]; if (!typeAndSize) { throw new Error("attribute"); } const [, components, , shaderType, vertexFormat] = typeAndSize; const attributeType = shaderType; return { attributeType, vertexFormat, components }; } // ../../node_modules/@luma.gl/webgl/dist/adapter/helpers/get-shader-layout.js function getShaderLayout(gl, program) { const shaderLayout = { attributes: [], bindings: [] }; shaderLayout.attributes = readAttributeDeclarations(gl, program); const uniformBlocks = readUniformBlocks(gl, program); for (const uniformBlock of uniformBlocks) { const uniforms2 = uniformBlock.uniforms.map((uniform) => ({ name: uniform.name, format: uniform.format, byteOffset: uniform.byteOffset, byteStride: uniform.byteStride, arrayLength: uniform.arrayLength })); shaderLayout.bindings.push({ type: "uniform", name: uniformBlock.name, location: uniformBlock.location, visibility: (uniformBlock.vertex ? 1 : 0) & (uniformBlock.fragment ? 2 : 0), minBindingSize: uniformBlock.byteLength, uniforms: uniforms2 }); } const uniforms = readUniformBindings(gl, program); let textureUnit = 0; for (const uniform of uniforms) { if (isSamplerUniform(uniform.type)) { const { viewDimension, sampleType } = getSamplerInfo(uniform.type); shaderLayout.bindings.push({ type: "texture", name: uniform.name, location: textureUnit, viewDimension, sampleType }); uniform.textureUnit = textureUnit; textureUnit += 1; } } if (uniforms.length) { shaderLayout.uniforms = uniforms; } const varyings = readVaryings(gl, program); if (varyings?.length) { shaderLayout.varyings = varyings; } return shaderLayout; } function readAttributeDeclarations(gl, program) { const attributes = []; const count2 = gl.getProgramParameter(program, 35721); for (let index2 = 0; index2 < count2; index2++) { const activeInfo = gl.getActiveAttrib(program, index2); if (!activeInfo) { throw new Error("activeInfo"); } const { name: name2, type: compositeType } = activeInfo; const location = gl.getAttribLocation(program, name2); if (location >= 0) { const { attributeType } = decodeGLAttributeType(compositeType); const stepMode = /instance/i.test(name2) ? "instance" : "vertex"; attributes.push({ name: name2, location, stepMode, type: attributeType }); } } attributes.sort((a, b) => a.location - b.location); return attributes; } function readVaryings(gl, program) { const varyings = []; const count2 = gl.getProgramParameter(program, 35971); for (let location = 0; location < count2; location++) { const activeInfo = gl.getTransformFeedbackVarying(program, location); if (!activeInfo) { throw new Error("activeInfo"); } const { name: name2, type: compositeType, size } = activeInfo; const { glType, components } = decodeGLUniformType(compositeType); const accessor = new Accessor({ type: glType, size: size * components }); const varying = { location, name: name2, accessor }; varyings.push(varying); } varyings.sort((a, b) => a.location - b.location); return varyings; } function readUniformBindings(gl, program) { const uniforms = []; const uniformCount = gl.getProgramParameter(program, 35718); for (let i = 0; i < uniformCount; i++) { const activeInfo = gl.getActiveUniform(program, i); if (!activeInfo) { throw new Error("activeInfo"); } const { name: rawName, size, type } = activeInfo; const { name: name2, isArray: isArray4 } = parseUniformName(rawName); let webglLocation = gl.getUniformLocation(program, name2); const uniformInfo = { location: webglLocation, name: name2, size, type, isArray: isArray4 }; uniforms.push(uniformInfo); if (uniformInfo.size > 1) { for (let j = 0; j < uniformInfo.size; j++) { const elementName = `${name2}[${j}]`; webglLocation = gl.getUniformLocation(program, elementName); const arrayElementUniformInfo = { ...uniformInfo, name: elementName, location: webglLocation }; uniforms.push(arrayElementUniformInfo); } } } return uniforms; } function readUniformBlocks(gl, program) { const getBlockParameter = (blockIndex, pname) => gl.getActiveUniformBlockParameter(program, blockIndex, pname); const uniformBlocks = []; const blockCount = gl.getProgramParameter(program, 35382); for (let blockIndex = 0; blockIndex < blockCount; blockIndex++) { const blockInfo = { name: gl.getActiveUniformBlockName(program, blockIndex) || "", location: getBlockParameter(blockIndex, 35391), byteLength: getBlockParameter(blockIndex, 35392), vertex: getBlockParameter(blockIndex, 35396), fragment: getBlockParameter(blockIndex, 35398), uniformCount: getBlockParameter(blockIndex, 35394), uniforms: [] }; const uniformIndices = getBlockParameter(blockIndex, 35395) || []; const uniformType = gl.getActiveUniforms(program, uniformIndices, 35383); const uniformArrayLength = gl.getActiveUniforms(program, uniformIndices, 35384); const uniformOffset = gl.getActiveUniforms(program, uniformIndices, 35387); const uniformStride = gl.getActiveUniforms(program, uniformIndices, 35388); for (let i = 0; i < blockInfo.uniformCount; ++i) { const activeInfo = gl.getActiveUniform(program, uniformIndices[i]); if (!activeInfo) { throw new Error("activeInfo"); } blockInfo.uniforms.push({ name: activeInfo.name, format: decodeGLUniformType(uniformType[i]).format, type: uniformType[i], arrayLength: uniformArrayLength[i], byteOffset: uniformOffset[i], byteStride: uniformStride[i] }); } uniformBlocks.push(blockInfo); } uniformBlocks.sort((a, b) => a.location - b.location); return uniformBlocks; } var SAMPLER_UNIFORMS_GL_TO_GPU = { [35678]: ["2d", "float"], [35680]: ["cube", "float"], [35679]: ["3d", "float"], [35682]: ["3d", "depth"], [36289]: ["2d-array", "float"], [36292]: ["2d-array", "depth"], [36293]: ["cube", "float"], [36298]: ["2d", "sint"], [36299]: ["3d", "sint"], [36300]: ["cube", "sint"], [36303]: ["2d-array", "uint"], [36306]: ["2d", "uint"], [36307]: ["3d", "uint"], [36308]: ["cube", "uint"], [36311]: ["2d-array", "uint"] }; function getSamplerInfo(type) { const sampler = SAMPLER_UNIFORMS_GL_TO_GPU[type]; if (!sampler) { throw new Error("sampler"); } const [viewDimension, sampleType] = sampler; return { viewDimension, sampleType }; } function parseUniformName(name2) { if (name2[name2.length - 1] !== "]") { return { name: name2, length: 1, isArray: false }; } const UNIFORM_NAME_REGEXP = /([^[]*)(\[[0-9]+\])?/; const matches3 = UNIFORM_NAME_REGEXP.exec(name2); if (!matches3 || matches3.length < 2) { throw new Error(`Failed to parse GLSL uniform name ${name2}`); } return { name: matches3[1], length: matches3[2] ? 1 : 0, isArray: Boolean(matches3[2]) }; } // ../../node_modules/@luma.gl/webgl/dist/adapter/helpers/set-uniform.js function setUniform(gl, location, type, value) { const gl2 = gl; let uniformValue = value; if (uniformValue === true) { uniformValue = 1; } if (uniformValue === false) { uniformValue = 0; } const arrayValue = typeof uniformValue === "number" ? [uniformValue] : uniformValue; switch (type) { case 35678: case 35680: case 35679: case 35682: case 36289: case 36292: case 36293: case 36298: case 36299: case 36300: case 36303: case 36306: case 36307: case 36308: case 36311: if (typeof value !== "number") { throw new Error("samplers must be set to integers"); } return gl.uniform1i(location, value); case 5126: return gl.uniform1fv(location, arrayValue); case 35664: return gl.uniform2fv(location, arrayValue); case 35665: return gl.uniform3fv(location, arrayValue); case 35666: return gl.uniform4fv(location, arrayValue); case 5124: return gl.uniform1iv(location, arrayValue); case 35667: return gl.uniform2iv(location, arrayValue); case 35668: return gl.uniform3iv(location, arrayValue); case 35669: return gl.uniform4iv(location, arrayValue); case 35670: return gl.uniform1iv(location, arrayValue); case 35671: return gl.uniform2iv(location, arrayValue); case 35672: return gl.uniform3iv(location, arrayValue); case 35673: return gl.uniform4iv(location, arrayValue); case 5125: return gl2.uniform1uiv(location, arrayValue, 1); case 36294: return gl2.uniform2uiv(location, arrayValue, 2); case 36295: return gl2.uniform3uiv(location, arrayValue, 3); case 36296: return gl2.uniform4uiv(location, arrayValue, 4); case 35674: return gl.uniformMatrix2fv(location, false, arrayValue); case 35675: return gl.uniformMatrix3fv(location, false, arrayValue); case 35676: return gl.uniformMatrix4fv(location, false, arrayValue); case 35685: return gl2.uniformMatrix2x3fv(location, false, arrayValue); case 35686: return gl2.uniformMatrix2x4fv(location, false, arrayValue); case 35687: return gl2.uniformMatrix3x2fv(location, false, arrayValue); case 35688: return gl2.uniformMatrix3x4fv(location, false, arrayValue); case 35689: return gl2.uniformMatrix4x2fv(location, false, arrayValue); case 35690: return gl2.uniformMatrix4x3fv(location, false, arrayValue); } throw new Error("Illegal uniform"); } // ../../node_modules/@luma.gl/webgl/dist/adapter/helpers/webgl-topology-utils.js function getGLDrawMode(topology) { switch (topology) { case "point-list": return 0; case "line-list": return 1; case "line-strip": return 3; case "line-loop-webgl": return 2; case "triangle-list": return 4; case "triangle-strip": return 5; case "triangle-fan-webgl": return 6; default: throw new Error(topology); } } function getGLPrimitive(topology) { switch (topology) { case "point-list": return 0; case "line-list": return 1; case "line-strip": return 1; case "line-loop-webgl": return 1; case "triangle-list": return 4; case "triangle-strip": return 4; case "triangle-fan-webgl": return 4; default: throw new Error(topology); } } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-render-pipeline.js var LOG_PROGRAM_PERF_PRIORITY = 4; var WEBGLRenderPipeline = class extends RenderPipeline { device; handle; vs; fs; introspectedLayout; uniforms = {}; bindings = {}; varyings = null; _uniformCount = 0; _uniformSetters = {}; constructor(device, props) { super(device, props); this.device = device; this.handle = this.props.handle || this.device.gl.createProgram(); this.device.setSpectorMetadata(this.handle, { id: this.props.id }); this.vs = cast(props.vs); this.fs = cast(props.fs); const { varyings, bufferMode = 35981 } = props; if (varyings && varyings.length > 0) { this.varyings = varyings; this.device.gl.transformFeedbackVaryings(this.handle, varyings, bufferMode); } this._linkShaders(); log.time(1, `RenderPipeline ${this.id} - shaderLayout introspection`)(); this.introspectedLayout = getShaderLayout(this.device.gl, this.handle); log.timeEnd(1, `RenderPipeline ${this.id} - shaderLayout introspection`)(); this.shaderLayout = mergeShaderLayout(this.introspectedLayout, props.shaderLayout); switch (this.props.topology) { case "triangle-fan-webgl": case "line-loop-webgl": log.warn(`Primitive topology ${this.props.topology} is deprecated and will be removed in v9.1`); break; default: } } destroy() { if (this.handle) { this.device.gl.deleteProgram(this.handle); this.destroyed = true; } } setBindings(bindings, options) { for (const [name2, value] of Object.entries(bindings)) { const binding = this.shaderLayout.bindings.find((binding2) => binding2.name === name2) || this.shaderLayout.bindings.find((binding2) => binding2.name === `${name2}Uniforms`); if (!binding) { const validBindings = this.shaderLayout.bindings.map((binding2) => `"${binding2.name}"`).join(", "); if (!options?.disableWarnings) { log.warn(`Unknown binding "${name2}" in render pipeline "${this.id}", expected one of ${validBindings}`)(); } continue; } if (!value) { log.warn(`Unsetting binding "${name2}" in render pipeline "${this.id}"`)(); } switch (binding.type) { case "uniform": if (!(value instanceof WEBGLBuffer) && !(value.buffer instanceof WEBGLBuffer)) { throw new Error("buffer value"); } break; case "texture": if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) { throw new Error("texture value"); } break; case "sampler": log.warn(`Ignoring sampler ${name2}`)(); break; default: throw new Error(binding.type); } this.bindings[name2] = value; } } draw(options) { const { renderPass, parameters = this.props.parameters, topology = this.props.topology, vertexArray, vertexCount, instanceCount, isInstanced = false, firstVertex = 0, transformFeedback } = options; const glDrawMode = getGLDrawMode(topology); const isIndexed = Boolean(vertexArray.indexBuffer); const glIndexType = vertexArray.indexBuffer?.glIndexType; if (this.linkStatus !== "success") { log.info(2, `RenderPipeline:${this.id}.draw() aborted - waiting for shader linking`)(); return false; } if (!this._areTexturesRenderable() || vertexCount === 0) { log.info(2, `RenderPipeline:${this.id}.draw() aborted - textures not yet loaded`)(); return false; } if (vertexCount === 0) { log.info(2, `RenderPipeline:${this.id}.draw() aborted - no vertices to draw`)(); return true; } this.device.gl.useProgram(this.handle); vertexArray.bindBeforeRender(renderPass); if (transformFeedback) { transformFeedback.begin(this.props.topology); } this._applyBindings(); this._applyUniforms(); const webglRenderPass = renderPass; withDeviceAndGLParameters(this.device, parameters, webglRenderPass.glParameters, () => { if (isIndexed && isInstanced) { this.device.gl.drawElementsInstanced( glDrawMode, vertexCount || 0, glIndexType, firstVertex, instanceCount || 0 ); } else if (isIndexed) { this.device.gl.drawElements(glDrawMode, vertexCount || 0, glIndexType, firstVertex); } else if (isInstanced) { this.device.gl.drawArraysInstanced(glDrawMode, firstVertex, vertexCount || 0, instanceCount || 0); } else { this.device.gl.drawArrays(glDrawMode, firstVertex, vertexCount || 0); } if (transformFeedback) { transformFeedback.end(); } }); vertexArray.unbindAfterRender(renderPass); return true; } setUniformsWebGL(uniforms) { const { bindings } = splitUniformsAndBindings(uniforms); Object.keys(bindings).forEach((name2) => { log.warn(`Unsupported value "${JSON.stringify(bindings[name2])}" used in setUniforms() for key ${name2}. Use setBindings() instead?`)(); }); Object.assign(this.uniforms, uniforms); } async _linkShaders() { const { gl } = this.device; gl.attachShader(this.handle, this.vs.handle); gl.attachShader(this.handle, this.fs.handle); log.time(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)(); gl.linkProgram(this.handle); log.timeEnd(LOG_PROGRAM_PERF_PRIORITY, `linkProgram for ${this.id}`)(); if (log.level === 0) { } if (!this.device.features.has("compilation-status-async-webgl")) { const status2 = this._getLinkStatus(); this._reportLinkStatus(status2); return; } log.once(1, "RenderPipeline linking is asynchronous")(); await this._waitForLinkComplete(); log.info(2, `RenderPipeline ${this.id} - async linking complete: ${this.linkStatus}`)(); const status = this._getLinkStatus(); this._reportLinkStatus(status); } _reportLinkStatus(status) { switch (status) { case "success": return; default: if (this.vs.compilationStatus === "error") { this.vs.debugShader(); throw new Error(`Error during compilation of shader ${this.vs.id}`); } if (this.fs?.compilationStatus === "error") { this.fs.debugShader(); throw new Error(`Error during compilation of shader ${this.fs.id}`); } throw new Error(`Error during ${status}: ${this.device.gl.getProgramInfoLog(this.handle)}`); } } _getLinkStatus() { const { gl } = this.device; const linked = gl.getProgramParameter(this.handle, 35714); if (!linked) { this.linkStatus = "error"; return "linking"; } gl.validateProgram(this.handle); const validated = gl.getProgramParameter(this.handle, 35715); if (!validated) { this.linkStatus = "error"; return "validation"; } this.linkStatus = "success"; return "success"; } async _waitForLinkComplete() { const waitMs = async (ms) => await new Promise((resolve2) => setTimeout(resolve2, ms)); const DELAY_MS = 10; if (!this.device.features.has("compilation-status-async-webgl")) { await waitMs(DELAY_MS); return; } const { gl } = this.device; for (; ; ) { const complete = gl.getProgramParameter(this.handle, 37297); if (complete) { return; } await waitMs(DELAY_MS); } } _areTexturesRenderable() { let texturesRenderable = true; for (const [, texture] of Object.entries(this.bindings)) { if (texture instanceof WEBGLTexture) { texture.update(); texturesRenderable = texturesRenderable && texture.loaded; } } return texturesRenderable; } _applyBindings() { if (this.linkStatus !== "success") { return; } const { gl } = this.device; gl.useProgram(this.handle); let textureUnit = 0; let uniformBufferIndex = 0; for (const binding of this.shaderLayout.bindings) { const value = this.bindings[binding.name] || this.bindings[binding.name.replace(/Uniforms$/, "")]; if (!value) { throw new Error(`No value for binding ${binding.name} in ${this.id}`); } switch (binding.type) { case "uniform": const { name: name2 } = binding; const location = gl.getUniformBlockIndex(this.handle, name2); if (location === 4294967295) { throw new Error(`Invalid uniform block name ${name2}`); } gl.uniformBlockBinding(this.handle, uniformBufferIndex, location); if (value instanceof WEBGLBuffer) { gl.bindBufferBase(35345, uniformBufferIndex, value.handle); } else { gl.bindBufferRange( 35345, uniformBufferIndex, value.buffer.handle, value.offset || 0, value.size || value.buffer.byteLength - value.offset ); } uniformBufferIndex += 1; break; case "texture": if (!(value instanceof WEBGLTextureView || value instanceof WEBGLTexture || value instanceof WEBGLFramebuffer)) { throw new Error("texture"); } let texture; if (value instanceof WEBGLTextureView) { texture = value.texture; } else if (value instanceof WEBGLTexture) { texture = value; } else if (value instanceof WEBGLFramebuffer && value.colorAttachments[0] instanceof WEBGLTextureView) { log.warn("Passing framebuffer in texture binding may be deprecated. Use fbo.colorAttachments[0] instead")(); texture = value.colorAttachments[0].texture; } else { throw new Error("No texture"); } gl.activeTexture(33984 + textureUnit); gl.bindTexture(texture.target, texture.handle); textureUnit += 1; break; case "sampler": break; case "storage": case "read-only-storage": throw new Error(`binding type '${binding.type}' not supported in WebGL`); } } } _applyUniforms() { for (const uniformLayout of this.shaderLayout.uniforms || []) { const { name: name2, location, type, textureUnit } = uniformLayout; const value = this.uniforms[name2] ?? textureUnit; if (value !== void 0) { setUniform(this.device.gl, location, type, value); } } } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-command-buffer.js function cast2(value) { return value; } var WEBGLCommandBuffer = class extends CommandBuffer { device; commands = []; constructor(device) { super(device, {}); this.device = device; } submitCommands(commands = this.commands) { for (const command of commands) { switch (command.name) { case "copy-buffer-to-buffer": _copyBufferToBuffer(this.device, command.options); break; case "copy-buffer-to-texture": _copyBufferToTexture(this.device, command.options); break; case "copy-texture-to-buffer": _copyTextureToBuffer(this.device, command.options); break; case "copy-texture-to-texture": _copyTextureToTexture(this.device, command.options); break; } } } }; function _copyBufferToBuffer(device, options) { const source = cast2(options.source); const destination = cast2(options.destination); device.gl.bindBuffer(36662, source.handle); device.gl.bindBuffer(36663, destination.handle); device.gl.copyBufferSubData(36662, 36663, options.sourceOffset ?? 0, options.destinationOffset ?? 0, options.size); device.gl.bindBuffer(36662, null); device.gl.bindBuffer(36663, null); } function _copyBufferToTexture(device, options) { throw new Error("Not implemented"); } function _copyTextureToBuffer(device, options) { const { source, mipLevel = 0, aspect = "all", width = options.source.width, height = options.source.height, depthOrArrayLayers = 0, origin = [0, 0], destination, byteOffset = 0, bytesPerRow, rowsPerImage } = options; if (aspect !== "all") { throw new Error("not supported"); } if (mipLevel !== 0 || depthOrArrayLayers !== 0 || bytesPerRow || rowsPerImage) { throw new Error("not implemented"); } const { framebuffer, destroyFramebuffer } = getFramebuffer(source); let prevHandle; try { const webglBuffer = destination; const sourceWidth = width || framebuffer.width; const sourceHeight = height || framebuffer.height; const sourceParams = getWebGLTextureParameters(framebuffer.texture.props.format); const sourceFormat = sourceParams.dataFormat; const sourceType = sourceParams.type; device.gl.bindBuffer(35051, webglBuffer.handle); prevHandle = device.gl.bindFramebuffer(36160, framebuffer.handle); device.gl.readPixels(origin[0], origin[1], sourceWidth, sourceHeight, sourceFormat, sourceType, byteOffset); } finally { device.gl.bindBuffer(35051, null); if (prevHandle !== void 0) { device.gl.bindFramebuffer(36160, prevHandle); } if (destroyFramebuffer) { framebuffer.destroy(); } } } function _copyTextureToTexture(device, options) { const { source, destinationMipLevel = 0, origin = [0, 0], destinationOrigin = [0, 0], destination } = options; let { width = options.destination.width, height = options.destination.height } = options; const { framebuffer, destroyFramebuffer } = getFramebuffer(source); const [sourceX, sourceY] = origin; const [destinationX, destinationY, destinationZ] = destinationOrigin; const prevHandle = device.gl.bindFramebuffer(36160, framebuffer.handle); let texture = null; let textureTarget; if (destination instanceof WEBGLTexture) { texture = destination; width = Number.isFinite(width) ? width : texture.width; height = Number.isFinite(height) ? height : texture.height; texture.bind(0); textureTarget = texture.target; } else { throw new Error("invalid destination"); } switch (textureTarget) { case 3553: case 34067: device.gl.copyTexSubImage2D(textureTarget, destinationMipLevel, destinationX, destinationY, sourceX, sourceY, width, height); break; case 35866: case 32879: device.gl.copyTexSubImage3D(textureTarget, destinationMipLevel, destinationX, destinationY, destinationZ, sourceX, sourceY, width, height); break; default: } if (texture) { texture.unbind(); } device.gl.bindFramebuffer(36160, prevHandle); if (destroyFramebuffer) { framebuffer.destroy(); } } function getFramebuffer(source) { if (source instanceof Texture) { const { width, height, id } = source; const framebuffer = source.device.createFramebuffer({ id: `framebuffer-for-${id}`, width, height, colorAttachments: [source] }); return { framebuffer, destroyFramebuffer: true }; } return { framebuffer: source, destroyFramebuffer: false }; } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-command-encoder.js var WEBGLCommandEncoder = class extends CommandEncoder { device; commandBuffer; constructor(device, props) { super(device, props); this.device = device; this.commandBuffer = new WEBGLCommandBuffer(device); } destroy() { } finish() { this.commandBuffer.submitCommands(); } copyBufferToBuffer(options) { this.commandBuffer.commands.push({ name: "copy-buffer-to-buffer", options }); } copyBufferToTexture(options) { this.commandBuffer.commands.push({ name: "copy-buffer-to-texture", options }); } copyTextureToBuffer(options) { this.commandBuffer.commands.push({ name: "copy-texture-to-buffer", options }); } copyTextureToTexture(options) { this.commandBuffer.commands.push({ name: "copy-texture-to-texture", options }); } pushDebugGroup(groupLabel) { } popDebugGroup() { } insertDebugMarker(markerLabel) { } resolveQuerySet(querySet, destination, options) { } }; // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-vertex-array.js var WEBGLVertexArray = class extends VertexArray { get [Symbol.toStringTag]() { return "VertexArray"; } device; handle; buffer = null; bufferValue = null; static isConstantAttributeZeroSupported(device) { return getBrowser() === "Chrome"; } constructor(device, props) { super(device, props); this.device = device; this.handle = this.device.gl.createVertexArray(); } destroy() { super.destroy(); if (this.buffer) { this.buffer?.destroy(); } if (this.handle) { this.device.gl.deleteVertexArray(this.handle); this.handle = void 0; } } setIndexBuffer(indexBuffer) { const buffer = indexBuffer; if (buffer && buffer.glTarget !== 34963) { throw new Error("Use .setBuffer()"); } this.device.gl.bindVertexArray(this.handle); this.device.gl.bindBuffer(34963, buffer ? buffer.handle : null); this.indexBuffer = buffer; this.device.gl.bindVertexArray(null); } setBuffer(location, attributeBuffer) { const buffer = attributeBuffer; if (buffer.glTarget === 34963) { throw new Error("Use .setIndexBuffer()"); } const { size, type, stride, offset, normalized, integer, divisor } = this._getAccessor(location); this.device.gl.bindVertexArray(this.handle); this.device.gl.bindBuffer(34962, buffer.handle); if (integer) { this.device.gl.vertexAttribIPointer(location, size, type, stride, offset); } else { this.device.gl.vertexAttribPointer(location, size, type, normalized, stride, offset); } this.device.gl.bindBuffer(34962, null); this.device.gl.enableVertexAttribArray(location); this.device.gl.vertexAttribDivisor(location, divisor || 0); this.attributes[location] = buffer; this.device.gl.bindVertexArray(null); } setConstantWebGL(location, value) { this._enable(location, false); this.attributes[location] = value; } bindBeforeRender() { this.device.gl.bindVertexArray(this.handle); this._applyConstantAttributes(); } unbindAfterRender() { this.device.gl.bindVertexArray(null); } _applyConstantAttributes() { for (let location = 0; location < this.maxVertexAttributes; ++location) { const constant = this.attributes[location]; if (ArrayBuffer.isView(constant)) { this.device.setConstantAttributeWebGL(location, constant); } } } _getAccessor(location) { const attributeInfo = this.attributeInfos[location]; if (!attributeInfo) { throw new Error(`Unknown attribute location ${location}`); } const glType = getGLFromVertexType(attributeInfo.bufferDataType); return { size: attributeInfo.bufferComponents, type: glType, stride: attributeInfo.byteStride, offset: attributeInfo.byteOffset, normalized: attributeInfo.normalized, integer: attributeInfo.integer, divisor: attributeInfo.stepMode === "instance" ? 1 : 0 }; } _enable(location, enable2 = true) { const canDisableAttributeZero = WEBGLVertexArray.isConstantAttributeZeroSupported(this.device); const canDisableAttribute = canDisableAttributeZero || location !== 0; if (enable2 || canDisableAttribute) { location = Number(location); this.device.gl.bindVertexArray(this.handle); if (enable2) { this.device.gl.enableVertexAttribArray(location); } else { this.device.gl.disableVertexAttribArray(location); } this.device.gl.bindVertexArray(null); } } getConstantBuffer(elementCount, value) { const constantValue = normalizeConstantArrayValue(value); const byteLength = constantValue.byteLength * elementCount; const length4 = constantValue.length * elementCount; if (this.buffer && byteLength !== this.buffer.byteLength) { throw new Error(`Buffer size is immutable, byte length ${byteLength} !== ${this.buffer.byteLength}.`); } let updateNeeded = !this.buffer; this.buffer = this.buffer || this.device.createBuffer({ byteLength }); updateNeeded = updateNeeded || !compareConstantArrayValues(constantValue, this.bufferValue); if (updateNeeded) { const typedArray = getScratchArray(value.constructor, length4); fillArray({ target: typedArray, source: constantValue, start: 0, count: length4 }); this.buffer.write(typedArray); this.bufferValue = value; } return this.buffer; } }; function normalizeConstantArrayValue(arrayValue) { if (Array.isArray(arrayValue)) { return new Float32Array(arrayValue); } return arrayValue; } function compareConstantArrayValues(v1, v2) { if (!v1 || !v2 || v1.length !== v2.length || v1.constructor !== v2.constructor) { return false; } for (let i = 0; i < v1.length; ++i) { if (v1[i] !== v2[i]) { return false; } } return true; } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-transform-feedback.js var WEBGLTransformFeedback = class extends TransformFeedback { device; gl; handle; layout; buffers = {}; unusedBuffers = {}; bindOnUse = true; _bound = false; constructor(device, props) { super(device, props); this.device = device; this.gl = device.gl; this.handle = this.props.handle || this.gl.createTransformFeedback(); this.layout = this.props.layout; if (props.buffers) { this.setBuffers(props.buffers); } Object.seal(this); } destroy() { this.gl.deleteTransformFeedback(this.handle); super.destroy(); } begin(topology = "point-list") { this.gl.bindTransformFeedback(36386, this.handle); if (this.bindOnUse) { this._bindBuffers(); } this.gl.beginTransformFeedback(getGLPrimitive(topology)); } end() { this.gl.endTransformFeedback(); if (this.bindOnUse) { this._unbindBuffers(); } this.gl.bindTransformFeedback(36386, null); } setBuffers(buffers) { this.buffers = {}; this.unusedBuffers = {}; this.bind(() => { for (const bufferName in buffers) { this.setBuffer(bufferName, buffers[bufferName]); } }); } setBuffer(locationOrName, bufferOrRange) { const location = this._getVaryingIndex(locationOrName); const { buffer, byteLength, byteOffset } = this._getBufferRange(bufferOrRange); if (location < 0) { this.unusedBuffers[locationOrName] = buffer; log.warn(`${this.id} unusedBuffers varying buffer ${locationOrName}`)(); return; } this.buffers[location] = { buffer, byteLength, byteOffset }; if (!this.bindOnUse) { this._bindBuffer(location, buffer, byteOffset, byteLength); } } getBuffer(locationOrName) { if (isIndex(locationOrName)) { return this.buffers[locationOrName] || null; } const location = this._getVaryingIndex(locationOrName); return location >= 0 ? this.buffers[location] : null; } bind(funcOrHandle = this.handle) { if (typeof funcOrHandle !== "function") { this.gl.bindTransformFeedback(36386, funcOrHandle); return this; } let value; if (!this._bound) { this.gl.bindTransformFeedback(36386, this.handle); this._bound = true; value = funcOrHandle(); this._bound = false; this.gl.bindTransformFeedback(36386, null); } else { value = funcOrHandle(); } return value; } unbind() { this.bind(null); } _getBufferRange(bufferOrRange) { if (bufferOrRange instanceof WEBGLBuffer) { return { buffer: bufferOrRange, byteOffset: 0, byteLength: bufferOrRange.byteLength }; } const { buffer, byteOffset = 0, byteLength = bufferOrRange.buffer.byteLength } = bufferOrRange; return { buffer, byteOffset, byteLength }; } _getVaryingIndex(locationOrName) { if (isIndex(locationOrName)) { return Number(locationOrName); } for (const varying of this.layout.varyings) { if (locationOrName === varying.name) { return varying.location; } } return -1; } _bindBuffers() { for (const bufferIndex in this.buffers) { const { buffer, byteLength, byteOffset } = this._getBufferRange(this.buffers[bufferIndex]); this._bindBuffer(Number(bufferIndex), buffer, byteOffset, byteLength); } } _unbindBuffers() { for (const bufferIndex in this.buffers) { this.gl.bindBufferBase(35982, Number(bufferIndex), null); } } _bindBuffer(index2, buffer, byteOffset = 0, byteLength) { const handle = buffer && buffer.handle; if (!handle || byteLength === void 0) { this.gl.bindBufferBase(35982, index2, handle); } else { this.gl.bindBufferRange(35982, index2, handle, byteOffset, byteLength); } } }; function isIndex(value) { if (typeof value === "number") { return Number.isInteger(value); } return /^\d+$/.test(value); } // ../../node_modules/@luma.gl/webgl/dist/adapter/resources/webgl-query-set.js var WEBGLQuerySet = class extends QuerySet { device; handle; target = null; _queryPending = false; _pollingPromise = null; get [Symbol.toStringTag]() { return "Query"; } constructor(device, props) { super(device, props); this.device = device; if (props.count > 1) { throw new Error("WebGL QuerySet can only have one value"); } this.handle = this.device.gl.createQuery(); Object.seal(this); } destroy() { this.device.gl.deleteQuery(this.handle); } beginTimestampQuery() { return this._begin(35007); } endTimestampQuery() { this._end(); } beginOcclusionQuery(options) { return this._begin(options?.conservative ? 36202 : 35887); } endOcclusionQuery() { this._end(); } beginTransformFeedbackQuery() { return this._begin(35976); } endTransformFeedbackQuery() { this._end(); } async resolveQuery() { const value = await this.pollQuery(); return [value]; } _begin(target) { if (this._queryPending) { return; } this.target = target; this.device.gl.beginQuery(this.target, this.handle); return; } _end() { if (this._queryPending) { return; } if (this.target) { this.device.gl.endQuery(this.target); this.target = null; this._queryPending = true; } return; } isResultAvailable() { if (!this._queryPending) { return false; } const resultAvailable = this.device.gl.getQueryParameter(this.handle, 34919); if (resultAvailable) { this._queryPending = false; } return resultAvailable; } isTimerDisjoint() { return this.device.gl.getParameter(36795); } getResult() { return this.device.gl.getQueryParameter(this.handle, 34918); } getTimerMilliseconds() { return this.getResult() / 1e6; } pollQuery(limit = Number.POSITIVE_INFINITY) { if (this._pollingPromise) { return this._pollingPromise; } let counter2 = 0; this._pollingPromise = new Promise((resolve2, reject) => { const poll = () => { if (this.isResultAvailable()) { resolve2(this.getResult()); this._pollingPromise = null; } else if (counter2++ > limit) { reject("Timed out"); this._pollingPromise = null; } else { requestAnimationFrame(poll); } }; requestAnimationFrame(poll); }); return this._pollingPromise; } }; // ../../node_modules/@luma.gl/webgl/dist/classic/format-utils.js function glFormatToComponents(format) { switch (format) { case 6406: case 33326: case 6403: return 1; case 33328: case 33319: return 2; case 6407: case 34837: return 3; case 6408: case 34836: return 4; default: assert2(false); return 0; } } function glTypeToBytes(type) { switch (type) { case 5121: return 1; case 33635: case 32819: case 32820: return 2; case 5126: return 4; default: assert2(false); return 0; } } // ../../node_modules/@luma.gl/webgl/dist/classic/copy-and-blit.js function readPixelsToArray(source, options) { const { sourceX = 0, sourceY = 0, sourceFormat = 6408, sourceAttachment = 36064 } = options || {}; let { target = null, sourceWidth, sourceHeight, sourceType } = options || {}; const { framebuffer, deleteFramebuffer } = getFramebuffer2(source); assert2(framebuffer); const { gl, handle } = framebuffer; sourceWidth = sourceWidth || framebuffer.width; sourceHeight = sourceHeight || framebuffer.height; const attachment = sourceAttachment - 36064; sourceType = sourceType || framebuffer.colorAttachments[attachment]?.texture?.type || 5121; target = getPixelArray(target, sourceType, sourceFormat, sourceWidth, sourceHeight); sourceType = sourceType || getGLTypeFromTypedArray(target); const prevHandle = gl.bindFramebuffer(36160, handle); gl.readPixels(sourceX, sourceY, sourceWidth, sourceHeight, sourceFormat, sourceType, target); gl.bindFramebuffer(36160, prevHandle || null); if (deleteFramebuffer) { framebuffer.destroy(); } return target; } function readPixelsToBuffer(source, options) { const { target, sourceX = 0, sourceY = 0, sourceFormat = 6408, targetByteOffset = 0 } = options || {}; let { sourceWidth, sourceHeight, sourceType } = options || {}; const { framebuffer, deleteFramebuffer } = getFramebuffer2(source); assert2(framebuffer); sourceWidth = sourceWidth || framebuffer.width; sourceHeight = sourceHeight || framebuffer.height; const webglFramebuffer = framebuffer; sourceType = sourceType || 5121; let webglBufferTarget = target; if (!webglBufferTarget) { const components = glFormatToComponents(sourceFormat); const byteCount = glTypeToBytes(sourceType); const byteLength = targetByteOffset + sourceWidth * sourceHeight * components * byteCount; webglBufferTarget = webglFramebuffer.device.createBuffer({ byteLength }); } const commandEncoder = source.device.createCommandEncoder(); commandEncoder.copyTextureToBuffer({ source, width: sourceWidth, height: sourceHeight, origin: [sourceX, sourceY], destination: webglBufferTarget, byteOffset: targetByteOffset }); commandEncoder.destroy(); if (deleteFramebuffer) { framebuffer.destroy(); } return webglBufferTarget; } function getFramebuffer2(source) { if (!(source instanceof Framebuffer)) { return { framebuffer: toFramebuffer(source), deleteFramebuffer: true }; } return { framebuffer: source, deleteFramebuffer: false }; } function toFramebuffer(texture, props) { const { device, width, height, id } = texture; const framebuffer = device.createFramebuffer({ ...props, id: `framebuffer-for-${id}`, width, height, colorAttachments: [texture] }); return framebuffer; } function getPixelArray(pixelArray, type, format, width, height) { if (pixelArray) { return pixelArray; } type = type || 5121; const ArrayType2 = getTypedArrayFromGLType(type, { clamped: false }); const components = glFormatToComponents(format); return new ArrayType2(width * height * components); } // ../../node_modules/@luma.gl/webgl/dist/classic/clear.js var GL_DEPTH_BUFFER_BIT2 = 256; var GL_STENCIL_BUFFER_BIT2 = 1024; var GL_COLOR_BUFFER_BIT2 = 16384; var ERR_ARGUMENTS = "clear: bad arguments"; function clear(device, options) { const { framebuffer = null, color = null, depth = null, stencil = null } = options || {}; const parameters = {}; if (framebuffer) { parameters.framebuffer = framebuffer; } let clearFlags = 0; if (color) { clearFlags |= GL_COLOR_BUFFER_BIT2; if (color !== true) { parameters.clearColor = color; } } if (depth) { clearFlags |= GL_DEPTH_BUFFER_BIT2; if (depth !== true) { parameters.clearDepth = depth; } } if (stencil) { clearFlags |= GL_STENCIL_BUFFER_BIT2; if (depth !== true) { parameters.clearStencil = depth; } } assert2(clearFlags !== 0, ERR_ARGUMENTS); const gl = device.gl; withGLParameters(gl, parameters, () => { gl.clear(clearFlags); }); } // ../../node_modules/@luma.gl/webgl/dist/adapter/webgl-device.js var LOG_LEVEL2 = 1; var _WebGLDevice = class extends Device { type = "webgl"; handle; features; limits; info; canvasContext; lost; _resolveContextLost; static isSupported() { return typeof WebGL2RenderingContext !== "undefined"; } static attach(gl) { if (gl instanceof _WebGLDevice) { return gl; } if (gl?.device instanceof Device) { return gl.device; } if (!isWebGL(gl)) { throw new Error("Invalid WebGL2RenderingContext"); } return new _WebGLDevice({ gl }); } static async create(props = {}) { log.groupCollapsed(LOG_LEVEL2, "WebGLDevice created")(); const promises = []; if (props.debug) { promises.push(loadWebGLDeveloperTools()); } if (props.spector) { promises.push(loadSpectorJS()); } if (typeof props.canvas === "string") { promises.push(CanvasContext.pageLoaded); } const results = await Promise.allSettled(promises); for (const result of results) { if (result.status === "rejected") { log.error(`Failed to initialize debug libraries ${result.reason}`)(); } } log.probe(LOG_LEVEL2 + 1, "DOM is loaded")(); if (props.gl?.device) { log.warn("reattaching existing device")(); return _WebGLDevice.attach(props.gl); } const device = new _WebGLDevice(props); const message2 = `Created ${device.type}${device.debug ? " debug" : ""} context: ${device.info.vendor}, ${device.info.renderer} for canvas: ${device.canvasContext.id}`; log.probe(LOG_LEVEL2, message2)(); log.table(LOG_LEVEL2, device.info)(); log.groupEnd(LOG_LEVEL2)(); return device; } constructor(props) { super({ ...props, id: props.id || uid("webgl-device") }); const device = props.gl?.device; if (device) { throw new Error(`WebGL context already attached to device ${device.id}`); } const canvas2 = props.gl?.canvas || props.canvas; this.canvasContext = new WebGLCanvasContext(this, { ...props, canvas: canvas2 }); this.lost = new Promise((resolve2) => { this._resolveContextLost = resolve2; }); let gl = props.gl || null; gl ||= createBrowserContext(this.canvasContext.canvas, { ...props, onContextLost: (event) => this._resolveContextLost?.({ reason: "destroyed", message: "Entered sleep mode, or too many apps or browser tabs are using the GPU." }) }); if (!gl) { throw new Error("WebGL context creation failed"); } this.handle = gl; this.gl = gl; this.gl.device = this; this.gl._version = 2; if (props.spector) { this.spectorJS = initializeSpectorJS({ ...this.props, canvas: this.handle.canvas }); } this.info = getDeviceInfo(this.gl, this._extensions); this.limits = new WebGLDeviceLimits(this.gl); this.features = new WebGLDeviceFeatures(this.gl, this._extensions, this.props.disabledFeatures); if (this.props.initalizeFeatures) { this.features.initializeFeatures(); } this.canvasContext.resize(); const { enable: enable2 = true, copyState = false } = props; trackContextState(this.gl, { enable: enable2, copyState, log: (...args) => log.log(1, ...args)() }); if (props.debug) { this.gl = makeDebugContext(this.gl, { ...props, throwOnError: true }); this.debug = true; log.level = Math.max(log.level, 1); log.warn("WebGL debug mode activated. Performance reduced.")(); } } destroy() { } get isLost() { return this.gl.isContextLost(); } getSize() { return [this.gl.drawingBufferWidth, this.gl.drawingBufferHeight]; } isTextureFormatSupported(format) { return isTextureFormatSupported(this.gl, format, this._extensions); } isTextureFormatFilterable(format) { return isTextureFormatFilterable(this.gl, format, this._extensions); } isTextureFormatRenderable(format) { return isTextureFormatRenderable(this.gl, format, this._extensions); } createCanvasContext(props) { throw new Error("WebGL only supports a single canvas"); } createBuffer(props) { const newProps = this._getBufferProps(props); return new WEBGLBuffer(this, newProps); } _createTexture(props) { return new WEBGLTexture(this, props); } createExternalTexture(props) { throw new Error("createExternalTexture() not implemented"); } createSampler(props) { return new WEBGLSampler(this, props); } createShader(props) { return new WEBGLShader(this, props); } createFramebuffer(props) { return new WEBGLFramebuffer(this, props); } createVertexArray(props) { return new WEBGLVertexArray(this, props); } createTransformFeedback(props) { return new WEBGLTransformFeedback(this, props); } createQuerySet(props) { return new WEBGLQuerySet(this, props); } createRenderPipeline(props) { return new WEBGLRenderPipeline(this, props); } beginRenderPass(props) { return new WEBGLRenderPass(this, props); } createComputePipeline(props) { throw new Error("ComputePipeline not supported in WebGL"); } beginComputePass(props) { throw new Error("ComputePass not supported in WebGL"); } renderPass = null; createCommandEncoder(props) { return new WEBGLCommandEncoder(this, props); } submit() { this.renderPass?.end(); this.renderPass = null; } readPixelsToArrayWebGL(source, options) { return readPixelsToArray(source, options); } readPixelsToBufferWebGL(source, options) { return readPixelsToBuffer(source, options); } setParametersWebGL(parameters) { setGLParameters(this.gl, parameters); } getParametersWebGL(parameters) { return getGLParameters(this.gl, parameters); } withParametersWebGL(parameters, func) { return withGLParameters(this.gl, parameters, func); } clearWebGL(options) { clear(this, options); } resetWebGL() { log.warn("WebGLDevice.resetWebGL is deprecated, use only for debugging")(); resetGLParameters(this.gl); } gl; debug = false; _canvasSizeInfo = { clientWidth: 0, clientHeight: 0, devicePixelRatio: 1 }; _extensions = {}; _polyfilled = false; spectorJS; loseDevice() { let deviceLossTriggered = false; const extensions = this.getExtension("WEBGL_lose_context"); const ext = extensions.WEBGL_lose_context; if (ext) { deviceLossTriggered = true; ext.loseContext(); } this._resolveContextLost?.({ reason: "destroyed", message: "Application triggered context loss" }); return deviceLossTriggered; } pushState() { pushContextState(this.gl); } popState() { popContextState(this.gl); } setSpectorMetadata(handle, props) { handle.__SPECTOR_Metadata = props; } getGLKey(value, gl) { gl = gl || this.gl2 || this.gl; const number = Number(value); for (const key in gl) { if (gl[key] === number) { return `GL.${key}`; } } return String(value); } _constants; setConstantAttributeWebGL(location, constant) { const maxVertexAttributes = this.limits.maxVertexAttributes; this._constants = this._constants || new Array(maxVertexAttributes).fill(null); const currentConstant = this._constants[location]; if (currentConstant && compareConstantArrayValues2(currentConstant, constant)) { log.info(1, `setConstantAttributeWebGL(${location}) could have been skipped, value unchanged`)(); } this._constants[location] = constant; switch (constant.constructor) { case Float32Array: setConstantFloatArray(this, location, constant); break; case Int32Array: setConstantIntArray(this, location, constant); break; case Uint32Array: setConstantUintArray(this, location, constant); break; default: assert2(false); } } getExtension(name2) { getWebGLExtension(this.gl, name2, this._extensions); return this._extensions; } }; var WebGLDevice = _WebGLDevice; __publicField(WebGLDevice, "type", "webgl"); function isWebGL(gl) { if (typeof WebGL2RenderingContext !== "undefined" && gl instanceof WebGL2RenderingContext) { return true; } return Boolean(gl && Number.isFinite(gl._version)); } function setConstantFloatArray(device, location, array) { switch (array.length) { case 1: device.gl.vertexAttrib1fv(location, array); break; case 2: device.gl.vertexAttrib2fv(location, array); break; case 3: device.gl.vertexAttrib3fv(location, array); break; case 4: device.gl.vertexAttrib4fv(location, array); break; default: assert2(false); } } function setConstantIntArray(device, location, array) { device.gl.vertexAttribI4iv(location, array); } function setConstantUintArray(device, location, array) { device.gl.vertexAttribI4uiv(location, array); } function compareConstantArrayValues2(v1, v2) { if (!v1 || !v2 || v1.length !== v2.length || v1.constructor !== v2.constructor) { return false; } for (let i = 0; i < v1.length; ++i) { if (v1[i] !== v2[i]) { return false; } } return true; } // ../../node_modules/mjolnir.js/dist/esm/utils/hammer.browser.js var hammerjs = __toESM(require_hammer()); // ../../node_modules/mjolnir.js/dist/esm/utils/hammer-overrides.js var INPUT_START = 1; var INPUT_MOVE = 2; var INPUT_END = 4; var MOUSE_INPUT_MAP = { mousedown: INPUT_START, mousemove: INPUT_MOVE, mouseup: INPUT_END }; function some(array, predict) { for (let i = 0; i < array.length; i++) { if (predict(array[i])) { return true; } } return false; } function enhancePointerEventInput(PointerEventInput2) { const oldHandler = PointerEventInput2.prototype.handler; PointerEventInput2.prototype.handler = function handler(ev) { const store = this.store; if (ev.button > 0 && ev.type === "pointerdown") { if (!some(store, (e2) => e2.pointerId === ev.pointerId)) { store.push(ev); } } oldHandler.call(this, ev); }; } function enhanceMouseInput(MouseInput2) { MouseInput2.prototype.handler = function handler(ev) { let eventType = MOUSE_INPUT_MAP[ev.type]; if (eventType & INPUT_START && ev.button >= 0) { this.pressed = true; } if (eventType & INPUT_MOVE && ev.which === 0) { eventType = INPUT_END; } if (!this.pressed) { return; } if (eventType & INPUT_END) { this.pressed = false; } this.callback(this.manager, eventType, { pointers: [ev], changedPointers: [ev], pointerType: "mouse", srcEvent: ev }); }; } // ../../node_modules/mjolnir.js/dist/esm/utils/hammer.browser.js enhancePointerEventInput(hammerjs.PointerEventInput); enhanceMouseInput(hammerjs.MouseInput); var Manager2 = hammerjs.Manager; var hammer_browser_default = hammerjs; // ../../node_modules/mjolnir.js/dist/esm/inputs/input.js var Input = class { constructor(element, callback, options) { this.element = element; this.callback = callback; this.options = { enable: true, ...options }; } }; // ../../node_modules/mjolnir.js/dist/esm/constants.js var RECOGNIZERS = hammer_browser_default ? [ [hammer_browser_default.Pan, { event: "tripan", pointers: 3, threshold: 0, enable: false }], [hammer_browser_default.Rotate, { enable: false }], [hammer_browser_default.Pinch, { enable: false }], [hammer_browser_default.Swipe, { enable: false }], [hammer_browser_default.Pan, { threshold: 0, enable: false }], [hammer_browser_default.Press, { enable: false }], [hammer_browser_default.Tap, { event: "doubletap", taps: 2, enable: false }], [hammer_browser_default.Tap, { event: "anytap", enable: false }], [hammer_browser_default.Tap, { enable: false }] ] : null; var RECOGNIZER_COMPATIBLE_MAP = { tripan: ["rotate", "pinch", "pan"], rotate: ["pinch"], pinch: ["pan"], pan: ["press", "doubletap", "anytap", "tap"], doubletap: ["anytap"], anytap: ["tap"] }; var RECOGNIZER_FALLBACK_MAP = { doubletap: ["tap"] }; var BASIC_EVENT_ALIASES = { pointerdown: "pointerdown", pointermove: "pointermove", pointerup: "pointerup", touchstart: "pointerdown", touchmove: "pointermove", touchend: "pointerup", mousedown: "pointerdown", mousemove: "pointermove", mouseup: "pointerup" }; var INPUT_EVENT_TYPES = { KEY_EVENTS: ["keydown", "keyup"], MOUSE_EVENTS: ["mousedown", "mousemove", "mouseup", "mouseover", "mouseout", "mouseleave"], WHEEL_EVENTS: [ "wheel", "mousewheel" ] }; var EVENT_RECOGNIZER_MAP = { tap: "tap", anytap: "anytap", doubletap: "doubletap", press: "press", pinch: "pinch", pinchin: "pinch", pinchout: "pinch", pinchstart: "pinch", pinchmove: "pinch", pinchend: "pinch", pinchcancel: "pinch", rotate: "rotate", rotatestart: "rotate", rotatemove: "rotate", rotateend: "rotate", rotatecancel: "rotate", tripan: "tripan", tripanstart: "tripan", tripanmove: "tripan", tripanup: "tripan", tripandown: "tripan", tripanleft: "tripan", tripanright: "tripan", tripanend: "tripan", tripancancel: "tripan", pan: "pan", panstart: "pan", panmove: "pan", panup: "pan", pandown: "pan", panleft: "pan", panright: "pan", panend: "pan", pancancel: "pan", swipe: "swipe", swipeleft: "swipe", swiperight: "swipe", swipeup: "swipe", swipedown: "swipe" }; var GESTURE_EVENT_ALIASES = { click: "tap", anyclick: "anytap", dblclick: "doubletap", mousedown: "pointerdown", mousemove: "pointermove", mouseup: "pointerup", mouseover: "pointerover", mouseout: "pointerout", mouseleave: "pointerleave" }; // ../../node_modules/mjolnir.js/dist/esm/utils/globals.js var userAgent = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent.toLowerCase() : ""; var window_4 = typeof window !== "undefined" ? window : global; var passiveSupported = false; try { const options = { get passive() { passiveSupported = true; return true; } }; window_4.addEventListener("test", null, options); window_4.removeEventListener("test", null); } catch (err) { passiveSupported = false; } // ../../node_modules/mjolnir.js/dist/esm/inputs/wheel-input.js var firefox = userAgent.indexOf("firefox") !== -1; var { WHEEL_EVENTS } = INPUT_EVENT_TYPES; var EVENT_TYPE = "wheel"; var WHEEL_DELTA_MAGIC_SCALER = 4.000244140625; var WHEEL_DELTA_PER_LINE = 40; var SHIFT_MULTIPLIER = 0.25; var WheelInput = class extends Input { constructor(element, callback, options) { super(element, callback, options); this.handleEvent = (event) => { if (!this.options.enable) { return; } let value = event.deltaY; if (window_4.WheelEvent) { if (firefox && event.deltaMode === window_4.WheelEvent.DOM_DELTA_PIXEL) { value /= window_4.devicePixelRatio; } if (event.deltaMode === window_4.WheelEvent.DOM_DELTA_LINE) { value *= WHEEL_DELTA_PER_LINE; } } if (value !== 0 && value % WHEEL_DELTA_MAGIC_SCALER === 0) { value = Math.floor(value / WHEEL_DELTA_MAGIC_SCALER); } if (event.shiftKey && value) { value = value * SHIFT_MULTIPLIER; } this.callback({ type: EVENT_TYPE, center: { x: event.clientX, y: event.clientY }, delta: -value, srcEvent: event, pointerType: "mouse", target: event.target }); }; this.events = (this.options.events || []).concat(WHEEL_EVENTS); this.events.forEach((event) => element.addEventListener(event, this.handleEvent, passiveSupported ? { passive: false } : false)); } destroy() { this.events.forEach((event) => this.element.removeEventListener(event, this.handleEvent)); } enableEventType(eventType, enabled) { if (eventType === EVENT_TYPE) { this.options.enable = enabled; } } }; // ../../node_modules/mjolnir.js/dist/esm/inputs/move-input.js var { MOUSE_EVENTS } = INPUT_EVENT_TYPES; var MOVE_EVENT_TYPE = "pointermove"; var OVER_EVENT_TYPE = "pointerover"; var OUT_EVENT_TYPE = "pointerout"; var ENTER_EVENT_TYPE = "pointerenter"; var LEAVE_EVENT_TYPE = "pointerleave"; var MoveInput = class extends Input { constructor(element, callback, options) { super(element, callback, options); this.handleEvent = (event) => { this.handleOverEvent(event); this.handleOutEvent(event); this.handleEnterEvent(event); this.handleLeaveEvent(event); this.handleMoveEvent(event); }; this.pressed = false; const { enable: enable2 } = this.options; this.enableMoveEvent = enable2; this.enableLeaveEvent = enable2; this.enableEnterEvent = enable2; this.enableOutEvent = enable2; this.enableOverEvent = enable2; this.events = (this.options.events || []).concat(MOUSE_EVENTS); this.events.forEach((event) => element.addEventListener(event, this.handleEvent)); } destroy() { this.events.forEach((event) => this.element.removeEventListener(event, this.handleEvent)); } enableEventType(eventType, enabled) { if (eventType === MOVE_EVENT_TYPE) { this.enableMoveEvent = enabled; } if (eventType === OVER_EVENT_TYPE) { this.enableOverEvent = enabled; } if (eventType === OUT_EVENT_TYPE) { this.enableOutEvent = enabled; } if (eventType === ENTER_EVENT_TYPE) { this.enableEnterEvent = enabled; } if (eventType === LEAVE_EVENT_TYPE) { this.enableLeaveEvent = enabled; } } handleOverEvent(event) { if (this.enableOverEvent) { if (event.type === "mouseover") { this._emit(OVER_EVENT_TYPE, event); } } } handleOutEvent(event) { if (this.enableOutEvent) { if (event.type === "mouseout") { this._emit(OUT_EVENT_TYPE, event); } } } handleEnterEvent(event) { if (this.enableEnterEvent) { if (event.type === "mouseenter") { this._emit(ENTER_EVENT_TYPE, event); } } } handleLeaveEvent(event) { if (this.enableLeaveEvent) { if (event.type === "mouseleave") { this._emit(LEAVE_EVENT_TYPE, event); } } } handleMoveEvent(event) { if (this.enableMoveEvent) { switch (event.type) { case "mousedown": if (event.button >= 0) { this.pressed = true; } break; case "mousemove": if (event.which === 0) { this.pressed = false; } if (!this.pressed) { this._emit(MOVE_EVENT_TYPE, event); } break; case "mouseup": this.pressed = false; break; default: } } } _emit(type, event) { this.callback({ type, center: { x: event.clientX, y: event.clientY }, srcEvent: event, pointerType: "mouse", target: event.target }); } }; // ../../node_modules/mjolnir.js/dist/esm/inputs/key-input.js var { KEY_EVENTS } = INPUT_EVENT_TYPES; var DOWN_EVENT_TYPE = "keydown"; var UP_EVENT_TYPE = "keyup"; var KeyInput = class extends Input { constructor(element, callback, options) { super(element, callback, options); this.handleEvent = (event) => { const targetElement = event.target || event.srcElement; if (targetElement.tagName === "INPUT" && targetElement.type === "text" || targetElement.tagName === "TEXTAREA") { return; } if (this.enableDownEvent && event.type === "keydown") { this.callback({ type: DOWN_EVENT_TYPE, srcEvent: event, key: event.key, target: event.target }); } if (this.enableUpEvent && event.type === "keyup") { this.callback({ type: UP_EVENT_TYPE, srcEvent: event, key: event.key, target: event.target }); } }; this.enableDownEvent = this.options.enable; this.enableUpEvent = this.options.enable; this.events = (this.options.events || []).concat(KEY_EVENTS); element.tabIndex = this.options.tabIndex || 0; element.style.outline = "none"; this.events.forEach((event) => element.addEventListener(event, this.handleEvent)); } destroy() { this.events.forEach((event) => this.element.removeEventListener(event, this.handleEvent)); } enableEventType(eventType, enabled) { if (eventType === DOWN_EVENT_TYPE) { this.enableDownEvent = enabled; } if (eventType === UP_EVENT_TYPE) { this.enableUpEvent = enabled; } } }; // ../../node_modules/mjolnir.js/dist/esm/inputs/contextmenu-input.js var EVENT_TYPE2 = "contextmenu"; var ContextmenuInput = class extends Input { constructor(element, callback, options) { super(element, callback, options); this.handleEvent = (event) => { if (!this.options.enable) { return; } this.callback({ type: EVENT_TYPE2, center: { x: event.clientX, y: event.clientY }, srcEvent: event, pointerType: "mouse", target: event.target }); }; element.addEventListener("contextmenu", this.handleEvent); } destroy() { this.element.removeEventListener("contextmenu", this.handleEvent); } enableEventType(eventType, enabled) { if (eventType === EVENT_TYPE2) { this.options.enable = enabled; } } }; // ../../node_modules/mjolnir.js/dist/esm/utils/event-utils.js var DOWN_EVENT = 1; var MOVE_EVENT = 2; var UP_EVENT = 4; var MOUSE_EVENTS2 = { pointerdown: DOWN_EVENT, pointermove: MOVE_EVENT, pointerup: UP_EVENT, mousedown: DOWN_EVENT, mousemove: MOVE_EVENT, mouseup: UP_EVENT }; var MOUSE_EVENT_WHICH_LEFT = 1; var MOUSE_EVENT_WHICH_MIDDLE = 2; var MOUSE_EVENT_WHICH_RIGHT = 3; var MOUSE_EVENT_BUTTON_LEFT = 0; var MOUSE_EVENT_BUTTON_MIDDLE = 1; var MOUSE_EVENT_BUTTON_RIGHT = 2; var MOUSE_EVENT_BUTTONS_LEFT_MASK = 1; var MOUSE_EVENT_BUTTONS_RIGHT_MASK = 2; var MOUSE_EVENT_BUTTONS_MIDDLE_MASK = 4; function whichButtons(event) { const eventType = MOUSE_EVENTS2[event.srcEvent.type]; if (!eventType) { return null; } const { buttons, button, which } = event.srcEvent; let leftButton = false; let middleButton = false; let rightButton = false; if (eventType === UP_EVENT || eventType === MOVE_EVENT && !Number.isFinite(buttons)) { leftButton = which === MOUSE_EVENT_WHICH_LEFT; middleButton = which === MOUSE_EVENT_WHICH_MIDDLE; rightButton = which === MOUSE_EVENT_WHICH_RIGHT; } else if (eventType === MOVE_EVENT) { leftButton = Boolean(buttons & MOUSE_EVENT_BUTTONS_LEFT_MASK); middleButton = Boolean(buttons & MOUSE_EVENT_BUTTONS_MIDDLE_MASK); rightButton = Boolean(buttons & MOUSE_EVENT_BUTTONS_RIGHT_MASK); } else if (eventType === DOWN_EVENT) { leftButton = button === MOUSE_EVENT_BUTTON_LEFT; middleButton = button === MOUSE_EVENT_BUTTON_MIDDLE; rightButton = button === MOUSE_EVENT_BUTTON_RIGHT; } return { leftButton, middleButton, rightButton }; } function getOffsetPosition(event, rootElement) { const center = event.center; if (!center) { return null; } const rect = rootElement.getBoundingClientRect(); const scaleX2 = rect.width / rootElement.offsetWidth || 1; const scaleY2 = rect.height / rootElement.offsetHeight || 1; const offsetCenter = { x: (center.x - rect.left - rootElement.clientLeft) / scaleX2, y: (center.y - rect.top - rootElement.clientTop) / scaleY2 }; return { center, offsetCenter }; } // ../../node_modules/mjolnir.js/dist/esm/utils/event-registrar.js var DEFAULT_OPTIONS = { srcElement: "root", priority: 0 }; var EventRegistrar = class { constructor(eventManager) { this.handleEvent = (event) => { if (this.isEmpty()) { return; } const mjolnirEvent = this._normalizeEvent(event); let target = event.srcEvent.target; while (target && target !== mjolnirEvent.rootElement) { this._emit(mjolnirEvent, target); if (mjolnirEvent.handled) { return; } target = target.parentNode; } this._emit(mjolnirEvent, "root"); }; this.eventManager = eventManager; this.handlers = []; this.handlersByElement = /* @__PURE__ */ new Map(); this._active = false; } isEmpty() { return !this._active; } add(type, handler, options, once = false, passive = false) { const { handlers, handlersByElement } = this; let opts = DEFAULT_OPTIONS; if (typeof options === "string" || options && options.addEventListener) { opts = { ...DEFAULT_OPTIONS, srcElement: options }; } else if (options) { opts = { ...DEFAULT_OPTIONS, ...options }; } let entries = handlersByElement.get(opts.srcElement); if (!entries) { entries = []; handlersByElement.set(opts.srcElement, entries); } const entry = { type, handler, srcElement: opts.srcElement, priority: opts.priority }; if (once) { entry.once = true; } if (passive) { entry.passive = true; } handlers.push(entry); this._active = this._active || !entry.passive; let insertPosition = entries.length - 1; while (insertPosition >= 0) { if (entries[insertPosition].priority >= entry.priority) { break; } insertPosition--; } entries.splice(insertPosition + 1, 0, entry); } remove(type, handler) { const { handlers, handlersByElement } = this; for (let i = handlers.length - 1; i >= 0; i--) { const entry = handlers[i]; if (entry.type === type && entry.handler === handler) { handlers.splice(i, 1); const entries = handlersByElement.get(entry.srcElement); entries.splice(entries.indexOf(entry), 1); if (entries.length === 0) { handlersByElement.delete(entry.srcElement); } } } this._active = handlers.some((entry) => !entry.passive); } _emit(event, srcElement) { const entries = this.handlersByElement.get(srcElement); if (entries) { let immediatePropagationStopped = false; const stopPropagation = () => { event.handled = true; }; const stopImmediatePropagation = () => { event.handled = true; immediatePropagationStopped = true; }; const entriesToRemove = []; for (let i = 0; i < entries.length; i++) { const { type, handler, once } = entries[i]; handler({ ...event, type, stopPropagation, stopImmediatePropagation }); if (once) { entriesToRemove.push(entries[i]); } if (immediatePropagationStopped) { break; } } for (let i = 0; i < entriesToRemove.length; i++) { const { type, handler } = entriesToRemove[i]; this.remove(type, handler); } } } _normalizeEvent(event) { const rootElement = this.eventManager.getElement(); return { ...event, ...whichButtons(event), ...getOffsetPosition(event, rootElement), preventDefault: () => { event.srcEvent.preventDefault(); }, stopImmediatePropagation: null, stopPropagation: null, handled: false, rootElement }; } }; // ../../node_modules/mjolnir.js/dist/esm/event-manager.js var DEFAULT_OPTIONS2 = { events: null, recognizers: null, recognizerOptions: {}, Manager: Manager2, touchAction: "none", tabIndex: 0 }; var EventManager = class { constructor(element = null, options) { this._onBasicInput = (event) => { const { srcEvent } = event; const alias = BASIC_EVENT_ALIASES[srcEvent.type]; if (alias) { this.manager.emit(alias, event); } }; this._onOtherEvent = (event) => { this.manager.emit(event.type, event); }; this.options = { ...DEFAULT_OPTIONS2, ...options }; this.events = /* @__PURE__ */ new Map(); this.setElement(element); const { events } = this.options; if (events) { this.on(events); } } getElement() { return this.element; } setElement(element) { if (this.element) { this.destroy(); } this.element = element; if (!element) { return; } const { options } = this; const ManagerClass = options.Manager; this.manager = new ManagerClass(element, { touchAction: options.touchAction, recognizers: options.recognizers || RECOGNIZERS }).on("hammer.input", this._onBasicInput); if (!options.recognizers) { Object.keys(RECOGNIZER_COMPATIBLE_MAP).forEach((name2) => { const recognizer = this.manager.get(name2); if (recognizer) { RECOGNIZER_COMPATIBLE_MAP[name2].forEach((otherName) => { recognizer.recognizeWith(otherName); }); } }); } for (const recognizerName in options.recognizerOptions) { const recognizer = this.manager.get(recognizerName); if (recognizer) { const recognizerOption = options.recognizerOptions[recognizerName]; delete recognizerOption.enable; recognizer.set(recognizerOption); } } this.wheelInput = new WheelInput(element, this._onOtherEvent, { enable: false }); this.moveInput = new MoveInput(element, this._onOtherEvent, { enable: false }); this.keyInput = new KeyInput(element, this._onOtherEvent, { enable: false, tabIndex: options.tabIndex }); this.contextmenuInput = new ContextmenuInput(element, this._onOtherEvent, { enable: false }); for (const [eventAlias, eventRegistrar] of this.events) { if (!eventRegistrar.isEmpty()) { this._toggleRecognizer(eventRegistrar.recognizerName, true); this.manager.on(eventAlias, eventRegistrar.handleEvent); } } } destroy() { if (this.element) { this.wheelInput.destroy(); this.moveInput.destroy(); this.keyInput.destroy(); this.contextmenuInput.destroy(); this.manager.destroy(); this.wheelInput = null; this.moveInput = null; this.keyInput = null; this.contextmenuInput = null; this.manager = null; this.element = null; } } on(event, handler, opts) { this._addEventHandler(event, handler, opts, false); } once(event, handler, opts) { this._addEventHandler(event, handler, opts, true); } watch(event, handler, opts) { this._addEventHandler(event, handler, opts, false, true); } off(event, handler) { this._removeEventHandler(event, handler); } _toggleRecognizer(name2, enabled) { const { manager } = this; if (!manager) { return; } const recognizer = manager.get(name2); if (recognizer && recognizer.options.enable !== enabled) { recognizer.set({ enable: enabled }); const fallbackRecognizers = RECOGNIZER_FALLBACK_MAP[name2]; if (fallbackRecognizers && !this.options.recognizers) { fallbackRecognizers.forEach((otherName) => { const otherRecognizer = manager.get(otherName); if (enabled) { otherRecognizer.requireFailure(name2); recognizer.dropRequireFailure(otherName); } else { otherRecognizer.dropRequireFailure(name2); } }); } } this.wheelInput.enableEventType(name2, enabled); this.moveInput.enableEventType(name2, enabled); this.keyInput.enableEventType(name2, enabled); this.contextmenuInput.enableEventType(name2, enabled); } _addEventHandler(event, handler, opts, once, passive) { if (typeof event !== "string") { opts = handler; for (const eventName in event) { this._addEventHandler(eventName, event[eventName], opts, once, passive); } return; } const { manager, events } = this; const eventAlias = GESTURE_EVENT_ALIASES[event] || event; let eventRegistrar = events.get(eventAlias); if (!eventRegistrar) { eventRegistrar = new EventRegistrar(this); events.set(eventAlias, eventRegistrar); eventRegistrar.recognizerName = EVENT_RECOGNIZER_MAP[eventAlias] || eventAlias; if (manager) { manager.on(eventAlias, eventRegistrar.handleEvent); } } eventRegistrar.add(event, handler, opts, once, passive); if (!eventRegistrar.isEmpty()) { this._toggleRecognizer(eventRegistrar.recognizerName, true); } } _removeEventHandler(event, handler) { if (typeof event !== "string") { for (const eventName in event) { this._removeEventHandler(eventName, event[eventName]); } return; } const { events } = this; const eventAlias = GESTURE_EVENT_ALIASES[event] || event; const eventRegistrar = events.get(eventAlias); if (!eventRegistrar) { return; } eventRegistrar.remove(event, handler); if (eventRegistrar.isEmpty()) { const { recognizerName } = eventRegistrar; let isRecognizerUsed = false; for (const eh of events.values()) { if (eh.recognizerName === recognizerName && !eh.isEmpty()) { isRecognizerUsed = true; break; } } if (!isRecognizerUsed) { this._toggleRecognizer(recognizerName, false); } } } }; // src/lib/deck.ts function noop3() { } var getCursor = ({ isDragging }) => isDragging ? "grabbing" : "grab"; var defaultProps = { id: "", width: "100%", height: "100%", style: null, viewState: null, initialViewState: null, pickingRadius: 0, layerFilter: null, parameters: {}, parent: null, device: null, deviceProps: { type: "webgl" }, gl: null, glOptions: {}, canvas: null, layers: [], effects: [], views: null, controller: null, useDevicePixels: true, touchAction: "none", eventRecognizerOptions: {}, _framebuffer: null, _animate: false, _pickable: true, _typedArrayManagerProps: {}, _customRender: null, widgets: [], onDeviceInitialized: noop3, onWebGLInitialized: noop3, onResize: noop3, onViewStateChange: noop3, onInteractionStateChange: noop3, onBeforeRender: noop3, onAfterRender: noop3, onLoad: noop3, onError: (error) => log_default.error(error.message, error.cause)(), onHover: null, onClick: null, onDragStart: null, onDrag: null, onDragEnd: null, _onMetrics: null, getCursor, getTooltip: null, debug: false, drawPickingColors: false }; var Deck = class { constructor(props) { this.width = 0; this.height = 0; this.userData = {}; this.device = null; this.canvas = null; this.viewManager = null; this.layerManager = null; this.effectManager = null; this.deckRenderer = null; this.deckPicker = null; this.eventManager = null; this.widgetManager = null; this.tooltip = null; this.animationLoop = null; this.cursorState = { isHovering: false, isDragging: false }; this.stats = new Stats({ id: "deck.gl" }); this.metrics = { fps: 0, setPropsTime: 0, updateAttributesTime: 0, framesRedrawn: 0, pickTime: 0, pickCount: 0, gpuTime: 0, gpuTimePerFrame: 0, cpuTime: 0, cpuTimePerFrame: 0, bufferMemory: 0, textureMemory: 0, renderbufferMemory: 0, gpuMemory: 0 }; this._metricsCounter = 0; this._needsRedraw = "Initial render"; this._pickRequest = { mode: "hover", x: -1, y: -1, radius: 0, event: null }; this._lastPointerDownInfo = null; this._onPointerMove = (event) => { const { _pickRequest } = this; if (event.type === "pointerleave") { _pickRequest.x = -1; _pickRequest.y = -1; _pickRequest.radius = 0; } else if (event.leftButton || event.rightButton) { return; } else { const pos = event.offsetCenter; if (!pos) { return; } _pickRequest.x = pos.x; _pickRequest.y = pos.y; _pickRequest.radius = this.props.pickingRadius; } if (this.layerManager) { this.layerManager.context.mousePosition = { x: _pickRequest.x, y: _pickRequest.y }; } _pickRequest.event = event; }; this._onEvent = (event) => { const eventOptions = EVENTS[event.type]; const pos = event.offsetCenter; if (!eventOptions || !pos || !this.layerManager) { return; } const layers = this.layerManager.getLayers(); const info = this.deckPicker.getLastPickedObject( { x: pos.x, y: pos.y, layers, viewports: this.getViewports(pos) }, this._lastPointerDownInfo ); const { layer } = info; const layerHandler = layer && (layer[eventOptions.handler] || layer.props[eventOptions.handler]); const rootHandler = this.props[eventOptions.handler]; let handled = false; if (layerHandler) { handled = layerHandler.call(layer, info, event); } if (!handled) { rootHandler?.(info, event); this.widgetManager.onEvent(info, event); } }; this._onPointerDown = (event) => { const pos = event.offsetCenter; const pickedInfo = this._pick("pickObject", "pickObject Time", { x: pos.x, y: pos.y, radius: this.props.pickingRadius }); this._lastPointerDownInfo = pickedInfo.result[0] || pickedInfo.emptyInfo; }; this.props = { ...defaultProps, ...props }; props = this.props; if (props.viewState && props.initialViewState) { log_default.warn( "View state tracking is disabled. Use either `initialViewState` for auto update or `viewState` for manual update." )(); } this.viewState = this.props.initialViewState; if (props.device) { this.device = props.device; } else if (props.gl) { if (props.gl instanceof WebGLRenderingContext) { log_default.error("WebGL1 context not supported.")(); } this.device = WebGLDevice.attach(props.gl); } let deviceOrPromise = this.device; if (!deviceOrPromise) { luma.registerDevices([WebGLDevice]); deviceOrPromise = luma.createDevice({ ...props.deviceProps, canvas: this._createCanvas(props) }); } this.animationLoop = this._createAnimationLoop(deviceOrPromise, props); this.setProps(props); if (props._typedArrayManagerProps) { typed_array_manager_default.setOptions(props._typedArrayManagerProps); } this.animationLoop.start(); } finalize() { this.animationLoop?.stop(); this.animationLoop?.destroy(); this.animationLoop = null; this._lastPointerDownInfo = null; this.layerManager?.finalize(); this.layerManager = null; this.viewManager?.finalize(); this.viewManager = null; this.effectManager?.finalize(); this.effectManager = null; this.deckRenderer?.finalize(); this.deckRenderer = null; this.deckPicker?.finalize(); this.deckPicker = null; this.eventManager?.destroy(); this.eventManager = null; this.widgetManager?.finalize(); this.widgetManager = null; if (!this.props.canvas && !this.props.device && !this.props.gl && this.canvas) { this.canvas.parentElement?.removeChild(this.canvas); this.canvas = null; } } setProps(props) { this.stats.get("setProps Time").timeStart(); if ("onLayerHover" in props) { log_default.removed("onLayerHover", "onHover")(); } if ("onLayerClick" in props) { log_default.removed("onLayerClick", "onClick")(); } if (props.initialViewState && !deepEqual2(this.props.initialViewState, props.initialViewState, 3)) { this.viewState = props.initialViewState; } Object.assign(this.props, props); this._setCanvasSize(this.props); const resolvedProps = Object.create(this.props); Object.assign(resolvedProps, { views: this._getViews(), width: this.width, height: this.height, viewState: this._getViewState() }); this.animationLoop?.setProps(resolvedProps); if (this.layerManager) { this.viewManager.setProps(resolvedProps); this.layerManager.activateViewport(this.getViewports()[0]); this.layerManager.setProps(resolvedProps); this.effectManager.setProps(resolvedProps); this.deckRenderer.setProps(resolvedProps); this.deckPicker.setProps(resolvedProps); this.widgetManager.setProps(resolvedProps); } this.stats.get("setProps Time").timeEnd(); } needsRedraw(opts = { clearRedrawFlags: false }) { if (!this.layerManager) { return false; } if (this.props._animate) { return "Deck._animate"; } let redraw = this._needsRedraw; if (opts.clearRedrawFlags) { this._needsRedraw = false; } const viewManagerNeedsRedraw = this.viewManager.needsRedraw(opts); const layerManagerNeedsRedraw = this.layerManager.needsRedraw(opts); const effectManagerNeedsRedraw = this.effectManager.needsRedraw(opts); const deckRendererNeedsRedraw = this.deckRenderer.needsRedraw(opts); redraw = redraw || viewManagerNeedsRedraw || layerManagerNeedsRedraw || effectManagerNeedsRedraw || deckRendererNeedsRedraw; return redraw; } redraw(reason) { if (!this.layerManager) { return; } let redrawReason = this.needsRedraw({ clearRedrawFlags: true }); redrawReason = reason || redrawReason; if (!redrawReason) { return; } this.stats.get("Redraw Count").incrementCount(); if (this.props._customRender) { this.props._customRender(redrawReason); } else { this._drawLayers(redrawReason); } } get isInitialized() { return this.viewManager !== null; } getViews() { assert8(this.viewManager); return this.viewManager.views; } getViewports(rect) { assert8(this.viewManager); return this.viewManager.getViewports(rect); } getCanvas() { return this.canvas; } pickObject(opts) { const infos = this._pick("pickObject", "pickObject Time", opts).result; return infos.length ? infos[0] : null; } pickMultipleObjects(opts) { opts.depth = opts.depth || 10; return this._pick("pickObject", "pickMultipleObjects Time", opts).result; } pickObjects(opts) { return this._pick("pickObjects", "pickObjects Time", opts); } _addResources(resources, forceUpdate = false) { for (const id in resources) { this.layerManager.resourceManager.add({ resourceId: id, data: resources[id], forceUpdate }); } } _removeResources(resourceIds) { for (const id of resourceIds) { this.layerManager.resourceManager.remove(id); } } _addDefaultEffect(effect) { this.effectManager.addDefaultEffect(effect); } _addDefaultShaderModule(module) { this.layerManager.addDefaultShaderModule(module); } _removeDefaultShaderModule(module) { this.layerManager?.removeDefaultShaderModule(module); } _pick(method, statKey, opts) { assert8(this.deckPicker); const { stats: stats2 } = this; stats2.get("Pick Count").incrementCount(); stats2.get(statKey).timeStart(); const infos = this.deckPicker[method]({ layers: this.layerManager.getLayers(opts), views: this.viewManager.getViews(), viewports: this.getViewports(opts), onViewportActive: this.layerManager.activateViewport, effects: this.effectManager.getEffects(), ...opts }); stats2.get(statKey).timeEnd(); return infos; } _createCanvas(props) { let canvas2 = props.canvas; if (typeof canvas2 === "string") { canvas2 = document.getElementById(canvas2); assert8(canvas2); } if (!canvas2) { canvas2 = document.createElement("canvas"); canvas2.id = props.id || "deckgl-overlay"; const parent = props.parent || document.body; parent.appendChild(canvas2); } Object.assign(canvas2.style, props.style); return canvas2; } _setCanvasSize(props) { if (!this.canvas) { return; } const { width, height } = props; if (width || width === 0) { const cssWidth = Number.isFinite(width) ? `${width}px` : width; this.canvas.style.width = cssWidth; } if (height || height === 0) { const cssHeight = Number.isFinite(height) ? `${height}px` : height; this.canvas.style.position = props.style?.position || "absolute"; this.canvas.style.height = cssHeight; } } _updateCanvasSize() { const { canvas: canvas2 } = this; if (!canvas2) { return; } const newWidth = canvas2.clientWidth ?? canvas2.width; const newHeight = canvas2.clientHeight ?? canvas2.height; if (newWidth !== this.width || newHeight !== this.height) { this.width = newWidth; this.height = newHeight; this.viewManager?.setProps({ width: newWidth, height: newHeight }); this.layerManager?.activateViewport(this.getViewports()[0]); this.props.onResize({ width: newWidth, height: newHeight }); } } _createAnimationLoop(deviceOrPromise, props) { const { gl, onError, useDevicePixels } = props; return new AnimationLoop({ device: deviceOrPromise, useDevicePixels, autoResizeDrawingBuffer: !gl, autoResizeViewport: false, onInitialize: (context) => this._setDevice(context.device), onRender: this._onRenderFrame.bind(this), onError }); } _getViewState() { return this.props.viewState || this.viewState; } _getViews() { const { views } = this.props; const normalizedViews = Array.isArray(views) ? views : views ? [views] : [new MapView({ id: "default-view" })]; if (normalizedViews.length && this.props.controller) { normalizedViews[0].props.controller = this.props.controller; } return normalizedViews; } _onContextLost() { const { onError } = this.props; if (this.animationLoop && onError) { onError(new Error("WebGL context is lost")); } } _pickAndCallback() { const { _pickRequest } = this; if (_pickRequest.event) { const { result, emptyInfo } = this._pick("pickObject", "pickObject Time", _pickRequest); this.cursorState.isHovering = result.length > 0; let pickedInfo = emptyInfo; let handled = false; for (const info of result) { pickedInfo = info; handled = info.layer?.onHover(info, _pickRequest.event) || handled; } if (!handled) { this.props.onHover?.(pickedInfo, _pickRequest.event); this.widgetManager.onHover(pickedInfo, _pickRequest.event); } _pickRequest.event = null; } } _updateCursor() { const container = this.props.parent || this.canvas; if (container) { container.style.cursor = this.props.getCursor(this.cursorState); } } _setDevice(device) { this.device = device; if (!this.animationLoop) { return; } if (!this.canvas) { this.canvas = this.device.canvasContext?.canvas; } this.device.setParametersWebGL({ blend: true, blendFunc: [GLEnum.SRC_ALPHA, GLEnum.ONE_MINUS_SRC_ALPHA, GLEnum.ONE, GLEnum.ONE_MINUS_SRC_ALPHA], polygonOffsetFill: true, depthTest: true, depthFunc: GLEnum.LEQUAL }); this.props.onDeviceInitialized(this.device); if (this.device instanceof WebGLDevice) { this.props.onWebGLInitialized(this.device.gl); } const timeline = new Timeline(); timeline.play(); this.animationLoop.attachTimeline(timeline); this.eventManager = new EventManager(this.props.parent || this.canvas, { touchAction: this.props.touchAction, recognizerOptions: this.props.eventRecognizerOptions, events: { pointerdown: this._onPointerDown, pointermove: this._onPointerMove, pointerleave: this._onPointerMove } }); for (const eventType in EVENTS) { this.eventManager.on(eventType, this._onEvent); } this.viewManager = new ViewManager({ timeline, eventManager: this.eventManager, onViewStateChange: this._onViewStateChange.bind(this), onInteractionStateChange: this._onInteractionStateChange.bind(this), views: this._getViews(), viewState: this._getViewState(), width: this.width, height: this.height }); const viewport = this.viewManager.getViewports()[0]; this.layerManager = new LayerManager(this.device, { deck: this, stats: this.stats, viewport, timeline }); this.effectManager = new EffectManager({ deck: this, device: this.device }); this.deckRenderer = new DeckRenderer(this.device); this.deckPicker = new DeckPicker(this.device); this.widgetManager = new WidgetManager({ deck: this, parentElement: this.canvas?.parentElement }); this.widgetManager.addDefault(new Tooltip()); this.setProps(this.props); this._updateCanvasSize(); this.props.onLoad(); } _drawLayers(redrawReason, renderOptions) { const { device, gl } = this.layerManager.context; this.props.onBeforeRender({ device, gl }); const opts = { target: this.props._framebuffer, layers: this.layerManager.getLayers(), viewports: this.viewManager.getViewports(), onViewportActive: this.layerManager.activateViewport, views: this.viewManager.getViews(), pass: "screen", effects: this.effectManager.getEffects(), ...renderOptions }; this.deckRenderer?.renderLayers(opts); if (opts.pass === "screen") { this.widgetManager.onRedraw({ viewports: opts.viewports, layers: opts.layers }); } this.props.onAfterRender({ device, gl }); } _onRenderFrame() { this._getFrameStats(); if (this._metricsCounter++ % 60 === 0) { this._getMetrics(); this.stats.reset(); log_default.table(4, this.metrics)(); if (this.props._onMetrics) { this.props._onMetrics(this.metrics); } } this._updateCanvasSize(); this._updateCursor(); this.layerManager.updateLayers(); this._pickAndCallback(); this.redraw(); if (this.viewManager) { this.viewManager.updateViewStates(); } } _onViewStateChange(params) { const viewState = this.props.onViewStateChange(params) || params.viewState; if (this.viewState) { this.viewState = { ...this.viewState, [params.viewId]: viewState }; if (!this.props.viewState) { if (this.viewManager) { this.viewManager.setProps({ viewState: this.viewState }); } } } } _onInteractionStateChange(interactionState) { this.cursorState.isDragging = interactionState.isDragging || false; this.props.onInteractionStateChange(interactionState); } _getFrameStats() { const { stats: stats2 } = this; stats2.get("frameRate").timeEnd(); stats2.get("frameRate").timeStart(); const animationLoopStats = this.animationLoop.stats; stats2.get("GPU Time").addTime(animationLoopStats.get("GPU Time").lastTiming); stats2.get("CPU Time").addTime(animationLoopStats.get("CPU Time").lastTiming); } _getMetrics() { const { metrics, stats: stats2 } = this; metrics.fps = stats2.get("frameRate").getHz(); metrics.setPropsTime = stats2.get("setProps Time").time; metrics.updateAttributesTime = stats2.get("Update Attributes").time; metrics.framesRedrawn = stats2.get("Redraw Count").count; metrics.pickTime = stats2.get("pickObject Time").time + stats2.get("pickMultipleObjects Time").time + stats2.get("pickObjects Time").time; metrics.pickCount = stats2.get("Pick Count").count; metrics.gpuTime = stats2.get("GPU Time").time; metrics.cpuTime = stats2.get("CPU Time").time; metrics.gpuTimePerFrame = stats2.get("GPU Time").getAverageTime(); metrics.cpuTimePerFrame = stats2.get("CPU Time").getAverageTime(); const memoryStats = luma.stats.get("Memory Usage"); metrics.bufferMemory = memoryStats.get("Buffer Memory").count; metrics.textureMemory = memoryStats.get("Texture Memory").count; metrics.renderbufferMemory = memoryStats.get("Renderbuffer Memory").count; metrics.gpuMemory = memoryStats.get("GPU Memory").count; } }; Deck.defaultProps = defaultProps; Deck.VERSION = VERSION5; // src/lib/attribute/gl-utils.ts function typedArrayFromDataType(type) { switch (type) { case "float64": return Float64Array; case "uint8": case "unorm8": return Uint8ClampedArray; default: return getTypedArrayFromDataType(type); } } var dataTypeFromTypedArray = getDataTypeFromTypedArray; function getBufferAttributeLayout(name2, accessor) { return { attribute: name2, format: accessor.size > 1 ? `${accessor.type}x${accessor.size}` : accessor.type, byteOffset: accessor.offset || 0 }; } function getStride(accessor) { return accessor.stride || accessor.size * accessor.bytesPerElement; } function bufferLayoutEqual(accessor1, accessor2) { return accessor1.type === accessor2.type && accessor1.size === accessor2.size && getStride(accessor1) === getStride(accessor2) && (accessor1.offset || 0) === (accessor2.offset || 0); } // src/lib/attribute/data-column.ts function resolveShaderAttribute(baseAccessor, shaderAttributeOptions) { if (shaderAttributeOptions.offset) { log_default.removed("shaderAttribute.offset", "vertexOffset, elementOffset")(); } const stride = getStride(baseAccessor); const vertexOffset = shaderAttributeOptions.vertexOffset !== void 0 ? shaderAttributeOptions.vertexOffset : baseAccessor.vertexOffset || 0; const elementOffset = shaderAttributeOptions.elementOffset || 0; const offset = vertexOffset * stride + elementOffset * baseAccessor.bytesPerElement + (baseAccessor.offset || 0); return { ...shaderAttributeOptions, offset, stride }; } function resolveDoublePrecisionShaderAttributes(baseAccessor, shaderAttributeOptions) { const resolvedOptions = resolveShaderAttribute(baseAccessor, shaderAttributeOptions); return { high: resolvedOptions, low: { ...resolvedOptions, offset: resolvedOptions.offset + baseAccessor.size * 4 } }; } var DataColumn = class { constructor(device, opts, state) { this._buffer = null; this.device = device; this.id = opts.id || ""; this.size = opts.size || 1; const logicalType = opts.logicalType || opts.type; const doublePrecision = logicalType === "float64"; let { defaultValue } = opts; defaultValue = Number.isFinite(defaultValue) ? [defaultValue] : defaultValue || new Array(this.size).fill(0); let bufferType; if (doublePrecision) { bufferType = "float32"; } else if (!logicalType && opts.isIndexed) { bufferType = "uint32"; } else { bufferType = logicalType || "float32"; } let defaultType = typedArrayFromDataType(logicalType || bufferType); this.doublePrecision = doublePrecision; if (doublePrecision && opts.fp64 === false) { defaultType = Float32Array; } this.value = null; this.settings = { ...opts, defaultType, defaultValue, logicalType, type: bufferType, normalized: bufferType.includes("norm"), size: this.size, bytesPerElement: defaultType.BYTES_PER_ELEMENT }; this.state = { ...state, externalBuffer: null, bufferAccessor: this.settings, allocatedValue: null, numInstances: 0, bounds: null, constant: false }; } get isConstant() { return this.state.constant; } get buffer() { return this._buffer; } get byteOffset() { const accessor = this.getAccessor(); if (accessor.vertexOffset) { return accessor.vertexOffset * getStride(accessor); } return 0; } get numInstances() { return this.state.numInstances; } set numInstances(n) { this.state.numInstances = n; } delete() { if (this._buffer) { this._buffer.delete(); this._buffer = null; } typed_array_manager_default.release(this.state.allocatedValue); } getBuffer() { if (this.state.constant) { return null; } return this.state.externalBuffer || this._buffer; } getValue(attributeName = this.id, options = null) { const result = {}; if (this.state.constant) { const value = this.value; if (options) { const shaderAttributeDef = resolveShaderAttribute(this.getAccessor(), options); const offset = shaderAttributeDef.offset / value.BYTES_PER_ELEMENT; const size = shaderAttributeDef.size || this.size; result[attributeName] = value.subarray(offset, offset + size); } else { result[attributeName] = value; } } else { result[attributeName] = this.getBuffer(); } if (this.doublePrecision) { if (this.value instanceof Float64Array) { result[`${attributeName}64Low`] = result[attributeName]; } else { result[`${attributeName}64Low`] = new Float32Array(this.size); } } return result; } _getBufferLayout(attributeName = this.id, options = null) { const accessor = this.getAccessor(); const attributes = []; const result = { name: this.id, byteStride: getStride(accessor), attributes }; if (this.doublePrecision) { const doubleShaderAttributeDefs = resolveDoublePrecisionShaderAttributes( accessor, options || {} ); attributes.push( getBufferAttributeLayout(attributeName, { ...accessor, ...doubleShaderAttributeDefs.high }), getBufferAttributeLayout(`${attributeName}64Low`, { ...accessor, ...doubleShaderAttributeDefs.low }) ); } else if (options) { const shaderAttributeDef = resolveShaderAttribute(accessor, options); attributes.push( getBufferAttributeLayout(attributeName, { ...accessor, ...shaderAttributeDef }) ); } else { attributes.push(getBufferAttributeLayout(attributeName, accessor)); } return result; } setAccessor(accessor) { this.state.bufferAccessor = accessor; } getAccessor() { return this.state.bufferAccessor; } getBounds() { if (this.state.bounds) { return this.state.bounds; } let result = null; if (this.state.constant && this.value) { const min4 = Array.from(this.value); result = [min4, min4]; } else { const { value, numInstances, size } = this; const len4 = numInstances * size; if (value && len4 && value.length >= len4) { const min4 = new Array(size).fill(Infinity); const max4 = new Array(size).fill(-Infinity); for (let i = 0; i < len4; ) { for (let j = 0; j < size; j++) { const v = value[i++]; if (v < min4[j]) min4[j] = v; if (v > max4[j]) max4[j] = v; } } result = [min4, max4]; } } this.state.bounds = result; return result; } setData(data) { const { state } = this; let opts; if (ArrayBuffer.isView(data)) { opts = { value: data }; } else if (data instanceof Buffer2) { opts = { buffer: data }; } else { opts = data; } const accessor = { ...this.settings, ...opts }; if (ArrayBuffer.isView(opts.value)) { if (!opts.type) { const is64Bit = this.doublePrecision && opts.value instanceof Float64Array; if (is64Bit) { accessor.type = "float32"; } else { const type = dataTypeFromTypedArray(opts.value); accessor.type = accessor.normalized ? type.replace("int", "norm") : type; } } accessor.bytesPerElement = opts.value.BYTES_PER_ELEMENT; accessor.stride = getStride(accessor); } state.bounds = null; if (opts.constant) { let value = opts.value; value = this._normalizeValue(value, [], 0); if (this.settings.normalized) { value = this.normalizeConstant(value); } const hasChanged = !state.constant || !this._areValuesEqual(value, this.value); if (!hasChanged) { return false; } state.externalBuffer = null; state.constant = true; this.value = ArrayBuffer.isView(value) ? value : new Float32Array(value); } else if (opts.buffer) { const buffer = opts.buffer; state.externalBuffer = buffer; state.constant = false; this.value = opts.value || null; } else if (opts.value) { this._checkExternalBuffer(opts); let value = opts.value; state.externalBuffer = null; state.constant = false; this.value = value; let { buffer } = this; const stride = getStride(accessor); const byteOffset = (accessor.vertexOffset || 0) * stride; if (this.doublePrecision && value instanceof Float64Array) { value = toDoublePrecisionArray(value, accessor); } if (this.settings.isIndexed) { const ArrayType2 = this.settings.defaultType; if (value.constructor !== ArrayType2) { value = new ArrayType2(value); } } const requiredBufferSize = value.byteLength + byteOffset + stride * 2; if (!buffer || buffer.byteLength < requiredBufferSize) { buffer = this._createBuffer(requiredBufferSize); } buffer.write(value, byteOffset); } this.setAccessor(accessor); return true; } updateSubBuffer(opts = {}) { this.state.bounds = null; const value = this.value; const { startOffset = 0, endOffset } = opts; this.buffer.write( this.doublePrecision && value instanceof Float64Array ? toDoublePrecisionArray(value, { size: this.size, startIndex: startOffset, endIndex: endOffset }) : value.subarray(startOffset, endOffset), startOffset * value.BYTES_PER_ELEMENT + this.byteOffset ); } allocate(numInstances, copy5 = false) { const { state } = this; const oldValue = state.allocatedValue; const value = typed_array_manager_default.allocate(oldValue, numInstances + 1, { size: this.size, type: this.settings.defaultType, copy: copy5 }); this.value = value; const { byteOffset } = this; let { buffer } = this; if (!buffer || buffer.byteLength < value.byteLength + byteOffset) { buffer = this._createBuffer(value.byteLength + byteOffset); if (copy5 && oldValue) { buffer.write( oldValue instanceof Float64Array ? toDoublePrecisionArray(oldValue, this) : oldValue, byteOffset ); } } state.allocatedValue = value; state.constant = false; state.externalBuffer = null; this.setAccessor(this.settings); return true; } _checkExternalBuffer(opts) { const { value } = opts; if (!ArrayBuffer.isView(value)) { throw new Error(`Attribute ${this.id} value is not TypedArray`); } const ArrayType2 = this.settings.defaultType; let illegalArrayType = false; if (this.doublePrecision) { illegalArrayType = value.BYTES_PER_ELEMENT < 4; } if (illegalArrayType) { throw new Error(`Attribute ${this.id} does not support ${value.constructor.name}`); } if (!(value instanceof ArrayType2) && this.settings.normalized && !("normalized" in opts)) { log_default.warn(`Attribute ${this.id} is normalized`)(); } } normalizeConstant(value) { switch (this.settings.type) { case "snorm8": return new Float32Array(value).map((x) => (x + 128) / 255 * 2 - 1); case "snorm16": return new Float32Array(value).map((x) => (x + 32768) / 65535 * 2 - 1); case "unorm8": return new Float32Array(value).map((x) => x / 255); case "unorm16": return new Float32Array(value).map((x) => x / 65535); default: return value; } } _normalizeValue(value, out, start) { const { defaultValue, size } = this.settings; if (Number.isFinite(value)) { out[start] = value; return out; } if (!value) { let i = size; while (--i >= 0) { out[start + i] = defaultValue[i]; } return out; } switch (size) { case 4: out[start + 3] = Number.isFinite(value[3]) ? value[3] : defaultValue[3]; case 3: out[start + 2] = Number.isFinite(value[2]) ? value[2] : defaultValue[2]; case 2: out[start + 1] = Number.isFinite(value[1]) ? value[1] : defaultValue[1]; case 1: out[start + 0] = Number.isFinite(value[0]) ? value[0] : defaultValue[0]; break; default: let i = size; while (--i >= 0) { out[start + i] = Number.isFinite(value[i]) ? value[i] : defaultValue[i]; } } return out; } _areValuesEqual(value1, value2) { if (!value1 || !value2) { return false; } const { size } = this; for (let i = 0; i < size; i++) { if (value1[i] !== value2[i]) { return false; } } return true; } _createBuffer(byteLength) { if (this._buffer) { this._buffer.destroy(); } const { isIndexed, type } = this.settings; this._buffer = this.device.createBuffer({ ...this._buffer?.props, id: this.id, usage: isIndexed ? Buffer2.INDEX : Buffer2.VERTEX, indexType: isIndexed ? type : void 0, byteLength }); return this._buffer; } }; // src/utils/iterable-utils.ts var EMPTY_ARRAY = []; var placeholderArray = []; function createIterable(data, startRow = 0, endRow = Infinity) { let iterable = EMPTY_ARRAY; const objectInfo = { index: -1, data, target: [] }; if (!data) { iterable = EMPTY_ARRAY; } else if (typeof data[Symbol.iterator] === "function") { iterable = data; } else if (data.length > 0) { placeholderArray.length = data.length; iterable = placeholderArray; } if (startRow > 0 || Number.isFinite(endRow)) { iterable = (Array.isArray(iterable) ? iterable : Array.from(iterable)).slice(startRow, endRow); objectInfo.index = startRow - 1; } return { iterable, objectInfo }; } function isAsyncIterable2(data) { return data && data[Symbol.asyncIterator]; } function getAccessorFromBuffer(typedArray, options) { const { size, stride, offset, startIndices, nested } = options; const bytesPerElement = typedArray.BYTES_PER_ELEMENT; const elementStride = stride ? stride / bytesPerElement : size; const elementOffset = offset ? offset / bytesPerElement : 0; const vertexCount = Math.floor((typedArray.length - elementOffset) / elementStride); return (_, { index: index2, target }) => { if (!startIndices) { const sourceIndex = index2 * elementStride + elementOffset; for (let j = 0; j < size; j++) { target[j] = typedArray[sourceIndex + j]; } return target; } const startIndex = startIndices[index2]; const endIndex = startIndices[index2 + 1] || vertexCount; let result; if (nested) { result = new Array(endIndex - startIndex); for (let i = startIndex; i < endIndex; i++) { const sourceIndex = i * elementStride + elementOffset; target = new Array(size); for (let j = 0; j < size; j++) { target[j] = typedArray[sourceIndex + j]; } result[i - startIndex] = target; } } else if (elementStride === size) { result = typedArray.subarray( startIndex * size + elementOffset, endIndex * size + elementOffset ); } else { result = new typedArray.constructor((endIndex - startIndex) * size); let targetIndex = 0; for (let i = startIndex; i < endIndex; i++) { const sourceIndex = i * elementStride + elementOffset; for (let j = 0; j < size; j++) { result[targetIndex++] = typedArray[sourceIndex + j]; } } } return result; }; } // src/utils/range.ts var EMPTY = []; var FULL = [[0, Infinity]]; function add5(rangeList, range) { if (rangeList === FULL) { return rangeList; } if (range[0] < 0) { range[0] = 0; } if (range[0] >= range[1]) { return rangeList; } const newRangeList = []; const len4 = rangeList.length; let insertPosition = 0; for (let i = 0; i < len4; i++) { const range0 = rangeList[i]; if (range0[1] < range[0]) { newRangeList.push(range0); insertPosition = i + 1; } else if (range0[0] > range[1]) { newRangeList.push(range0); } else { range = [Math.min(range0[0], range[0]), Math.max(range0[1], range[1])]; } } newRangeList.splice(insertPosition, 0, range); return newRangeList; } // src/lib/attribute/transition-settings.ts var DEFAULT_TRANSITION_SETTINGS = { interpolation: { duration: 0, easing: (t) => t }, spring: { stiffness: 0.05, damping: 0.5 } }; function normalizeTransitionSettings(userSettings, layerSettings) { if (!userSettings) { return null; } if (Number.isFinite(userSettings)) { userSettings = { type: "interpolation", duration: userSettings }; } const type = userSettings.type || "interpolation"; return { ...DEFAULT_TRANSITION_SETTINGS[type], ...layerSettings, ...userSettings, type }; } // src/lib/attribute/attribute.ts var Attribute2 = class extends DataColumn { constructor(device, opts) { super(device, opts, { startIndices: null, lastExternalBuffer: null, binaryValue: null, binaryAccessor: null, needsUpdate: true, needsRedraw: false, layoutChanged: false, updateRanges: FULL }); this.constant = false; this.settings.update = opts.update || (opts.accessor ? this._autoUpdater : void 0); Object.seal(this.settings); Object.seal(this.state); this._validateAttributeUpdaters(); } get startIndices() { return this.state.startIndices; } set startIndices(layout) { this.state.startIndices = layout; } needsUpdate() { return this.state.needsUpdate; } needsRedraw({ clearChangedFlags = false } = {}) { const needsRedraw = this.state.needsRedraw; this.state.needsRedraw = needsRedraw && !clearChangedFlags; return needsRedraw; } layoutChanged() { return this.state.layoutChanged; } setAccessor(accessor) { this.state.layoutChanged ||= !bufferLayoutEqual(accessor, this.getAccessor()); super.setAccessor(accessor); } getUpdateTriggers() { const { accessor } = this.settings; return [this.id].concat(typeof accessor !== "function" && accessor || []); } supportsTransition() { return Boolean(this.settings.transition); } getTransitionSetting(opts) { if (!opts || !this.supportsTransition()) { return null; } const { accessor } = this.settings; const layerSettings = this.settings.transition; const userSettings = Array.isArray(accessor) ? opts[accessor.find((a) => opts[a])] : opts[accessor]; return normalizeTransitionSettings(userSettings, layerSettings); } setNeedsUpdate(reason = this.id, dataRange) { this.state.needsUpdate = this.state.needsUpdate || reason; this.setNeedsRedraw(reason); if (dataRange) { const { startRow = 0, endRow = Infinity } = dataRange; this.state.updateRanges = add5(this.state.updateRanges, [startRow, endRow]); } else { this.state.updateRanges = FULL; } } clearNeedsUpdate() { this.state.needsUpdate = false; this.state.updateRanges = EMPTY; } setNeedsRedraw(reason = this.id) { this.state.needsRedraw = this.state.needsRedraw || reason; } allocate(numInstances) { const { state, settings } = this; if (settings.noAlloc) { return false; } if (settings.update) { super.allocate(numInstances, state.updateRanges !== FULL); return true; } return false; } updateBuffer({ numInstances, data, props, context }) { if (!this.needsUpdate()) { return false; } const { state: { updateRanges }, settings: { update, noAlloc } } = this; let updated = true; if (update) { for (const [startRow, endRow] of updateRanges) { update.call(context, this, { data, startRow, endRow, props, numInstances }); } if (!this.value) { } else if (this.constant || !this.buffer || this.buffer.byteLength < this.value.byteLength + this.byteOffset) { this.setData({ value: this.value, constant: this.constant }); this.constant = false; } else { for (const [startRow, endRow] of updateRanges) { const startOffset = Number.isFinite(startRow) ? this.getVertexOffset(startRow) : 0; const endOffset = Number.isFinite(endRow) ? this.getVertexOffset(endRow) : noAlloc || !Number.isFinite(numInstances) ? this.value.length : numInstances * this.size; super.updateSubBuffer({ startOffset, endOffset }); } } this._checkAttributeArray(); } else { updated = false; } this.clearNeedsUpdate(); this.setNeedsRedraw(); return updated; } setConstantValue(value) { if (value === void 0 || typeof value === "function") { return false; } const hasChanged = this.setData({ constant: true, value }); if (hasChanged) { this.setNeedsRedraw(); } this.clearNeedsUpdate(); return true; } setExternalBuffer(buffer) { const { state } = this; if (!buffer) { state.lastExternalBuffer = null; return false; } this.clearNeedsUpdate(); if (state.lastExternalBuffer === buffer) { return true; } state.lastExternalBuffer = buffer; this.setNeedsRedraw(); this.setData(buffer); return true; } setBinaryValue(buffer, startIndices = null) { const { state, settings } = this; if (!buffer) { state.binaryValue = null; state.binaryAccessor = null; return false; } if (settings.noAlloc) { return false; } if (state.binaryValue === buffer) { this.clearNeedsUpdate(); return true; } state.binaryValue = buffer; this.setNeedsRedraw(); const needsUpdate = settings.transform || startIndices !== this.startIndices; if (needsUpdate) { if (ArrayBuffer.isView(buffer)) { buffer = { value: buffer }; } const binaryValue = buffer; assert8(ArrayBuffer.isView(binaryValue.value), `invalid ${settings.accessor}`); const needsNormalize = Boolean(binaryValue.size) && binaryValue.size !== this.size; state.binaryAccessor = getAccessorFromBuffer(binaryValue.value, { size: binaryValue.size || this.size, stride: binaryValue.stride, offset: binaryValue.offset, startIndices, nested: needsNormalize }); return false; } this.clearNeedsUpdate(); this.setData(buffer); return true; } getVertexOffset(row) { const { startIndices } = this; const vertexIndex = startIndices ? row < startIndices.length ? startIndices[row] : this.numInstances : row; return vertexIndex * this.size; } getValue() { const shaderAttributeDefs = this.settings.shaderAttributes; const result = super.getValue(); if (!shaderAttributeDefs) { return result; } for (const shaderAttributeName in shaderAttributeDefs) { Object.assign( result, super.getValue(shaderAttributeName, shaderAttributeDefs[shaderAttributeName]) ); } return result; } getBufferLayout(modelInfo) { this.state.layoutChanged = false; const shaderAttributeDefs = this.settings.shaderAttributes; const result = super._getBufferLayout(); const { stepMode } = this.settings; if (stepMode === "dynamic") { result.stepMode = modelInfo ? modelInfo.isInstanced ? "instance" : "vertex" : "instance"; } else { result.stepMode = stepMode ?? "vertex"; } if (!shaderAttributeDefs) { return result; } for (const shaderAttributeName in shaderAttributeDefs) { const map3 = super._getBufferLayout( shaderAttributeName, shaderAttributeDefs[shaderAttributeName] ); result.attributes.push(...map3.attributes); } return result; } _autoUpdater(attribute, { data, startRow, endRow, props, numInstances }) { if (attribute.constant) { return; } const { settings, state, value, size, startIndices } = attribute; const { accessor, transform } = settings; const accessorFunc = state.binaryAccessor || (typeof accessor === "function" ? accessor : props[accessor]); assert8(typeof accessorFunc === "function", `accessor "${accessor}" is not a function`); let i = attribute.getVertexOffset(startRow); const { iterable, objectInfo } = createIterable(data, startRow, endRow); for (const object of iterable) { objectInfo.index++; let objectValue = accessorFunc(object, objectInfo); if (transform) { objectValue = transform.call(this, objectValue); } if (startIndices) { const numVertices = (objectInfo.index < startIndices.length - 1 ? startIndices[objectInfo.index + 1] : numInstances) - startIndices[objectInfo.index]; if (objectValue && Array.isArray(objectValue[0])) { let startIndex = i; for (const item of objectValue) { attribute._normalizeValue(item, value, startIndex); startIndex += size; } } else if (objectValue && objectValue.length > size) { value.set(objectValue, i); } else { attribute._normalizeValue(objectValue, objectInfo.target, 0); fillArray2({ target: value, source: objectInfo.target, start: i, count: numVertices }); } i += numVertices * size; } else { attribute._normalizeValue(objectValue, value, i); i += size; } } } _validateAttributeUpdaters() { const { settings } = this; const hasUpdater = settings.noAlloc || typeof settings.update === "function"; if (!hasUpdater) { throw new Error(`Attribute ${this.id} missing update or accessor`); } } _checkAttributeArray() { const { value } = this; const limit = Math.min(4, this.size); if (value && value.length >= limit) { let valid = true; switch (limit) { case 4: valid = valid && Number.isFinite(value[3]); case 3: valid = valid && Number.isFinite(value[2]); case 2: valid = valid && Number.isFinite(value[1]); case 1: valid = valid && Number.isFinite(value[0]); break; default: valid = false; } if (!valid) { throw new Error(`Illegal attribute generated for ${this.id}`); } } } }; // src/utils/array-utils.ts function padArrayChunk(options) { const { source, target, start = 0, size, getData } = options; const end = options.end || target.length; const sourceLength = source.length; const targetLength = end - start; if (sourceLength > targetLength) { target.set(source.subarray(0, targetLength), start); return; } target.set(source, start); if (!getData) { return; } let i = sourceLength; while (i < targetLength) { const datum = getData(i, source); for (let j = 0; j < size; j++) { target[start + i] = datum[j] || 0; i++; } } } function padArray({ source, target, size, getData, sourceStartIndices, targetStartIndices }) { if (!sourceStartIndices || !targetStartIndices) { padArrayChunk({ source, target, size, getData }); return target; } let sourceIndex = 0; let targetIndex = 0; const getChunkData = getData && ((i, chunk) => getData(i + targetIndex, chunk)); const n = Math.min(sourceStartIndices.length, targetStartIndices.length); for (let i = 1; i < n; i++) { const nextSourceIndex = sourceStartIndices[i] * size; const nextTargetIndex = targetStartIndices[i] * size; padArrayChunk({ source: source.subarray(sourceIndex, nextSourceIndex), target, start: targetIndex, end: nextTargetIndex, size, getData: getChunkData }); sourceIndex = nextSourceIndex; targetIndex = nextTargetIndex; } if (targetIndex < target.length) { padArrayChunk({ source: [], target, start: targetIndex, size, getData: getChunkData }); } return target; } // src/transitions/gpu-transition-utils.ts function cloneAttribute(attribute) { const { device, settings, value } = attribute; const newAttribute = new Attribute2(device, settings); newAttribute.setData({ value: value instanceof Float64Array ? new Float64Array(0) : new Float32Array(0), normalized: settings.normalized }); return newAttribute; } function getAttributeTypeFromSize(size) { switch (size) { case 1: return "float"; case 2: return "vec2"; case 3: return "vec3"; case 4: return "vec4"; default: throw new Error(`No defined attribute type for size "${size}"`); } } function getFloat32VertexFormat(size) { switch (size) { case 1: return "float32"; case 2: return "float32x2"; case 3: return "float32x3"; case 4: return "float32x4"; default: throw new Error("invalid type size"); } } function cycleBuffers(buffers) { buffers.push(buffers.shift()); } function getAttributeBufferLength(attribute, numInstances) { const { doublePrecision, settings, value, size } = attribute; const multiplier = doublePrecision && value instanceof Float64Array ? 2 : 1; let maxVertexOffset = 0; const { shaderAttributes } = attribute.settings; if (shaderAttributes) { for (const shaderAttribute of Object.values(shaderAttributes)) { maxVertexOffset = Math.max(maxVertexOffset, shaderAttribute.vertexOffset ?? 0); } } return (settings.noAlloc ? value.length : (numInstances + maxVertexOffset) * size) * multiplier; } function matchBuffer({ device, source, target }) { if (!target || target.byteLength < source.byteLength) { target?.destroy(); target = device.createBuffer({ byteLength: source.byteLength, usage: source.usage }); } return target; } function padBuffer({ device, buffer, attribute, fromLength, toLength, fromStartIndices, getData = (x) => x }) { const precisionMultiplier = attribute.doublePrecision && attribute.value instanceof Float64Array ? 2 : 1; const size = attribute.size * precisionMultiplier; const byteOffset = attribute.byteOffset; const targetByteOffset = attribute.settings.bytesPerElement < 4 ? byteOffset / attribute.settings.bytesPerElement * 4 : byteOffset; const toStartIndices = attribute.startIndices; const hasStartIndices = fromStartIndices && toStartIndices; const isConstant = attribute.isConstant; if (!hasStartIndices && buffer && fromLength >= toLength) { return buffer; } const ArrayType2 = attribute.value instanceof Float64Array ? Float32Array : attribute.value.constructor; const toData = isConstant ? attribute.value : new ArrayType2( attribute.getBuffer().readSyncWebGL(byteOffset, toLength * ArrayType2.BYTES_PER_ELEMENT).buffer ); if (attribute.settings.normalized && !isConstant) { const getter = getData; getData = (value, chunk) => attribute.normalizeConstant(getter(value, chunk)); } const getMissingData = isConstant ? (i, chunk) => getData(toData, chunk) : (i, chunk) => getData(toData.subarray(i + byteOffset, i + byteOffset + size), chunk); const source = buffer ? new Float32Array(buffer.readSyncWebGL(targetByteOffset, fromLength * 4).buffer) : new Float32Array(0); const target = new Float32Array(toLength); padArray({ source, target, sourceStartIndices: fromStartIndices, targetStartIndices: toStartIndices, size, getData: getMissingData }); if (!buffer || buffer.byteLength < target.byteLength + targetByteOffset) { buffer?.destroy(); buffer = device.createBuffer({ byteLength: target.byteLength + targetByteOffset, usage: GLEnum.DYNAMIC_COPY }); } buffer.write(target, targetByteOffset); return buffer; } // src/transitions/gpu-transition.ts var GPUTransitionBase = class { constructor({ device, attribute, timeline }) { this.buffers = []; this.currentLength = 0; this.device = device; this.transition = new Transition(timeline); this.attribute = attribute; this.attributeInTransition = cloneAttribute(attribute); this.currentStartIndices = attribute.startIndices; } get inProgress() { return this.transition.inProgress; } start(transitionSettings, numInstances, duration = Infinity) { this.settings = transitionSettings; this.currentStartIndices = this.attribute.startIndices; this.currentLength = getAttributeBufferLength(this.attribute, numInstances); this.transition.start({ ...transitionSettings, duration }); } update() { const updated = this.transition.update(); if (updated) { this.onUpdate(); } return updated; } setBuffer(buffer) { this.attributeInTransition.setData({ buffer, normalized: this.attribute.settings.normalized, value: this.attributeInTransition.value }); } cancel() { this.transition.cancel(); } delete() { this.cancel(); for (const buffer of this.buffers) { buffer.destroy(); } this.buffers.length = 0; } }; // src/transitions/gpu-interpolation-transition.ts var GPUInterpolationTransition = class extends GPUTransitionBase { constructor({ device, attribute, timeline }) { super({ device, attribute, timeline }); this.type = "interpolation"; this.transform = getTransform(device, attribute); } start(transitionSettings, numInstances) { const prevLength = this.currentLength; const prevStartIndices = this.currentStartIndices; super.start(transitionSettings, numInstances, transitionSettings.duration); if (transitionSettings.duration <= 0) { this.transition.cancel(); return; } const { buffers, attribute } = this; cycleBuffers(buffers); buffers[0] = padBuffer({ device: this.device, buffer: buffers[0], attribute, fromLength: prevLength, toLength: this.currentLength, fromStartIndices: prevStartIndices, getData: transitionSettings.enter }); buffers[1] = matchBuffer({ device: this.device, source: buffers[0], target: buffers[1] }); this.setBuffer(buffers[1]); const { transform } = this; const model = transform.model; let vertexCount = Math.floor(this.currentLength / attribute.size); if (useFp64(attribute)) { vertexCount /= 2; } model.setVertexCount(vertexCount); if (attribute.isConstant) { model.setAttributes({ aFrom: buffers[0] }); model.setConstantAttributes({ aTo: attribute.value }); } else { model.setAttributes({ aFrom: buffers[0], aTo: attribute.getBuffer() }); } transform.transformFeedback.setBuffers({ vCurrent: buffers[1] }); } onUpdate() { const { duration, easing } = this.settings; const { time } = this.transition; let t = time / duration; if (easing) { t = easing(t); } const { model } = this.transform; model.setUniforms({ time: t }); this.transform.run({ discard: true }); } delete() { super.delete(); this.transform.destroy(); } }; var vs5 = `#version 300 es #define SHADER_NAME interpolation-transition-vertex-shader uniform float time; in ATTRIBUTE_TYPE aFrom; in ATTRIBUTE_TYPE aTo; out ATTRIBUTE_TYPE vCurrent; void main(void) { vCurrent = mix(aFrom, aTo, time); gl_Position = vec4(0.0); } `; var vs64 = `#version 300 es #define SHADER_NAME interpolation-transition-vertex-shader uniform float time; in ATTRIBUTE_TYPE aFrom; in ATTRIBUTE_TYPE aFrom64Low; in ATTRIBUTE_TYPE aTo; in ATTRIBUTE_TYPE aTo64Low; out ATTRIBUTE_TYPE vCurrent; out ATTRIBUTE_TYPE vCurrent64Low; vec2 mix_fp64(vec2 a, vec2 b, float x) { vec2 range = sub_fp64(b, a); return sum_fp64(a, mul_fp64(range, vec2(x, 0.0))); } void main(void) { for (int i=0; i 0; if (!isTransitioning) { transition.end(); } } delete() { super.delete(); this.transform.destroy(); this.texture.destroy(); this.framebuffer.destroy(); } }; var vs6 = `#version 300 es #define SHADER_NAME spring-transition-vertex-shader #define EPSILON 0.00001 uniform float stiffness; uniform float damping; in ATTRIBUTE_TYPE aPrev; in ATTRIBUTE_TYPE aCur; in ATTRIBUTE_TYPE aTo; out ATTRIBUTE_TYPE vNext; out float vIsTransitioningFlag; ATTRIBUTE_TYPE getNextValue(ATTRIBUTE_TYPE cur, ATTRIBUTE_TYPE prev, ATTRIBUTE_TYPE dest) { ATTRIBUTE_TYPE velocity = cur - prev; ATTRIBUTE_TYPE delta = dest - cur; ATTRIBUTE_TYPE spring = delta * stiffness; ATTRIBUTE_TYPE damper = velocity * -1.0 * damping; return spring + damper + velocity + cur; } void main(void) { bool isTransitioning = length(aCur - aPrev) > EPSILON || length(aTo - aCur) > EPSILON; vIsTransitioningFlag = isTransitioning ? 1.0 : 0.0; vNext = getNextValue(aCur, aPrev, aTo); gl_Position = vec4(0, 0, 0, 1); gl_PointSize = 100.0; } `; var fs4 = `#version 300 es #define SHADER_NAME spring-transition-is-transitioning-fragment-shader in float vIsTransitioningFlag; out vec4 fragColor; void main(void) { if (vIsTransitioningFlag == 0.0) { discard; } fragColor = vec4(1.0); }`; function getTransform2(device, attribute) { const attributeType = getAttributeTypeFromSize(attribute.size); const format = getFloat32VertexFormat(attribute.size); return new BufferTransform(device, { vs: vs6, fs: fs4, bufferLayout: [ { name: "aPrev", format }, { name: "aCur", format }, { name: "aTo", format: attribute.getBufferLayout().attributes[0].format } ], varyings: ["vNext"], defines: { ATTRIBUTE_TYPE: attributeType }, parameters: { depthCompare: "always", blendColorOperation: "max", blendColorSrcFactor: "one", blendColorDstFactor: "one", blendAlphaOperation: "max", blendAlphaSrcFactor: "one", blendAlphaDstFactor: "one" } }); } function getTexture(device) { return device.createTexture({ data: new Uint8Array(4), format: "rgba8unorm", mipmaps: false, width: 1, height: 1 }); } function getFramebuffer3(device, texture) { return device.createFramebuffer({ id: "spring-transition-is-transitioning-framebuffer", width: 1, height: 1, colorAttachments: [texture] }); } // src/lib/attribute/attribute-transition-manager.ts var TRANSITION_TYPES = { interpolation: GPUInterpolationTransition, spring: GPUSpringTransition }; var AttributeTransitionManager = class { constructor(device, { id, timeline }) { if (!device) throw new Error("AttributeTransitionManager is constructed without device"); this.id = id; this.device = device; this.timeline = timeline; this.transitions = {}; this.needsRedraw = false; this.numInstances = 1; } finalize() { for (const attributeName in this.transitions) { this._removeTransition(attributeName); } } update({ attributes, transitions, numInstances }) { this.numInstances = numInstances || 1; for (const attributeName in attributes) { const attribute = attributes[attributeName]; const settings = attribute.getTransitionSetting(transitions); if (!settings) continue; this._updateAttribute(attributeName, attribute, settings); } for (const attributeName in this.transitions) { const attribute = attributes[attributeName]; if (!attribute || !attribute.getTransitionSetting(transitions)) { this._removeTransition(attributeName); } } } hasAttribute(attributeName) { const transition = this.transitions[attributeName]; return transition && transition.inProgress; } getAttributes() { const animatedAttributes = {}; for (const attributeName in this.transitions) { const transition = this.transitions[attributeName]; if (transition.inProgress) { animatedAttributes[attributeName] = transition.attributeInTransition; } } return animatedAttributes; } run() { if (this.numInstances === 0) { return false; } for (const attributeName in this.transitions) { const updated = this.transitions[attributeName].update(); if (updated) { this.needsRedraw = true; } } const needsRedraw = this.needsRedraw; this.needsRedraw = false; return needsRedraw; } _removeTransition(attributeName) { this.transitions[attributeName].delete(); delete this.transitions[attributeName]; } _updateAttribute(attributeName, attribute, settings) { const transition = this.transitions[attributeName]; let isNew = !transition || transition.type !== settings.type; if (isNew) { if (transition) { this._removeTransition(attributeName); } const TransitionType = TRANSITION_TYPES[settings.type]; if (TransitionType) { this.transitions[attributeName] = new TransitionType({ attribute, timeline: this.timeline, device: this.device }); } else { log_default.error(`unsupported transition type '${settings.type}'`)(); isNew = false; } } if (isNew || attribute.needsRedraw()) { this.needsRedraw = true; this.transitions[attributeName].start(settings, this.numInstances); } } }; // src/lib/attribute/attribute-manager.ts var TRACE_INVALIDATE = "attributeManager.invalidate"; var TRACE_UPDATE_START = "attributeManager.updateStart"; var TRACE_UPDATE_END = "attributeManager.updateEnd"; var TRACE_ATTRIBUTE_UPDATE_START = "attribute.updateStart"; var TRACE_ATTRIBUTE_ALLOCATE = "attribute.allocate"; var TRACE_ATTRIBUTE_UPDATE_END = "attribute.updateEnd"; var AttributeManager = class { constructor(device, { id = "attribute-manager", stats: stats2, timeline } = {}) { this.mergeBoundsMemoized = memoize(mergeBounds); this.id = id; this.device = device; this.attributes = {}; this.updateTriggers = {}; this.needsRedraw = true; this.userData = {}; this.stats = stats2; this.attributeTransitionManager = new AttributeTransitionManager(device, { id: `${id}-transitions`, timeline }); Object.seal(this); } finalize() { for (const attributeName in this.attributes) { this.attributes[attributeName].delete(); } this.attributeTransitionManager.finalize(); } getNeedsRedraw(opts = { clearRedrawFlags: false }) { const redraw = this.needsRedraw; this.needsRedraw = this.needsRedraw && !opts.clearRedrawFlags; return redraw && this.id; } setNeedsRedraw() { this.needsRedraw = true; } add(attributes) { this._add(attributes); } addInstanced(attributes) { this._add(attributes, { stepMode: "instance" }); } remove(attributeNameArray) { for (const name2 of attributeNameArray) { if (this.attributes[name2] !== void 0) { this.attributes[name2].delete(); delete this.attributes[name2]; } } } invalidate(triggerName, dataRange) { const invalidatedAttributes = this._invalidateTrigger(triggerName, dataRange); debug(TRACE_INVALIDATE, this, triggerName, invalidatedAttributes); } invalidateAll(dataRange) { for (const attributeName in this.attributes) { this.attributes[attributeName].setNeedsUpdate(attributeName, dataRange); } debug(TRACE_INVALIDATE, this, "all"); } update({ data, numInstances, startIndices = null, transitions, props = {}, buffers = {}, context = {} }) { let updated = false; debug(TRACE_UPDATE_START, this); if (this.stats) { this.stats.get("Update Attributes").timeStart(); } for (const attributeName in this.attributes) { const attribute = this.attributes[attributeName]; const accessorName = attribute.settings.accessor; attribute.startIndices = startIndices; attribute.numInstances = numInstances; if (props[attributeName]) { log_default.removed(`props.${attributeName}`, `data.attributes.${attributeName}`)(); } if (attribute.setExternalBuffer(buffers[attributeName])) { } else if (attribute.setBinaryValue( typeof accessorName === "string" ? buffers[accessorName] : void 0, data.startIndices )) { } else if (typeof accessorName === "string" && !buffers[accessorName] && attribute.setConstantValue(props[accessorName])) { } else if (attribute.needsUpdate()) { updated = true; this._updateAttribute({ attribute, numInstances, data, props, context }); } this.needsRedraw = this.needsRedraw || attribute.needsRedraw(); } if (updated) { debug(TRACE_UPDATE_END, this, numInstances); } if (this.stats) { this.stats.get("Update Attributes").timeEnd(); } this.attributeTransitionManager.update({ attributes: this.attributes, numInstances, transitions }); } updateTransition() { const { attributeTransitionManager } = this; const transitionUpdated = attributeTransitionManager.run(); this.needsRedraw = this.needsRedraw || transitionUpdated; return transitionUpdated; } getAttributes() { return { ...this.attributes, ...this.attributeTransitionManager.getAttributes() }; } getBounds(attributeNames) { const bounds = attributeNames.map((attributeName) => this.attributes[attributeName]?.getBounds()); return this.mergeBoundsMemoized(bounds); } getChangedAttributes(opts = { clearChangedFlags: false }) { const { attributes, attributeTransitionManager } = this; const changedAttributes = { ...attributeTransitionManager.getAttributes() }; for (const attributeName in attributes) { const attribute = attributes[attributeName]; if (attribute.needsRedraw(opts) && !attributeTransitionManager.hasAttribute(attributeName)) { changedAttributes[attributeName] = attribute; } } return changedAttributes; } getBufferLayouts(modelInfo) { return Object.values(this.getAttributes()).map( (attribute) => attribute.getBufferLayout(modelInfo) ); } _add(attributes, overrideOptions) { for (const attributeName in attributes) { const attribute = attributes[attributeName]; const props = { ...attribute, id: attributeName, size: attribute.isIndexed && 1 || attribute.size || 1, ...overrideOptions }; this.attributes[attributeName] = new Attribute2(this.device, props); } this._mapUpdateTriggersToAttributes(); } _mapUpdateTriggersToAttributes() { const triggers = {}; for (const attributeName in this.attributes) { const attribute = this.attributes[attributeName]; attribute.getUpdateTriggers().forEach((triggerName) => { if (!triggers[triggerName]) { triggers[triggerName] = []; } triggers[triggerName].push(attributeName); }); } this.updateTriggers = triggers; } _invalidateTrigger(triggerName, dataRange) { const { attributes, updateTriggers } = this; const invalidatedAttributes = updateTriggers[triggerName]; if (invalidatedAttributes) { invalidatedAttributes.forEach((name2) => { const attribute = attributes[name2]; if (attribute) { attribute.setNeedsUpdate(attribute.id, dataRange); } }); } return invalidatedAttributes; } _updateAttribute(opts) { const { attribute, numInstances } = opts; debug(TRACE_ATTRIBUTE_UPDATE_START, attribute); if (attribute.constant) { attribute.setConstantValue(attribute.value); return; } if (attribute.allocate(numInstances)) { debug(TRACE_ATTRIBUTE_ALLOCATE, attribute, numInstances); } const updated = attribute.updateBuffer(opts); if (updated) { this.needsRedraw = true; debug(TRACE_ATTRIBUTE_UPDATE_END, attribute, numInstances); } } }; // src/transitions/cpu-interpolation-transition.ts var CPUInterpolationTransition = class extends Transition { get value() { return this._value; } _onUpdate() { const { time, settings: { fromValue, toValue, duration, easing } } = this; const t = easing(time / duration); this._value = lerp(fromValue, toValue, t); } }; // src/transitions/cpu-spring-transition.ts var EPSILON4 = 1e-5; function updateSpringElement(prev, cur, dest, damping, stiffness) { const velocity = cur - prev; const delta = dest - cur; const spring = delta * stiffness; const damper = -velocity * damping; return spring + damper + velocity + cur; } function updateSpring(prev, cur, dest, damping, stiffness) { if (Array.isArray(dest)) { const next = []; for (let i = 0; i < dest.length; i++) { next[i] = updateSpringElement(prev[i], cur[i], dest[i], damping, stiffness); } return next; } return updateSpringElement(prev, cur, dest, damping, stiffness); } function distance4(value1, value2) { if (Array.isArray(value1)) { let distanceSquare = 0; for (let i = 0; i < value1.length; i++) { const d = value1[i] - value2[i]; distanceSquare += d * d; } return Math.sqrt(distanceSquare); } return Math.abs(value1 - value2); } var CPUSpringTransition = class extends Transition { get value() { return this._currValue; } _onUpdate() { const { fromValue, toValue, damping, stiffness } = this.settings; const { _prevValue = fromValue, _currValue = fromValue } = this; let nextValue = updateSpring(_prevValue, _currValue, toValue, damping, stiffness); const delta = distance4(nextValue, toValue); const velocity = distance4(nextValue, _currValue); if (delta < EPSILON4 && velocity < EPSILON4) { nextValue = toValue; this.end(); } this._prevValue = _currValue; this._currValue = nextValue; } }; // src/lib/uniform-transition-manager.ts var TRANSITION_TYPES2 = { interpolation: CPUInterpolationTransition, spring: CPUSpringTransition }; var UniformTransitionManager = class { constructor(timeline) { this.transitions = /* @__PURE__ */ new Map(); this.timeline = timeline; } get active() { return this.transitions.size > 0; } add(key, fromValue, toValue, settings) { const { transitions } = this; if (transitions.has(key)) { const transition2 = transitions.get(key); const { value = transition2.settings.fromValue } = transition2; fromValue = value; this.remove(key); } settings = normalizeTransitionSettings(settings); if (!settings) { return; } const TransitionType = TRANSITION_TYPES2[settings.type]; if (!TransitionType) { log_default.error(`unsupported transition type '${settings.type}'`)(); return; } const transition = new TransitionType(this.timeline); transition.start({ ...settings, fromValue, toValue }); transitions.set(key, transition); } remove(key) { const { transitions } = this; if (transitions.has(key)) { transitions.get(key).cancel(); transitions.delete(key); } } update() { const propsInTransition = {}; for (const [key, transition] of this.transitions) { transition.update(); propsInTransition[key] = transition.value; if (!transition.inProgress) { this.remove(key); } } return propsInTransition; } clear() { for (const key of this.transitions.keys()) { this.remove(key); } } }; // src/lifecycle/props.ts function validateProps(props) { const propTypes = props[PROP_TYPES_SYMBOL]; for (const propName in propTypes) { const propType = propTypes[propName]; const { validate } = propType; if (validate && !validate(props[propName], propType)) { throw new Error(`Invalid prop ${propName}: ${props[propName]}`); } } } function diffProps(props, oldProps) { const propsChangedReason = compareProps({ newProps: props, oldProps, propTypes: props[PROP_TYPES_SYMBOL], ignoreProps: { data: null, updateTriggers: null, extensions: null, transitions: null } }); const dataChangedReason = diffDataProps(props, oldProps); let updateTriggersChangedReason = false; if (!dataChangedReason) { updateTriggersChangedReason = diffUpdateTriggers(props, oldProps); } return { dataChanged: dataChangedReason, propsChanged: propsChangedReason, updateTriggersChanged: updateTriggersChangedReason, extensionsChanged: diffExtensions(props, oldProps), transitionsChanged: diffTransitions(props, oldProps) }; } function diffTransitions(props, oldProps) { if (!props.transitions) { return false; } const result = {}; const propTypes = props[PROP_TYPES_SYMBOL]; let changed = false; for (const key in props.transitions) { const propType = propTypes[key]; const type = propType && propType.type; const isTransitionable = type === "number" || type === "color" || type === "array"; if (isTransitionable && comparePropValues(props[key], oldProps[key], propType)) { result[key] = true; changed = true; } } return changed ? result : false; } function compareProps({ newProps, oldProps, ignoreProps = {}, propTypes = {}, triggerName = "props" }) { if (oldProps === newProps) { return false; } if (typeof newProps !== "object" || newProps === null) { return `${triggerName} changed shallowly`; } if (typeof oldProps !== "object" || oldProps === null) { return `${triggerName} changed shallowly`; } for (const key of Object.keys(newProps)) { if (!(key in ignoreProps)) { if (!(key in oldProps)) { return `${triggerName}.${key} added`; } const changed = comparePropValues(newProps[key], oldProps[key], propTypes[key]); if (changed) { return `${triggerName}.${key} ${changed}`; } } } for (const key of Object.keys(oldProps)) { if (!(key in ignoreProps)) { if (!(key in newProps)) { return `${triggerName}.${key} dropped`; } if (!Object.hasOwnProperty.call(newProps, key)) { const changed = comparePropValues(newProps[key], oldProps[key], propTypes[key]); if (changed) { return `${triggerName}.${key} ${changed}`; } } } } return false; } function comparePropValues(newProp, oldProp, propType) { let equal = propType && propType.equal; if (equal && !equal(newProp, oldProp, propType)) { return "changed deeply"; } if (!equal) { equal = newProp && oldProp && newProp.equals; if (equal && !equal.call(newProp, oldProp)) { return "changed deeply"; } } if (!equal && oldProp !== newProp) { return "changed shallowly"; } return null; } function diffDataProps(props, oldProps) { if (oldProps === null) { return "oldProps is null, initial diff"; } let dataChanged = false; const { dataComparator, _dataDiff } = props; if (dataComparator) { if (!dataComparator(props.data, oldProps.data)) { dataChanged = "Data comparator detected a change"; } } else if (props.data !== oldProps.data) { dataChanged = "A new data container was supplied"; } if (dataChanged && _dataDiff) { dataChanged = _dataDiff(props.data, oldProps.data) || dataChanged; } return dataChanged; } function diffUpdateTriggers(props, oldProps) { if (oldProps === null) { return { all: true }; } if ("all" in props.updateTriggers) { const diffReason = diffUpdateTrigger(props, oldProps, "all"); if (diffReason) { return { all: true }; } } const reason = {}; let changed = false; for (const triggerName in props.updateTriggers) { if (triggerName !== "all") { const diffReason = diffUpdateTrigger(props, oldProps, triggerName); if (diffReason) { reason[triggerName] = true; changed = true; } } } return changed ? reason : false; } function diffExtensions(props, oldProps) { if (oldProps === null) { return true; } const oldExtensions = oldProps.extensions; const { extensions } = props; if (extensions === oldExtensions) { return false; } if (!oldExtensions || !extensions) { return true; } if (extensions.length !== oldExtensions.length) { return true; } for (let i = 0; i < extensions.length; i++) { if (!extensions[i].equals(oldExtensions[i])) { return true; } } return false; } function diffUpdateTrigger(props, oldProps, triggerName) { let newTriggers = props.updateTriggers[triggerName]; newTriggers = newTriggers === void 0 || newTriggers === null ? {} : newTriggers; let oldTriggers = oldProps.updateTriggers[triggerName]; oldTriggers = oldTriggers === void 0 || oldTriggers === null ? {} : oldTriggers; const diffReason = compareProps({ oldProps: oldTriggers, newProps: newTriggers, triggerName }); return diffReason; } // src/utils/count.ts var ERR_NOT_OBJECT = "count(): argument not an object"; var ERR_NOT_CONTAINER = "count(): argument not a container"; function count(container) { if (!isObject2(container)) { throw new Error(ERR_NOT_OBJECT); } if (typeof container.count === "function") { return container.count(); } if (Number.isFinite(container.size)) { return container.size; } if (Number.isFinite(container.length)) { return container.length; } if (isPlainObject(container)) { return Object.keys(container).length; } throw new Error(ERR_NOT_CONTAINER); } function isPlainObject(value) { return value !== null && typeof value === "object" && value.constructor === Object; } function isObject2(value) { return value !== null && typeof value === "object"; } // src/utils/shader.ts function mergeShaders(target, source) { if (!source) { return target; } const result = { ...target, ...source }; if ("defines" in source) { result.defines = { ...target.defines, ...source.defines }; } if ("modules" in source) { result.modules = (target.modules || []).concat(source.modules); if (source.modules.some((module) => module.name === "project64")) { const index2 = result.modules.findIndex((module) => module.name === "project32"); if (index2 >= 0) { result.modules.splice(index2, 1); } } } if ("inject" in source) { if (!target.inject) { result.inject = source.inject; } else { const mergedInjection = { ...target.inject }; for (const key in source.inject) { mergedInjection[key] = (mergedInjection[key] || "") + source.inject[key]; } result.inject = mergedInjection; } } return result; } // src/utils/texture.ts var DEFAULT_TEXTURE_PARAMETERS = { minFilter: "linear", mipmapFilter: "linear", magFilter: "linear", addressModeU: "clamp-to-edge", addressModeV: "clamp-to-edge" }; var internalTextures = {}; function createTexture(owner, device, image, sampler) { if (image instanceof Texture) { return image; } else if (image.constructor && image.constructor.name !== "Object") { image = { data: image }; } let samplerParameters = null; if (image.compressed) { samplerParameters = { minFilter: "linear", mipmapFilter: image.data.length > 1 ? "nearest" : "linear" }; } const texture = device.createTexture({ ...image, sampler: { ...DEFAULT_TEXTURE_PARAMETERS, ...samplerParameters, ...sampler } }); internalTextures[texture.id] = owner; return texture; } function destroyTexture(owner, texture) { if (!texture || !(texture instanceof Texture)) { return; } if (internalTextures[texture.id] === owner) { texture.delete(); delete internalTextures[texture.id]; } } // src/lifecycle/prop-types.ts var TYPE_DEFINITIONS = { boolean: { validate(value, propType) { return true; }, equal(value1, value2, propType) { return Boolean(value1) === Boolean(value2); } }, number: { validate(value, propType) { return Number.isFinite(value) && (!("max" in propType) || value <= propType.max) && (!("min" in propType) || value >= propType.min); } }, color: { validate(value, propType) { return propType.optional && !value || isArray3(value) && (value.length === 3 || value.length === 4); }, equal(value1, value2, propType) { return deepEqual2(value1, value2, 1); } }, accessor: { validate(value, propType) { const valueType = getTypeOf2(value); return valueType === "function" || valueType === getTypeOf2(propType.value); }, equal(value1, value2, propType) { if (typeof value2 === "function") { return true; } return deepEqual2(value1, value2, 1); } }, array: { validate(value, propType) { return propType.optional && !value || isArray3(value); }, equal(value1, value2, propType) { const { compare } = propType; const depth = Number.isInteger(compare) ? compare : compare ? 1 : 0; return compare ? deepEqual2(value1, value2, depth) : value1 === value2; } }, object: { equal(value1, value2, propType) { if (propType.ignore) { return true; } const { compare } = propType; const depth = Number.isInteger(compare) ? compare : compare ? 1 : 0; return compare ? deepEqual2(value1, value2, depth) : value1 === value2; } }, function: { validate(value, propType) { return propType.optional && !value || typeof value === "function"; }, equal(value1, value2, propType) { const shouldIgnore = !propType.compare && propType.ignore !== false; return shouldIgnore || value1 === value2; } }, data: { transform: (value, propType, component) => { if (!value) { return value; } const { dataTransform } = component.props; if (dataTransform) { return dataTransform(value); } if (typeof value.shape === "string" && value.shape.endsWith("-table") && Array.isArray(value.data)) { return value.data; } return value; } }, image: { transform: (value, propType, component) => { const context = component.context; if (!context || !context.device) { return null; } return createTexture(component.id, context.device, value, { ...propType.parameters, ...component.props.textureParameters }); }, release: (value, propType, component) => { destroyTexture(component.id, value); } } }; function parsePropTypes(propDefs) { const propTypes = {}; const defaultProps3 = {}; const deprecatedProps = {}; for (const [propName, propDef] of Object.entries(propDefs)) { const deprecated = propDef?.deprecatedFor; if (deprecated) { deprecatedProps[propName] = Array.isArray(deprecated) ? deprecated : [deprecated]; } else { const propType = parsePropType(propName, propDef); propTypes[propName] = propType; defaultProps3[propName] = propType.value; } } return { propTypes, defaultProps: defaultProps3, deprecatedProps }; } function parsePropType(name2, propDef) { switch (getTypeOf2(propDef)) { case "object": return normalizePropDefinition(name2, propDef); case "array": return normalizePropDefinition(name2, { type: "array", value: propDef, compare: false }); case "boolean": return normalizePropDefinition(name2, { type: "boolean", value: propDef }); case "number": return normalizePropDefinition(name2, { type: "number", value: propDef }); case "function": return normalizePropDefinition(name2, { type: "function", value: propDef, compare: true }); default: return { name: name2, type: "unknown", value: propDef }; } } function normalizePropDefinition(name2, propDef) { if (!("type" in propDef)) { if (!("value" in propDef)) { return { name: name2, type: "object", value: propDef }; } return { name: name2, type: getTypeOf2(propDef.value), ...propDef }; } return { name: name2, ...TYPE_DEFINITIONS[propDef.type], ...propDef }; } function isArray3(value) { return Array.isArray(value) || ArrayBuffer.isView(value); } function getTypeOf2(value) { if (isArray3(value)) { return "array"; } if (value === null) { return "null"; } return typeof value; } // src/lifecycle/create-props.ts function createProps(component, propObjects) { let extensions; for (let i = propObjects.length - 1; i >= 0; i--) { const props = propObjects[i]; if ("extensions" in props) { extensions = props.extensions; } } const propsPrototype = getPropsPrototype(component.constructor, extensions); const propsInstance = Object.create(propsPrototype); propsInstance[COMPONENT_SYMBOL] = component; propsInstance[ASYNC_ORIGINAL_SYMBOL] = {}; propsInstance[ASYNC_RESOLVED_SYMBOL] = {}; for (let i = 0; i < propObjects.length; ++i) { const props = propObjects[i]; for (const key in props) { propsInstance[key] = props[key]; } } Object.freeze(propsInstance); return propsInstance; } var MergedDefaultPropsCacheKey = "_mergedDefaultProps"; function getPropsPrototype(componentClass, extensions) { if (!(componentClass instanceof Component.constructor)) return {}; let cacheKey = MergedDefaultPropsCacheKey; if (extensions) { for (const extension of extensions) { const ExtensionClass = extension.constructor; if (ExtensionClass) { cacheKey += `:${ExtensionClass.extensionName || ExtensionClass.name}`; } } } const defaultProps3 = getOwnProperty(componentClass, cacheKey); if (!defaultProps3) { return componentClass[cacheKey] = createPropsPrototypeAndTypes( componentClass, extensions || [] ); } return defaultProps3; } function createPropsPrototypeAndTypes(componentClass, extensions) { const parent = componentClass.prototype; if (!parent) { return null; } const parentClass = Object.getPrototypeOf(componentClass); const parentDefaultProps = getPropsPrototype(parentClass); const componentDefaultProps = getOwnProperty(componentClass, "defaultProps") || {}; const componentPropDefs = parsePropTypes(componentDefaultProps); const defaultProps3 = Object.assign( /* @__PURE__ */ Object.create(null), parentDefaultProps, componentPropDefs.defaultProps ); const propTypes = Object.assign( /* @__PURE__ */ Object.create(null), parentDefaultProps?.[PROP_TYPES_SYMBOL], componentPropDefs.propTypes ); const deprecatedProps = Object.assign( /* @__PURE__ */ Object.create(null), parentDefaultProps?.[DEPRECATED_PROPS_SYMBOL], componentPropDefs.deprecatedProps ); for (const extension of extensions) { const extensionDefaultProps = getPropsPrototype(extension.constructor); if (extensionDefaultProps) { Object.assign(defaultProps3, extensionDefaultProps); Object.assign(propTypes, extensionDefaultProps[PROP_TYPES_SYMBOL]); Object.assign(deprecatedProps, extensionDefaultProps[DEPRECATED_PROPS_SYMBOL]); } } createPropsPrototype(defaultProps3, componentClass); addAsyncPropsToPropPrototype(defaultProps3, propTypes); addDeprecatedPropsToPropPrototype(defaultProps3, deprecatedProps); defaultProps3[PROP_TYPES_SYMBOL] = propTypes; defaultProps3[DEPRECATED_PROPS_SYMBOL] = deprecatedProps; if (extensions.length === 0 && !hasOwnProperty(componentClass, "_propTypes")) { componentClass._propTypes = propTypes; } return defaultProps3; } function createPropsPrototype(defaultProps3, componentClass) { const id = getComponentName(componentClass); Object.defineProperties(defaultProps3, { id: { writable: true, value: id } }); } function addDeprecatedPropsToPropPrototype(defaultProps3, deprecatedProps) { for (const propName in deprecatedProps) { Object.defineProperty(defaultProps3, propName, { enumerable: false, set(newValue) { const nameStr = `${this.id}: ${propName}`; for (const newPropName of deprecatedProps[propName]) { if (!hasOwnProperty(this, newPropName)) { this[newPropName] = newValue; } } log_default.deprecated(nameStr, deprecatedProps[propName].join("/"))(); } }); } } function addAsyncPropsToPropPrototype(defaultProps3, propTypes) { const defaultValues = {}; const descriptors = {}; for (const propName in propTypes) { const propType = propTypes[propName]; const { name: name2, value } = propType; if (propType.async) { defaultValues[name2] = value; descriptors[name2] = getDescriptorForAsyncProp(name2); } } defaultProps3[ASYNC_DEFAULTS_SYMBOL] = defaultValues; defaultProps3[ASYNC_ORIGINAL_SYMBOL] = {}; Object.defineProperties(defaultProps3, descriptors); } function getDescriptorForAsyncProp(name2) { return { enumerable: true, set(newValue) { if (typeof newValue === "string" || newValue instanceof Promise || isAsyncIterable2(newValue)) { this[ASYNC_ORIGINAL_SYMBOL][name2] = newValue; } else { this[ASYNC_RESOLVED_SYMBOL][name2] = newValue; } }, get() { if (this[ASYNC_RESOLVED_SYMBOL]) { if (name2 in this[ASYNC_RESOLVED_SYMBOL]) { const value = this[ASYNC_RESOLVED_SYMBOL][name2]; return value || this[ASYNC_DEFAULTS_SYMBOL][name2]; } if (name2 in this[ASYNC_ORIGINAL_SYMBOL]) { const state = this[COMPONENT_SYMBOL] && this[COMPONENT_SYMBOL].internalState; if (state && state.hasAsyncProp(name2)) { return state.getAsyncProp(name2) || this[ASYNC_DEFAULTS_SYMBOL][name2]; } } } return this[ASYNC_DEFAULTS_SYMBOL][name2]; } }; } function hasOwnProperty(object, prop) { return Object.prototype.hasOwnProperty.call(object, prop); } function getOwnProperty(object, prop) { return hasOwnProperty(object, prop) && object[prop]; } function getComponentName(componentClass) { const componentName = componentClass.componentName; if (!componentName) { log_default.warn(`${componentClass.name}.componentName not specified`)(); } return componentName || componentClass.name; } // src/lifecycle/component.ts var counter = 0; var Component = class { constructor(...propObjects) { this.props = createProps(this, propObjects); this.id = this.props.id; this.count = counter++; } clone(newProps) { const { props } = this; const asyncProps = {}; for (const key in props[ASYNC_DEFAULTS_SYMBOL]) { if (key in props[ASYNC_RESOLVED_SYMBOL]) { asyncProps[key] = props[ASYNC_RESOLVED_SYMBOL][key]; } else if (key in props[ASYNC_ORIGINAL_SYMBOL]) { asyncProps[key] = props[ASYNC_ORIGINAL_SYMBOL][key]; } } return new this.constructor({ ...props, ...asyncProps, ...newProps }); } }; Component.componentName = "Component"; Component.defaultProps = {}; // src/lifecycle/component-state.ts var EMPTY_PROPS = Object.freeze({}); var ComponentState = class { constructor(component) { this.component = component; this.asyncProps = {}; this.onAsyncPropUpdated = () => { }; this.oldProps = null; this.oldAsyncProps = null; } finalize() { for (const propName in this.asyncProps) { const asyncProp = this.asyncProps[propName]; if (asyncProp && asyncProp.type && asyncProp.type.release) { asyncProp.type.release( asyncProp.resolvedValue, asyncProp.type, this.component ); } } this.asyncProps = {}; this.component = null; this.resetOldProps(); } getOldProps() { return this.oldAsyncProps || this.oldProps || EMPTY_PROPS; } resetOldProps() { this.oldAsyncProps = null; this.oldProps = this.component ? this.component.props : null; } hasAsyncProp(propName) { return propName in this.asyncProps; } getAsyncProp(propName) { const asyncProp = this.asyncProps[propName]; return asyncProp && asyncProp.resolvedValue; } isAsyncPropLoading(propName) { if (propName) { const asyncProp = this.asyncProps[propName]; return Boolean( asyncProp && asyncProp.pendingLoadCount > 0 && asyncProp.pendingLoadCount !== asyncProp.resolvedLoadCount ); } for (const key in this.asyncProps) { if (this.isAsyncPropLoading(key)) { return true; } } return false; } reloadAsyncProp(propName, value) { this._watchPromise(propName, Promise.resolve(value)); } setAsyncProps(props) { this.component = props[COMPONENT_SYMBOL] || this.component; const resolvedValues = props[ASYNC_RESOLVED_SYMBOL] || {}; const originalValues = props[ASYNC_ORIGINAL_SYMBOL] || props; const defaultValues = props[ASYNC_DEFAULTS_SYMBOL] || {}; for (const propName in resolvedValues) { const value = resolvedValues[propName]; this._createAsyncPropData(propName, defaultValues[propName]); this._updateAsyncProp(propName, value); resolvedValues[propName] = this.getAsyncProp(propName); } for (const propName in originalValues) { const value = originalValues[propName]; this._createAsyncPropData(propName, defaultValues[propName]); this._updateAsyncProp(propName, value); } } _fetch(propName, url) { return null; } _onResolve(propName, value) { } _onError(propName, error) { } _updateAsyncProp(propName, value) { if (!this._didAsyncInputValueChange(propName, value)) { return; } if (typeof value === "string") { value = this._fetch(propName, value); } if (value instanceof Promise) { this._watchPromise(propName, value); return; } if (isAsyncIterable2(value)) { this._resolveAsyncIterable(propName, value); return; } this._setPropValue(propName, value); } _freezeAsyncOldProps() { if (!this.oldAsyncProps && this.oldProps) { this.oldAsyncProps = Object.create(this.oldProps); for (const propName in this.asyncProps) { Object.defineProperty(this.oldAsyncProps, propName, { enumerable: true, value: this.oldProps[propName] }); } } } _didAsyncInputValueChange(propName, value) { const asyncProp = this.asyncProps[propName]; if (value === asyncProp.resolvedValue || value === asyncProp.lastValue) { return false; } asyncProp.lastValue = value; return true; } _setPropValue(propName, value) { this._freezeAsyncOldProps(); const asyncProp = this.asyncProps[propName]; if (asyncProp) { value = this._postProcessValue(asyncProp, value); asyncProp.resolvedValue = value; asyncProp.pendingLoadCount++; asyncProp.resolvedLoadCount = asyncProp.pendingLoadCount; } } _setAsyncPropValue(propName, value, loadCount) { const asyncProp = this.asyncProps[propName]; if (asyncProp && loadCount >= asyncProp.resolvedLoadCount && value !== void 0) { this._freezeAsyncOldProps(); asyncProp.resolvedValue = value; asyncProp.resolvedLoadCount = loadCount; this.onAsyncPropUpdated(propName, value); } } _watchPromise(propName, promise) { const asyncProp = this.asyncProps[propName]; if (asyncProp) { asyncProp.pendingLoadCount++; const loadCount = asyncProp.pendingLoadCount; promise.then((data) => { if (!this.component) { return; } data = this._postProcessValue(asyncProp, data); this._setAsyncPropValue(propName, data, loadCount); this._onResolve(propName, data); }).catch((error) => { this._onError(propName, error); }); } } async _resolveAsyncIterable(propName, iterable) { if (propName !== "data") { this._setPropValue(propName, iterable); return; } const asyncProp = this.asyncProps[propName]; if (!asyncProp) { return; } asyncProp.pendingLoadCount++; const loadCount = asyncProp.pendingLoadCount; let data = []; let count2 = 0; for await (const chunk of iterable) { if (!this.component) { return; } const { dataTransform } = this.component.props; if (dataTransform) { data = dataTransform(chunk, data); } else { data = data.concat(chunk); } Object.defineProperty(data, "__diff", { enumerable: false, value: [{ startRow: count2, endRow: data.length }] }); count2 = data.length; this._setAsyncPropValue(propName, data, loadCount); } this._onResolve(propName, data); } _postProcessValue(asyncProp, value) { const propType = asyncProp.type; if (propType && this.component) { if (propType.release) { propType.release(asyncProp.resolvedValue, propType, this.component); } if (propType.transform) { return propType.transform(value, propType, this.component); } } return value; } _createAsyncPropData(propName, defaultValue) { const asyncProp = this.asyncProps[propName]; if (!asyncProp) { const propTypes = this.component && this.component.props[PROP_TYPES_SYMBOL]; this.asyncProps[propName] = { type: propTypes && propTypes[propName], lastValue: null, resolvedValue: defaultValue, pendingLoadCount: 0, resolvedLoadCount: 0 }; } } }; // src/lib/layer-state.ts var LayerState = class extends ComponentState { constructor({ attributeManager, layer }) { super(layer); this.attributeManager = attributeManager; this.needsRedraw = true; this.needsUpdate = true; this.subLayers = null; this.usesPickingColorCache = false; } get layer() { return this.component; } _fetch(propName, url) { const layer = this.layer; const fetch2 = layer?.props.fetch; if (fetch2) { return fetch2(url, { propName, layer }); } return super._fetch(propName, url); } _onResolve(propName, value) { const layer = this.layer; if (layer) { const onDataLoad = layer.props.onDataLoad; if (propName === "data" && onDataLoad) { onDataLoad(value, { propName, layer }); } } } _onError(propName, error) { const layer = this.layer; if (layer) { layer.raiseError(error, `loading ${propName} of ${this.layer}`); } } }; // src/lib/layer.ts var TRACE_CHANGE_FLAG = "layer.changeFlag"; var TRACE_INITIALIZE = "layer.initialize"; var TRACE_UPDATE = "layer.update"; var TRACE_FINALIZE = "layer.finalize"; var TRACE_MATCHED = "layer.matched"; var MAX_PICKING_COLOR_CACHE_SIZE = 2 ** 24 - 1; var EMPTY_ARRAY2 = Object.freeze([]); var areViewportsEqual = memoize( ({ oldViewport, viewport }) => { return oldViewport.equals(viewport); } ); var pickingColorCache = new Uint8ClampedArray(0); var defaultProps2 = { data: { type: "data", value: EMPTY_ARRAY2, async: true }, dataComparator: { type: "function", value: null, optional: true }, _dataDiff: { type: "function", value: (data) => data && data.__diff, optional: true }, dataTransform: { type: "function", value: null, optional: true }, onDataLoad: { type: "function", value: null, optional: true }, onError: { type: "function", value: null, optional: true }, fetch: { type: "function", value: (url, { propName, layer, loaders, loadOptions, signal }) => { const { resourceManager } = layer.context; loadOptions = loadOptions || layer.getLoadOptions(); loaders = loaders || layer.props.loaders; if (signal) { loadOptions = { ...loadOptions, fetch: { ...loadOptions?.fetch, signal } }; } let inResourceManager = resourceManager.contains(url); if (!inResourceManager && !loadOptions) { resourceManager.add({ resourceId: url, data: load(url, loaders), persistent: false }); inResourceManager = true; } if (inResourceManager) { return resourceManager.subscribe({ resourceId: url, onChange: (data) => layer.internalState?.reloadAsyncProp(propName, data), consumerId: layer.id, requestId: propName }); } return load(url, loaders, loadOptions); } }, updateTriggers: {}, visible: true, pickable: false, opacity: { type: "number", min: 0, max: 1, value: 1 }, operation: "draw", onHover: { type: "function", value: null, optional: true }, onClick: { type: "function", value: null, optional: true }, onDragStart: { type: "function", value: null, optional: true }, onDrag: { type: "function", value: null, optional: true }, onDragEnd: { type: "function", value: null, optional: true }, coordinateSystem: COORDINATE_SYSTEM.DEFAULT, coordinateOrigin: { type: "array", value: [0, 0, 0], compare: true }, modelMatrix: { type: "array", value: null, compare: true, optional: true }, wrapLongitude: false, positionFormat: "XYZ", colorFormat: "RGBA", parameters: { type: "object", value: {}, optional: true, compare: 2 }, loadOptions: { type: "object", value: null, optional: true, ignore: true }, transitions: null, extensions: [], loaders: { type: "array", value: [], optional: true, ignore: true }, getPolygonOffset: { type: "function", value: ({ layerIndex }) => [0, -layerIndex * 100] }, highlightedObjectIndex: null, autoHighlight: false, highlightColor: { type: "accessor", value: [0, 0, 128, 128] } }; var Layer = class extends Component { constructor() { super(...arguments); this.internalState = null; this.lifecycle = LIFECYCLE.NO_STATE; this.parent = null; } static get componentName() { return Object.prototype.hasOwnProperty.call(this, "layerName") ? this.layerName : ""; } get root() { let layer = this; while (layer.parent) { layer = layer.parent; } return layer; } toString() { const className = this.constructor.layerName || this.constructor.name; return `${className}({id: '${this.props.id}'})`; } project(xyz) { assert8(this.internalState); const viewport = this.internalState.viewport || this.context.viewport; const worldPosition = getWorldPosition(xyz, { viewport, modelMatrix: this.props.modelMatrix, coordinateOrigin: this.props.coordinateOrigin, coordinateSystem: this.props.coordinateSystem }); const [x, y, z] = worldToPixels(worldPosition, viewport.pixelProjectionMatrix); return xyz.length === 2 ? [x, y] : [x, y, z]; } unproject(xy) { assert8(this.internalState); const viewport = this.internalState.viewport || this.context.viewport; return viewport.unproject(xy); } projectPosition(xyz, params) { assert8(this.internalState); const viewport = this.internalState.viewport || this.context.viewport; return projectPosition(xyz, { viewport, modelMatrix: this.props.modelMatrix, coordinateOrigin: this.props.coordinateOrigin, coordinateSystem: this.props.coordinateSystem, ...params }); } get isComposite() { return false; } setState(partialState) { this.setChangeFlags({ stateChanged: true }); Object.assign(this.state, partialState); this.setNeedsRedraw(); } setNeedsRedraw() { if (this.internalState) { this.internalState.needsRedraw = true; } } setNeedsUpdate() { if (this.internalState) { this.context.layerManager.setNeedsUpdate(String(this)); this.internalState.needsUpdate = true; } } get isLoaded() { return this.internalState ? !this.internalState.isAsyncPropLoading() : false; } get wrapLongitude() { return this.props.wrapLongitude; } isPickable() { return this.props.pickable && this.props.visible; } getModels() { const state = this.state; return state && (state.models || state.model && [state.model]) || []; } setModuleParameters(moduleParameters) { for (const model of this.getModels()) { model.updateModuleSettings(moduleParameters); } } setShaderModuleProps(...props) { for (const model of this.getModels()) { model.shaderInputs.setProps(...props); } } getAttributeManager() { return this.internalState && this.internalState.attributeManager; } getCurrentLayer() { return this.internalState && this.internalState.layer; } getLoadOptions() { return this.props.loadOptions; } use64bitPositions() { const { coordinateSystem } = this.props; return coordinateSystem === COORDINATE_SYSTEM.DEFAULT || coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN; } onHover(info, pickingEvent) { if (this.props.onHover) { return this.props.onHover(info, pickingEvent) || false; } return false; } onClick(info, pickingEvent) { if (this.props.onClick) { return this.props.onClick(info, pickingEvent) || false; } return false; } nullPickingColor() { return [0, 0, 0]; } encodePickingColor(i, target = []) { target[0] = i + 1 & 255; target[1] = i + 1 >> 8 & 255; target[2] = i + 1 >> 8 >> 8 & 255; return target; } decodePickingColor(color) { assert8(color instanceof Uint8Array); const [i1, i2, i3] = color; const index2 = i1 + i2 * 256 + i3 * 65536 - 1; return index2; } getNumInstances() { if (Number.isFinite(this.props.numInstances)) { return this.props.numInstances; } if (this.state && this.state.numInstances !== void 0) { return this.state.numInstances; } return count(this.props.data); } getStartIndices() { if (this.props.startIndices) { return this.props.startIndices; } if (this.state && this.state.startIndices) { return this.state.startIndices; } return null; } getBounds() { return this.getAttributeManager()?.getBounds(["positions", "instancePositions"]); } getShaders(shaders) { shaders = mergeShaders(shaders, { disableWarnings: true, modules: this.context.defaultShaderModules }); for (const extension of this.props.extensions) { shaders = mergeShaders(shaders, extension.getShaders.call(this, extension)); } return shaders; } shouldUpdateState(params) { return params.changeFlags.propsOrDataChanged; } updateState(params) { const attributeManager = this.getAttributeManager(); const { dataChanged } = params.changeFlags; if (dataChanged && attributeManager) { if (Array.isArray(dataChanged)) { for (const dataRange of dataChanged) { attributeManager.invalidateAll(dataRange); } } else { attributeManager.invalidateAll(); } } if (attributeManager) { const { props } = params; const hasPickingBuffer = this.internalState.hasPickingBuffer; const needsPickingBuffer = Number.isInteger(props.highlightedObjectIndex) || props.pickable || props.extensions.some((extension) => extension.getNeedsPickingBuffer.call(this, extension)); if (hasPickingBuffer !== needsPickingBuffer) { this.internalState.hasPickingBuffer = needsPickingBuffer; const { pickingColors, instancePickingColors } = attributeManager.attributes; const pickingColorsAttribute = pickingColors || instancePickingColors; if (pickingColorsAttribute) { if (needsPickingBuffer && pickingColorsAttribute.constant) { pickingColorsAttribute.constant = false; attributeManager.invalidate(pickingColorsAttribute.id); } if (!pickingColorsAttribute.value && !needsPickingBuffer) { pickingColorsAttribute.constant = true; pickingColorsAttribute.value = [0, 0, 0]; } } } } } finalizeState(context) { for (const model of this.getModels()) { model.destroy(); } const attributeManager = this.getAttributeManager(); if (attributeManager) { attributeManager.finalize(); } if (this.context) { this.context.resourceManager.unsubscribe({ consumerId: this.id }); } if (this.internalState) { this.internalState.uniformTransitions.clear(); this.internalState.finalize(); } } draw(opts) { for (const model of this.getModels()) { model.draw(opts); } } getPickingInfo({ info, mode, sourceLayer }) { const { index: index2 } = info; if (index2 >= 0) { if (Array.isArray(this.props.data)) { info.object = this.props.data[index2]; } } return info; } raiseError(error, message2) { if (message2) { error = new Error(`${message2}: ${error.message}`, { cause: error }); } if (!this.props.onError?.(error)) { this.context?.onError?.(error, this); } } getNeedsRedraw(opts = { clearRedrawFlags: false }) { return this._getNeedsRedraw(opts); } needsUpdate() { if (!this.internalState) { return false; } return this.internalState.needsUpdate || this.hasUniformTransition() || this.shouldUpdateState(this._getUpdateParams()); } hasUniformTransition() { return this.internalState?.uniformTransitions.active || false; } activateViewport(viewport) { if (!this.internalState) { return; } const oldViewport = this.internalState.viewport; this.internalState.viewport = viewport; if (!oldViewport || !areViewportsEqual({ oldViewport, viewport })) { this.setChangeFlags({ viewportChanged: true }); if (this.isComposite) { if (this.needsUpdate()) { this.setNeedsUpdate(); } } else { this._update(); } } } invalidateAttribute(name2 = "all") { const attributeManager = this.getAttributeManager(); if (!attributeManager) { return; } if (name2 === "all") { attributeManager.invalidateAll(); } else { attributeManager.invalidate(name2); } } updateAttributes(changedAttributes) { let bufferLayoutChanged = false; for (const id in changedAttributes) { if (changedAttributes[id].layoutChanged()) { bufferLayoutChanged = true; } } for (const model of this.getModels()) { this._setModelAttributes(model, changedAttributes, bufferLayoutChanged); } } _updateAttributes() { const attributeManager = this.getAttributeManager(); if (!attributeManager) { return; } const props = this.props; const numInstances = this.getNumInstances(); const startIndices = this.getStartIndices(); attributeManager.update({ data: props.data, numInstances, startIndices, props, transitions: props.transitions, buffers: props.data.attributes, context: this }); const changedAttributes = attributeManager.getChangedAttributes({ clearChangedFlags: true }); this.updateAttributes(changedAttributes); } _updateAttributeTransition() { const attributeManager = this.getAttributeManager(); if (attributeManager) { attributeManager.updateTransition(); } } _updateUniformTransition() { const { uniformTransitions } = this.internalState; if (uniformTransitions.active) { const propsInTransition = uniformTransitions.update(); const props = Object.create(this.props); for (const key in propsInTransition) { Object.defineProperty(props, key, { value: propsInTransition[key] }); } return props; } return this.props; } calculateInstancePickingColors(attribute, { numInstances }) { if (attribute.constant) { return; } const cacheSize = Math.floor(pickingColorCache.length / 4); this.internalState.usesPickingColorCache = true; if (cacheSize < numInstances) { if (numInstances > MAX_PICKING_COLOR_CACHE_SIZE) { log_default.warn( "Layer has too many data objects. Picking might not be able to distinguish all objects." )(); } pickingColorCache = typed_array_manager_default.allocate(pickingColorCache, numInstances, { size: 4, copy: true, maxCount: Math.max(numInstances, MAX_PICKING_COLOR_CACHE_SIZE) }); const newCacheSize = Math.floor(pickingColorCache.length / 4); const pickingColor = []; for (let i = cacheSize; i < newCacheSize; i++) { this.encodePickingColor(i, pickingColor); pickingColorCache[i * 4 + 0] = pickingColor[0]; pickingColorCache[i * 4 + 1] = pickingColor[1]; pickingColorCache[i * 4 + 2] = pickingColor[2]; } } attribute.value = pickingColorCache.subarray(0, numInstances * 4); } _setModelAttributes(model, changedAttributes, bufferLayoutChanged = false) { if (!Object.keys(changedAttributes).length) { return; } if (bufferLayoutChanged) { const attributeManager = this.getAttributeManager(); model.setBufferLayout(attributeManager.getBufferLayouts(model)); changedAttributes = attributeManager.getAttributes(); } const excludeAttributes = model.userData?.excludeAttributes || {}; const attributeBuffers = {}; const constantAttributes = {}; for (const name2 in changedAttributes) { if (excludeAttributes[name2]) { continue; } const values = changedAttributes[name2].getValue(); for (const attributeName in values) { const value = values[attributeName]; if (value instanceof Buffer2) { if (changedAttributes[name2].settings.isIndexed) { model.setIndexBuffer(value); } else { attributeBuffers[attributeName] = value; } } else if (value) { constantAttributes[attributeName] = value; } } } model.setAttributes(attributeBuffers); model.setConstantAttributes(constantAttributes); } disablePickingIndex(objectIndex) { const data = this.props.data; if (!("attributes" in data)) { this._disablePickingIndex(objectIndex); return; } const { pickingColors, instancePickingColors } = this.getAttributeManager().attributes; const colors = pickingColors || instancePickingColors; const externalColorAttribute = colors && data.attributes && data.attributes[colors.id]; if (externalColorAttribute && externalColorAttribute.value) { const values = externalColorAttribute.value; const objectColor = this.encodePickingColor(objectIndex); for (let index2 = 0; index2 < data.length; index2++) { const i = colors.getVertexOffset(index2); if (values[i] === objectColor[0] && values[i + 1] === objectColor[1] && values[i + 2] === objectColor[2]) { this._disablePickingIndex(index2); } } } else { this._disablePickingIndex(objectIndex); } } _disablePickingIndex(objectIndex) { const { pickingColors, instancePickingColors } = this.getAttributeManager().attributes; const colors = pickingColors || instancePickingColors; if (!colors) { return; } const start = colors.getVertexOffset(objectIndex); const end = colors.getVertexOffset(objectIndex + 1); colors.buffer.write(new Uint8Array(end - start), start); } restorePickingColors() { const { pickingColors, instancePickingColors } = this.getAttributeManager().attributes; const colors = pickingColors || instancePickingColors; if (!colors) { return; } if (this.internalState.usesPickingColorCache && colors.value.buffer !== pickingColorCache.buffer) { colors.value = pickingColorCache.subarray(0, colors.value.length); } colors.updateSubBuffer({ startOffset: 0 }); } _initialize() { assert8(!this.internalState); assert8(Number.isFinite(this.props.coordinateSystem)); debug(TRACE_INITIALIZE, this); const attributeManager = this._getAttributeManager(); if (attributeManager) { attributeManager.addInstanced({ instancePickingColors: { type: "uint8", size: 4, noAlloc: true, update: this.calculateInstancePickingColors } }); } this.internalState = new LayerState({ attributeManager, layer: this }); this._clearChangeFlags(); this.state = {}; Object.defineProperty(this.state, "attributeManager", { get: () => { log_default.deprecated("layer.state.attributeManager", "layer.getAttributeManager()")(); return attributeManager; } }); this.internalState.uniformTransitions = new UniformTransitionManager(this.context.timeline); this.internalState.onAsyncPropUpdated = this._onAsyncPropUpdated.bind(this); this.internalState.setAsyncProps(this.props); this.initializeState(this.context); for (const extension of this.props.extensions) { extension.initializeState.call(this, this.context, extension); } this.setChangeFlags({ dataChanged: "init", propsChanged: "init", viewportChanged: true, extensionsChanged: true }); this._update(); } _transferState(oldLayer) { debug(TRACE_MATCHED, this, this === oldLayer); const { state, internalState } = oldLayer; if (this === oldLayer) { return; } this.internalState = internalState; this.state = state; this.internalState.setAsyncProps(this.props); this._diffProps(this.props, this.internalState.getOldProps()); } _update() { const stateNeedsUpdate = this.needsUpdate(); debug(TRACE_UPDATE, this, stateNeedsUpdate); if (!stateNeedsUpdate) { return; } const currentProps = this.props; const context = this.context; const internalState = this.internalState; const currentViewport = context.viewport; const propsInTransition = this._updateUniformTransition(); internalState.propsInTransition = propsInTransition; context.viewport = internalState.viewport || currentViewport; this.props = propsInTransition; try { const updateParams = this._getUpdateParams(); const oldModels = this.getModels(); if (context.device) { this.updateState(updateParams); } else { try { this.updateState(updateParams); } catch (error) { } } for (const extension of this.props.extensions) { extension.updateState.call(this, updateParams, extension); } const modelChanged = this.getModels()[0] !== oldModels[0]; this._postUpdate(updateParams, modelChanged); } finally { context.viewport = currentViewport; this.props = currentProps; this._clearChangeFlags(); internalState.needsUpdate = false; internalState.resetOldProps(); } } _finalize() { debug(TRACE_FINALIZE, this); this.finalizeState(this.context); for (const extension of this.props.extensions) { extension.finalizeState.call(this, this.context, extension); } } _drawLayer({ renderPass, moduleParameters = null, uniforms = {}, parameters = {} }) { this._updateAttributeTransition(); const currentProps = this.props; const context = this.context; this.props = this.internalState.propsInTransition || currentProps; const opacity = this.props.opacity; uniforms.opacity = Math.pow(opacity, 1 / 2.2); try { if (moduleParameters) { const { isActive, isAttribute } = moduleParameters.picking; this.setModuleParameters(moduleParameters); this.setShaderModuleProps({ picking: { isActive, isAttribute } }); } const { getPolygonOffset } = this.props; const offsets = getPolygonOffset && getPolygonOffset(uniforms) || [0, 0]; context.device.setParametersWebGL({ polygonOffset: offsets }); for (const model of this.getModels()) { model.setParameters(parameters); } context.device.withParametersWebGL(parameters, () => { const opts = { renderPass, moduleParameters, uniforms, parameters, context }; for (const extension of this.props.extensions) { extension.draw.call(this, opts, extension); } this.draw(opts); }); } finally { this.props = currentProps; } } getChangeFlags() { return this.internalState?.changeFlags; } setChangeFlags(flags) { if (!this.internalState) { return; } const { changeFlags } = this.internalState; for (const key in flags) { if (flags[key]) { let flagChanged = false; switch (key) { case "dataChanged": const dataChangedReason = flags[key]; const prevDataChangedReason = changeFlags[key]; if (dataChangedReason && Array.isArray(prevDataChangedReason)) { changeFlags.dataChanged = Array.isArray(dataChangedReason) ? prevDataChangedReason.concat(dataChangedReason) : dataChangedReason; flagChanged = true; } default: if (!changeFlags[key]) { changeFlags[key] = flags[key]; flagChanged = true; } } if (flagChanged) { debug(TRACE_CHANGE_FLAG, this, key, flags); } } } const propsOrDataChanged = Boolean( changeFlags.dataChanged || changeFlags.updateTriggersChanged || changeFlags.propsChanged || changeFlags.extensionsChanged ); changeFlags.propsOrDataChanged = propsOrDataChanged; changeFlags.somethingChanged = propsOrDataChanged || changeFlags.viewportChanged || changeFlags.stateChanged; } _clearChangeFlags() { this.internalState.changeFlags = { dataChanged: false, propsChanged: false, updateTriggersChanged: false, viewportChanged: false, stateChanged: false, extensionsChanged: false, propsOrDataChanged: false, somethingChanged: false }; } _diffProps(newProps, oldProps) { const changeFlags = diffProps(newProps, oldProps); if (changeFlags.updateTriggersChanged) { for (const key in changeFlags.updateTriggersChanged) { if (changeFlags.updateTriggersChanged[key]) { this.invalidateAttribute(key); } } } if (changeFlags.transitionsChanged) { for (const key in changeFlags.transitionsChanged) { this.internalState.uniformTransitions.add( key, oldProps[key], newProps[key], newProps.transitions?.[key] ); } } return this.setChangeFlags(changeFlags); } validateProps() { validateProps(this.props); } updateAutoHighlight(info) { if (this.props.autoHighlight && !Number.isInteger(this.props.highlightedObjectIndex)) { this._updateAutoHighlight(info); } } _updateAutoHighlight(info) { const picking2 = { highlightedObjectColor: info.picked ? info.color : null }; const { highlightColor } = this.props; if (info.picked && typeof highlightColor === "function") { picking2.highlightColor = highlightColor(info); } this.setShaderModuleProps({ picking: picking2 }); this.setNeedsRedraw(); } _getAttributeManager() { const context = this.context; return new AttributeManager(context.device, { id: this.props.id, stats: context.stats, timeline: context.timeline }); } _postUpdate(updateParams, forceUpdate) { const { props, oldProps } = updateParams; this.setNeedsRedraw(); this._updateAttributes(); const model = this.state.model; if (model?.isInstanced) { model.setInstanceCount(this.getNumInstances()); } const { autoHighlight, highlightedObjectIndex, highlightColor } = props; if (forceUpdate || oldProps.autoHighlight !== autoHighlight || oldProps.highlightedObjectIndex !== highlightedObjectIndex || oldProps.highlightColor !== highlightColor) { const picking2 = {}; if (Array.isArray(highlightColor)) { picking2.highlightColor = highlightColor; } if (forceUpdate || oldProps.autoHighlight !== autoHighlight || highlightedObjectIndex !== oldProps.highlightedObjectIndex) { picking2.highlightedObjectColor = Number.isFinite(highlightedObjectIndex) && highlightedObjectIndex >= 0 ? this.encodePickingColor(highlightedObjectIndex) : null; } this.setShaderModuleProps({ picking: picking2 }); } } _getUpdateParams() { return { props: this.props, oldProps: this.internalState.getOldProps(), context: this.context, changeFlags: this.internalState.changeFlags }; } _getNeedsRedraw(opts) { if (!this.internalState) { return false; } let redraw = false; redraw = redraw || this.internalState.needsRedraw && this.id; const attributeManager = this.getAttributeManager(); const attributeManagerNeedsRedraw = attributeManager ? attributeManager.getNeedsRedraw(opts) : false; redraw = redraw || attributeManagerNeedsRedraw; if (redraw) { for (const extension of this.props.extensions) { extension.onNeedsRedraw.call(this, extension); } } this.internalState.needsRedraw = this.internalState.needsRedraw && !opts.clearRedrawFlags; return redraw; } _onAsyncPropUpdated() { this._diffProps(this.props, this.internalState.getOldProps()); this.setNeedsUpdate(); } }; Layer.defaultProps = defaultProps2; Layer.layerName = "Layer"; // src/lib/composite-layer.ts var TRACE_RENDER_LAYERS2 = "compositeLayer.renderLayers"; var CompositeLayer = class extends Layer { get isComposite() { return true; } get isLoaded() { return super.isLoaded && this.getSubLayers().every((layer) => layer.isLoaded); } getSubLayers() { return this.internalState && this.internalState.subLayers || []; } initializeState(context) { } setState(updateObject) { super.setState(updateObject); this.setNeedsUpdate(); } getPickingInfo({ info }) { const { object } = info; const isDataWrapped = object && object.__source && object.__source.parent && object.__source.parent.id === this.id; if (!isDataWrapped) { return info; } info.object = object.__source.object; info.index = object.__source.index; return info; } filterSubLayer(context) { return true; } shouldRenderSubLayer(subLayerId, data) { return data && data.length; } getSubLayerClass(subLayerId, DefaultLayerClass) { const { _subLayerProps: overridingProps } = this.props; return overridingProps && overridingProps[subLayerId] && overridingProps[subLayerId].type || DefaultLayerClass; } getSubLayerRow(row, sourceObject, sourceObjectIndex) { row.__source = { parent: this, object: sourceObject, index: sourceObjectIndex }; return row; } getSubLayerAccessor(accessor) { if (typeof accessor === "function") { const objectInfo = { index: -1, data: this.props.data, target: [] }; return (x, i) => { if (x && x.__source) { objectInfo.index = x.__source.index; return accessor(x.__source.object, objectInfo); } return accessor(x, i); }; } return accessor; } getSubLayerProps(sublayerProps = {}) { const { opacity, pickable, visible, parameters, getPolygonOffset, highlightedObjectIndex, autoHighlight, highlightColor, coordinateSystem, coordinateOrigin, wrapLongitude, positionFormat, modelMatrix, extensions, fetch: fetch2, operation, _subLayerProps: overridingProps } = this.props; const newProps = { id: "", updateTriggers: {}, opacity, pickable, visible, parameters, getPolygonOffset, highlightedObjectIndex, autoHighlight, highlightColor, coordinateSystem, coordinateOrigin, wrapLongitude, positionFormat, modelMatrix, extensions, fetch: fetch2, operation }; const overridingSublayerProps = overridingProps && sublayerProps.id && overridingProps[sublayerProps.id]; const overridingSublayerTriggers = overridingSublayerProps && overridingSublayerProps.updateTriggers; const sublayerId = sublayerProps.id || "sublayer"; if (overridingSublayerProps) { const propTypes = this.props[PROP_TYPES_SYMBOL]; const subLayerPropTypes = sublayerProps.type ? sublayerProps.type._propTypes : {}; for (const key in overridingSublayerProps) { const propType = subLayerPropTypes[key] || propTypes[key]; if (propType && propType.type === "accessor") { overridingSublayerProps[key] = this.getSubLayerAccessor(overridingSublayerProps[key]); } } } Object.assign( newProps, sublayerProps, overridingSublayerProps ); newProps.id = `${this.props.id}-${sublayerId}`; newProps.updateTriggers = { all: this.props.updateTriggers?.all, ...sublayerProps.updateTriggers, ...overridingSublayerTriggers }; for (const extension of extensions) { const passThroughProps = extension.getSubLayerProps.call(this, extension); if (passThroughProps) { Object.assign(newProps, passThroughProps, { updateTriggers: Object.assign(newProps.updateTriggers, passThroughProps.updateTriggers) }); } } return newProps; } _updateAutoHighlight(info) { for (const layer of this.getSubLayers()) { layer.updateAutoHighlight(info); } } _getAttributeManager() { return null; } _postUpdate(updateParams, forceUpdate) { let subLayers = this.internalState.subLayers; const shouldUpdate = !subLayers || this.needsUpdate(); if (shouldUpdate) { const subLayersList = this.renderLayers(); subLayers = flatten(subLayersList, Boolean); this.internalState.subLayers = subLayers; } debug(TRACE_RENDER_LAYERS2, this, shouldUpdate, subLayers); for (const layer of subLayers) { layer.parent = this; } } }; CompositeLayer.layerName = "CompositeLayer"; // src/viewports/globe-viewport.ts var DEGREES_TO_RADIANS6 = Math.PI / 180; var RADIANS_TO_DEGREES3 = 180 / Math.PI; var EARTH_RADIUS = 6370972; var GLOBE_RADIUS = 256; function getDistanceScales2() { const unitsPerMeter2 = GLOBE_RADIUS / EARTH_RADIUS; const unitsPerDegree = Math.PI / 180 * GLOBE_RADIUS; return { unitsPerMeter: [unitsPerMeter2, unitsPerMeter2, unitsPerMeter2], unitsPerMeter2: [0, 0, 0], metersPerUnit: [1 / unitsPerMeter2, 1 / unitsPerMeter2, 1 / unitsPerMeter2], unitsPerDegree: [unitsPerDegree, unitsPerDegree, unitsPerMeter2], unitsPerDegree2: [0, 0, 0], degreesPerUnit: [1 / unitsPerDegree, 1 / unitsPerDegree, 1 / unitsPerMeter2] }; } var GlobeViewport = class extends Viewport { constructor(opts = {}) { const { latitude = 0, longitude = 0, zoom = 0, nearZMultiplier = 0.1, farZMultiplier = 2, resolution = 10 } = opts; let { height, altitude = 1.5 } = opts; height = height || 1; altitude = Math.max(0.75, altitude); const viewMatrix2 = new Matrix4().lookAt({ eye: [0, -altitude, 0], up: [0, 0, 1] }); const scale5 = Math.pow(2, zoom); viewMatrix2.rotateX(latitude * DEGREES_TO_RADIANS6); viewMatrix2.rotateZ(-longitude * DEGREES_TO_RADIANS6); viewMatrix2.scale(scale5 / height); const halfFov = Math.atan(0.5 / altitude); const relativeScale = GLOBE_RADIUS * 2 * scale5 / height; super({ ...opts, height, viewMatrix: viewMatrix2, longitude, latitude, zoom, distanceScales: getDistanceScales2(), fovyRadians: halfFov * 2, focalDistance: altitude, near: nearZMultiplier, far: Math.min(2, 1 / relativeScale + 1) * altitude * farZMultiplier }); this.latitude = latitude; this.longitude = longitude; this.resolution = resolution; } get projectionMode() { return PROJECTION_MODE.GLOBE; } getDistanceScales() { return this.distanceScales; } getBounds(options = {}) { const unprojectOption = { targetZ: options.z || 0 }; const left = this.unproject([0, this.height / 2], unprojectOption); const top = this.unproject([this.width / 2, 0], unprojectOption); const right = this.unproject([this.width, this.height / 2], unprojectOption); const bottom = this.unproject([this.width / 2, this.height], unprojectOption); if (right[0] < this.longitude) right[0] += 360; if (left[0] > this.longitude) left[0] -= 360; return [ Math.min(left[0], right[0], top[0], bottom[0]), Math.min(left[1], right[1], top[1], bottom[1]), Math.max(left[0], right[0], top[0], bottom[0]), Math.max(left[1], right[1], top[1], bottom[1]) ]; } unproject(xyz, { topLeft = true, targetZ } = {}) { const [x, y, z] = xyz; const y2 = topLeft ? y : this.height - y; const { pixelUnprojectionMatrix } = this; let coord; if (Number.isFinite(z)) { coord = transformVector2(pixelUnprojectionMatrix, [x, y2, z, 1]); } else { const coord0 = transformVector2(pixelUnprojectionMatrix, [x, y2, -1, 1]); const coord1 = transformVector2(pixelUnprojectionMatrix, [x, y2, 1, 1]); const lt = ((targetZ || 0) / EARTH_RADIUS + 1) * GLOBE_RADIUS; const lSqr = vec3_exports.sqrLen(vec3_exports.sub([], coord0, coord1)); const l0Sqr = vec3_exports.sqrLen(coord0); const l1Sqr = vec3_exports.sqrLen(coord1); const sSqr = (4 * l0Sqr * l1Sqr - (lSqr - l0Sqr - l1Sqr) ** 2) / 16; const dSqr = 4 * sSqr / lSqr; const r0 = Math.sqrt(l0Sqr - dSqr); const dr = Math.sqrt(Math.max(0, lt * lt - dSqr)); const t = (r0 - dr) / Math.sqrt(lSqr); coord = vec3_exports.lerp([], coord0, coord1, t); } const [X, Y, Z] = this.unprojectPosition(coord); if (Number.isFinite(z)) { return [X, Y, Z]; } return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y]; } projectPosition(xyz) { const [lng, lat, Z = 0] = xyz; const lambda = lng * DEGREES_TO_RADIANS6; const phi = lat * DEGREES_TO_RADIANS6; const cosPhi = Math.cos(phi); const D = (Z / EARTH_RADIUS + 1) * GLOBE_RADIUS; return [Math.sin(lambda) * cosPhi * D, -Math.cos(lambda) * cosPhi * D, Math.sin(phi) * D]; } unprojectPosition(xyz) { const [x, y, z] = xyz; const D = vec3_exports.len(xyz); const phi = Math.asin(z / D); const lambda = Math.atan2(x, -y); const lng = lambda * RADIANS_TO_DEGREES3; const lat = phi * RADIANS_TO_DEGREES3; const Z = (D / GLOBE_RADIUS - 1) * EARTH_RADIUS; return [lng, lat, Z]; } projectFlat(xyz) { return xyz; } unprojectFlat(xyz) { return xyz; } panByPosition(coords, pixel) { const fromPosition = this.unproject(pixel); return { longitude: coords[0] - fromPosition[0] + this.longitude, latitude: coords[1] - fromPosition[1] + this.latitude }; } }; function transformVector2(matrix, vector) { const result = vec4_exports.transformMat4([], vector, matrix); vec4_exports.scale(result, result, 1 / result[3]); return result; } // src/viewports/orbit-viewport.ts var DEGREES_TO_RADIANS7 = Math.PI / 180; function getViewMatrix2({ height, focalDistance, orbitAxis, rotationX, rotationOrbit, zoom }) { const up = orbitAxis === "Z" ? [0, 0, 1] : [0, 1, 0]; const eye = orbitAxis === "Z" ? [0, -focalDistance, 0] : [0, 0, focalDistance]; const viewMatrix2 = new Matrix4().lookAt({ eye, up }); viewMatrix2.rotateX(rotationX * DEGREES_TO_RADIANS7); if (orbitAxis === "Z") { viewMatrix2.rotateZ(rotationOrbit * DEGREES_TO_RADIANS7); } else { viewMatrix2.rotateY(rotationOrbit * DEGREES_TO_RADIANS7); } const projectionScale = Math.pow(2, zoom) / height; viewMatrix2.scale(projectionScale); return viewMatrix2; } var OrbitViewport = class extends Viewport { constructor(props) { const { height, projectionMatrix, fovy = 50, orbitAxis = "Z", target = [0, 0, 0], rotationX = 0, rotationOrbit = 0, zoom = 0 } = props; const focalDistance = projectionMatrix ? projectionMatrix[5] / 2 : fovyToAltitude(fovy); super({ ...props, longitude: void 0, viewMatrix: getViewMatrix2({ height: height || 1, focalDistance, orbitAxis, rotationX, rotationOrbit, zoom }), fovy, focalDistance, position: target, zoom }); this.projectedCenter = this.project(this.center); } unproject(xyz, { topLeft = true } = {}) { const [x, y, z = this.projectedCenter[2]] = xyz; const y2 = topLeft ? y : this.height - y; const [X, Y, Z] = pixelsToWorld([x, y2, z], this.pixelUnprojectionMatrix); return [X, Y, Z]; } panByPosition(coords, pixel) { const p0 = this.project(coords); const nextCenter = [ this.width / 2 + p0[0] - pixel[0], this.height / 2 + p0[1] - pixel[1], this.projectedCenter[2] ]; return { target: this.unproject(nextCenter) }; } }; // src/viewports/orthographic-viewport.ts var viewMatrix = new Matrix4().lookAt({ eye: [0, 0, 1] }); function getProjectionMatrix2({ width, height, near, far, padding }) { let left = -width / 2; let right = width / 2; let bottom = -height / 2; let top = height / 2; if (padding) { const { left: l = 0, right: r = 0, top: t = 0, bottom: b = 0 } = padding; const offsetX = clamp((l + width - r) / 2, 0, width) - width / 2; const offsetY = clamp((t + height - b) / 2, 0, height) - height / 2; left -= offsetX; right -= offsetX; bottom += offsetY; top += offsetY; } return new Matrix4().ortho({ left, right, bottom, top, near, far }); } var OrthographicViewport = class extends Viewport { constructor(props) { const { width, height, near = 0.1, far = 1e3, zoom = 0, target = [0, 0, 0], padding = null, flipY = true } = props; const zoomX = Array.isArray(zoom) ? zoom[0] : zoom; const zoomY = Array.isArray(zoom) ? zoom[1] : zoom; const zoom_ = Math.min(zoomX, zoomY); const scale5 = Math.pow(2, zoom_); let distanceScales; if (zoomX !== zoomY) { const scaleX2 = Math.pow(2, zoomX); const scaleY2 = Math.pow(2, zoomY); distanceScales = { unitsPerMeter: [scaleX2 / scale5, scaleY2 / scale5, 1], metersPerUnit: [scale5 / scaleX2, scale5 / scaleY2, 1] }; } super({ ...props, longitude: void 0, position: target, viewMatrix: viewMatrix.clone().scale([scale5, scale5 * (flipY ? -1 : 1), scale5]), projectionMatrix: getProjectionMatrix2({ width: width || 1, height: height || 1, padding, near, far }), zoom: zoom_, distanceScales }); } projectFlat([X, Y]) { const { unitsPerMeter: unitsPerMeter2 } = this.distanceScales; return [X * unitsPerMeter2[0], Y * unitsPerMeter2[1]]; } unprojectFlat([x, y]) { const { metersPerUnit } = this.distanceScales; return [x * metersPerUnit[0], y * metersPerUnit[1]]; } panByPosition(coords, pixel) { const fromLocation = pixelsToWorld(pixel, this.pixelUnprojectionMatrix); const toLocation = this.projectFlat(coords); const translate2 = vec2_exports.add([], toLocation, vec2_exports.negate([], fromLocation)); const newCenter = vec2_exports.add([], this.center, translate2); return { target: this.unprojectFlat(newCenter) }; } }; // src/viewports/first-person-viewport.ts var FirstPersonViewport = class extends Viewport { constructor(props) { const { longitude, latitude, modelMatrix, bearing = 0, pitch = 0, up = [0, 0, 1] } = props; const spherical = new SphericalCoordinates({ bearing, pitch: pitch === -90 ? 1e-4 : 90 + pitch }); const dir = spherical.toVector3().normalize(); const center = modelMatrix ? new Matrix4(modelMatrix).transformAsVector(dir) : dir; const zoom = Number.isFinite(latitude) ? getMeterZoom({ latitude }) : 0; const scale5 = Math.pow(2, zoom); const viewMatrix2 = new Matrix4().lookAt({ eye: [0, 0, 0], center, up }).scale(scale5); super({ ...props, zoom, viewMatrix: viewMatrix2 }); this.latitude = latitude; this.longitude = longitude; } }; // src/controllers/first-person-controller.ts var MOVEMENT_SPEED = 20; var PAN_SPEED = 500; var FirstPersonState = class extends ViewState { constructor(options) { const { width, height, position = [0, 0, 0], bearing = 0, pitch = 0, longitude = null, latitude = null, maxPitch = 90, minPitch = -90, startRotatePos, startBearing, startPitch, startZoomPosition, startPanPos, startPanPosition } = options; super( { width, height, position, bearing, pitch, longitude, latitude, maxPitch, minPitch }, { startRotatePos, startBearing, startPitch, startZoomPosition, startPanPos, startPanPosition } ); this.makeViewport = options.makeViewport; } panStart({ pos }) { const { position } = this.getViewportProps(); return this._getUpdatedState({ startPanPos: pos, startPanPosition: position }); } pan({ pos }) { if (!pos) { return this; } const { startPanPos = [0, 0], startPanPosition = [0, 0] } = this.getState(); const { width, height, bearing, pitch } = this.getViewportProps(); const deltaScaleX = PAN_SPEED * (pos[0] - startPanPos[0]) / width; const deltaScaleY = PAN_SPEED * (pos[1] - startPanPos[1]) / height; const up = new SphericalCoordinates({ bearing, pitch }); const forward = new SphericalCoordinates({ bearing, pitch: -90 }); const yDirection = up.toVector3().normalize(); const xDirection = forward.toVector3().cross(yDirection).normalize(); return this._getUpdatedState({ position: new Vector3(startPanPosition).add(xDirection.scale(deltaScaleX)).add(yDirection.scale(deltaScaleY)) }); } panEnd() { return this._getUpdatedState({ startPanPos: null, startPanPosition: null }); } rotateStart({ pos }) { return this._getUpdatedState({ startRotatePos: pos, startBearing: this.getViewportProps().bearing, startPitch: this.getViewportProps().pitch }); } rotate({ pos, deltaAngleX = 0, deltaAngleY = 0 }) { const { startRotatePos, startBearing, startPitch } = this.getState(); const { width, height } = this.getViewportProps(); if (!startRotatePos || startBearing === void 0 || startPitch === void 0) { return this; } let newRotation; if (pos) { const deltaScaleX = (pos[0] - startRotatePos[0]) / width; const deltaScaleY = (pos[1] - startRotatePos[1]) / height; newRotation = { bearing: startBearing - deltaScaleX * 180, pitch: startPitch - deltaScaleY * 90 }; } else { newRotation = { bearing: startBearing - deltaAngleX, pitch: startPitch - deltaAngleY }; } return this._getUpdatedState(newRotation); } rotateEnd() { return this._getUpdatedState({ startRotatePos: null, startBearing: null, startPitch: null }); } zoomStart() { return this._getUpdatedState({ startZoomPosition: this.getViewportProps().position }); } zoom({ pos, scale: scale5 }) { const viewportProps = this.getViewportProps(); const startZoomPosition = this.getState().startZoomPosition || viewportProps.position; const viewport = this.makeViewport(viewportProps); const { projectionMatrix, width } = viewport; const fovxRadians = 2 * Math.atan(1 / projectionMatrix[0]); const angle3 = fovxRadians * (pos[0] / width - 0.5); const direction = this.getDirection(true); return this._move( direction.rotateZ({ radians: -angle3 }), Math.log2(scale5) * MOVEMENT_SPEED, startZoomPosition ); } zoomEnd() { return this._getUpdatedState({ startZoomPosition: null }); } moveLeft(speed = MOVEMENT_SPEED) { const direction = this.getDirection(true); return this._move(direction.rotateZ({ radians: Math.PI / 2 }), speed); } moveRight(speed = MOVEMENT_SPEED) { const direction = this.getDirection(true); return this._move(direction.rotateZ({ radians: -Math.PI / 2 }), speed); } moveUp(speed = MOVEMENT_SPEED) { const direction = this.getDirection(true); return this._move(direction, speed); } moveDown(speed = MOVEMENT_SPEED) { const direction = this.getDirection(true); return this._move(direction.negate(), speed); } rotateLeft(speed = 15) { return this._getUpdatedState({ bearing: this.getViewportProps().bearing - speed }); } rotateRight(speed = 15) { return this._getUpdatedState({ bearing: this.getViewportProps().bearing + speed }); } rotateUp(speed = 10) { return this._getUpdatedState({ pitch: this.getViewportProps().pitch + speed }); } rotateDown(speed = 10) { return this._getUpdatedState({ pitch: this.getViewportProps().pitch - speed }); } zoomIn(speed = MOVEMENT_SPEED) { return this._move(new Vector3(0, 0, 1), speed); } zoomOut(speed = MOVEMENT_SPEED) { return this._move(new Vector3(0, 0, -1), speed); } shortestPathFrom(viewState) { const fromProps = viewState.getViewportProps(); const props = { ...this.getViewportProps() }; const { bearing, longitude } = props; if (Math.abs(bearing - fromProps.bearing) > 180) { props.bearing = bearing < 0 ? bearing + 360 : bearing - 360; } if (longitude !== null && fromProps.longitude !== null && Math.abs(longitude - fromProps.longitude) > 180) { props.longitude = longitude < 0 ? longitude + 360 : longitude - 360; } return props; } _move(direction, speed, fromPosition = this.getViewportProps().position) { const delta = direction.scale(speed); return this._getUpdatedState({ position: new Vector3(fromPosition).add(delta) }); } getDirection(use2D = false) { const spherical = new SphericalCoordinates({ bearing: this.getViewportProps().bearing, pitch: use2D ? 90 : 90 + this.getViewportProps().pitch }); const direction = spherical.toVector3().normalize(); return direction; } _getUpdatedState(newProps) { return new FirstPersonState({ makeViewport: this.makeViewport, ...this.getViewportProps(), ...this.getState(), ...newProps }); } applyConstraints(props) { const { pitch, maxPitch, minPitch, longitude, bearing } = props; props.pitch = clamp(pitch, minPitch, maxPitch); if (longitude !== null && (longitude < -180 || longitude > 180)) { props.longitude = mod2(longitude + 180, 360) - 180; } if (bearing < -180 || bearing > 180) { props.bearing = mod2(bearing + 180, 360) - 180; } return props; } }; var FirstPersonController = class extends Controller { constructor() { super(...arguments); this.ControllerState = FirstPersonState; this.transition = { transitionDuration: 300, transitionInterpolator: new LinearInterpolator(["position", "pitch", "bearing"]) }; } }; // src/views/first-person-view.ts var FirstPersonView = class extends View { constructor(props = {}) { super(props); } get ViewportType() { return FirstPersonViewport; } get ControllerType() { return FirstPersonController; } }; FirstPersonView.displayName = "FirstPersonView"; // src/controllers/orbit-controller.ts var OrbitState = class extends ViewState { constructor(options) { const { width, height, rotationX = 0, rotationOrbit = 0, target = [0, 0, 0], zoom = 0, minRotationX = -90, maxRotationX = 90, minZoom = -Infinity, maxZoom = Infinity, startPanPosition, startRotatePos, startRotationX, startRotationOrbit, startZoomPosition, startZoom } = options; super( { width, height, rotationX, rotationOrbit, target, zoom, minRotationX, maxRotationX, minZoom, maxZoom }, { startPanPosition, startRotatePos, startRotationX, startRotationOrbit, startZoomPosition, startZoom } ); this.makeViewport = options.makeViewport; } panStart({ pos }) { return this._getUpdatedState({ startPanPosition: this._unproject(pos) }); } pan({ pos, startPosition }) { const startPanPosition = this.getState().startPanPosition || startPosition; if (!startPanPosition) { return this; } const viewport = this.makeViewport(this.getViewportProps()); const newProps = viewport.panByPosition(startPanPosition, pos); return this._getUpdatedState(newProps); } panEnd() { return this._getUpdatedState({ startPanPosition: null }); } rotateStart({ pos }) { return this._getUpdatedState({ startRotatePos: pos, startRotationX: this.getViewportProps().rotationX, startRotationOrbit: this.getViewportProps().rotationOrbit }); } rotate({ pos, deltaAngleX = 0, deltaAngleY = 0 }) { const { startRotatePos, startRotationX, startRotationOrbit } = this.getState(); const { width, height } = this.getViewportProps(); if (!startRotatePos || startRotationX === void 0 || startRotationOrbit === void 0) { return this; } let newRotation; if (pos) { let deltaScaleX = (pos[0] - startRotatePos[0]) / width; const deltaScaleY = (pos[1] - startRotatePos[1]) / height; if (startRotationX < -90 || startRotationX > 90) { deltaScaleX *= -1; } newRotation = { rotationX: startRotationX + deltaScaleY * 180, rotationOrbit: startRotationOrbit + deltaScaleX * 180 }; } else { newRotation = { rotationX: startRotationX + deltaAngleY, rotationOrbit: startRotationOrbit + deltaAngleX }; } return this._getUpdatedState(newRotation); } rotateEnd() { return this._getUpdatedState({ startRotationX: null, startRotationOrbit: null }); } shortestPathFrom(viewState) { const fromProps = viewState.getViewportProps(); const props = { ...this.getViewportProps() }; const { rotationOrbit } = props; if (Math.abs(rotationOrbit - fromProps.rotationOrbit) > 180) { props.rotationOrbit = rotationOrbit < 0 ? rotationOrbit + 360 : rotationOrbit - 360; } return props; } zoomStart({ pos }) { return this._getUpdatedState({ startZoomPosition: this._unproject(pos), startZoom: this.getViewportProps().zoom }); } zoom({ pos, startPos, scale: scale5 }) { let { startZoom, startZoomPosition } = this.getState(); if (!startZoomPosition) { startZoom = this.getViewportProps().zoom; startZoomPosition = this._unproject(startPos) || this._unproject(pos); } if (!startZoomPosition) { return this; } const newZoom = this._calculateNewZoom({ scale: scale5, startZoom }); const zoomedViewport = this.makeViewport({ ...this.getViewportProps(), zoom: newZoom }); return this._getUpdatedState({ zoom: newZoom, ...zoomedViewport.panByPosition(startZoomPosition, pos) }); } zoomEnd() { return this._getUpdatedState({ startZoomPosition: null, startZoom: null }); } zoomIn(speed = 2) { return this._getUpdatedState({ zoom: this._calculateNewZoom({ scale: speed }) }); } zoomOut(speed = 2) { return this._getUpdatedState({ zoom: this._calculateNewZoom({ scale: 1 / speed }) }); } moveLeft(speed = 50) { return this._panFromCenter([-speed, 0]); } moveRight(speed = 50) { return this._panFromCenter([speed, 0]); } moveUp(speed = 50) { return this._panFromCenter([0, -speed]); } moveDown(speed = 50) { return this._panFromCenter([0, speed]); } rotateLeft(speed = 15) { return this._getUpdatedState({ rotationOrbit: this.getViewportProps().rotationOrbit - speed }); } rotateRight(speed = 15) { return this._getUpdatedState({ rotationOrbit: this.getViewportProps().rotationOrbit + speed }); } rotateUp(speed = 10) { return this._getUpdatedState({ rotationX: this.getViewportProps().rotationX - speed }); } rotateDown(speed = 10) { return this._getUpdatedState({ rotationX: this.getViewportProps().rotationX + speed }); } _unproject(pos) { const viewport = this.makeViewport(this.getViewportProps()); return pos && viewport.unproject(pos); } _calculateNewZoom({ scale: scale5, startZoom }) { const { maxZoom, minZoom } = this.getViewportProps(); if (startZoom === void 0) { startZoom = this.getViewportProps().zoom; } const zoom = startZoom + Math.log2(scale5); return clamp(zoom, minZoom, maxZoom); } _panFromCenter(offset) { const { width, height, target } = this.getViewportProps(); return this.pan({ startPosition: target, pos: [width / 2 + offset[0], height / 2 + offset[1]] }); } _getUpdatedState(newProps) { return new this.constructor({ makeViewport: this.makeViewport, ...this.getViewportProps(), ...this.getState(), ...newProps }); } applyConstraints(props) { const { maxZoom, minZoom, zoom, maxRotationX, minRotationX, rotationOrbit } = props; props.zoom = Array.isArray(zoom) ? [clamp(zoom[0], minZoom, maxZoom), clamp(zoom[1], minZoom, maxZoom)] : clamp(zoom, minZoom, maxZoom); props.rotationX = clamp(props.rotationX, minRotationX, maxRotationX); if (rotationOrbit < -180 || rotationOrbit > 180) { props.rotationOrbit = mod2(rotationOrbit + 180, 360) - 180; } return props; } }; var OrbitController = class extends Controller { constructor() { super(...arguments); this.ControllerState = OrbitState; this.transition = { transitionDuration: 300, transitionInterpolator: new LinearInterpolator({ transitionProps: { compare: ["target", "zoom", "rotationX", "rotationOrbit"], required: ["target", "zoom"] } }) }; } }; // src/views/orbit-view.ts var OrbitView = class extends View { constructor(props = {}) { super(props); this.props.orbitAxis = props.orbitAxis || "Z"; } get ViewportType() { return OrbitViewport; } get ControllerType() { return OrbitController; } }; OrbitView.displayName = "OrbitView"; // src/controllers/orthographic-controller.ts var OrthographicState = class extends OrbitState { constructor(props) { super(props); this.zoomAxis = props.zoomAxis || "all"; } _calculateNewZoom({ scale: scale5, startZoom }) { const { maxZoom, minZoom } = this.getViewportProps(); if (startZoom === void 0) { startZoom = this.getViewportProps().zoom; } let deltaZoom = Math.log2(scale5); if (Array.isArray(startZoom)) { let [newZoomX, newZoomY] = startZoom; switch (this.zoomAxis) { case "X": newZoomX = clamp(newZoomX + deltaZoom, minZoom, maxZoom); break; case "Y": newZoomY = clamp(newZoomY + deltaZoom, minZoom, maxZoom); break; default: let z = Math.min(newZoomX + deltaZoom, newZoomY + deltaZoom); if (z < minZoom) { deltaZoom += minZoom - z; } z = Math.max(newZoomX + deltaZoom, newZoomY + deltaZoom); if (z > maxZoom) { deltaZoom += maxZoom - z; } newZoomX += deltaZoom; newZoomY += deltaZoom; } return [newZoomX, newZoomY]; } return clamp(startZoom + deltaZoom, minZoom, maxZoom); } }; var OrthographicController = class extends Controller { constructor() { super(...arguments); this.ControllerState = OrthographicState; this.transition = { transitionDuration: 300, transitionInterpolator: new LinearInterpolator(["target", "zoom"]) }; this.dragMode = "pan"; } _onPanRotate() { return false; } }; // src/views/orthographic-view.ts var OrthographicView = class extends View { constructor(props = {}) { super(props); } get ViewportType() { return OrthographicViewport; } get ControllerType() { return OrthographicController; } }; OrthographicView.displayName = "OrthographicView"; // src/controllers/globe-controller.ts var GlobeState = class extends MapState { applyConstraints(props) { const { maxZoom, minZoom, zoom } = props; props.zoom = clamp(zoom, minZoom, maxZoom); const { longitude, latitude } = props; if (longitude < -180 || longitude > 180) { props.longitude = mod2(longitude + 180, 360) - 180; } props.latitude = clamp(latitude, -89, 89); return props; } }; var GlobeController = class extends Controller { constructor() { super(...arguments); this.ControllerState = GlobeState; this.transition = { transitionDuration: 300, transitionInterpolator: new LinearInterpolator(["longitude", "latitude", "zoom"]) }; this.dragMode = "pan"; } setProps(props) { super.setProps(props); this.dragRotate = false; this.touchRotate = false; } }; // src/views/globe-view.ts var GlobeView = class extends View { constructor(props = {}) { super(props); } get ViewportType() { return GlobeViewport; } get ControllerType() { return GlobeController; } }; GlobeView.displayName = "GlobeView"; // src/lib/layer-extension.ts var LayerExtension = class { static get componentName() { return Object.prototype.hasOwnProperty.call(this, "extensionName") ? this.extensionName : ""; } constructor(opts) { if (opts) { this.opts = opts; } } equals(extension) { if (this === extension) { return true; } return this.constructor === extension.constructor && deepEqual2(this.opts, extension.opts, 1); } getShaders(extension) { return null; } getSubLayerProps(extension) { const { defaultProps: defaultProps3 } = extension.constructor; const newProps = { updateTriggers: {} }; for (const key in defaultProps3) { if (key in this.props) { const propDef = defaultProps3[key]; const propValue = this.props[key]; newProps[key] = propValue; if (propDef && propDef.type === "accessor") { newProps.updateTriggers[key] = this.props.updateTriggers[key]; if (typeof propValue === "function") { newProps[key] = this.getSubLayerAccessor(propValue); } } } } return newProps; } initializeState(context, extension) { } updateState(params, extension) { } onNeedsRedraw(extension) { } getNeedsPickingBuffer(extension) { return false; } draw(params, extension) { } finalizeState(context, extension) { } }; LayerExtension.defaultProps = {}; LayerExtension.extensionName = "LayerExtension"; // src/transitions/fly-to-interpolator.ts var LINEARLY_INTERPOLATED_PROPS = { bearing: 0, pitch: 0, position: [0, 0, 0] }; var DEFAULT_OPTS2 = { speed: 1.2, curve: 1.414 }; var FlyToInterpolator = class extends TransitionInterpolator { constructor(opts = {}) { super({ compare: ["longitude", "latitude", "zoom", "bearing", "pitch", "position"], extract: ["width", "height", "longitude", "latitude", "zoom", "bearing", "pitch", "position"], required: ["width", "height", "latitude", "longitude", "zoom"] }); this.opts = { ...DEFAULT_OPTS2, ...opts }; } interpolateProps(startProps, endProps, t) { const viewport = flyToViewport(startProps, endProps, t, this.opts); for (const key in LINEARLY_INTERPOLATED_PROPS) { viewport[key] = lerp( startProps[key] || LINEARLY_INTERPOLATED_PROPS[key], endProps[key] || LINEARLY_INTERPOLATED_PROPS[key], t ); } return viewport; } getDuration(startProps, endProps) { let { transitionDuration } = endProps; if (transitionDuration === "auto") { transitionDuration = getFlyToDuration(startProps, endProps, this.opts); } return transitionDuration; } }; // src/utils/tesselator.ts var Tesselator = class { constructor(opts) { this.indexStarts = [0]; this.vertexStarts = [0]; this.vertexCount = 0; this.instanceCount = 0; const { attributes = {} } = opts; this.typedArrayManager = typed_array_manager_default; this.attributes = {}; this._attributeDefs = attributes; this.opts = opts; this.updateGeometry(opts); } updateGeometry(opts) { Object.assign(this.opts, opts); const { data, buffers = {}, getGeometry, geometryBuffer, positionFormat, dataChanged, normalize: normalize4 = true } = this.opts; this.data = data; this.getGeometry = getGeometry; this.positionSize = geometryBuffer && geometryBuffer.size || (positionFormat === "XY" ? 2 : 3); this.buffers = buffers; this.normalize = normalize4; if (geometryBuffer) { assert8(data.startIndices); this.getGeometry = this.getGeometryFromBuffer(geometryBuffer); if (!normalize4) { buffers.vertexPositions = geometryBuffer; } } this.geometryBuffer = buffers.vertexPositions; if (Array.isArray(dataChanged)) { for (const dataRange of dataChanged) { this._rebuildGeometry(dataRange); } } else { this._rebuildGeometry(); } } updatePartialGeometry({ startRow, endRow }) { this._rebuildGeometry({ startRow, endRow }); } getGeometryFromBuffer(geometryBuffer) { const value = geometryBuffer.value || geometryBuffer; if (!ArrayBuffer.isView(value)) { return null; } return getAccessorFromBuffer(value, { size: this.positionSize, offset: geometryBuffer.offset, stride: geometryBuffer.stride, startIndices: this.data.startIndices }); } _allocate(instanceCount, copy5) { const { attributes, buffers, _attributeDefs, typedArrayManager } = this; for (const name2 in _attributeDefs) { if (name2 in buffers) { typedArrayManager.release(attributes[name2]); attributes[name2] = null; } else { const def = _attributeDefs[name2]; def.copy = copy5; attributes[name2] = typedArrayManager.allocate(attributes[name2], instanceCount, def); } } } _forEachGeometry(visitor, startRow, endRow) { const { data, getGeometry } = this; const { iterable, objectInfo } = createIterable(data, startRow, endRow); for (const object of iterable) { objectInfo.index++; const geometry = getGeometry ? getGeometry(object, objectInfo) : null; visitor(geometry, objectInfo.index); } } _rebuildGeometry(dataRange) { if (!this.data) { return; } let { indexStarts, vertexStarts, instanceCount } = this; const { data, geometryBuffer } = this; const { startRow = 0, endRow = Infinity } = dataRange || {}; const normalizedData = {}; if (!dataRange) { indexStarts = [0]; vertexStarts = [0]; } if (this.normalize || !geometryBuffer) { this._forEachGeometry( (geometry, dataIndex) => { const normalizedGeometry = geometry && this.normalizeGeometry(geometry); normalizedData[dataIndex] = normalizedGeometry; vertexStarts[dataIndex + 1] = vertexStarts[dataIndex] + (normalizedGeometry ? this.getGeometrySize(normalizedGeometry) : 0); }, startRow, endRow ); instanceCount = vertexStarts[vertexStarts.length - 1]; } else { vertexStarts = data.startIndices; instanceCount = vertexStarts[data.length] || 0; if (ArrayBuffer.isView(geometryBuffer)) { instanceCount = instanceCount || geometryBuffer.length / this.positionSize; } else if (geometryBuffer instanceof Buffer2) { const byteStride = this.positionSize * 4; instanceCount = instanceCount || geometryBuffer.byteLength / byteStride; } else if (geometryBuffer.buffer) { const byteStride = geometryBuffer.stride || this.positionSize * 4; instanceCount = instanceCount || geometryBuffer.buffer.byteLength / byteStride; } else if (geometryBuffer.value) { const bufferValue = geometryBuffer.value; const elementStride = geometryBuffer.stride / bufferValue.BYTES_PER_ELEMENT || this.positionSize; instanceCount = instanceCount || bufferValue.length / elementStride; } } this._allocate(instanceCount, Boolean(dataRange)); this.indexStarts = indexStarts; this.vertexStarts = vertexStarts; this.instanceCount = instanceCount; const context = {}; this._forEachGeometry( (geometry, dataIndex) => { const normalizedGeometry = normalizedData[dataIndex] || geometry; context.vertexStart = vertexStarts[dataIndex]; context.indexStart = indexStarts[dataIndex]; const vertexEnd = dataIndex < vertexStarts.length - 1 ? vertexStarts[dataIndex + 1] : instanceCount; context.geometrySize = vertexEnd - vertexStarts[dataIndex]; context.geometryIndex = dataIndex; this.updateGeometryAttributes(normalizedGeometry, context); }, startRow, endRow ); this.vertexCount = indexStarts[indexStarts.length - 1]; } }; // src/scripting/map-wrapper.ts var MapWrapper = class { constructor(props) { this.map = null; this.width = 0; this.height = 0; this.props = { ...props }; this._initialize(this.props); } finalize() { this.map?.remove(); this.map = null; } setProps(props) { const oldProps = this.props; const newProps = { ...this.props, ...props }; this.props = newProps; if (!this.map) { return; } const needsRedraw = this._update(oldProps, newProps); if (needsRedraw) { this.redraw(); } } redraw() { const map3 = this.map; if (map3.style) { if (map3._frame) { map3._frame.cancel(); map3._frame = null; } map3._render(); } } getMap() { return this.map; } _initialize(props) { const { mapLib, container } = props; mapLib.accessToken = props.mapboxApiAccessToken || ""; this.map = new props.mapLib.Map({ container, maxZoom: 24, ...props.mapOptions, ...viewStateToMapboxProps(props.viewState), style: props.mapStyle, interactive: false, trackResize: false }); Object.defineProperty(container, "offsetWidth", { get: () => this.width }); Object.defineProperty(container, "clientWidth", { get: () => this.width }); Object.defineProperty(container, "offsetHeight", { get: () => this.height }); Object.defineProperty(container, "clientHeight", { get: () => this.height }); this.map.resize(); } _update(oldProps, newProps) { const styleChanged = oldProps.mapStyle !== newProps.mapStyle; if (styleChanged) { this.map.setStyle(newProps.mapStyle); } const sizeChanged = oldProps.width !== newProps.width || oldProps.height !== newProps.height; if (sizeChanged) { this.width = newProps.width; this.height = newProps.height; this.map.resize(); } const oldViewState = oldProps.viewState; const newViewState = newProps.viewState; const viewportChanged = newViewState.latitude !== oldViewState.latitude || newViewState.longitude !== oldViewState.longitude || newViewState.zoom !== oldViewState.zoom || newViewState.pitch !== oldViewState.pitch || newViewState.bearing !== oldViewState.bearing; if (viewportChanged) { this.map.jumpTo(viewStateToMapboxProps(newViewState)); } return sizeChanged || viewportChanged; } }; function viewStateToMapboxProps(viewState) { return { center: [viewState.longitude, viewState.latitude], zoom: viewState.zoom, bearing: viewState.bearing ?? 0, pitch: viewState.pitch ?? 0 }; } // src/scripting/deckgl.ts var CANVAS_STYLE = { position: "absolute", left: 0, top: 0, width: "100%", height: "100%" }; function createCanvas2(props) { let { container = document.body } = props; if (typeof container === "string") { container = document.getElementById(container); } if (!container) { throw Error("Deck: container not found"); } const containerStyle = window.getComputedStyle(container); if (containerStyle.position === "static") { container.style.position = "relative"; } const mapCanvas = document.createElement("div"); container.appendChild(mapCanvas); Object.assign(mapCanvas.style, CANVAS_STYLE); const deckCanvas = document.createElement("canvas"); container.appendChild(deckCanvas); Object.assign(deckCanvas.style, CANVAS_STYLE); return { container, mapCanvas, deckCanvas }; } var DeckGL = class extends Deck { constructor(props) { if (typeof document === "undefined") { throw Error("Deck can only be used in the browser"); } const { mapCanvas, deckCanvas } = createCanvas2(props); const viewState = props.viewState || props.initialViewState; const isMap = Number.isFinite(viewState && viewState.latitude); const { map: map3 = globalThis.mapboxgl || globalThis.maplibregl } = props; super({ canvas: deckCanvas, ...props }); if (map3 && map3.Map) { this._map = isMap && new MapWrapper({ ...props, width: 0, height: 0, viewState, container: mapCanvas, mapLib: map3 }); } else { this._map = map3; } } getMapboxMap() { return this._map && this._map.getMap(); } finalize() { if (this._map) { this._map.finalize(); } super.finalize(); } setProps(props) { if ("mapStyle" in props && this._map) { this._map.setProps({ mapStyle: props.mapStyle }); } super.setProps(props); } _drawLayers(redrawReason, options) { if (this._map) { const viewport = this.getViewports()[0]; if (viewport) { this._map.setProps({ width: viewport.width, height: viewport.height, viewState: viewport }); } } super._drawLayers(redrawReason, options); } }; // bundle/index.ts globalThis.luma = globalThis.luma || {}; globalThis.loaders = globalThis.loaders || {}; Object.assign(globalThis.luma, lumagl_exports); Object.assign(globalThis.loaders, loadersgl_exports); return __toCommonJS(bundle_exports); })(); return __exports__; });