@honua/sdk-esri-compat 0.0.6-alpha.0

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 (289) hide show
  1. package/README.md +5 -0
  2. package/contract/edit-session.d.ts +203 -0
  3. package/contract/edit-session.d.ts.map +1 -0
  4. package/contract/edit-session.js +717 -0
  5. package/contract/index.d.ts +20 -0
  6. package/contract/index.d.ts.map +1 -0
  7. package/contract/index.js +15 -0
  8. package/contract/jobs.d.ts +115 -0
  9. package/contract/jobs.d.ts.map +1 -0
  10. package/contract/jobs.js +22 -0
  11. package/contract/source.d.ts +138 -0
  12. package/contract/source.d.ts.map +1 -0
  13. package/contract/source.js +3364 -0
  14. package/contract/spatial-aggregation.d.ts +312 -0
  15. package/contract/spatial-aggregation.d.ts.map +1 -0
  16. package/contract/spatial-aggregation.js +196 -0
  17. package/contract/types.d.ts +542 -0
  18. package/contract/types.d.ts.map +1 -0
  19. package/contract/types.js +171 -0
  20. package/core/batch.d.ts +37 -0
  21. package/core/batch.d.ts.map +1 -0
  22. package/core/batch.js +78 -0
  23. package/core/cache-state.d.ts +76 -0
  24. package/core/cache-state.d.ts.map +1 -0
  25. package/core/cache-state.js +84 -0
  26. package/core/client.d.ts +289 -0
  27. package/core/client.d.ts.map +1 -0
  28. package/core/client.js +2625 -0
  29. package/core/errors.d.ts +68 -0
  30. package/core/errors.d.ts.map +1 -0
  31. package/core/errors.js +116 -0
  32. package/core/grpc-adapter.d.ts +23 -0
  33. package/core/grpc-adapter.d.ts.map +1 -0
  34. package/core/grpc-adapter.js +704 -0
  35. package/core/odata.d.ts +347 -0
  36. package/core/odata.d.ts.map +1 -0
  37. package/core/odata.js +837 -0
  38. package/core/ogc-conformance.d.ts +35 -0
  39. package/core/ogc-conformance.d.ts.map +1 -0
  40. package/core/ogc-conformance.js +121 -0
  41. package/core/ogc-maps.d.ts +45 -0
  42. package/core/ogc-maps.d.ts.map +1 -0
  43. package/core/ogc-maps.js +53 -0
  44. package/core/ogc-processes.d.ts +92 -0
  45. package/core/ogc-processes.d.ts.map +1 -0
  46. package/core/ogc-processes.js +325 -0
  47. package/core/ogc-tiles.d.ts +55 -0
  48. package/core/ogc-tiles.d.ts.map +1 -0
  49. package/core/ogc-tiles.js +81 -0
  50. package/core/pbf-decoder.d.ts +28 -0
  51. package/core/pbf-decoder.d.ts.map +1 -0
  52. package/core/pbf-decoder.js +627 -0
  53. package/core/query-builder.d.ts +261 -0
  54. package/core/query-builder.d.ts.map +1 -0
  55. package/core/query-builder.js +538 -0
  56. package/core/spatial-filter.d.ts +93 -0
  57. package/core/spatial-filter.d.ts.map +1 -0
  58. package/core/spatial-filter.js +153 -0
  59. package/core/stac.d.ts +43 -0
  60. package/core/stac.d.ts.map +1 -0
  61. package/core/stac.js +116 -0
  62. package/core/surfaces.d.ts +464 -0
  63. package/core/surfaces.d.ts.map +1 -0
  64. package/core/surfaces.js +1322 -0
  65. package/core/types.d.ts +1238 -0
  66. package/core/types.d.ts.map +1 -0
  67. package/core/types.js +13 -0
  68. package/core/wfs-capabilities.d.ts +143 -0
  69. package/core/wfs-capabilities.d.ts.map +1 -0
  70. package/core/wfs-capabilities.js +478 -0
  71. package/core/wfs-filter.d.ts +118 -0
  72. package/core/wfs-filter.d.ts.map +1 -0
  73. package/core/wfs-filter.js +586 -0
  74. package/core/wfs.d.ts +219 -0
  75. package/core/wfs.d.ts.map +1 -0
  76. package/core/wfs.js +406 -0
  77. package/core/wms-capabilities.d.ts +110 -0
  78. package/core/wms-capabilities.d.ts.map +1 -0
  79. package/core/wms-capabilities.js +566 -0
  80. package/core/wms-types.d.ts +128 -0
  81. package/core/wms-types.d.ts.map +1 -0
  82. package/core/wms-types.js +32 -0
  83. package/core/wms.d.ts +108 -0
  84. package/core/wms.d.ts.map +1 -0
  85. package/core/wms.js +182 -0
  86. package/core/wmts-capabilities.d.ts +82 -0
  87. package/core/wmts-capabilities.d.ts.map +1 -0
  88. package/core/wmts-capabilities.js +409 -0
  89. package/core/wmts.d.ts +80 -0
  90. package/core/wmts.d.ts.map +1 -0
  91. package/core/wmts.js +173 -0
  92. package/esri-compat/basemap-gallery.d.ts +38 -0
  93. package/esri-compat/basemap-gallery.d.ts.map +1 -0
  94. package/esri-compat/basemap-gallery.js +159 -0
  95. package/esri-compat/basemap-layer-list.d.ts +35 -0
  96. package/esri-compat/basemap-layer-list.d.ts.map +1 -0
  97. package/esri-compat/basemap-layer-list.js +139 -0
  98. package/esri-compat/basemap.d.ts +32 -0
  99. package/esri-compat/basemap.d.ts.map +1 -0
  100. package/esri-compat/basemap.js +84 -0
  101. package/esri-compat/bookmarks.d.ts +36 -0
  102. package/esri-compat/bookmarks.d.ts.map +1 -0
  103. package/esri-compat/bookmarks.js +108 -0
  104. package/esri-compat/class-breaks-renderer.d.ts +50 -0
  105. package/esri-compat/class-breaks-renderer.d.ts.map +1 -0
  106. package/esri-compat/class-breaks-renderer.js +164 -0
  107. package/esri-compat/color.d.ts +22 -0
  108. package/esri-compat/color.d.ts.map +1 -0
  109. package/esri-compat/color.js +106 -0
  110. package/esri-compat/controls.d.ts +174 -0
  111. package/esri-compat/controls.d.ts.map +1 -0
  112. package/esri-compat/controls.js +479 -0
  113. package/esri-compat/coordinate-conversion.d.ts +41 -0
  114. package/esri-compat/coordinate-conversion.d.ts.map +1 -0
  115. package/esri-compat/coordinate-conversion.js +125 -0
  116. package/esri-compat/directions.d.ts +45 -0
  117. package/esri-compat/directions.d.ts.map +1 -0
  118. package/esri-compat/directions.js +123 -0
  119. package/esri-compat/editor.d.ts +47 -0
  120. package/esri-compat/editor.d.ts.map +1 -0
  121. package/esri-compat/editor.js +170 -0
  122. package/esri-compat/esri-config.d.ts +16 -0
  123. package/esri-compat/esri-config.d.ts.map +1 -0
  124. package/esri-compat/esri-config.js +23 -0
  125. package/esri-compat/esri-request.d.ts +17 -0
  126. package/esri-compat/esri-request.d.ts.map +1 -0
  127. package/esri-compat/esri-request.js +66 -0
  128. package/esri-compat/event-bus.d.ts +106 -0
  129. package/esri-compat/event-bus.d.ts.map +1 -0
  130. package/esri-compat/event-bus.js +90 -0
  131. package/esri-compat/expand.d.ts +36 -0
  132. package/esri-compat/expand.d.ts.map +1 -0
  133. package/esri-compat/expand.js +97 -0
  134. package/esri-compat/extent.d.ts +43 -0
  135. package/esri-compat/extent.d.ts.map +1 -0
  136. package/esri-compat/extent.js +140 -0
  137. package/esri-compat/feature-form.d.ts +64 -0
  138. package/esri-compat/feature-form.d.ts.map +1 -0
  139. package/esri-compat/feature-form.js +137 -0
  140. package/esri-compat/feature-layer.d.ts +173 -0
  141. package/esri-compat/feature-layer.d.ts.map +1 -0
  142. package/esri-compat/feature-layer.js +655 -0
  143. package/esri-compat/feature-set.d.ts +32 -0
  144. package/esri-compat/feature-set.d.ts.map +1 -0
  145. package/esri-compat/feature-set.js +80 -0
  146. package/esri-compat/feature-table.d.ts +141 -0
  147. package/esri-compat/feature-table.d.ts.map +1 -0
  148. package/esri-compat/feature-table.js +500 -0
  149. package/esri-compat/feature-templates.d.ts +41 -0
  150. package/esri-compat/feature-templates.d.ts.map +1 -0
  151. package/esri-compat/feature-templates.js +97 -0
  152. package/esri-compat/feature.d.ts +33 -0
  153. package/esri-compat/feature.d.ts.map +1 -0
  154. package/esri-compat/feature.js +83 -0
  155. package/esri-compat/graphic.d.ts +46 -0
  156. package/esri-compat/graphic.d.ts.map +1 -0
  157. package/esri-compat/graphic.js +103 -0
  158. package/esri-compat/graphics-layer.d.ts +49 -0
  159. package/esri-compat/graphics-layer.d.ts.map +1 -0
  160. package/esri-compat/graphics-layer.js +185 -0
  161. package/esri-compat/group-layer.d.ts +48 -0
  162. package/esri-compat/group-layer.d.ts.map +1 -0
  163. package/esri-compat/group-layer.js +212 -0
  164. package/esri-compat/identify.d.ts +71 -0
  165. package/esri-compat/identify.d.ts.map +1 -0
  166. package/esri-compat/identify.js +299 -0
  167. package/esri-compat/identity-manager.d.ts +31 -0
  168. package/esri-compat/identity-manager.d.ts.map +1 -0
  169. package/esri-compat/identity-manager.js +115 -0
  170. package/esri-compat/label-class.d.ts +31 -0
  171. package/esri-compat/label-class.d.ts.map +1 -0
  172. package/esri-compat/label-class.js +102 -0
  173. package/esri-compat/layer-list.d.ts +77 -0
  174. package/esri-compat/layer-list.d.ts.map +1 -0
  175. package/esri-compat/layer-list.js +342 -0
  176. package/esri-compat/legend.d.ts +53 -0
  177. package/esri-compat/legend.d.ts.map +1 -0
  178. package/esri-compat/legend.js +254 -0
  179. package/esri-compat/map-image-layer.d.ts +162 -0
  180. package/esri-compat/map-image-layer.d.ts.map +1 -0
  181. package/esri-compat/map-image-layer.js +704 -0
  182. package/esri-compat/map-view.d.ts +315 -0
  183. package/esri-compat/map-view.d.ts.map +1 -0
  184. package/esri-compat/map-view.js +1110 -0
  185. package/esri-compat/map.d.ts +47 -0
  186. package/esri-compat/map.d.ts.map +1 -0
  187. package/esri-compat/map.js +209 -0
  188. package/esri-compat/measurement-2d.d.ts +61 -0
  189. package/esri-compat/measurement-2d.d.ts.map +1 -0
  190. package/esri-compat/measurement-2d.js +184 -0
  191. package/esri-compat/measurement.d.ts +45 -0
  192. package/esri-compat/measurement.d.ts.map +1 -0
  193. package/esri-compat/measurement.js +193 -0
  194. package/esri-compat/oauth-info.d.ts +35 -0
  195. package/esri-compat/oauth-info.d.ts.map +1 -0
  196. package/esri-compat/oauth-info.js +115 -0
  197. package/esri-compat/picture-marker-symbol.d.ts +35 -0
  198. package/esri-compat/picture-marker-symbol.d.ts.map +1 -0
  199. package/esri-compat/picture-marker-symbol.js +126 -0
  200. package/esri-compat/point.d.ts +31 -0
  201. package/esri-compat/point.d.ts.map +1 -0
  202. package/esri-compat/point.js +102 -0
  203. package/esri-compat/polygon.d.ts +31 -0
  204. package/esri-compat/polygon.d.ts.map +1 -0
  205. package/esri-compat/polygon.js +107 -0
  206. package/esri-compat/polyline.d.ts +31 -0
  207. package/esri-compat/polyline.d.ts.map +1 -0
  208. package/esri-compat/polyline.js +107 -0
  209. package/esri-compat/popup-template.d.ts +55 -0
  210. package/esri-compat/popup-template.d.ts.map +1 -0
  211. package/esri-compat/popup-template.js +128 -0
  212. package/esri-compat/popup.d.ts +54 -0
  213. package/esri-compat/popup.d.ts.map +1 -0
  214. package/esri-compat/popup.js +312 -0
  215. package/esri-compat/print.d.ts +47 -0
  216. package/esri-compat/print.d.ts.map +1 -0
  217. package/esri-compat/print.js +105 -0
  218. package/esri-compat/query.d.ts +46 -0
  219. package/esri-compat/query.d.ts.map +1 -0
  220. package/esri-compat/query.js +119 -0
  221. package/esri-compat/reactive-utils.d.ts +23 -0
  222. package/esri-compat/reactive-utils.d.ts.map +1 -0
  223. package/esri-compat/reactive-utils.js +178 -0
  224. package/esri-compat/request.d.ts +41 -0
  225. package/esri-compat/request.d.ts.map +1 -0
  226. package/esri-compat/request.js +253 -0
  227. package/esri-compat/route-layer.d.ts +59 -0
  228. package/esri-compat/route-layer.d.ts.map +1 -0
  229. package/esri-compat/route-layer.js +223 -0
  230. package/esri-compat/route-task.d.ts +88 -0
  231. package/esri-compat/route-task.d.ts.map +1 -0
  232. package/esri-compat/route-task.js +225 -0
  233. package/esri-compat/scene-view.d.ts +41 -0
  234. package/esri-compat/scene-view.d.ts.map +1 -0
  235. package/esri-compat/scene-view.js +68 -0
  236. package/esri-compat/search.d.ts +112 -0
  237. package/esri-compat/search.d.ts.map +1 -0
  238. package/esri-compat/search.js +820 -0
  239. package/esri-compat/simple-fill-symbol.d.ts +27 -0
  240. package/esri-compat/simple-fill-symbol.d.ts.map +1 -0
  241. package/esri-compat/simple-fill-symbol.js +85 -0
  242. package/esri-compat/simple-line-symbol.d.ts +27 -0
  243. package/esri-compat/simple-line-symbol.d.ts.map +1 -0
  244. package/esri-compat/simple-line-symbol.js +85 -0
  245. package/esri-compat/simple-marker-symbol.d.ts +29 -0
  246. package/esri-compat/simple-marker-symbol.d.ts.map +1 -0
  247. package/esri-compat/simple-marker-symbol.js +92 -0
  248. package/esri-compat/simple-renderer.d.ts +29 -0
  249. package/esri-compat/simple-renderer.d.ts.map +1 -0
  250. package/esri-compat/simple-renderer.js +92 -0
  251. package/esri-compat/sketch.d.ts +64 -0
  252. package/esri-compat/sketch.d.ts.map +1 -0
  253. package/esri-compat/sketch.js +227 -0
  254. package/esri-compat/spatial-reference.d.ts +31 -0
  255. package/esri-compat/spatial-reference.d.ts.map +1 -0
  256. package/esri-compat/spatial-reference.js +102 -0
  257. package/esri-compat/swipe.d.ts +34 -0
  258. package/esri-compat/swipe.d.ts.map +1 -0
  259. package/esri-compat/swipe.js +93 -0
  260. package/esri-compat/table-list.d.ts +36 -0
  261. package/esri-compat/table-list.d.ts.map +1 -0
  262. package/esri-compat/table-list.js +126 -0
  263. package/esri-compat/text-symbol.d.ts +37 -0
  264. package/esri-compat/text-symbol.d.ts.map +1 -0
  265. package/esri-compat/text-symbol.js +123 -0
  266. package/esri-compat/tile-layer.d.ts +52 -0
  267. package/esri-compat/tile-layer.d.ts.map +1 -0
  268. package/esri-compat/tile-layer.js +167 -0
  269. package/esri-compat/time-slider.d.ts +70 -0
  270. package/esri-compat/time-slider.d.ts.map +1 -0
  271. package/esri-compat/time-slider.js +208 -0
  272. package/esri-compat/track.d.ts +51 -0
  273. package/esri-compat/track.d.ts.map +1 -0
  274. package/esri-compat/track.js +174 -0
  275. package/esri-compat/unique-value-renderer.d.ts +41 -0
  276. package/esri-compat/unique-value-renderer.d.ts.map +1 -0
  277. package/esri-compat/unique-value-renderer.js +127 -0
  278. package/esri-compat/url.d.ts +12 -0
  279. package/esri-compat/url.d.ts.map +1 -0
  280. package/esri-compat/url.js +54 -0
  281. package/esri-compat/web-map.d.ts +14 -0
  282. package/esri-compat/web-map.d.ts.map +1 -0
  283. package/esri-compat/web-map.js +24 -0
  284. package/gen/honua/v1/feature_service_pb.d.ts +918 -0
  285. package/gen/honua/v1/feature_service_pb.d.ts.map +1 -0
  286. package/gen/honua/v1/feature_service_pb.js +375 -0
  287. package/index.d.ts +130 -0
  288. package/index.js +65 -0
  289. package/package.json +22 -0
