zenit-sdk 0.1.7 → 0.1.8

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/dist/index.js CHANGED
@@ -1824,6 +1824,14 @@ var LayerGeoJson = ({
1824
1824
  onEachFeature,
1825
1825
  onPolygonLabel
1826
1826
  }) => {
1827
+ const styleFnRef = (0, import_react.useRef)(styleFn);
1828
+ const onEachFeatureRef = (0, import_react.useRef)(onEachFeature);
1829
+ (0, import_react.useEffect)(() => {
1830
+ styleFnRef.current = styleFn;
1831
+ }, [styleFn]);
1832
+ (0, import_react.useEffect)(() => {
1833
+ onEachFeatureRef.current = onEachFeature;
1834
+ }, [onEachFeature]);
1827
1835
  const safeData = (0, import_react.useMemo)(() => sanitizeGeoJson(data, String(layerId)), [data, layerId]);
1828
1836
  const features = (0, import_react.useMemo)(() => safeData.features ?? [], [safeData]);
1829
1837
  const fillFeatures = (0, import_react.useMemo)(() => features.filter(isNonPointGeometry), [features]);
@@ -1867,14 +1875,14 @@ var LayerGeoJson = ({
1867
1875
  if (!isValidLatLng(latlng)) {
1868
1876
  return createInvisibleFallbackClusterMarker();
1869
1877
  }
1870
- const style = styleFn(feature, layerType, baseOpacity);
1878
+ const style = styleFnRef.current(feature, layerType, baseOpacity);
1871
1879
  return import_leaflet.default.marker(latlng, {
1872
1880
  icon: createPointDivIcon(style, isMobile),
1873
1881
  pane: clusterPaneName,
1874
1882
  interactive: true
1875
1883
  });
1876
1884
  },
1877
- onEachFeature
1885
+ onEachFeature: (feature, layer) => onEachFeatureRef.current(feature, layer)
1878
1886
  });
1879
1887
  clusterLayer.addLayer(geoJsonLayer);
1880
1888
  return () => {
@@ -1889,11 +1897,9 @@ var LayerGeoJson = ({
1889
1897
  isMobile,
1890
1898
  layerType,
1891
1899
  mapInstance,
1892
- onEachFeature,
1893
1900
  panesReady,
1894
1901
  pointsData,
1895
- resolvedPointsPane,
1896
- styleFn
1902
+ resolvedPointsPane
1897
1903
  ]);
1898
1904
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1899
1905
  fillData && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -2805,6 +2811,14 @@ function pickIntersectFeature(params) {
2805
2811
  selectedIdx: candidates.findIndex((candidate) => candidate === feature),
2806
2812
  reason
2807
2813
  });
2814
+ if (clickIntent === "point") {
2815
+ const anyPoint = candidates.find(
2816
+ (c) => isCandidateGeometryType(c, POINT_GEOMETRY_TYPES2)
2817
+ );
2818
+ if (anyPoint) {
2819
+ return getResult(anyPoint, "point:first-point-geometry");
2820
+ }
2821
+ }
2808
2822
  const sameLayer = candidates.filter(
2809
2823
  (candidate) => isLayerIdMatch(candidateLayerId(candidate), expectedLayerId)
2810
2824
  );
