@mapbox/mapbox-gl-style-spec 14.10.0 → 14.11.0-beta.2

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 (46) hide show
  1. package/composite.ts +1 -0
  2. package/dist/index.cjs +467 -191
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +76 -39
  5. package/dist/index.es.js +467 -191
  6. package/dist/index.es.js.map +1 -1
  7. package/expression/compound_expression.ts +5 -7
  8. package/expression/definitions/at.ts +5 -19
  9. package/expression/definitions/at_interpolated.ts +80 -0
  10. package/expression/definitions/coercion.ts +1 -5
  11. package/expression/definitions/comparison.ts +2 -8
  12. package/expression/definitions/config.ts +1 -4
  13. package/expression/definitions/distance.ts +28 -43
  14. package/expression/definitions/format.ts +4 -9
  15. package/expression/definitions/image.ts +126 -73
  16. package/expression/definitions/index.ts +3 -2
  17. package/expression/definitions/interpolate.ts +28 -80
  18. package/expression/definitions/let.ts +2 -7
  19. package/expression/definitions/literal.ts +1 -2
  20. package/expression/definitions/match.ts +3 -12
  21. package/expression/definitions/step.ts +1 -5
  22. package/expression/evaluation_context.ts +3 -3
  23. package/expression/index.ts +12 -18
  24. package/expression/parsing_context.ts +3 -7
  25. package/expression/types/formatted.ts +7 -3
  26. package/expression/types/image_id.ts +61 -0
  27. package/expression/types/image_variant.ts +79 -0
  28. package/expression/types/resolved_image.ts +44 -53
  29. package/format.ts +1 -0
  30. package/function/index.ts +1 -0
  31. package/migrate/v8.ts +1 -0
  32. package/migrate/v9.ts +1 -0
  33. package/migrate.ts +1 -0
  34. package/package.json +1 -1
  35. package/read_style.ts +1 -0
  36. package/reference/v8.json +154 -7
  37. package/types/brand.ts +4 -0
  38. package/types.ts +30 -2
  39. package/util/color.ts +1 -1
  40. package/validate/validate.ts +6 -1
  41. package/validate/validate_iconset.ts +40 -0
  42. package/validate/validate_layer.ts +1 -5
  43. package/validate/validate_lights.ts +3 -2
  44. package/validate/validate_object.ts +2 -0
  45. package/validate/validate_style.ts +0 -1
  46. package/expression/types/image_id_with_options.ts +0 -58
package/dist/index.es.js CHANGED
@@ -142,6 +142,17 @@ var $root = {
142
142
  }
143
143
  }
144
144
  },
145
+ iconsets: {
146
+ experimental: true,
147
+ type: "iconsets",
148
+ doc: "A collection of icon sets",
149
+ "sdk-support": {
150
+ "basic functionality": {
151
+ android: "11.11.0",
152
+ ios: "11.11.0"
153
+ }
154
+ }
155
+ },
145
156
  schema: {
146
157
  type: "schema",
147
158
  doc: "Definition of the schema for configuration options.",
@@ -683,6 +694,51 @@ var properties_light_flat = {
683
694
  }
684
695
  }
685
696
  };
697
+ var iconsets = {
698
+ "*": {
699
+ type: "iconset",
700
+ doc: "Specification of an icon set. For sprite icon set, a URL must be provided. For `raster-array` source icon set, a source name must be provided."
701
+ }
702
+ };
703
+ var iconset = [
704
+ "iconset_sprite",
705
+ "iconset_source"
706
+ ];
707
+ var iconset_sprite = {
708
+ type: {
709
+ required: true,
710
+ type: "enum",
711
+ values: {
712
+ sprite: {
713
+ doc: "A sprite icon set."
714
+ }
715
+ },
716
+ doc: "The type of the icon set."
717
+ },
718
+ url: {
719
+ required: true,
720
+ type: "string",
721
+ doc: "A base URL for retrieving the icon set and metadata. The extension `.pbf` will be automatically appended. The URL must be absolute, containing the [scheme, authority and path components](https://en.wikipedia.org/wiki/URL#Syntax).",
722
+ example: "mapbox://sprites/mapbox/bright"
723
+ }
724
+ };
725
+ var iconset_source = {
726
+ type: {
727
+ required: true,
728
+ type: "enum",
729
+ values: {
730
+ source: {
731
+ doc: "A source icon set."
732
+ }
733
+ },
734
+ doc: "The type of the icon set."
735
+ },
736
+ source: {
737
+ required: true,
738
+ type: "string",
739
+ doc: "Name of a source of `raster-array` type to be used for the icon set."
740
+ }
741
+ };
686
742
  var sources = {
687
743
  "*": {
688
744
  type: "source",
@@ -1663,6 +1719,32 @@ var layout_fill = {
1663
1719
  interpolated: false
1664
1720
  },
1665
1721
  "property-type": "data-constant"
1722
+ },
1723
+ "fill-construct-bridge-guard-rail": {
1724
+ type: "boolean",
1725
+ doc: "Determines whether bridge guard rails are added for elevated roads.",
1726
+ "default": "true",
1727
+ transition: false,
1728
+ experimental: true,
1729
+ "private": true,
1730
+ "sdk-support": {
1731
+ "basic functionality": {
1732
+ android: "11.11.0",
1733
+ ios: "11.11.0"
1734
+ },
1735
+ "data-driven styling": {
1736
+ android: "11.11.0",
1737
+ ios: "11.11.0"
1738
+ }
1739
+ },
1740
+ expression: {
1741
+ interpolated: false,
1742
+ parameters: [
1743
+ "zoom",
1744
+ "feature"
1745
+ ]
1746
+ },
1747
+ "property-type": "data-driven"
1666
1748
  }
1667
1749
  };
1668
1750
  var layout_circle = {
@@ -3835,7 +3917,7 @@ var expression_name = {
3835
3917
  }
3836
3918
  },