@@ -0,0 +1,1110 @@
1
+ import { CompatEventBus, resolveCompatEventBus, safeInvokeCompatListener } from "./event-bus.js";
2
+ export class MapViewPopupCompat {
3
+ visible;
4
+ location;
5
+ features;
6
+ selectedFeature;
7
+ selectedFeatureIndex;
8
+ title;
9
+ content;
10
+ autoOpenEnabled;
11
+ dockEnabled;
12
+ dockOptions;
13
+ viewModel;
14
+ onChange;
15
+ constructor(onChange, options = {}) {
16
+ this.visible = false;
17
+ this.location = undefined;
18
+ this.features = [];
19
+ this.selectedFeature = undefined;
20
+ this.selectedFeatureIndex = -1;
21
+ this.title = undefined;
22
+ this.content = undefined;
23
+ this.autoOpenEnabled = options.autoOpenEnabled ?? true;
24
+ this.dockEnabled = options.dockEnabled ?? false;
25
+ this.dockOptions = options.dockOptions;
26
+ this.viewModel = {
27
+ active: false,
28
+ };
29
+ this.onChange = onChange;
30
+ }
31
+ open(options = {}) {
32
+ this.visible = true;
33
+ this.viewModel.active = true;
34
+ this.location = options.location;
35
+ this.features = options.features ? [...options.features] : [];
36
+ this.selectedFeature = this.features[0];
37
+ this.selectedFeatureIndex = this.features.length > 0 ? 0 : -1;
38
+ this.title = options.title;
39
+ this.content = options.content;
40
+ this.onChange("open", options);
41
+ }
42
+ close() {
43
+ if (!this.visible) {
44
+ return;
45
+ }
46
+ this.visible = false;
47
+ this.viewModel.active = false;
48
+ this.location = undefined;
49
+ this.features = [];
50
+ this.selectedFeature = undefined;
51
+ this.selectedFeatureIndex = -1;
52
+ this.title = undefined;
53
+ this.content = undefined;
54
+ this.onChange("close");
55
+ }
56
+ selectFeature(featureOrIndex) {
57
+ if (this.features.length === 0) {
58
+ return undefined;
59
+ }
60
+ const index = typeof featureOrIndex === "number"
61
+ ? normalizeFeatureIndex(featureOrIndex, this.features.length)
62
+ : this.features.findIndex((feature) => feature === featureOrIndex);
63
+ if (index < 0) {
64
+ return undefined;
65
+ }
66
+ this.selectedFeatureIndex = index;
67
+ this.selectedFeature = this.features[index];
68
+ this.onChange("selection");
69
+ return this.selectedFeature;
70
+ }
71
+ next() {
72
+ if (this.features.length === 0) {
73
+ return undefined;
74
+ }
75
+ const current = this.selectedFeatureIndex >= 0 ? this.selectedFeatureIndex : 0;
76
+ const next = Math.min(current + 1, this.features.length - 1);
77
+ return this.selectFeature(next);
78
+ }
79
+ previous() {
80
+ if (this.features.length === 0) {
81
+ return undefined;
82
+ }
83
+ const current = this.selectedFeatureIndex >= 0 ? this.selectedFeatureIndex : 0;
84
+ const previous = Math.max(current - 1, 0);
85
+ return this.selectFeature(previous);
86
+ }
87
+ }
88
+ export class MapViewLayerViewCompat {
89
+ layer;
90
+ updating;
91
+ suspended;
92
+ hasAllFeatures;
93
+ hasAllFeaturesInView;
94
+ watchListeners;
95
+ eventBus;
96
+ highlightsInternal;
97
+ nextHighlightId;
98
+ constructor(layer, eventBus) {
99
+ this.layer = layer;
100
+ this.updating = false;
101
+ this.suspended = false;
102
+ this.hasAllFeatures = true;
103
+ this.hasAllFeaturesInView = true;
104
+ this.watchListeners = new Map();
105
+ this.eventBus = eventBus;
106
+ this.highlightsInternal = new Map();
107
+ this.nextHighlightId = 1;
108
+ }
109
+ get highlights() {
110
+ return Array.from(this.highlightsInternal.values()).map((record) => ({
111
+ targets: [...record.targets],
112
+ options: { ...record.options },
113
+ }));
114
+ }
115
+ watch(propertyName, listener) {
116
+ let listeners = this.watchListeners.get(propertyName);
117
+ if (!listeners) {
118
+ listeners = new Set();
119
+ this.watchListeners.set(propertyName, listeners);
120
+ }
121
+ listeners.add(listener);
122
+ return {
123
+ remove: () => {
124
+ listeners?.delete(listener);
125
+ },
126
+ };
127
+ }
128
+ setUpdating(value) {
129
+ this.updating = value;
130
+ this.notifyWatchers("updating", value);
131
+ this.eventBus?.emit("view.layer-view-updating-changed", { layer: this.layer, updating: value }, this);
132
+ }
133
+ setSuspended(value) {
134
+ this.suspended = value;
135
+ this.notifyWatchers("suspended", value);
136
+ this.eventBus?.emit("view.layer-view-suspended-changed", { layer: this.layer, suspended: value }, this);
137
+ }
138
+ setHasAllFeatures(value) {
139
+ this.hasAllFeatures = value;
140
+ this.notifyWatchers("hasAllFeatures", value);
141
+ this.eventBus?.emit("view.layer-view-has-all-features-changed", { layer: this.layer, hasAllFeatures: value }, this);
142
+ }
143
+ setHasAllFeaturesInView(value) {
144
+ this.hasAllFeaturesInView = value;
145
+ this.notifyWatchers("hasAllFeaturesInView", value);
146
+ this.eventBus?.emit("view.layer-view-has-all-features-in-view-changed", { layer: this.layer, hasAllFeaturesInView: value }, this);
147
+ }
148
+ async queryFeatures(options = {}) {
149
+ if (isQueryFeaturesProvider(this.layer)) {
150
+ return this.layer.queryFeatures(options);
151
+ }
152
+ return { features: [] };
153
+ }
154
+ async queryFeatureCount(options = {}) {
155
+ if (isQueryFeatureCountProvider(this.layer)) {
156
+ const count = await this.layer.queryFeatureCount(options);
157
+ return normalizeCount(count);
158
+ }
159
+ const result = await this.queryFeatures(options);
160
+ if (isFeatureCollection(result)) {
161
+ return result.features.length;
162
+ }
163
+ return 0;
164
+ }
165
+ async queryObjectIds(options = {}) {
166
+ if (isQueryObjectIdsProvider(this.layer)) {
167
+ const ids = await this.layer.queryObjectIds(options);
168
+ return Array.isArray(ids)
169
+ ? ids.filter((value) => typeof value === "number" && Number.isFinite(value))
170
+ : [];
171
+ }
172
+ const result = await this.queryFeatures(options);
173
+ if (!isFeatureCollection(result)) {
174
+ return [];
175
+ }
176
+ const ids = [];
177
+ for (const feature of result.features) {
178
+ const objectId = extractObjectId(feature);
179
+ if (typeof objectId === "number" && Number.isFinite(objectId)) {
180
+ ids.push(objectId);
181
+ }
182
+ }
183
+ return ids;
184
+ }
185
+ highlight(target, options = {}) {
186
+ const id = this.nextHighlightId;
187
+ this.nextHighlightId += 1;
188
+ const record = {
189
+ targets: normalizeHighlightTargets(target),
190
+ options: { ...options },
191
+ };
192
+ this.highlightsInternal.set(id, record);
193
+ this.notifyWatchers("highlights", this.highlights);
194
+ this.eventBus?.emit("view.layer-view-highlight-added", {
195
+ layer: this.layer,
196
+ targets: [...record.targets],
197
+ options: { ...record.options },
198
+ count: this.highlightsInternal.size,
199
+ }, this);
200
+ return {
201
+ remove: () => {
202
+ this.removeHighlight(id);
203
+ },
204
+ };
205
+ }
206
+ destroy() {
207
+ if (this.highlightsInternal.size > 0) {
208
+ this.highlightsInternal.clear();
209
+ this.notifyWatchers("highlights", this.highlights);
210
+ this.eventBus?.emit("view.layer-view-highlights-cleared", { layer: this.layer, count: 0 }, this);
211
+ }
212
+ this.watchListeners.clear();
213
+ }
214
+ removeHighlight(id) {
215
+ const record = this.highlightsInternal.get(id);
216
+ if (!record) {
217
+ return false;
218
+ }
219
+ this.highlightsInternal.delete(id);
220
+ this.notifyWatchers("highlights", this.highlights);
221
+ this.eventBus?.emit("view.layer-view-highlight-removed", {
222
+ layer: this.layer,
223
+ targets: [...record.targets],
224
+ options: { ...record.options },
225
+ count: this.highlightsInternal.size,
226
+ }, this);
227
+ return true;
228
+ }
229
+ notifyWatchers(propertyName, value) {
230
+ const listeners = this.watchListeners.get(propertyName);
231
+ if (!listeners) {
232
+ return;
233
+ }
234
+ for (const listener of listeners) {
235
+ safeInvokeListener(() => listener(value));
236
+ }
237
+ }
238
+ }
239
+ export class MapViewUiCompat {
240
+ eventBus;
241
+ onChanged;
242
+ componentsInternal;
243
+ constructor(eventBus, onChanged) {
244
+ this.eventBus = eventBus;
245
+ this.onChanged = onChanged;
246
+ this.componentsInternal = [];
247
+ }
248
+ get components() {
249
+ return this.componentsInternal.map((record) => ({ ...record }));
250
+ }
251
+ add(componentOrComponents, positionOrOptions = "manual") {
252
+ if (Array.isArray(componentOrComponents)) {
253
+ for (const component of componentOrComponents) {
254
+ this.add(component, positionOrOptions);
255
+ }
256
+ return;
257
+ }
258
+ const component = componentOrComponents;
259
+ const options = normalizeUiOptions(positionOrOptions);
260
+ const existingIndex = this.findComponentIndex(component);
261
+ if (existingIndex >= 0) {
262
+ this.componentsInternal.splice(existingIndex, 1);
263
+ }
264
+ const insertIndex = normalizeUiIndex(options.index, this.componentsInternal.length);
265
+ const record = {
266
+ component,
267
+ position: options.position,
268
+ index: insertIndex,
269
+ };
270
+ this.componentsInternal.splice(insertIndex, 0, record);
271
+ this.reindexComponents();
272
+ this.eventBus.emit("view.ui.component-added", {
273
+ component,
274
+ position: record.position,
275
+ index: record.index,
276
+ }, this);
277
+ this.notifyChanged();
278
+ }
279
+ remove(componentOrId) {
280
+ const index = this.findComponentIndex(componentOrId);
281
+ if (index < 0) {
282
+ return false;
283
+ }
284
+ const [removed] = this.componentsInternal.splice(index, 1);
285
+ this.reindexComponents();
286
+ this.eventBus.emit("view.ui.component-removed", {
287
+ component: removed?.component,
288
+ position: removed?.position,
289
+ }, this);
290
+ this.notifyChanged();
291
+ return true;
292
+ }
293
+ removeAll() {
294
+ if (this.componentsInternal.length === 0) {
295
+ return;
296
+ }
297
+ const removedComponents = this.componentsInternal.map((record) => record.component);
298
+ this.componentsInternal.length = 0;
299
+ this.eventBus.emit("view.ui.components-cleared", {
300
+ count: removedComponents.length,
301
+ }, this);
302
+ this.notifyChanged();
303
+ }
304
+ empty(position) {
305
+ const previous = this.componentsInternal.length;
306
+ const remaining = this.componentsInternal.filter((record) => record.position !== position);
307
+ if (remaining.length === previous) {
308
+ return;
309
+ }
310
+ this.componentsInternal.length = 0;
311
+ this.componentsInternal.push(...remaining);
312
+ this.reindexComponents();
313
+ this.eventBus.emit("view.ui.position-cleared", {
314
+ position,
315
+ remainingCount: this.componentsInternal.length,
316
+ }, this);
317
+ this.notifyChanged();
318
+ }
319
+ move(componentOrId, positionOrOptions) {
320
+ const index = this.findComponentIndex(componentOrId);
321
+ if (index < 0) {
322
+ return false;
323
+ }
324
+ const [record] = this.componentsInternal.splice(index, 1);
325
+ const options = normalizeUiOptions(positionOrOptions);
326
+ const insertIndex = normalizeUiIndex(options.index, this.componentsInternal.length);
327
+ const movedRecord = {
328
+ component: record.component,
329
+ position: options.position,
330
+ index: insertIndex,
331
+ };
332
+ this.componentsInternal.splice(insertIndex, 0, movedRecord);
333
+ this.reindexComponents();
334
+ this.eventBus.emit("view.ui.component-moved", {
335
+ component: movedRecord.component,
336
+ position: movedRecord.position,
337
+ index: movedRecord.index,
338
+ }, this);
339
+ this.notifyChanged();
340
+ return true;
341
+ }
342
+ find(componentOrId) {
343
+ const index = this.findComponentIndex(componentOrId);
344
+ return index < 0 ? undefined : this.componentsInternal[index]?.component;
345
+ }
346
+ getComponents(position) {
347
+ if (position === undefined) {
348
+ return this.componentsInternal.map((record) => record.component);
349
+ }
350
+ return this.componentsInternal.filter((record) => record.position === position).map((record) => record.component);
351
+ }
352
+ findComponentIndex(componentOrId) {
353
+ if (typeof componentOrId === "string") {
354
+ for (let i = 0; i < this.componentsInternal.length; i += 1) {
355
+ const component = this.componentsInternal[i]?.component;
356
+ if (isRecord(component) && component.id === componentOrId) {
357
+ return i;
358
+ }
359
+ }
360
+ return -1;
361
+ }
362
+ return this.componentsInternal.findIndex((record) => record.component === componentOrId);
363
+ }
364
+ reindexComponents() {
365
+ for (let i = 0; i < this.componentsInternal.length; i += 1) {
366
+ const existing = this.componentsInternal[i];
367
+ if (!existing) {
368
+ continue;
369
+ }
370
+ existing.index = i;
371
+ }
372
+ }
373
+ notifyChanged() {
374
+ this.onChanged?.(this.components);
375
+ }
376
+ }
377
+ export class MapViewCompat {
378
+ map;
379
+ container;
380
+ loaded;
381
+ loadStatus;
382
+ center;
383
+ zoom;
384
+ scale;
385
+ rotation;
386
+ extent;
387
+ constraints;
388
+ padding;
389
+ highlightOptions;
390
+ spatialReference;
391
+ eventBus;
392
+ popup;
393
+ ui;
394
+ eventListeners;
395
+ watchListeners;
396
+ layerViews;
397
+ readyPromise;
398
+ constructor(options = {}) {
399
+ this.map = options.map;
400
+ this.container = options.container;
401
+ this.loaded = false;
402
+ this.loadStatus = "not-loaded";
403
+ this.center = options.center;
404
+ this.zoom = options.zoom;
405
+ this.scale = options.scale;
406
+ this.rotation = options.rotation;
407
+ this.extent = options.extent;
408
+ this.constraints = options.constraints;
409
+ this.padding = options.padding;
410
+ this.highlightOptions = options.highlightOptions;
411
+ this.spatialReference = options.spatialReference;
412
+ this.eventBus = options.eventBus ?? resolveCompatEventBus(options.map, options.container) ?? new CompatEventBus();
413
+ this.popup = new MapViewPopupCompat((type, popupOptions) => {
414
+ this.notifyWatchers("popup.visible", this.popup.visible);
415
+ this.notifyWatchers("popup.features", this.popup.features);
416
+ this.notifyWatchers("popup.selectedFeature", this.popup.selectedFeature);
417
+ this.notifyWatchers("popup.selectedFeatureIndex", this.popup.selectedFeatureIndex);
418
+ this.notifyWatchers("popup.location", this.popup.location);
419
+ this.notifyWatchers("popup.title", this.popup.title);
420
+ this.notifyWatchers("popup.content", this.popup.content);
421
+ this.notifyWatchers("popup.viewModel.active", this.popup.viewModel.active);
422
+ if (type === "open") {
423
+ this.eventBus.emit("popup.open", popupOptions, this);
424
+ this.emit("popup-open", popupOptions);
425
+ }
426
+ else if (type === "close") {
427
+ this.eventBus.emit("popup.close", popupOptions, this);
428
+ this.emit("popup-close", popupOptions);
429
+ }
430
+ else {
431
+ const selection = {
432
+ selectedFeature: this.popup.selectedFeature,
433
+ selectedFeatureIndex: this.popup.selectedFeatureIndex,
434
+ };
435
+ this.eventBus.emit("popup.selected-feature-changed", selection, this);
436
+ this.emit("popup-selection-change", selection);
437
+ }
438
+ }, extractPopupOptions(options.popup));
439
+ this.ui = new MapViewUiCompat(this.eventBus, (components) => {
440
+ this.notifyWatchers("ui.components", components);
441
+ });
442
+ this.eventListeners = new Map();
443
+ this.watchListeners = new Map();
444
+ this.layerViews = new Map();
445
+ this.readyPromise = Promise.resolve(this);
446
+ }
447
+ async load() {
448
+ if (this.loaded) {
449
+ return this;
450
+ }
451
+ this.loadStatus = "loading";
452
+ this.notifyWatchers("loadStatus", this.loadStatus);
453
+ this.eventBus.emit("view.loading", undefined, this);
454
+ await this.readyPromise;
455
+ this.loaded = true;
456
+ this.notifyWatchers("loaded", this.loaded);
457
+ this.loadStatus = "loaded";
458
+ this.notifyWatchers("loadStatus", this.loadStatus);
459
+ this.eventBus.emit("view.loaded", undefined, this);
460
+ return this;
461
+ }
462
+ async when(callback) {
463
+ const view = await this.load();
464
+ if (callback) {
465
+ callback(view);
466
+ }
467
+ return view;
468
+ }
469
+ toMap(screenPoint) {
470
+ const mapPoint = {
471
+ x: screenPoint.x,
472
+ y: screenPoint.y,
473
+ };
474
+ if (this.spatialReference !== undefined) {
475
+ mapPoint.spatialReference = this.spatialReference;
476
+ }
477
+ return mapPoint;
478
+ }
479
+ toScreen(mapPoint) {
480
+ return {
481
+ x: mapPoint.x,
482
+ y: mapPoint.y,
483
+ };
484
+ }
485
+ async hitTest(event = {}) {
486
+ const mapPoint = event.mapPoint ??
487
+ (typeof event.x === "number" && typeof event.y === "number" ? this.toMap({ x: event.x, y: event.y }) : undefined);
488
+ return {
489
+ results: this.popup.features.map((feature) => ({
490
+ type: "graphic",
491
+ graphic: feature,
492
+ layer: extractGraphicLayer(feature),
493
+ mapPoint,
494
+ })),
495
+ };
496
+ }
497
+ async goTo(target, options = {}) {
498
+ const normalizedTarget = normalizeGoToTarget(target);
499
+ if (normalizedTarget.center !== undefined) {
500
+ this.setCenter(normalizedTarget.center);
501
+ }
502
+ if (normalizedTarget.zoom !== undefined) {
503
+ this.setZoom(normalizedTarget.zoom);
504
+ }
505
+ if (normalizedTarget.scale !== undefined) {
506
+ this.setScale(normalizedTarget.scale);
507
+ }
508
+ if (normalizedTarget.rotation !== undefined) {
509
+ this.setRotation(normalizedTarget.rotation);
510
+ }
511
+ if (normalizedTarget.extent !== undefined) {
512
+ this.setExtent(normalizedTarget.extent);
513
+ }
514
+ const payload = hasGoToOptions(options) ? { target, options } : target;
515
+ this.eventBus.emit("view.go-to", payload, this);
516
+ this.emit("go-to", payload);
517
+ return this;
518
+ }
519
+ async takeScreenshot(options = {}) {
520
+ const width = normalizeScreenshotDimension(options.width, 1024);
521
+ const height = normalizeScreenshotDimension(options.height, 768);
522
+ const format = normalizeScreenshotFormat(options.format);
523
+ const mimeType = format === "jpg" ? "image/jpeg" : "image/png";
524
+ const result = {
525
+ data: new Uint8ClampedArray(width * height * 4),
526
+ dataUrl: `data:${mimeType};base64,`,
527
+ width,
528
+ height,
529
+ };
530
+ const payload = {
531
+ width,
532
+ height,
533
+ format,
534
+ quality: options.quality,
535
+ area: options.area,
536
+ ignoreBackground: options.ignoreBackground,
537
+ };
538
+ this.eventBus.emit("view.screenshot", payload, this);
539
+ this.emit("take-screenshot", payload);
540
+ return result;
541
+ }
542
+ openPopup(options = {}) {
543
+ this.popup.open(options);
544
+ }
545
+ closePopup() {
546
+ this.popup.close();
547
+ }
548
+ setCenter(center) {
549
+ this.center = center;
550
+ this.notifyWatchers("center", this.center);
551
+ this.eventBus.emit("view.center-changed", { center }, this);
552
+ }
553
+ setZoom(zoom) {
554
+ this.zoom = zoom;
555
+ this.notifyWatchers("zoom", this.zoom);
556
+ this.eventBus.emit("view.zoom-changed", { zoom }, this);
557
+ }
558
+ setScale(scale) {
559
+ this.scale = scale;
560
+ this.notifyWatchers("scale", this.scale);
561
+ this.eventBus.emit("view.scale-changed", { scale }, this);
562
+ }
563
+ setRotation(rotation) {
564
+ this.rotation = rotation;
565
+ this.notifyWatchers("rotation", this.rotation);
566
+ this.eventBus.emit("view.rotation-changed", { rotation }, this);
567
+ }
568
+ setExtent(extent) {
569
+ this.extent = extent;
570
+ this.notifyWatchers("extent", this.extent);
571
+ this.eventBus.emit("view.extent-changed", { extent }, this);
572
+ }
573
+ setPadding(padding) {
574
+ this.padding = padding;
575
+ this.notifyWatchers("padding", this.padding);
576
+ this.eventBus.emit("view.padding-changed", { padding }, this);
577
+ }
578
+ setConstraints(constraints) {
579
+ this.constraints = constraints;
580
+ this.notifyWatchers("constraints", this.constraints);
581
+ this.eventBus.emit("view.constraints-changed", { constraints }, this);
582
+ }
583
+ setHighlightOptions(highlightOptions) {
584
+ this.highlightOptions = highlightOptions;
585
+ this.notifyWatchers("highlightOptions", this.highlightOptions);
586
+ this.eventBus.emit("view.highlight-options-changed", { highlightOptions }, this);
587
+ }
588
+ setSpatialReference(spatialReference) {
589
+ this.spatialReference = spatialReference;
590
+ this.notifyWatchers("spatialReference", this.spatialReference);
591
+ this.eventBus.emit("view.spatial-reference-changed", { spatialReference }, this);
592
+ }
593
+ /** Returns all currently created layer views as a read-only collection. */
594
+ get allLayerViews() {
595
+ return Array.from(this.layerViews.values());
596
+ }
597
+ /**
598
+ * Returns an existing layer view for the given layer, or undefined if
599
+ * whenLayerView has not yet been called for it.
600
+ */
601
+ getLayerView(layer) {
602
+ return this.layerViews.get(layer);
603
+ }
604
+ async whenLayerView(layer) {
605
+ const existing = this.layerViews.get(layer);
606
+ if (existing) {
607
+ return existing;
608
+ }
609
+ const layerView = new MapViewLayerViewCompat(layer, this.eventBus);
610
+ this.layerViews.set(layer, layerView);
611
+ this.notifyWatchers("allLayerViews", this.allLayerViews);
612
+ this.eventBus.emit("view.layer-view-created", { layer, layerView }, this);
613
+ this.eventBus.emit("feature-layer.layerview-create", { view: this, layerView }, this);
614
+ this.emit("layerview-create", { layer, layerView });
615
+ return layerView;
616
+ }
617
+ on(eventName, listener) {
618
+ let listeners = this.eventListeners.get(eventName);
619
+ if (!listeners) {
620
+ listeners = new Set();
621
+ this.eventListeners.set(eventName, listeners);
622
+ }
623
+ listeners.add(listener);
624
+ return {
625
+ remove: () => {
626
+ listeners?.delete(listener);
627
+ },
628
+ };
629
+ }
630
+ watch(propertyName, listener) {
631
+ let listeners = this.watchListeners.get(propertyName);
632
+ if (!listeners) {
633
+ listeners = new Set();
634
+ this.watchListeners.set(propertyName, listeners);
635
+ }
636
+ listeners.add(listener);
637
+ return {
638
+ remove: () => {
639
+ listeners?.delete(listener);
640
+ },
641
+ };
642
+ }
643
+ destroy() {
644
+ this.eventBus.emit("view.destroy", undefined, this);
645
+ this.emit("destroy", undefined);
646
+ this.ui.removeAll();
647
+ for (const layerView of this.layerViews.values()) {
648
+ layerView.destroy();
649
+ }
650
+ this.layerViews.clear();
651
+ this.notifyWatchers("allLayerViews", this.allLayerViews);
652
+ this.closePopup();
653
+ this.map = undefined;
654
+ this.notifyWatchers("map", this.map);
655
+ this.container = undefined;
656
+ this.notifyWatchers("container", this.container);
657
+ this.center = undefined;
658
+ this.notifyWatchers("center", this.center);
659
+ this.zoom = undefined;
660
+ this.notifyWatchers("zoom", this.zoom);
661
+ this.scale = undefined;
662
+ this.notifyWatchers("scale", this.scale);
663
+ this.rotation = undefined;
664
+ this.notifyWatchers("rotation", this.rotation);
665
+ this.extent = undefined;
666
+ this.notifyWatchers("extent", this.extent);
667
+ this.constraints = undefined;
668
+ this.notifyWatchers("constraints", this.constraints);
669
+ this.padding = undefined;
670
+ this.notifyWatchers("padding", this.padding);
671
+ this.highlightOptions = undefined;
672
+ this.notifyWatchers("highlightOptions", this.highlightOptions);
673
+ this.spatialReference = undefined;
674
+ this.notifyWatchers("spatialReference", this.spatialReference);
675
+ this.loaded = false;
676
+ this.notifyWatchers("loaded", this.loaded);
677
+ this.loadStatus = "not-loaded";
678
+ this.notifyWatchers("loadStatus", this.loadStatus);
679
+ this.eventListeners.clear();
680
+ this.watchListeners.clear();
681
+ }
682
+ emit(eventName, payload) {
683
+ const listeners = this.eventListeners.get(eventName);
684
+ if (!listeners || listeners.size === 0) {
685
+ return false;
686
+ }
687
+ for (const listener of listeners) {
688
+ safeInvokeListener(() => listener(payload));
689
+ }
690
+ return true;
691
+ }
692
+ notifyWatchers(propertyName, value) {
693
+ const listeners = this.watchListeners.get(propertyName);
694
+ if (!listeners) {
695
+ return;
696
+ }
697
+ for (const listener of listeners) {
698
+ safeInvokeListener(() => listener(value));
699
+ }
700
+ }
701
+ }
702
+ const GEOMETRY_SEQUENCE_KEYS = ["points", "path", "paths", "ring", "rings"];
703
+ function normalizeGoToTarget(target) {
704
+ const normalized = {};
705
+ const targetRecord = asRecord(target);
706
+ if (targetRecord !== undefined) {
707
+ if ("target" in targetRecord && targetRecord.target !== undefined) {
708
+ mergeGoToTarget(normalized, normalizeGoToTarget(targetRecord.target));
709
+ }
710
+ if (targetRecord.center !== undefined) {
711
+ normalized.center = targetRecord.center;
712
+ }
713
+ const zoom = normalizeFiniteNumber(targetRecord.zoom);
714
+ if (zoom !== undefined) {
715
+ normalized.zoom = zoom;
716
+ }
717
+ const scale = normalizeFiniteNumber(targetRecord.scale);
718
+ if (scale !== undefined) {
719
+ normalized.scale = scale;
720
+ }
721
+ const rotation = normalizeFiniteNumber(targetRecord.rotation);
722
+ if (rotation !== undefined) {
723
+ normalized.rotation = rotation;
724
+ }
725
+ if (targetRecord.extent !== undefined) {
726
+ normalized.extent = targetRecord.extent;
727
+ }
728
+ }
729
+ if (normalized.center === undefined) {
730
+ const derivedCenter = extractGoToCenter(target);
731
+ if (derivedCenter !== undefined) {
732
+ normalized.center = derivedCenter;
733
+ }
734
+ }
735
+ if (normalized.extent === undefined) {
736
+ const derivedExtent = extractGoToExtent(target);
737
+ if (derivedExtent !== undefined) {
738
+ normalized.extent = derivedExtent;
739
+ }
740
+ }
741
+ if (normalized.center === undefined && normalized.extent !== undefined) {
742
+ const centerFromExtent = extractExtentCenter(normalized.extent);
743
+ if (centerFromExtent !== undefined) {
744
+ normalized.center = centerFromExtent;
745
+ }
746
+ }
747
+ return normalized;
748
+ }
749
+ function mergeGoToTarget(target, source) {
750
+ if (source.center !== undefined) {
751
+ target.center = source.center;
752
+ }
753
+ if (source.zoom !== undefined) {
754
+ target.zoom = source.zoom;
755
+ }
756
+ if (source.scale !== undefined) {
757
+ target.scale = source.scale;
758
+ }
759
+ if (source.rotation !== undefined) {
760
+ target.rotation = source.rotation;
761
+ }
762
+ if (source.extent !== undefined) {
763
+ target.extent = source.extent;
764
+ }
765
+ }
766
+ function hasGoToOptions(options) {
767
+ return (options.animate !== undefined ||
768
+ options.duration !== undefined ||
769
+ options.speedFactor !== undefined ||
770
+ options.easing !== undefined);
771
+ }
772
+ function extractGoToCenter(value, visited = new Set()) {
773
+ if (isCoordinatePair(value)) {
774
+ return [value[0], value[1]];
775
+ }
776
+ if (Array.isArray(value)) {
777
+ return undefined;
778
+ }
779
+ if (!isRecord(value)) {
780
+ return undefined;
781
+ }
782
+ if (visited.has(value)) {
783
+ return undefined;
784
+ }
785
+ visited.add(value);
786
+ if ("target" in value && value.target !== undefined) {
787
+ const nestedCenter = extractGoToCenter(value.target, visited);
788
+ if (nestedCenter !== undefined) {
789
+ return nestedCenter;
790
+ }
791
+ }
792
+ if ("geometry" in value && value.geometry !== undefined) {
793
+ const nestedCenter = extractGoToCenter(value.geometry, visited);
794
+ if (nestedCenter !== undefined) {
795
+ return nestedCenter;
796
+ }
797
+ }
798
+ return extractPointCenterFromRecord(value);
799
+ }
800
+ function extractGoToExtent(value) {
801
+ if (!shouldDeriveExtentFromTarget(value)) {
802
+ return undefined;
803
+ }
804
+ const bounds = collectBounds(value);
805
+ return bounds ? toExtentLike(bounds) : undefined;
806
+ }
807
+ function shouldDeriveExtentFromTarget(value, visited = new Set()) {
808
+ if (isExtentLike(value)) {
809
+ return true;
810
+ }
811
+ if (isCoordinatePair(value)) {
812
+ return false;
813
+ }
814
+ if (Array.isArray(value)) {
815
+ return value.length > 0;
816
+ }
817
+ if (!isRecord(value)) {
818
+ return false;
819
+ }
820
+ if (visited.has(value)) {
821
+ return false;
822
+ }
823
+ visited.add(value);
824
+ if ("target" in value && value.target !== undefined && shouldDeriveExtentFromTarget(value.target, visited)) {
825
+ return true;
826
+ }
827
+ if ("geometry" in value && value.geometry !== undefined && shouldDeriveExtentFromTarget(value.geometry, visited)) {
828
+ return true;
829
+ }
830
+ return hasCoordinateSequences(value);
831
+ }
832
+ function collectBounds(value, visited = new Set()) {
833
+ if (isExtentLike(value)) {
834
+ return {
835
+ xmin: value.xmin,
836
+ ymin: value.ymin,
837
+ xmax: value.xmax,
838
+ ymax: value.ymax,
839
+ spatialReference: value.spatialReference,
840
+ };
841
+ }
842
+ if (isCoordinatePair(value)) {
843
+ return createBoundsFromPoint(value[0], value[1]);
844
+ }
845
+ if (Array.isArray(value)) {
846
+ let bounds;
847
+ for (const item of value) {
848
+ bounds = mergeBounds(bounds, collectBounds(item, visited));
849
+ }
850
+ return bounds;
851
+ }
852
+ if (!isRecord(value)) {
853
+ return undefined;
854
+ }
855
+ if (visited.has(value)) {
856
+ return undefined;
857
+ }
858
+ visited.add(value);
859
+ let bounds;
860
+ if ("target" in value && value.target !== undefined) {
861
+ bounds = mergeBounds(bounds, collectBounds(value.target, visited));
862
+ }
863
+ if ("geometry" in value && value.geometry !== undefined) {
864
+ bounds = mergeBounds(bounds, collectBounds(value.geometry, visited));
865
+ }
866
+ const point = extractPointFromRecord(value);
867
+ if (point !== undefined) {
868
+ bounds = mergeBounds(bounds, createBoundsFromPoint(point.x, point.y, point.spatialReference));
869
+ }
870
+ for (const key of GEOMETRY_SEQUENCE_KEYS) {
871
+ if (key in value) {
872
+ bounds = mergeBounds(bounds, collectBounds(value[key], visited));
873
+ }
874
+ }
875
+ return bounds;
876
+ }
877
+ function hasCoordinateSequences(value) {
878
+ return GEOMETRY_SEQUENCE_KEYS.some((key) => key in value && Array.isArray(value[key]));
879
+ }
880
+ function extractPointCenterFromRecord(value) {
881
+ const point = extractPointFromRecord(value);
882
+ if (point === undefined) {
883
+ return undefined;
884
+ }
885
+ return {
886
+ x: point.x,
887
+ y: point.y,
888
+ spatialReference: point.spatialReference,
889
+ };
890
+ }
891
+ function extractPointFromRecord(value) {
892
+ const x = normalizeFiniteNumber(value.x);
893
+ const y = normalizeFiniteNumber(value.y);
894
+ if (x !== undefined && y !== undefined) {
895
+ return {
896
+ x,
897
+ y,
898
+ spatialReference: asSpatialReferenceLike(value.spatialReference),
899
+ };
900
+ }
901
+ const longitude = normalizeFiniteNumber(value.longitude);
902
+ const latitude = normalizeFiniteNumber(value.latitude);
903
+ if (longitude !== undefined && latitude !== undefined) {
904
+ return {
905
+ x: longitude,
906
+ y: latitude,
907
+ spatialReference: asSpatialReferenceLike(value.spatialReference),
908
+ };
909
+ }
910
+ return undefined;
911
+ }
912
+ function asSpatialReferenceLike(value) {
913
+ return isRecord(value) ? value : undefined;
914
+ }
915
+ function normalizeFiniteNumber(value) {
916
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
917
+ }
918
+ function normalizeScreenshotDimension(value, fallback) {
919
+ if (value === undefined || !Number.isFinite(value)) {
920
+ return fallback;
921
+ }
922
+ return Math.max(1, Math.trunc(value));
923
+ }
924
+ function normalizeScreenshotFormat(format) {
925
+ if (format === "jpg" || format === "jpeg") {
926
+ return "jpg";
927
+ }
928
+ return "png";
929
+ }
930
+ function createBoundsFromPoint(x, y, spatialReference) {
931
+ return {
932
+ xmin: x,
933
+ ymin: y,
934
+ xmax: x,
935
+ ymax: y,
936
+ spatialReference,
937
+ };
938
+ }
939
+ function mergeBounds(current, next) {
940
+ if (next === undefined) {
941
+ return current;
942
+ }
943
+ if (current === undefined) {
944
+ return next;
945
+ }
946
+ return {
947
+ xmin: Math.min(current.xmin, next.xmin),
948
+ ymin: Math.min(current.ymin, next.ymin),
949
+ xmax: Math.max(current.xmax, next.xmax),
950
+ ymax: Math.max(current.ymax, next.ymax),
951
+ spatialReference: current.spatialReference ?? next.spatialReference,
952
+ };
953
+ }
954
+ function toExtentLike(bounds) {
955
+ return {
956
+ xmin: bounds.xmin,
957
+ ymin: bounds.ymin,
958
+ xmax: bounds.xmax,
959
+ ymax: bounds.ymax,
960
+ spatialReference: bounds.spatialReference,
961
+ };
962
+ }
963
+ function extractExtentCenter(extent) {
964
+ if (!isExtentLike(extent)) {
965
+ return undefined;
966
+ }
967
+ return {
968
+ x: (extent.xmin + extent.xmax) / 2,
969
+ y: (extent.ymin + extent.ymax) / 2,
970
+ spatialReference: extent.spatialReference,
971
+ };
972
+ }
973
+ function isCoordinatePair(value) {
974
+ return (Array.isArray(value) &&
975
+ value.length >= 2 &&
976
+ typeof value[0] === "number" &&
977
+ Number.isFinite(value[0]) &&
978
+ typeof value[1] === "number" &&
979
+ Number.isFinite(value[1]));
980
+ }
981
+ function isExtentLike(value) {
982
+ return (isRecord(value) &&
983
+ typeof value.xmin === "number" &&
984
+ Number.isFinite(value.xmin) &&
985
+ typeof value.ymin === "number" &&
986
+ Number.isFinite(value.ymin) &&
987
+ typeof value.xmax === "number" &&
988
+ Number.isFinite(value.xmax) &&
989
+ typeof value.ymax === "number" &&
990
+ Number.isFinite(value.ymax));
991
+ }
992
+ function normalizeUiOptions(input) {
993
+ if (typeof input === "string") {
994
+ return {
995
+ position: input,
996
+ index: Number.NaN,
997
+ };
998
+ }
999
+ const position = typeof input.position === "string" && input.position.length > 0 ? input.position : "manual";
1000
+ const index = typeof input.index === "number" && Number.isFinite(input.index) ? Math.trunc(input.index) : Number.NaN;
1001
+ return {
1002
+ position,
1003
+ index,
1004
+ };
1005
+ }
1006
+ function normalizeUiIndex(index, length) {
1007
+ if (!Number.isFinite(index)) {
1008
+ return length;
1009
+ }
1010
+ return Math.min(Math.max(index, 0), length);
1011
+ }
1012
+ function normalizeFeatureIndex(index, length) {
1013
+ if (!Number.isFinite(index)) {
1014
+ return -1;
1015
+ }
1016
+ const normalized = Math.trunc(index);
1017
+ if (normalized < 0 || normalized >= length) {
1018
+ return -1;
1019
+ }
1020
+ return normalized;
1021
+ }
1022
+ function normalizeHighlightTargets(target) {
1023
+ if (Array.isArray(target)) {
1024
+ return [...target];
1025
+ }
1026
+ return [target];
1027
+ }
1028
+ function isQueryFeaturesProvider(value) {
1029
+ return (typeof value === "object" && value !== null && "queryFeatures" in value && typeof value.queryFeatures === "function");
1030
+ }
1031
+ function isQueryFeatureCountProvider(value) {
1032
+ return (typeof value === "object" &&
1033
+ value !== null &&
1034
+ "queryFeatureCount" in value &&
1035
+ typeof value.queryFeatureCount === "function");
1036
+ }
1037
+ function isQueryObjectIdsProvider(value) {
1038
+ return (typeof value === "object" &&
1039
+ value !== null &&
1040
+ "queryObjectIds" in value &&
1041
+ typeof value.queryObjectIds === "function");
1042
+ }
1043
+ function isFeatureCollection(value) {
1044
+ return typeof value === "object" && value !== null && "features" in value && Array.isArray(value.features);
1045
+ }
1046
+ function extractObjectId(feature) {
1047
+ if (typeof feature !== "object" || feature === null) {
1048
+ return undefined;
1049
+ }
1050
+ if ("objectId" in feature && typeof feature.objectId === "number") {
1051
+ return feature.objectId;
1052
+ }
1053
+ if ("attributes" in feature && typeof feature.attributes === "object" && feature.attributes !== null) {
1054
+ if ("OBJECTID" in feature.attributes &&
1055
+ typeof feature.attributes.OBJECTID === "number" &&
1056
+ Number.isFinite(feature.attributes.OBJECTID)) {
1057
+ return feature.attributes.OBJECTID;
1058
+ }
1059
+ if ("objectid" in feature.attributes &&
1060
+ typeof feature.attributes.objectid === "number" &&
1061
+ Number.isFinite(feature.attributes.objectid)) {
1062
+ return feature.attributes.objectid;
1063
+ }
1064
+ if ("objectId" in feature.attributes &&
1065
+ typeof feature.attributes.objectId === "number" &&
1066
+ Number.isFinite(feature.attributes.objectId)) {
1067
+ return feature.attributes.objectId;
1068
+ }
1069
+ }
1070
+ return undefined;
1071
+ }
1072
+ function normalizeCount(value) {
1073
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
1074
+ }
1075
+ function extractGraphicLayer(value) {
1076
+ if (!("layer" in value) || value.layer === undefined || value.layer === null) {
1077
+ return undefined;
1078
+ }
1079
+ if (typeof value.layer === "object") {
1080
+ return value.layer;
1081
+ }
1082
+ return undefined;
1083
+ }
1084
+ function safeInvokeListener(invoke) {
1085
+ try {
1086
+ invoke();
1087
+ }
1088
+ catch {
1089
+ // Listener errors should not break compatibility flow.
1090
+ }
1091
+ }
1092
+ function isRecord(value) {
1093
+ return typeof value === "object" && value !== null;
1094
+ }
1095
+ function asRecord(value) {
1096
+ if (!isRecord(value) || Array.isArray(value)) {
1097
+ return undefined;
1098
+ }
1099
+ return value;
1100
+ }
1101
+ function extractPopupOptions(popup) {
1102
+ if (!isRecord(popup)) {
1103
+ return {};
1104
+ }
1105
+ return {
1106
+ autoOpenEnabled: typeof popup.autoOpenEnabled === "boolean" ? popup.autoOpenEnabled : undefined,
1107
+ dockEnabled: typeof popup.dockEnabled === "boolean" ? popup.dockEnabled : undefined,
1108
+ dockOptions: popup.dockOptions,
1109
+ };
1110
+ }