@@ -3241,7 +3255,7 @@ var ZenitMap = (0, import_react5.forwardRef)(({
3241
3255
  const ensureLayerPanes = (0, import_react5.useCallback)(
3242
3256
  (targetMap, targetLayers) => {
3243
3257
  const fillBaseZIndex = 400;
3244
- const pointsBaseZIndex = 700;
3258
+ const pointsBaseZIndex = 750;
3245
3259
  targetLayers.forEach((layer) => {
3246
3260
  const order = Number.isFinite(layer.displayOrder) ? layer.displayOrder : 0;
3247
3261
  const orderOffset = Math.max(0, Math.min(order, 150));
@@ -3325,7 +3339,10 @@ var ZenitMap = (0, import_react5.forwardRef)(({
3325
3339
  className: "zenit-map-tooltip"
3326
3340
  });
3327
3341
  }
3328
- layer.on("click", () => {
3342
+ layer.on("click", (e) => {
3343
+ if (clickIntent === "point") {
3344
+ import_leaflet4.default.DomEvent.stopPropagation(e);
3345
+ }
3329
3346
  if (featureInfoMode === "popup" && client && layerId !== void 0 && !extractDescriptionValue(feature?.properties) && feature?.geometry) {
3330
3347
  if (DEV_MODE2) {
3331
3348
  console.debug("[ZenitMap] click/intersect:start", {
@@ -3425,11 +3442,16 @@ var ZenitMap = (0, import_react5.forwardRef)(({
3425
3442
  properties: feature?.properties ?? void 0
3426
3443
  });
3427
3444
  }, [currentZoom, resolveLayerStyle]);
3428
- const makeStyleFnForLayer = (0, import_react5.useCallback)((layerId) => {
3429
- return (feature, layerType, baseOpacity) => {
3430
- return buildLayerStyle(layerId, baseOpacity ?? 1, feature, layerType);
3431
- };
3432
- }, [buildLayerStyle]);
3445
+ const styleFnByLayerId = (0, import_react5.useMemo)(() => {
3446
+ const next = /* @__PURE__ */ new Map();
3447
+ orderedLayers.forEach((layerState) => {
3448
+ const layerId = layerState.mapLayer.layerId;
3449
+ next.set(String(layerId), (feature, layerType, baseOpacity) => {
3450
+ return buildLayerStyle(layerId, baseOpacity ?? 1, feature, layerType);
3451
+ });
3452
+ });
3453
+ return next;
3454
+ }, [buildLayerStyle, orderedLayers]);
3433
3455
  (0, import_react5.useImperativeHandle)(ref, () => ({
3434
3456
  setLayerOpacity: (layerId, opacity) => {
3435
3457
  upsertUiOverride(layerId, { overrideOpacity: opacity });
@@ -3596,7 +3618,7 @@ var ZenitMap = (0, import_react5.forwardRef)(({
3596
3618
  fillPaneName,
3597
3619
  pointsPaneName,
3598
3620
  layerType,
3599
- styleFn: makeStyleFnForLayer(layerState.mapLayer.layerId),
3621
+ styleFn: styleFnByLayerId.get(String(layerState.mapLayer.layerId)) ?? ((feature, layerType2, baseOpacity2) => buildLayerStyle(layerState.mapLayer.layerId, baseOpacity2 ?? 1, feature, layerType2)),
3600
3622
  onEachFeature: overlayOnEachFeature,
3601
3623
  onPolygonLabel: labelKey ? (feature, layer) => {
3602
3624
  const geometryType = feature?.geometry?.type;
@@ -3740,7 +3762,7 @@ var ZenitMap = (0, import_react5.forwardRef)(({
3740
3762
  ZenitMap.displayName = "ZenitMap";
3741
3763
 
3742
3764
  // src/react/ZenitLayerManager.tsx
3743
- var import_react7 = __toESM(require("react"));
3765
+ var import_react8 = __toESM(require("react"));
3744
3766
 
3745
3767
  // src/react/icons.tsx
3746
3768
  var import_lucide_react = require("lucide-react");
@@ -4098,9 +4120,191 @@ var ZenitSelect = ({
4098
4120
  ] });
4099
4121
  };
4100
4122
 
4101
- // src/react/ZenitLayerManager.tsx
4123
+ // src/react/ui/ZenitCombobox.tsx
4124
+ var import_react7 = __toESM(require("react"));
4102
4125
  var import_jsx_runtime5 = require("react/jsx-runtime");
4126
+ var ZenitCombobox = ({
4127
+ options,
4128
+ value,
4129
+ onChange,
4130
+ placeholder = "Seleccionar\u2026",
4131
+ searchPlaceholder = "Buscar\u2026",
4132
+ disabled = false
4133
+ }) => {
4134
+ const rootRef = import_react7.default.useRef(null);
4135
+ const [isOpen, setIsOpen] = import_react7.default.useState(false);
4136
+ const [query, setQuery] = import_react7.default.useState("");
4137
+ const filteredOptions = import_react7.default.useMemo(() => {
4138
+ const normalized = query.trim().toLowerCase();
4139
+ if (!normalized) return options;
4140
+ return options.filter((option) => option.toLowerCase().includes(normalized));
4141
+ }, [options, query]);
4142
+ import_react7.default.useEffect(() => {
4143
+ if (!isOpen) return;
4144
+ const onClickOutside = (event) => {
4145
+ if (!rootRef.current?.contains(event.target)) {
4146
+ setIsOpen(false);
4147
+ }
4148
+ };
4149
+ const onEscape = (event) => {
4150
+ if (event.key === "Escape") {
4151
+ setIsOpen(false);
4152
+ }
4153
+ };
4154
+ document.addEventListener("mousedown", onClickOutside);
4155
+ document.addEventListener("keydown", onEscape);
4156
+ return () => {
4157
+ document.removeEventListener("mousedown", onClickOutside);
4158
+ document.removeEventListener("keydown", onEscape);
4159
+ };
4160
+ }, [isOpen]);
4161
+ import_react7.default.useEffect(() => {
4162
+ if (!isOpen) {
4163
+ setQuery("");
4164
+ }
4165
+ }, [isOpen]);
4166
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: rootRef, className: "zenit-combobox-root", style: { position: "relative" }, children: [
4167
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: `
4168
+ .zenit-combobox-trigger {
4169
+ width: 100%;
4170
+ min-height: 40px;
4171
+ height: 40px;
4172
+ border: 1px solid #cbd5e1;
4173
+ border-radius: 6px;
4174
+ background: #ffffff;
4175
+ color: #0f172a;
4176
+ display: inline-flex;
4177
+ align-items: center;
4178
+ padding: 0 12px;
4179
+ font-size: 14px;
4180
+ line-height: 1.25;
4181
+ cursor: pointer;
4182
+ text-align: left;
4183
+ }
4184
+ .zenit-combobox-trigger.is-placeholder {
4185
+ color: #64748b;
4186
+ }
4187
+ .zenit-combobox-trigger:disabled {
4188
+ opacity: 0.6;
4189
+ cursor: not-allowed;
4190
+ }
4191
+ .zenit-combobox-content {
4192
+ position: absolute;
4193
+ top: calc(100% + 6px);
4194
+ left: 0;
4195
+ right: 0;
4196
+ border: 1px solid #cbd5e1;
4197
+ border-radius: 6px;
4198
+ background: #ffffff;
4199
+ box-shadow: 0 10px 25px rgba(15, 23, 42, 0.18);
4200
+ padding: 8px;
4201
+ z-index: 4000;
4202
+ }
4203
+ .zenit-combobox-search {
4204
+ width: 100%;
4205
+ min-height: 36px;
4206
+ border: 1px solid #cbd5e1;
4207
+ border-radius: 6px;
4208
+ background: #ffffff;
4209
+ color: #0f172a;
4210
+ padding: 0 10px;
4211
+ font-size: 14px;
4212
+ margin-bottom: 8px;
4213
+ box-sizing: border-box;
4214
+ }
4215
+ .zenit-combobox-list {
4216
+ max-height: 220px;
4217
+ overflow-y: auto;
4218
+ }
4219
+ .zenit-combobox-item {
4220
+ width: 100%;
4221
+ border-radius: 4px;
4222
+ color: #0f172a;
4223
+ font-size: 14px;
4224
+ min-height: 34px;
4225
+ padding: 8px 10px;
4226
+ cursor: pointer;
4227
+ user-select: none;
4228
+ }
4229
+ .zenit-combobox-item:hover { background: #f1f5f9; }
4230
+ .zenit-combobox-item.is-selected { background: #e2e8f0; font-weight: 600; }
4231
+ ` }),
4232
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4233
+ "button",
4234
+ {
4235
+ type: "button",
4236
+ className: `zenit-combobox-trigger${!value ? " is-placeholder" : ""}`,
4237
+ disabled,
4238
+ onClick: () => !disabled && setIsOpen((prev) => !prev),
4239
+ children: value || placeholder
4240
+ }
4241
+ ),
4242
+ isOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "zenit-combobox-content", children: [
4243
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4244
+ "input",
4245
+ {
4246
+ className: "zenit-combobox-search",
4247
+ value: query,
4248
+ onChange: (event) => setQuery(event.target.value),
4249
+ placeholder: searchPlaceholder,
4250
+ autoFocus: true
4251
+ }
4252
+ ),
4253
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "zenit-combobox-list", children: [
4254
+ filteredOptions.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "zenit-combobox-item", style: { color: "#64748b", cursor: "default" }, children: "Sin coincidencias" }),
4255
+ filteredOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4256
+ "div",
4257
+ {
4258
+ className: `zenit-combobox-item${option === value ? " is-selected" : ""}`,
4259
+ onClick: () => {
4260
+ onChange(option);
4261
+ setIsOpen(false);
4262
+ },
4263
+ children: option
4264
+ },
4265
+ option
4266
+ ))
4267
+ ] })
4268
+ ] })
4269
+ ] });
4270
+ };
4271
+
4272
+ // src/react/ZenitLayerManager.tsx
4273
+ var import_jsx_runtime6 = require("react/jsx-runtime");
4103
4274
  var FLOAT_TOLERANCE = 1e-3;
4275
+ var CATALOG_FIELD_BLACKLIST = /* @__PURE__ */ new Set([
4276
+ "mapids",
4277
+ "mapId",
4278
+ "mapIDs",
4279
+ "mapId",
4280
+ "field",
4281
+ "Field",
4282
+ "objectid",
4283
+ "OBJECTID",
4284
+ "objectId",
4285
+ "gforms",
4286
+ "GFORMS",
4287
+ "nomina",
4288
+ "NOMINA",
4289
+ "shape_area",
4290
+ "SHAPE_AREA",
4291
+ "shape_leng",
4292
+ "SHAPE_LENG",
4293
+ "fid",
4294
+ "FID",
4295
+ "gid",
4296
+ "GID",
4297
+ "created_at",
4298
+ "updated_at",
4299
+ "created_user",
4300
+ "last_edited_user",
4301
+ "globalid",
4302
+ "GLOBALID"
4303
+ ]);
4304
+ function isFieldVisible(key) {
4305
+ return !CATALOG_FIELD_BLACKLIST.has(key) && !key.startsWith("_") && !key.startsWith("__");
4306
+ }
4307
+ var matchesWhitelist = (key, whitelist) => whitelist.some((w) => w.toUpperCase() === key.toUpperCase());
4104
4308
  function areEffectiveStatesEqual(a, b) {
4105
4309
  if (a.length !== b.length) return false;
4106
4310
  return a.every((state, index) => {
@@ -4139,26 +4343,29 @@ var ZenitLayerManager = ({
4139
4343
  layerFeatureCounts,
4140
4344
  mapLayers,
4141
4345
  onApplyLayerFilter,
4142
- onClearLayerFilter
4346
+ onClearLayerFilter,
4347
+ availableFilterLayers = [],
4348
+ filterFieldWhitelist = []
4143
4349
  }) => {
4144
- const [map, setMap] = (0, import_react7.useState)(null);
4145
- const [loadingMap, setLoadingMap] = (0, import_react7.useState)(false);
4146
- const [mapError, setMapError] = (0, import_react7.useState)(null);
4147
- const [layers, setLayers] = (0, import_react7.useState)([]);
4148
- const [activeTab, setActiveTab] = (0, import_react7.useState)("layers");
4149
- const [panelVisible, setPanelVisible] = (0, import_react7.useState)(true);
4150
- const [selectedFilterLayerId, setSelectedFilterLayerId] = (0, import_react7.useState)("");
4151
- const [selectedFilterField, setSelectedFilterField] = (0, import_react7.useState)("");
4152
- const [selectedFilterValue, setSelectedFilterValue] = (0, import_react7.useState)("");
4153
- const [catalogByLayerField, setCatalogByLayerField] = (0, import_react7.useState)({});
4154
- const [loadingCatalog, setLoadingCatalog] = (0, import_react7.useState)(false);
4155
- const [applyingFilter, setApplyingFilter] = (0, import_react7.useState)(false);
4156
- const [filterError, setFilterError] = (0, import_react7.useState)(null);
4157
- const [appliedFilter, setAppliedFilter] = (0, import_react7.useState)(null);
4158
- const catalogAbortRef = (0, import_react7.useRef)(null);
4159
- const lastEmittedStatesRef = (0, import_react7.useRef)(null);
4350
+ const [map, setMap] = (0, import_react8.useState)(null);
4351
+ const [loadingMap, setLoadingMap] = (0, import_react8.useState)(false);
4352
+ const [mapError, setMapError] = (0, import_react8.useState)(null);
4353
+ const [layers, setLayers] = (0, import_react8.useState)([]);
4354
+ const [activeTab, setActiveTab] = (0, import_react8.useState)("layers");
4355
+ const [panelVisible, setPanelVisible] = (0, import_react8.useState)(true);
4356
+ const [selectedFilterLayerId, setSelectedFilterLayerId] = (0, import_react8.useState)("");
4357
+ const [selectedFilterField, setSelectedFilterField] = (0, import_react8.useState)("");
4358
+ const [selectedFilterValue, setSelectedFilterValue] = (0, import_react8.useState)("");
4359
+ const [catalogByLayerField, setCatalogByLayerField] = (0, import_react8.useState)({});
4360
+ const [catalogFieldsByLayer, setCatalogFieldsByLayer] = (0, import_react8.useState)({});
4361
+ const [loadingCatalog, setLoadingCatalog] = (0, import_react8.useState)(false);
4362
+ const [applyingFilter, setApplyingFilter] = (0, import_react8.useState)(false);
4363
+ const [filterError, setFilterError] = (0, import_react8.useState)(null);
4364
+ const [appliedFilter, setAppliedFilter] = (0, import_react8.useState)(null);
4365
+ const catalogAbortRef = (0, import_react8.useRef)(null);
4366
+ const lastEmittedStatesRef = (0, import_react8.useRef)(null);
4160
4367
  const isControlled = Array.isArray(layerStates) && typeof onLayerStatesChange === "function";
4161
- const baseStates = (0, import_react7.useMemo)(
4368
+ const baseStates = (0, import_react8.useMemo)(
4162
4369
  () => initLayerStates(
4163
4370
  layers.map((entry) => ({
4164
4371
  ...entry.mapLayer,
@@ -4169,7 +4376,7 @@ var ZenitLayerManager = ({
4169
4376
  ),
4170
4377
  [layers]
4171
4378
  );
4172
- const overrideStates = (0, import_react7.useMemo)(
4379
+ const overrideStates = (0, import_react8.useMemo)(
4173
4380
  () => layers.map(
4174
4381
  (entry) => ({
4175
4382
  layerId: entry.mapLayer.layerId,
@@ -4179,11 +4386,11 @@ var ZenitLayerManager = ({
4179
4386
  ),
4180
4387
  [layers]
4181
4388
  );
4182
- const effectiveStates = (0, import_react7.useMemo)(
4389
+ const effectiveStates = (0, import_react8.useMemo)(
4183
4390
  () => layerStates ?? applyLayerOverrides(baseStates, overrideStates),
4184
4391
  [baseStates, layerStates, overrideStates]
4185
4392
  );
4186
- const layerMetaIndex = (0, import_react7.useMemo)(() => {
4393
+ const layerMetaIndex = (0, import_react8.useMemo)(() => {
4187
4394
  const index = /* @__PURE__ */ new Map();
4188
4395
  mapLayers?.forEach((entry) => {
4189
4396
  const key = String(entry.layerId);
@@ -4197,7 +4404,7 @@ var ZenitLayerManager = ({
4197
4404
  });
4198
4405
  return index;
4199
4406
  }, [map, mapLayers]);
4200
- const resolveUserOpacity = import_react7.default.useCallback((state) => {
4407
+ const resolveUserOpacity = import_react8.default.useCallback((state) => {
4201
4408
  if (typeof state.overrideOpacity === "number") return state.overrideOpacity;
4202
4409
  if (typeof state.overrideOpacity === "string") {
4203
4410
  const parsed = Number.parseFloat(state.overrideOpacity);
@@ -4205,7 +4412,7 @@ var ZenitLayerManager = ({
4205
4412
  }
4206
4413
  return state.opacity ?? 1;
4207
4414
  }, []);
4208
- const resolveEffectiveOpacity = import_react7.default.useCallback(
4415
+ const resolveEffectiveOpacity = import_react8.default.useCallback(
4209
4416
  (layerId, userOpacity) => {
4210
4417
  if (!autoOpacityOnZoom || typeof mapZoom !== "number") {
4211
4418
  return userOpacity;
@@ -4221,7 +4428,7 @@ var ZenitLayerManager = ({
4221
4428
  },
4222
4429
  [autoOpacityConfig, autoOpacityOnZoom, layerMetaIndex, mapZoom]
4223
4430
  );
4224
- const effectiveStatesWithZoom = (0, import_react7.useMemo)(() => {
4431
+ const effectiveStatesWithZoom = (0, import_react8.useMemo)(() => {
4225
4432
  if (!autoOpacityOnZoom || typeof mapZoom !== "number") {
4226
4433
  return effectiveStates;
4227
4434
  }
@@ -4235,7 +4442,7 @@ var ZenitLayerManager = ({
4235
4442
  };
4236
4443
  });
4237
4444
  }, [autoOpacityOnZoom, effectiveStates, mapZoom, resolveEffectiveOpacity, resolveUserOpacity]);
4238
- (0, import_react7.useEffect)(() => {
4445
+ (0, import_react8.useEffect)(() => {
4239
4446
  let cancelled = false;
4240
4447
  setLoadingMap(true);
4241
4448
  setMapError(null);
@@ -4267,12 +4474,12 @@ var ZenitLayerManager = ({
4267
4474
  cancelled = true;
4268
4475
  };
4269
4476
  }, [client.maps, mapId]);
4270
- (0, import_react7.useEffect)(() => {
4477
+ (0, import_react8.useEffect)(() => {
4271
4478
  if (!showUploadTab && activeTab === "upload") {
4272
4479
  setActiveTab("layers");
4273
4480
  }
4274
4481
  }, [activeTab, showUploadTab]);
4275
- (0, import_react7.useEffect)(() => {
4482
+ (0, import_react8.useEffect)(() => {
4276
4483
  if (isControlled) return;
4277
4484
  if (!onLayerStatesChange) return;
4278
4485
  const emitStates = autoOpacityOnZoom && typeof mapZoom === "number" ? effectiveStatesWithZoom : effectiveStates;
@@ -4290,7 +4497,7 @@ var ZenitLayerManager = ({
4290
4497
  mapZoom,
4291
4498
  onLayerStatesChange
4292
4499
  ]);
4293
- const updateLayerVisible = import_react7.default.useCallback(
4500
+ const updateLayerVisible = import_react8.default.useCallback(
4294
4501
  (layerId, visible) => {
4295
4502
  if (!onLayerStatesChange) return;
4296
4503
  const next = effectiveStates.map(
@@ -4300,7 +4507,7 @@ var ZenitLayerManager = ({
4300
4507
  },
4301
4508
  [effectiveStates, onLayerStatesChange]
4302
4509
  );
4303
- const updateLayerOpacity = import_react7.default.useCallback(
4510
+ const updateLayerOpacity = import_react8.default.useCallback(
4304
4511
  (layerId, opacity) => {
4305
4512
  if (!onLayerStatesChange) return;
4306
4513
  const adjustedOpacity = resolveEffectiveOpacity(layerId, opacity);
@@ -4311,7 +4518,7 @@ var ZenitLayerManager = ({
4311
4518
  },
4312
4519
  [effectiveStates, onLayerStatesChange, resolveEffectiveOpacity]
4313
4520
  );
4314
- const resolveFeatureCount = import_react7.default.useCallback(
4521
+ const resolveFeatureCount = import_react8.default.useCallback(
4315
4522
  (layerId, layer) => {
4316
4523
  const resolvedFeatureCount = layerFeatureCounts?.[layerId] ?? layerFeatureCounts?.[String(layerId)];
4317
4524
  if (typeof resolvedFeatureCount === "number") return resolvedFeatureCount;
@@ -4320,7 +4527,7 @@ var ZenitLayerManager = ({
4320
4527
  },
4321
4528
  [layerFeatureCounts]
4322
4529
  );
4323
- const decoratedLayers = (0, import_react7.useMemo)(() => {
4530
+ const decoratedLayers = (0, import_react8.useMemo)(() => {
4324
4531
  return layers.map((entry) => ({
4325
4532
  ...entry,
4326
4533
  effective: effectiveStates.find((state) => state.layerId === entry.mapLayer.layerId),
@@ -4349,7 +4556,7 @@ var ZenitLayerManager = ({
4349
4556
  return String(a.mapLayer.layerId).localeCompare(String(b.mapLayer.layerId));
4350
4557
  });
4351
4558
  }, [effectiveStates, layers, resolveFeatureCount]);
4352
- const hasPrefilters = (0, import_react7.useMemo)(() => {
4559
+ const hasPrefilters = (0, import_react8.useMemo)(() => {
4353
4560
  const candidates = [...mapLayers ?? [], ...map?.mapLayers ?? []];
4354
4561
  return candidates.some((layer) => {
4355
4562
  const record = layer;
@@ -4357,23 +4564,32 @@ var ZenitLayerManager = ({
4357
4564
  return !!applied && typeof applied === "object" && Object.keys(applied).length > 0;
4358
4565
  });
4359
4566
  }, [map?.mapLayers, mapLayers]);
4360
- const filterableLayers = (0, import_react7.useMemo)(() => {
4567
+ const filterableLayers = (0, import_react8.useMemo)(() => {
4568
+ const forcedLayerIds = new Set(availableFilterLayers.map((layerId) => String(layerId)));
4361
4569
  return decoratedLayers.filter((entry) => {
4362
4570
  const prefilters = entry.mapLayer.layerConfig?.prefilters;
4363
- return !!prefilters && Object.keys(prefilters).length > 0;
4571
+ if (prefilters && Object.keys(prefilters).length > 0) return true;
4572
+ if (forcedLayerIds.has(String(entry.mapLayer.layerId))) return true;
4573
+ const layerType = (entry.mapLayer.layerType ?? entry.layer?.layerType ?? "").toString().toLowerCase();
4574
+ return layerType === "multipolygon";
4364
4575
  });
4365
- }, [decoratedLayers]);
4366
- const selectedFilterLayer = (0, import_react7.useMemo)(
4576
+ }, [availableFilterLayers, decoratedLayers]);
4577
+ const selectedFilterLayer = (0, import_react8.useMemo)(
4367
4578
  () => filterableLayers.find((layer) => String(layer.mapLayer.layerId) === selectedFilterLayerId) ?? null,
4368
4579
  [filterableLayers, selectedFilterLayerId]
4369
4580
  );
4370
- const filterFields = (0, import_react7.useMemo)(() => {
4371
- const prefilters = selectedFilterLayer?.mapLayer.layerConfig?.prefilters;
4372
- return prefilters ? Object.keys(prefilters) : [];
4373
- }, [selectedFilterLayer]);
4581
+ const filterFields = (0, import_react8.useMemo)(() => {
4582
+ if (!selectedFilterLayer) return [];
4583
+ const prefilters = selectedFilterLayer.mapLayer.layerConfig?.prefilters;
4584
+ if (prefilters) {
4585
+ const keys = Object.keys(prefilters);
4586
+ if (keys.length > 0) return keys;
4587
+ }
4588
+ return catalogFieldsByLayer[String(selectedFilterLayer.mapLayer.layerId)] ?? [];
4589
+ }, [catalogFieldsByLayer, selectedFilterLayer]);
4374
4590
  const activeCatalogKey = selectedFilterLayer ? `${selectedFilterLayer.mapLayer.layerId}:${selectedFilterField}` : null;
4375
4591
  const activeCatalogValues = activeCatalogKey ? catalogByLayerField[activeCatalogKey] ?? [] : [];
4376
- const extractCatalogValues = import_react7.default.useCallback((catalogData, field) => {
4592
+ const extractCatalogValues = import_react8.default.useCallback((catalogData, field) => {
4377
4593
  const values = /* @__PURE__ */ new Set();
4378
4594
  const pushValue = (value) => {
4379
4595
  if (value === null || value === void 0) return;
@@ -4410,7 +4626,46 @@ var ZenitLayerManager = ({
4410
4626
  }
4411
4627
  return [...values].sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
4412
4628
  }, []);
4413
- (0, import_react7.useEffect)(() => {
4629
+ const extractCatalogFieldMap = import_react8.default.useCallback((catalogData, whitelist) => {
4630
+ if (!catalogData || typeof catalogData !== "object") return {};
4631
+ const maybeRecord = catalogData;
4632
+ const fieldNames = /* @__PURE__ */ new Set();
4633
+ Object.entries(maybeRecord).forEach(([key, value]) => {
4634
+ if (Array.isArray(value) && key !== "items" && key !== "features") {
4635
+ if (isFieldVisible(key)) fieldNames.add(key);
4636
+ }
4637
+ });
4638
+ const items = maybeRecord.items;
4639
+ if (Array.isArray(items)) {
4640
+ items.forEach((item) => {
4641
+ if (!item || typeof item !== "object") return;
4642
+ const row = item;
4643
+ if (row.field !== null && row.field !== void 0) {
4644
+ const fieldName = String(row.field).trim();
4645
+ if (fieldName && isFieldVisible(fieldName)) fieldNames.add(fieldName);
4646
+ }
4647
+ });
4648
+ }
4649
+ const features = maybeRecord.features;
4650
+ if (Array.isArray(features)) {
4651
+ features.forEach((feature) => {
4652
+ if (!feature || typeof feature !== "object") return;
4653
+ const properties = feature.properties;
4654
+ if (!properties || typeof properties !== "object") return;
4655
+ Object.keys(properties).forEach((key) => {
4656
+ if (isFieldVisible(key)) fieldNames.add(key);
4657
+ });
4658
+ });
4659
+ }
4660
+ const normalizedWhitelist = (whitelist ?? []).map((item) => String(item).trim()).filter(Boolean);
4661
+ const resolvedFieldNames = normalizedWhitelist.length > 0 ? [...fieldNames].filter((field) => matchesWhitelist(field, normalizedWhitelist)) : [...fieldNames];
4662
+ const next = {};
4663
+ resolvedFieldNames.forEach((field) => {
4664
+ next[field] = extractCatalogValues(catalogData, field);
4665
+ });
4666
+ return next;
4667
+ }, [extractCatalogValues]);
4668
+ (0, import_react8.useEffect)(() => {
4414
4669
  if (!filterableLayers.length) {
4415
4670
  setSelectedFilterLayerId("");
4416
4671
  return;
@@ -4419,7 +4674,7 @@ var ZenitLayerManager = ({
4419
4674
  setSelectedFilterLayerId(String(filterableLayers[0].mapLayer.layerId));
4420
4675
  }
4421
4676
  }, [filterableLayers, selectedFilterLayerId]);
4422
- (0, import_react7.useEffect)(() => {
4677
+ (0, import_react8.useEffect)(() => {
4423
4678
  if (!filterFields.length) {
4424
4679
  setSelectedFilterField("");
4425
4680
  return;
@@ -4429,24 +4684,42 @@ var ZenitLayerManager = ({
4429
4684
  setSelectedFilterValue("");
4430
4685
  }
4431
4686
  }, [filterFields, selectedFilterField]);
4432
- (0, import_react7.useEffect)(() => {
4687
+ (0, import_react8.useEffect)(() => {
4433
4688
  if (hasPrefilters && activeTab === "filters") {
4434
4689
  setActiveTab("layers");
4435
4690
  }
4436
4691
  }, [activeTab, hasPrefilters]);
4437
- (0, import_react7.useEffect)(() => {
4692
+ (0, import_react8.useEffect)(() => {
4438
4693
  if (activeTab !== "filters") return;
4439
- if (!selectedFilterLayer || !selectedFilterField || !activeCatalogKey) return;
4440
- if (catalogByLayerField[activeCatalogKey]) return;
4694
+ if (!selectedFilterLayer) return;
4695
+ const layerId = selectedFilterLayer.mapLayer.layerId;
4696
+ const layerKey = String(layerId);
4697
+ const prefilters = selectedFilterLayer.mapLayer.layerConfig?.prefilters;
4698
+ const requiresCatalogForFields = !prefilters || Object.keys(prefilters).length === 0;
4699
+ const hasFieldsLoaded = (catalogFieldsByLayer[layerKey]?.length ?? 0) > 0;
4700
+ const needsLayerCatalog = requiresCatalogForFields && !hasFieldsLoaded;
4701
+ const needsFieldCatalog = Boolean(activeCatalogKey && selectedFilterField && !catalogByLayerField[activeCatalogKey]);
4702
+ if (!needsLayerCatalog && !needsFieldCatalog) return;
4441
4703
  catalogAbortRef.current?.abort();
4442
4704
  const controller = new AbortController();
4443
4705
  catalogAbortRef.current = controller;
4444
4706
  setLoadingCatalog(true);
4445
4707
  setFilterError(null);
4446
- client.layers.getLayerFeaturesCatalog(selectedFilterLayer.mapLayer.layerId).then((response) => {
4708
+ client.layers.getLayerFeaturesCatalog(layerId).then((response) => {
4447
4709
  if (controller.signal.aborted) return;
4448
- const values = extractCatalogValues(response.data, selectedFilterField);
4449
- setCatalogByLayerField((prev) => ({ ...prev, [activeCatalogKey]: values }));
4710
+ const fieldMap = extractCatalogFieldMap(response.data, filterFieldWhitelist);
4711
+ const fields = Object.keys(fieldMap);
4712
+ setCatalogFieldsByLayer((prev) => ({ ...prev, [layerKey]: fields }));
4713
+ setCatalogByLayerField((prev) => {
4714
+ const next = { ...prev };
4715
+ fields.forEach((field) => {
4716
+ const key = `${layerKey}:${field}`;
4717
+ if (!next[key]) {
4718
+ next[key] = fieldMap[field] ?? [];
4719
+ }
4720
+ });
4721
+ return next;
4722
+ });
4450
4723
  }).catch((error) => {
4451
4724
  if (controller.signal.aborted) return;
4452
4725
  const message = error instanceof Error ? error.message : "No se pudo cargar el cat\xE1logo";
@@ -4457,8 +4730,8 @@ var ZenitLayerManager = ({
4457
4730
  return () => {
4458
4731
  controller.abort();
4459
4732
  };
4460
- }, [activeCatalogKey, activeTab, catalogByLayerField, client.layers, extractCatalogValues, selectedFilterField, selectedFilterLayer]);
4461
- const handleApplyFilter = import_react7.default.useCallback(async () => {
4733
+ }, [activeCatalogKey, activeTab, catalogByLayerField, catalogFieldsByLayer, client.layers, extractCatalogFieldMap, filterFieldWhitelist, selectedFilterField, selectedFilterLayer]);
4734
+ const handleApplyFilter = import_react8.default.useCallback(async () => {
4462
4735
  if (!selectedFilterLayer || !selectedFilterField || !selectedFilterValue || !onApplyLayerFilter) return;
4463
4736
  setApplyingFilter(true);
4464
4737
  setFilterError(null);
@@ -4480,7 +4753,7 @@ var ZenitLayerManager = ({
4480
4753
  setApplyingFilter(false);
4481
4754
  }
4482
4755
  }, [onApplyLayerFilter, selectedFilterField, selectedFilterLayer, selectedFilterValue]);
4483
- const handleClearFilter = import_react7.default.useCallback(async () => {
4756
+ const handleClearFilter = import_react8.default.useCallback(async () => {
4484
4757
  if (!selectedFilterLayer) return;
4485
4758
  setApplyingFilter(true);
4486
4759
  setFilterError(null);
@@ -4495,7 +4768,7 @@ var ZenitLayerManager = ({
4495
4768
  setApplyingFilter(false);
4496
4769
  }
4497
4770
  }, [onClearLayerFilter, selectedFilterField, selectedFilterLayer]);
4498
- const resolveLayerStyle = import_react7.default.useCallback(
4771
+ const resolveLayerStyle = import_react8.default.useCallback(
4499
4772
  (layerId) => {
4500
4773
  const layerKey = String(layerId);
4501
4774
  const fromProp = mapLayers?.find((entry) => String(entry.layerId) === layerKey)?.style;
@@ -4509,6 +4782,22 @@ var ZenitLayerManager = ({
4509
4782
  },
4510
4783
  [map, mapLayers]
4511
4784
  );
4785
+ const allVisible = decoratedLayers.every(
4786
+ (entry) => entry.effective?.visible ?? false
4787
+ );
4788
+ const anyVisible = decoratedLayers.some(
4789
+ (entry) => entry.effective?.visible ?? false
4790
+ );
4791
+ const handleToggleAllLayers = import_react8.default.useCallback(() => {
4792
+ if (!onLayerStatesChange) return;
4793
+ const nextVisible = !anyVisible;
4794
+ const next = effectiveStates.map((state) => ({
4795
+ ...state,
4796
+ visible: nextVisible,
4797
+ overrideVisible: nextVisible
4798
+ }));
4799
+ onLayerStatesChange(next);
4800
+ }, [anyVisible, effectiveStates, onLayerStatesChange]);
4512
4801
  const panelStyle = {
4513
4802
  width: 360,
4514
4803
  borderLeft: side === "right" ? "1px solid #e2e8f0" : void 0,
@@ -4525,10 +4814,10 @@ var ZenitLayerManager = ({
4525
4814
  ...height ? { height } : {}
4526
4815
  };
4527
4816
  if (loadingMap) {
4528
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className, style: panelStyle, children: "Cargando capas\u2026" });
4817
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className, style: panelStyle, children: "Cargando capas\u2026" });
4529
4818
  }
4530
4819
  if (mapError) {
4531
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className, style: { ...panelStyle, color: "#c53030" }, children: [
4820
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className, style: { ...panelStyle, color: "#c53030" }, children: [
4532
4821
  "Error al cargar mapa: ",
4533
4822
  mapError
4534
4823
  ] });
@@ -4546,7 +4835,7 @@ var ZenitLayerManager = ({
4546
4835
  boxShadow: "0 1px 0 rgba(148, 163, 184, 0.25)"
4547
4836
  };
4548
4837
  const renderLayerCards = () => {
4549
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: decoratedLayers.map((layerState) => {
4838
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: decoratedLayers.map((layerState) => {
4550
4839
  const layerId = layerState.mapLayer.layerId;
4551
4840
  const layerName = layerState.layerName ?? `Capa ${layerId}`;
4552
4841
  const visible = layerState.effective?.visible ?? false;
@@ -4556,7 +4845,7 @@ var ZenitLayerManager = ({
4556
4845
  const muted = !visible;
4557
4846
  const opacityPercent = Math.round(userOpacity * 100);
4558
4847
  const sliderBackground = `linear-gradient(to right, ${layerColor} 0%, ${layerColor} ${opacityPercent}%, #e5e7eb ${opacityPercent}%, #e5e7eb 100%)`;
4559
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
4848
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4560
4849
  "div",
4561
4850
  {
4562
4851
  className: `zlm-card${muted ? " is-muted" : ""}`,
@@ -4571,9 +4860,9 @@ var ZenitLayerManager = ({
4571
4860
  width: "100%"
4572
4861
  },
4573
4862
  children: [
4574
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", gap: 12 }, children: [
4575
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", gap: 10, alignItems: "flex-start", minWidth: 0, flex: 1 }, children: [
4576
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4863
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", gap: 12 }, children: [
4864
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", gap: 10, alignItems: "flex-start", minWidth: 0, flex: 1 }, children: [
4865
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4577
4866
  "div",
4578
4867
  {
4579
4868
  style: {
@@ -4588,7 +4877,7 @@ var ZenitLayerManager = ({
4588
4877
  title: "Color de la capa"
4589
4878
  }
4590
4879
  ),
4591
- showLayerVisibilityIcon && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4880
+ showLayerVisibilityIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4592
4881
  "button",
4593
4882
  {
4594
4883
  type: "button",
@@ -4599,11 +4888,11 @@ var ZenitLayerManager = ({
4599
4888
  )
4600
4889
  ),
4601
4890
  "aria-label": visible ? "Ocultar capa" : "Mostrar capa",
4602
- children: visible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Eye, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.EyeOff, { size: 16 })
4891
+ children: visible ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.Eye, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.EyeOff, { size: 16 })
4603
4892
  }
4604
4893
  ),
4605
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { minWidth: 0, flex: 1 }, children: [
4606
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4894
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { minWidth: 0, flex: 1 }, children: [
4895
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4607
4896
  "div",
4608
4897
  {
4609
4898
  className: "zlm-layer-name",
@@ -4621,26 +4910,26 @@ var ZenitLayerManager = ({
4621
4910
  children: layerName
4622
4911
  }
4623
4912
  ),
4624
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { color: muted ? "#94a3b8" : "#64748b", fontSize: 12 }, children: [
4913
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { color: muted ? "#94a3b8" : "#64748b", fontSize: 12 }, children: [
4625
4914
  "ID ",
4626
4915
  layerId
4627
4916
  ] })
4628
4917
  ] })
4629
4918
  ] }),
4630
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", alignItems: "flex-start", gap: 6, flexShrink: 0 }, children: typeof featureCount === "number" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "zlm-badge", children: [
4919
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", alignItems: "flex-start", gap: 6, flexShrink: 0 }, children: typeof featureCount === "number" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "zlm-badge", children: [
4631
4920
  featureCount.toLocaleString(),
4632
4921
  " features"
4633
4922
  ] }) })
4634
4923
  ] }),
4635
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { display: "flex", gap: 10, alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { flex: 1 }, children: [
4636
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 6, color: "#64748b", fontSize: 12 }, children: [
4637
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Opacidad" }),
4638
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
4924
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { display: "flex", gap: 10, alignItems: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { flex: 1 }, children: [
4925
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", marginBottom: 6, color: "#64748b", fontSize: 12 }, children: [
4926
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Opacidad" }),
4927
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
4639
4928
  opacityPercent,
4640
4929
  "%"
4641
4930
  ] })
4642
4931
  ] }),
4643
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4932
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4644
4933
  "input",
4645
4934
  {
4646
4935
  className: "zlm-range",
@@ -4678,8 +4967,8 @@ var ZenitLayerManager = ({
4678
4967
  );
4679
4968
  }) });
4680
4969
  };
4681
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: ["zenit-layer-manager", className].filter(Boolean).join(" "), style: panelStyle, children: [
4682
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("style", { children: `
4970
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: ["zenit-layer-manager", className].filter(Boolean).join(" "), style: panelStyle, children: [
4971
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("style", { children: `
4683
4972
  .zenit-layer-manager .zlm-card {
4684
4973
  transition: box-shadow 0.2s ease, transform 0.2s ease, opacity 0.2s ease;
4685
4974
  box-shadow: 0 6px 16px rgba(15, 23, 42, 0.08);
@@ -4774,16 +5063,16 @@ var ZenitLayerManager = ({
4774
5063
  outline-offset: 2px;
4775
5064
  }
4776
5065
  ` }),
4777
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: headerStyle, children: [
4778
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
4779
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
4780
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { fontWeight: 800, fontSize: 16, color: "#0f172a" }, children: "Gesti\xF3n de Capas" }),
4781
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { color: "#64748b", fontSize: 12 }, children: [
5066
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: headerStyle, children: [
5067
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [
5068
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
5069
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { fontWeight: 800, fontSize: 16, color: "#0f172a" }, children: "Gesti\xF3n de Capas" }),
5070
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { color: "#64748b", fontSize: 12 }, children: [
4782
5071
  "Mapa #",
4783
5072
  map.id
4784
5073
  ] })
4785
5074
  ] }),
4786
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5075
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4787
5076
  "button",
4788
5077
  {
4789
5078
  type: "button",
@@ -4791,13 +5080,13 @@ var ZenitLayerManager = ({
4791
5080
  className: "zlm-panel-toggle",
4792
5081
  "aria-label": panelVisible ? "Ocultar panel de capas" : "Mostrar panel de capas",
4793
5082
  children: [
4794
- panelVisible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Eye, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.EyeOff, { size: 16 }),
5083
+ panelVisible ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.Eye, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.EyeOff, { size: 16 }),
4795
5084
  panelVisible ? "Ocultar" : "Mostrar"
4796
5085
  ]
4797
5086
  }
4798
5087
  )
4799
5088
  ] }),
4800
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5089
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4801
5090
  "div",
4802
5091
  {
4803
5092
  style: {
@@ -4810,38 +5099,38 @@ var ZenitLayerManager = ({
4810
5099
  background: "#f1f5f9"
4811
5100
  },
4812
5101
  children: [
4813
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5102
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4814
5103
  "button",
4815
5104
  {
4816
5105
  type: "button",
4817
5106
  className: `zlm-tab${activeTab === "layers" ? " is-active" : ""}`,
4818
5107
  onClick: () => setActiveTab("layers"),
4819
5108
  children: [
4820
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Layers, { size: 16 }),
5109
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.Layers, { size: 16 }),
4821
5110
  "Capas"
4822
5111
  ]
4823
5112
  }
4824
5113
  ),
4825
- showUploadTab && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5114
+ showUploadTab && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4826
5115
  "button",
4827
5116
  {
4828
5117
  type: "button",
4829
5118
  className: `zlm-tab${activeTab === "upload" ? " is-active" : ""}`,
4830
5119
  onClick: () => setActiveTab("upload"),
4831
5120
  children: [
4832
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Upload, { size: 16 }),
5121
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.Upload, { size: 16 }),
4833
5122
  "Subir"
4834
5123
  ]
4835
5124
  }
4836
5125
  ),
4837
- !hasPrefilters && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
5126
+ !hasPrefilters && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
4838
5127
  "button",
4839
5128
  {
4840
5129
  type: "button",
4841
5130
  className: `zlm-tab${activeTab === "filters" ? " is-active" : ""}`,
4842
5131
  onClick: () => setActiveTab("filters"),
4843
5132
  children: [
4844
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react.Layers, { size: 16 }),
5133
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.Layers, { size: 16 }),
4845
5134
  "Filtros"
4846
5135
  ]
4847
5136
  }
@@ -4850,13 +5139,29 @@ var ZenitLayerManager = ({
4850
5139
  }
4851
5140
  )
4852
5141
  ] }),
4853
- panelVisible && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { style: { padding: "12px 10px 18px", overflowY: "auto", flex: 1, minHeight: 0 }, children: [
4854
- hasPrefilters && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "zlm-badge", style: { marginBottom: 10 }, children: "Este mapa ya incluye filtros preaplicados" }),
4855
- activeTab === "layers" && renderLayerCards(),
4856
- !hasPrefilters && activeTab === "filters" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "zlm-filter-panel", style: { display: "flex", flexDirection: "column", gap: 12, background: "#fff", border: "1px solid #e2e8f0", borderRadius: 12, padding: 12 }, children: !filterableLayers.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: "#64748b", fontSize: 13 }, children: "No hay filtros disponibles para las capas de este mapa." }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
4857
- filterableLayers.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
5142
+ panelVisible && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { padding: "12px 10px 18px", overflowY: "auto", flex: 1, minHeight: 0 }, children: [
5143
+ hasPrefilters && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "zlm-badge", style: { marginBottom: 10 }, children: "Este mapa ya incluye filtros preaplicados" }),
5144
+ activeTab === "layers" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5145
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { marginBottom: 10 }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5146
+ "button",
5147
+ {
5148
+ type: "button",
5149
+ className: "zlm-panel-toggle",
5150
+ onClick: handleToggleAllLayers,
5151
+ disabled: decoratedLayers.length === 0,
5152
+ "aria-label": anyVisible ? "Ocultar todas las capas" : "Mostrar todas las capas",
5153
+ children: [
5154
+ anyVisible ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.EyeOff, { size: 14 }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react.Eye, { size: 14 }),
5155
+ anyVisible ? "Ocultar todas" : "Mostrar todas"
5156
+ ]
5157
+ }
5158
+ ) }),
5159
+ renderLayerCards()
5160
+ ] }),
5161
+ !hasPrefilters && activeTab === "filters" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "zlm-filter-panel", style: { display: "flex", flexDirection: "column", gap: 12, background: "#fff", border: "1px solid #e2e8f0", borderRadius: 12, padding: 12 }, children: !filterableLayers.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { color: "#64748b", fontSize: 13 }, children: "No hay filtros disponibles para las capas de este mapa." }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5162
+ filterableLayers.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
4858
5163
  "Capa",
4859
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5164
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4860
5165
  ZenitSelect,
4861
5166
  {
4862
5167
  ariaLabel: "Seleccionar capa para filtrar",
@@ -4869,9 +5174,9 @@ var ZenitLayerManager = ({
4869
5174
  }
4870
5175
  )
4871
5176
  ] }),
4872
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
5177
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
4873
5178
  "Campo",
4874
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5179
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4875
5180
  ZenitSelect,
4876
5181
  {
4877
5182
  ariaLabel: "Seleccionar campo de filtrado",
@@ -4884,34 +5189,31 @@ var ZenitLayerManager = ({
4884
5189
  }
4885
5190
  )
4886
5191
  ] }),
4887
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
5192
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { style: { display: "flex", flexDirection: "column", gap: 6, fontSize: 12, color: "#475569" }, children: [
4888
5193
  "Valor",
4889
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
4890
- ZenitSelect,
5194
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5195
+ ZenitCombobox,
4891
5196
  {
4892
- ariaLabel: "Seleccionar valor de filtrado",
4893
5197
  value: selectedFilterValue,
4894
5198
  placeholder: "Seleccionar\u2026",
4895
- onValueChange: (nextValue) => setSelectedFilterValue(nextValue),
4896
- disabled: loadingCatalog || activeCatalogValues.length === 0,
4897
- options: activeCatalogValues.map((catalogValue) => ({
4898
- value: catalogValue,
4899
- label: catalogValue
4900
- }))
5199
+ searchPlaceholder: "Buscar valor\u2026",
5200
+ onChange: (nextValue) => setSelectedFilterValue(nextValue),
5201
+ options: activeCatalogValues,
5202
+ disabled: loadingCatalog || activeCatalogValues.length === 0
4901
5203
  }
4902
5204
  )
4903
5205
  ] }),
4904
- loadingCatalog && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: "#64748b", fontSize: 12 }, children: "Cargando cat\xE1logo\u2026" }),
4905
- !loadingCatalog && selectedFilterField && activeCatalogValues.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: "#64748b", fontSize: 12 }, children: "No hay cat\xE1logo disponible para este filtro." }),
4906
- filterError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: "#b91c1c", fontSize: 12 }, children: filterError }),
4907
- appliedFilter && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "zlm-badge", style: { alignSelf: "flex-start" }, children: [
5206
+ loadingCatalog && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { color: "#64748b", fontSize: 12 }, children: "Cargando cat\xE1logo\u2026" }),
5207
+ !loadingCatalog && selectedFilterField && activeCatalogValues.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { color: "#64748b", fontSize: 12 }, children: "No hay cat\xE1logo disponible para este filtro." }),
5208
+ filterError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { color: "#b91c1c", fontSize: 12 }, children: filterError }),
5209
+ appliedFilter && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "zlm-badge", style: { alignSelf: "flex-start" }, children: [
4908
5210
  "Activo: ",
4909
5211
  appliedFilter.field,
4910
5212
  " = ",
4911
5213
  appliedFilter.value
4912
5214
  ] }),
4913
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "zlm-filter-actions", style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
4914
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5215
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "zlm-filter-actions", style: { display: "flex", gap: 8, flexWrap: "wrap" }, children: [
5216
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4915
5217
  "button",
4916
5218
  {
4917
5219
  type: "button",
@@ -4921,7 +5223,7 @@ var ZenitLayerManager = ({
4921
5223
  children: applyingFilter ? "Aplicando\u2026" : "Aplicar"
4922
5224
  }
4923
5225
  ),
4924
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
5226
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4925
5227
  "button",
4926
5228
  {
4927
5229
  type: "button",
@@ -4933,13 +5235,13 @@ var ZenitLayerManager = ({
4933
5235
  )
4934
5236
  ] })
4935
5237
  ] }) }),
4936
- showUploadTab && activeTab === "upload" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { style: { color: "#475569", fontSize: 13 }, children: "Pr\xF3ximamente podr\xE1s subir capas desde este panel." })
5238
+ showUploadTab && activeTab === "upload" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: { color: "#475569", fontSize: 13 }, children: "Pr\xF3ximamente podr\xE1s subir capas desde este panel." })
4937
5239
  ] })
4938
5240
  ] });
4939
5241
  };
4940
5242
 
4941
5243
  // src/react/ZenitFeatureFilterPanel.tsx
4942
- var import_jsx_runtime6 = require("react/jsx-runtime");
5244
+ var import_jsx_runtime7 = require("react/jsx-runtime");
4943
5245
  var ZenitFeatureFilterPanel = ({
4944
5246
  title = "Filtros",
4945
5247
  description,
@@ -4947,7 +5249,7 @@ var ZenitFeatureFilterPanel = ({
4947
5249
  style,
4948
5250
  children
4949
5251
  }) => {
4950
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5252
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
4951
5253
  "section",
4952
5254
  {
4953
5255
  className,
@@ -4960,26 +5262,26 @@ var ZenitFeatureFilterPanel = ({
4960
5262
  ...style
4961
5263
  },
4962
5264
  children: [
4963
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("header", { style: { marginBottom: 12 }, children: [
4964
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { style: { margin: 0, fontSize: 16 }, children: title }),
4965
- description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: { margin: "6px 0 0", color: "#475569", fontSize: 13 }, children: description })
5265
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("header", { style: { marginBottom: 12 }, children: [
5266
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { style: { margin: 0, fontSize: 16 }, children: title }),
5267
+ description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: { margin: "6px 0 0", color: "#475569", fontSize: 13 }, children: description })
4966
5268
  ] }),
4967
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children })
5269
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children })
4968
5270
  ]
4969
5271
  }
4970
5272
  );
4971
5273
  };
4972
5274
 
4973
5275
  // src/react/ai/FloatingChatBox.tsx
4974
- var import_react9 = require("react");
5276
+ var import_react10 = require("react");
4975
5277
  var import_react_dom3 = require("react-dom");
4976
5278
 
4977
5279
  // src/react/hooks/use-chat.ts
4978
- var import_react8 = require("react");
5280
+ var import_react9 = require("react");
4979
5281
  var useSendMessage = (config) => {
4980
- const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
4981
- const [error, setError] = (0, import_react8.useState)(null);
4982
- const send = (0, import_react8.useCallback)(
5282
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
5283
+ const [error, setError] = (0, import_react9.useState)(null);
5284
+ const send = (0, import_react9.useCallback)(
4983
5285
  async (mapId, request, options) => {
4984
5286
  setIsLoading(true);
4985
5287
  setError(null);
@@ -4997,18 +5299,18 @@ var useSendMessage = (config) => {
4997
5299
  return { sendMessage: send, isLoading, error };
4998
5300
  };
4999
5301
  var useSendMessageStream = (config) => {
5000
- const [isStreaming, setIsStreaming] = (0, import_react8.useState)(false);
5001
- const [streamingText, setStreamingText] = (0, import_react8.useState)("");
5002
- const [completeResponse, setCompleteResponse] = (0, import_react8.useState)(null);
5003
- const [error, setError] = (0, import_react8.useState)(null);
5004
- const requestIdRef = (0, import_react8.useRef)(0);
5005
- const reset = (0, import_react8.useCallback)(() => {
5302
+ const [isStreaming, setIsStreaming] = (0, import_react9.useState)(false);
5303
+ const [streamingText, setStreamingText] = (0, import_react9.useState)("");
5304
+ const [completeResponse, setCompleteResponse] = (0, import_react9.useState)(null);
5305
+ const [error, setError] = (0, import_react9.useState)(null);
5306
+ const requestIdRef = (0, import_react9.useRef)(0);
5307
+ const reset = (0, import_react9.useCallback)(() => {
5006
5308
  setIsStreaming(false);
5007
5309
  setStreamingText("");
5008
5310
  setCompleteResponse(null);
5009
5311
  setError(null);
5010
5312
  }, []);
5011
- const send = (0, import_react8.useCallback)(
5313
+ const send = (0, import_react9.useCallback)(
5012
5314
  async (mapId, request, options) => {
5013
5315
  const requestId = requestIdRef.current + 1;
5014
5316
  requestIdRef.current = requestId;
@@ -5062,7 +5364,7 @@ var useSendMessageStream = (config) => {
5062
5364
  // src/react/components/MarkdownRenderer.tsx
5063
5365
  var import_react_markdown = __toESM(require("react-markdown"));
5064
5366
  var import_remark_gfm = __toESM(require("remark-gfm"));
5065
- var import_jsx_runtime7 = require("react/jsx-runtime");
5367
+ var import_jsx_runtime8 = require("react/jsx-runtime");
5066
5368
  function normalizeAssistantMarkdown(text) {
5067
5369
  if (!text || typeof text !== "string") return "";
5068
5370
  let normalized = text;
@@ -5078,28 +5380,28 @@ var MarkdownRenderer = ({ content, className }) => {
5078
5380
  if (!normalizedContent) {
5079
5381
  return null;
5080
5382
  }
5081
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className, style: { wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5383
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className, style: { wordBreak: "break-word" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5082
5384
  import_react_markdown.default,
5083
5385
  {
5084
5386
  remarkPlugins: [import_remark_gfm.default],
5085
5387
  components: {
5086
5388
  // Headings with proper spacing
5087
- h1: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { style: { fontSize: "1.5em", fontWeight: 700, marginTop: "1em", marginBottom: "0.5em" }, ...props, children }),
5088
- h2: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h2", { style: { fontSize: "1.3em", fontWeight: 700, marginTop: "0.9em", marginBottom: "0.45em" }, ...props, children }),
5089
- h3: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { style: { fontSize: "1.15em", fontWeight: 600, marginTop: "0.75em", marginBottom: "0.4em" }, ...props, children }),
5090
- h4: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { style: { fontSize: "1.05em", fontWeight: 600, marginTop: "0.6em", marginBottom: "0.35em" }, ...props, children }),
5091
- h5: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h5", { style: { fontSize: "1em", fontWeight: 600, marginTop: "0.5em", marginBottom: "0.3em" }, ...props, children }),
5092
- h6: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h6", { style: { fontSize: "0.95em", fontWeight: 600, marginTop: "0.5em", marginBottom: "0.3em" }, ...props, children }),
5389
+ h1: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h1", { style: { fontSize: "1.5em", fontWeight: 700, marginTop: "1em", marginBottom: "0.5em" }, ...props, children }),
5390
+ h2: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h2", { style: { fontSize: "1.3em", fontWeight: 700, marginTop: "0.9em", marginBottom: "0.45em" }, ...props, children }),
5391
+ h3: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { style: { fontSize: "1.15em", fontWeight: 600, marginTop: "0.75em", marginBottom: "0.4em" }, ...props, children }),
5392
+ h4: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { style: { fontSize: "1.05em", fontWeight: 600, marginTop: "0.6em", marginBottom: "0.35em" }, ...props, children }),
5393
+ h5: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h5", { style: { fontSize: "1em", fontWeight: 600, marginTop: "0.5em", marginBottom: "0.3em" }, ...props, children }),
5394
+ h6: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h6", { style: { fontSize: "0.95em", fontWeight: 600, marginTop: "0.5em", marginBottom: "0.3em" }, ...props, children }),
5093
5395
  // Paragraphs with comfortable line height
5094
- p: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: { marginTop: "0.5em", marginBottom: "0.5em", lineHeight: 1.6 }, ...props, children }),
5396
+ p: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { style: { marginTop: "0.5em", marginBottom: "0.5em", lineHeight: 1.6 }, ...props, children }),
5095
5397
  // Lists with proper indentation
5096
- ul: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { style: { paddingLeft: "1.5em", marginTop: "0.5em", marginBottom: "0.5em" }, ...props, children }),
5097
- ol: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ol", { style: { paddingLeft: "1.5em", marginTop: "0.5em", marginBottom: "0.5em" }, ...props, children }),
5098
- li: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { style: { marginTop: "0.25em", marginBottom: "0.25em" }, ...props, children }),
5398
+ ul: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { style: { paddingLeft: "1.5em", marginTop: "0.5em", marginBottom: "0.5em" }, ...props, children }),
5399
+ ol: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ol", { style: { paddingLeft: "1.5em", marginTop: "0.5em", marginBottom: "0.5em" }, ...props, children }),
5400
+ li: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("li", { style: { marginTop: "0.25em", marginBottom: "0.25em" }, ...props, children }),
5099
5401
  // Code blocks
5100
5402
  code: ({ inline, children, ...props }) => {
5101
5403
  if (inline) {
5102
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5404
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5103
5405
  "code",
5104
5406
  {
5105
5407
  style: {
@@ -5114,7 +5416,7 @@ var MarkdownRenderer = ({ content, className }) => {
5114
5416
  }
5115
5417
  );
5116
5418
  }
5117
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5419
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5118
5420
  "code",
5119
5421
  {
5120
5422
  style: {
@@ -5134,9 +5436,9 @@ var MarkdownRenderer = ({ content, className }) => {
5134
5436
  );
5135
5437
  },
5136
5438
  // Pre (code block wrapper)
5137
- pre: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { style: { margin: 0 }, ...props, children }),
5439
+ pre: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("pre", { style: { margin: 0 }, ...props, children }),
5138
5440
  // Blockquotes
5139
- blockquote: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5441
+ blockquote: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5140
5442
  "blockquote",
5141
5443
  {
5142
5444
  style: {
@@ -5152,11 +5454,11 @@ var MarkdownRenderer = ({ content, className }) => {
5152
5454
  }
5153
5455
  ),
5154
5456
  // Strong/bold
5155
- strong: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { style: { fontWeight: 600 }, ...props, children }),
5457
+ strong: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { style: { fontWeight: 600 }, ...props, children }),
5156
5458
  // Emphasis/italic
5157
- em: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("em", { style: { fontStyle: "italic" }, ...props, children }),
5459
+ em: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("em", { style: { fontStyle: "italic" }, ...props, children }),
5158
5460
  // Horizontal rule
5159
- hr: (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5461
+ hr: (props) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5160
5462
  "hr",
5161
5463
  {
5162
5464
  style: {
@@ -5169,7 +5471,7 @@ var MarkdownRenderer = ({ content, className }) => {
5169
5471
  }
5170
5472
  ),
5171
5473
  // Tables (GFM)
5172
- table: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: { overflowX: "auto", marginTop: "0.5em", marginBottom: "0.5em" }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5474
+ table: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { overflowX: "auto", marginTop: "0.5em", marginBottom: "0.5em" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5173
5475
  "table",
5174
5476
  {
5175
5477
  style: {
@@ -5181,7 +5483,7 @@ var MarkdownRenderer = ({ content, className }) => {
5181
5483
  children
5182
5484
  }
5183
5485
  ) }),
5184
- th: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5486
+ th: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5185
5487
  "th",
5186
5488
  {
5187
5489
  style: {
@@ -5195,7 +5497,7 @@ var MarkdownRenderer = ({ content, className }) => {
5195
5497
  children
5196
5498
  }
5197
5499
  ),
5198
- td: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5500
+ td: ({ children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
5199
5501
  "td",
5200
5502
  {
5201
5503
  style: {
@@ -5213,32 +5515,32 @@ var MarkdownRenderer = ({ content, className }) => {
5213
5515
  };
5214
5516
 
5215
5517
  // src/react/ai/FloatingChatBox.tsx
5216
- var import_jsx_runtime8 = require("react/jsx-runtime");
5217
- var ChatIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
5218
- var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5219
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
5220
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
5518
+ var import_jsx_runtime9 = require("react/jsx-runtime");
5519
+ var ChatIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" }) });
5520
+ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5521
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
5522
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
5221
5523
  ] });
5222
- var ExpandIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5223
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "15 3 21 3 21 9" }),
5224
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "9 21 3 21 3 15" }),
5225
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
5226
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
5524
+ var ExpandIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "15 3 21 3 21 9" }),
5526
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "9 21 3 21 3 15" }),
5527
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "21", y1: "3", x2: "14", y2: "10" }),
5528
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
5227
5529
  ] });
5228
- var CollapseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5229
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "4 14 10 14 10 20" }),
5230
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "20 10 14 10 14 4" }),
5231
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "14", y1: "10", x2: "21", y2: "3" }),
5232
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
5530
+ var CollapseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5531
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "4 14 10 14 10 20" }),
5532
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "20 10 14 10 14 4" }),
5533
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "14", y1: "10", x2: "21", y2: "3" }),
5534
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "3", y1: "21", x2: "10", y2: "14" })
5233
5535
  ] });
5234
- var SendIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5235
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
5236
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
5536
+ var SendIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5537
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
5538
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
5237
5539
  ] });
5238
- var LayersIcon = () => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5239
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polygon", { points: "12 2 2 7 12 12 22 7 12 2" }),
5240
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "2 17 12 22 22 17" }),
5241
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("polyline", { points: "2 12 12 17 22 12" })
5540
+ var LayersIcon = () => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
5541
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polygon", { points: "12 2 2 7 12 12 22 7 12 2" }),
5542
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "2 17 12 22 22 17" }),
5543
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("polyline", { points: "2 12 12 17 22 12" })
5242
5544
  ] });
5243
5545
  var styles = {
5244
5546
  root: {
@@ -5543,42 +5845,42 @@ var FloatingChatBox = ({
5543
5845
  open: openProp
5544
5846
  }) => {
5545
5847
  const isControlled = openProp !== void 0;
5546
- const [internalOpen, setInternalOpen] = (0, import_react9.useState)(false);
5848
+ const [internalOpen, setInternalOpen] = (0, import_react10.useState)(false);
5547
5849
  const open = isControlled ? openProp : internalOpen;
5548
- const setOpen = (0, import_react9.useCallback)((value) => {
5850
+ const setOpen = (0, import_react10.useCallback)((value) => {
5549
5851
  const newValue = typeof value === "function" ? value(open) : value;
5550
5852
  if (!isControlled) {
5551
5853
  setInternalOpen(newValue);
5552
5854
  }
5553
5855
  onOpenChange?.(newValue);
5554
5856
  }, [isControlled, open, onOpenChange]);
5555
- const [expanded, setExpanded] = (0, import_react9.useState)(false);
5556
- const [messages, setMessages] = (0, import_react9.useState)([]);
5557
- const [inputValue, setInputValue] = (0, import_react9.useState)("");
5558
- const [conversationId, setConversationId] = (0, import_react9.useState)();
5559
- const [errorMessage, setErrorMessage] = (0, import_react9.useState)(null);
5560
- const [isFocused, setIsFocused] = (0, import_react9.useState)(false);
5561
- const [isMobile, setIsMobile] = (0, import_react9.useState)(false);
5562
- const messagesEndRef = (0, import_react9.useRef)(null);
5563
- const messagesContainerRef = (0, import_react9.useRef)(null);
5564
- const chatBoxRef = (0, import_react9.useRef)(null);
5565
- const chatConfig = (0, import_react9.useMemo)(() => {
5857
+ const [expanded, setExpanded] = (0, import_react10.useState)(false);
5858
+ const [messages, setMessages] = (0, import_react10.useState)([]);
5859
+ const [inputValue, setInputValue] = (0, import_react10.useState)("");
5860
+ const [conversationId, setConversationId] = (0, import_react10.useState)();
5861
+ const [errorMessage, setErrorMessage] = (0, import_react10.useState)(null);
5862
+ const [isFocused, setIsFocused] = (0, import_react10.useState)(false);
5863
+ const [isMobile, setIsMobile] = (0, import_react10.useState)(false);
5864
+ const messagesEndRef = (0, import_react10.useRef)(null);
5865
+ const messagesContainerRef = (0, import_react10.useRef)(null);
5866
+ const chatBoxRef = (0, import_react10.useRef)(null);
5867
+ const chatConfig = (0, import_react10.useMemo)(() => {
5566
5868
  if (!baseUrl) return void 0;
5567
5869
  return { baseUrl, accessToken, getAccessToken };
5568
5870
  }, [accessToken, baseUrl, getAccessToken]);
5569
5871
  const { sendMessage: sendMessage2, isStreaming, streamingText, completeResponse } = useSendMessageStream(chatConfig);
5570
5872
  const canSend = Boolean(mapId) && Boolean(baseUrl) && inputValue.trim().length > 0 && !isStreaming;
5571
- (0, import_react9.useEffect)(() => {
5873
+ (0, import_react10.useEffect)(() => {
5572
5874
  if (open && isMobile) {
5573
5875
  setExpanded(true);
5574
5876
  }
5575
5877
  }, [open, isMobile]);
5576
- const scrollToBottom = (0, import_react9.useCallback)(() => {
5878
+ const scrollToBottom = (0, import_react10.useCallback)(() => {
5577
5879
  if (messagesEndRef.current) {
5578
5880
  messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
5579
5881
  }
5580
5882
  }, []);
5581
- (0, import_react9.useEffect)(() => {
5883
+ (0, import_react10.useEffect)(() => {
5582
5884
  if (open && messages.length === 0) {
5583
5885
  setMessages([
5584
5886
  {
@@ -5589,10 +5891,10 @@ var FloatingChatBox = ({
5589
5891
  ]);
5590
5892
  }
5591
5893
  }, [open, messages.length]);
5592
- (0, import_react9.useEffect)(() => {
5894
+ (0, import_react10.useEffect)(() => {
5593
5895
  scrollToBottom();
5594
5896
  }, [messages, streamingText, scrollToBottom]);
5595
- (0, import_react9.useEffect)(() => {
5897
+ (0, import_react10.useEffect)(() => {
5596
5898
  if (!open) return;
5597
5899
  if (isMobile && expanded) return;
5598
5900
  const handleClickOutside = (event) => {
@@ -5605,7 +5907,7 @@ var FloatingChatBox = ({
5605
5907
  document.removeEventListener("mousedown", handleClickOutside);
5606
5908
  };
5607
5909
  }, [open, isMobile, expanded]);
5608
- (0, import_react9.useEffect)(() => {
5910
+ (0, import_react10.useEffect)(() => {
5609
5911
  if (typeof window === "undefined") return;
5610
5912
  const mediaQuery = window.matchMedia("(max-width: 768px)");
5611
5913
  const updateMobile = () => setIsMobile(mediaQuery.matches);
@@ -5623,7 +5925,7 @@ var FloatingChatBox = ({
5623
5925
  }
5624
5926
  };
5625
5927
  }, []);
5626
- (0, import_react9.useEffect)(() => {
5928
+ (0, import_react10.useEffect)(() => {
5627
5929
  if (typeof document === "undefined") return;
5628
5930
  if (!open || !isMobile) return;
5629
5931
  document.body.style.overflow = "hidden";
@@ -5631,10 +5933,10 @@ var FloatingChatBox = ({
5631
5933
  document.body.style.overflow = "";
5632
5934
  };
5633
5935
  }, [open, isMobile]);
5634
- const addMessage = (0, import_react9.useCallback)((message) => {
5936
+ const addMessage = (0, import_react10.useCallback)((message) => {
5635
5937
  setMessages((prev) => [...prev, message]);
5636
5938
  }, []);
5637
- const handleSend = (0, import_react9.useCallback)(async () => {
5939
+ const handleSend = (0, import_react10.useCallback)(async () => {
5638
5940
  if (!mapId) {
5639
5941
  setErrorMessage("Selecciona un mapa para usar el asistente.");
5640
5942
  return;
@@ -5687,7 +5989,7 @@ var FloatingChatBox = ({
5687
5989
  sendMessage2,
5688
5990
  userId
5689
5991
  ]);
5690
- const handleKeyDown = (0, import_react9.useCallback)(
5992
+ const handleKeyDown = (0, import_react10.useCallback)(
5691
5993
  (event) => {
5692
5994
  if (event.key === "Enter" && !event.shiftKey) {
5693
5995
  event.preventDefault();
@@ -5698,20 +6000,20 @@ var FloatingChatBox = ({
5698
6000
  },
5699
6001
  [canSend, handleSend]
5700
6002
  );
5701
- const handleFollowUpClick = (0, import_react9.useCallback)((question) => {
6003
+ const handleFollowUpClick = (0, import_react10.useCallback)((question) => {
5702
6004
  setInputValue(question);
5703
6005
  }, []);
5704
6006
  const renderMetadata = (response) => {
5705
6007
  if (!response?.metadata) return null;
5706
6008
  const referencedLayers = response.metadata.referencedLayers;
5707
6009
  if (!referencedLayers || referencedLayers.length === 0) return null;
5708
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.metadataSection, children: [
5709
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.metadataTitle, children: [
5710
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(LayersIcon, {}),
6010
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.metadataSection, children: [
6011
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.metadataTitle, children: [
6012
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LayersIcon, {}),
5711
6013
  "Capas Analizadas"
5712
6014
  ] }),
5713
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { style: styles.metadataList, children: referencedLayers.map((layer, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { style: styles.metadataItem, children: [
5714
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("strong", { children: layer.layerName }),
6015
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { style: styles.metadataList, children: referencedLayers.map((layer, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { style: styles.metadataItem, children: [
6016
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: layer.layerName }),
5715
6017
  " (",
5716
6018
  layer.featureCount,
5717
6019
  " ",
@@ -5720,7 +6022,7 @@ var FloatingChatBox = ({
5720
6022
  ] }, index)) })
5721
6023
  ] });
5722
6024
  };
5723
- const handleActionClick = (0, import_react9.useCallback)((action) => {
6025
+ const handleActionClick = (0, import_react10.useCallback)((action) => {
5724
6026
  if (isStreaming) return;
5725
6027
  setOpen(false);
5726
6028
  requestAnimationFrame(() => {
@@ -5729,9 +6031,9 @@ var FloatingChatBox = ({
5729
6031
  }, [isStreaming, setOpen, onActionClick]);
5730
6032
  const renderActions = (response) => {
5731
6033
  if (!response?.suggestedActions?.length) return null;
5732
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.actionsSection, children: [
5733
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.sectionLabel, children: "Acciones Sugeridas" }),
5734
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.actionsGrid, children: response.suggestedActions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6034
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.actionsSection, children: [
6035
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.sectionLabel, children: "Acciones Sugeridas" }),
6036
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.actionsGrid, children: response.suggestedActions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5735
6037
  "button",
5736
6038
  {
5737
6039
  type: "button",
@@ -5762,9 +6064,9 @@ var FloatingChatBox = ({
5762
6064
  };
5763
6065
  const renderFollowUps = (response) => {
5764
6066
  if (!response?.followUpQuestions?.length) return null;
5765
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.actionsSection, children: [
5766
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.sectionLabel, children: "Preguntas Relacionadas" }),
5767
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: response.followUpQuestions.map((question, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6067
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.actionsSection, children: [
6068
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.sectionLabel, children: "Preguntas Relacionadas" }),
6069
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: response.followUpQuestions.map((question, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5768
6070
  "button",
5769
6071
  {
5770
6072
  type: "button",
@@ -5793,8 +6095,8 @@ var FloatingChatBox = ({
5793
6095
  )) })
5794
6096
  ] });
5795
6097
  };
5796
- const chatContent = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.root, children: [
5797
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: `
6098
+ const chatContent = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.root, children: [
6099
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: `
5798
6100
  @keyframes zenitBlink {
5799
6101
  0%, 49% { opacity: 1; }
5800
6102
  50%, 100% { opacity: 0; }
@@ -5850,7 +6152,7 @@ var FloatingChatBox = ({
5850
6152
  }
5851
6153
  }
5852
6154
  ` }),
5853
- open && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
6155
+ open && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5854
6156
  "div",
5855
6157
  {
5856
6158
  ref: chatBoxRef,
@@ -5864,10 +6166,10 @@ var FloatingChatBox = ({
5864
6166
  };
5865
6167
  })(),
5866
6168
  children: [
5867
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("header", { style: styles.header, children: [
5868
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { style: styles.title, children: "Asistente Zenit AI" }),
5869
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.headerButtons, children: [
5870
- !isMobile && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6169
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("header", { style: styles.header, children: [
6170
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { style: styles.title, children: "Asistente Zenit AI" }),
6171
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.headerButtons, children: [
6172
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5871
6173
  "button",
5872
6174
  {
5873
6175
  type: "button",
@@ -5880,10 +6182,10 @@ var FloatingChatBox = ({
5880
6182
  e.currentTarget.style.background = "rgba(255, 255, 255, 0.15)";
5881
6183
  },
5882
6184
  "aria-label": expanded ? "Contraer" : "Expandir",
5883
- children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CollapseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ExpandIcon, {})
6185
+ children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CollapseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ExpandIcon, {})
5884
6186
  }
5885
6187
  ),
5886
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6188
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5887
6189
  "button",
5888
6190
  {
5889
6191
  type: "button",
@@ -5896,20 +6198,20 @@ var FloatingChatBox = ({
5896
6198
  e.currentTarget.style.background = "rgba(255, 255, 255, 0.15)";
5897
6199
  },
5898
6200
  "aria-label": "Cerrar",
5899
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon, {})
6201
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseIcon, {})
5900
6202
  }
5901
6203
  )
5902
6204
  ] })
5903
6205
  ] }),
5904
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { ref: messagesContainerRef, className: "zenit-ai-body", style: styles.messages, children: [
5905
- messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6206
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { ref: messagesContainerRef, className: "zenit-ai-body", style: styles.messages, children: [
6207
+ messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5906
6208
  "div",
5907
6209
  {
5908
6210
  style: {
5909
6211
  ...styles.messageWrapper,
5910
6212
  alignItems: message.role === "user" ? "flex-end" : "flex-start"
5911
6213
  },
5912
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
6214
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
5913
6215
  "div",
5914
6216
  {
5915
6217
  style: {
@@ -5917,7 +6219,7 @@ var FloatingChatBox = ({
5917
6219
  ...message.role === "user" ? styles.userMessage : styles.assistantMessage
5918
6220
  },
5919
6221
  children: [
5920
- message.role === "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MarkdownRenderer, { content: message.content }) : message.content,
6222
+ message.role === "assistant" ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MarkdownRenderer, { content: message.content }) : message.content,
5921
6223
  message.role === "assistant" && renderMetadata(message.response),
5922
6224
  message.role === "assistant" && renderActions(message.response),
5923
6225
  message.role === "assistant" && renderFollowUps(message.response)
@@ -5927,39 +6229,39 @@ var FloatingChatBox = ({
5927
6229
  },
5928
6230
  message.id
5929
6231
  )),
5930
- isStreaming && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6232
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5931
6233
  "div",
5932
6234
  {
5933
6235
  style: {
5934
6236
  ...styles.messageWrapper,
5935
6237
  alignItems: "flex-start"
5936
6238
  },
5937
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6239
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5938
6240
  "div",
5939
6241
  {
5940
6242
  style: {
5941
6243
  ...styles.messageBubble,
5942
6244
  ...styles.assistantMessage
5943
6245
  },
5944
- children: streamingText ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
5945
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MarkdownRenderer, { content: streamingText }),
5946
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { style: styles.cursor })
5947
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.thinkingText, children: [
5948
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Pensando" }),
5949
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { style: styles.typingIndicator, children: [
5950
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "zenit-typing-dot", style: styles.typingDot }),
5951
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "zenit-typing-dot", style: styles.typingDot }),
5952
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "zenit-typing-dot", style: styles.typingDot })
6246
+ children: streamingText ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
6247
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(MarkdownRenderer, { content: streamingText }),
6248
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: styles.cursor })
6249
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.thinkingText, children: [
6250
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Pensando" }),
6251
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { style: styles.typingIndicator, children: [
6252
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "zenit-typing-dot", style: styles.typingDot }),
6253
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "zenit-typing-dot", style: styles.typingDot }),
6254
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "zenit-typing-dot", style: styles.typingDot })
5953
6255
  ] })
5954
6256
  ] })
5955
6257
  }
5956
6258
  )
5957
6259
  }
5958
6260
  ),
5959
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { ref: messagesEndRef })
6261
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { ref: messagesEndRef })
5960
6262
  ] }),
5961
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "zenit-ai-input-area", style: styles.inputWrapper, children: [
5962
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6263
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "zenit-ai-input-area", style: styles.inputWrapper, children: [
6264
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5963
6265
  "textarea",
5964
6266
  {
5965
6267
  style: {
@@ -5976,7 +6278,7 @@ var FloatingChatBox = ({
5976
6278
  disabled: !mapId || !baseUrl || isStreaming
5977
6279
  }
5978
6280
  ),
5979
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6281
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
5980
6282
  "button",
5981
6283
  {
5982
6284
  type: "button",
@@ -5985,18 +6287,18 @@ var FloatingChatBox = ({
5985
6287
  onClick: () => void handleSend(),
5986
6288
  disabled: !canSend,
5987
6289
  "aria-label": "Enviar mensaje",
5988
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SendIcon, {})
6290
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SendIcon, {})
5989
6291
  }
5990
6292
  )
5991
6293
  ] }),
5992
- errorMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.errorText, children: errorMessage }),
5993
- isStreaming && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.statusNote, children: "Generando sugerencias..." }),
5994
- !mapId && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.statusNote, children: "Selecciona un mapa para usar el asistente" }),
5995
- !baseUrl && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { style: styles.statusNote, children: "Configura la baseUrl del SDK" })
6294
+ errorMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.errorText, children: errorMessage }),
6295
+ isStreaming && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.statusNote, children: "Generando sugerencias..." }),
6296
+ !mapId && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.statusNote, children: "Selecciona un mapa para usar el asistente" }),
6297
+ !baseUrl && !errorMessage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { style: styles.statusNote, children: "Configura la baseUrl del SDK" })
5996
6298
  ]
5997
6299
  }
5998
6300
  ),
5999
- !(hideButton && !open) && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
6301
+ !(hideButton && !open) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
6000
6302
  "button",
6001
6303
  {
6002
6304
  type: "button",
@@ -6008,9 +6310,9 @@ var FloatingChatBox = ({
6008
6310
  },
6009
6311
  onClick: () => setOpen((prev) => !prev),
6010
6312
  "aria-label": open ? "Cerrar asistente" : "Abrir asistente Zenit AI",
6011
- children: open ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
6012
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChatIcon, {}),
6013
- !isMobile && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Asistente IA" })
6313
+ children: open ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
6314
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ChatIcon, {}),
6315
+ !isMobile && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: "Asistente IA" })
6014
6316
  ] })
6015
6317
  }
6016
6318
  )