3837
3919
  config: {
3838
- doc: "Retrieves the configuration value for the given option.",
3920
+ doc: "Retrieves the configuration value for the given option. Returns null if the requested option is missing.",
3839
3921
  group: "Lookup",
3840
3922
  "sdk-support": {
3841
3923
  "basic functionality": {
@@ -3878,6 +3960,17 @@ var expression_name = {
3878
3960
  }
3879
3961
  }
3880
3962
  },
3963
+ "at-interpolated": {
3964
+ doc: "Retrieves an item from an array. If the array contains numeric values and the provided index is non-integer, the expression returns an interpolated value between adjacent items.",
3965
+ group: "Lookup",
3966
+ "sdk-support": {
3967
+ "basic functionality": {
3968
+ js: "3.11.0",
3969
+ android: "11.12.0",
3970
+ ios: "11.12.0"
3971
+ }
3972
+ }
3973
+ },
3881
3974
  "in": {
3882
3975
  doc: "Determines whether an item exists in an array or a substring exists in a string. In the specific case when the second and third arguments are string literals, you must wrap at least one of them in a [`literal`](#types-literal) expression to hint correct interpretation to the [type system](#type-system).",
3883
3976
  group: "Lookup",
@@ -4522,7 +4615,7 @@ var expression_name = {
4522
4615
  }
4523
4616
  },
4524
4617
  sin: {
4525
- doc: "Returns the sine of the input.",
4618
+ doc: "Returns the sine of the input, interpreted as radians.",
4526
4619
  group: "Math",
4527
4620
  "sdk-support": {
4528
4621
  "basic functionality": {
@@ -4533,7 +4626,7 @@ var expression_name = {
4533
4626
  }
4534
4627
  },
4535
4628
  cos: {
4536
- doc: "Returns the cosine of the input.",
4629
+ doc: "Returns the cosine of the input, interpreted as radians.",
4537
4630
  group: "Math",
4538
4631
  "sdk-support": {
4539
4632
  "basic functionality": {
@@ -4544,7 +4637,7 @@ var expression_name = {
4544
4637
  }
4545
4638
  },
4546
4639
  tan: {
4547
- doc: "Returns the tangent of the input.",
4640
+ doc: "Returns the tangent of the input, interpreted as radians.",
4548
4641
  group: "Math",
4549
4642
  "sdk-support": {
4550
4643
  "basic functionality": {
@@ -4555,7 +4648,7 @@ var expression_name = {
4555
4648
  }
4556
4649
  },
4557
4650
  asin: {
4558
- doc: "Returns the arcsine of the input.",
4651
+ doc: "Returns the arcsine of the input, in radians between −π/2 and π/2.",
4559
4652
  group: "Math",
4560
4653
  "sdk-support": {
4561
4654
  "basic functionality": {
@@ -4566,7 +4659,7 @@ var expression_name = {
4566
4659
  }
4567
4660
  },
4568
4661
  acos: {
4569
- doc: "Returns the arccosine of the input.",
4662
+ doc: "Returns the arccosine of the input, in radians between −π/2 and π/2.",
4570
4663
  group: "Math",
4571
4664
  "sdk-support": {
4572
4665
  "basic functionality": {
@@ -4577,7 +4670,7 @@ var expression_name = {
4577
4670
  }
4578
4671
  },
4579
4672
  atan: {
4580
- doc: "Returns the arctangent of the input.",
4673
+ doc: "Returns the arctangent of the input, in radians between −π/2 and π/2.",
4581
4674
  group: "Math",
4582
4675
  "sdk-support": {
4583
4676
  "basic functionality": {
@@ -6267,6 +6360,60 @@ var paint_fill = {
6267
6360
  ]
6268
6361
  },
6269
6362
  "property-type": "data-driven"
6363
+ },
6364
+ "fill-bridge-guard-rail-color": {
6365
+ type: "color",
6366
+ "default": "rgba(241, 236, 225, 255)",
6367
+ doc: "The color of bridge guard rail.",
6368
+ experimental: true,
6369
+ "private": true,
6370
+ transition: true,
6371
+ "sdk-support": {
6372
+ "basic functionality": {
6373
+ android: "11.11.0",
6374
+ ios: "11.11.0"
6375
+ },
6376
+ "data-driven styling": {
6377
+ android: "11.11.0",
6378
+ ios: "11.11.0"
6379
+ }
6380
+ },
6381
+ expression: {
6382
+ interpolated: true,
6383
+ parameters: [
6384
+ "zoom",
6385
+ "measure-light",
6386
+ "feature"
6387
+ ]
6388
+ },
6389
+ "property-type": "data-driven"
6390
+ },
6391
+ "fill-tunnel-structure-color": {
6392
+ type: "color",
6393
+ "default": "rgba(241, 236, 225, 255)",
6394
+ doc: "The color of tunnel structures (tunnel entrance and tunnel walls).",
6395
+ transition: true,
6396
+ experimental: true,
6397
+ "private": true,
6398
+ "sdk-support": {
6399
+ "basic functionality": {
6400
+ android: "11.11.0",
6401
+ ios: "11.11.0"
6402
+ },
6403
+ "data-driven styling": {
6404
+ android: "11.11.0",
6405
+ ios: "11.11.0"
6406
+ }
6407
+ },
6408
+ expression: {
6409
+ interpolated: true,
6410
+ parameters: [
6411
+ "zoom",
6412
+ "measure-light",
6413
+ "feature"
6414
+ ]
6415
+ },
6416
+ "property-type": "data-driven"
6270
6417
  }
6271
6418
  };
6272
6419
  var paint_line = {
@@ -9421,6 +9568,10 @@ var v8 = {
9421
9568
  properties_light_directional: properties_light_directional,
9422
9569
  properties_light_ambient: properties_light_ambient,
9423
9570
  properties_light_flat: properties_light_flat,
9571
+ iconsets: iconsets,
9572
+ iconset: iconset,
9573
+ iconset_sprite: iconset_sprite,
9574
+ iconset_source: iconset_source,
9424
9575
  sources: sources,
9425
9576
  source: source,
9426
9577
  source_vector: source_vector,
@@ -12290,7 +12441,13 @@ class Formatted {
12290
12441
  isEmpty() {
12291
12442
  if (this.sections.length === 0)
12292
12443
  return true;
12293
- return !this.sections.some(section => section.text.length !== 0 || section.image && section.image.namePrimary);
12444
+ return !this.sections.some(section => {
12445
+ if (section.text.length !== 0)
12446
+ return true;
12447
+ if (!section.image)
12448
+ return false;
12449
+ return section.image.hasPrimary();
12450
+ });
12294
12451
  }
12295
12452
  static factory(text) {
12296
12453
  if (text instanceof Formatted) {
@@ -12308,9 +12465,10 @@ class Formatted {
12308
12465
  const serialized = ['format'];
12309
12466
  for (const section of this.sections) {
12310
12467
  if (section.image) {
12468
+ const primaryId = section.image.getPrimary().id.toString();
12311
12469
  serialized.push([
12312
12470
  'image',
12313
- section.image.namePrimary
12471
+ primaryId
12314
12472
  ]);
12315
12473
  continue;
12316
12474
  }
@@ -12334,11 +12492,57 @@ class Formatted {
12334
12492
  }
12335
12493
  }
12336
12494
 
12337
- class ImageIdWithOptions {
12338
- constructor(id, options) {
12339
- this.id = id;
12340
- this.options = options || { params: {} };
12341
- if (!this.options.transform) {
12495
+ class ImageId {
12496
+ constructor(id) {
12497
+ if (typeof id === 'string') {
12498
+ this.name = id;
12499
+ } else {
12500
+ this.name = id.name;
12501
+ this.iconsetId = id.iconsetId;
12502
+ }
12503
+ }
12504
+ static from(id) {
12505
+ return new ImageId(id);
12506
+ }
12507
+ static toString(id) {
12508
+ return JSON.stringify({
12509
+ name: id.name,
12510
+ iconsetId: id.iconsetId
12511
+ });
12512
+ }
12513
+ static parse(str) {
12514
+ try {
12515
+ const {name, iconsetId} = JSON.parse(str);
12516
+ return new ImageId({
12517
+ name,
12518
+ iconsetId
12519
+ });
12520
+ } catch (e) {
12521
+ return null;
12522
+ }
12523
+ }
12524
+ static isEqual(a, b) {
12525
+ return a.name === b.name && a.iconsetId === b.iconsetId;
12526
+ }
12527
+ toString() {
12528
+ return JSON.stringify({
12529
+ name: this.name,
12530
+ iconsetId: this.iconsetId
12531
+ });
12532
+ }
12533
+ serialize() {
12534
+ return {
12535
+ name: this.name,
12536
+ iconsetId: this.iconsetId
12537
+ };
12538
+ }
12539
+ }
12540
+
12541
+ class ImageVariant {
12542
+ constructor(id, options = {}) {
12543
+ this.id = ImageId.from(id);
12544
+ this.options = Object.assign({}, options);
12545
+ if (!options.transform) {
12342
12546
  this.options.transform = new DOMMatrix([
12343
12547
  1,
12344
12548
  0,
@@ -12348,7 +12552,7 @@ class ImageIdWithOptions {
12348
12552
  0
12349
12553
  ]);
12350
12554
  } else {
12351
- const {a, b, c, d, e, f} = this.options.transform;
12555
+ const {a, b, c, d, e, f} = options.transform;
12352
12556
  this.options.transform = new DOMMatrix([
12353
12557
  a,
12354
12558
  b,
@@ -12359,90 +12563,93 @@ class ImageIdWithOptions {
12359
12563
  ]);
12360
12564
  }
12361
12565
  }
12362
- static deserializeId(serialized) {
12363
- return JSON.parse(serialized).id;
12566
+ toString() {
12567
+ const {a, b, c, d, e, f} = this.options.transform;
12568
+ const serialized = {
12569
+ name: this.id.name,
12570
+ iconsetId: this.id.iconsetId,
12571
+ params: this.options.params,
12572
+ transform: {
12573
+ a,
12574
+ b,
12575
+ c,
12576
+ d,
12577
+ e,
12578
+ f
12579
+ }
12580
+ };
12581
+ return JSON.stringify(serialized);
12364
12582
  }
12365
- static deserializeFromString(serialized) {
12366
- const deserializedObject = JSON.parse(serialized);
12367
- ({ params: deserializedObject.options.params });
12368
- const {a, b, c, d, e, f} = deserializedObject.options.transform;
12369
- new DOMMatrix([
12370
- a,
12371
- b,
12372
- c,
12373
- d,
12374
- e,
12375
- f
12376
- ]);
12377
- return new ImageIdWithOptions(deserializedObject.id, deserializedObject.options);
12583
+ static parse(str) {
12584
+ let name, iconsetId, params, transform;
12585
+ try {
12586
+ ({name, iconsetId, params, transform} = JSON.parse(str) || {});
12587
+ } catch (e2) {
12588
+ return null;
12589
+ }
12590
+ if (!name)
12591
+ return null;
12592
+ const {a, b, c, d, e, f} = transform || {};
12593
+ return new ImageVariant({
12594
+ name,
12595
+ iconsetId
12596
+ }, {
12597
+ params,
12598
+ transform: new DOMMatrix([
12599
+ a,
12600
+ b,
12601
+ c,
12602
+ d,
12603
+ e,
12604
+ f
12605
+ ])
12606
+ });
12378
12607
  }
12379
12608
  scaleSelf(factor) {
12380
- this.options.transform = this.options.transform.scale(factor);
12609
+ this.options.transform.scaleSelf(factor);
12381
12610
  return this;
12382
12611
  }
12383
- serialize() {
12384
- const serialisedObject = { id: this.id };
12385
- if (this.options) {
12386
- serialisedObject.options = this.options;
12387
- }
12388
- const {a, b, c, d, e, f} = this.options.transform;
12389
- serialisedObject.options.transform = {
12390
- a,
12391
- b,
12392
- c,
12393
- d,
12394
- e,
12395
- f
12396
- };
12397
- return JSON.stringify(serialisedObject);
12398
- }
12399
12612
  }
12400
12613
 
12401
12614
  class ResolvedImage {
12402
- constructor(options) {
12403
- this.namePrimary = options.namePrimary;
12404
- if (options.nameSecondary) {
12405
- this.nameSecondary = options.nameSecondary;
12406
- }
12407
- if (options.optionsPrimary) {
12408
- this.optionsPrimary = options.optionsPrimary;
12409
- }
12410
- if (options.optionsSecondary) {
12411
- this.optionsSecondary = options.optionsSecondary;
12412
- }
12413
- this.available = options.available;
12615
+ constructor(primaryId, primaryOptions, secondaryId, secondaryOptions, available = false) {
12616
+ this.primaryId = ImageId.from(primaryId);
12617
+ this.primaryOptions = primaryOptions;
12618
+ if (secondaryId)
12619
+ this.secondaryId = ImageId.from(secondaryId);
12620
+ this.secondaryOptions = secondaryOptions;
12621
+ this.available = available;
12414
12622
  }
12415
12623
  toString() {
12416
- if (this.namePrimary && this.nameSecondary) {
12417
- return `[${ this.namePrimary },${ this.nameSecondary }]`;
12624
+ if (this.primaryId && this.secondaryId) {
12625
+ const primaryName = this.primaryId.name;
12626
+ const secondaryName = this.secondaryId.name;
12627
+ return `[${ primaryName },${ secondaryName }]`;
12418
12628
  }
12419
- return this.namePrimary;
12629
+ return this.primaryId.name;
12630
+ }
12631
+ hasPrimary() {
12632
+ return !!this.primaryId;
12420
12633
  }
12421
12634
  getPrimary() {
12422
- return new ImageIdWithOptions(this.namePrimary, { params: this.optionsPrimary ? this.optionsPrimary.params || {} : {} });
12635
+ return new ImageVariant(this.primaryId, this.primaryOptions);
12423
12636
  }
12424
- getSerializedPrimary() {
12425
- return this.getPrimary().serialize();
12637
+ hasSecondary() {
12638
+ return !!this.secondaryId;
12426
12639
  }
12427
12640
  getSecondary() {
12428
- if (this.nameSecondary) {
12429
- return new ImageIdWithOptions(this.nameSecondary, { params: this.optionsSecondary ? this.optionsSecondary.params || {} : {} });
12641
+ if (!this.secondaryId) {
12642
+ return null;
12430
12643
  }
12431
- return null;
12644
+ return new ImageVariant(this.secondaryId, this.secondaryOptions);
12432
12645
  }
12433
12646
  static from(image) {
12434
- return typeof image === 'string' ? ResolvedImage.build(image) : image;
12647
+ return typeof image === 'string' ? ResolvedImage.build({ name: image }) : image;
12435
12648
  }
12436
- static build(namePrimary, nameSecondary, optionsPrimary, optionsSecondary) {
12437
- if (!namePrimary)
12649
+ static build(primaryId, secondaryId, primaryOptions, secondaryOptions) {
12650
+ if (!primaryId || typeof primaryId === 'object' && !('name' in primaryId))
12438
12651
  return null;
12439
- return new ResolvedImage({
12440
- namePrimary,
12441
- nameSecondary,
12442
- optionsPrimary,
12443
- optionsSecondary,
12444
- available: false
12445
- });
12652
+ return new ResolvedImage(primaryId, primaryOptions, secondaryId, secondaryOptions);
12446
12653
  }
12447
12654
  }
12448
12655
 
@@ -12836,19 +13043,22 @@ class FormatExpression {
12836
13043
  }
12837
13044
 
12838
13045
  function isImageOptions(value) {
12839
- if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
12840
- return true;
12841
- }
12842
- return false;
13046
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
12843
13047
  }
12844
13048
  class ImageExpression {
12845
- constructor(inputPrimary, inputSecondary, inputPrimaryParams, inputSecondaryParams) {
13049
+ constructor(inputPrimary, inputSecondary, inputPrimaryOptions, inputSecondaryOptions) {
12846
13050
  this._imageWarnHistory = {};
12847
13051
  this.type = ResolvedImageType;
12848
- this.inputPrimary = inputPrimary;
12849
- this.inputSecondary = inputSecondary;
12850
- this.inputPrimaryParams = inputPrimaryParams;
12851
- this.inputSecondaryParams = inputSecondaryParams;
13052
+ this.namePrimary = inputPrimary;
13053
+ this.nameSecondary = inputSecondary;
13054
+ if (inputPrimaryOptions) {
13055
+ this.paramsPrimary = inputPrimaryOptions.params;
13056
+ this.iconsetIdPrimary = inputPrimaryOptions.iconset ? inputPrimaryOptions.iconset.id : void 0;
13057
+ }
13058
+ if (inputSecondaryOptions) {
13059
+ this.paramsSecondary = inputSecondaryOptions.params;
13060
+ this.iconsetIdSecondary = inputSecondaryOptions.iconset ? inputSecondaryOptions.iconset.id : void 0;
13061
+ }
12852
13062
  }
12853
13063
  static parse(args, context) {
12854
13064
  if (args.length < 2) {
@@ -12865,7 +13075,7 @@ class ImageExpression {
12865
13075
  }
12866
13076
  imageExpression.push({
12867
13077
  image: imageName,
12868
- options: void 0
13078
+ options: {}
12869
13079
  });
12870
13080
  return true;
12871
13081
  }
@@ -12873,33 +13083,48 @@ class ImageExpression {
12873
13083
  }
12874
13084
  function tryParseOptions() {
12875
13085
  if (nextArgId < args.length) {
12876
- if (!isImageOptions(args[nextArgId])) {
13086
+ const options = args[nextArgId];
13087
+ if (!isImageOptions(options)) {
12877
13088
  return true;
12878
13089
  }
12879
- const params = args[nextArgId].params;
13090
+ const params = options.params;
13091
+ const iconset = options.iconset;
12880
13092
  const optionsContext = context.concat(nextArgId);
12881
- if (!params) {
13093
+ if (!params && !iconset) {
12882
13094
  nextArgId++;
12883
13095
  return true;
12884
13096
  }
12885
- if (typeof params !== 'object' || params.constructor !== Object) {
12886
- optionsContext.error(`Image options "params" should be an object`);
12887
- return false;
13097
+ if (params) {
13098
+ if (typeof params !== 'object' || params.constructor !== Object) {
13099
+ optionsContext.error(`Image options "params" should be an object`);
13100
+ return false;
13101
+ }
13102
+ const parsedParams = {};
13103
+ const childContext = optionsContext.concat(void 0, 'params');
13104
+ for (const key in params) {
13105
+ if (!key) {
13106
+ childContext.error(`Image parameter name should be non-empty`);
13107
+ return false;
13108
+ }
13109
+ const value = childContext.concat(void 0, key).parse(params[key], void 0, ColorType, void 0, { typeAnnotation: 'coerce' });
13110
+ if (!value) {
13111
+ return false;
13112
+ }
13113
+ parsedParams[key] = value;
13114
+ }
13115
+ imageExpression[imageExpression.length - 1].options.params = parsedParams;
12888
13116
  }
12889
- const parsed = {};
12890
- const childContext = optionsContext.concat(void 0, 'params');
12891
- for (const key in params) {
12892
- if (!key) {
12893
- childContext.error(`Image parameter name should be non-empty`);
13117
+ if (iconset) {
13118
+ if (typeof iconset !== 'object' || iconset.constructor !== Object) {
13119
+ optionsContext.error(`Image options "iconset" should be an object`);
12894
13120
  return false;
12895
13121
  }
12896
- const value = childContext.concat(void 0, key).parse(params[key], void 0, ColorType, void 0, { typeAnnotation: 'coerce' });
12897
- if (!value) {
13122
+ if (!iconset.id) {
13123
+ optionsContext.error(`Image options "iconset" should have an "id" property`);
12898
13124
  return false;
12899
13125
  }
12900
- parsed[key] = value;
13126
+ imageExpression[imageExpression.length - 1].options.iconset = iconset;
12901
13127
  }
12902
- imageExpression[imageExpression.length - 1].options = parsed;
12903
13128
  nextArgId++;
12904
13129
  return true;
12905
13130
  }
@@ -12942,30 +13167,41 @@ class ImageExpression {
12942
13167
  return { params: result };
12943
13168
  }
12944
13169
  evaluate(ctx) {
12945
- const value = ResolvedImage.build(this.inputPrimary.evaluate(ctx), this.inputSecondary ? this.inputSecondary.evaluate(ctx) : void 0, this.inputPrimaryParams ? this.evaluateParams(ctx, this.inputPrimaryParams) : void 0, this.inputSecondaryParams ? this.evaluateParams(ctx, this.inputSecondaryParams) : void 0);
13170
+ const primaryId = {
13171
+ name: this.namePrimary.evaluate(ctx),
13172
+ iconsetId: this.iconsetIdPrimary
13173
+ };
13174
+ const secondaryId = this.nameSecondary ? {
13175
+ name: this.nameSecondary.evaluate(ctx),
13176
+ iconsetId: this.iconsetIdSecondary
13177
+ } : void 0;
13178
+ const value = ResolvedImage.build(primaryId, secondaryId, this.paramsPrimary ? this.evaluateParams(ctx, this.paramsPrimary) : void 0, this.paramsSecondary ? this.evaluateParams(ctx, this.paramsSecondary) : void 0);
12946
13179
  if (value && ctx.availableImages) {
12947
- value.available = ctx.availableImages.indexOf(value.namePrimary) > -1;
12948
- if (value.nameSecondary && value.available && ctx.availableImages) {
12949
- value.available = ctx.availableImages.indexOf(value.nameSecondary) > -1;
13180
+ const primaryId2 = value.getPrimary().id;
13181
+ value.available = ctx.availableImages.some(id => ImageId.isEqual(id, primaryId2));
13182
+ if (value.available) {
13183
+ const secondaryId2 = value.getSecondary() ? value.getSecondary().id : null;
13184
+ if (secondaryId2)
13185
+ value.available = ctx.availableImages.some(id => ImageId.isEqual(id, secondaryId2));
12950
13186
  }
12951
13187
  }
12952
13188
  return value;
12953
13189
  }
12954
13190
  eachChild(fn) {
12955
- fn(this.inputPrimary);
12956
- if (this.inputPrimaryParams) {
12957
- for (const key in this.inputPrimaryParams) {
12958
- if (this.inputPrimaryParams[key]) {
12959
- fn(this.inputPrimaryParams[key]);
13191
+ fn(this.namePrimary);
13192
+ if (this.paramsPrimary) {
13193
+ for (const key in this.paramsPrimary) {
13194
+ if (this.paramsPrimary[key]) {
13195
+ fn(this.paramsPrimary[key]);
12960
13196
  }
12961
13197
  }
12962
13198
  }
12963
- if (this.inputSecondary) {
12964
- fn(this.inputSecondary);
12965
- if (this.inputSecondaryParams) {
12966
- for (const key in this.inputSecondaryParams) {
12967
- if (this.inputSecondaryParams[key]) {
12968
- fn(this.inputSecondaryParams[key]);
13199
+ if (this.nameSecondary) {
13200
+ fn(this.nameSecondary);
13201
+ if (this.paramsSecondary) {
13202
+ for (const key in this.paramsSecondary) {
13203
+ if (this.paramsSecondary[key]) {
13204
+ fn(this.paramsSecondary[key]);
12969
13205
  }
12970
13206
  }
12971
13207
  }
@@ -12974,31 +13210,37 @@ class ImageExpression {
12974
13210
  outputDefined() {
12975
13211
  return false;
12976
13212
  }
12977
- serializeParams(params) {
13213
+ serializeOptions(params, iconsetId) {
12978
13214
  const result = {};
13215
+ if (iconsetId) {
13216
+ result.iconset = { id: iconsetId };
13217
+ }
12979
13218
  if (params) {
13219
+ result.params = {};
12980
13220
  for (const key in params) {
12981
13221
  if (params[key]) {
12982
- result[key] = params[key].serialize();
13222
+ result.params[key] = params[key].serialize();
12983
13223
  }
12984
13224
  }
12985
- } else {
12986
- return void 0;
12987
13225
  }
12988
- return { params: result };
13226
+ return Object.keys(result).length > 0 ? result : void 0;
12989
13227
  }
12990
13228
  serialize() {
12991
13229
  const serialized = [
12992
13230
  'image',
12993
- this.inputPrimary.serialize()
13231
+ this.namePrimary.serialize()
12994
13232
  ];
12995
- if (this.inputPrimaryParams) {
12996
- serialized.push(this.serializeParams(this.inputPrimaryParams));
13233
+ if (this.paramsPrimary || this.iconsetIdPrimary) {
13234
+ const options = this.serializeOptions(this.paramsPrimary, this.iconsetIdPrimary);
13235
+ if (options)
13236
+ serialized.push(options);
12997
13237
  }
12998
- if (this.inputSecondary) {
12999
- serialized.push(this.inputSecondary.serialize());
13000
- if (this.inputSecondaryParams) {
13001
- serialized.push(this.serializeParams(this.inputSecondaryParams));
13238
+ if (this.nameSecondary) {
13239
+ serialized.push(this.nameSecondary.serialize());
13240
+ if (this.paramsSecondary || this.iconsetIdSecondary) {
13241
+ const options = this.serializeOptions(this.paramsSecondary, this.iconsetIdSecondary);
13242
+ if (options)
13243
+ serialized.push(options);
13002
13244
  }
13003
13245
  }
13004
13246
  return serialized;
@@ -14436,12 +14678,8 @@ function pointsToLineDistance(points, rangeA, line, rangeB, ruler) {
14436
14678
  return dist;
14437
14679
  }
14438
14680
  function segmentToSegmentDistance(p1, p2, q1, q2, ruler) {
14439
- const dist1 = Math.min(// @ts-expect-error - TS2345 - Argument of type 'Position' is not assignable to parameter of type 'Point'.
14440
- ruler.pointToSegmentDistance(p1, q1, q2), // @ts-expect-error - TS2345 - Argument of type 'Position' is not assignable to parameter of type 'Point'.
14441
- ruler.pointToSegmentDistance(p2, q1, q2));
14442
- const dist2 = Math.min(// @ts-expect-error - TS2345 - Argument of type 'Position' is not assignable to parameter of type 'Point'.
14443
- ruler.pointToSegmentDistance(q1, p1, p2), // @ts-expect-error - TS2345 - Argument of type 'Position' is not assignable to parameter of type 'Point'.
14444
- ruler.pointToSegmentDistance(q2, p1, p2));
14681
+ const dist1 = Math.min(ruler.pointToSegmentDistance(p1, q1, q2), ruler.pointToSegmentDistance(p2, q1, q2));
14682
+ const dist2 = Math.min(ruler.pointToSegmentDistance(q1, p1, p2), ruler.pointToSegmentDistance(q2, p1, p2));
14445
14683
  return Math.min(dist1, dist2);
14446
14684
  }
14447
14685
  function lineToLineDistance(line1, range1, line2, range2, ruler) {
@@ -15541,12 +15779,11 @@ var colorSpaces = /*#__PURE__*/Object.freeze({
15541
15779
  });
15542
15780
 
15543
15781
  class Interpolate {
15544
- constructor(type, operator, interpolation, input, dynamicStops, stops) {
15782
+ constructor(type, operator, interpolation, input, stops) {
15545
15783
  this.type = type;
15546
15784
  this.operator = operator;
15547
15785
  this.interpolation = interpolation;
15548
15786
  this.input = input;
15549
- this.dynamicStops = dynamicStops;
15550
15787
  this.labels = [];
15551
15788
  this.outputs = [];
15552
15789
  for (const [label, expression] of stops) {
@@ -15594,8 +15831,8 @@ class Interpolate {
15594
15831
  } else {
15595
15832
  return context.error(`Unknown interpolation type ${ String(interpolation[0]) }`, 1, 0);
15596
15833
  }
15597
- if (args.length - 1 < 3) {
15598
- return context.error(`Expected at least 3 arguments, but found only ${ args.length - 1 }.`);
15834
+ if (args.length - 1 < 4) {
15835
+ return context.error(`Expected at least 4 arguments, but found only ${ args.length - 1 }.`);
15599
15836
  }
15600
15837
  if (args.length - 1 > 3 && (args.length - 1) % 2 !== 0) {
15601
15838
  return context.error(`Expected an even number of arguments.`);
@@ -15610,12 +15847,6 @@ class Interpolate {
15610
15847
  } else if (context.expectedType && context.expectedType.kind !== 'value') {
15611
15848
  outputType = context.expectedType;
15612
15849
  }
15613
- if (args.length - 1 === 3) {
15614
- const dynamicStops = context.parse(rest[0], 3, ValueType);
15615
- if (!dynamicStops)
15616
- return null;
15617
- return new Interpolate(outputType, operator, interpolation, input, dynamicStops, stops);
15618
- }
15619
15850
  for (let i = 0; i < rest.length; i += 2) {
15620
15851
  const label = rest[i];
15621
15852
  const value = rest[i + 1];
@@ -15639,34 +15870,11 @@ class Interpolate {
15639
15870
  if (outputType.kind !== 'number' && outputType.kind !== 'color' && !(outputType.kind === 'array' && outputType.itemType.kind === 'number' && typeof outputType.N === 'number')) {
15640
15871
  return context.error(`Type ${ toString$1(outputType) } is not interpolatable.`);
15641
15872
  }
15642
- return new Interpolate(outputType, operator, interpolation, input, null, stops);
15873
+ return new Interpolate(outputType, operator, interpolation, input, stops);
15643
15874
  }
15644
15875
  evaluate(ctx) {
15645
- let labels = this.labels;
15646
- let outputs = this.outputs;
15647
- if (this.dynamicStops) {
15648
- const dynamicStopsValue = this.dynamicStops.evaluate(ctx);
15649
- if (dynamicStopsValue.length % 2 !== 0) {
15650
- throw new RuntimeError('Expected an even number of arguments.');
15651
- }
15652
- labels = [];
15653
- outputs = [];
15654
- for (let i = 0; i < dynamicStopsValue.length; i += 2) {
15655
- const label = dynamicStopsValue[i];
15656
- const output = new Literal(NumberType, dynamicStopsValue[i + 1]);
15657
- if (typeof label !== 'number') {
15658
- throw new RuntimeError('Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.');
15659
- }
15660
- if (labels.length && labels[labels.length - 1] >= label) {
15661
- throw new RuntimeError('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.');
15662
- }
15663
- labels.push(label);
15664
- outputs.push(output);
15665
- }
15666
- if (labels.length === 0) {
15667
- throw new RuntimeError('Expected at least one input/output pair.');
15668
- }
15669
- }
15876
+ const labels = this.labels;
15877
+ const outputs = this.outputs;
15670
15878
  if (labels.length === 1) {
15671
15879
  return outputs[0].evaluate(ctx);
15672
15880
  }
@@ -15715,19 +15923,18 @@ class Interpolate {
15715
15923
  ];
15716
15924
  }
15717
15925
  } else {
15718
- interpolation = ['cubic-bezier'].concat(this.interpolation.controlPoints);
15926
+ interpolation = [
15927
+ 'cubic-bezier',
15928
+ ...this.interpolation.controlPoints
15929
+ ];
15719
15930
  }
15720
15931
  const serialized = [
15721
15932
  this.operator,
15722
15933
  interpolation,
15723
15934
  this.input.serialize()
15724
15935
  ];
15725
- if (this.dynamicStops) {
15726
- serialized.push(this.dynamicStops.serialize());
15727
- } else {
15728
- for (let i = 0; i < this.labels.length; i++) {
15729
- serialized.push(this.labels[i], this.outputs[i].serialize());
15730
- }
15936
+ for (let i = 0; i < this.labels.length; i++) {
15937
+ serialized.push(this.labels[i], this.outputs[i].serialize());
15731
15938
  }
15732
15939
  return serialized;
15733
15940
  }
@@ -15874,6 +16081,52 @@ class At {
15874
16081
  const t = input.type;
15875
16082
  return new At(t.itemType, index, input);
15876
16083
  }
16084
+ evaluate(ctx) {
16085
+ const index = this.index.evaluate(ctx);
16086
+ const array2 = this.input.evaluate(ctx);
16087
+ if (index < 0) {
16088
+ throw new RuntimeError(`Array index out of bounds: ${ index } < 0.`);
16089
+ }
16090
+ if (index >= array2.length) {
16091
+ throw new RuntimeError(`Array index out of bounds: ${ index } > ${ array2.length - 1 }.`);
16092
+ }
16093
+ if (index !== Math.floor(index)) {
16094
+ throw new RuntimeError(`Array index must be an integer, but found ${ index } instead. Use at-interpolated to retrieve interpolated result with a fractional index.`);
16095
+ }
16096
+ return array2[index];
16097
+ }
16098
+ eachChild(fn) {
16099
+ fn(this.index);
16100
+ fn(this.input);
16101
+ }
16102
+ outputDefined() {
16103
+ return false;
16104
+ }
16105
+ serialize() {
16106
+ return [
16107
+ 'at',
16108
+ this.index.serialize(),
16109
+ this.input.serialize()
16110
+ ];
16111
+ }
16112
+ }
16113
+
16114
+ class AtInterpolated {
16115
+ constructor(type, index, input) {
16116
+ this.type = type;
16117
+ this.index = index;
16118
+ this.input = input;
16119
+ }
16120
+ static parse(args, context) {
16121
+ if (args.length !== 3)
16122
+ return context.error(`Expected 2 arguments, but found ${ args.length - 1 } instead.`);
16123
+ const index = context.parse(args[1], 1, NumberType);
16124
+ const input = context.parse(args[2], 2, array$1(context.expectedType || ValueType));
16125
+ if (!index || !input)
16126
+ return null;
16127
+ const t = input.type;
16128
+ return new AtInterpolated(t.itemType, index, input);
16129
+ }
15877
16130
  evaluate(ctx) {
15878
16131
  const index = this.index.evaluate(ctx);
15879
16132
  const array2 = this.input.evaluate(ctx);
@@ -15905,7 +16158,7 @@ class At {
15905
16158
  }
15906
16159
  serialize() {
15907
16160
  return [
15908
- 'at',
16161
+ 'at-interpolated',
15909
16162
  this.index.serialize(),
15910
16163
  this.input.serialize()
15911
16164
  ];
@@ -16607,6 +16860,7 @@ const expressions = {
16607
16860
  '<=': LessThanOrEqual,
16608
16861
  'array': Assertion,
16609
16862
  'at': At,
16863
+ 'at-interpolated': AtInterpolated,
16610
16864
  'boolean': Assertion,
16611
16865
  'case': Case,
16612
16866
  'coalesce': Coalesce,
@@ -17641,14 +17895,10 @@ function createPropertyExpression(expression, propertySpec, scope, options) {
17641
17895
  return error([new ParsingError$1('', '"interpolate" expressions cannot be used with this property')]);
17642
17896
  }
17643
17897
  if (!zoomCurve) {
17644
- return success(isFeatureConstant$1 && isLineProgressConstant ? // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
17645
- new ZoomConstantExpression('constant', expression.value, isLightConstant, isLineProgressConstant) : // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
17646
- new ZoomConstantExpression('source', expression.value, isLightConstant, isLineProgressConstant));
17898
+ return success(isFeatureConstant$1 && isLineProgressConstant ? new ZoomConstantExpression('constant', expression.value, isLightConstant, isLineProgressConstant) : new ZoomConstantExpression('source', expression.value, isLightConstant, isLineProgressConstant));
17647
17899
  }
17648
17900
  const interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : void 0;
17649
- return success(isFeatureConstant$1 && isLineProgressConstant ? // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
17650
- new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType, isLightConstant, isLineProgressConstant) : // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
17651
- new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType, isLightConstant, isLineProgressConstant));
17901
+ return success(isFeatureConstant$1 && isLineProgressConstant ? new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType, isLightConstant, isLineProgressConstant) : new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType, isLightConstant, isLineProgressConstant));
17652
17902
  }
17653
17903
  class StylePropertyFunction {
17654
17904
  constructor(parameters, specification) {
@@ -19987,7 +20237,6 @@ function validateLayer(options) {
19987
20237
  valueSpec: styleSpec.layer.type,
19988
20238
  style: options.style,
19989
20239
  styleSpec: options.styleSpec,
19990
- // @ts-expect-error - TS2353 - Object literal may only specify known properties, and 'object' does not exist in type 'ValidationOptions'.
19991
20240
  object: layer,
19992
20241
  objectKey: 'type'
19993
20242
  });
@@ -19997,7 +20246,6 @@ function validateLayer(options) {
19997
20246
  },
19998
20247
  layout(options2) {
19999
20248
  return validateObject({
20000
- // @ts-expect-error - TS2353 - Object literal may only specify known properties, and 'layer' does not exist in type 'Options'.
20001
20249
  layer,
20002
20250
  key: options2.key,
20003
20251
  value: options2.value,
@@ -20013,7 +20261,6 @@ function validateLayer(options) {
20013
20261
  },
20014
20262
  paint(options2) {
20015
20263
  return validateObject({
20016
- // @ts-expect-error - TS2353 - Object literal may only specify known properties, and 'layer' does not exist in type 'Options'.
20017
20264
  layer,
20018
20265
  key: options2.key,
20019
20266
  value: options2.value,
@@ -20509,6 +20756,35 @@ function validateProjection(options) {
20509
20756
  return errors;
20510
20757
  }
20511
20758
 
20759
+ function validateIconset(options) {
20760
+ const iconset = options.value;
20761
+ const key = options.key;
20762
+ const styleSpec = options.styleSpec;
20763
+ const style = options.style;
20764
+ if (!iconset.type) {
20765
+ return [new ValidationError(key, iconset, '"type" is required')];
20766
+ }
20767
+ const type = unbundle(iconset.type);
20768
+ let errors = [];
20769
+ errors = errors.concat(validateObject({
20770
+ key,
20771
+ value: iconset,
20772
+ valueSpec: styleSpec[`iconset_${ type }`],
20773
+ style,
20774
+ styleSpec
20775
+ }));
20776
+ if (type === 'source' && iconset.source) {
20777
+ const source = style.sources && style.sources[iconset.source];
20778
+ const sourceType = source && unbundle(source.type);
20779
+ if (!source) {
20780
+ errors.push(new ValidationError(key, iconset.source, `source "${ iconset.source }" not found`));
20781
+ } else if (sourceType !== 'raster-array') {
20782
+ errors.push(new ValidationError(key, iconset.source, `iconset cannot be used with a source of type ${ String(sourceType) }, it only be used with a "raster-array" source type`));
20783
+ }
20784
+ }
20785
+ return errors;
20786
+ }
20787
+
20512
20788
  const VALIDATORS = {
20513
20789
  '*'() {
20514
20790
  return [];
@@ -20532,7 +20808,8 @@ const VALIDATORS = {
20532
20808
  'formatted': validateFormatted,
20533
20809
  'resolvedImage': validateImage,
20534
20810
  'projection': validateProjection,
20535
- 'import': validateImport
20811
+ 'import': validateImport,
20812
+ 'iconset': validateIconset
20536
20813
  };
20537
20814
  function validate(options, arrayAsExpression = false) {
20538
20815
  const value = options.value;
@@ -20577,7 +20854,6 @@ function validateStyle$2(style, styleSpec = v8, options = {}) {
20577
20854
  valueSpec: styleSpec.$root,
20578
20855
  styleSpec,
20579
20856
  style,
20580
- // @ts-expect-error - TS2353 - Object literal may only specify known properties, and 'objectElementValidators' does not exist in type 'ValidationOptions'.
20581
20857
  objectElementValidators: {
20582
20858
  glyphs: validateGlyphsURL,
20583
20859
  '*': () => []