deck.gl 9.3.0-alpha.6 → 9.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/dist.dev.js +952 -468
  2. package/dist.min.js +437 -269
  3. package/package.json +15 -15
package/dist/dist.dev.js CHANGED
@@ -30931,33 +30931,33 @@ float smoothedge(float edge, float x) {
30931
30931
  /**
30932
30932
  * `LNGLAT` if rendering into a geospatial viewport, `CARTESIAN` otherwise
30933
30933
  */
30934
- DEFAULT: -1,
30934
+ DEFAULT: "default",
30935
30935
  /**
30936
30936
  * Positions are interpreted as [longitude, latitude, elevation]
30937
30937
  * longitude/latitude are in degrees, elevation is in meters.
30938
30938
  * Dimensions are in meters.
30939
30939
  */
30940
- LNGLAT: 1,
30940
+ LNGLAT: "lnglat",
30941
30941
  /**
30942
30942
  * Positions are interpreted as [x, y, z] in meter offsets from the coordinate origin.
30943
30943
  * Dimensions are in meters.
30944
30944
  */
30945
- METER_OFFSETS: 2,
30945
+ METER_OFFSETS: "meter-offsets",
30946
30946
  /**
30947
30947
  * Positions are interpreted as [deltaLng, deltaLat, elevation] from the coordinate origin.
30948
30948
  * deltaLng/deltaLat are in degrees, elevation is in meters.
30949
30949
  * Dimensions are in meters.
30950
30950
  */
30951
- LNGLAT_OFFSETS: 3,
30951
+ LNGLAT_OFFSETS: "lnglat-offsets",
30952
30952
  /**
30953
30953
  * Positions and dimensions are in the common units of the viewport.
30954
30954
  */
30955
- CARTESIAN: 0
30955
+ CARTESIAN: "cartesian"
30956
30956
  };
30957
30957
  Object.defineProperty(COORDINATE_SYSTEM, "IDENTITY", {
30958
30958
  get: () => {
30959
30959
  log_default.deprecated("COORDINATE_SYSTEM.IDENTITY", "COORDINATE_SYSTEM.CARTESIAN")();
30960
- return 0;
30960
+ return COORDINATE_SYSTEM.CARTESIAN;
30961
30961
  }
30962
30962
  });
