@honua/react 0.0.20-alpha.0 → 0.1.1-beta.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.
- package/contract/discovery.d.ts +231 -0
- package/contract/discovery.d.ts.map +1 -0
- package/contract/discovery.js +554 -0
- package/contract/edit-sketch.d.ts +8 -0
- package/contract/edit-sketch.d.ts.map +1 -1
- package/contract/edit-sketch.js +15 -0
- package/contract/edit-snapping.d.ts +160 -0
- package/contract/edit-snapping.d.ts.map +1 -0
- package/contract/edit-snapping.js +675 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts +35 -0
- package/contract/generated/projjson-v0.7-crs-validator.d.ts.map +1 -0
- package/contract/generated/projjson-v0.7-crs-validator.js +3941 -0
- package/contract/index.d.ts +12 -1
- package/contract/index.d.ts.map +1 -1
- package/contract/index.js +4 -0
- package/contract/pmtiles.d.ts +193 -0
- package/contract/pmtiles.d.ts.map +1 -0
- package/contract/pmtiles.js +195 -0
- package/contract/protocol-module.d.ts +70 -0
- package/contract/protocol-module.d.ts.map +1 -0
- package/contract/protocol-module.js +1 -0
- package/contract/schema-envelope.d.ts +26 -0
- package/contract/schema-envelope.d.ts.map +1 -0
- package/contract/schema-envelope.js +25 -0
- package/contract/schema.d.ts +582 -0
- package/contract/schema.d.ts.map +1 -0
- package/contract/schema.js +2483 -0
- package/contract/source-capability-support.d.ts +6 -0
- package/contract/source-capability-support.d.ts.map +1 -0
- package/contract/source-capability-support.js +154 -0
- package/contract/source.d.ts +57 -15
- package/contract/source.d.ts.map +1 -1
- package/contract/source.js +368 -65
- package/contract/types.d.ts +171 -6
- package/contract/types.d.ts.map +1 -1
- package/contract/types.js +14 -14
- package/core/auth/client-credentials-provider.d.ts +51 -0
- package/core/auth/client-credentials-provider.d.ts.map +1 -0
- package/core/auth/client-credentials-provider.js +115 -0
- package/core/auth/credential-store.d.ts +52 -0
- package/core/auth/credential-store.d.ts.map +1 -0
- package/core/auth/credential-store.js +82 -0
- package/core/auth/index.d.ts +23 -0
- package/core/auth/index.d.ts.map +1 -0
- package/core/auth/index.js +20 -0
- package/core/auth/oauth2-provider.d.ts +114 -0
- package/core/auth/oauth2-provider.d.ts.map +1 -0
- package/core/auth/oauth2-provider.js +408 -0
- package/core/auth/pkce.d.ts +25 -0
- package/core/auth/pkce.d.ts.map +1 -0
- package/core/auth/pkce.js +46 -0
- package/core/auth/static-providers.d.ts +20 -0
- package/core/auth/static-providers.d.ts.map +1 -0
- package/core/auth/static-providers.js +26 -0
- package/core/auth/token-endpoint.d.ts +40 -0
- package/core/auth/token-endpoint.d.ts.map +1 -0
- package/core/auth/token-endpoint.js +133 -0
- package/core/auth/types.d.ts +144 -0
- package/core/auth/types.d.ts.map +1 -0
- package/core/auth/types.js +8 -0
- package/core/bounded-json.d.ts +4 -0
- package/core/bounded-json.d.ts.map +1 -0
- package/core/bounded-json.js +38 -0
- package/core/cache-state.d.ts +9 -0
- package/core/cache-state.d.ts.map +1 -1
- package/core/cache-state.js +10 -0
- package/core/capabilities-xml.d.ts +33 -0
- package/core/capabilities-xml.d.ts.map +1 -0
- package/core/capabilities-xml.js +331 -0
- package/core/client.d.ts +35 -2
- package/core/client.d.ts.map +1 -1
- package/core/client.js +167 -29
- package/core/error-classifications.d.ts +153 -0
- package/core/error-classifications.d.ts.map +1 -0
- package/core/error-classifications.js +140 -0
- package/core/error-code-registry.d.ts +158 -0
- package/core/error-code-registry.d.ts.map +1 -0
- package/core/error-code-registry.js +143 -0
- package/core/error-envelope.d.ts +68 -0
- package/core/error-envelope.d.ts.map +1 -0
- package/core/error-envelope.js +357 -0
- package/core/errors.d.ts +73 -25
- package/core/errors.d.ts.map +1 -1
- package/core/errors.js +113 -46
- package/core/geoparquet-sql.d.ts +190 -0
- package/core/geoparquet-sql.d.ts.map +1 -0
- package/core/geoparquet-sql.js +368 -0
- package/core/odata-key-path.d.ts +12 -0
- package/core/odata-key-path.d.ts.map +1 -0
- package/core/odata-key-path.js +28 -0
- package/core/odata-write-codec.d.ts +66 -0
- package/core/odata-write-codec.d.ts.map +1 -0
- package/core/odata-write-codec.js +1083 -0
- package/core/odata.d.ts +59 -7
- package/core/odata.d.ts.map +1 -1
- package/core/odata.js +431 -99
- package/core/ogc-endpoint-layout.d.ts +70 -0
- package/core/ogc-endpoint-layout.d.ts.map +1 -0
- package/core/ogc-endpoint-layout.js +173 -0
- package/core/ogc-features.d.ts.map +1 -1
- package/core/ogc-features.js +35 -17
- package/core/ogc-maps.d.ts +7 -0
- package/core/ogc-maps.d.ts.map +1 -1
- package/core/ogc-maps.js +46 -7
- package/core/ogc-processes.d.ts +2 -1
- package/core/ogc-processes.d.ts.map +1 -1
- package/core/ogc-processes.js +33 -5
- package/core/ogc-records.d.ts +9 -0
- package/core/ogc-records.d.ts.map +1 -1
- package/core/ogc-records.js +78 -29
- package/core/ogc-tiles.d.ts +10 -1
- package/core/ogc-tiles.d.ts.map +1 -1
- package/core/ogc-tiles.js +56 -17
- package/core/path-utils.d.ts +9 -0
- package/core/path-utils.d.ts.map +1 -1
- package/core/path-utils.js +19 -0
- package/core/protocol-transport.d.ts +1 -0
- package/core/protocol-transport.d.ts.map +1 -1
- package/core/request-pipeline.d.ts.map +1 -1
- package/core/request-pipeline.js +1 -1
- package/core/spatial-filter.d.ts +8 -4
- package/core/spatial-filter.d.ts.map +1 -1
- package/core/spatial-filter.js +206 -16
- package/core/stac-static.d.ts +55 -0
- package/core/stac-static.d.ts.map +1 -0
- package/core/stac-static.js +386 -0
- package/core/stac.d.ts +12 -0
- package/core/stac.d.ts.map +1 -1
- package/core/stac.js +45 -15
- package/core/surfaces.d.ts +13 -0
- package/core/surfaces.d.ts.map +1 -1
- package/core/surfaces.js +127 -16
- package/core/types.d.ts +174 -7
- package/core/types.d.ts.map +1 -1
- package/core/wfs-capabilities.d.ts +12 -0
- package/core/wfs-capabilities.d.ts.map +1 -1
- package/core/wfs-capabilities.js +22 -3
- package/core/wfs.d.ts +13 -0
- package/core/wfs.d.ts.map +1 -1
- package/core/wfs.js +35 -5
- package/core/wms-capabilities.d.ts +56 -84
- package/core/wms-capabilities.d.ts.map +1 -1
- package/core/wms-capabilities.js +212 -509
- package/core/wmts-capabilities.d.ts +62 -62
- package/core/wmts-capabilities.d.ts.map +1 -1
- package/core/wmts-capabilities.js +224 -371
- package/esri-compat/editor.d.ts +8 -0
- package/esri-compat/editor.d.ts.map +1 -1
- package/esri-compat/editor.js +13 -0
- package/esri-compat/feature-layer.d.ts +2 -0
- package/esri-compat/feature-layer.d.ts.map +1 -1
- package/esri-compat/feature-layer.js +1 -0
- package/esri-compat/identity-manager.d.ts +43 -0
- package/esri-compat/identity-manager.d.ts.map +1 -1
- package/esri-compat/identity-manager.js +131 -1
- package/esri-compat/layer-list.d.ts +11 -0
- package/esri-compat/layer-list.d.ts.map +1 -1
- package/esri-compat/layer-list.js +49 -0
- package/esri-compat/legend.d.ts +10 -0
- package/esri-compat/legend.d.ts.map +1 -1
- package/esri-compat/legend.js +27 -0
- package/esri-compat/oauth-info.d.ts +15 -0
- package/esri-compat/oauth-info.d.ts.map +1 -1
- package/esri-compat/oauth-info.js +27 -0
- package/esri-compat/portal.d.ts +197 -0
- package/esri-compat/portal.d.ts.map +1 -0
- package/esri-compat/portal.js +251 -0
- package/esri-compat/renderer-objects.d.ts +40 -0
- package/esri-compat/renderer-objects.d.ts.map +1 -0
- package/esri-compat/renderer-objects.js +62 -0
- package/esri-compat/sketch.d.ts +43 -0
- package/esri-compat/sketch.d.ts.map +1 -1
- package/esri-compat/sketch.js +46 -0
- package/esri-compat/snapping.d.ts +43 -0
- package/esri-compat/snapping.d.ts.map +1 -0
- package/esri-compat/snapping.js +45 -0
- package/esri-compat/url.d.ts.map +1 -1
- package/esri-compat/url.js +1 -1
- package/esri-compat/widget-host.d.ts +84 -0
- package/esri-compat/widget-host.d.ts.map +1 -0
- package/esri-compat/widget-host.js +159 -0
- package/filter-registry/index.d.ts +145 -0
- package/filter-registry/index.d.ts.map +1 -0
- package/filter-registry/index.js +531 -0
- package/generated-app/errors.d.ts +18 -2
- package/generated-app/errors.d.ts.map +1 -1
- package/generated-app/errors.js +44 -11
- package/map/automatic-mount-integration.d.ts +134 -0
- package/map/automatic-mount-integration.d.ts.map +1 -0
- package/map/automatic-mount-integration.js +305 -0
- package/map/automatic-source-strategy.d.ts +125 -0
- package/map/automatic-source-strategy.d.ts.map +1 -0
- package/map/automatic-source-strategy.js +494 -0
- package/map/data-to-map-bridge.d.ts +293 -0
- package/map/data-to-map-bridge.d.ts.map +1 -0
- package/map/data-to-map-bridge.js +817 -0
- package/map/geojson-projection.d.ts +33 -0
- package/map/geojson-projection.d.ts.map +1 -0
- package/map/geojson-projection.js +118 -0
- package/map/index.d.ts +14 -0
- package/map/index.d.ts.map +1 -1
- package/map/index.js +8 -0
- package/map/raster-source-spec.d.ts +30 -0
- package/map/raster-source-spec.d.ts.map +1 -0
- package/map/raster-source-spec.js +190 -0
- package/map/raster-source-strategy.d.ts +65 -0
- package/map/raster-source-strategy.d.ts.map +1 -0
- package/map/raster-source-strategy.js +232 -0
- package/map/source-to-maplibre.d.ts +91 -0
- package/map/source-to-maplibre.d.ts.map +1 -0
- package/map/source-to-maplibre.js +454 -0
- package/map/temporal-playback.d.ts +139 -0
- package/map/temporal-playback.d.ts.map +1 -0
- package/map/temporal-playback.js +247 -0
- package/package.json +19 -1
- package/query-planner/canonical.d.ts +7 -0
- package/query-planner/canonical.d.ts.map +1 -0
- package/query-planner/canonical.js +145 -0
- package/query-planner/cql2-json.d.ts +17 -0
- package/query-planner/cql2-json.d.ts.map +1 -0
- package/query-planner/cql2-json.js +646 -0
- package/query-planner/diagnostics.d.ts +35 -0
- package/query-planner/diagnostics.d.ts.map +1 -0
- package/query-planner/diagnostics.js +373 -0
- package/query-planner/duckdb.d.ts +79 -0
- package/query-planner/duckdb.d.ts.map +1 -0
- package/query-planner/duckdb.js +758 -0
- package/query-planner/execution-context.d.ts +5 -0
- package/query-planner/execution-context.d.ts.map +1 -0
- package/query-planner/execution-context.js +50 -0
- package/query-planner/executor.d.ts +5 -0
- package/query-planner/executor.d.ts.map +1 -0
- package/query-planner/executor.js +223 -0
- package/query-planner/geoservices.d.ts +91 -0
- package/query-planner/geoservices.d.ts.map +1 -0
- package/query-planner/geoservices.js +667 -0
- package/query-planner/grpc.d.ts +100 -0
- package/query-planner/grpc.d.ts.map +1 -0
- package/query-planner/grpc.js +736 -0
- package/query-planner/index.d.ts +44 -0
- package/query-planner/index.d.ts.map +1 -0
- package/query-planner/index.js +30 -0
- package/query-planner/ir.d.ts +20 -0
- package/query-planner/ir.d.ts.map +1 -0
- package/query-planner/ir.js +417 -0
- package/query-planner/local-aggregate.d.ts +5 -0
- package/query-planner/local-aggregate.d.ts.map +1 -0
- package/query-planner/local-aggregate.js +126 -0
- package/query-planner/odata.d.ts +48 -0
- package/query-planner/odata.d.ts.map +1 -0
- package/query-planner/odata.js +662 -0
- package/query-planner/ogc-compiler.d.ts +55 -0
- package/query-planner/ogc-compiler.d.ts.map +1 -0
- package/query-planner/ogc-compiler.js +480 -0
- package/query-planner/ogc-features.d.ts +53 -0
- package/query-planner/ogc-features.d.ts.map +1 -0
- package/query-planner/ogc-features.js +617 -0
- package/query-planner/planner.d.ts +17 -0
- package/query-planner/planner.d.ts.map +1 -0
- package/query-planner/planner.js +818 -0
- package/query-planner/resource.d.ts +94 -0
- package/query-planner/resource.d.ts.map +1 -0
- package/query-planner/resource.js +526 -0
- package/query-planner/semantic-canonical.d.ts +15 -0
- package/query-planner/semantic-canonical.d.ts.map +1 -0
- package/query-planner/semantic-canonical.js +62 -0
- package/query-planner/semantic-compat.d.ts +10 -0
- package/query-planner/semantic-compat.d.ts.map +1 -0
- package/query-planner/semantic-compat.js +35 -0
- package/query-planner/semantic-compiler.d.ts +64 -0
- package/query-planner/semantic-compiler.d.ts.map +1 -0
- package/query-planner/semantic-compiler.js +81 -0
- package/query-planner/semantic-literals.d.ts +30 -0
- package/query-planner/semantic-literals.d.ts.map +1 -0
- package/query-planner/semantic-literals.js +133 -0
- package/query-planner/semantic-types.d.ts +265 -0
- package/query-planner/semantic-types.d.ts.map +1 -0
- package/query-planner/semantic-types.js +1 -0
- package/query-planner/semantic.d.ts +54 -0
- package/query-planner/semantic.d.ts.map +1 -0
- package/query-planner/semantic.js +1421 -0
- package/query-planner/types.d.ts +560 -0
- package/query-planner/types.d.ts.map +1 -0
- package/query-planner/types.js +49 -0
- package/query-planner/wfs-semantic.d.ts +58 -0
- package/query-planner/wfs-semantic.d.ts.map +1 -0
- package/query-planner/wfs-semantic.js +547 -0
- package/query-planner/wfs.d.ts +6 -0
- package/query-planner/wfs.d.ts.map +1 -0
- package/query-planner/wfs.js +71 -0
- package/react/external-map.d.ts +67 -0
- package/react/external-map.d.ts.map +1 -0
- package/react/external-map.js +63 -0
- package/react/honua-map.d.ts.map +1 -1
- package/react/honua-map.js +3 -2
- package/react/honua-source-layer.d.ts +110 -0
- package/react/honua-source-layer.d.ts.map +1 -0
- package/react/honua-source-layer.js +101 -0
- package/react/hooks.d.ts +28 -0
- package/react/hooks.d.ts.map +1 -1
- package/react/hooks.js +26 -4
- package/react/index.d.ts +8 -0
- package/react/index.d.ts.map +1 -1
- package/react/index.js +5 -0
- package/react/query-cache.d.ts +26 -4
- package/react/query-cache.d.ts.map +1 -1
- package/react/query-cache.js +51 -8
- package/react/selection.d.ts +177 -0
- package/react/selection.d.ts.map +1 -0
- package/react/selection.js +0 -0
- package/react/use-mounted-source.d.ts +69 -0
- package/react/use-mounted-source.d.ts.map +1 -0
- package/react/use-mounted-source.js +346 -0
- package/runtime/edit-snapping.d.ts +107 -0
- package/runtime/edit-snapping.d.ts.map +1 -0
- package/runtime/edit-snapping.js +190 -0
- package/runtime/errors.d.ts +3 -2
- package/runtime/errors.d.ts.map +1 -1
- package/runtime/errors.js +19 -2
- package/runtime/index.d.ts +8 -2
- package/runtime/index.d.ts.map +1 -1
- package/runtime/index.js +4 -4
- package/runtime/load-package.d.ts.map +1 -1
- package/runtime/load-package.js +8 -0
- package/runtime/map-package-validation.d.ts +0 -13
- package/runtime/map-package-validation.d.ts.map +1 -1
- package/runtime/map-package-validation.js +0 -12
- package/runtime/map-package.d.ts +1 -1
- package/runtime/map-package.d.ts.map +1 -1
- package/runtime/maplibre-renderer.d.ts +41 -0
- package/runtime/maplibre-renderer.d.ts.map +1 -0
- package/runtime/maplibre-renderer.js +322 -0
- package/runtime/pmtiles-protocol.d.ts +77 -0
- package/runtime/pmtiles-protocol.d.ts.map +1 -0
- package/runtime/pmtiles-protocol.js +120 -0
- package/runtime/query-tiles.d.ts +2 -1
- package/runtime/query-tiles.d.ts.map +1 -1
- package/runtime/query-tiles.js +6 -2
- package/runtime/source-bridge.d.ts +4 -4
- package/runtime/source-bridge.d.ts.map +1 -1
- package/runtime/source-bridge.js +36 -56
- package/runtime/style-interactions.d.ts +3 -2
- package/runtime/style-interactions.d.ts.map +1 -1
- package/runtime/style-interactions.js +11 -3
- package/runtime/terra-draw-sketch.d.ts +275 -0
- package/runtime/terra-draw-sketch.d.ts.map +1 -0
- package/runtime/terra-draw-sketch.js +404 -0
- package/source-capability-registry.d.ts +1 -0
- package/source-capability-registry.js +1 -0
- package/source-capability-types.d.ts +186 -0
- package/source-capability-types.js +7 -0
- package/style/index.d.ts +2 -0
- package/style/index.d.ts.map +1 -1
- package/style/index.js +2 -0
- package/style/renderers.d.ts +326 -0
- package/style/renderers.d.ts.map +1 -0
- package/style/renderers.js +517 -0
- package/webmap/convert-renderer.d.ts +24 -3
- package/webmap/convert-renderer.d.ts.map +1 -1
- package/webmap/convert-renderer.js +93 -112
- package/webmap/index.d.ts +1 -1
- package/webmap/index.d.ts.map +1 -1
- package/webmap/index.js +1 -1
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { HonuaSdkError, mergeHonuaErrorContext } from "../core/error-envelope.js";
|
|
2
|
+
import { buildWmsRasterSourceSpec, buildWmtsRasterSourceSpec, validateRasterTileSize, } from "./raster-source-spec.js";
|
|
3
|
+
export class HonuaMapLibreRasterStrategyError extends HonuaSdkError {
|
|
4
|
+
code;
|
|
5
|
+
detail;
|
|
6
|
+
constructor(code, message, detail, options = {}) {
|
|
7
|
+
super(MAPLIBRE_RASTER_ERROR_CODES[code], message, {
|
|
8
|
+
...options,
|
|
9
|
+
context: mergeHonuaErrorContext(detail, options.context),
|
|
10
|
+
});
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.detail = detail;
|
|
13
|
+
this.name = "HonuaMapLibreRasterStrategyError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const MAPLIBRE_RASTER_ERROR_CODES = {
|
|
17
|
+
"unsupported-strategy": "map.raster-strategy.unsupported-strategy",
|
|
18
|
+
"capability-mismatch": "map.raster-strategy.capability-mismatch",
|
|
19
|
+
"missing-metadata": "map.raster-strategy.missing-metadata",
|
|
20
|
+
"invalid-option": "map.raster-strategy.invalid-option",
|
|
21
|
+
"source-conflict": "map.raster-strategy.source-conflict",
|
|
22
|
+
"layer-conflict": "map.raster-strategy.layer-conflict",
|
|
23
|
+
"map-mutation-failed": "map.raster-strategy.map-mutation-failed",
|
|
24
|
+
};
|
|
25
|
+
/** Select and project the exact raster strategy implied by source metadata. */
|
|
26
|
+
export function projectRasterSourceToMapLibre(descriptor, options = {}) {
|
|
27
|
+
validateOptions(options);
|
|
28
|
+
const strategy = selectStrategy(descriptor);
|
|
29
|
+
assertCapabilities(descriptor);
|
|
30
|
+
assertMetadata(descriptor, strategy);
|
|
31
|
+
const sourceId = options.sourceId ?? `honua-${safeId(descriptor.id)}`;
|
|
32
|
+
const layerId = options.layerId ?? `${sourceId}-raster`;
|
|
33
|
+
const source = buildSource(descriptor, strategy, options);
|
|
34
|
+
const layer = Object.freeze({
|
|
35
|
+
id: layerId,
|
|
36
|
+
type: "raster",
|
|
37
|
+
source: sourceId,
|
|
38
|
+
...(options.minzoom !== undefined ? { minzoom: options.minzoom } : {}),
|
|
39
|
+
...(options.maxzoom !== undefined ? { maxzoom: options.maxzoom } : {}),
|
|
40
|
+
...(options.paint ? { paint: { ...options.paint } } : {}),
|
|
41
|
+
...(options.layout ? { layout: { ...options.layout } } : {}),
|
|
42
|
+
metadata: { "honua:strategy": strategy, "honua:protocol": descriptor.protocol },
|
|
43
|
+
});
|
|
44
|
+
const diagnostic = Object.freeze({
|
|
45
|
+
code: "strategy-selected",
|
|
46
|
+
severity: "info",
|
|
47
|
+
stage: "project",
|
|
48
|
+
fidelity: "exact",
|
|
49
|
+
sourceId,
|
|
50
|
+
strategy,
|
|
51
|
+
message: `Selected exact ${strategy} strategy from source metadata.`,
|
|
52
|
+
detail: Object.freeze({ protocol: descriptor.protocol }),
|
|
53
|
+
});
|
|
54
|
+
return Object.freeze({
|
|
55
|
+
strategy,
|
|
56
|
+
sourceId,
|
|
57
|
+
layerId,
|
|
58
|
+
source: Object.freeze(source),
|
|
59
|
+
layer,
|
|
60
|
+
diagnostics: Object.freeze([diagnostic]),
|
|
61
|
+
state: "ready",
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Project and transactionally mount a metadata-selected raster source/layer. */
|
|
65
|
+
export function mountRasterSourceToMapLibre(map, descriptor, options = {}) {
|
|
66
|
+
const projection = projectRasterSourceToMapLibre(descriptor, options);
|
|
67
|
+
if (map.getSource(projection.sourceId) !== undefined) {
|
|
68
|
+
throw failure("source-conflict", `MapLibre source "${projection.sourceId}" already exists.`, projection);
|
|
69
|
+
}
|
|
70
|
+
if (map.getLayer(projection.layerId) !== undefined) {
|
|
71
|
+
throw failure("layer-conflict", `MapLibre layer "${projection.layerId}" already exists.`, projection);
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
map.addSource(projection.sourceId, projection.source);
|
|
75
|
+
map.addLayer(projection.layer, options.beforeId);
|
|
76
|
+
}
|
|
77
|
+
catch (cause) {
|
|
78
|
+
const rollbackErrors = rollbackMount(map, projection);
|
|
79
|
+
throw failure("map-mutation-failed", `Failed to mount raster source "${projection.sourceId}" transactionally.`, projection, { rollbackErrors }, cause);
|
|
80
|
+
}
|
|
81
|
+
let state = "ready";
|
|
82
|
+
const diagnostics = [...projection.diagnostics];
|
|
83
|
+
return {
|
|
84
|
+
strategy: projection.strategy,
|
|
85
|
+
sourceId: projection.sourceId,
|
|
86
|
+
layerId: projection.layerId,
|
|
87
|
+
get state() {
|
|
88
|
+
return state;
|
|
89
|
+
},
|
|
90
|
+
get diagnostics() {
|
|
91
|
+
return Object.freeze([...diagnostics]);
|
|
92
|
+
},
|
|
93
|
+
dispose() {
|
|
94
|
+
if (state === "disposed")
|
|
95
|
+
return;
|
|
96
|
+
const cleanupErrors = [];
|
|
97
|
+
removeIfPresent(map, "layer", projection.layerId, cleanupErrors);
|
|
98
|
+
removeIfPresent(map, "source", projection.sourceId, cleanupErrors);
|
|
99
|
+
if (cleanupErrors.length > 0) {
|
|
100
|
+
diagnostics.push(Object.freeze({
|
|
101
|
+
code: "cleanup-failed",
|
|
102
|
+
severity: "warning",
|
|
103
|
+
stage: "dispose",
|
|
104
|
+
fidelity: "unsupported",
|
|
105
|
+
sourceId: projection.sourceId,
|
|
106
|
+
strategy: projection.strategy,
|
|
107
|
+
message: "Raster mount cleanup did not remove every renderer object.",
|
|
108
|
+
detail: Object.freeze({ errors: cleanupErrors }),
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
state = "disposed";
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function selectStrategy(descriptor) {
|
|
116
|
+
switch (descriptor.protocol) {
|
|
117
|
+
case "maplibre-raster":
|
|
118
|
+
return "native-raster-tiles";
|
|
119
|
+
case "wms":
|
|
120
|
+
return "wms-raster";
|
|
121
|
+
case "wmts":
|
|
122
|
+
return "wmts-raster";
|
|
123
|
+
default:
|
|
124
|
+
throw new HonuaMapLibreRasterStrategyError("unsupported-strategy", `Protocol "${descriptor.protocol}" has no automatic raster strategy.`, { sourceId: descriptor.id, protocol: descriptor.protocol });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function assertCapabilities(descriptor) {
|
|
128
|
+
const missing = ["render", "tiles"].filter((capability) => !descriptor.capabilities.has(capability));
|
|
129
|
+
if (missing.length > 0) {
|
|
130
|
+
throw new HonuaMapLibreRasterStrategyError("capability-mismatch", `Source "${descriptor.id}" cannot use a raster strategy because required capabilities are missing.`, { sourceId: descriptor.id, missingCapabilities: missing });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function assertMetadata(descriptor, strategy) {
|
|
134
|
+
const missing = [];
|
|
135
|
+
if (!nonEmpty(descriptor.locator.url))
|
|
136
|
+
missing.push("locator.url");
|
|
137
|
+
if (strategy === "native-raster-tiles" && !isXyzTemplate(descriptor.locator.url)) {
|
|
138
|
+
missing.push("locator.url:{z}/{x}/{y}");
|
|
139
|
+
}
|
|
140
|
+
if ((strategy === "wms-raster" || strategy === "wmts-raster") && !nonEmpty(descriptor.locator.typeName)) {
|
|
141
|
+
missing.push("locator.typeName");
|
|
142
|
+
}
|
|
143
|
+
if (strategy === "wmts-raster" && !nonEmpty(descriptor.locator.tileMatrixSetId)) {
|
|
144
|
+
missing.push("locator.tileMatrixSetId");
|
|
145
|
+
}
|
|
146
|
+
if (missing.length > 0) {
|
|
147
|
+
throw new HonuaMapLibreRasterStrategyError("missing-metadata", `Source "${descriptor.id}" lacks metadata required by ${strategy}.`, { sourceId: descriptor.id, strategy, missing });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function buildSource(descriptor, strategy, options) {
|
|
151
|
+
if (strategy === "wms-raster")
|
|
152
|
+
return buildWmsRasterSourceSpec(descriptor, options);
|
|
153
|
+
if (strategy === "wmts-raster")
|
|
154
|
+
return buildWmtsRasterSourceSpec(descriptor, options);
|
|
155
|
+
return {
|
|
156
|
+
type: "raster",
|
|
157
|
+
tiles: [descriptor.locator.url],
|
|
158
|
+
tileSize: options.tileSize ?? 256,
|
|
159
|
+
...(options.minzoom !== undefined ? { minzoom: options.minzoom } : {}),
|
|
160
|
+
...(options.maxzoom !== undefined ? { maxzoom: options.maxzoom } : {}),
|
|
161
|
+
...(descriptor.attribution ? { attribution: descriptor.attribution } : {}),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function validateOptions(options) {
|
|
165
|
+
if (options.tileSize !== undefined) {
|
|
166
|
+
try {
|
|
167
|
+
validateRasterTileSize(options.tileSize);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
throw new HonuaMapLibreRasterStrategyError("invalid-option", error instanceof Error ? error.message : "tileSize is invalid.", { option: "tileSize", value: options.tileSize });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
for (const [name, value] of [
|
|
174
|
+
["minzoom", options.minzoom],
|
|
175
|
+
["maxzoom", options.maxzoom],
|
|
176
|
+
]) {
|
|
177
|
+
if (value !== undefined && (!Number.isInteger(value) || value < 0)) {
|
|
178
|
+
throw new HonuaMapLibreRasterStrategyError("invalid-option", `${name} must be a non-negative integer.`, {
|
|
179
|
+
option: name,
|
|
180
|
+
value,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (options.minzoom !== undefined && options.maxzoom !== undefined && options.minzoom > options.maxzoom) {
|
|
185
|
+
throw new HonuaMapLibreRasterStrategyError("invalid-option", "minzoom cannot exceed maxzoom.", {
|
|
186
|
+
minzoom: options.minzoom,
|
|
187
|
+
maxzoom: options.maxzoom,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function rollbackMount(map, projection) {
|
|
192
|
+
const errors = [];
|
|
193
|
+
removeIfPresent(map, "layer", projection.layerId, errors);
|
|
194
|
+
removeIfPresent(map, "source", projection.sourceId, errors);
|
|
195
|
+
return errors;
|
|
196
|
+
}
|
|
197
|
+
function removeIfPresent(map, kind, id, errors) {
|
|
198
|
+
try {
|
|
199
|
+
const present = kind === "layer" ? map.getLayer(id) : map.getSource(id);
|
|
200
|
+
if (present !== undefined) {
|
|
201
|
+
if (kind === "layer")
|
|
202
|
+
map.removeLayer(id);
|
|
203
|
+
else
|
|
204
|
+
map.removeSource(id);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
errors.push(`${kind}:${id}:${errorMessage(error)}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function failure(code, message, projection, extra = {}, cause) {
|
|
212
|
+
return new HonuaMapLibreRasterStrategyError(code, message, { sourceId: projection.sourceId, layerId: projection.layerId, strategy: projection.strategy, ...extra }, cause === undefined ? undefined : { cause });
|
|
213
|
+
}
|
|
214
|
+
function safeId(value) {
|
|
215
|
+
const normalized = value.trim().replace(/[^a-zA-Z0-9_-]+/g, "-");
|
|
216
|
+
let start = 0;
|
|
217
|
+
while (start < normalized.length && normalized[start] === "-")
|
|
218
|
+
start += 1;
|
|
219
|
+
let end = normalized.length;
|
|
220
|
+
while (end > start && normalized[end - 1] === "-")
|
|
221
|
+
end -= 1;
|
|
222
|
+
return normalized.slice(start, end) || "source";
|
|
223
|
+
}
|
|
224
|
+
function nonEmpty(value) {
|
|
225
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
226
|
+
}
|
|
227
|
+
function isXyzTemplate(value) {
|
|
228
|
+
return nonEmpty(value) && value.includes("{z}") && value.includes("{x}") && value.includes("{y}");
|
|
229
|
+
}
|
|
230
|
+
function errorMessage(error) {
|
|
231
|
+
return error instanceof Error ? error.message : String(error);
|
|
232
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plan-bound canonical Source → MapLibre GeoJSON workflow.
|
|
3
|
+
*
|
|
4
|
+
* This module is peer-injected and safe to import in Node/SSR/worker code: it
|
|
5
|
+
* never imports `maplibre-gl`. The first production slice deliberately covers
|
|
6
|
+
* exact feature-query plans; tile and realtime strategies remain separate.
|
|
7
|
+
*/
|
|
8
|
+
import type { Result, Source } from "../contract/types.js";
|
|
9
|
+
import { type HonuaErrorOptions, HonuaSdkError } from "../core/error-envelope.js";
|
|
10
|
+
import { type ExecuteQueryPlanOptions, type QueryExecutionPlanV1 } from "../query-planner/types.js";
|
|
11
|
+
import { type MapLibreGeometryKind } from "./geojson-projection.js";
|
|
12
|
+
export type MapLibreSourceStrategy = "geojson-query";
|
|
13
|
+
export type { MapLibreGeometryKind } from "./geojson-projection.js";
|
|
14
|
+
export type MapLibreSourceWorkflowState = "ready" | "empty" | "degraded" | "disposed";
|
|
15
|
+
export type MapLibreSourceDiagnosticCode = "strategy-selected" | "empty-result" | "transfer-limit" | "source-degraded" | "geometry-unsupported" | "geometry-mismatch" | "mixed-geometry" | "incremental-update" | "incremental-update-failed";
|
|
16
|
+
export interface MapLibreSourceDiagnostic {
|
|
17
|
+
readonly code: MapLibreSourceDiagnosticCode;
|
|
18
|
+
readonly severity: "info" | "warning";
|
|
19
|
+
readonly stage: "project" | "execute" | "update";
|
|
20
|
+
readonly fidelity: "exact" | "equivalent" | "unsupported";
|
|
21
|
+
readonly sourceId: string;
|
|
22
|
+
readonly planId: string;
|
|
23
|
+
readonly message: string;
|
|
24
|
+
readonly detail?: Readonly<Record<string, unknown>>;
|
|
25
|
+
}
|
|
26
|
+
export type MapLibreSourceAdapterErrorCode = "disposed" | "source-conflict" | "layer-conflict" | "unsupported-plan" | "invalid-option" | "map-mutation-failed";
|
|
27
|
+
/** A stable, machine-readable adapter failure. */
|
|
28
|
+
export declare class HonuaMapLibreSourceAdapterError extends HonuaSdkError {
|
|
29
|
+
readonly code: MapLibreSourceAdapterErrorCode;
|
|
30
|
+
readonly detail?: Readonly<Record<string, unknown>> | undefined;
|
|
31
|
+
constructor(code: MapLibreSourceAdapterErrorCode, message: string, detail?: Readonly<Record<string, unknown>> | undefined, options?: HonuaErrorOptions);
|
|
32
|
+
}
|
|
33
|
+
/** Minimal injected MapLibre map surface. */
|
|
34
|
+
export interface SourceToMapLibreMap {
|
|
35
|
+
getSource(id: string): unknown;
|
|
36
|
+
addSource(id: string, source: unknown): void;
|
|
37
|
+
removeSource(id: string): void;
|
|
38
|
+
getLayer(id: string): unknown;
|
|
39
|
+
addLayer(layer: unknown, beforeId?: string): void;
|
|
40
|
+
removeLayer(id: string): void;
|
|
41
|
+
}
|
|
42
|
+
export interface ProjectSourceToMapLibreOptions {
|
|
43
|
+
readonly sourceId?: string;
|
|
44
|
+
readonly layerId?: string;
|
|
45
|
+
readonly beforeId?: string;
|
|
46
|
+
readonly geometry?: MapLibreGeometryKind | "auto";
|
|
47
|
+
readonly cluster?: boolean;
|
|
48
|
+
readonly clusterRadius?: number;
|
|
49
|
+
readonly attribution?: string;
|
|
50
|
+
readonly paint?: Readonly<Record<string, unknown>>;
|
|
51
|
+
readonly layout?: Readonly<Record<string, unknown>>;
|
|
52
|
+
}
|
|
53
|
+
export interface MapLibreSourceProjection {
|
|
54
|
+
readonly strategy: MapLibreSourceStrategy;
|
|
55
|
+
readonly sourceId: string;
|
|
56
|
+
readonly layerId: string;
|
|
57
|
+
readonly planId: string;
|
|
58
|
+
readonly planFingerprint: string;
|
|
59
|
+
readonly sourceVersion?: string;
|
|
60
|
+
readonly schemaVersion?: string;
|
|
61
|
+
readonly authorizationScope: readonly string[];
|
|
62
|
+
readonly source: Readonly<Record<string, unknown>>;
|
|
63
|
+
readonly layers: readonly Readonly<Record<string, unknown>>[];
|
|
64
|
+
readonly diagnostics: readonly MapLibreSourceDiagnostic[];
|
|
65
|
+
readonly state: Exclude<MapLibreSourceWorkflowState, "disposed">;
|
|
66
|
+
}
|
|
67
|
+
export interface MountSourceToMapLibreOptions extends ProjectSourceToMapLibreOptions, ExecuteQueryPlanOptions {
|
|
68
|
+
}
|
|
69
|
+
export interface MountedMapLibreSource {
|
|
70
|
+
readonly strategy: MapLibreSourceStrategy;
|
|
71
|
+
readonly sourceId: string;
|
|
72
|
+
readonly layerIds: readonly string[];
|
|
73
|
+
readonly planId: string;
|
|
74
|
+
readonly planFingerprint: string;
|
|
75
|
+
readonly state: MapLibreSourceWorkflowState;
|
|
76
|
+
readonly diagnostics: readonly MapLibreSourceDiagnostic[];
|
|
77
|
+
refresh(options?: ExecuteQueryPlanOptions): Promise<MapLibreSourceProjection>;
|
|
78
|
+
dispose(): void;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Project an already-executed plan result into native MapLibre source/layers.
|
|
82
|
+
* This function is deterministic and does not mutate a map.
|
|
83
|
+
*/
|
|
84
|
+
export declare function projectSourceToMapLibre<T>(source: Source<T>, plan: QueryExecutionPlanV1, result: Result<T>, options?: ProjectSourceToMapLibreOptions): MapLibreSourceProjection;
|
|
85
|
+
/**
|
|
86
|
+
* Execute an accepted plan, mount its projection, and return one lifecycle.
|
|
87
|
+
* Omitted execution bindings inherit the accepted plan; explicit overrides
|
|
88
|
+
* remain fail-closed when they describe another context.
|
|
89
|
+
*/
|
|
90
|
+
export declare function mountSourceToMapLibre<T>(map: SourceToMapLibreMap, source: Source<T>, plan: QueryExecutionPlanV1, options?: MountSourceToMapLibreOptions): Promise<MountedMapLibreSource>;
|
|
91
|
+
//# sourceMappingURL=source-to-maplibre.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-to-maplibre.d.ts","sourceRoot":"","sources":["../../../src/map/source-to-maplibre.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,KAAK,iBAAiB,EAAE,aAAa,EAA0B,MAAM,2BAA2B,CAAC;AAM1G,OAAO,EACL,KAAK,uBAAuB,EAE5B,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,KAAK,oBAAoB,EAS1B,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,sBAAsB,GAAG,eAAe,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,MAAM,MAAM,2BAA2B,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;AAEtF,MAAM,MAAM,4BAA4B,GACpC,mBAAmB,GACnB,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,sBAAsB,GACtB,mBAAmB,GACnB,gBAAgB,GAChB,oBAAoB,GACpB,2BAA2B,CAAC;AAEhC,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,YAAY,GAAG,aAAa,CAAC;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,MAAM,8BAA8B,GACtC,UAAU,GACV,iBAAiB,GACjB,gBAAgB,GAChB,kBAAkB,GAClB,gBAAgB,GAChB,qBAAqB,CAAC;AAE1B,kDAAkD;AAClD,qBAAa,+BAAgC,SAAQ,aAAa;aAE9C,IAAI,EAAE,8BAA8B;aAEpC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAF1C,IAAI,EAAE,8BAA8B,EACpD,OAAO,EAAE,MAAM,EACC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,YAAA,EAC1D,OAAO,GAAE,iBAAsB;CAQlC;AAWD,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAC9B,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAMD,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAAC;IAClD,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IAC9D,QAAQ,CAAC,WAAW,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC1D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,4BAA6B,SAAQ,8BAA8B,EAAE,uBAAuB;CAAG;AAEhH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,2BAA2B,CAAC;IAC5C,QAAQ,CAAC,WAAW,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAC1D,OAAO,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC9E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,IAAI,EAAE,oBAAoB,EAC1B,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,OAAO,GAAE,8BAAmC,GAC3C,wBAAwB,CAgL1B;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAC3C,GAAG,EAAE,mBAAmB,EACxB,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,IAAI,EAAE,oBAAoB,EAC1B,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,qBAAqB,CAAC,CA2LhC"}
|