30963
30963
  var PROJECTION_MODE = {
@@ -31043,6 +31043,20 @@ float smoothedge(float edge, float x) {
31043
31043
  var IDENTITY_MATRIX4 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
31044
31044
  var DEFAULT_PIXELS_PER_UNIT2 = [0, 0, 0];
31045
31045
  var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0];
31046
+ var COORDINATE_SYSTEM_NUMBERS = {
31047
+ default: -1,
31048
+ cartesian: 0,
31049
+ lnglat: 1,
31050
+ "meter-offsets": 2,
31051
+ "lnglat-offsets": 3
31052
+ };
31053
+ function getShaderCoordinateSystem(coordinateSystem) {
31054
+ const shaderCoordinateSystem = COORDINATE_SYSTEM_NUMBERS[coordinateSystem];
31055
+ if (shaderCoordinateSystem === void 0) {
31056
+ throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
31057
+ }
31058
+ return shaderCoordinateSystem;
31059
+ }
31046
31060
  var getMemoizedViewportUniforms = memoize(calculateViewportUniforms);
31047
31061
  function getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin = DEFAULT_COORDINATE_ORIGIN) {
31048
31062
  if (coordinateOrigin.length < 3) {
@@ -31051,7 +31065,7 @@ float smoothedge(float edge, float x) {
31051
31065
  let shaderCoordinateOrigin = coordinateOrigin;
31052
31066
  let geospatialOrigin;
31053
31067
  let offsetMode = true;
31054
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) {
31068
+ if (coordinateSystem === "lnglat-offsets" || coordinateSystem === "meter-offsets") {
31055
31069
  geospatialOrigin = coordinateOrigin;
31056
31070
  } else {
31057
31071
  geospatialOrigin = viewport.isGeospatial ? (
@@ -31061,15 +31075,15 @@ float smoothedge(float edge, float x) {
31061
31075
  }
31062
31076
  switch (viewport.projectionMode) {
31063
31077
  case PROJECTION_MODE.WEB_MERCATOR:
31064
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
31078
+ if (coordinateSystem === "lnglat" || coordinateSystem === "cartesian") {
31065
31079
  geospatialOrigin = [0, 0, 0];
31066
31080
  offsetMode = false;
31067
31081
  }
31068
31082
  break;
31069
31083
  case PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET:
31070
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
31084
+ if (coordinateSystem === "lnglat") {
31071
31085
  shaderCoordinateOrigin = geospatialOrigin;
31072
- } else if (coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
31086
+ } else if (coordinateSystem === "cartesian") {
31073
31087
  shaderCoordinateOrigin = [
31074
31088
  Math.fround(viewport.center[0]),
31075
31089
  Math.fround(viewport.center[1]),
@@ -31133,12 +31147,12 @@ float smoothedge(float edge, float x) {
31133
31147
  devicePixelRatio: devicePixelRatio2 = 1,
31134
31148
  modelMatrix: modelMatrix2 = null,
31135
31149
  // Match Layer.defaultProps
31136
- coordinateSystem = COORDINATE_SYSTEM.DEFAULT,
31150
+ coordinateSystem = "default",
31137
31151
  coordinateOrigin = DEFAULT_COORDINATE_ORIGIN,
31138
31152
  autoWrapLongitude = false
31139
31153
  }) {
31140
- if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
31141
- coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN;
31154
+ if (coordinateSystem === "default") {
31155
+ coordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
31142
31156
  }
31143
31157
  const uniforms = getMemoizedViewportUniforms({
31144
31158
  viewport,
@@ -31172,7 +31186,7 @@ float smoothedge(float edge, float x) {
31172
31186
  const focalDistance = vec4_exports.transformMat4([], [0, 0, -viewport.focalDistance, 1], viewport.projectionMatrix)[3] || 1;
31173
31187
  const uniforms = {
31174
31188
  // Projection mode values
31175
- coordinateSystem,
31189
+ coordinateSystem: getShaderCoordinateSystem(coordinateSystem),
31176
31190
  projectionMode: viewport.projectionMode,
31177
31191
  coordinateOrigin: shaderCoordinateOrigin,
31178
31192
  commonOrigin: originCommon.slice(0, 3),
@@ -31199,19 +31213,19 @@ float smoothedge(float edge, float x) {
31199
31213
  if (geospatialOrigin) {
31200
31214
  const distanceScalesAtOrigin = viewport.getDistanceScales(geospatialOrigin);
31201
31215
  switch (coordinateSystem) {
31202
- case COORDINATE_SYSTEM.METER_OFFSETS:
31216
+ case "meter-offsets":
31203
31217
  uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter;
31204
31218
  uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2;
31205
31219
  break;
31206
- case COORDINATE_SYSTEM.LNGLAT:
31207
- case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
31220
+ case "lnglat":
31221
+ case "lnglat-offsets":
31208
31222
  if (!viewport._pseudoMeters) {
31209
31223
  uniforms.commonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter;
31210
31224
  }
31211
31225
  uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerDegree;
31212
31226
  uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerDegree2;
31213
31227
  break;
31214
- case COORDINATE_SYSTEM.CARTESIAN:
31228
+ case "cartesian":
31215
31229
  uniforms.commonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]];
31216
31230
  uniforms.commonUnitsPerWorldUnit2 = [0, 0, distanceScalesAtOrigin.unitsPerMeter2[2]];
31217
31231
  break;
@@ -31223,7 +31237,16 @@ float smoothedge(float edge, float x) {
31223
31237
  }
31224
31238
 
31225
31239
  // ../core/src/shaderlib/project/project.wgsl.ts
31226
- var COORDINATE_SYSTEM_WGSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const COORDINATE_SYSTEM_${key}: i32 = ${COORDINATE_SYSTEM[key]};`).join("");
31240
+ var SHADER_COORDINATE_SYSTEMS = [
31241
+ "default",
31242
+ "lnglat",
31243
+ "meter-offsets",
31244
+ "lnglat-offsets",
31245
+ "cartesian"
31246
+ ];
31247
+ var COORDINATE_SYSTEM_WGSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS.map(
31248
+ (coordinateSystem) => `const COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll("-", "_")}: i32 = ${getShaderCoordinateSystem(coordinateSystem)};`
31249
+ ).join("");
31227
31250
  var PROJECTION_MODE_WGSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const PROJECTION_MODE_${key}: i32 = ${PROJECTION_MODE[key]};`).join("");
31228
31251
  var UNIT_WGSL_CONSTANTS = Object.keys(UNIT).map((key) => `const UNIT_${key.toUpperCase()}: i32 = ${UNIT[key]};`).join("");
31229
31252
  var projectWGSLHeader = (
@@ -31517,7 +31540,16 @@ fn project_pixel_size_vec2(pixels: vec2<f32>) -> vec2<f32> {
31517
31540
  );
31518
31541
 
31519
31542
  // ../core/src/shaderlib/project/project.glsl.ts
31520
- var COORDINATE_SYSTEM_GLSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const int COORDINATE_SYSTEM_${key} = ${COORDINATE_SYSTEM[key]};`).join("");
31543
+ var SHADER_COORDINATE_SYSTEMS2 = [
31544
+ "default",
31545
+ "lnglat",
31546
+ "meter-offsets",
31547
+ "lnglat-offsets",
31548
+ "cartesian"
31549
+ ];
31550
+ var COORDINATE_SYSTEM_GLSL_CONSTANTS = SHADER_COORDINATE_SYSTEMS2.map(
31551
+ (coordinateSystem) => `const int COORDINATE_SYSTEM_${coordinateSystem.toUpperCase().replaceAll("-", "_")} = ${getShaderCoordinateSystem(coordinateSystem)};`
31552
+ ).join("");
31521
31553
  var PROJECTION_MODE_GLSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const int PROJECTION_MODE_${key} = ${PROJECTION_MODE[key]};`).join("");
31522
31554
  var UNIT_GLSL_CONSTANTS = Object.keys(UNIT).map((key) => `const int UNIT_${key.toUpperCase()} = ${UNIT[key]};`).join("");
31523
31555
  var projectGLSL = (
@@ -32425,7 +32457,7 @@ ${fragment}
32425
32457
  for (let i4 = 0; i4 < opts.shadowMatrices.length; i4++) {
32426
32458
  const viewProjectionMatrix = viewProjectionMatrices[i4];
32427
32459
  const viewProjectionMatrixCentered = viewProjectionMatrix.clone().translate(new Vector3(projectProps.viewport.center).negate());
32428
- if (projectUniforms.coordinateSystem === COORDINATE_SYSTEM.LNGLAT && projectUniforms.projectionMode === PROJECTION_MODE.WEB_MERCATOR) {
32460
+ if (projectUniforms.coordinateSystem === getShaderCoordinateSystem("lnglat") && projectUniforms.projectionMode === PROJECTION_MODE.WEB_MERCATOR) {
32429
32461
  viewProjectionMatrices[i4] = viewProjectionMatrixCentered;
32430
32462
  projectCenters[i4] = center2;
32431
32463
  } else {
@@ -32485,7 +32517,7 @@ ${fragment}
32485
32517
  isActive: f32,
32486
32518
  isAttribute: f32,
32487
32519
  isHighlightActive: f32,
32488
- useFloatColors: f32,
32520
+ useByteColors: f32,
32489
32521
  highlightedObjectColor: vec3<f32>,
32490
32522
  highlightColor: vec4<f32>,
32491
32523
  };
@@ -32493,11 +32525,11 @@ ${fragment}
32493
32525
  @group(0) @binding(auto) var<uniform> picking: pickingUniforms;
32494
32526
 
32495
32527
  fn picking_normalizeColor(color: vec3<f32>) -> vec3<f32> {
32496
- return select(color / 255.0, color, picking.useFloatColors > 0.5);
32528
+ return select(color, color / 255.0, picking.useByteColors > 0.5);
32497
32529
  }
32498
32530
 
32499
32531
  fn picking_normalizeColor4(color: vec4<f32>) -> vec4<f32> {
32500
- return select(color / 255.0, color, picking.useFloatColors > 0.5);
32532
+ return select(color, color / 255.0, picking.useByteColors > 0.5);
32501
32533
  }
32502
32534
 
32503
32535
  fn picking_isColorZero(color: vec3<f32>) -> bool {
@@ -32512,7 +32544,7 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
32512
32544
  var picking_default = {
32513
32545
  ...picking,
32514
32546
  source: sourceWGSL,
32515
- defaultUniforms: { ...picking.defaultUniforms, useFloatColors: false },
32547
+ defaultUniforms: { ...picking.defaultUniforms, useByteColors: true },
32516
32548
  inject: {
32517
32549
  "vs:DECKGL_FILTER_GL_POSITION": `
32518
32550
  // for picking depth values
@@ -33892,11 +33924,13 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
33892
33924
  function normalizeParameters(opts) {
33893
33925
  const { viewport, modelMatrix: modelMatrix2, coordinateOrigin } = opts;
33894
33926
  let { coordinateSystem, fromCoordinateSystem, fromCoordinateOrigin } = opts;
33895
- if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
33896
- coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN;
33927
+ if (coordinateSystem === "default") {
33928
+ coordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
33897
33929
  }
33898
33930
  if (fromCoordinateSystem === void 0) {
33899
33931
  fromCoordinateSystem = coordinateSystem;
33932
+ } else if (fromCoordinateSystem === "default") {
33933
+ fromCoordinateSystem = viewport.isGeospatial ? "lnglat" : "cartesian";
33900
33934
  }
33901
33935
  if (fromCoordinateOrigin === void 0) {
33902
33936
  fromCoordinateOrigin = coordinateOrigin;
@@ -33922,23 +33956,32 @@ fn picking_isColorValid(color: vec3<f32>) -> bool {
33922
33956
  [x2, y3, z3] = vec4_exports.transformMat4([], [x2, y3, z3, 1], modelMatrix2);
33923
33957
  }
33924
33958
  switch (coordinateSystem) {
33925
- case COORDINATE_SYSTEM.LNGLAT:
33959
+ case "default":
33960
+ return getWorldPosition(position, {
33961
+ viewport,
33962
+ modelMatrix: modelMatrix2,
33963
+ coordinateSystem: viewport.isGeospatial ? "lnglat" : "cartesian",
33964
+ coordinateOrigin,
33965
+ offsetMode
33966
+ });
33967
+ case "lnglat":
33926
33968
  return lngLatZToWorldPosition([x2, y3, z3], viewport, offsetMode);
33927
- case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
33969
+ case "lnglat-offsets":
33928
33970
  return lngLatZToWorldPosition(
33929
33971
  [x2 + coordinateOrigin[0], y3 + coordinateOrigin[1], z3 + (coordinateOrigin[2] || 0)],
33930
33972
  viewport,
33931
33973
  offsetMode
33932
33974
  );
33933
- case COORDINATE_SYSTEM.METER_OFFSETS:
33975
+ case "meter-offsets":
33934
33976
  return lngLatZToWorldPosition(
33935
33977
  addMetersToLngLat(coordinateOrigin, [x2, y3, z3]),
33936
33978
  viewport,
33937
33979
  offsetMode
33938
33980
  );
33939
- case COORDINATE_SYSTEM.CARTESIAN:
33940
- default:
33981
+ case "cartesian":
33941
33982
  return viewport.isGeospatial ? [x2 + coordinateOrigin[0], y3 + coordinateOrigin[1], z3 + coordinateOrigin[2]] : viewport.projectPosition([x2, y3, z3]);
33983
+ default:
33984
+ throw new Error(`Invalid coordinateSystem: ${coordinateSystem}`);
33942
33985
  }
33943
33986
  }
33944
33987
  function projectPosition(position, params) {
@@ -44349,10 +44392,14 @@ void main() {
44349
44392
  }
44350
44393
  if (!this.value) {
44351
44394
  } else if (this.constant || !this.buffer || this.buffer.byteLength < this.value.byteLength + this.byteOffset) {
44352
- this.setData({
44353
- value: this.value,
44354
- constant: this.constant
44355
- });
44395
+ if (this.constant) {
44396
+ this.setConstantValue(context, this.value);
44397
+ } else {
44398
+ this.setData({
44399
+ value: this.value,
44400
+ constant: this.constant
44401
+ });
44402
+ }
44356
44403
  this.constant = false;
44357
44404
  } else {
44358
44405
  for (const [startRow, endRow] of updateRanges) {
@@ -44372,17 +44419,13 @@ void main() {
44372
44419
  // Use generic value
44373
44420
  // Returns true if successful
44374
44421
  setConstantValue(context, value) {
44375
- const isWebGPU = this.device.type === "webgpu";
44376
- if (isWebGPU || value === void 0 || typeof value === "function") {
44377
- if (isWebGPU && typeof value !== "function") {
44378
- const normalisedValue = this._normalizeValue(value, [], 0);
44379
- if (!this._areValuesEqual(normalisedValue, this.value)) {
44380
- this.setNeedsUpdate("WebGPU constant updated");
44381
- }
44382
- }
44422
+ if (value === void 0 || typeof value === "function") {
44383
44423
  return false;
44384
44424
  }
44385
44425
  const transformedValue = this.settings.transform && context ? this.settings.transform.call(context, value) : value;
44426
+ if (this.device.type === "webgpu") {
44427
+ return this.setConstantBufferValue(transformedValue, this.numInstances);
44428
+ }
44386
44429
  const hasChanged = this.setData({ constant: true, value: transformedValue });
44387
44430
  if (hasChanged) {
44388
44431
  this.setNeedsRedraw();
@@ -44390,6 +44433,41 @@ void main() {
44390
44433
  this.clearNeedsUpdate();
44391
44434
  return true;
44392
44435
  }
44436
+ setConstantBufferValue(value, numInstances) {
44437
+ const ArrayType = this.settings.defaultType;
44438
+ const constantValue = this._normalizeValue(value, new ArrayType(this.size), 0);
44439
+ if (this._hasConstantBufferValue(constantValue, numInstances)) {
44440
+ this.constant = false;
44441
+ this.clearNeedsUpdate();
44442
+ return false;
44443
+ }
44444
+ const repeatedValue = new ArrayType(Math.max(numInstances, 1) * this.size);
44445
+ for (let i4 = 0; i4 < repeatedValue.length; i4 += this.size) {
44446
+ repeatedValue.set(constantValue, i4);
44447
+ }
44448
+ const hasChanged = this.setData({ value: repeatedValue });
44449
+ this.constant = false;
44450
+ this.clearNeedsUpdate();
44451
+ if (hasChanged) {
44452
+ this.setNeedsRedraw();
44453
+ }
44454
+ return hasChanged;
44455
+ }
44456
+ _hasConstantBufferValue(value, numInstances) {
44457
+ const currentValue = this.value;
44458
+ const expectedLength = Math.max(numInstances, 1) * this.size;
44459
+ if (!ArrayBuffer.isView(currentValue) || currentValue.length !== expectedLength || currentValue.length % this.size !== 0) {
44460
+ return false;
44461
+ }
44462
+ for (let i4 = 0; i4 < currentValue.length; i4 += this.size) {
44463
+ for (let j3 = 0; j3 < this.size; j3++) {
44464
+ if (currentValue[i4 + j3] !== value[j3]) {
44465
+ return false;
44466
+ }
44467
+ }
44468
+ }
44469
+ return true;
44470
+ }
44393
44471
  // Use external buffer
44394
44472
  // Returns true if successful
44395
44473
  // eslint-disable-next-line max-statements
@@ -44498,18 +44576,10 @@ void main() {
44498
44576
  props,
44499
44577
  numInstances
44500
44578
  }) {
44501
- if (attribute.constant) {
44502
- if (this.context.device.type !== "webgpu") {
44503
- return;
44504
- }
44505
- }
44506
44579
  const { settings, state, value, size: size2, startIndices } = attribute;
44507
44580
  const { accessor, transform: transform2 } = settings;
44508
- let accessorFunc = state.binaryAccessor || // @ts-ignore
44581
+ const accessorFunc = state.binaryAccessor || // @ts-ignore
44509
44582
  (typeof accessor === "function" ? accessor : props[accessor]);
44510
- if (typeof accessorFunc !== "function" && typeof accessor === "string") {
44511
- accessorFunc = () => props[accessor];
44512
- }
44513
44583
  assert10(typeof accessorFunc === "function", `accessor "${accessor}" is not a function`);
44514
44584
  let i4 = attribute.getVertexOffset(startRow);
44515
44585
  const { iterable, objectInfo } = createIterable(data, startRow, endRow);
@@ -46665,7 +46735,7 @@ void main(void) {
46665
46735
  onDragStart: { type: "function", value: null, optional: true },
46666
46736
  onDrag: { type: "function", value: null, optional: true },
46667
46737
  onDragEnd: { type: "function", value: null, optional: true },
46668
- coordinateSystem: COORDINATE_SYSTEM.DEFAULT,
46738
+ coordinateSystem: "default",
46669
46739
  coordinateOrigin: { type: "array", value: [0, 0, 0], compare: true },
46670
46740
  modelMatrix: { type: "array", value: null, compare: true, optional: true },
46671
46741
  wrapLongitude: false,
@@ -46809,7 +46879,7 @@ void main(void) {
46809
46879
  }
46810
46880
  use64bitPositions() {
46811
46881
  const { coordinateSystem } = this.props;
46812
- return coordinateSystem === COORDINATE_SYSTEM.DEFAULT || coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN;
46882
+ return coordinateSystem === "default" || coordinateSystem === "lnglat" || coordinateSystem === "cartesian";
46813
46883
  }
46814
46884
  // Event handling
46815
46885
  onHover(info, pickingEvent) {
@@ -47189,7 +47259,6 @@ void main(void) {
47189
47259
  /* (Internal) Called by layer manager when a new layer is found */
47190
47260
  _initialize() {
47191
47261
  assert10(!this.internalState);
47192
- assert10(Number.isFinite(this.props.coordinateSystem));
47193
47262
  debug(TRACE_INITIALIZE, this);
47194
47263
  const attributeManager = this._getAttributeManager();
47195
47264
  if (attributeManager) {
@@ -50212,7 +50281,7 @@ void main(void) {
50212
50281
  var defaultProps4 = {
50213
50282
  image: { type: "image", value: null, async: true },
50214
50283
  bounds: { type: "array", value: [1, 0, 0, 1], compare: true },
50215
- _imageCoordinateSystem: COORDINATE_SYSTEM.DEFAULT,
50284
+ _imageCoordinateSystem: "default",
50216
50285
  desaturate: { type: "number", min: 0, max: 1, value: 0 },
50217
50286
  // More context: because of the blending mode we're using for ground imagery,
50218
50287
  // alpha is not effective when blending the bitmap layers with the base map.
@@ -50344,19 +50413,18 @@ void main(void) {
50344
50413
  }
50345
50414
  }
50346
50415
  _getCoordinateUniforms() {
50347
- const { LNGLAT, CARTESIAN, DEFAULT } = COORDINATE_SYSTEM;
50348
50416
  let { _imageCoordinateSystem: imageCoordinateSystem } = this.props;
50349
- if (imageCoordinateSystem !== DEFAULT) {
50417
+ if (imageCoordinateSystem !== "default") {
50350
50418
  const { bounds } = this.props;
50351
50419
  if (!isRectangularBounds(bounds)) {
50352
50420
  throw new Error("_imageCoordinateSystem only supports rectangular bounds");
50353
50421
  }
50354
- const defaultImageCoordinateSystem = this.context.viewport.resolution ? LNGLAT : CARTESIAN;
50355
- imageCoordinateSystem = imageCoordinateSystem === LNGLAT ? LNGLAT : CARTESIAN;
50356
- if (imageCoordinateSystem === LNGLAT && defaultImageCoordinateSystem === CARTESIAN) {
50422
+ const defaultImageCoordinateSystem = this.context.viewport.resolution ? "lnglat" : "cartesian";
50423
+ imageCoordinateSystem = imageCoordinateSystem === "lnglat" ? "lnglat" : "cartesian";
50424
+ if (imageCoordinateSystem === "lnglat" && defaultImageCoordinateSystem === "cartesian") {
50357
50425
  return { coordinateConversion: -1, bounds };
50358
50426
  }
50359
- if (imageCoordinateSystem === CARTESIAN && defaultImageCoordinateSystem === LNGLAT) {
50427
+ if (imageCoordinateSystem === "cartesian" && defaultImageCoordinateSystem === "lnglat") {
50360
50428
  const bottomLeft = lngLatToWorld([bounds[0], bounds[1]]);
50361
50429
  const topRight = lngLatToWorld([bounds[2], bounds[3]]);
50362
50430
  return {
@@ -50745,7 +50813,8 @@ fn fragmentMain(inp: Varyings) -> @location(0) vec4<f32> {
50745
50813
  width: oldWidth,
50746
50814
  height: oldHeight
50747
50815
  });
50748
- commandEncoder.finish();
50816
+ const commandBuffer = commandEncoder.finish();
50817
+ device.submit(commandBuffer);
50749
50818
  regenerateMipmaps(newTexture);
50750
50819
  texture.destroy();
50751
50820
  return newTexture;
@@ -52072,7 +52141,7 @@ void main(void) {
52072
52141
 
52073
52142
  float distToCenter = length(unitPosition) * outerRadiusPixels;
52074
52143
  float inCircle = scatterplot.antialiasing ?
52075
- smoothedge(distToCenter, outerRadiusPixels) :
52144
+ smoothedge(distToCenter, outerRadiusPixels) :
52076
52145
  step(distToCenter, outerRadiusPixels);
52077
52146
 
52078
52147
  if (inCircle == 0.0) {
@@ -52080,7 +52149,7 @@ void main(void) {
52080
52149
  }
52081
52150
 
52082
52151
  if (scatterplot.stroked > 0.5) {
52083
- float isLine = scatterplot.antialiasing ?
52152
+ float isLine = scatterplot.antialiasing ?
52084
52153
  smoothedge(innerUnitRadius * outerRadiusPixels, distToCenter) :
52085
52154
  step(innerUnitRadius * outerRadiusPixels, distToCenter);
52086
52155
 
@@ -52174,7 +52243,7 @@ struct Attributes {
52174
52243
  @location(4) instanceLineWidths: f32,
52175
52244
  @location(5) instanceFillColors: vec4<f32>,
52176
52245
  @location(6) instanceLineColors: vec4<f32>,
52177
- @location(7) instancePickingColors: vec3<f32>
52246
+ @location(7) instancePickingColors: vec3<f32>,
52178
52247
  };
52179
52248
 
52180
52249
  struct Varyings {
@@ -55100,11 +55169,11 @@ void main(void) {
55100
55169
  const { viewport } = this.context;
55101
55170
  let { coordinateSystem } = this.props;
55102
55171
  const { _full3d } = this.props;
55103
- if (viewport.isGeospatial && coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
55104
- coordinateSystem = COORDINATE_SYSTEM.LNGLAT;
55172
+ if (viewport.isGeospatial && coordinateSystem === "default") {
55173
+ coordinateSystem = "lnglat";
55105
55174
  }
55106
55175
  let preproject;
55107
- if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
55176
+ if (coordinateSystem === "lnglat") {
55108
55177
  if (_full3d) {
55109
55178
  preproject = viewport.projectPosition.bind(viewport);
55110
55179
  } else {
@@ -55671,6 +55740,7 @@ void main(void) {
55671
55740
  var glslUniformBlock3 = `layout(std140) uniform textUniforms {
55672
55741
  highp vec2 cutoffPixels;
55673
55742
  highp ivec2 align;
55743
+ highp float fontSize;
55674
55744
  bool flipY;
55675
55745
  } text;
55676
55746
 
@@ -55685,15 +55755,18 @@ void main(void) {
55685
55755
  contentCutoffPixels = [0, 0],
55686
55756
  contentAlignHorizontal = "none",
55687
55757
  contentAlignVertical = "none",
55758
+ fontSize,
55688
55759
  viewport
55689
55760
  }) => ({
55690
55761
  cutoffPixels: contentCutoffPixels,
55691
55762
  align: [CONTENT_ALIGN[contentAlignHorizontal], CONTENT_ALIGN[contentAlignVertical]],
55763
+ fontSize,
55692
55764
  flipY: viewport?.flipY ?? false
55693
55765
  }),
55694
55766
  uniformTypes: {
55695
55767
  cutoffPixels: "vec2<f32>",
55696
55768
  align: "vec2<i32>",
55769
+ fontSize: "f32",
55697
55770
  flipY: "f32"
55698
55771
  }
55699
55772
  };
@@ -55762,9 +55835,7 @@ void main(void) {
55762
55835
  icon.sizeMinPixels, icon.sizeMaxPixels
55763
55836
  );
55764
55837
 
55765
- // Choose correct constraint based on the 'sizeBasis' value (0.0 = width, 1.0 = height)
55766
- float iconConstraint = icon.sizeBasis == 0.0 ? iconSize.x : iconSize.y;
55767
- float instanceScale = iconConstraint == 0.0 ? 0.0 : sizePixels / iconConstraint;
55838
+ float instanceScale = sizePixels / text.fontSize;
55768
55839
 
55769
55840
  // scale and rotate vertex in "pixel" value and convert back to fraction in clipspace
55770
55841
  vec2 pixelOffset = positions / 2.0 * iconSize + instanceOffsets;
@@ -55902,6 +55973,7 @@ void main(void) {
55902
55973
  var defaultProps14 = {
55903
55974
  getIconOffsets: { type: "accessor", value: (x2) => x2.offsets },
55904
55975
  getContentBox: { type: "accessor", value: [0, 0, -1, -1] },
55976
+ fontSize: 1,
55905
55977
  alphaCutoff: 1e-3,
55906
55978
  smoothing: 0.1,
55907
55979
  outlineWidth: 0,
@@ -55959,6 +56031,7 @@ void main(void) {
55959
56031
  const {
55960
56032
  sdf,
55961
56033
  smoothing,
56034
+ fontSize,
55962
56035
  outlineWidth,
55963
56036
  contentCutoffPixels,
55964
56037
  contentAlignHorizontal,
@@ -55978,6 +56051,7 @@ void main(void) {
55978
56051
  contentCutoffPixels,
55979
56052
  contentAlignHorizontal,
55980
56053
  contentAlignVertical,
56054
+ fontSize,
55981
56055
  viewport: this.context.viewport
55982
56056
  };
55983
56057
  model.shaderInputs.setProps({ sdf: sdfProps, text: textProps });
@@ -56005,7 +56079,7 @@ void main(void) {
56005
56079
  for (const char of Array.from(text)) {
56006
56080
  const def = super.getInstanceIconDef(char);
56007
56081
  def[0] = offsets[j3 * 2];
56008
- def[1] = offsets[j3 * 2 + 1];
56082
+ def[1] += offsets[j3 * 2 + 1];
56009
56083
  def[6] = 1;
56010
56084
  output.set(def, i4);
56011
56085
  i4 += attribute.size;
@@ -56141,47 +56215,52 @@ void main(void) {
56141
56215
  }
56142
56216
  function buildMapping2({
56143
56217
  characterSet,
56144
- getFontWidth,
56145
- fontHeight,
56218
+ measureText: measureText2,
56146
56219
  buffer,
56147
56220
  maxCanvasWidth,
56148
56221
  mapping = {},
56149
56222
  xOffset = 0,
56150
- yOffset = 0
56223
+ yOffsetMin = 0,
56224
+ yOffsetMax = 0
56151
56225
  }) {
56152
- let row = 0;
56226
+ const row = 0;
56153
56227
  let x2 = xOffset;
56154
- const rowHeight = fontHeight + buffer * 2;
56228
+ let yMin = yOffsetMin;
56229
+ let yMax = yOffsetMax;
56155
56230
  for (const char of characterSet) {
56156
56231
  if (!mapping[char]) {
56157
- const width = getFontWidth(char);
56232
+ const { advance, width, ascent, descent } = measureText2(char);
56233
+ const height = ascent + descent;
56158
56234
  if (x2 + width + buffer * 2 > maxCanvasWidth) {
56159
56235
  x2 = 0;
56160
- row++;
56236
+ yMin = yMax;
56161
56237
  }
56162
56238
  mapping[char] = {
56163
56239
  x: x2 + buffer,
56164
- y: yOffset + row * rowHeight + buffer,
56240
+ y: yMin + buffer,
56165
56241
  width,
56166
- height: rowHeight,
56167
- layoutWidth: width,
56168
- layoutHeight: fontHeight
56242
+ height,
56243
+ advance,
56244
+ anchorX: width / 2,
56245
+ anchorY: ascent
56169
56246
  };
56170
56247
  x2 += width + buffer * 2;
56248
+ yMax = Math.max(yMax, yMin + height + buffer * 2);
56171
56249
  }
56172
56250
  }
56173
56251
  return {
56174
56252
  mapping,
56175
56253
  xOffset: x2,
56176
- yOffset: yOffset + row * rowHeight,
56177
- canvasHeight: nextPowOfTwo2(yOffset + (row + 1) * rowHeight)
56254
+ yOffsetMin: yMin,
56255
+ yOffsetMax: yMax,
56256
+ canvasHeight: nextPowOfTwo2(yMax)
56178
56257
  };
56179
56258
  }
56180
56259
  function getTextWidth(text, startIndex, endIndex, mapping) {
56181
56260
  let width = 0;
56182
56261
  for (let i4 = startIndex; i4 < endIndex; i4++) {
56183
56262
  const character = text[i4];
56184
- width += mapping[character]?.layoutWidth || 0;
56263
+ width += mapping[character]?.advance || 0;
56185
56264
  }
56186
56265
  return width;
56187
56266
  }
@@ -56257,11 +56336,15 @@ void main(void) {
56257
56336
  const character = line[i4];
56258
56337
  const frame = iconMapping[character];
56259
56338
  if (frame) {
56260
- if (!rowHeight) {
56261
- rowHeight = frame.layoutHeight;
56262
- }
56263
- leftOffsets[i4] = x2 + frame.layoutWidth / 2;
56264
- x2 += frame.layoutWidth;
56339
+ rowHeight = Math.max(rowHeight, frame.height);
56340
+ }
56341
+ }
56342
+ for (let i4 = startIndex; i4 < endIndex; i4++) {
56343
+ const character = line[i4];
56344
+ const frame = iconMapping[character];
56345
+ if (frame) {
56346
+ leftOffsets[i4] = x2 + frame.anchorX;
56347
+ x2 += frame.advance;
56265
56348
  } else {
56266
56349
  log_default.warn(`Missing character: ${character} (${character.codePointAt(0)})`)();
56267
56350
  leftOffsets[i4] = x2;
@@ -56271,7 +56354,7 @@ void main(void) {
56271
56354
  rowSize[0] = x2;
56272
56355
  rowSize[1] = rowHeight;
56273
56356
  }
56274
- function transformParagraph(paragraph, lineHeight, wordBreak, maxWidth, iconMapping) {
56357
+ function transformParagraph(paragraph, baselineOffset, lineHeight, wordBreak, maxWidth, iconMapping) {
56275
56358
  const characters = Array.from(paragraph);
56276
56359
  const numCharacters = characters.length;
56277
56360
  const x2 = new Array(numCharacters);
@@ -56280,7 +56363,8 @@ void main(void) {
56280
56363
  const autoWrappingEnabled = (wordBreak === "break-word" || wordBreak === "break-all") && isFinite(maxWidth) && maxWidth > 0;
56281
56364
  const size2 = [0, 0];
56282
56365
  const rowSize = [0, 0];
56283
- let rowOffsetTop = 0;
56366
+ let rowCount = 0;
56367
+ let rowOffsetTop = baselineOffset + lineHeight / 2;
56284
56368
  let lineStartIndex = 0;
56285
56369
  let lineEndIndex = 0;
56286
56370
  for (let i4 = 0; i4 <= numCharacters; i4++) {
@@ -56295,12 +56379,11 @@ void main(void) {
56295
56379
  const rowEnd = rowIndex < rows.length ? rows[rowIndex] : lineEndIndex;
56296
56380
  transformRow(characters, rowStart, rowEnd, iconMapping, x2, rowSize);
56297
56381
  for (let j3 = rowStart; j3 < rowEnd; j3++) {
56298
- const char2 = characters[j3];
56299
- const layoutOffsetY = iconMapping[char2]?.layoutOffsetY || 0;
56300
- y3[j3] = rowOffsetTop + rowSize[1] / 2 + layoutOffsetY;
56382
+ y3[j3] = rowOffsetTop;
56301
56383
  rowWidth[j3] = rowSize[0];
56302
56384
  }
56303
- rowOffsetTop = rowOffsetTop + rowSize[1] * lineHeight;
56385
+ rowCount++;
56386
+ rowOffsetTop += lineHeight;
56304
56387
  size2[0] = Math.max(size2[0], rowSize[0]);
56305
56388
  }
56306
56389
  lineStartIndex = lineEndIndex;
@@ -56312,7 +56395,7 @@ void main(void) {
56312
56395
  lineStartIndex++;
56313
56396
  }
56314
56397
  }
56315
- size2[1] = rowOffsetTop;
56398
+ size2[1] = rowCount * lineHeight;
56316
56399
  return { x: x2, y: y3, rowWidth, size: size2 };
56317
56400
  }
56318
56401
  function getTextFromBuffer({
@@ -56421,8 +56504,8 @@ void main(void) {
56421
56504
  smoothing: 0.1
56422
56505
  };
56423
56506
  var MAX_CANVAS_WIDTH = 1024;
56424
- var BASELINE_SCALE = 0.9;
56425
- var HEIGHT_SCALE = 1.2;
56507
+ var DEFAULT_ASCENT = 0.9;
56508
+ var DEFAULT_DESCENT = 0.3;
56426
56509
  var CACHE_LIMIT = 3;
56427
56510
  var cache = new LRUCache(CACHE_LIMIT);
56428
56511
  function getNewChars(cacheKey, characterSet) {
@@ -56454,6 +56537,40 @@ void main(void) {
56454
56537
  ctx.textBaseline = "alphabetic";
56455
56538
  ctx.textAlign = "left";
56456
56539
  }
56540
+ function measureText(ctx, fontSize, char) {
56541
+ if (char === void 0) {
56542
+ const fontMetrics = ctx.measureText("A");
56543
+ if (fontMetrics.fontBoundingBoxAscent) {
56544
+ return {
56545
+ advance: 0,
56546
+ width: 0,
56547
+ ascent: Math.ceil(fontMetrics.fontBoundingBoxAscent),
56548
+ descent: Math.ceil(fontMetrics.fontBoundingBoxDescent)
56549
+ };
56550
+ }
56551
+ return {
56552
+ advance: 0,
56553
+ width: 0,
56554
+ ascent: fontSize * DEFAULT_ASCENT,
56555
+ descent: fontSize * DEFAULT_DESCENT
56556
+ };
56557
+ }
56558
+ const metrics = ctx.measureText(char);
56559
+ if (!metrics.actualBoundingBoxAscent) {
56560
+ return {
56561
+ advance: metrics.width,
56562
+ width: metrics.width,
56563
+ ascent: fontSize * DEFAULT_ASCENT,
56564
+ descent: fontSize * DEFAULT_DESCENT
56565
+ };
56566
+ }
56567
+ return {
56568
+ advance: metrics.width,
56569
+ width: Math.ceil(metrics.actualBoundingBoxRight - metrics.actualBoundingBoxLeft),
56570
+ ascent: Math.ceil(metrics.actualBoundingBoxAscent),
56571
+ descent: Math.ceil(metrics.actualBoundingBoxDescent)
56572
+ };
56573
+ }
56457
56574
  function setFontAtlasCacheLimit(limit) {
56458
56575
  log_default.assert(Number.isFinite(limit) && limit >= CACHE_LIMIT, "Invalid cache limit");
56459
56576
  cache = new LRUCache(limit);
@@ -56473,12 +56590,11 @@ void main(void) {
56473
56590
  get mapping() {
56474
56591
  return this._atlas && this._atlas.mapping;
56475
56592
  }
56476
- get scale() {
56477
- const { fontSize, buffer } = this.props;
56478
- return (fontSize * HEIGHT_SCALE + buffer * 2) / fontSize;
56479
- }
56480
56593
  setProps(props = {}) {
56481
56594
  Object.assign(this.props, props);
56595
+ if (props._getFontRenderer) {
56596
+ this._getFontRenderer = props._getFontRenderer;
56597
+ }
56482
56598
  this._key = this._getKey();
56483
56599
  const charSet = getNewChars(this._key, this.props.characterSet);
56484
56600
  const cachedFontAtlas = cache.get(this._key);
@@ -56502,49 +56618,62 @@ void main(void) {
56502
56618
  }
56503
56619
  const ctx = canvas.getContext("2d", { willReadFrequently: true });
56504
56620
  setTextStyle(ctx, fontFamily, fontSize, fontWeight);
56505
- const { mapping, canvasHeight, xOffset, yOffset } = buildMapping2({
56506
- getFontWidth: (char) => ctx.measureText(char).width,
56507
- fontHeight: fontSize * HEIGHT_SCALE,
56621
+ const defaultMeasure = (char) => measureText(ctx, fontSize, char);
56622
+ let renderer;
56623
+ if (this._getFontRenderer) {
56624
+ renderer = this._getFontRenderer(this.props);
56625
+ } else if (sdf) {
56626
+ renderer = {
56627
+ measure: defaultMeasure,
56628
+ draw: getSdfFontRenderer(this.props)
56629
+ };
56630
+ }
56631
+ const { mapping, canvasHeight, xOffset, yOffsetMin, yOffsetMax } = buildMapping2({
56632
+ measureText: (char) => renderer ? renderer.measure(char) : defaultMeasure(char),
56508
56633
  buffer,
56509
56634
  characterSet,
56510
56635
  maxCanvasWidth: MAX_CANVAS_WIDTH,
56511
56636
  ...cachedFontAtlas && {
56512
56637
  mapping: cachedFontAtlas.mapping,
56513
56638
  xOffset: cachedFontAtlas.xOffset,
56514
- yOffset: cachedFontAtlas.yOffset
56639
+ yOffsetMin: cachedFontAtlas.yOffsetMin,
56640
+ yOffsetMax: cachedFontAtlas.yOffsetMax
56515
56641
  }
56516
56642
  });
56517
56643
  if (canvas.height !== canvasHeight) {
56518
- const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
56644
+ const imageData = canvas.height > 0 ? ctx.getImageData(0, 0, canvas.width, canvas.height) : null;
56519
56645
  canvas.height = canvasHeight;
56520
- ctx.putImageData(imageData, 0, 0);
56646
+ if (imageData) {
56647
+ ctx.putImageData(imageData, 0, 0);
56648
+ }
56521
56649
  }
56522
56650
  setTextStyle(ctx, fontFamily, fontSize, fontWeight);
56523
- if (sdf) {
56524
- const tinySDF = new TinySDF({
56525
- fontSize,
56526
- buffer,
56527
- radius,
56528
- cutoff,
56529
- fontFamily,
56530
- fontWeight: `${fontWeight}`
56531
- });
56651
+ if (renderer) {
56532
56652
  for (const char of characterSet) {
56533
- const { data, width, height, glyphTop } = tinySDF.draw(char);
56534
- mapping[char].width = width;
56535
- mapping[char].layoutOffsetY = fontSize * BASELINE_SCALE - glyphTop;
56536
- const imageData = ctx.createImageData(width, height);
56537
- populateAlphaChannel(data, imageData);
56538
- ctx.putImageData(imageData, mapping[char].x, mapping[char].y);
56653
+ const frame = mapping[char];
56654
+ const { data, left = 0, top = 0 } = renderer.draw(char);
56655
+ const x2 = frame.x - left;
56656
+ const y3 = frame.y - top;
56657
+ const x0 = Math.max(0, Math.round(x2));
56658
+ const y0 = Math.max(0, Math.round(y3));
56659
+ const w4 = Math.min(data.width, canvas.width - x0);
56660
+ const h4 = Math.min(data.height, canvas.height - y0);
56661
+ ctx.putImageData(data, x0, y0, 0, 0, w4, h4);
56662
+ frame.x += x0 - x2;
56663
+ frame.y += y0 - y3;
56539
56664
  }
56540
56665
  } else {
56541
56666
  for (const char of characterSet) {
56542
- ctx.fillText(char, mapping[char].x, mapping[char].y + buffer + fontSize * BASELINE_SCALE);
56667
+ const frame = mapping[char];
56668
+ ctx.fillText(char, frame.x, frame.y + frame.anchorY);
56543
56669
  }
56544
56670
  }
56671
+ const fontMetrics = renderer ? renderer.measure() : defaultMeasure();
56545
56672
  return {
56673
+ baselineOffset: (fontMetrics.ascent - fontMetrics.descent) / 2,
56546
56674
  xOffset,
56547
- yOffset,
56675
+ yOffsetMin,
56676
+ yOffsetMax,
56548
56677
  mapping,
56549
56678
  data: canvas,
56550
56679
  width: canvas.width,
@@ -56559,6 +56688,29 @@ void main(void) {
56559
56688
  return `${fontFamily} ${fontWeight} ${fontSize} ${buffer}`;
56560
56689
  }
56561
56690
  };
56691
+ function getSdfFontRenderer({
56692
+ fontSize,
56693
+ buffer,
56694
+ radius,
56695
+ cutoff,
56696
+ fontFamily,
56697
+ fontWeight
56698
+ }) {
56699
+ const tinySDF = new TinySDF({
56700
+ fontSize,
56701
+ buffer,
56702
+ radius,
56703
+ cutoff,
56704
+ fontFamily,
56705
+ fontWeight: `${fontWeight}`
56706
+ });
56707
+ return (char) => {
56708
+ const { data, width, height } = tinySDF.draw(char);
56709
+ const imageData = new ImageData(width, height);
56710
+ populateAlphaChannel(data, imageData);
56711
+ return { data: imageData, left: buffer, top: buffer };
56712
+ };
56713
+ }
56562
56714
 
56563
56715
  // ../layers/src/text-layer/text-background-layer/text-background-layer-uniforms.ts
56564
56716
  var uniformBlock14 = `layout(std140) uniform textBackgroundUniforms {
@@ -56636,10 +56788,11 @@ void main(void) {
56636
56788
  project_size_to_pixel(instanceSizes * textBackground.sizeScale, textBackground.sizeUnits),
56637
56789
  textBackground.sizeMinPixels, textBackground.sizeMaxPixels
56638
56790
  );
56791
+ float instanceScale = sizePixels / text.fontSize;
56639
56792
 
56640
- dimensions = instanceRects.zw * sizePixels + textBackground.padding.xy + textBackground.padding.zw;
56793
+ dimensions = instanceRects.zw * instanceScale + textBackground.padding.xy + textBackground.padding.zw;
56641
56794
 
56642
- vec2 pixelOffset = (positions * instanceRects.zw + instanceRects.xy) * sizePixels + mix(-textBackground.padding.xy, textBackground.padding.zw, positions);
56795
+ vec2 pixelOffset = (positions * instanceRects.zw + instanceRects.xy) * instanceScale + mix(-textBackground.padding.xy, textBackground.padding.zw, positions);
56643
56796
  pixelOffset = rotate_by_angle(pixelOffset, instanceAngles);
56644
56797
  pixelOffset += instancePixelOffsets;
56645
56798
  pixelOffset.y *= -1.0;
@@ -56730,13 +56883,15 @@ void main(void) {
56730
56883
 
56731
56884
  if (textBackground.borderRadius != vec4(0.0)) {
56732
56885
  float distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
56886
+ float shapeAlpha = smoothedge(-distToEdge, 0.0);
56887
+ if (shapeAlpha == 0.0) {
56888
+ discard;
56889
+ }
56733
56890
  if (textBackground.stroked) {
56734
56891
  fragColor = get_stroked_fragColor(distToEdge);
56735
56892
  } else {
56736
56893
  fragColor = vFillColor;
56737
56894
  }
56738
- // add border radius
56739
- float shapeAlpha = smoothedge(-distToEdge, 0.0);
56740
56895
  fragColor.a *= shapeAlpha;
56741
56896
  } else {
56742
56897
  if (textBackground.stroked) {
@@ -56757,6 +56912,7 @@ void main(void) {
56757
56912
  sizeUnits: "pixels",
56758
56913
  sizeMinPixels: 0,
56759
56914
  sizeMaxPixels: Number.MAX_SAFE_INTEGER,
56915
+ fontSize: 1,
56760
56916
  borderRadius: { type: "object", value: 0 },
56761
56917
  padding: { type: "array", value: [0, 0, 0, 0] },
56762
56918
  getPosition: { type: "accessor", value: (x2) => x2.position },
@@ -56843,7 +56999,7 @@ void main(void) {
56843
56999
  }
56844
57000
  }
56845
57001
  draw({ uniforms }) {
56846
- const { billboard, sizeScale, sizeUnits, sizeMinPixels, sizeMaxPixels, getLineWidth } = this.props;
57002
+ const { billboard, sizeScale, sizeUnits, sizeMinPixels, sizeMaxPixels, getLineWidth, fontSize } = this.props;
56847
57003
  let { padding, borderRadius } = this.props;
56848
57004
  if (padding.length < 4) {
56849
57005
  padding = [padding[0], padding[1], padding[0], padding[1]];
@@ -56868,6 +57024,7 @@ void main(void) {
56868
57024
  sizeMaxPixels
56869
57025
  };
56870
57026
  const textProps = {
57027
+ fontSize,
56871
57028
  viewport: this.context.viewport
56872
57029
  };
56873
57030
  model.shaderInputs.setProps({ textBackground: textBackgroundProps, text: textProps });
@@ -56950,12 +57107,9 @@ void main(void) {
56950
57107
  * Used to render the background.
56951
57108
  */
56952
57109
  this.getBoundingRect = (object, objectInfo) => {
56953
- let {
57110
+ const {
56954
57111
  size: [width, height]
56955
57112
  } = this.transformParagraph(object, objectInfo);
56956
- const { fontSize } = this.state.fontAtlasManager.props;
56957
- width /= fontSize;
56958
- height /= fontSize;
56959
57113
  const { getTextAnchor, getAlignmentBaseline } = this.props;
56960
57114
  const anchorX = TEXT_ANCHOR[typeof getTextAnchor === "function" ? getTextAnchor(object, objectInfo) : getTextAnchor];
56961
57115
  const anchorY = ALIGNMENT_BASELINE[typeof getAlignmentBaseline === "function" ? getAlignmentBaseline(object, objectInfo) : getAlignmentBaseline];
@@ -56970,7 +57124,7 @@ void main(void) {
56970
57124
  x: x2,
56971
57125
  y: y3,
56972
57126
  rowWidth,
56973
- size: [width, height]
57127
+ size: [, height]
56974
57128
  } = this.transformParagraph(object, objectInfo);
56975
57129
  const anchorX = TEXT_ANCHOR[typeof getTextAnchor === "function" ? getTextAnchor(object, objectInfo) : getTextAnchor];
56976
57130
  const anchorY = ALIGNMENT_BASELINE[typeof getAlignmentBaseline === "function" ? getAlignmentBaseline(object, objectInfo) : getAlignmentBaseline];
@@ -56978,8 +57132,7 @@ void main(void) {
56978
57132
  const offsets = new Array(numCharacters * 2);
56979
57133
  let index = 0;
56980
57134
  for (let i4 = 0; i4 < numCharacters; i4++) {
56981
- const rowOffset = (1 - anchorX) * (width - rowWidth[i4]) / 2;
56982
- offsets[index++] = (anchorX - 1) * width / 2 + rowOffset + x2[i4];
57135
+ offsets[index++] = (anchorX - 1) * rowWidth[i4] / 2 + x2[i4];
56983
57136
  offsets[index++] = (anchorY - 1) * height / 2 + y3[i4];
56984
57137
  }
56985
57138
  return offsets;
@@ -57015,13 +57168,14 @@ void main(void) {
57015
57168
  }
57016
57169
  /** Returns true if font has changed */
57017
57170
  _updateFontAtlas() {
57018
- const { fontSettings, fontFamily, fontWeight } = this.props;
57171
+ const { fontSettings, fontFamily, fontWeight, _getFontRenderer } = this.props;
57019
57172
  const { fontAtlasManager, characterSet } = this.state;
57020
57173
  const fontProps = {
57021
57174
  ...fontSettings,
57022
57175
  characterSet,
57023
57176
  fontFamily,
57024
- fontWeight
57177
+ fontWeight,
57178
+ _getFontRenderer
57025
57179
  };
57026
57180
  if (!fontAtlasManager.mapping) {
57027
57181
  fontAtlasManager.setProps(fontProps);
@@ -57091,14 +57245,17 @@ void main(void) {
57091
57245
  transformParagraph(object, objectInfo) {
57092
57246
  const { fontAtlasManager } = this.state;
57093
57247
  const iconMapping = fontAtlasManager.mapping;
57248
+ const { baselineOffset } = fontAtlasManager.atlas;
57249
+ const { fontSize } = fontAtlasManager.props;
57094
57250
  const getText = this.state.getText;
57095
57251
  const { wordBreak, lineHeight, maxWidth } = this.props;
57096
57252
  const paragraph = getText(object, objectInfo) || "";
57097
57253
  return transformParagraph(
57098
57254
  paragraph,
57099
- lineHeight,
57255
+ baselineOffset,
57256
+ lineHeight * fontSize,
57100
57257
  wordBreak,
57101
- maxWidth * fontAtlasManager.props.fontSize,
57258
+ maxWidth * fontSize,
57102
57259
  iconMapping
57103
57260
  );
57104
57261
  }
@@ -57107,7 +57264,7 @@ void main(void) {
57107
57264
  startIndices,
57108
57265
  numInstances,
57109
57266
  getText,
57110
- fontAtlasManager: { scale: scale8, atlas, mapping },
57267
+ fontAtlasManager: { atlas, mapping },
57111
57268
  styleVersion
57112
57269
  } = this.state;
57113
57270
  const {
@@ -57141,6 +57298,7 @@ void main(void) {
57141
57298
  } = this.props;
57142
57299
  const CharactersLayerClass = this.getSubLayerClass("characters", MultiIconLayer);
57143
57300
  const BackgroundLayerClass = this.getSubLayerClass("background", TextBackgroundLayer);
57301
+ const { fontSize } = this.state.fontAtlasManager.props;
57144
57302
  return [
57145
57303
  background && new BackgroundLayerClass(
57146
57304
  {
@@ -57161,6 +57319,7 @@ void main(void) {
57161
57319
  sizeUnits,
57162
57320
  sizeMinPixels,
57163
57321
  sizeMaxPixels,
57322
+ fontSize,
57164
57323
  transitions: transitions && {
57165
57324
  getPosition: transitions.getPosition,
57166
57325
  getAngle: transitions.getAngle,
@@ -57218,10 +57377,11 @@ void main(void) {
57218
57377
  getPixelOffset,
57219
57378
  getContentBox,
57220
57379
  billboard,
57221
- sizeScale: sizeScale * scale8,
57380
+ sizeScale,
57222
57381
  sizeUnits,
57223
- sizeMinPixels: sizeMinPixels * scale8,
57224
- sizeMaxPixels: sizeMaxPixels * scale8,
57382
+ sizeMinPixels,
57383
+ sizeMaxPixels,
57384
+ fontSize,
57225
57385
  contentCutoffPixels,
57226
57386
  contentAlignHorizontal,
57227
57387
  contentAlignVertical,
@@ -59371,6 +59531,8 @@ void main(void) {
59371
59531
  var distanceToVertex = 3 - Math.sqrt(5);
59372
59532
  var Rmidedge = Math.sqrt(3 - \u03C6);
59373
59533
  var Rcircumscribed = Math.sqrt(3) * Rmidedge / \u03C6;
59534
+ var AUTHALIC_RADIUS_EARTH = 63710072e-1;
59535
+ var AUTHALIC_AREA_EARTH = 4 * Math.PI * AUTHALIC_RADIUS_EARTH * AUTHALIC_RADIUS_EARTH;
59374
59536
  common_exports2.setMatrixArrayType(Float64Array);
59375
59537
  var PentagonShape = class _PentagonShape {
59376
59538
  constructor(vertices) {
@@ -60072,12 +60234,13 @@ void main(void) {
60072
60234
  }
60073
60235
  }
60074
60236
  };
60075
- common_exports2.setMatrixArrayType(Float64Array);
60076
60237
  var YES = -1;
60077
60238
  var NO = 1;
60239
+ common_exports2.setMatrixArrayType(Float64Array);
60078
60240
  var KJToIJ = ([k3, j3]) => {
60079
60241
  return vec2_exports2.fromValues(k3 - j3, j3);
60080
60242
  };
60243
+ common_exports2.setMatrixArrayType(Float64Array);
60081
60244
  var kPos = vec2_exports2.fromValues(1, 0);
60082
60245
  var jPos = vec2_exports2.fromValues(0, 1);
60083
60246
  var kNeg = vec2_exports2.negate(vec2_exports2.create(), kPos);
@@ -60115,7 +60278,6 @@ void main(void) {
60115
60278
  var quaternaryToFlips = (n2) => {
60116
60279
  return [[NO, NO], [NO, YES], [NO, NO], [YES, NO]][n2];
60117
60280
  };
60118
- var FLIP_SHIFT = vec2_exports2.fromValues(-1, 1);
60119
60281
  function reversePattern(pattern) {
60120
60282
  return Array.from({ length: pattern.length }, (_3, i4) => pattern.indexOf(i4));
60121
60283
  }
@@ -60123,7 +60285,7 @@ void main(void) {
60123
60285
  var PATTERN_FLIPPED = [0, 1, 2, 7, 3, 4, 5, 6];
60124
60286
  var PATTERN_REVERSED = reversePattern(PATTERN);
60125
60287
  var PATTERN_FLIPPED_REVERSED = reversePattern(PATTERN_FLIPPED);
60126
- var _shiftDigits = (digits, i4, flips, invertJ, pattern) => {
60288
+ var shiftDigits = (digits, i4, flips, invertJ, pattern) => {
60127
60289
  if (i4 <= 0)
60128
60290
  return;
60129
60291
  const parentK = digits[i4] || 0;
@@ -60145,7 +60307,10 @@ void main(void) {
60145
60307
  digits[i4 - 1] = dst % 4;
60146
60308
  digits[i4] = (parentK + 4 + Math.floor(dst / 4) - Math.floor(src / 4)) % 4;
60147
60309
  };
60148
- var sToAnchor = (s3, resolution, orientation) => {
60310
+ common_exports2.setMatrixArrayType(Float64Array);
60311
+ var FLIP_SHIFT = vec2_exports2.fromValues(-1, 1);
60312
+ var SHIFTDIGITS = true;
60313
+ var sToAnchor = (s3, resolution, orientation, doShiftDigits = SHIFTDIGITS) => {
60149
60314
  let input = BigInt(s3);
60150
60315
  const reverse = orientation === "vu" || orientation === "wu" || orientation === "vw";
60151
60316
  const invertJ = orientation === "wv" || orientation === "vw";
@@ -60153,7 +60318,7 @@ void main(void) {
60153
60318
  if (reverse) {
60154
60319
  input = (1n << BigInt(2 * resolution)) - input - 1n;
60155
60320
  }
60156
- const anchor = _sToAnchor(input, resolution, invertJ, flipIJ);
60321
+ const anchor = _sToAnchor(input, resolution, invertJ, flipIJ, doShiftDigits);
60157
60322
  if (flipIJ) {
60158
60323
  const { offset: [_i, _j], flips: [flipX, flipY] } = anchor;
60159
60324
  anchor.offset = [_j, _i];
@@ -60171,7 +60336,7 @@ void main(void) {
60171
60336
  }
60172
60337
  return anchor;
60173
60338
  };
60174
- var _sToAnchor = (s3, resolution, invertJ, flipIJ) => {
60339
+ var _sToAnchor = (s3, resolution, invertJ, flipIJ, doShiftDigits = SHIFTDIGITS) => {
60175
60340
  const offset3 = vec2_exports2.create();
60176
60341
  const flips = [NO, NO];
60177
60342
  let input = BigInt(s3);
@@ -60182,7 +60347,9 @@ void main(void) {
60182
60347
  }
60183
60348
  const pattern = flipIJ ? PATTERN_FLIPPED : PATTERN;
60184
60349
  for (let i4 = digits.length - 1; i4 >= 0; i4--) {
60185
- _shiftDigits(digits, i4, flips, invertJ, pattern);
60350
+ if (doShiftDigits) {
60351
+ shiftDigits(digits, i4, flips, invertJ, pattern);
60352
+ }
60186
60353
  vec2_exports2.multiply(flips, flips, quaternaryToFlips(digits[i4]));
60187
60354
  }
60188
60355
  flips[0] = NO;
@@ -60193,9 +60360,16 @@ void main(void) {
60193
60360
  vec2_exports2.add(offset3, offset3, childOffset);
60194
60361
  vec2_exports2.multiply(flips, flips, quaternaryToFlips(digits[i4]));
60195
60362
  }
60196
- const k3 = digits[0] || 0;
60197
- return { flips, k: k3, offset: KJToIJ(offset3) };
60363
+ const q3 = digits[0] || 0;
60364
+ return { q: q3, offset: KJToIJ(offset3), flips };
60198
60365
  };
60366
+ var PROBE_R = 0.1;
60367
+ var PROBE_OFFSETS = [
60368
+ [PROBE_R * Math.cos(45 * Math.PI / 180), PROBE_R * Math.sin(45 * Math.PI / 180)],
60369
+ [PROBE_R * Math.cos(113 * Math.PI / 180), PROBE_R * Math.sin(113 * Math.PI / 180)],
60370
+ [PROBE_R * Math.cos(293 * Math.PI / 180), PROBE_R * Math.sin(293 * Math.PI / 180)],
60371
+ [PROBE_R * Math.cos(225 * Math.PI / 180), PROBE_R * Math.sin(225 * Math.PI / 180)]
60372
+ ];
60199
60373
  common_exports2.setMatrixArrayType(Float64Array);
60200
60374
  var TRIANGLE_MODE = false;
60201
60375
  var shiftRight = vec2_exports2.clone(w);
@@ -60212,12 +60386,12 @@ void main(void) {
60212
60386
  if (anchor.flips[0] === NO && anchor.flips[1] === YES) {
60213
60387
  pentagon.rotate180();
60214
60388
  }
60215
- const { k: k3 } = anchor;
60389
+ const { q: q3 } = anchor;
60216
60390
  const F22 = anchor.flips[0] + anchor.flips[1];
60217
60391
  if (
60218
60392
  // Orient last two pentagons when both or neither flips are YES
60219
- (F22 === -2 || F22 === 2) && k3 > 1 || // Orient first & last pentagons when only one of flips is YES
60220
- F22 === 0 && (k3 === 0 || k3 === 3)
60393
+ (F22 === -2 || F22 === 2) && q3 > 1 || // Orient first & last pentagons when only one of flips is YES
60394
+ F22 === 0 && (q3 === 0 || q3 === 3)
60221
60395
  ) {
60222
60396
  pentagon.reflectY();
60223
60397
  }
@@ -60451,13 +60625,40 @@ void main(void) {
60451
60625
  var FIRST_HILBERT_RESOLUTION = 2;
60452
60626
  var MAX_RESOLUTION = 30;
60453
60627
  var HILBERT_START_BIT = 58n;
60454
- var REMOVAL_MASK = 0x3ffffffffffffffn;
60628
+ var WORLD_CELL = 0n;
60455
60629
  function getResolution(index) {
60630
+ if (index === 0n)
60631
+ return -1;
60632
+ if (index & 1n || (index & 0b111n) === 0b100n || (index & 0b11111n) === 0b10000n)
60633
+ return MAX_RESOLUTION;
60456
60634
  let resolution = MAX_RESOLUTION - 1;
60457
60635
  let shifted = index >> 1n;
60458
- while (resolution > -1 && (shifted & 0b1n) === 0n) {
60636
+ if (shifted === 0n)
60637
+ return -1;
60638
+ let low32 = Number(shifted & 0xFFFFFFFFn);
60639
+ let remaining;
60640
+ if (low32 === 0) {
60641
+ shifted >>= 32n;
60642
+ resolution -= 16;
60643
+ remaining = Number(shifted);
60644
+ } else {
60645
+ remaining = low32;
60646
+ }
60647
+ if ((remaining & 65535) === 0) {
60648
+ remaining >>= 16;
60649
+ resolution -= 8;
60650
+ }
60651
+ if (resolution >= 6 && (remaining & 255) === 0) {
60652
+ remaining >>= 8;
60653
+ resolution -= 4;
60654
+ }
60655
+ if (resolution >= 4 && (remaining & 15) === 0) {
60656
+ remaining >>= 4;
60657
+ resolution -= 2;
60658
+ }
60659
+ while (resolution > -1 && (remaining & 1) === 0) {
60459
60660
  resolution -= 1;
60460
- shifted = shifted >> (resolution < FIRST_HILBERT_RESOLUTION ? 1n : 2n);
60661
+ remaining = remaining >> (resolution < FIRST_HILBERT_RESOLUTION ? 1 : 2);
60461
60662
  }
60462
60663
  return resolution;
60463
60664
  }
@@ -60466,27 +60667,33 @@ void main(void) {
60466
60667
  if (resolution === -1) {
60467
60668
  return { origin: origins[0], segment: 0, S: 0n, resolution };
60468
60669
  }
60469
- const top6Bits = Number(index >> 58n);
60670
+ let quintantShift = HILBERT_START_BIT;
60671
+ let quintantOffset = 0;
60672
+ if (resolution === MAX_RESOLUTION) {
60673
+ const markerBits = index & 1n ? 1n : index & 0b100n ? 3n : 5n;
60674
+ quintantShift = HILBERT_START_BIT + markerBits;
60675
+ quintantOffset = markerBits === 1n ? 0 : markerBits === 3n ? 32 : 40;
60676
+ }
60677
+ const topBits = Number(index >> quintantShift) + quintantOffset;
60470
60678
  let origin, segment;
60471
60679
  if (resolution === 0) {
60472
- const originId2 = top6Bits;
60473
- origin = origins[originId2];
60680
+ origin = origins[topBits];
60474
60681
  segment = 0;
60475
60682
  } else {
60476
- const originId2 = Math.floor(top6Bits / 5);
60683
+ const originId2 = Math.floor(topBits / 5);
60477
60684
  origin = origins[originId2];
60478
- segment = (top6Bits + origin.firstQuintant) % 5;
60685
+ segment = (topBits + origin.firstQuintant) % 5;
60479
60686
  }
60480
60687
  if (!origin) {
60481
- throw new Error(`Could not parse origin: ${top6Bits}`);
60688
+ throw new Error(`Could not parse origin: ${topBits}`);
60482
60689
  }
60483
60690
  if (resolution < FIRST_HILBERT_RESOLUTION) {
60484
60691
  return { origin, segment, S: 0n, resolution };
60485
60692
  }
60486
60693
  const hilbertLevels = resolution - FIRST_HILBERT_RESOLUTION + 1;
60487
60694
  const hilbertBits = BigInt(2 * hilbertLevels);
60488
- const shift3 = HILBERT_START_BIT - hilbertBits;
60489
- const S2 = (index & REMOVAL_MASK) >> shift3;
60695
+ const removalMask = (1n << quintantShift) - 1n;
60696
+ const S2 = (index & removalMask) >> quintantShift - hilbertBits;
60490
60697
  return { origin, segment, S: S2, resolution };
60491
60698
  }
60492
60699
  common_exports2.setMatrixArrayType(Float64Array);
@@ -60505,6 +60712,9 @@ void main(void) {
60505
60712
  return getPentagonVertices(hilbertResolution, quintant, anchor);
60506
60713
  }
60507
60714
  function cellToBoundary(cellId, { closedRing = true, segments = "auto" } = { closedRing: true, segments: "auto" }) {
60715
+ if (cellId === WORLD_CELL) {
60716
+ return [];
60717
+ }
60508
60718
  const { S: S2, segment, origin, resolution } = deserialize(cellId);
60509
60719
  if (segments === "auto") {
60510
60720
  segments = Math.max(1, Math.pow(2, 6 - resolution));
@@ -60524,8 +60734,13 @@ void main(void) {
60524
60734
  function hexToU64(hex) {
60525
60735
  return BigInt(`0x${hex}`);
60526
60736
  }
60527
- var AUTHALIC_RADIUS = 63710072e-1;
60528
- var AUTHALIC_AREA = 4 * Math.PI * AUTHALIC_RADIUS * AUTHALIC_RADIUS;
60737
+ var CELL_RADIUS_SAFETY_FACTOR = 2;
60738
+ var BASE_CELL_RADIUS = CELL_RADIUS_SAFETY_FACTOR * AUTHALIC_RADIUS_EARTH / Math.sqrt(15);
60739
+ var _cellRadius = new Array(31);
60740
+ _cellRadius[0] = CELL_RADIUS_SAFETY_FACTOR * AUTHALIC_RADIUS_EARTH / Math.sqrt(3);
60741
+ for (let r3 = 1; r3 <= 30; r3++) {
60742
+ _cellRadius[r3] = BASE_CELL_RADIUS / (1 << r3 - 1);
60743
+ }
60529
60744
  common_exports2.setMatrixArrayType(Float64Array);
60530
60745
 
60531
60746
  // ../geo-layers/src/h3-layers/h3-utils.ts
@@ -64612,7 +64827,7 @@ void main(void) {
64612
64827
  visibleMinZoom,
64613
64828
  visibleMaxZoom
64614
64829
  }) {
64615
- let z3 = viewport.isGeospatial ? Math.round(viewport.zoom + Math.log2(TILE_SIZE4 / tileSize)) + zoomOffset : Math.ceil(viewport.zoom) + zoomOffset;
64830
+ let z3 = viewport.isGeospatial ? Math.round(viewport.zoom + Math.log2(TILE_SIZE4 / tileSize) + zoomOffset) : Math.ceil(viewport.zoom + zoomOffset);
64616
64831
  if (typeof minZoom === "number" && Number.isFinite(minZoom) && z3 < minZoom) {
64617
64832
  if (!extent) {
64618
64833
  return [];
@@ -65787,7 +66002,7 @@ out float vTime;
65787
66002
  }
65788
66003
  };
65789
66004
  function shouldComposeModelMatrix(viewport, coordinateSystem) {
65790
- return coordinateSystem === COORDINATE_SYSTEM.CARTESIAN || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.DEFAULT && !viewport.isGeospatial;
66005
+ return coordinateSystem === "cartesian" || coordinateSystem === "meter-offsets" || coordinateSystem === "default" && !viewport.isGeospatial;
65791
66006
  }
65792
66007
 
65793
66008
  // ../mesh-layers/src/simple-mesh-layer/simple-mesh-layer-uniforms.ts
@@ -82201,7 +82416,7 @@ vec4 project_position_to_clipspace(
82201
82416
  var Fp64Extension = class extends LayerExtension {
82202
82417
  getShaders() {
82203
82418
  const { coordinateSystem } = this.props;
82204
- if (coordinateSystem !== COORDINATE_SYSTEM.LNGLAT && coordinateSystem !== COORDINATE_SYSTEM.DEFAULT) {
82419
+ if (coordinateSystem !== "lnglat" && coordinateSystem !== "default") {
82205
82420
  throw new Error("fp64: coordinateSystem must be LNGLAT");
82206
82421
  }
82207
82422
  return {
@@ -82287,6 +82502,209 @@ in float vDashOffset;
82287
82502
  }
82288
82503
  }
82289
82504
  }
82505
+ `
82506
+ }
82507
+ };
82508
+ var scatterplotDashShaders = {
82509
+ inject: {
82510
+ "vs:#decl": `
82511
+ in vec2 instanceDashArrays;
82512
+ out vec2 vDashArray;
82513
+ `,
82514
+ "vs:#main-end": `
82515
+ vDashArray = instanceDashArrays;
82516
+ `,
82517
+ "fs:#decl": `
82518
+ layout(std140) uniform pathStyleUniforms {
82519
+ bool dashGapPickable;
82520
+ } pathStyle;
82521
+
82522
+ in vec2 vDashArray;
82523
+
82524
+ #define PI 3.141592653589793
82525
+ `,
82526
+ "fs:#main-start": `
82527
+ bool inDashGap = false;
82528
+ float dashUnitLength = vDashArray.x + vDashArray.y;
82529
+ if (dashUnitLength > 0.0 && scatterplot.stroked > 0.5) {
82530
+ float _distToCenter = length(unitPosition) * outerRadiusPixels;
82531
+ float innerRadius = innerUnitRadius * outerRadiusPixels;
82532
+ if (_distToCenter >= innerRadius) {
82533
+ float strokeWidth = (1.0 - innerUnitRadius) * outerRadiusPixels;
82534
+ float midStrokeRadius = (innerUnitRadius + 1.0) * 0.5 * outerRadiusPixels;
82535
+ float angle = atan(unitPosition.y, unitPosition.x) + PI;
82536
+ float circumference = 2.0 * PI * midStrokeRadius;
82537
+ float posAlongStroke = (angle / (2.0 * PI)) * circumference / strokeWidth;
82538
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
82539
+ if (unitOffset > vDashArray.x) {
82540
+ if (scatterplot.filled > 0.5) {
82541
+ inDashGap = true;
82542
+ } else {
82543
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
82544
+ discard;
82545
+ }
82546
+ }
82547
+ }
82548
+ }
82549
+ }
82550
+ `,
82551
+ "fs:#main-end": `
82552
+ if (inDashGap) {
82553
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
82554
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
82555
+ fragColor = picking_filterPickingColor(fragColor);
82556
+ fragColor = picking_filterHighlightColor(fragColor);
82557
+ }
82558
+ `
82559
+ }
82560
+ };
82561
+ var textBackgroundDashShaders = {
82562
+ inject: {
82563
+ "vs:#decl": `
82564
+ in vec2 instanceDashArrays;
82565
+ out vec2 vDashArray;
82566
+ `,
82567
+ "vs:#main-end": `
82568
+ vDashArray = instanceDashArrays;
82569
+ `,
82570
+ "fs:#decl": `
82571
+ layout(std140) uniform pathStyleUniforms {
82572
+ bool dashGapPickable;
82573
+ } pathStyle;
82574
+
82575
+ in vec2 vDashArray;
82576
+
82577
+ #define PI 3.141592653589793
82578
+
82579
+ // Calculate position along rounded rectangle perimeter in stroke-width units
82580
+ float getPerimeterPosition(vec2 fragUV, vec2 dims, vec4 radii, float lineWidth) {
82581
+ float width = dims.x;
82582
+ float height = dims.y;
82583
+
82584
+ float maxRadius = min(width, height) * 0.5;
82585
+ float rBL = min(radii.w, maxRadius);
82586
+ float rTL = min(radii.z, maxRadius);
82587
+ float rTR = min(radii.x, maxRadius);
82588
+ float rBR = min(radii.y, maxRadius);
82589
+
82590
+ vec2 p = fragUV * dims;
82591
+
82592
+ float leftLen = height - rBL - rTL;
82593
+ float topLen = width - rTL - rTR;
82594
+ float rightLen = height - rTR - rBR;
82595
+ float bottomLen = width - rBR - rBL;
82596
+
82597
+ float arcBL = PI * 0.5 * rBL;
82598
+ float arcTL = PI * 0.5 * rTL;
82599
+ float arcTR = PI * 0.5 * rTR;
82600
+ float arcBR = PI * 0.5 * rBR;
82601
+
82602
+ float pos = 0.0;
82603
+
82604
+ float distLeft = p.x;
82605
+ float distRight = width - p.x;
82606
+ float distBottom = p.y;
82607
+ float distTop = height - p.y;
82608
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
82609
+
82610
+ if (p.x < rBL && p.y < rBL) {
82611
+ vec2 c = vec2(rBL, rBL);
82612
+ vec2 d = p - c;
82613
+ float angle = atan(-d.x, -d.y);
82614
+ pos = angle / (PI * 0.5) * arcBL;
82615
+ } else if (p.x < rTL && p.y > height - rTL) {
82616
+ vec2 c = vec2(rTL, height - rTL);
82617
+ vec2 d = p - c;
82618
+ float angle = atan(d.y, -d.x);
82619
+ pos = arcBL + leftLen + angle / (PI * 0.5) * arcTL;
82620
+ } else if (p.x > width - rTR && p.y > height - rTR) {
82621
+ vec2 c = vec2(width - rTR, height - rTR);
82622
+ vec2 d = p - c;
82623
+ float angle = atan(d.x, d.y);
82624
+ pos = arcBL + leftLen + arcTL + topLen + angle / (PI * 0.5) * arcTR;
82625
+ } else if (p.x > width - rBR && p.y < rBR) {
82626
+ vec2 c = vec2(width - rBR, rBR);
82627
+ vec2 d = p - c;
82628
+ float angle = atan(-d.y, d.x);
82629
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + angle / (PI * 0.5) * arcBR;
82630
+ } else if (minDist == distLeft) {
82631
+ pos = arcBL + clamp(p.y - rBL, 0.0, leftLen);
82632
+ } else if (minDist == distTop) {
82633
+ pos = arcBL + leftLen + arcTL + clamp(p.x - rTL, 0.0, topLen);
82634
+ } else if (minDist == distRight) {
82635
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + clamp(height - rTR - p.y, 0.0, rightLen);
82636
+ } else {
82637
+ pos = arcBL + leftLen + arcTL + topLen + arcTR + rightLen + arcBR + clamp(width - rBR - p.x, 0.0, bottomLen);
82638
+ }
82639
+
82640
+ return pos / lineWidth;
82641
+ }
82642
+
82643
+ // Simple rectangular perimeter calculation (no rounded corners)
82644
+ float getRectPerimeterPosition(vec2 fragUV, vec2 dims, float lineWidth) {
82645
+ float width = dims.x;
82646
+ float height = dims.y;
82647
+
82648
+ float distLeft = fragUV.x * width;
82649
+ float distRight = (1.0 - fragUV.x) * width;
82650
+ float distBottom = fragUV.y * height;
82651
+ float distTop = (1.0 - fragUV.y) * height;
82652
+
82653
+ float minDist = min(min(distLeft, distRight), min(distBottom, distTop));
82654
+
82655
+ float pos = 0.0;
82656
+ if (minDist == distLeft) {
82657
+ pos = fragUV.y * height;
82658
+ } else if (minDist == distTop) {
82659
+ pos = height + fragUV.x * width;
82660
+ } else if (minDist == distRight) {
82661
+ pos = height + width + (1.0 - fragUV.y) * height;
82662
+ } else {
82663
+ pos = 2.0 * height + width + (1.0 - fragUV.x) * width;
82664
+ }
82665
+
82666
+ return pos / lineWidth;
82667
+ }
82668
+ `,
82669
+ "fs:#main-start": `
82670
+ bool inDashGap = false;
82671
+ float dashUnitLength = vDashArray.x + vDashArray.y;
82672
+ if (dashUnitLength > 0.0 && textBackground.stroked) {
82673
+ float distToEdge;
82674
+ bool hasRoundedCorners = textBackground.borderRadius != vec4(0.0);
82675
+ if (hasRoundedCorners) {
82676
+ distToEdge = round_rect(uv, dimensions, textBackground.borderRadius);
82677
+ } else {
82678
+ distToEdge = rect(uv, dimensions);
82679
+ }
82680
+
82681
+ if (distToEdge <= vLineWidth && distToEdge >= 0.0) {
82682
+ float posAlongStroke;
82683
+ if (hasRoundedCorners) {
82684
+ posAlongStroke = getPerimeterPosition(uv, dimensions, textBackground.borderRadius, vLineWidth);
82685
+ } else {
82686
+ posAlongStroke = getRectPerimeterPosition(uv, dimensions, vLineWidth);
82687
+ }
82688
+ float unitOffset = mod(posAlongStroke, dashUnitLength);
82689
+ if (unitOffset > vDashArray.x) {
82690
+ if (vFillColor.a > 0.0) {
82691
+ inDashGap = true;
82692
+ } else {
82693
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
82694
+ discard;
82695
+ }
82696
+ }
82697
+ }
82698
+ }
82699
+ }
82700
+ `,
82701
+ "fs:#main-end": `
82702
+ if (inDashGap) {
82703
+ float alphaFactor = fragColor.a / max(vLineColor.a, 0.001);
82704
+ fragColor = vec4(vFillColor.rgb, vFillColor.a * alphaFactor);
82705
+ fragColor = picking_filterPickingColor(fragColor);
82706
+ fragColor = picking_filterHighlightColor(fragColor);
82707
+ }
82290
82708
  `
82291
82709
  }
82292
82710
  };
@@ -82331,13 +82749,41 @@ in float instanceOffsets;
82331
82749
  } = {}) {
82332
82750
  super({ dash: dash || highPrecisionDash, offset: offset3, highPrecisionDash });
82333
82751
  }
82752
+ getLayerType(layer) {
82753
+ if ("pathTesselator" in layer.state) {
82754
+ return "path";
82755
+ }
82756
+ const layerName = layer.constructor.layerName;
82757
+ if (layerName === "ScatterplotLayer") {
82758
+ return "scatterplot";
82759
+ }
82760
+ if (layerName === "TextBackgroundLayer") {
82761
+ return "textBackground";
82762
+ }
82763
+ return null;
82764
+ }
82334
82765
  isEnabled(layer) {
82335
- return "pathTesselator" in layer.state;
82766
+ return this.getLayerType(layer) !== null;
82336
82767
  }
82337
82768
  getShaders(extension) {
82338
- if (!extension.isEnabled(this)) {
82769
+ const layerType = extension.getLayerType(this);
82770
+ if (!layerType) {
82339
82771
  return null;
82340
82772
  }
82773
+ if (layerType === "scatterplot" || layerType === "textBackground") {
82774
+ if (!extension.opts.dash) {
82775
+ return null;
82776
+ }
82777
+ const inject7 = layerType === "scatterplot" ? scatterplotDashShaders.inject : textBackgroundDashShaders.inject;
82778
+ const pathStyle2 = {
82779
+ name: "pathStyle",
82780
+ inject: inject7,
82781
+ uniformTypes: {
82782
+ dashGapPickable: "i32"
82783
+ }
82784
+ };
82785
+ return { modules: [pathStyle2] };
82786
+ }
82341
82787
  let result = {};
82342
82788
  const defines2 = {};
82343
82789
  if (extension.opts.dash) {
@@ -82365,13 +82811,14 @@ in float instanceOffsets;
82365
82811
  }
82366
82812
  initializeState(context, extension) {
82367
82813
  const attributeManager = this.getAttributeManager();
82368
- if (!attributeManager || !extension.isEnabled(this)) {
82814
+ const layerType = extension.getLayerType(this);
82815
+ if (!attributeManager || !layerType) {
82369
82816
  return;
82370
82817
  }
82371
82818
  if (extension.opts.dash) {
82372
82819
  attributeManager.addInstanced({
82373
82820
  instanceDashArrays: { size: 2, accessor: "getDashArray" },
82374
- ...extension.opts.highPrecisionDash ? {
82821
+ ...layerType === "path" && extension.opts.highPrecisionDash ? {
82375
82822
  instanceDashOffsets: {
82376
82823
  size: 1,
82377
82824
  accessor: "getPath",
@@ -82380,7 +82827,7 @@ in float instanceOffsets;
82380
82827
  } : {}
82381
82828
  });
82382
82829
  }
82383
- if (extension.opts.offset) {
82830
+ if (layerType === "path" && extension.opts.offset) {
82384
82831
  attributeManager.addInstanced({
82385
82832
  instanceOffsets: { size: 1, accessor: "getOffset" }
82386
82833
  });
@@ -82391,11 +82838,19 @@ in float instanceOffsets;
82391
82838
  return;
82392
82839
  }
82393
82840
  if (extension.opts.dash) {
82394
- const pathStyleProps = {
82395
- dashAlignMode: this.props.dashJustified ? 1 : 0,
82396
- dashGapPickable: Boolean(this.props.dashGapPickable)
82397
- };
82398
- this.setShaderModuleProps({ pathStyle: pathStyleProps });
82841
+ const layerType = extension.getLayerType(this);
82842
+ if (layerType === "scatterplot" || layerType === "textBackground") {
82843
+ const pathStyleProps = {
82844
+ dashGapPickable: Boolean(this.props.dashGapPickable)
82845
+ };
82846
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
82847
+ } else {
82848
+ const pathStyleProps = {
82849
+ dashAlignMode: this.props.dashJustified ? 1 : 0,
82850
+ dashGapPickable: Boolean(this.props.dashGapPickable)
82851
+ };
82852
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
82853
+ }
82399
82854
  }
82400
82855
  }
82401
82856
  getDashOffsets(path) {
@@ -90477,7 +90932,7 @@ void main() {
90477
90932
  {
90478
90933
  // position buffer is filled with world coordinates generated from viewport.unproject
90479
90934
  // i.e. LNGLAT if geospatial, CARTESIAN otherwise
90480
- coordinateSystem: COORDINATE_SYSTEM.DEFAULT,
90935
+ coordinateSystem: "default",
90481
90936
  data: {
90482
90937
  attributes: {
90483
90938
  positions: triPositionBuffer,
@@ -90679,7 +91134,7 @@ void main() {
90679
91134
  if (forceUpdate || !this.state.worldBounds || !boundsContain(this.state.worldBounds, visibleWorldBounds)) {
90680
91135
  const scaledCommonBounds = this._worldToCommonBounds(visibleWorldBounds);
90681
91136
  const worldBounds = this._commonToWorldBounds(scaledCommonBounds);
90682
- if (this.props.coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
91137
+ if (this.props.coordinateSystem === "lnglat") {
90683
91138
  worldBounds[1] = Math.max(worldBounds[1], -85.051129);
90684
91139
  worldBounds[3] = Math.min(worldBounds[3], 85.051129);
90685
91140
  worldBounds[0] = Math.max(worldBounds[0], -360);
@@ -90781,7 +91236,7 @@ void main() {
90781
91236
  const { viewport } = this.context;
90782
91237
  const { textureSize } = this.state;
90783
91238
  const { coordinateSystem } = this.props;
90784
- const offsetMode = useLayerCoordinateSystem && (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS);
91239
+ const offsetMode = useLayerCoordinateSystem && (coordinateSystem === "lnglat-offsets" || coordinateSystem === "meter-offsets");
90785
91240
  const offsetOriginCommon = offsetMode ? viewport.projectPosition(this.props.coordinateOrigin) : [0, 0];
90786
91241
  const size2 = textureSize * RESOLUTION / viewport.scale;
90787
91242
  let bottomLeftCommon;
@@ -91285,6 +91740,85 @@ void main() {
91285
91740
  }
91286
91741
  };
91287
91742
 
91743
+ // ../mapbox/src/mapbox-layer-group.ts
91744
+ var MapboxLayerGroup = class {
91745
+ /* eslint-disable no-this-before-super */
91746
+ constructor(props) {
91747
+ assert10(props.id, "id is required");
91748
+ this.id = props.id;
91749
+ this.type = "custom";
91750
+ this.renderingMode = props.renderingMode || "3d";
91751
+ this.slot = props.slot;
91752
+ this.beforeId = props.beforeId;
91753
+ this.map = null;
91754
+ }
91755
+ /* Mapbox custom layer methods */
91756
+ onAdd(map3, gl) {
91757
+ this.map = map3;
91758
+ }
91759
+ render(gl, renderParameters) {
91760
+ if (!this.map)
91761
+ return;
91762
+ drawLayerGroup(this.map.__deck, this.map, this, renderParameters);
91763
+ }
91764
+ };
91765
+
91766
+ // ../mapbox/src/resolve-layer-groups.ts
91767
+ var UNDEFINED_BEFORE_ID = "__UNDEFINED__";
91768
+ function getLayerGroupId(layer) {
91769
+ if (layer.props.beforeId) {
91770
+ return `deck-layer-group-before:${layer.props.beforeId}`;
91771
+ } else if (layer.props.slot) {
91772
+ return `deck-layer-group-slot:${layer.props.slot}`;
91773
+ }
91774
+ return "deck-layer-group-last";
91775
+ }
91776
+ function resolveLayerGroups(map3, oldLayers, newLayers) {
91777
+ if (!map3 || !map3.style || !map3.style._loaded) {
91778
+ return;
91779
+ }
91780
+ const layers = flatten(newLayers, Boolean);
91781
+ if (oldLayers !== newLayers) {
91782
+ const prevLayers = flatten(oldLayers, Boolean);
91783
+ const prevLayerGroupIds = new Set(prevLayers.map((l3) => getLayerGroupId(l3)));
91784
+ const newLayerGroupIds = new Set(layers.map((l3) => getLayerGroupId(l3)));
91785
+ for (const groupId of prevLayerGroupIds) {
91786
+ if (!newLayerGroupIds.has(groupId)) {
91787
+ if (map3.getLayer(groupId)) {
91788
+ map3.removeLayer(groupId);
91789
+ }
91790
+ }
91791
+ }
91792
+ }
91793
+ const layerGroups = {};
91794
+ for (const layer of layers) {
91795
+ const groupId = getLayerGroupId(layer);
91796
+ const mapboxGroup = map3.getLayer(groupId);
91797
+ if (mapboxGroup) {
91798
+ const groupInstance = mapboxGroup.implementation || mapboxGroup;
91799
+ layerGroups[groupId] = groupInstance;
91800
+ } else {
91801
+ const newGroup = new MapboxLayerGroup({
91802
+ id: groupId,
91803
+ slot: layer.props.slot,
91804
+ beforeId: layer.props.beforeId
91805
+ });
91806
+ layerGroups[groupId] = newGroup;
91807
+ map3.addLayer(newGroup, layer.props.beforeId);
91808
+ }
91809
+ }
91810
+ const mapLayers = map3.style._order;
91811
+ for (const [groupId, group] of Object.entries(layerGroups)) {
91812
+ const beforeId = group.beforeId || UNDEFINED_BEFORE_ID;
91813
+ const expectedGroupIndex = beforeId === UNDEFINED_BEFORE_ID ? mapLayers.length : mapLayers.indexOf(beforeId);
91814
+ const currentGropupIndex = mapLayers.indexOf(groupId);
91815
+ if (currentGropupIndex !== expectedGroupIndex - 1) {
91816
+ const moveBeforeId = beforeId === UNDEFINED_BEFORE_ID ? void 0 : beforeId;
91817
+ map3.moveLayer(groupId, moveBeforeId);
91818
+ }
91819
+ }
91820
+ }
91821
+
91288
91822
  // ../mapbox/src/deck-utils.ts
91289
91823
  var MAPBOX_VIEW_ID = "mapbox";
91290
91824
  var TILE_SIZE5 = 512;
@@ -91360,27 +91894,6 @@ void main() {
91360
91894
  }
91361
91895
  return result;
91362
91896
  }
91363
- function drawLayer(deck, map3, layer, renderParameters) {
91364
- if (!deck.isInitialized) {
91365
- return;
91366
- }
91367
- let { currentViewport } = deck.userData;
91368
- let clearStack = false;
91369
- if (!currentViewport) {
91370
- currentViewport = getViewport(deck, map3, renderParameters);
91371
- deck.userData.currentViewport = currentViewport;
91372
- clearStack = true;
91373
- }
91374
- if (!currentViewport) {
91375
- return;
91376
- }
91377
- deck._drawLayers("mapbox-repaint", {
91378
- viewports: [currentViewport],
91379
- layerFilter: (params) => (!deck.props.layerFilter || deck.props.layerFilter(params)) && (layer.id === params.layer.id || params.layer.props.operation.includes("terrain")),
91380
- clearStack,
91381
- clearCanvas: false
91382
- });
91383
- }
91384
91897
  function drawLayerGroup(deck, map3, group, renderParameters) {
91385
91898
  if (!deck.isInitialized) {
91386
91899
  return;
@@ -91499,7 +92012,9 @@ void main() {
91499
92012
  }
91500
92013
  function afterRender(deck, map3) {
91501
92014
  const deckLayers = flatten(deck.props.layers, Boolean);
91502
- const hasNonMapboxLayers = deckLayers.some((layer) => layer && !map3.getLayer(layer.id));
92015
+ const hasNonMapboxLayers = deckLayers.some(
92016
+ (layer) => layer && !map3.getLayer(getLayerGroupId(layer))
92017
+ );
91503
92018
  let viewports = deck.getViewports();
91504
92019
  const mapboxViewportIdx = viewports.findIndex((vp) => vp.id === MAPBOX_VIEW_ID);
91505
92020
  const hasNonMapboxViews = viewports.length > 1 || mapboxViewportIdx < 0;
@@ -91515,7 +92030,7 @@ void main() {
91515
92030
  }
91516
92031
  deck._drawLayers("mapbox-repaint", {
91517
92032
  viewports,
91518
- layerFilter: (params) => (!deck.props.layerFilter || deck.props.layerFilter(params)) && (params.viewport.id !== MAPBOX_VIEW_ID || !map3.getLayer(params.layer.id)),
92033
+ layerFilter: (params) => (!deck.props.layerFilter || deck.props.layerFilter(params)) && (params.viewport.id !== MAPBOX_VIEW_ID || !map3.getLayer(getLayerGroupId(params.layer))),
91519
92034
  clearCanvas: false
91520
92035
  });
91521
92036
  } else {
@@ -91533,181 +92048,6 @@ void main() {
91533
92048
  deck.needsRedraw({ clearRedrawFlags: true });
91534
92049
  }
91535
92050
 
91536
- // ../mapbox/src/mapbox-layer.ts
91537
- var MapboxLayer = class {
91538
- /* eslint-disable no-this-before-super */
91539
- constructor(props) {
91540
- if (!props.id) {
91541
- throw new Error("Layer must have an unique id");
91542
- }
91543
- this.id = props.id;
91544
- this.type = "custom";
91545
- this.renderingMode = props.renderingMode || "3d";
91546
- this.slot = props.slot;
91547
- this.map = null;
91548
- this.props = props;
91549
- }
91550
- /* Mapbox custom layer methods */
91551
- onAdd(map3, gl) {
91552
- this.map = map3;
91553
- }
91554
- onRemove() {
91555
- this.map = null;
91556
- }
91557
- setProps(props) {
91558
- Object.assign(this.props, props, { id: this.id });
91559
- }
91560
- render(gl, renderParameters) {
91561
- if (!this.map)
91562
- return;
91563
- drawLayer(this.map.__deck, this.map, this, renderParameters);
91564
- }
91565
- };
91566
-
91567
- // ../mapbox/src/resolve-layers.ts
91568
- var UNDEFINED_BEFORE_ID = "__UNDEFINED__";
91569
- function resolveLayers(map3, deck, oldLayers, newLayers) {
91570
- if (!map3 || !deck || !map3.style || !map3.style._loaded) {
91571
- return;
91572
- }
91573
- const layers = flatten(newLayers, Boolean);
91574
- if (oldLayers !== newLayers) {
91575
- const prevLayers = flatten(oldLayers, Boolean);
91576
- const prevLayerIds = new Set(prevLayers.map((l3) => l3.id));
91577
- for (const layer of layers) {
91578
- prevLayerIds.delete(layer.id);
91579
- }
91580
- for (const id of prevLayerIds) {
91581
- if (map3.getLayer(id)) {
91582
- map3.removeLayer(id);
91583
- }
91584
- }
91585
- }
91586
- for (const layer of layers) {
91587
- const mapboxLayer = map3.getLayer(layer.id);
91588
- if (mapboxLayer) {
91589
- const layerInstance = mapboxLayer.implementation || mapboxLayer;
91590
- layerInstance.setProps(layer.props);
91591
- } else {
91592
- map3.addLayer(
91593
- new MapboxLayer({
91594
- id: layer.id,
91595
- // @ts-expect-error slot is not defined in LayerProps
91596
- slot: layer.props.slot
91597
- }),
91598
- // @ts-expect-error beforeId is not defined in LayerProps
91599
- layer.props.beforeId
91600
- );
91601
- }
91602
- }
91603
- const mapLayers = map3.style._order;
91604
- const layerGroups = {};
91605
- for (const layer of layers) {
91606
- let { beforeId } = layer.props;
91607
- if (!beforeId || !mapLayers.includes(beforeId)) {
91608
- beforeId = UNDEFINED_BEFORE_ID;
91609
- }
91610
- layerGroups[beforeId] = layerGroups[beforeId] || [];
91611
- layerGroups[beforeId].push(layer.id);
91612
- }
91613
- for (const beforeId in layerGroups) {
91614
- const layerGroup = layerGroups[beforeId];
91615
- let lastLayerIndex = beforeId === UNDEFINED_BEFORE_ID ? mapLayers.length : mapLayers.indexOf(beforeId);
91616
- let lastLayerId = beforeId === UNDEFINED_BEFORE_ID ? void 0 : beforeId;
91617
- for (let i4 = layerGroup.length - 1; i4 >= 0; i4--) {
91618
- const layerId = layerGroup[i4];
91619
- const layerIndex = mapLayers.indexOf(layerId);
91620
- if (layerIndex !== lastLayerIndex - 1) {
91621
- map3.moveLayer(layerId, lastLayerId);
91622
- if (layerIndex > lastLayerIndex) {
91623
- lastLayerIndex++;
91624
- }
91625
- }
91626
- lastLayerIndex--;
91627
- lastLayerId = layerId;
91628
- }
91629
- }
91630
- }
91631
-
91632
- // ../mapbox/src/mapbox-layer-group.ts
91633
- var MapboxLayerGroup = class {
91634
- /* eslint-disable no-this-before-super */
91635
- constructor(props) {
91636
- assert10(props.id, "id is required");
91637
- this.id = props.id;
91638
- this.type = "custom";
91639
- this.renderingMode = props.renderingMode || "3d";
91640
- this.slot = props.slot;
91641
- this.beforeId = props.beforeId;
91642
- this.map = null;
91643
- }
91644
- /* Mapbox custom layer methods */
91645
- onAdd(map3, gl) {
91646
- this.map = map3;
91647
- }
91648
- render(gl, renderParameters) {
91649
- if (!this.map)
91650
- return;
91651
- drawLayerGroup(this.map.__deck, this.map, this, renderParameters);
91652
- }
91653
- };
91654
-
91655
- // ../mapbox/src/resolve-layer-groups.ts
91656
- var UNDEFINED_BEFORE_ID2 = "__UNDEFINED__";
91657
- function getLayerGroupId(layer) {
91658
- if (layer.props.beforeId) {
91659
- return `deck-layer-group-before:${layer.props.beforeId}`;
91660
- } else if (layer.props.slot) {
91661
- return `deck-layer-group-slot:${layer.props.slot}`;
91662
- }
91663
- return "deck-layer-group-last";
91664
- }
91665
- function resolveLayerGroups(map3, oldLayers, newLayers) {
91666
- if (!map3 || !map3.style || !map3.style._loaded) {
91667
- return;
91668
- }
91669
- const layers = flatten(newLayers, Boolean);
91670
- if (oldLayers !== newLayers) {
91671
- const prevLayers = flatten(oldLayers, Boolean);
91672
- const prevLayerGroupIds = new Set(prevLayers.map((l3) => getLayerGroupId(l3)));
91673
- const newLayerGroupIds = new Set(layers.map((l3) => getLayerGroupId(l3)));
91674
- for (const groupId of prevLayerGroupIds) {
91675
- if (!newLayerGroupIds.has(groupId)) {
91676
- if (map3.getLayer(groupId)) {
91677
- map3.removeLayer(groupId);
91678
- }
91679
- }
91680
- }
91681
- }
91682
- const layerGroups = {};
91683
- for (const layer of layers) {
91684
- const groupId = getLayerGroupId(layer);
91685
- const mapboxGroup = map3.getLayer(groupId);
91686
- if (mapboxGroup) {
91687
- const groupInstance = mapboxGroup.implementation || mapboxGroup;
91688
- layerGroups[groupId] = groupInstance;
91689
- } else {
91690
- const newGroup = new MapboxLayerGroup({
91691
- id: groupId,
91692
- slot: layer.props.slot,
91693
- beforeId: layer.props.beforeId
91694
- });
91695
- layerGroups[groupId] = newGroup;
91696
- map3.addLayer(newGroup, layer.props.beforeId);
91697
- }
91698
- }
91699
- const mapLayers = map3.style._order;
91700
- for (const [groupId, group] of Object.entries(layerGroups)) {
91701
- const beforeId = group.beforeId || UNDEFINED_BEFORE_ID2;
91702
- const expectedGroupIndex = beforeId === UNDEFINED_BEFORE_ID2 ? mapLayers.length : mapLayers.indexOf(beforeId);
91703
- const currentGropupIndex = mapLayers.indexOf(groupId);
91704
- if (currentGropupIndex !== expectedGroupIndex - 1) {
91705
- const moveBeforeId = beforeId === UNDEFINED_BEFORE_ID2 ? void 0 : beforeId;
91706
- map3.moveLayer(groupId, moveBeforeId);
91707
- }
91708
- }
91709
- }
91710
-
91711
92051
  // ../mapbox/src/mapbox-overlay.ts
91712
92052
  var MapboxOverlay = class {
91713
92053
  constructor(props) {
@@ -91716,8 +92056,8 @@ void main() {
91716
92056
  if (!this._map)
91717
92057
  return;
91718
92058
  const projection = getProjection(this._map);
91719
- if (projection && !this._props.views) {
91720
- this._deck?.setProps({ views: getDefaultView(this._map) });
92059
+ if (projection) {
92060
+ this._deck?.setProps({ views: this._getViews(this._map) });
91721
92061
  }
91722
92062
  };
91723
92063
  this._updateContainerSize = () => {
@@ -91734,7 +92074,7 @@ void main() {
91734
92074
  const map3 = this._map;
91735
92075
  if (deck && map3) {
91736
92076
  deck.setProps({
91737
- views: this._props.views || getDefaultView(map3),
92077
+ views: this._getViews(map3),
91738
92078
  viewState: getViewState(map3)
91739
92079
  });
91740
92080
  if (deck.isInitialized) {
@@ -91806,7 +92146,6 @@ void main() {
91806
92146
  };
91807
92147
  const { interleaved = false } = props;
91808
92148
  this._interleaved = interleaved;
91809
- this._renderLayersInGroups = props._renderLayersInGroups || false;
91810
92149
  this._props = this.filterProps(props);
91811
92150
  }
91812
92151
  /** Filter out props to pass to Deck **/
@@ -91826,6 +92165,7 @@ void main() {
91826
92165
  if (this._deck && this._map) {
91827
92166
  this._deck.setProps({
91828
92167
  ...this._props,
92168
+ views: this._getViews(this._map),
91829
92169
  parameters: {
91830
92170
  ...getDefaultParameters(this._map, this._interleaved),
91831
92171
  ...this._props.parameters
@@ -91854,7 +92194,7 @@ void main() {
91854
92194
  ...this._props,
91855
92195
  parent: container,
91856
92196
  parameters: { ...getDefaultParameters(map3, false), ...this._props.parameters },
91857
- views: this._props.views || getDefaultView(map3),
92197
+ views: this._getViews(map3),
91858
92198
  viewState: getViewState(map3)
91859
92199
  });
91860
92200
  map3.on("resize", this._updateContainerSize);
@@ -91881,6 +92221,7 @@ void main() {
91881
92221
  map: map3,
91882
92222
  deck: new Deck({
91883
92223
  ...this._props,
92224
+ views: this._getViews(map3),
91884
92225
  gl,
91885
92226
  parameters: { ...getDefaultParameters(map3, true), ...this._props.parameters }
91886
92227
  })
@@ -91889,12 +92230,8 @@ void main() {
91889
92230
  this._resolveLayers(map3, this._deck, [], this._props.layers);
91890
92231
  return document.createElement("div");
91891
92232
  }
91892
- _resolveLayers(map3, deck, prevLayers, newLayers) {
91893
- if (this._renderLayersInGroups) {
91894
- resolveLayerGroups(map3, prevLayers, newLayers);
91895
- } else {
91896
- resolveLayers(map3, deck, prevLayers, newLayers);
91897
- }
92233
+ _resolveLayers(map3, _deck, prevLayers, newLayers) {
92234
+ resolveLayerGroups(map3, prevLayers, newLayers);
91898
92235
  }
91899
92236
  /** Called when the control is removed from a map */
91900
92237
  onRemove() {
@@ -91959,6 +92296,17 @@ void main() {
91959
92296
  }
91960
92297
  return this._interleaved ? this._map.getCanvas() : this._deck.getCanvas();
91961
92298
  }
92299
+ _getViews(map3) {
92300
+ if (!this._props.views) {
92301
+ return getDefaultView(map3);
92302
+ }
92303
+ const views = Array.isArray(this._props.views) ? this._props.views : [this._props.views];
92304
+ const hasMapboxView = views.some((v4) => v4.id === MAPBOX_VIEW_ID);
92305
+ if (hasMapboxView) {
92306
+ return this._props.views;
92307
+ }
92308
+ return [getDefaultView(map3), ...views];
92309
+ }
91962
92310
  };
91963
92311
 
91964
92312
  // ../../node_modules/preact/dist/preact.module.js
@@ -92515,7 +92863,7 @@ void main() {
92515
92863
  ] });
92516
92864
  B2(ui, rootElement);
92517
92865
  }
92518
- handleZoom(viewId, nextZoom) {
92866
+ handleZoom(viewId, nextZoom, delta) {
92519
92867
  const viewState = this.getViewState(viewId);
92520
92868
  if (viewState) {
92521
92869
  const { minZoom, maxZoom } = viewState;
@@ -92526,6 +92874,7 @@ void main() {
92526
92874
  nextZoom = Math.min(maxZoom, nextZoom);
92527
92875
  }
92528
92876
  }
92877
+ this.props.onZoom?.({ viewId, delta, zoom: nextZoom });
92529
92878
  const nextViewState = {
92530
92879
  ...viewState,
92531
92880
  zoom: nextZoom
@@ -92542,14 +92891,14 @@ void main() {
92542
92891
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v4) => v4.id) ?? [];
92543
92892
  for (const viewId of viewIds) {
92544
92893
  const viewState = this.getViewState(viewId);
92545
- this.handleZoom(viewId, viewState.zoom + 1);
92894
+ this.handleZoom(viewId, viewState.zoom + 1, 1);
92546
92895
  }
92547
92896
  }
92548
92897
  handleZoomOut() {
92549
92898
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v4) => v4.id) ?? [];
92550
92899
  for (const viewId of viewIds) {
92551
92900
  const viewState = this.getViewState(viewId);
92552
- this.handleZoom(viewId, viewState.zoom - 1);
92901
+ this.handleZoom(viewId, viewState.zoom - 1, -1);
92553
92902
  }
92554
92903
  }
92555
92904
  };
@@ -92561,7 +92910,9 @@ void main() {
92561
92910
  transitionDuration: 200,
92562
92911
  zoomInLabel: "Zoom In",
92563
92912
  zoomOutLabel: "Zoom Out",
92564
- viewId: null
92913
+ viewId: null,
92914
+ onZoom: () => {
92915
+ }
92565
92916
  };
92566
92917
 
92567
92918
  // ../widgets/src/reset-view-widget.tsx
@@ -92603,6 +92954,7 @@ void main() {
92603
92954
  // transitionDuration: this.props.transitionDuration,
92604
92955
  // transitionInterpolator: new FlyToInterpolator()
92605
92956
  };
92957
+ this.props.onReset?.({ viewId, viewState: nextViewState });
92606
92958
  this.setViewState(viewId, nextViewState);
92607
92959
  }
92608
92960
  }
@@ -92613,7 +92965,9 @@ void main() {
92613
92965
  placement: "top-left",
92614
92966
  label: "Reset View",
92615
92967
  initialViewState: void 0,
92616
- viewId: null
92968
+ viewId: null,
92969
+ onReset: () => {
92970
+ }
92617
92971
  };
92618
92972
 
92619
92973
  // ../widgets/src/gimbal-widget.tsx
@@ -92711,6 +93065,7 @@ void main() {
92711
93065
  const viewId = this.viewId || viewport?.id || "OrbitView";
92712
93066
  const viewState = this.getViewState(viewId);
92713
93067
  if ("rotationOrbit" in viewState || "rotationX" in viewState) {
93068
+ this.props.onReset?.({ viewId, rotationOrbit: 0, rotationX: 0 });
92714
93069
  const nextViewState = {
92715
93070
  ...viewState,
92716
93071
  rotationOrbit: 0,
@@ -92745,7 +93100,9 @@ void main() {
92745
93100
  viewId: null,
92746
93101
  label: "Gimbal",
92747
93102
  strokeWidth: 1.5,
92748
- transitionDuration: 200
93103
+ transitionDuration: 200,
93104
+ onReset: () => {
93105
+ }
92749
93106
  };
92750
93107
  function normalizeAndClampAngle(angle4) {
92751
93108
  let normalized = ((angle4 + 180) % 360 + 360) % 360 - 180;
@@ -92828,10 +93185,14 @@ void main() {
92828
93185
  const viewId = this.viewId || viewport.id;
92829
93186
  if (viewport instanceof WebMercatorViewport2) {
92830
93187
  const viewState = this.getViewState(viewId);
93188
+ const resetPitch = this.getRotation(viewport)[0] === 0;
93189
+ const nextBearing = 0;
93190
+ const nextPitch = resetPitch ? 0 : viewport.pitch;
93191
+ this.props.onReset?.({ viewId, bearing: nextBearing, pitch: nextPitch });
92831
93192
  const nextViewState = {
92832
93193
  ...viewState,
92833
- bearing: 0,
92834
- ...this.getRotation(viewport)[0] === 0 ? { pitch: 0 } : {},
93194
+ bearing: nextBearing,
93195
+ ...resetPitch ? { pitch: nextPitch } : {},
92835
93196
  transitionDuration: this.props.transitionDuration,
92836
93197
  transitionInterpolator: new FlyToInterpolator()
92837
93198
  };
@@ -92845,7 +93206,9 @@ void main() {
92845
93206
  placement: "top-left",
92846
93207
  viewId: null,
92847
93208
  label: "Reset Compass",
92848
- transitionDuration: 200
93209
+ transitionDuration: 200,
93210
+ onReset: () => {
93211
+ }
92849
93212
  };
92850
93213
 
92851
93214
  // ../widgets/src/scale-widget.tsx
@@ -93354,6 +93717,16 @@ void main() {
93354
93717
  flyTo(viewState) {
93355
93718
  const viewIds = this.viewId ? [this.viewId] : this.deck?.getViews().map((v4) => v4.id) ?? [];
93356
93719
  for (const viewId of viewIds) {
93720
+ if ("longitude" in viewState && "latitude" in viewState) {
93721
+ this.props.onGeocode?.({
93722
+ viewId,
93723
+ coordinates: {
93724
+ longitude: viewState.longitude,
93725
+ latitude: viewState.latitude,
93726
+ zoom: viewState.zoom
93727
+ }
93728
+ });
93729
+ }
93357
93730
  const currentViewState = this.getViewState(viewId);
93358
93731
  const nextViewState = {
93359
93732
  ...currentViewState,
@@ -93377,7 +93750,9 @@ void main() {
93377
93750
  geocoder: "coordinates",
93378
93751
  customGeocoder: CoordinatesGeocoder,
93379
93752
  apiKey: "",
93380
- _geolocation: false
93753
+ _geolocation: false,
93754
+ onGeocode: () => {
93755
+ }
93381
93756
  };
93382
93757
  function getGeocoder(props) {
93383
93758
  switch (props.geocoder) {
@@ -93415,6 +93790,7 @@ void main() {
93415
93790
  document.removeEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
93416
93791
  }
93417
93792
  onRenderHTML(rootElement) {
93793
+ const isFullscreen = this.getFullscreen();
93418
93794
  B2(
93419
93795
  /* @__PURE__ */ u3(
93420
93796
  IconButton,
@@ -93422,8 +93798,8 @@ void main() {
93422
93798
  onClick: () => {
93423
93799
  this.handleClick().catch((err) => log_default.error(err)());
93424
93800
  },
93425
- label: this.fullscreen ? this.props.exitLabel : this.props.enterLabel,
93426
- className: this.fullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter"
93801
+ label: isFullscreen ? this.props.exitLabel : this.props.enterLabel,
93802
+ className: isFullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter"
93427
93803
  }
93428
93804
  ),
93429
93805
  rootElement
@@ -93437,21 +93813,24 @@ void main() {
93437
93813
  getContainer() {
93438
93814
  return this.props.container || this.deck?.props.parent || this.deck?.getCanvas()?.parentElement;
93439
93815
  }
93816
+ getFullscreen() {
93817
+ return this.fullscreen;
93818
+ }
93440
93819
  onFullscreenChange() {
93441
- const prevFullscreen = this.fullscreen;
93442
93820
  const fullscreen = document.fullscreenElement === this.getContainer();
93443
- if (prevFullscreen !== fullscreen) {
93444
- this.fullscreen = !this.fullscreen;
93821
+ if (fullscreen !== this.fullscreen) {
93822
+ this.fullscreen = fullscreen;
93823
+ this.props.onFullscreenChange?.(fullscreen);
93824
+ this.updateHTML();
93445
93825
  }
93446
- this.updateHTML();
93447
93826
  }
93448
93827
  async handleClick() {
93449
- if (this.fullscreen) {
93828
+ const isFullscreen = this.getFullscreen();
93829
+ if (isFullscreen) {
93450
93830
  await this.exitFullscreen();
93451
93831
  } else {
93452
93832
  await this.requestFullscreen();
93453
93833
  }
93454
- this.updateHTML();
93455
93834
  }
93456
93835
  async requestFullscreen() {
93457
93836
  const container = this.getContainer();
@@ -93470,6 +93849,9 @@ void main() {
93470
93849
  }
93471
93850
  togglePseudoFullscreen() {
93472
93851
  this.getContainer()?.classList.toggle("deck-pseudo-fullscreen");
93852
+ this.fullscreen = !this.fullscreen;
93853
+ this.props.onFullscreenChange?.(this.fullscreen);
93854
+ this.updateHTML();
93473
93855
  }
93474
93856
  };
93475
93857
  FullscreenWidget.defaultProps = {
@@ -93479,7 +93861,9 @@ void main() {
93479
93861
  viewId: null,
93480
93862
  enterLabel: "Enter Fullscreen",
93481
93863
  exitLabel: "Exit Fullscreen",
93482
- container: void 0
93864
+ container: void 0,
93865
+ onFullscreenChange: () => {
93866
+ }
93483
93867
  };
93484
93868
 
93485
93869
  // ../widgets/src/splitter-widget.tsx
@@ -96263,20 +96647,27 @@ void main() {
96263
96647
  this.id = "timeline";
96264
96648
  this.className = "deck-widget-timeline";
96265
96649
  this.placement = "fill";
96266
- this.playing = false;
96650
+ this._playing = false;
96267
96651
  this.timerId = null;
96268
96652
  this.handlePlayPause = () => {
96269
- if (this.playing) {
96270
- this.stop();
96271
- } else {
96272
- this.play();
96653
+ const isPlaying = this.getPlaying();
96654
+ const nextPlaying = !isPlaying;
96655
+ this.props.onPlayingChange?.(nextPlaying);
96656
+ if (this.props.playing === void 0) {
96657
+ if (nextPlaying) {
96658
+ this.play();
96659
+ } else {
96660
+ this.stop();
96661
+ }
96273
96662
  }
96274
96663
  };
96275
96664
  this.handleTimeChange = ([value]) => {
96276
- this.currentTime = value;
96277
- this.props.timeline?.setTime(value);
96278
96665
  this.props.onTimeChange(value);
96279
- this.updateHTML();
96666
+ if (this.props.time === void 0) {
96667
+ this.currentTime = value;
96668
+ this.props.timeline?.setTime(value);
96669
+ this.updateHTML();
96670
+ }
96280
96671
  };
96281
96672
  this.tick = () => {
96282
96673
  const {
@@ -96285,51 +96676,90 @@ void main() {
96285
96676
  loop
96286
96677
  } = this.props;
96287
96678
  if (step > 0) {
96288
- let next = Math.round(this.currentTime / step) * step + step;
96679
+ const currentTime = this.getTime();
96680
+ let next = Math.round(currentTime / step) * step + step;
96289
96681
  if (next > max7) {
96290
- if (this.currentTime < max7) {
96682
+ if (currentTime < max7) {
96291
96683
  next = max7;
96292
96684
  } else if (loop) {
96293
96685
  next = min7;
96294
96686
  } else {
96295
96687
  next = max7;
96296
- this.playing = false;
96688
+ this._playing = false;
96689
+ this.props.onPlayingChange?.(false);
96297
96690
  }
96298
96691
  }
96299
- this.currentTime = next;
96300
96692
  this.props.onTimeChange(next);
96693
+ if (this.props.time === void 0) {
96694
+ this.currentTime = next;
96695
+ this.props.timeline?.setTime(next);
96696
+ }
96301
96697
  this.updateHTML();
96302
96698
  }
96303
- if (this.playing) {
96699
+ if (this._playing) {
96304
96700
  this.timerId = window.setTimeout(this.tick, this.props.playInterval);
96305
96701
  } else {
96306
96702
  this.timerId = null;
96307
96703
  }
96308
96704
  };
96309
96705
  this.currentTime = this.props.initialTime ?? this.props.timeRange[0];
96310
- this.props.timeline?.setTime(this.currentTime);
96706
+ const syncTime = this.props.time ?? this.currentTime;
96707
+ this.props.timeline?.setTime(syncTime);
96311
96708
  this.setProps(this.props);
96312
96709
  }
96710
+ /**
96711
+ * Returns the current time value.
96712
+ * In controlled mode, returns the time prop.
96713
+ * In uncontrolled mode, returns the internal state.
96714
+ */
96715
+ getTime() {
96716
+ return this.props.time ?? this.currentTime;
96717
+ }
96718
+ /**
96719
+ * Returns the current playing state.
96720
+ * In controlled mode, returns the playing prop.
96721
+ * In uncontrolled mode, returns the internal state.
96722
+ */
96723
+ getPlaying() {
96724
+ return this.props.playing ?? this._playing;
96725
+ }
96313
96726
  setProps(props) {
96727
+ const { playing: prevPlaying, time: prevTime } = this.props;
96314
96728
  this.viewId = props.viewId ?? this.viewId;
96315
96729
  super.setProps(props);
96730
+ if (props.time !== void 0 && props.time !== prevTime) {
96731
+ this.props.timeline?.setTime(props.time);
96732
+ }
96733
+ if (props.playing !== void 0 && props.playing !== prevPlaying) {
96734
+ if (props.playing && !this._playing) {
96735
+ this._startTimer();
96736
+ } else if (!props.playing && this._playing) {
96737
+ this._stopTimer();
96738
+ }
96739
+ }
96316
96740
  }
96317
96741
  onAdd() {
96318
- this.playing = false;
96742
+ this._playing = false;
96319
96743
  this.timerId = null;
96320
- if (this.props.autoPlay)
96321
- this.play();
96744
+ if (this.props.autoPlay) {
96745
+ if (this.props.playing !== void 0) {
96746
+ this.props.onPlayingChange?.(true);
96747
+ } else {
96748
+ this.play();
96749
+ }
96750
+ }
96322
96751
  }
96323
96752
  onRemove() {
96324
96753
  this.stop();
96325
96754
  }
96326
96755
  onRenderHTML(rootElement) {
96327
96756
  const { timeRange, step, formatLabel } = this.props;
96328
- const currentTime = this.currentTime;
96757
+ const isPlaying = this.getPlaying();
96758
+ const currentTime = this.getTime();
96329
96759
  rootElement.dataset.placement = this.props.placement;
96330
96760
  B2(
96331
96761
  /* @__PURE__ */ u3("div", { className: "deck-widget-button-group", children: [
96332
- this.playing ? /* @__PURE__ */ u3(
96762
+ isPlaying ? /* @__PURE__ */ u3(
96333
96763
  IconButton,
96334
96764
  {
96335
96765
  label: "Pause",
@@ -96366,24 +96796,34 @@ void main() {
96366
96796
  );
96367
96797
  }
96368
96798
  play() {
96369
- this.playing = true;
96799
+ this._playing = true;
96370
96800
  const {
96371
96801
  timeRange: [min7, max7]
96372
96802
  } = this.props;
96373
- if (this.currentTime >= max7) {
96803
+ if (this.props.time === void 0 && this.getTime() >= max7) {
96374
96804
  this.currentTime = min7;
96375
96805
  this.props.onTimeChange(min7);
96806
+ this.props.timeline?.setTime(min7);
96376
96807
  }
96377
96808
  this.updateHTML();
96378
96809
  this.tick();
96379
96810
  }
96380
96811
  stop() {
96381
- this.playing = false;
96812
+ this._stopTimer();
96813
+ this.updateHTML();
96814
+ }
96815
+ /** Start the playback timer (used internally) */
96816
+ _startTimer() {
96817
+ this._playing = true;
96818
+ this.tick();
96819
+ }
96820
+ /** Stop the playback timer (used internally) */
96821
+ _stopTimer() {
96822
+ this._playing = false;
96382
96823
  if (this.timerId !== null) {
96383
96824
  window.clearTimeout(this.timerId);
96384
96825
  this.timerId = null;
96385
96826
  }
96386
- this.updateHTML();
96387
96827
  }
96388
96828
  };
96389
96829
  TimelineWidget.defaultProps = {
@@ -96395,11 +96835,15 @@ void main() {
96395
96835
  timeRange: [0, 100],
96396
96836
  step: 1,
96397
96837
  initialTime: void 0,
96838
+ time: void 0,
96398
96839
  onTimeChange: () => {
96399
96840
  },
96400
96841
  autoPlay: false,
96401
96842
  loop: false,
96402
96843
  playInterval: 1e3,
96844
+ playing: void 0,
96845
+ onPlayingChange: () => {
96846
+ },
96403
96847
  formatLabel: String
96404
96848
  };
96405
96849
 
@@ -96589,53 +97033,72 @@ void main() {
96589
97033
  }
96590
97034
  // eslint-disable-next-line complexity
96591
97035
  setProps(props) {
96592
- const { lightModeTheme, darkModeTheme } = this.props;
97036
+ const { lightModeTheme, darkModeTheme, themeMode: prevThemeMode } = this.props;
96593
97037
  this.placement = props.placement ?? this.placement;
96594
97038
  this.viewId = props.viewId ?? this.viewId;
96595
97039
  super.setProps(props);
96596
- switch (this.themeMode) {
97040
+ const currentMode = this.getThemeMode();
97041
+ if (props.themeMode !== void 0 && props.themeMode !== prevThemeMode) {
97042
+ this._applyTheme(props.themeMode);
97043
+ return;
97044
+ }
97045
+ switch (currentMode) {
96597
97046
  case "light":
96598
97047
  if (props.lightModeTheme && !deepEqual2(props.lightModeTheme, lightModeTheme, 1)) {
96599
- this._setThemeMode("light");
97048
+ this._applyTheme("light");
96600
97049
  }
96601
97050
  break;
96602
97051
  case "dark":
96603
97052
  if (props.darkModeTheme && !deepEqual2(props.darkModeTheme, darkModeTheme, 1)) {
96604
- this._setThemeMode("dark");
97053
+ this._applyTheme("dark");
96605
97054
  }
96606
97055
  break;
96607
97056
  default:
96608
- log_default.warn(`Invalid theme mode ${this.themeMode}`)();
97057
+ log_default.warn(`Invalid theme mode ${currentMode}`)();
96609
97058
  }
96610
97059
  }
96611
97060
  onRenderHTML(rootElement) {
96612
97061
  const { lightModeLabel, darkModeLabel } = this.props;
97062
+ const currentMode = this.getThemeMode();
96613
97063
  B2(
96614
97064
  /* @__PURE__ */ u3(
96615
97065
  IconButton,
96616
97066
  {
96617
97067
  onClick: this._handleClick.bind(this),
96618
- label: this.themeMode === "dark" ? darkModeLabel : lightModeLabel,
96619
- className: this.themeMode === "dark" ? "deck-widget-moon" : "deck-widget-sun"
97068
+ label: currentMode === "dark" ? darkModeLabel : lightModeLabel,
97069
+ className: currentMode === "dark" ? "deck-widget-moon" : "deck-widget-sun"
96620
97070
  }
96621
97071
  ),
96622
97072
  rootElement
96623
97073
  );
96624
97074
  }
96625
97075
  onAdd() {
96626
- this._setThemeMode(this.themeMode);
97076
+ this._applyTheme(this.getThemeMode());
97077
+ }
97078
+ /**
97079
+ * Returns the current theme mode.
97080
+ * In controlled mode, returns the themeMode prop.
97081
+ * In uncontrolled mode, returns the internal state.
97082
+ */
97083
+ getThemeMode() {
97084
+ return this.props.themeMode ?? this.themeMode;
96627
97085
  }
96628
97086
  _handleClick() {
96629
- const newThemeMode = this.themeMode === "dark" ? "light" : "dark";
96630
- this._setThemeMode(newThemeMode);
97087
+ const currentMode = this.getThemeMode();
97088
+ const nextMode = currentMode === "dark" ? "light" : "dark";
97089
+ this.props.onThemeModeChange?.(nextMode);
97090
+ if (this.props.themeMode === void 0) {
97091
+ this.themeMode = nextMode;
97092
+ this._applyTheme(nextMode);
97093
+ }
96631
97094
  }
96632
- _setThemeMode(themeMode) {
96633
- this.themeMode = themeMode;
97095
+ /** Apply theme styling without changing internal state */
97096
+ _applyTheme(themeMode) {
96634
97097
  const container = this.rootElement?.closest(".deck-widget-container");
96635
97098
  if (container) {
96636
97099
  const themeStyle = themeMode === "dark" ? this.props.darkModeTheme : this.props.lightModeTheme;
96637
97100
  applyStyles(container, themeStyle);
96638
- const label = this.themeMode === "dark" ? this.props.darkModeLabel : this.props.lightModeLabel;
97101
+ const label = themeMode === "dark" ? this.props.darkModeLabel : this.props.lightModeLabel;
96639
97102
  log_default.log(1, `Switched theme to ${label}`, themeStyle)();
96640
97103
  this.updateHTML();
96641
97104
  }
@@ -96661,7 +97124,10 @@ void main() {
96661
97124
  lightModeTheme: LightGlassTheme,
96662
97125
  darkModeLabel: "Dark Mode",
96663
97126
  darkModeTheme: DarkGlassTheme,
96664
- initialThemeMode: "auto"
97127
+ initialThemeMode: "auto",
97128
+ themeMode: void 0,
97129
+ onThemeModeChange: () => {
97130
+ }
96665
97131
  };
96666
97132
 
96667
97133
  // ../widgets/src/loading-widget.tsx
@@ -96696,6 +97162,7 @@ void main() {
96696
97162
  const loading = layers.some((layer) => !layer.isLoaded);
96697
97163
  if (loading !== this.loading) {
96698
97164
  this.loading = loading;
97165
+ this.props.onLoadingChange?.(loading);
96699
97166
  this.updateHTML();
96700
97167
  }
96701
97168
  }
@@ -96708,7 +97175,9 @@ void main() {
96708
97175
  id: "loading",
96709
97176
  placement: "top-left",
96710
97177
  viewId: null,
96711
- label: "Loading layer data"
97178
+ label: "Loading layer data",
97179
+ onLoadingChange: () => {
97180
+ }
96712
97181
  };
96713
97182
 
96714
97183
  // ../widgets/src/stats-widget.tsx
@@ -96734,19 +97203,31 @@ void main() {
96734
97203
  this.className = "deck-widget-stats";
96735
97204
  this.placement = "top-left";
96736
97205
  this._counter = 0;
96737
- this.collapsed = true;
96738
- this._toggleCollapsed = () => {
96739
- this.collapsed = !this.collapsed;
96740
- this.updateHTML();
97206
+ this._expanded = false;
97207
+ this._toggleExpanded = () => {
97208
+ const nextExpanded = !this.getExpanded();
97209
+ this.props.onExpandedChange?.(nextExpanded);
97210
+ if (this.props.expanded === void 0) {
97211
+ this._expanded = nextExpanded;
97212
+ this.updateHTML();
97213
+ }
96741
97214
  };
96742
97215
  this._getFps = () => {
96743
97216
  return Math.round(this.deck?.metrics.fps ?? 0);
96744
97217
  };
96745
97218
  this._formatters = { ...DEFAULT_FORMATTERS };
96746
97219
  this._resetOnUpdate = { ...this.props.resetOnUpdate };
96747
- this.collapsed = !props.defaultIsExpanded;
97220
+ this._expanded = Boolean(props.initialExpanded);
96748
97221
  this.setProps(props);
96749
97222
  }
97223
+ /**
97224
+ * Returns the current expanded state.
97225
+ * In controlled mode, returns the expanded prop.
97226
+ * In uncontrolled mode, returns the internal state.
97227
+ */
97228
+ getExpanded() {
97229
+ return this.props.expanded ?? this._expanded;
97230
+ }
96750
97231
  setProps(props) {
96751
97232
  this.placement = props.placement ?? this.placement;
96752
97233
  this.viewId = props.viewId ?? this.viewId;
@@ -96767,9 +97248,9 @@ void main() {
96767
97248
  }
96768
97249
  }
96769
97250
  onRenderHTML(rootElement) {
96770
- const collapsed = this.collapsed;
96771
- if (collapsed) {
96772
- B2(/* @__PURE__ */ u3(FpsIcon, { getFps: this._getFps, onClick: this._toggleCollapsed }), rootElement);
97251
+ const isExpanded = this.getExpanded();
97252
+ if (!isExpanded) {
97253
+ B2(/* @__PURE__ */ u3(FpsIcon, { getFps: this._getFps, onClick: this._toggleExpanded }), rootElement);
96773
97254
  return;
96774
97255
  }
96775
97256
  const stats2 = this._getStats();
@@ -96796,7 +97277,7 @@ void main() {
96796
97277
  {
96797
97278
  className: "deck-widget-stats-header",
96798
97279
  style: { cursor: "pointer", pointerEvents: "auto" },
96799
- onClick: this._toggleCollapsed,
97280
+ onClick: this._toggleExpanded,
96800
97281
  children: [
96801
97282
  /* @__PURE__ */ u3("b", { children: title }),
96802
97283
  deviceLabel && /* @__PURE__ */ u3("span", { className: "deck-widget-stats-device", children: deviceLabel }),
@@ -96810,7 +97291,7 @@ void main() {
96810
97291
  );
96811
97292
  }
96812
97293
  onRedraw() {
96813
- if (!this.collapsed) {
97294
+ if (this.getExpanded()) {
96814
97295
  const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);
96815
97296
  if (this._counter++ % framesPerUpdate === 0) {
96816
97297
  this.updateHTML();
@@ -96863,13 +97344,16 @@ void main() {
96863
97344
  type: "deck",
96864
97345
  placement: "top-left",
96865
97346
  viewId: null,
96866
- defaultIsExpanded: false,
97347
+ initialExpanded: false,
96867
97348
  stats: void 0,
96868
97349
  title: "Stats",
96869
97350
  framesPerUpdate: 1,
96870
97351
  formatters: {},
96871
97352
  resetOnUpdate: {},
96872
- id: "stats"
97353
+ id: "stats",
97354
+ expanded: void 0,
97355
+ onExpandedChange: () => {
97356
+ }
96873
97357
  };
96874
97358
  function FpsIcon({ getFps, onClick }) {
96875
97359
  const [fps, setFps] = h2(getFps());