myio-js-library 0.1.565 → 0.1.566

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.cjs CHANGED
@@ -276,6 +276,7 @@ __export(src_exports, {
276
276
  POWER_LIMITS_DEVICE_TYPES: () => DEVICE_TYPES,
277
277
  POWER_LIMITS_STATUS_CONFIG: () => STATUS_CONFIG,
278
278
  POWER_LIMITS_TELEMETRY_TYPES: () => TELEMETRY_TYPES,
279
+ PUMP_POWER_KEY: () => PUMP_POWER_KEY,
279
280
  REPORT_MONEY_HEADER: () => REPORT_MONEY_HEADER,
280
281
  SCHEDULE_HOLIDAY_CSS_PREFIX: () => SCHEDULE_HOLIDAY_CSS_PREFIX,
281
282
  SCHEDULE_IR_CSS_PREFIX: () => SCHEDULE_IR_CSS_PREFIX,
@@ -328,6 +329,7 @@ __export(src_exports, {
328
329
  TempSensorSummaryTooltip: () => TempSensorSummaryTooltip,
329
330
  Temperature: () => Temperature,
330
331
  UsersSummaryTooltip: () => UsersSummaryTooltip,
332
+ VALVE_STATE_KEYS: () => VALVE_STATE_KEYS,
331
333
  VARIANCE_LABEL_ABOVE: () => VARIANCE_LABEL_ABOVE,
332
334
  VARIANCE_LABEL_BELOW: () => VARIANCE_LABEL_BELOW,
333
335
  VARIANCE_LABEL_ONTARGET: () => VARIANCE_LABEL_ONTARGET,
@@ -450,6 +452,7 @@ __export(src_exports, {
450
452
  createDistributionChartWidget: () => createDistributionChartWidget,
451
453
  createDivCard: () => createDivCard,
452
454
  createEnergyPanelComponent: () => createEnergyPanelComponent,
455
+ createEquipmentIndicatorStrip: () => createEquipmentIndicatorStrip,
453
456
  createErrorSpan: () => createErrorSpan,
454
457
  createExportButton: () => createExportButton,
455
458
  createFakeDeviceCategoryPort: () => createFakeDeviceCategoryPort,
@@ -544,7 +547,7 @@ __export(src_exports, {
544
547
  doSchedulesOverlap: () => doSchedulesOverlap,
545
548
  downloadAnnotationsTextFile: () => downloadTextFile,
546
549
  encodeDeviceProductCode: () => encodeDeviceProductCode,
547
- escapeAnnotationHtml: () => escapeHtml16,
550
+ escapeAnnotationHtml: () => escapeHtml17,
548
551
  evaluateDeviceStatus: () => evaluateDeviceStatus,
549
552
  expandBandHours: () => expandBandHours,
550
553
  expandBandToHourBucketsByYear: () => expandBandToHourBucketsByYear,
@@ -676,6 +679,7 @@ __export(src_exports, {
676
679
  hasCoverageGaps: () => hasCoverageGaps,
677
680
  hasSelectedDays: () => hasSelectedDays,
678
681
  highlightAnnotationMatches: () => highlightMatches,
682
+ indicatorsFromModalData: () => indicatorsFromModalData,
679
683
  initMyIOAuthContext: () => initMyIOAuthContext,
680
684
  initOnOffTimelineTooltips: () => initOnOffTimelineTooltips,
681
685
  injectActionButtonStyles: () => injectActionButtonStyles,
@@ -712,6 +716,7 @@ __export(src_exports, {
712
716
  injectSolenoidControlStyles: () => injectSolenoidControlStyles,
713
717
  injectSwitchControlStyles: () => injectSwitchControlStyles,
714
718
  interpolateTemperature: () => interpolateTemperature,
719
+ intervalsFromTelemetry: () => intervalsFromTelemetry,
715
720
  inventory: () => inventory_exports,
716
721
  isAlarmActive: () => isAlarmActive,
717
722
  isAnnotationOverdue: () => isOverdue,
@@ -741,6 +746,7 @@ __export(src_exports, {
741
746
  isValidTimeFormat: () => isValidTimeFormat,
742
747
  isWaterCategory: () => isWaterCategory,
743
748
  latestHourlyTemperature: () => latestHourlyTemperature,
749
+ latestPowerKw: () => latestPowerKw,
744
750
  liftProfileToTree: () => liftProfileToTree,
745
751
  listDeviceProductTypes: () => listDeviceProductTypes,
746
752
  listDomains: () => listDomains,
@@ -809,10 +815,12 @@ __export(src_exports, {
809
815
  openUpsellModal: () => openUpsellModal,
810
816
  openUserManagementModal: () => openUserManagementModal,
811
817
  openWelcomeModal: () => openWelcomeModal,
818
+ openWellPumpsModal: () => openWellPumpsModal,
812
819
  overlayWithholdsVerdict: () => overlayWithholdsVerdict,
813
820
  panelCategoryToWire: () => panelCategoryToWire,
814
821
  panelDomainToWire: () => panelDomainToWire,
815
822
  panelTermToDeviceCategory: () => panelTermToDeviceCategory,
823
+ parseBinaryState: () => parseBinaryState,
816
824
  parseClassificationEntities: () => parseClassificationEntities,
817
825
  parseGcdrEnergyRoot: () => parseGcdrEnergyRoot,
818
826
  parseGcdrEntityForest: () => parseGcdrEntityForest,
@@ -820,6 +828,7 @@ __export(src_exports, {
820
828
  parseLogAnnotations: () => parseLogAnnotations,
821
829
  periodKey: () => periodKey,
822
830
  pickUniqueCustomerCode: () => pickUniqueCustomerCode,
831
+ pumpHistoryFromConsumption: () => pumpHistoryFromConsumption,
823
832
  readFreshdeskTicketsFromTB: () => readFreshdeskTicketsFromTB,
824
833
  recalculateDeviceStatus: () => recalculateDeviceStatus,
825
834
  recomputeDeviceGridPercentages: () => recomputePercentages,
@@ -847,6 +856,8 @@ __export(src_exports, {
847
856
  renderDashboardDowntimeList: () => renderDowntimeList,
848
857
  renderDeviceGridList: () => renderList,
849
858
  renderDualLineChart: () => renderDualLineChart,
859
+ renderEquipmentShortcutHTML: () => renderEquipmentShortcutHTML,
860
+ renderEquipmentTilesHTML: () => renderEquipmentTilesHTML,
850
861
  renderFinancialIndicators: () => renderFinancialIndicators,
851
862
  renderGatedMoney: () => renderGatedMoney,
852
863
  renderKPICards: () => renderKPICards,
@@ -875,7 +886,7 @@ __export(src_exports, {
875
886
  schedCreateNumberInput: () => createNumberInput,
876
887
  schedCreateSelect: () => createSelect,
877
888
  schedCreateTimeInput: () => createTimeInput,
878
- schedEscapeHtml: () => escapeHtml15,
889
+ schedEscapeHtml: () => escapeHtml16,
879
890
  schedShowConfirmModal: () => showConfirmModal,
880
891
  schedShowNotificationModal: () => showNotificationModal,
881
892
  selectBreakdownItems: () => selectBreakdownItems,
@@ -923,7 +934,7 @@ module.exports = __toCommonJS(src_exports);
923
934
  // package.json
924
935
  var package_default = {
925
936
  name: "myio-js-library",
926
- version: "0.1.565",
937
+ version: "0.1.566",
927
938
  description: "A clean, standalone JS SDK for MYIO projects",
928
939
  license: "MIT",
929
940
  repository: "github:gh-myio/myio-js-library",
@@ -2307,6 +2318,7 @@ var DeviceIconType = {
2307
2318
  BOMBA_CAG: "BOMBA_CAG",
2308
2319
  BOMBA_INCENDIO: "BOMBA_INCENDIO",
2309
2320
  BOMBA: "BOMBA",
2321
+ BOMBA_POCO: "BOMBA_POCO",
2310
2322
  MEDIDOR_3F: "3F_MEDIDOR",
2311
2323
  RELOGIO: "RELOGIO",
2312
2324
  ENTRADA: "ENTRADA",
@@ -2318,6 +2330,8 @@ var DeviceIconType = {
2318
2330
  HIDROMETRO_AREA_COMUM: "HIDROMETRO_AREA_COMUM",
2319
2331
  HIDROMETRO_SHOPPING: "HIDROMETRO_SHOPPING",
2320
2332
  CAIXA_DAGUA: "CAIXA_DAGUA",
2333
+ CISTERNA: "CISTERNA",
2334
+ CISTERNA_ENTRADA: "CISTERNA_ENTRADA",
2321
2335
  TERMOSTATO: "TERMOSTATO",
2322
2336
  COMPRESSOR: "COMPRESSOR",
2323
2337
  VENTILADOR: "VENTILADOR",
@@ -2327,6 +2341,11 @@ var DeviceIconType = {
2327
2341
  };
2328
2342
  var BOX_ICON_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96" fill="none" stroke-linejoin="round"><ellipse cx="48" cy="85" rx="36" ry="5" fill="#000" opacity=".08"/><polygon points="12,40 56,22 84,36 40,54" fill="#E3BC85" stroke="#7A5527" stroke-width="2"/><polygon points="12,40 40,54 40,84 12,70" fill="#C99A5B" stroke="#7A5527" stroke-width="2"/><polygon points="40,54 84,36 84,66 40,84" fill="#B5823F" stroke="#7A5527" stroke-width="2"/><polygon points="22.6,45.3 66.6,27.3 73.4,30.7 29.4,48.7" fill="#F3DDB0"/><polygon points="22.6,45.3 29.4,48.7 29.4,59 22.6,55.6" fill="#E6CB96"/><path d="M26 47L70 29" stroke="#7A5527" stroke-width="1" opacity=".55"/><polygon points="64.2,59.1 77.4,53.7 77.4,62.7 64.2,68.1" fill="#FBF6EC" stroke="#7A5527" stroke-width="1"/><path d="M66.6 61.4l8.6-3.5M66.6 64.6l5.6-2.3" stroke="#7A5527" stroke-width="1.2" stroke-linecap="round"/></svg>';
2329
2343
  var BOX_ICON_DATA_URI = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(BOX_ICON_SVG);
2344
+ var CISTERNA_ICON_SVG = (
2345
+ // width/height explícitos: sem tamanho intrínseco o <img> do card (.device-image, height auto) renderiza 0×0
2346
+ '<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96" viewBox="0 0 96 96" fill="none" stroke-linejoin="round" stroke-linecap="round"><path d="M3 36h24M66 40h10M66 66h10" stroke="#0B3B5C" stroke-width="7"/><path d="M3 36h24M66 40h10M66 66h10" stroke="#B0BEC5" stroke-width="3.5"/><path d="M26 28v46c0 3.3 9 6 20 6s20-2.7 20-6V28" fill="#29B6F6"/><path d="M26 44c0 3.3 9 6 20 6s20-2.7 20-6v15c0 3.3-9 6-20 6s-20-2.7-20-6z" fill="#4FC3F7"/><path d="M26 44c0 3.3 9 6 20 6s20-2.7 20-6M26 59c0 3.3 9 6 20 6s20-2.7 20-6" stroke="#0B3B5C" stroke-width="2.5"/><path d="M26 28v46c0 3.3 9 6 20 6s20-2.7 20-6V28" stroke="#0B3B5C" stroke-width="3.5"/><ellipse cx="46" cy="28" rx="20" ry="6" fill="#81D4FA" stroke="#0B3B5C" stroke-width="3.5"/><path d="M14 36v-9" stroke="#0B3B5C" stroke-width="2.5"/><rect x="8.5" y="17" width="11" height="9" rx="2" fill="#FFB300" stroke="#0B3B5C" stroke-width="2.5"/><path d="M8 30l12 12V30L8 42z" fill="#29B6F6" stroke="#0B3B5C" stroke-width="2.5"/><circle cx="83" cy="40" r="9" fill="#ECEFF1" stroke="#0B3B5C" stroke-width="3"/><path d="M87 35v10l-8-5z" fill="#0B3B5C"/><circle cx="83" cy="66" r="9" fill="#ECEFF1" stroke="#0B3B5C" stroke-width="3"/><path d="M87 61v10l-8-5z" fill="#0B3B5C"/></svg>'
2347
+ );
2348
+ var CISTERNA_ICON_DATA_URI = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(CISTERNA_ICON_SVG);
2330
2349
  var deviceIcons = {
2331
2350
  ESCADA_ROLANTE: "https://dashboard.myio-bas.com/api/images/public/EJ997iB2HD1AYYUHwIloyQOOszeqb2jp",
2332
2351
  ELEVADOR: "https://dashboard.myio-bas.com/api/images/public/rAjOvdsYJLGah6w6BABPJSD9znIyrkJX",
@@ -2335,6 +2354,8 @@ var deviceIcons = {
2335
2354
  BOMBA_CAG: "https://dashboard.myio-bas.com/api/images/public/rbO2wQb6iKBtX0Ec04DFDcO3Qg04EOoD",
2336
2355
  BOMBA_INCENDIO: "https://dashboard.myio-bas.com/api/images/public/YJkELCk9kluQSM6QXaFINX6byQWI7vbB",
2337
2356
  BOMBA: "https://dashboard.myio-bas.com/api/images/public/Rge8Q3t0CP5PW8XyTn9bBK9aVP6uzSTT",
2357
+ // BOMBA_POCO (ED-1354): bomba de poço artesiano — sem arte própria ainda, usa a do MOTOR/BOMBA.
2358
+ BOMBA_POCO: "https://dashboard.myio-bas.com/api/images/public/Rge8Q3t0CP5PW8XyTn9bBK9aVP6uzSTT",
2338
2359
  "3F_MEDIDOR": "https://dashboard.myio-bas.com/api/images/public/f9Ce4meybsdaAhAkUlAfy5ei3I4kcN4k",
2339
2360
  RELOGIO: "https://dashboard.myio-bas.com/api/images/public/ljHZostWg0G5AfKiyM8oZixWRIIGRASB",
2340
2361
  ENTRADA: "https://dashboard.myio-bas.com/api/images/public/TQHPFqiejMW6lOSVsb8Pi85WtC0QKOLU",
@@ -2349,6 +2370,10 @@ var deviceIcons = {
2349
2370
  HIDROMETRO_AREA_COMUM: "https://dashboard.myio-bas.com/api/images/public/IbEhjsvixAxwKg1ntGGZc5xZwwvGKv2t",
2350
2371
  HIDROMETRO_SHOPPING: "https://dashboard.myio-bas.com/api/images/public/OIMmvN4ZTKYDvrpPGYY5agqMRoSaWNTI",
2351
2372
  CAIXA_DAGUA: "https://dashboard.myio-bas.com/api/images/public/3t6WVhMQJFsrKA8bSZmrngDsNPkZV7fq",
2373
+ // CISTERNA (ED-1354): poço/cisterna (nível + bombas BOMBA_POCO + solenoides) — SVG inline no estilo do TANK.
2374
+ CISTERNA: CISTERNA_ICON_DATA_URI,
2375
+ // CISTERNA_ENTRADA: mesma arte — o sufixo só decide a coluna (Entrada × Área Comum)
2376
+ CISTERNA_ENTRADA: CISTERNA_ICON_DATA_URI,
2352
2377
  TERMOSTATO: "https://dashboard.myio-bas.com/api/images/public/rtCcq6kZZVCD7wgJywxEurRZwR8LA7Q7",
2353
2378
  // COMPRESSOR shares FANCOIL art; VENTILADOR shares MOTOR/BOMBA art (single static icons, no on/off variation).
2354
2379
  COMPRESSOR: "https://dashboard.myio-bas.com/api/images/public/4BWMuVIFHnsfqatiV86DmTrOB7IF0X8Y",
@@ -2369,6 +2394,7 @@ var deviceIconLabels = {
2369
2394
  BOMBA_CAG: "Bomba CAG",
2370
2395
  BOMBA_INCENDIO: "Bomba Inc\xEAndio",
2371
2396
  BOMBA: "Bomba",
2397
+ BOMBA_POCO: "Bomba de Po\xE7o",
2372
2398
  "3F_MEDIDOR": "Medidor 3F",
2373
2399
  RELOGIO: "Rel\xF3gio",
2374
2400
  ENTRADA: "Entrada",
@@ -2380,6 +2406,8 @@ var deviceIconLabels = {
2380
2406
  HIDROMETRO_AREA_COMUM: "Hidr\xF4metro \xC1rea Comum",
2381
2407
  HIDROMETRO_SHOPPING: "Hidr\xF4metro Shopping",
2382
2408
  CAIXA_DAGUA: "Caixa d'\xC1gua",
2409
+ CISTERNA: "Cisterna",
2410
+ CISTERNA_ENTRADA: "Cisterna (Entrada)",
2383
2411
  TERMOSTATO: "Termostato",
2384
2412
  COMPRESSOR: "Compressor",
2385
2413
  VENTILADOR: "Ventilador",
@@ -2422,6 +2450,11 @@ var DEVICE_TYPE_CONFIG = {
2422
2450
  HIDROMETRO_AREA_COMUM: { category: "water", image: deviceIcons.HIDROMETRO_AREA_COMUM },
2423
2451
  HIDROMETRO_SHOPPING: { category: "water", image: deviceIcons.HIDROMETRO_SHOPPING },
2424
2452
  CAIXA_DAGUA: { category: "water", image: deviceIcons.CAIXA_DAGUA },
2453
+ // ED-1354: poço/cisterna (nível, como CAIXA_DAGUA) — _ENTRADA vai p/ a coluna Entrada, o outro p/ Área Comum
2454
+ CISTERNA: { category: "water", image: deviceIcons.CISTERNA },
2455
+ CISTERNA_ENTRADA: { category: "water", image: deviceIcons.CISTERNA_ENTRADA },
2456
+ BOMBA_POCO: { category: "energy", image: deviceIcons.BOMBA_POCO },
2457
+ // ED-1354: bomba do poço (consumption W)
2425
2458
  // Tank devices (dynamic images based on level)
2426
2459
  TANK: { category: "tank", image: null },
2427
2460
  // Temperature devices (dynamic images based on status)
@@ -20781,6 +20814,234 @@ function resolvePercentDecimals(explicit) {
20781
20814
  return 2;
20782
20815
  }
20783
20816
 
20817
+ // src/components/well-pumps/equipmentState.ts
20818
+ var HOUR_MS = 36e5;
20819
+ var DAY_MS = 24 * HOUR_MS;
20820
+ var TRUE_WORDS = /* @__PURE__ */ new Set(["1", "true", "on", "ligada", "ligado", "open", "opened", "aberta", "aberto", "running", "run"]);
20821
+ var FALSE_WORDS = /* @__PURE__ */ new Set(["0", "false", "off", "desligada", "desligado", "closed", "close", "fechada", "fechado", "stopped", "stop"]);
20822
+ function parseBinaryState(value) {
20823
+ if (typeof value === "boolean") return value;
20824
+ if (typeof value === "number") return Number.isFinite(value) ? value !== 0 : null;
20825
+ if (typeof value !== "string") return null;
20826
+ const v = value.trim().toLowerCase();
20827
+ if (TRUE_WORDS.has(v)) return true;
20828
+ if (FALSE_WORDS.has(v)) return false;
20829
+ const n = Number(v);
20830
+ return v !== "" && Number.isFinite(n) ? n !== 0 : null;
20831
+ }
20832
+ function intervalsFromTelemetry(points, opts = {}) {
20833
+ const toState = (v) => {
20834
+ if (typeof opts.threshold !== "number") return parseBinaryState(v);
20835
+ const n = typeof v === "number" ? v : typeof v === "string" && v.trim() !== "" ? Number(v) : NaN;
20836
+ return Number.isFinite(n) ? n > opts.threshold : null;
20837
+ };
20838
+ const sorted = (points || []).map((p) => ({ ts: Number(p?.ts), state: toState(p?.value) })).filter((p) => Number.isFinite(p.ts) && p.state !== null).sort((a, b) => a.ts - b.ts);
20839
+ const out = [];
20840
+ let open = null;
20841
+ for (const p of sorted) {
20842
+ if (p.state && open === null) open = p.ts;
20843
+ else if (!p.state && open !== null) {
20844
+ out.push([open, p.ts]);
20845
+ open = null;
20846
+ }
20847
+ }
20848
+ if (open !== null) out.push([open, null]);
20849
+ return out;
20850
+ }
20851
+ var PUMP_POWER_KEY = "consumption";
20852
+ var VALVE_STATE_KEYS = ["state", "status"];
20853
+ function pumpHistoryFromConsumption(points, thresholdW = 0) {
20854
+ return intervalsFromTelemetry(points, { threshold: thresholdW });
20855
+ }
20856
+ function latestPowerKw(points) {
20857
+ let best = null;
20858
+ for (const p of points || []) {
20859
+ const ts = Number(p?.ts);
20860
+ const v = Number(p?.value);
20861
+ if (!Number.isFinite(ts) || !Number.isFinite(v) || p?.value === "" || p?.value === null) continue;
20862
+ if (!best || ts > best.ts) best = { ts, v };
20863
+ }
20864
+ return best ? best.v / 1e3 : null;
20865
+ }
20866
+ function isActive(history) {
20867
+ const last = history?.[history.length - 1];
20868
+ return !!last && last[1] === null;
20869
+ }
20870
+ function stateSince(history) {
20871
+ const last = history?.[history.length - 1];
20872
+ if (!last) return null;
20873
+ return last[1] === null ? last[0] : last[1];
20874
+ }
20875
+ function dayStats(history, now = Date.now()) {
20876
+ const midnight = new Date(now);
20877
+ midnight.setHours(0, 0, 0, 0);
20878
+ const m = midnight.getTime();
20879
+ let activeMs = 0;
20880
+ let starts = 0;
20881
+ for (const [s, e] of history || []) {
20882
+ const end = Math.min(e ?? now, now);
20883
+ const a = Math.max(s, m);
20884
+ if (end > a) activeMs += end - a;
20885
+ if (s >= m && s <= now) starts++;
20886
+ }
20887
+ return { activeMs, starts };
20888
+ }
20889
+ function timelineSegments(history, now = Date.now(), windowMs = DAY_MS) {
20890
+ const from = now - windowMs;
20891
+ const out = [];
20892
+ for (const [s, e] of history || []) {
20893
+ const b = Math.min(e ?? now, now);
20894
+ if (b <= from || s >= now) continue;
20895
+ const a = Math.max(s, from);
20896
+ out.push({
20897
+ leftPct: (a - from) / windowMs * 100,
20898
+ widthPct: Math.max((b - a) / windowMs * 100, 0.6),
20899
+ live: e === null,
20900
+ start: s,
20901
+ end: e
20902
+ });
20903
+ }
20904
+ return out;
20905
+ }
20906
+ function formatClock(ts) {
20907
+ if (ts === null || ts === void 0 || !Number.isFinite(ts)) return "\u2014";
20908
+ return new Date(ts).toLocaleTimeString("pt-BR", { hour: "2-digit", minute: "2-digit" });
20909
+ }
20910
+ function formatDuration2(ms) {
20911
+ const m = Math.max(0, Math.round(ms / 6e4));
20912
+ return m < 60 ? `${m} min` : `${Math.floor(m / 60)} h ${String(m % 60).padStart(2, "0")}`;
20913
+ }
20914
+ function indicatorsFromModalData(data) {
20915
+ if (!data) return [];
20916
+ const list = (data.pumps || []).map((p) => ({
20917
+ code: p.code,
20918
+ label: p.label,
20919
+ kind: "pump",
20920
+ active: Array.isArray(p.history) ? isActive(p.history) : null,
20921
+ since: stateSince(p.history),
20922
+ deviceProfile: p.deviceProfile || "BOMBA_POCO"
20923
+ }));
20924
+ (data.valves || []).forEach((v) => {
20925
+ list.push({
20926
+ code: v.code,
20927
+ label: v.label,
20928
+ kind: "valve",
20929
+ active: Array.isArray(v.history) ? isActive(v.history) : null,
20930
+ since: stateSince(v.history),
20931
+ deviceProfile: v.deviceProfile || "SOLENOIDE"
20932
+ });
20933
+ });
20934
+ return list;
20935
+ }
20936
+
20937
+ // src/components/well-pumps/equipmentIndicators.ts
20938
+ var STYLE_ID4 = "myio-equipment-indicators-styles";
20939
+ var PUMP_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="12" cy="12" r="8"/><g class="myio-eq-rotor"><path d="M12 4v4M12 16v4M4 12h4M16 12h4"/></g></svg>`;
20940
+ var VALVE_SVG = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linejoin="round" aria-hidden="true"><path d="M3 7v10l9-5zM21 7v10l-9-5z"/><path d="M12 12V5M9 5h6"/></svg>`;
20941
+ function escapeHtml2(s) {
20942
+ return String(s ?? "").replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" })[c]);
20943
+ }
20944
+ function indicatorStateClass(ind) {
20945
+ if (ind.active === null || ind.active === void 0) return "unk";
20946
+ if (ind.kind === "valve") return ind.active ? "open" : "closed";
20947
+ return ind.active ? "on" : "off";
20948
+ }
20949
+ function indicatorStateText(ind, short = false) {
20950
+ if (ind.active === null || ind.active === void 0) return short ? "S/ leit." : "sem leitura";
20951
+ if (ind.kind === "valve") return ind.active ? short ? "Aberta" : "aberta" : short ? "Fechada" : "fechada";
20952
+ return ind.active ? short ? "Ligada" : "ligada" : short ? "Deslig." : "desligada";
20953
+ }
20954
+ function indicatorTitle(ind) {
20955
+ const profile = ind.deviceProfile ? ` (${ind.deviceProfile})` : "";
20956
+ const since = ind.since ? ` desde ${formatClock(ind.since)}` : "";
20957
+ return `${ind.code} \xB7 ${ind.label}${profile}: ${indicatorStateText(ind)}${ind.active === null || ind.active === void 0 ? "" : since}`;
20958
+ }
20959
+ function ensureEquipmentIndicatorStyles() {
20960
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID4)) return;
20961
+ const style = document.createElement("style");
20962
+ style.id = STYLE_ID4;
20963
+ style.textContent = `
20964
+ .myio-eq-strip{position:absolute;right:12px;top:50%;transform:translateY(-50%);z-index:25;display:flex;flex-direction:column;flex-wrap:wrap-reverse;align-content:flex-end;max-height:96px;gap:4px;font-family:Nunito,system-ui,sans-serif}
20965
+ .myio-eq-strip.clickable{cursor:pointer}
20966
+ .myio-eq-b{position:relative;display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 5px;
20967
+ border-radius:6px;font:800 11px Nunito,system-ui,sans-serif;border:1.5px solid;transition:all .25s;box-sizing:border-box}
20968
+ .myio-eq-b svg{width:13px;height:13px}
20969
+ .myio-eq-b.on{background:#22c55e;border-color:#16a34a;color:#fff;box-shadow:0 0 0 2px rgba(34,197,94,.25)}
20970
+ .myio-eq-b.off{background:#f1f5f9;border-color:#cbd5e1;color:#94a3b8}
20971
+ .myio-eq-b.open{background:#3b82f6;border-color:#1d4ed8;color:#fff;box-shadow:0 0 0 2px rgba(59,130,246,.25)}
20972
+ .myio-eq-b.closed{background:#fef2f2;border-color:#f87171;color:#dc2626}
20973
+ .myio-eq-b.unk{background:#fff;border-style:dashed;border-color:#cbd5e1;color:#94a3b8}
20974
+ .myio-eq-b.on::after,.myio-eq-b.open::after{content:'';position:absolute;top:-3px;right:-3px;width:7px;height:7px;border-radius:50%;
20975
+ border:1.5px solid #fff;animation:myioEqPulse 1.4s ease-in-out infinite}
20976
+ .myio-eq-b.on::after{background:#16a34a}.myio-eq-b.open::after{background:#1d4ed8}
20977
+
20978
+ .myio-eq-tiles{display:flex;gap:6px;justify-content:center;flex-wrap:wrap}
20979
+ .myio-eq-ti{width:50px;padding:6px 0 5px;border-radius:10px;background:rgba(255,255,255,.75);border:1px solid #e2e8f0;
20980
+ box-shadow:0 1px 2px rgba(15,23,42,.06);display:flex;flex-direction:column;align-items:center;gap:2px;
20981
+ font-family:Nunito,system-ui,sans-serif;transition:all .3s}
20982
+ .myio-eq-ti b{font-size:11.5px;font-weight:800;color:#334155;line-height:1}
20983
+ .myio-eq-ti small{font-size:9px;font-weight:700;color:#94a3b8;text-transform:uppercase;letter-spacing:.3px;line-height:1}
20984
+ .myio-eq-ti i{width:8px;height:8px;border-radius:50%;background:#cbd5e1;margin-bottom:2px}
20985
+ .myio-eq-ti.on{border-color:#bbf7d0;background:linear-gradient(180deg,#f0fdf4,#fff)}
20986
+ .myio-eq-ti.on i{background:#22c55e;box-shadow:0 0 0 3px rgba(34,197,94,.18);animation:myioEqPulse 1.6s ease-in-out infinite}
20987
+ .myio-eq-ti.on small{color:#16a34a}
20988
+ .myio-eq-ti.open{border-color:#bfdbfe;background:linear-gradient(180deg,#eff6ff,#fff)}
20989
+ .myio-eq-ti.open i{background:#3b82f6;box-shadow:0 0 0 3px rgba(59,130,246,.18);animation:myioEqPulse 1.6s ease-in-out infinite}
20990
+ .myio-eq-ti.open small{color:#2563eb}
20991
+ .myio-eq-ti.closed{border-color:#fecaca}.myio-eq-ti.closed i{background:#ef4444}.myio-eq-ti.closed small{color:#dc2626}
20992
+
20993
+ .myio-eq-shortcut{display:inline-flex;align-items:center;gap:5px;margin-right:6px;padding:5px 10px;border-radius:8px;cursor:pointer;
20994
+ background:rgba(255,255,255,.14);border:1px solid rgba(255,255,255,.35);color:#fff;font:700 12px Nunito,system-ui,sans-serif}
20995
+ .myio-eq-shortcut:hover{background:rgba(255,255,255,.26)}
20996
+ .myio-eq-shortcut svg{width:15px;height:15px}
20997
+ .myio-eq-shortcut i{font-style:normal;font-size:10px;font-weight:800;padding:1px 5px;border-radius:4px}
20998
+ .myio-eq-shortcut i.on{background:#22c55e;color:#fff}.myio-eq-shortcut i.off,.myio-eq-shortcut i.unk{background:rgba(255,255,255,.25);color:#e2e8f0}
20999
+ .myio-eq-shortcut i.open{background:#3b82f6;color:#fff}.myio-eq-shortcut i.closed{background:#ef4444;color:#fff}
21000
+
21001
+ .myio-eq-rotor{transform-origin:12px 12px}
21002
+ .myio-eq-spin .myio-eq-rotor{animation:myioEqSpin 1s linear infinite}
21003
+ @keyframes myioEqSpin{to{transform:rotate(360deg)}}
21004
+ @keyframes myioEqPulse{0%,100%{opacity:1}50%{opacity:.35}}
21005
+ @media (prefers-reduced-motion:reduce){.myio-eq-b::after,.myio-eq-ti i,.myio-eq-spin .myio-eq-rotor{animation:none!important}}
21006
+ `;
21007
+ document.head.appendChild(style);
21008
+ }
21009
+ function renderEquipmentStripHTML(indicators) {
21010
+ return (indicators || []).map((ind) => {
21011
+ const cls = indicatorStateClass(ind);
21012
+ const content = ind.kind === "valve" && ind.code.length <= 1 ? VALVE_SVG : escapeHtml2(ind.code);
21013
+ return `<span class="myio-eq-b ${cls}" data-code="${escapeHtml2(ind.code)}" title="${escapeHtml2(indicatorTitle(ind))}">${content}</span>`;
21014
+ }).join("");
21015
+ }
21016
+ function createEquipmentIndicatorStrip(indicators, opts = {}) {
21017
+ ensureEquipmentIndicatorStyles();
21018
+ const el2 = document.createElement("div");
21019
+ el2.className = "myio-eq-strip";
21020
+ el2.setAttribute("role", "group");
21021
+ el2.setAttribute("aria-label", "Bombas e solenoide");
21022
+ el2.innerHTML = renderEquipmentStripHTML(indicators);
21023
+ if (typeof opts.onClick === "function") {
21024
+ el2.classList.add("clickable");
21025
+ el2.addEventListener("click", (ev) => {
21026
+ ev.stopPropagation();
21027
+ ev.preventDefault();
21028
+ opts.onClick(ev);
21029
+ });
21030
+ }
21031
+ return el2;
21032
+ }
21033
+ function renderEquipmentTilesHTML(indicators) {
21034
+ if (!indicators?.length) return "";
21035
+ return `<div class="myio-eq-tiles">${indicators.map((ind) => {
21036
+ const cls = indicatorStateClass(ind);
21037
+ return `<div class="myio-eq-ti ${cls}" title="${escapeHtml2(indicatorTitle(ind))}"><i></i><b>${escapeHtml2(ind.code)}</b><small>${indicatorStateText(ind, true)}</small></div>`;
21038
+ }).join("")}</div>`;
21039
+ }
21040
+ function renderEquipmentShortcutHTML(indicators, label = "Bombas") {
21041
+ const anyOn = (indicators || []).some((i) => i.kind === "pump" && i.active === true);
21042
+ return `<span class="${anyOn ? "myio-eq-spin" : ""}" style="display:inline-flex">${PUMP_SVG}</span><span>${escapeHtml2(label)}</span>` + (indicators || []).map((ind) => `<i class="${indicatorStateClass(ind)}">${escapeHtml2(ind.code)}</i>`).join("");
21043
+ }
21044
+
20784
21045
  // src/components/cards/main-view/v5.2.0/template-card-v5.js
20785
21046
  var LABEL_CHAR_LIMIT2 = 18;
20786
21047
  var ENERGY_DEVICE_TYPES = getTypesByCategory("energy");
@@ -20815,7 +21076,9 @@ function renderCardComponentV5({
20815
21076
  // Tooltip on device image for temperature devices
20816
21077
  // Decimal places for the % badge. Resolved at render time so it can be changed
20817
21078
  // without rebuilding the lib: this prop > window.MyIOUtils.percentDecimals > 2.
20818
- percentDecimals
21079
+ percentDecimals,
21080
+ // ED-1354: clique na coluna B1/B2/S (entityObject.equipmentIndicators) — ex.: abre a modal das bombas
21081
+ handleActionEquipment
20819
21082
  }) {
20820
21083
  const {
20821
21084
  entityId,
@@ -20864,7 +21127,9 @@ function renderCardComponentV5({
20864
21127
  excludeGroupsTotals,
20865
21128
  // Card já desenhado, telemetria (valor/status) ainda chegando → spinner no valor, sem selo,
20866
21129
  // status neutro (não marca offline nem pisca enquanto carrega)
20867
- dataLoading = false
21130
+ dataLoading = false,
21131
+ // ED-1354: indicadores B1/B2/S (bombas MOTOR + solenoide) no card do poço
21132
+ equipmentIndicators
20868
21133
  } = entityObject;
20869
21134
  const deviceStatus = dataLoading ? "loading" : rawDeviceStatus;
20870
21135
  const deviceType = deviceProfile || legacyDeviceType || "";
@@ -21019,7 +21284,7 @@ function renderCardComponentV5({
21019
21284
  };
21020
21285
  const isEnergyDevice2 = (deviceType2) => isEnergyDeviceType(deviceType2);
21021
21286
  const isTemperatureDevice2 = (deviceType2) => isTemperatureDeviceType(deviceType2);
21022
- const isTankDevice2 = deviceType === "TANK" || deviceType === "CAIXA_DAGUA";
21287
+ const isTankDevice2 = deviceType === "TANK" || deviceType === "CAIXA_DAGUA" || deviceType === "CISTERNA" || deviceType === "CISTERNA_ENTRADA";
21023
21288
  const percentageForDisplay = isTankDevice2 ? (waterPercentage || 0) * 100 : perc;
21024
21289
  const tankLevelCm = isTankDevice2 ? Number(waterLevel ?? val) : null;
21025
21290
  const _pctDecimals = resolvePercentDecimals(percentDecimals);
@@ -21455,6 +21720,13 @@ function renderCardComponentV5({
21455
21720
  `;
21456
21721
  container.innerHTML = cardHTML;
21457
21722
  const enhancedCardElement = container.querySelector(".device-card-centered");
21723
+ if (Array.isArray(equipmentIndicators) && equipmentIndicators.length > 0 && enhancedCardElement) {
21724
+ enhancedCardElement.appendChild(
21725
+ createEquipmentIndicatorStrip(equipmentIndicators, {
21726
+ onClick: typeof handleActionEquipment === "function" ? () => handleActionEquipment(entityObject) : void 0
21727
+ })
21728
+ );
21729
+ }
21458
21730
  try {
21459
21731
  const _excl = typeof excludeGroupsTotals === "string" ? JSON.parse(excludeGroupsTotals) : excludeGroupsTotals;
21460
21732
  const _isExcluded = !!(_excl && _excl.enabled === true && (_excl.groups && Object.values(_excl.groups).some((v) => v === true) || Array.isArray(_excl.excludedGroups) && _excl.excludedGroups.length > 0));
@@ -27318,7 +27590,7 @@ var TOAST_TYPE_META = {
27318
27590
  warning: { icon: "\u26A0\uFE0F", title: "Aviso" },
27319
27591
  error: { icon: "\u{1F6AB}", title: "Erro" }
27320
27592
  };
27321
- function escapeHtml2(text2) {
27593
+ function escapeHtml3(text2) {
27322
27594
  const div = document.createElement("div");
27323
27595
  div.textContent = text2 == null ? "" : String(text2);
27324
27596
  return div.innerHTML;
@@ -27515,7 +27787,7 @@ var MyIOToast = (function() {
27515
27787
  InfoTooltip_default.show(expandBtn, {
27516
27788
  icon: meta.icon,
27517
27789
  title: meta.title,
27518
- content: escapeHtml2(fullMessage).replace(/\n/g, "<br>")
27790
+ content: escapeHtml3(fullMessage).replace(/\n/g, "<br>")
27519
27791
  });
27520
27792
  });
27521
27793
  toastEl.appendChild(expandBtn);
@@ -35759,7 +36031,7 @@ function paletteColor(base, index, dark) {
35759
36031
  }
35760
36032
  var defaultFormatValue = (v) => Number(v || 0).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
35761
36033
  var fmtPct = (pct) => `${pct.toLocaleString("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 1 })}%`;
35762
- function escapeHtml3(s) {
36034
+ function escapeHtml4(s) {
35763
36035
  return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
35764
36036
  }
35765
36037
  function slugify2(s) {
@@ -35924,7 +36196,7 @@ function createParticipationChart(container, params) {
35924
36196
  content: `
35925
36197
  <div class="myio-info-tooltip__section" style="min-width:180px;">
35926
36198
  <div style="font-size:12px;line-height:1.6;">
35927
- <div><strong>Valor:</strong> ${escapeHtml3(settings.formatValue(item.value))}${settings.unit ? ` ${escapeHtml3(settings.unit)}` : ""}</div>
36199
+ <div><strong>Valor:</strong> ${escapeHtml4(settings.formatValue(item.value))}${settings.unit ? ` ${escapeHtml4(settings.unit)}` : ""}</div>
35928
36200
  <div><strong>Participa\xE7\xE3o:</strong> ${fmtPct(pct)}</div>
35929
36201
  </div>
35930
36202
  </div>
@@ -41006,6 +41278,9 @@ var WaterTankModalView = class {
41006
41278
  * Get tank image URL based on level percentage (same logic as device card)
41007
41279
  */
41008
41280
  getTankImageUrl(percentage) {
41281
+ if (/^CISTERNA(_ENTRADA)?$/.test(String(this.config.params.deviceType || "").toUpperCase())) {
41282
+ return deviceIcons.CISTERNA;
41283
+ }
41009
41284
  if (percentage >= 70) {
41010
41285
  return "https://dashboard.myio-bas.com/api/images/public/3t6WVhMQJFsrKA8bSZmrngDsNPkZV7fq";
41011
41286
  } else if (percentage >= 40) {
@@ -41043,10 +41318,10 @@ var WaterTankModalView = class {
41043
41318
  */
41044
41319
  render() {
41045
41320
  const { params } = this.config;
41046
- const STYLE_ID18 = "myio-water-tank-modal-styles";
41047
- if (!document.getElementById(STYLE_ID18)) {
41321
+ const STYLE_ID20 = "myio-water-tank-modal-styles";
41322
+ if (!document.getElementById(STYLE_ID20)) {
41048
41323
  const style = document.createElement("style");
41049
- style.id = STYLE_ID18;
41324
+ style.id = STYLE_ID20;
41050
41325
  style.textContent = `
41051
41326
  @media (max-width: 640px) {
41052
41327
  .myio-water-tank-modal { width: 100vw !important; max-width: 100vw !important; max-height: 100vh !important; border-radius: 0 !important; }
@@ -41059,6 +41334,7 @@ var WaterTankModalView = class {
41059
41334
  `;
41060
41335
  document.head.appendChild(style);
41061
41336
  }
41337
+ if (params.equipmentIndicators?.length || params.headerActions?.length) ensureEquipmentIndicatorStyles();
41062
41338
  this.overlay = document.createElement("div");
41063
41339
  this.overlay.className = "myio-water-tank-modal-overlay";
41064
41340
  this.overlay.style.cssText = `
@@ -41122,6 +41398,7 @@ var WaterTankModalView = class {
41122
41398
  line-height: 2;
41123
41399
  ">\u{1F4A7} ${title}</h2>
41124
41400
  <div style="display: flex; gap: 4px; align-items: center;">
41401
+ ${this.renderHeaderActions()}
41125
41402
  <button class="myio-water-tank-modal-close" title="${this.i18n.close}" style="
41126
41403
  background: none;
41127
41404
  border: none;
@@ -41136,6 +41413,46 @@ var WaterTankModalView = class {
41136
41413
  </div>
41137
41414
  `;
41138
41415
  }
41416
+ /**
41417
+ * ED-1354: botões extras do header (ex.: atalho "Bombas B1 B2 S")
41418
+ */
41419
+ renderHeaderActions() {
41420
+ const actions = this.config.params.headerActions || [];
41421
+ return actions.map((a, i) => {
41422
+ const content = a.indicators ? renderEquipmentShortcutHTML(a.indicators, a.label) : `<span>${escapeHtml2(a.label)}</span>`;
41423
+ return `<button type="button" class="myio-eq-shortcut" data-header-action="${i}" title="${escapeHtml2(a.title || a.label)}">${content}</button>`;
41424
+ }).join("");
41425
+ }
41426
+ /**
41427
+ * ED-1354: B1/B2/S sob o ícone do reservatório
41428
+ */
41429
+ renderEquipmentTiles() {
41430
+ const indicators = this.config.params.equipmentIndicators;
41431
+ if (!indicators?.length) return "";
41432
+ return `<div class="myio-water-tank-equipment">${renderEquipmentTilesHTML(indicators)}</div>`;
41433
+ }
41434
+ /**
41435
+ * ED-1354: atualiza tiles e mini-badges dos atalhos sem re-renderizar a modal
41436
+ */
41437
+ updateEquipmentIndicators(indicators) {
41438
+ const { params } = this.config;
41439
+ params.equipmentIndicators = indicators;
41440
+ if (!this.modal) return;
41441
+ ensureEquipmentIndicatorStyles();
41442
+ const tiles = this.modal.querySelector(".myio-water-tank-equipment");
41443
+ if (tiles) {
41444
+ tiles.innerHTML = renderEquipmentTilesHTML(indicators);
41445
+ } else {
41446
+ const img = this.modal.querySelector(".myio-water-tank-tank-panel img");
41447
+ img?.insertAdjacentHTML("afterend", this.renderEquipmentTiles());
41448
+ }
41449
+ (params.headerActions || []).forEach((a, i) => {
41450
+ if (!a.indicators) return;
41451
+ a.indicators = indicators;
41452
+ const btn = this.modal.querySelector(`[data-header-action="${i}"]`);
41453
+ if (btn) btn.innerHTML = renderEquipmentShortcutHTML(indicators, a.label);
41454
+ });
41455
+ }
41139
41456
  /**
41140
41457
  * RFC-0107: Render modal body with new layout
41141
41458
  * Left side: Tank visualization with percentage
@@ -41294,6 +41611,7 @@ var WaterTankModalView = class {
41294
41611
  height: auto;
41295
41612
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1));
41296
41613
  "/>
41614
+ ${this.renderEquipmentTiles()}
41297
41615
  <div style="
41298
41616
  font-size: 42px;
41299
41617
  font-weight: 700;
@@ -41756,6 +42074,17 @@ var WaterTankModalView = class {
41756
42074
  if (closeBtn) {
41757
42075
  closeBtn.addEventListener("click", () => this.config.onClose());
41758
42076
  }
42077
+ this.modal.querySelectorAll("[data-header-action]").forEach((btn) => {
42078
+ btn.addEventListener("click", (e) => {
42079
+ e.stopPropagation();
42080
+ const action = this.config.params.headerActions?.[Number(btn.dataset.headerAction)];
42081
+ try {
42082
+ action?.onClick();
42083
+ } catch (err) {
42084
+ console.warn("[WaterTankModal] headerAction falhou:", err);
42085
+ }
42086
+ });
42087
+ });
41759
42088
  const exportBtn = this.modal.querySelector(".myio-water-tank-export-btn");
41760
42089
  if (exportBtn) {
41761
42090
  exportBtn.addEventListener("click", () => this.config.onExport());
@@ -42401,7 +42730,9 @@ var WaterTankModal = class {
42401
42730
  }
42402
42731
  dbg5("[WaterTankModal] Modal opened successfully");
42403
42732
  return {
42404
- close: () => this.close()
42733
+ close: () => this.close(),
42734
+ // ED-1354: host atualiza B1/B2/S (tiles + atalho) sem reabrir a modal
42735
+ updateEquipmentIndicators: (indicators) => this.view?.updateEquipmentIndicators(indicators)
42405
42736
  };
42406
42737
  } catch (error) {
42407
42738
  console.error("[WaterTankModal] Failed to show modal:", error);
@@ -50986,8 +51317,8 @@ var AnnotationsTab = class {
50986
51317
  */
50987
51318
  toggleTypeFilter(type) {
50988
51319
  if (type === "archived") {
50989
- const isActive = this.filters.statusList?.includes("archived") || false;
50990
- this.filters.statusList = isActive ? [] : ["archived"];
51320
+ const isActive2 = this.filters.statusList?.includes("archived") || false;
51321
+ this.filters.statusList = isActive2 ? [] : ["archived"];
50991
51322
  this.applyFilters();
50992
51323
  return;
50993
51324
  }
@@ -53660,24 +53991,24 @@ var BUILDING_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="
53660
53991
  function renderAlarmCard(alarm, _params) {
53661
53992
  const severityConfig = SEVERITY_CONFIG[alarm.severity];
53662
53993
  const stateConfig = STATE_CONFIG[alarm.state];
53663
- const isActive = isAlarmActive(alarm.state);
53994
+ const isActive2 = isAlarmActive(alarm.state);
53664
53995
  const firstSeenRelative = formatRelativeTimeShort(alarm.firstOccurrence);
53665
53996
  const lastSeenRelative = formatRelativeTimeShort(alarm.lastOccurrence);
53666
53997
  const isSelected = _params?.selected ?? false;
53667
53998
  const rawTitle = alarm.title || "Sem t\xEDtulo";
53668
53999
  const truncatedTitle = rawTitle.length > 42 ? rawTitle.substring(0, 42) + "\u2026" : rawTitle;
53669
- const safeTitle = escapeHtml4(truncatedTitle);
53670
- const safeTitleFull = escapeHtml4(rawTitle);
53671
- const safeCustomerName = escapeHtml4(alarm.customerName || "N/A");
54000
+ const safeTitle = escapeHtml5(truncatedTitle);
54001
+ const safeTitleFull = escapeHtml5(rawTitle);
54002
+ const safeCustomerName = escapeHtml5(alarm.customerName || "N/A");
53672
54003
  const safeOccurrences = alarm.occurrenceCount || 1;
53673
54004
  const showCustomer = _params?.showCustomerName ?? true;
53674
54005
  const showDeviceBadge = _params?.showDeviceBadge ?? false;
53675
- const safeSource = escapeHtml4(alarm.source || "");
54006
+ const safeSource = escapeHtml5(alarm.source || "");
53676
54007
  const alarmTypes = _params?.alarmTypes ?? [];
53677
54008
  const typeChipsHtml = alarmTypes.length > 0 ? `<div class="alarm-card-type-scroll">
53678
54009
  <button class="alarm-type-scroll-btn alarm-type-scroll-btn--left" tabindex="-1" aria-hidden="true">&#8249;</button>
53679
54010
  <div class="alarm-card-type-list">${alarmTypes.map(
53680
- (t) => `<span class="alarm-type-chip" title="${escapeHtml4(t)}">${escapeHtml4(t.length > 22 ? t.substring(0, 22) + "\u2026" : t)}</span>`
54011
+ (t) => `<span class="alarm-type-chip" title="${escapeHtml5(t)}">${escapeHtml5(t.length > 22 ? t.substring(0, 22) + "\u2026" : t)}</span>`
53681
54012
  ).join("")}</div>
53682
54013
  <button class="alarm-type-scroll-btn alarm-type-scroll-btn--right" tabindex="-1" aria-hidden="true">&#8250;</button>
53683
54014
  </div>` : "";
@@ -53687,7 +54018,7 @@ function renderAlarmCard(alarm, _params) {
53687
54018
  return `<article class="alarm-card${isSelected ? " alarm-card--selected" : ""}${hideDetails ? " alarm-card--clickable" : ""}" data-alarm-id="${alarm.id}" data-severity="${alarm.severity}" data-state="${alarm.state}">
53688
54019
  <header class="alarm-card-header">
53689
54020
  ${!hideSelect ? `<label class="alarm-card-checkbox-wrap" title="Selecionar para a\xE7\xE3o em lote" onclick="event.stopPropagation()">
53690
- <input type="checkbox" class="alarm-card-select" data-alarm-id="${alarm.id}" data-alarm-title="${escapeHtml4(rawTitle)}"${isSelected ? " checked" : ""}>
54021
+ <input type="checkbox" class="alarm-card-select" data-alarm-id="${alarm.id}" data-alarm-title="${escapeHtml5(rawTitle)}"${isSelected ? " checked" : ""}>
53691
54022
  </label>` : ""}
53692
54023
  ${showDeviceBadge && safeSource ? `<span class="alarm-card-device-badge" title="${safeSource}">${safeSource}</span>` : ""}
53693
54024
  <div class="alarm-card-badges">
@@ -53715,7 +54046,7 @@ function renderAlarmCard(alarm, _params) {
53715
54046
  </div>
53716
54047
  </div>
53717
54048
  <footer class="alarm-card-footer">
53718
- ${!_params?.hideActions && _params?.canAcknowledge !== false && isActive ? `<button class="btn btn-ack" data-action="acknowledge" data-alarm-id="${alarm.id}" title="Reconhecer"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" aria-hidden="true"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg></button>` : ""}
54049
+ ${!_params?.hideActions && _params?.canAcknowledge !== false && isActive2 ? `<button class="btn btn-ack" data-action="acknowledge" data-alarm-id="${alarm.id}" title="Reconhecer"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" aria-hidden="true"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg></button>` : ""}
53719
54050
  ${!_params?.hideActions && _params?.canSnooze !== false && alarm.state !== "CLOSED" ? `<button class="btn btn-snooze" data-action="snooze" data-alarm-id="${alarm.id}" title="Adiar"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" aria-hidden="true"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67V7z"/></svg></button>` : ""}
53720
54051
  ${!_params?.hideActions && _params?.canEscalate !== false && alarm.state !== "CLOSED" ? `<button class="btn btn-escalate" data-action="escalate" data-alarm-id="${alarm.id}" title="Escalar"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" aria-hidden="true"><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg></button>` : ""}
53721
54052
  ${!hideDetails ? `<button class="btn btn-details" data-action="details" data-alarm-id="${alarm.id}" title="Detalhes"><svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" aria-hidden="true"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg></button>` : ""}
@@ -53843,7 +54174,7 @@ function _attachAnnotationBadges(card, alarmId) {
53843
54174
  if (!addedAny) return;
53844
54175
  card.appendChild(container);
53845
54176
  }
53846
- function escapeHtml4(text2) {
54177
+ function escapeHtml5(text2) {
53847
54178
  const div = document.createElement("div");
53848
54179
  div.textContent = text2;
53849
54180
  return div.innerHTML;
@@ -55110,7 +55441,7 @@ function openAlarmDetailsModal(alarm, themeMode = "light", groupMode, onAction)
55110
55441
  }
55111
55442
  const showDevice = !isSeparado && devices.length > 0;
55112
55443
  const showAlarm = groupMode === "porDispositivo" && (alarm._groupAlarmIds?.length || 0) > 1;
55113
- const isActive = alarm.state === "OPEN" || alarm.state === "ESCALATED";
55444
+ const isActive2 = alarm.state === "OPEN" || alarm.state === "ESCALATED";
55114
55445
  const isClosed = alarm.state === "CLOSED";
55115
55446
  const occIndex = /* @__PURE__ */ new Map();
55116
55447
  occEvents().forEach((e, i) => occIndex.set(e, i + 1));
@@ -55159,7 +55490,7 @@ function openAlarmDetailsModal(alarm, themeMode = "light", groupMode, onAction)
55159
55490
  <td class="adm-rpt-cell adm-tl-action-cell">
55160
55491
  ${e.occurrence ? `<label class="adm-tl-cb-wrap" data-cb-wrap><input type="checkbox" class="adm-tl-row-cb" data-item-id="${escHtml2(itemId)}"></label>
55161
55492
  <div class="adm-tl-row-btns" data-row-btns>
55162
- ${isActive ? `<button class="adm-tl-row-btn adm-tl-row-btn--ack" data-action="acknowledge" data-item-id="${escHtml2(itemId)}" title="Reconhecer">${_svgAck}</button>` : ""}
55493
+ ${isActive2 ? `<button class="adm-tl-row-btn adm-tl-row-btn--ack" data-action="acknowledge" data-item-id="${escHtml2(itemId)}" title="Reconhecer">${_svgAck}</button>` : ""}
55163
55494
  ${!isClosed ? `<button class="adm-tl-row-btn adm-tl-row-btn--snooze" data-action="snooze" data-item-id="${escHtml2(itemId)}" title="Adiar">${_svgSnooze}</button>` : ""}
55164
55495
  ${!isClosed ? `<button class="adm-tl-row-btn adm-tl-row-btn--escalate" data-action="escalate" data-item-id="${escHtml2(itemId)}" title="Escalar">${_svgEscalate}</button>` : ""}
55165
55496
  </div>` : ""}
@@ -63550,10 +63881,10 @@ ${this._formatFileSize(f.size)} \xB7 ${f.type || "arquivo"}`;
63550
63881
  // Styles
63551
63882
  // ==========================================================================
63552
63883
  injectStyles() {
63553
- const STYLE_ID18 = "myio-tickets-tab-styles";
63554
- if (document.getElementById(STYLE_ID18)) return;
63884
+ const STYLE_ID20 = "myio-tickets-tab-styles";
63885
+ if (document.getElementById(STYLE_ID20)) return;
63555
63886
  const style = document.createElement("style");
63556
- style.id = STYLE_ID18;
63887
+ style.id = STYLE_ID20;
63557
63888
  style.textContent = `
63558
63889
  /* ===== TicketsTab layout ===== */
63559
63890
  .ct-tab {
@@ -68606,11 +68937,11 @@ function connectivityFieldsetHtml(data, l, language, errors) {
68606
68937
  </div>
68607
68938
  `;
68608
68939
  }
68609
- var STYLE_ID4 = "myio-central-settings-modal-styles";
68940
+ var STYLE_ID5 = "myio-central-settings-modal-styles";
68610
68941
  function injectStyles9() {
68611
- if (typeof document === "undefined" || document.getElementById(STYLE_ID4)) return;
68942
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID5)) return;
68612
68943
  const tag = document.createElement("style");
68613
- tag.id = STYLE_ID4;
68944
+ tag.id = STYLE_ID5;
68614
68945
  tag.textContent = `
68615
68946
  .myio-csettings__input{
68616
68947
  font:600 13px 'Nunito', system-ui, sans-serif;padding:6px 8px;border-radius:6px;
@@ -74600,14 +74931,14 @@ var DEFAULT_CONFIG_TEMPLATE2 = {
74600
74931
  };
74601
74932
 
74602
74933
  // src/components/footer/styles.ts
74603
- var STYLE_ID5 = "myio-footer-component-styles";
74934
+ var STYLE_ID6 = "myio-footer-component-styles";
74604
74935
  function areStylesInjected() {
74605
- return !!document.getElementById(STYLE_ID5);
74936
+ return !!document.getElementById(STYLE_ID6);
74606
74937
  }
74607
74938
  function injectStyles10() {
74608
74939
  if (areStylesInjected()) return;
74609
74940
  const style = document.createElement("style");
74610
- style.id = STYLE_ID5;
74941
+ style.id = STYLE_ID6;
74611
74942
  style.textContent = getStyles();
74612
74943
  document.head.appendChild(style);
74613
74944
  }
@@ -75925,10 +76256,10 @@ function render(container, modalId, state6) {
75925
76256
  <div class="alarm-list">
75926
76257
  ${state6.alarms.map((a) => `
75927
76258
  <div class="alarm-row">
75928
- <div class="alarm-title">${escapeHtml5(a.title || a.id)}</div>
75929
- <div class="alarm-meta">${escapeHtml5(a.customerName || "")}</div>
75930
- <div class="alarm-meta">${escapeHtml5(a.severity)}</div>
75931
- <div class="alarm-meta">${escapeHtml5(a.state)}</div>
76259
+ <div class="alarm-title">${escapeHtml6(a.title || a.id)}</div>
76260
+ <div class="alarm-meta">${escapeHtml6(a.customerName || "")}</div>
76261
+ <div class="alarm-meta">${escapeHtml6(a.severity)}</div>
76262
+ <div class="alarm-meta">${escapeHtml6(a.state)}</div>
75932
76263
  <div class="alarm-meta">${formatDate2(a.lastOccurrence, state6.locale, true)}</div>
75933
76264
  </div>
75934
76265
  `).join("")}
@@ -76115,7 +76446,7 @@ function buildBars(data, order, colors2) {
76115
76446
  const pct = Math.round(value / maxVal * 100);
76116
76447
  return `
76117
76448
  <div class="bar-row">
76118
- <span class="bar-label">${escapeHtml5(String(key))}</span>
76449
+ <span class="bar-label">${escapeHtml6(String(key))}</span>
76119
76450
  <div class="bar-track"><div class="bar-fill" style="width:${pct}%"></div></div>
76120
76451
  <span class="bar-value">${value}</span>
76121
76452
  </div>
@@ -76145,7 +76476,7 @@ function toTime(value) {
76145
76476
  const parsed = new Date(value).getTime();
76146
76477
  return Number.isNaN(parsed) ? 0 : parsed;
76147
76478
  }
76148
- function escapeHtml5(text2) {
76479
+ function escapeHtml6(text2) {
76149
76480
  const div = document.createElement("div");
76150
76481
  div.textContent = text2 || "";
76151
76482
  return div.innerHTML;
@@ -76332,8 +76663,8 @@ function render2(container, modalId, state6) {
76332
76663
  </div>
76333
76664
  ${state6.devices.map((d) => `
76334
76665
  <div class="device-table-row">
76335
- <div class="col-name">${escapeHtml6(d.name)}</div>
76336
- <div class="col-customer">${escapeHtml6(d.customerName)}</div>
76666
+ <div class="col-name">${escapeHtml7(d.name)}</div>
76667
+ <div class="col-customer">${escapeHtml7(d.customerName)}</div>
76337
76668
  <div class="col-status">
76338
76669
  <span class="status-badge" style="background: ${STATUS_COLORS3[d.status] || "#6b7280"}20; color: ${STATUS_COLORS3[d.status] || "#6b7280"};">
76339
76670
  ${STATUS_LABELS5[d.status] || d.status}
@@ -76580,7 +76911,7 @@ function buildHorizontalBarChart(devices, metric, unit, colors2, getColor, inver
76580
76911
  const displayValue = metric === "availability" ? value.toFixed(1) : value.toFixed(metric === "mttr" ? 1 : 0);
76581
76912
  return `
76582
76913
  <div class="bar-row">
76583
- <span class="bar-label" title="${escapeHtml6(d.name)}">${escapeHtml6(d.name)}</span>
76914
+ <span class="bar-label" title="${escapeHtml7(d.name)}">${escapeHtml7(d.name)}</span>
76584
76915
  <div class="bar-track">
76585
76916
  <div class="bar-fill" style="width:${pct}%; background:${color};"></div>
76586
76917
  </div>
@@ -76611,7 +76942,7 @@ function formatDate3(value, locale) {
76611
76942
  if (isNaN(d.getTime())) return "-";
76612
76943
  return d.toLocaleDateString(locale, { day: "2-digit", month: "2-digit", year: "numeric" });
76613
76944
  }
76614
- function escapeHtml6(text2) {
76945
+ function escapeHtml7(text2) {
76615
76946
  const div = document.createElement("div");
76616
76947
  div.textContent = text2 || "";
76617
76948
  return div.innerHTML;
@@ -78913,6 +79244,247 @@ async function openDashboardPopupSettings(params) {
78913
79244
  }
78914
79245
  }
78915
79246
 
79247
+ // src/components/well-pumps/WellPumpsModal.ts
79248
+ var STYLE_ID7 = "myio-well-pumps-modal-styles";
79249
+ var TICK_MS = 3e4;
79250
+ function ensureStyles() {
79251
+ if (document.getElementById(STYLE_ID7)) return;
79252
+ const style = document.createElement("style");
79253
+ style.id = STYLE_ID7;
79254
+ style.textContent = `
79255
+ .myio-wp-overlay{position:fixed;inset:0;background:rgba(15,23,42,.55);backdrop-filter:blur(2px);display:flex;align-items:center;
79256
+ justify-content:center;font-family:Nunito,system-ui,sans-serif;animation:myioWpFade .15s ease-out}
79257
+ @keyframes myioWpFade{from{opacity:0}to{opacity:1}}
79258
+ .myio-wp-modal{width:min(880px,94vw);max-height:90vh;overflow:auto;background:#f8fafc;border-radius:14px;box-shadow:0 24px 64px rgba(0,0,0,.35);color:#1e293b}
79259
+ .myio-wp-head{display:flex;align-items:center;gap:12px;padding:16px 20px;color:#fff;background:linear-gradient(135deg,#3e1a7d 0%,#5b2bb5 100%);
79260
+ border-radius:14px 14px 0 0;position:sticky;top:0;z-index:2}
79261
+ .myio-wp-head h2{margin:0;font-size:17px;font-weight:800;color:#fff}
79262
+ .myio-wp-head p{margin:2px 0 0;font-size:12px;opacity:.85}
79263
+ .myio-wp-sim{margin-left:auto;font-size:10px;font-weight:800;background:rgba(255,255,255,.18);border:1px solid rgba(255,255,255,.35);padding:2px 8px;border-radius:999px}
79264
+ .myio-wp-close{margin-left:auto;background:rgba(255,255,255,.15);border:0;color:#fff;width:32px;height:32px;border-radius:8px;font-size:18px;cursor:pointer;flex:none}
79265
+ .myio-wp-sim + .myio-wp-close{margin-left:0}
79266
+ .myio-wp-close:hover{background:rgba(255,255,255,.28)}
79267
+ .myio-wp-body{padding:18px 20px 20px;display:flex;flex-direction:column;gap:16px}
79268
+ .myio-wp-empty{padding:28px;text-align:center;color:#64748b;font-size:13px}
79269
+ .myio-wp-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
79270
+ .myio-wp-kpi{background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:10px 12px}
79271
+ .myio-wp-kpi small{display:block;font-size:11px;color:#64748b;font-weight:700;text-transform:uppercase;letter-spacing:.3px}
79272
+ .myio-wp-kpi b{font-size:20px;font-weight:800}
79273
+ .myio-wp-kpi .sub{font-size:11px;color:#64748b}
79274
+ .myio-wp-kpi b.open{color:#1d4ed8}.myio-wp-kpi b.closed{color:#b91c1c}
79275
+ .myio-wp-pumps{display:grid;grid-template-columns:1fr 1fr;gap:14px}
79276
+ @media (max-width:720px){.myio-wp-pumps,.myio-wp-kpis{grid-template-columns:1fr}}
79277
+ .myio-wp-card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:14px;display:flex;flex-direction:column;gap:12px;transition:box-shadow .2s,border-color .2s}
79278
+ .myio-wp-card.focus{border-color:#7c3aed;box-shadow:0 0 0 3px rgba(124,58,237,.18)}
79279
+ .myio-wp-top{display:flex;align-items:center;gap:12px}
79280
+ .myio-wp-img{width:54px;height:54px;object-fit:contain;transition:filter .3s}
79281
+ .myio-wp-card.is-off .myio-wp-img,.myio-wp-card.is-closed .myio-wp-img{filter:grayscale(1) opacity(.55)}
79282
+ .myio-wp-name{font-weight:800;font-size:15px}
79283
+ .myio-wp-tag{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:22px;padding:0 5px;border-radius:6px;
79284
+ font:800 11px Nunito,system-ui,sans-serif;margin-right:6px;vertical-align:middle;background:#e2e8f0;color:#64748b}
79285
+ .myio-wp-card.is-on .myio-wp-tag{background:#22c55e;color:#fff}
79286
+ .myio-wp-card.is-open .myio-wp-tag{background:#3b82f6;color:#fff}
79287
+ .myio-wp-card.is-closed .myio-wp-tag{background:#fecaca;color:#b91c1c}
79288
+ .myio-wp-meta{font-size:11.5px;color:#64748b;display:flex;gap:6px;align-items:center;flex-wrap:wrap;margin-top:2px}
79289
+ .myio-wp-prof{font-size:10px;font-weight:800;color:#475569;background:#f1f5f9;border:1px solid #e2e8f0;border-radius:4px;padding:0 5px}
79290
+ .myio-wp-state{margin-left:auto;display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:999px;font-weight:800;font-size:13px;border:1px solid;white-space:nowrap}
79291
+ .myio-wp-state svg{width:16px;height:16px}
79292
+ .myio-wp-state.on{background:#dcfce7;border-color:#22c55e;color:#15803d}
79293
+ .myio-wp-state.off{background:#f1f5f9;border-color:#cbd5e1;color:#64748b}
79294
+ .myio-wp-state.open{background:#dbeafe;border-color:#3b82f6;color:#1d4ed8}
79295
+ .myio-wp-state.closed{background:#fef2f2;border-color:#fca5a5;color:#b91c1c}
79296
+ .myio-wp-state.unk{background:#fff;border-style:dashed;border-color:#cbd5e1;color:#94a3b8}
79297
+ .myio-wp-state.on .myio-eq-rotor{transform-origin:12px 12px;animation:myioWpSpin 1s linear infinite}
79298
+ @keyframes myioWpSpin{to{transform:rotate(360deg)}}
79299
+ .myio-wp-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
79300
+ .myio-wp-cell{background:#f8fafc;border:1px solid #eef2f7;border-radius:8px;padding:7px 9px}
79301
+ .myio-wp-cell small{display:block;font-size:10.5px;color:#64748b;font-weight:700}
79302
+ .myio-wp-cell span{font-size:14px;font-weight:800}
79303
+ .myio-wp-level{display:flex;align-items:center;gap:8px;font-size:12px;color:#475569}
79304
+ .myio-wp-bar{flex:1;height:8px;border-radius:999px;background:#e2e8f0;overflow:hidden}
79305
+ .myio-wp-bar i{display:block;height:100%;background:linear-gradient(90deg,#38bdf8,#0284c7);border-radius:999px}
79306
+ .myio-wp-tl small{font-size:10.5px;color:#64748b;font-weight:700;display:flex;justify-content:space-between}
79307
+ .myio-wp-track{position:relative;height:16px;border-radius:5px;background:#eef2f7;margin:4px 0 2px;overflow:hidden}
79308
+ .myio-wp-seg{position:absolute;top:0;bottom:0;background:#22c55e;border-radius:3px}
79309
+ .myio-wp-seg.live{background:repeating-linear-gradient(45deg,#22c55e 0 6px,#16a34a 6px 12px)}
79310
+ .myio-wp-seg.valve{background:#3b82f6}
79311
+ .myio-wp-seg.valve.live{background:repeating-linear-gradient(45deg,#3b82f6 0 6px,#1d4ed8 6px 12px)}
79312
+ .myio-wp-valve{display:grid;grid-template-columns:auto 1fr;gap:12px 16px;align-items:center}
79313
+ .myio-wp-foot{font-size:11.5px;color:#64748b}
79314
+ @media (prefers-reduced-motion:reduce){.myio-wp-overlay{animation:none}.myio-wp-state.on .myio-eq-rotor{animation:none}}
79315
+ `;
79316
+ document.head.appendChild(style);
79317
+ }
79318
+ var fmtKw = (n) => `${n.toFixed(1).replace(".", ",")} kW`;
79319
+ function timelineHTML(history, now, kind) {
79320
+ const segs = timelineSegments(history, now, DAY_MS).map((s) => {
79321
+ const title = `${kind === "valve" ? "aberta " : ""}${formatClock(s.start)} \u2013 ${s.end ? formatClock(s.end) : "agora"}`;
79322
+ return `<span class="myio-wp-seg ${kind === "valve" ? "valve" : ""} ${s.live ? "live" : ""}" style="left:${s.leftPct.toFixed(3)}%;width:${s.widthPct.toFixed(3)}%" title="${title}"></span>`;
79323
+ }).join("");
79324
+ return `
79325
+ <div class="myio-wp-tl">
79326
+ <small><span>\xDAltimas 24 h</span><span>${kind === "valve" ? "azul = aberta" : "verde = ligada"}</span></small>
79327
+ <div class="myio-wp-track">${segs}</div>
79328
+ <small><span>${formatClock(now - DAY_MS)}</span><span>agora</span></small>
79329
+ </div>`;
79330
+ }
79331
+ function pumpCardHTML(p, now, images, focusWellId) {
79332
+ const on = isActive(p.history);
79333
+ const known = Array.isArray(p.history);
79334
+ const since = stateSince(p.history);
79335
+ const { activeMs, starts } = dayStats(p.history, now);
79336
+ const power = on ? typeof p.powerKw === "number" ? fmtKw(p.powerKw) : "\u2014" : fmtKw(0).replace(",0", "");
79337
+ const hasLevel = typeof p.wellLevelMca === "number";
79338
+ const hasPerc = typeof p.wellPercentage === "number";
79339
+ const pct = hasPerc ? Math.round(Math.max(0, Math.min(1, p.wellPercentage)) * 100) : null;
79340
+ const meta = [p.identifier, p.wellLabel].filter(Boolean).map(escapeHtml2).join(" \xB7 ");
79341
+ return `
79342
+ <div class="myio-wp-card ${on ? "is-on" : "is-off"} ${focusWellId && p.wellId === focusWellId ? "focus" : ""}" data-code="${escapeHtml2(p.code)}">
79343
+ <div class="myio-wp-top">
79344
+ <img class="myio-wp-img" src="${escapeHtml2(images.pump)}" alt="">
79345
+ <div>
79346
+ <div class="myio-wp-name"><span class="myio-wp-tag">${escapeHtml2(p.code)}</span>${escapeHtml2(p.label)}</div>
79347
+ <div class="myio-wp-meta"><span class="myio-wp-prof">${escapeHtml2(p.deviceProfile || "BOMBA_POCO")}</span>${meta}</div>
79348
+ </div>
79349
+ <span class="myio-wp-state ${!known ? "unk" : on ? "on" : "off"}">${PUMP_SVG}${!known ? "SEM LEITURA" : on ? "LIGADA" : "DESLIGADA"}</span>
79350
+ </div>
79351
+ <div class="myio-wp-grid">
79352
+ <div class="myio-wp-cell"><small>${on ? "Ligada desde" : "Desligada desde"}</small><span>${formatClock(since)}</span></div>
79353
+ <div class="myio-wp-cell"><small>Tempo ligada hoje</small><span>${formatDuration2(activeMs)}</span></div>
79354
+ <div class="myio-wp-cell"><small>Acionamentos hoje</small><span>${starts}</span></div>
79355
+ <div class="myio-wp-cell"><small>Pot\xEAncia atual</small><span>${power}</span></div>
79356
+ <div class="myio-wp-cell"><small>Estado h\xE1</small><span>${since ? formatDuration2(now - since) : "\u2014"}</span></div>
79357
+ <div class="myio-wp-cell"><small>N\xEDvel do po\xE7o</small><span>${hasLevel ? `${(p.wellLevelMca / 100).toFixed(2).replace(".", ",")} M.C.A` : "\u2014"}</span></div>
79358
+ </div>
79359
+ ${pct !== null ? `<div class="myio-wp-level">${escapeHtml2(p.wellLabel || "Po\xE7o")}<div class="myio-wp-bar"><i style="width:${pct}%"></i></div>${pct}%</div>` : ""}
79360
+ ${timelineHTML(p.history, now, "pump")}
79361
+ </div>`;
79362
+ }
79363
+ function valveCardHTML(v, now, images) {
79364
+ const open = isActive(v.history);
79365
+ const known = Array.isArray(v.history);
79366
+ const since = stateSince(v.history);
79367
+ const { activeMs, starts } = dayStats(v.history, now);
79368
+ const meta = [v.identifier, v.description].filter(Boolean).map(escapeHtml2).join(" \xB7 ");
79369
+ return `
79370
+ <div class="myio-wp-card myio-wp-valve ${open ? "is-open" : "is-closed"}" data-code="${escapeHtml2(v.code)}">
79371
+ <img class="myio-wp-img" src="${escapeHtml2(images.valve)}" alt="">
79372
+ <div style="display:flex;flex-direction:column;gap:10px;min-width:0">
79373
+ <div class="myio-wp-top">
79374
+ <div>
79375
+ <div class="myio-wp-name"><span class="myio-wp-tag">${escapeHtml2(v.code)}</span>${escapeHtml2(v.label)}</div>
79376
+ <div class="myio-wp-meta"><span class="myio-wp-prof">${escapeHtml2(v.deviceProfile || "SOLENOIDE")}</span>${meta}</div>
79377
+ </div>
79378
+ <span class="myio-wp-state ${!known ? "unk" : open ? "open" : "closed"}">${VALVE_SVG}${!known ? "SEM LEITURA" : open ? "ABERTA" : "FECHADA"}</span>
79379
+ </div>
79380
+ <div class="myio-wp-grid">
79381
+ <div class="myio-wp-cell"><small>${open ? "Aberta desde" : "Fechada desde"}</small><span>${formatClock(since)}</span></div>
79382
+ <div class="myio-wp-cell"><small>Tempo aberta hoje</small><span>${formatDuration2(activeMs)}</span></div>
79383
+ <div class="myio-wp-cell"><small>Aberturas hoje</small><span>${starts}</span></div>
79384
+ </div>
79385
+ ${timelineHTML(v.history, now, "valve")}
79386
+ </div>
79387
+ </div>`;
79388
+ }
79389
+ function renderWellPumpsBodyHTML(data, opts = {}) {
79390
+ const now = opts.now ?? Date.now();
79391
+ const images = {
79392
+ pump: opts.images?.pump || deviceIcons.BOMBA_POCO,
79393
+ valve: opts.images?.valve || deviceIcons.SOLENOIDE
79394
+ };
79395
+ const pumps = data?.pumps || [];
79396
+ const valves = data?.valves || [];
79397
+ if (!pumps.length && !valves.length) return `<div class="myio-wp-empty">Nenhuma bomba ou solenoide vinculada a este po\xE7o.</div>`;
79398
+ const onPumps = pumps.filter((p) => isActive(p.history));
79399
+ const knownPower = onPumps.filter((p) => typeof p.powerKw === "number");
79400
+ const totalPower = knownPower.length ? fmtKw(knownPower.reduce((s, p) => s + p.powerKw, 0)) : onPumps.length ? "\u2014" : "0 kW";
79401
+ const openValves = valves.filter((v) => isActive(v.history));
79402
+ const valveKpi = valves.length === 1 ? `<div class="myio-wp-kpi"><small>${escapeHtml2(valves[0].label)}</small><b class="${openValves.length ? "open" : "closed"}">${openValves.length ? "Aberta" : "Fechada"}</b>
79403
+ <div class="sub">desde ${formatClock(stateSince(valves[0].history))}</div></div>` : valves.length > 1 ? `<div class="myio-wp-kpi"><small>Solenoides abertas</small><b>${openValves.length} de ${valves.length}</b></div>` : "";
79404
+ return `
79405
+ <div class="myio-wp-kpis">
79406
+ <div class="myio-wp-kpi"><small>Bombas ligadas</small><b>${onPumps.length} de ${pumps.length}</b></div>
79407
+ <div class="myio-wp-kpi"><small>Pot\xEAncia total</small><b>${totalPower}</b></div>
79408
+ ${valveKpi}
79409
+ </div>
79410
+ ${pumps.length ? `<div class="myio-wp-pumps">${pumps.map((p) => pumpCardHTML(p, now, images, opts.focusWellId)).join("")}</div>` : ""}
79411
+ ${valves.map((v) => valveCardHTML(v, now, images)).join("")}
79412
+ ${opts.footnote ? `<div class="myio-wp-foot">\u24D8 ${escapeHtml2(opts.footnote)}</div>` : ""}`;
79413
+ }
79414
+ function openWellPumpsModal(params) {
79415
+ ensureStyles();
79416
+ const overlay = document.createElement("div");
79417
+ overlay.className = "myio-wp-overlay";
79418
+ overlay.style.zIndex = String(params.zIndex ?? 1e5);
79419
+ overlay.innerHTML = `
79420
+ <div class="myio-wp-modal" role="dialog" aria-modal="true" aria-labelledby="myio-wp-title">
79421
+ <div class="myio-wp-head">
79422
+ <div>
79423
+ <h2 id="myio-wp-title">${escapeHtml2(params.title || "Automa\xE7\xE3o dos Po\xE7os")}</h2>
79424
+ ${params.subtitle ? `<p>${escapeHtml2(params.subtitle)}</p>` : ""}
79425
+ </div>
79426
+ ${params.simulated ? '<span class="myio-wp-sim">SIMULADO</span>' : ""}
79427
+ <button type="button" class="myio-wp-close" title="Fechar" aria-label="Fechar">\xD7</button>
79428
+ </div>
79429
+ <div class="myio-wp-body"><div class="myio-wp-empty">Carregando\u2026</div></div>
79430
+ </div>`;
79431
+ const body = overlay.querySelector(".myio-wp-body");
79432
+ let current = null;
79433
+ let closed = false;
79434
+ const timers = [];
79435
+ const render3 = () => {
79436
+ if (closed || !current) return;
79437
+ body.innerHTML = renderWellPumpsBodyHTML(current, {
79438
+ focusWellId: params.focusWellId,
79439
+ footnote: params.footnote,
79440
+ images: params.images
79441
+ });
79442
+ };
79443
+ const update = (data) => {
79444
+ current = data;
79445
+ render3();
79446
+ };
79447
+ const load = async () => {
79448
+ if (typeof params.data !== "function") return;
79449
+ try {
79450
+ update(await params.data());
79451
+ } catch (err) {
79452
+ console.warn("[WellPumpsModal] falha ao carregar dados:", err);
79453
+ if (!current) body.innerHTML = `<div class="myio-wp-empty">N\xE3o foi poss\xEDvel carregar o estado das bombas.</div>`;
79454
+ }
79455
+ };
79456
+ const onKey = (e) => {
79457
+ if (e.key === "Escape") close();
79458
+ };
79459
+ function close() {
79460
+ if (closed) return;
79461
+ closed = true;
79462
+ timers.forEach(clearInterval);
79463
+ document.removeEventListener("keydown", onKey);
79464
+ overlay.remove();
79465
+ try {
79466
+ params.onClose?.();
79467
+ } catch (err) {
79468
+ console.warn("[WellPumpsModal] onClose falhou:", err);
79469
+ }
79470
+ }
79471
+ overlay.addEventListener("click", (e) => {
79472
+ if (e.target === overlay) close();
79473
+ });
79474
+ overlay.querySelector(".myio-wp-close").addEventListener("click", close);
79475
+ document.addEventListener("keydown", onKey);
79476
+ document.body.appendChild(overlay);
79477
+ overlay.querySelector(".myio-wp-close").focus();
79478
+ if (typeof params.data === "function") {
79479
+ load();
79480
+ if (params.refreshIntervalMs && params.refreshIntervalMs > 0) timers.push(setInterval(load, params.refreshIntervalMs));
79481
+ } else {
79482
+ update(params.data);
79483
+ }
79484
+ timers.push(setInterval(render3, TICK_MS));
79485
+ return { update, close, element: overlay };
79486
+ }
79487
+
78916
79488
  // src/utils/telemetryUtils.ts
78917
79489
  function detectTelemetryType(keys) {
78918
79490
  if (!keys) {
@@ -80570,7 +81142,7 @@ async function openDemandModal(params) {
80570
81142
 
80571
81143
  // src/components/premium-modals/dialog/styles.ts
80572
81144
  var FONT_LINK_ID = "myio-dialog-font-nunito";
80573
- var STYLE_ID6 = "myio-dialog-styles";
81145
+ var STYLE_ID8 = "myio-dialog-styles";
80574
81146
  function injectDialogStyles() {
80575
81147
  if (!document.getElementById(FONT_LINK_ID)) {
80576
81148
  const link = document.createElement("link");
@@ -80579,9 +81151,9 @@ function injectDialogStyles() {
80579
81151
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
80580
81152
  document.head.appendChild(link);
80581
81153
  }
80582
- if (document.getElementById(STYLE_ID6)) return;
81154
+ if (document.getElementById(STYLE_ID8)) return;
80583
81155
  const style = document.createElement("style");
80584
- style.id = STYLE_ID6;
81156
+ style.id = STYLE_ID8;
80585
81157
  style.textContent = `
80586
81158
  .myio-dialog-overlay {
80587
81159
  position: fixed;
@@ -80720,11 +81292,11 @@ function injectDialogStyles() {
80720
81292
  // src/components/premium-modals/dialog/openDialog.ts
80721
81293
  var BASE_Z_INDEX = 10500;
80722
81294
  var openCount = 0;
80723
- function escapeHtml7(value) {
81295
+ function escapeHtml8(value) {
80724
81296
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
80725
81297
  }
80726
81298
  function escapeMessage(value) {
80727
- return escapeHtml7(value).replace(/\n/g, "<br>");
81299
+ return escapeHtml8(value).replace(/\n/g, "<br>");
80728
81300
  }
80729
81301
  function cssWidth(width) {
80730
81302
  if (width == null) return "420px";
@@ -80749,7 +81321,7 @@ function openDialog(params) {
80749
81321
  overlay.style.zIndex = String(BASE_Z_INDEX + openCount);
80750
81322
  const buttonsHtml = params.buttons.map((btn, i) => {
80751
81323
  const variant = btn.variant ?? "secondary";
80752
- return `<button type="button" class="myio-dialog__btn myio-dialog__btn--${variant}" data-index="${i}">${escapeHtml7(btn.label)}</button>`;
81324
+ return `<button type="button" class="myio-dialog__btn myio-dialog__btn--${variant}" data-index="${i}">${escapeHtml8(btn.label)}</button>`;
80753
81325
  }).join("");
80754
81326
  overlay.innerHTML = `
80755
81327
  <div class="myio-dialog${params.modifier ? ` ${params.modifier}` : ""}"
@@ -80759,7 +81331,7 @@ function openDialog(params) {
80759
81331
  <div class="myio-dialog__accent"></div>
80760
81332
  <div class="myio-dialog__header">
80761
81333
  ${params.icon ? `<span class="myio-dialog__icon" aria-hidden="true">${params.icon}</span>` : ""}
80762
- <h3 class="myio-dialog__title" id="${idBase}-title">${escapeHtml7(params.title)}</h3>
81334
+ <h3 class="myio-dialog__title" id="${idBase}-title">${escapeHtml8(params.title)}</h3>
80763
81335
  ${dismissible ? `<button type="button" class="myio-dialog__close" aria-label="Fechar">\u2715</button>` : ""}
80764
81336
  </div>
80765
81337
  <p class="myio-dialog__message" id="${idBase}-message">${escapeMessage(params.message)}</p>
@@ -80851,11 +81423,11 @@ function openMessageDialog(params) {
80851
81423
  }
80852
81424
 
80853
81425
  // src/components/premium-modals/dialog/openGenericModal.ts
80854
- var STYLE_ID7 = "myio-genmodal-styles";
81426
+ var STYLE_ID9 = "myio-genmodal-styles";
80855
81427
  var FONT_LINK_ID2 = "myio-dialog-font-nunito";
80856
81428
  var BASE_Z_INDEX2 = 10600;
80857
81429
  var openCount2 = 0;
80858
- function escapeHtml8(value) {
81430
+ function escapeHtml9(value) {
80859
81431
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
80860
81432
  }
80861
81433
  function cssSize(v, fallback) {
@@ -80870,9 +81442,9 @@ function injectGenericModalStyles() {
80870
81442
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
80871
81443
  document.head.appendChild(link);
80872
81444
  }
80873
- if (document.getElementById(STYLE_ID7)) return;
81445
+ if (document.getElementById(STYLE_ID9)) return;
80874
81446
  const style = document.createElement("style");
80875
- style.id = STYLE_ID7;
81447
+ style.id = STYLE_ID9;
80876
81448
  style.textContent = `
80877
81449
  .myio-genmodal-overlay {
80878
81450
  position: fixed;
@@ -81005,17 +81577,17 @@ function openGenericModal(params) {
81005
81577
  overlay.style.zIndex = String(BASE_Z_INDEX2 + openCount2);
81006
81578
  const buttonsHtml = buttons.map((btn, i) => {
81007
81579
  const variant = btn.variant ?? "secondary";
81008
- return `<button type="button" class="myio-genmodal__btn myio-genmodal__btn--${variant}" data-index="${i}">${escapeHtml8(btn.label)}</button>`;
81580
+ return `<button type="button" class="myio-genmodal__btn myio-genmodal__btn--${variant}" data-index="${i}">${escapeHtml9(btn.label)}</button>`;
81009
81581
  }).join("");
81010
81582
  overlay.innerHTML = `
81011
- <div class="myio-genmodal${params.className ? ` ${escapeHtml8(params.className)}` : ""}"
81583
+ <div class="myio-genmodal${params.className ? ` ${escapeHtml9(params.className)}` : ""}"
81012
81584
  role="dialog" aria-modal="true"
81013
81585
  aria-labelledby="${idBase}-title"
81014
81586
  style="width:${cssSize(params.width, "560px")}">
81015
81587
  <div class="myio-genmodal__accent"></div>
81016
81588
  <div class="myio-genmodal__header">
81017
81589
  ${params.icon ? `<span class="myio-genmodal__icon" aria-hidden="true">${params.icon}</span>` : ""}
81018
- <h3 class="myio-genmodal__title" id="${idBase}-title">${escapeHtml8(params.title)}</h3>
81590
+ <h3 class="myio-genmodal__title" id="${idBase}-title">${escapeHtml9(params.title)}</h3>
81019
81591
  ${dismissible ? `<button type="button" class="myio-genmodal__close" aria-label="Fechar">\u2715</button>` : ""}
81020
81592
  </div>
81021
81593
  <div class="myio-genmodal__body" id="${idBase}-body" style="max-height:${cssSize(params.bodyMaxHeight, "70vh")}"></div>
@@ -81253,7 +81825,7 @@ function telemetriesInCatalogOrder(keys) {
81253
81825
 
81254
81826
  // src/utils/reports/demand/period.ts
81255
81827
  var SP_OFFSET_MS2 = -3 * 36e5;
81256
- var DAY_MS = 864e5;
81828
+ var DAY_MS2 = 864e5;
81257
81829
  var END_TOLERANCE_MS = 5 * 6e4;
81258
81830
  var MIN_PERIOD_START = "2019-03-01";
81259
81831
  var MIN_PERIOD_START_MS = Date.UTC(2019, 2, 1) - SP_OFFSET_MS2;
@@ -81305,7 +81877,7 @@ function localMidnightOf(ms) {
81305
81877
  }
81306
81878
  function bucketCount(start, end, resolution) {
81307
81879
  if (!(end > start)) return 0;
81308
- if (resolution === "1d") return Math.ceil((localMidnightOf(end - 1) - localMidnightOf(start)) / DAY_MS) + 1;
81880
+ if (resolution === "1d") return Math.ceil((localMidnightOf(end - 1) - localMidnightOf(start)) / DAY_MS2) + 1;
81309
81881
  return Math.ceil((end - start) / RESOLUTION_BY_ID[resolution].ms);
81310
81882
  }
81311
81883
  function finestFittingResolution(range, limits) {
@@ -81313,7 +81885,7 @@ function finestFittingResolution(range, limits) {
81313
81885
  const len = range.end - range.start;
81314
81886
  return RESOLUTIONS.find((r) => {
81315
81887
  const d = limits.maxDaysByResolution[r.id];
81316
- return d != null && len <= d * DAY_MS;
81888
+ return d != null && len <= d * DAY_MS2;
81317
81889
  })?.id ?? null;
81318
81890
  }
81319
81891
  function maxPeriodDays(resolution, limits) {
@@ -81327,7 +81899,7 @@ function periodErrors(range, resolution, now, limits = null) {
81327
81899
  if (range.start > now) errs.push("O in\xEDcio est\xE1 no futuro.");
81328
81900
  if (range.end > now + END_TOLERANCE_MS) errs.push("O fim n\xE3o pode estar no futuro.");
81329
81901
  const maxDays = maxPeriodDays(resolution, limits);
81330
- if (maxDays != null && range.end - range.start > maxDays * DAY_MS) {
81902
+ if (maxDays != null && range.end - range.start > maxDays * DAY_MS2) {
81331
81903
  errs.push(`Com intervalos de ${RESOLUTION_BY_ID[resolution].label}, o per\xEDodo m\xE1ximo \xE9 ${maxDays} dia(s).`);
81332
81904
  }
81333
81905
  if (resolution === "1d" && !isLocalMidnight(range.start)) {
@@ -92050,13 +92622,13 @@ var COLUMN_SUMMARY_CSS = `
92050
92622
  var _cssInjected2 = false;
92051
92623
  function injectCSS10() {
92052
92624
  if (_cssInjected2 || typeof document === "undefined") return;
92053
- const STYLE_ID18 = "myio-column-summary-tooltip-css";
92054
- if (document.getElementById(STYLE_ID18)) {
92625
+ const STYLE_ID20 = "myio-column-summary-tooltip-css";
92626
+ if (document.getElementById(STYLE_ID20)) {
92055
92627
  _cssInjected2 = true;
92056
92628
  return;
92057
92629
  }
92058
92630
  const style = document.createElement("style");
92059
- style.id = STYLE_ID18;
92631
+ style.id = STYLE_ID20;
92060
92632
  style.textContent = COLUMN_SUMMARY_CSS;
92061
92633
  document.head.appendChild(style);
92062
92634
  _cssInjected2 = true;
@@ -99867,12 +100439,12 @@ function createConsumptionChartWidget(config2) {
99867
100439
  }
99868
100440
 
99869
100441
  // src/components/tooltips/goals-bar-tooltip/createGoalsBarTooltip.ts
99870
- var STYLE_ID8 = "myio-goals-bar-tooltip-styles";
100442
+ var STYLE_ID10 = "myio-goals-bar-tooltip-styles";
99871
100443
  var DEFAULT_ACCENT = "#6c5ce7";
99872
100444
  function injectStyles12(doc) {
99873
- if (doc.getElementById(STYLE_ID8)) return;
100445
+ if (doc.getElementById(STYLE_ID10)) return;
99874
100446
  const s = doc.createElement("style");
99875
- s.id = STYLE_ID8;
100447
+ s.id = STYLE_ID10;
99876
100448
  s.textContent = `
99877
100449
  .myio-gbt {
99878
100450
  position: fixed;
@@ -100981,11 +101553,11 @@ function _rerenderFromCache() {
100981
101553
  const { labels, totals, goalLine, prevTotals, domain } = _lastRender;
100982
101554
  _renderChart(canvas, labels, totals, goalLine, domain, prevTotals);
100983
101555
  }
100984
- var STYLE_ID9 = "myio-goals-modal-v2-styles";
101556
+ var STYLE_ID11 = "myio-goals-modal-v2-styles";
100985
101557
  function _injectStyles(topDoc) {
100986
- if (topDoc.getElementById(STYLE_ID9)) return;
101558
+ if (topDoc.getElementById(STYLE_ID11)) return;
100987
101559
  const s = topDoc.createElement("style");
100988
- s.id = STYLE_ID9;
101560
+ s.id = STYLE_ID11;
100989
101561
  s.textContent = `
100990
101562
  .gm-overlay{position:fixed;inset:0;z-index:1000000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.5);backdrop-filter:blur(4px);opacity:0;transition:opacity .2s ease;font-family:'Nunito', system-ui, sans-serif;}
100991
101563
  .gm-overlay.show{opacity:1;}
@@ -103836,7 +104408,7 @@ function createMyIOTheme(settings, mode) {
103836
104408
  // src/components/settings-hub/openSettingsHubModal.ts
103837
104409
  var ROUTE_DELAY_MS = 250;
103838
104410
  var MODAL_ID2 = "myio-conf-picker";
103839
- var STYLE_ID10 = "myio-conf-picker-styles";
104411
+ var STYLE_ID12 = "myio-conf-picker-styles";
103840
104412
  var HUB_OPTIONS = [
103841
104413
  {
103842
104414
  action: "temperature",
@@ -104027,7 +104599,7 @@ var HUB_CSS = `
104027
104599
  color: var(--myio-brand-700, #7B2FF7);
104028
104600
  }
104029
104601
  `;
104030
- function escapeHtml9(value) {
104602
+ function escapeHtml10(value) {
104031
104603
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
104032
104604
  }
104033
104605
  function resolveTopDocument() {
@@ -104047,9 +104619,9 @@ function resolveHubThemeVars(explicit) {
104047
104619
  function openSettingsHubModal(options) {
104048
104620
  const { customerName = "", isSuperAdmin: isSuperAdmin2 = false, handlers } = options;
104049
104621
  const doc = options.targetDocument || resolveTopDocument();
104050
- if (!doc.getElementById(STYLE_ID10)) {
104622
+ if (!doc.getElementById(STYLE_ID12)) {
104051
104623
  const style = doc.createElement("style");
104052
- style.id = STYLE_ID10;
104624
+ style.id = STYLE_ID12;
104053
104625
  style.textContent = HUB_CSS;
104054
104626
  doc.head.appendChild(style);
104055
104627
  }
@@ -104074,7 +104646,7 @@ function openSettingsHubModal(options) {
104074
104646
  <div class="myio-conf-picker__overlay"></div>
104075
104647
  <div class="myio-conf-picker__content">
104076
104648
  <div class="myio-conf-picker__header">
104077
- <h3>\u2699\uFE0F Configura\xE7\xF5es${customerName ? ` \u2014 ${escapeHtml9(customerName)}` : ""}</h3>
104649
+ <h3>\u2699\uFE0F Configura\xE7\xF5es${customerName ? ` \u2014 ${escapeHtml10(customerName)}` : ""}</h3>
104078
104650
  <button class="myio-conf-picker__close" aria-label="Fechar">&times;</button>
104079
104651
  </div>
104080
104652
  <div class="myio-conf-picker__body">${cardsHtml}
@@ -105269,7 +105841,7 @@ function createTariffApiAdapter(client, opts) {
105269
105841
 
105270
105842
  // src/components/pricing-panel/openPricingPanel.ts
105271
105843
  var MODAL_ID3 = "myio-pricing-panel";
105272
- function escapeHtml10(value) {
105844
+ function escapeHtml11(value) {
105273
105845
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
105274
105846
  }
105275
105847
  function resolveTopDocument2() {
@@ -105424,7 +105996,7 @@ function openPricingPanel(params) {
105424
105996
  }
105425
105997
  const initDomain = params.domain || "energy";
105426
105998
  const initCategory = params.category || "lojas";
105427
- const customerOptions = customers.map((c) => `<option value="${escapeHtml10(resolveCustomerId(c))}">${escapeHtml10(c.title)}</option>`).join("");
105999
+ const customerOptions = customers.map((c) => `<option value="${escapeHtml11(resolveCustomerId(c))}">${escapeHtml11(c.title)}</option>`).join("");
105428
106000
  modal.innerHTML = `
105429
106001
  <div class="myio-pricing__overlay"></div>
105430
106002
  <div class="myio-pricing__content">
@@ -105639,9 +106211,9 @@ function openPricingPanel(params) {
105639
106211
  const pushAudit = (rec) => {
105640
106212
  if (rec) auditLog = [rec, ...auditLog];
105641
106213
  };
105642
- const badge = (domain, category) => `<span class="myio-pricing__badge${domain === "water" ? " myio-pricing__badge--water" : ""}">${escapeHtml10(
106214
+ const badge = (domain, category) => `<span class="myio-pricing__badge${domain === "water" ? " myio-pricing__badge--water" : ""}">${escapeHtml11(
105643
106215
  DOMAIN_LABEL[domain]
105644
- )} \xB7 ${escapeHtml10(CATEGORY_LABEL[category])}</span>`;
106216
+ )} \xB7 ${escapeHtml11(CATEGORY_LABEL[category])}</span>`;
105645
106217
  const renderList2 = () => {
105646
106218
  const customerId = customerSel.value;
105647
106219
  const rows = entries.filter((e) => e.customerId === customerId).sort((a, b) => {
@@ -105654,15 +106226,15 @@ function openPricingPanel(params) {
105654
106226
  const boundsKey = b ? `${b.start}__${b.end}` : "";
105655
106227
  return `
105656
106228
  <li class="myio-pricing__item">
105657
- <span class="myio-pricing__item-period">${badge(e.domain, e.category)} ${escapeHtml10(
106229
+ <span class="myio-pricing__item-period">${badge(e.domain, e.category)} ${escapeHtml11(
105658
106230
  formatPeriodLabel(e)
105659
106231
  )}</span>
105660
- <span class="myio-pricing__item-price">${escapeHtml10(formatBRL2(e.pricePerKwh))} ${escapeHtml10(
106232
+ <span class="myio-pricing__item-price">${escapeHtml11(formatBRL2(e.pricePerKwh))} ${escapeHtml11(
105661
106233
  unitLabel(e.domain)
105662
106234
  )}</span>
105663
- <button class="myio-pricing__remove" data-remove="${escapeHtml10(e.domain)}|${escapeHtml10(
106235
+ <button class="myio-pricing__remove" data-remove="${escapeHtml11(e.domain)}|${escapeHtml11(
105664
106236
  e.category
105665
- )}|${escapeHtml10(boundsKey)}" aria-label="Remover" type="button">\u2715</button>
106237
+ )}|${escapeHtml11(boundsKey)}" aria-label="Remover" type="button">\u2715</button>
105666
106238
  </li>`;
105667
106239
  }).join("");
105668
106240
  emptyEl.style.display = rows.length ? "none" : "";
@@ -105761,8 +106333,8 @@ function openPricingPanel(params) {
105761
106333
  kpiEl.innerHTML = cards.map(
105762
106334
  (c) => `
105763
106335
  <div class="myio-pricing__kpi">
105764
- <div class="myio-pricing__kpi-value">${escapeHtml10(c.value)}</div>
105765
- <div class="myio-pricing__kpi-label">${escapeHtml10(c.label)}</div>
106336
+ <div class="myio-pricing__kpi-value">${escapeHtml11(c.value)}</div>
106337
+ <div class="myio-pricing__kpi-label">${escapeHtml11(c.label)}</div>
105766
106338
  </div>`
105767
106339
  ).join("");
105768
106340
  renderReport();
@@ -105781,11 +106353,11 @@ function openPricingPanel(params) {
105781
106353
  reportBody.innerHTML = rows.length ? rows.map(
105782
106354
  (e) => `
105783
106355
  <tr>
105784
- <td>${escapeHtml10(customerTitle(e.customerId))}</td>
105785
- <td>${escapeHtml10(DOMAIN_LABEL[e.domain])}</td>
105786
- <td>${escapeHtml10(CATEGORY_LABEL[e.category])}</td>
105787
- <td>${escapeHtml10(formatPeriodLabel(e))}</td>
105788
- <td>${escapeHtml10(formatBRL2(e.pricePerKwh))} ${escapeHtml10(unitLabel(e.domain))}</td>
106356
+ <td>${escapeHtml11(customerTitle(e.customerId))}</td>
106357
+ <td>${escapeHtml11(DOMAIN_LABEL[e.domain])}</td>
106358
+ <td>${escapeHtml11(CATEGORY_LABEL[e.category])}</td>
106359
+ <td>${escapeHtml11(formatPeriodLabel(e))}</td>
106360
+ <td>${escapeHtml11(formatBRL2(e.pricePerKwh))} ${escapeHtml11(unitLabel(e.domain))}</td>
105789
106361
  </tr>`
105790
106362
  ).join("") : `<tr><td colspan="5" style="text-align:center;color:var(--myio-text-muted,#6b7280);padding:24px;">Nenhum pre\xE7o para o filtro selecionado.</td></tr>`;
105791
106363
  }
@@ -105795,15 +106367,15 @@ function openPricingPanel(params) {
105795
106367
  return `
105796
106368
  <li class="myio-pricing__history-item">
105797
106369
  <div class="myio-pricing__history-head">
105798
- <span class="myio-pricing__action myio-pricing__action--${escapeHtml10(rec.action)}">${escapeHtml10(
106370
+ <span class="myio-pricing__action myio-pricing__action--${escapeHtml11(rec.action)}">${escapeHtml11(
105799
106371
  rec.action
105800
106372
  )}</span>
105801
106373
  ${badge(rec.domain, rec.category)}
105802
- <span>${escapeHtml10(rec.periodLabel)}${escapeHtml10(priceInfo)}</span>
106374
+ <span>${escapeHtml11(rec.periodLabel)}${escapeHtml11(priceInfo)}</span>
105803
106375
  </div>
105804
- <div class="myio-pricing__history-meta">${escapeHtml10(customerTitle(rec.customerId))} \xB7 ${escapeHtml10(
106376
+ <div class="myio-pricing__history-meta">${escapeHtml11(customerTitle(rec.customerId))} \xB7 ${escapeHtml11(
105805
106377
  rec.by || "\u2014"
105806
- )} \xB7 ${escapeHtml10(fmtTimestamp(rec.at))}</div>
106378
+ )} \xB7 ${escapeHtml11(fmtTimestamp(rec.at))}</div>
105807
106379
  </li>`;
105808
106380
  }).join("");
105809
106381
  historyEmpty.style.display = auditLog.length ? "none" : "";
@@ -109381,11 +109953,11 @@ function renderModal6(container, state6, modalId, t, error) {
109381
109953
  setupEventListeners5(container, state6, modalId, t);
109382
109954
  }
109383
109955
  function renderStepIndicator(step, label, currentStep, colors2) {
109384
- const isActive = step === currentStep;
109956
+ const isActive2 = step === currentStep;
109385
109957
  const isCompleted = step < currentStep;
109386
- const bgColor = isActive ? MYIO_PURPLE : isCompleted ? colors2.success : colors2.cardBg;
109387
- const textColor = isActive || isCompleted ? "white" : colors2.textMuted;
109388
- const borderColor = isActive || isCompleted ? "transparent" : colors2.border;
109958
+ const bgColor = isActive2 ? MYIO_PURPLE : isCompleted ? colors2.success : colors2.cardBg;
109959
+ const textColor = isActive2 || isCompleted ? "white" : colors2.textMuted;
109960
+ const borderColor = isActive2 || isCompleted ? "transparent" : colors2.border;
109389
109961
  return `
109390
109962
  <div style="
109391
109963
  display: flex; align-items: center; gap: 8px;
@@ -109425,10 +109997,10 @@ function renderStep1(state6, modalId, colors2, t) {
109425
109997
  const { field: sortField, order: sortOrder } = state6.customerSort;
109426
109998
  const sortedCustomers = sortCustomers(state6.customers, sortField, sortOrder, state6.customerNameMap);
109427
109999
  const sortIcon = sortOrder === "asc" ? "\u2191" : "\u2193";
109428
- const btnStyle = (isActive) => `
109429
- background: ${isActive ? MYIO_PURPLE : colors2.cardBg};
109430
- color: ${isActive ? "white" : colors2.text};
109431
- border: 1px solid ${isActive ? MYIO_PURPLE : colors2.border};
110000
+ const btnStyle = (isActive2) => `
110001
+ background: ${isActive2 ? MYIO_PURPLE : colors2.cardBg};
110002
+ color: ${isActive2 ? "white" : colors2.text};
110003
+ border: 1px solid ${isActive2 ? MYIO_PURPLE : colors2.border};
109432
110004
  padding: 6px 12px; border-radius: 6px; cursor: pointer;
109433
110005
  font-size: 12px; font-weight: 500; display: flex; align-items: center; gap: 4px;
109434
110006
  `;
@@ -109653,16 +110225,16 @@ function renderStep2(state6, modalId, colors2, t) {
109653
110225
  const gridHeight = state6.isMaximized ? "calc(100vh - 340px)" : "360px";
109654
110226
  const hasActiveFilters = filterTypes.length > 0 || filterDeviceTypes.length > 0 || filterDeviceProfiles.length > 0 || filterStatuses.length > 0 || filterTelemetryKeys.length > 0;
109655
110227
  const renderSortableHeader = (col2, label, field, width) => {
109656
- const isActive = sortField === field;
109657
- const arrow = isActive ? sortOrder === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
110228
+ const isActive2 = sortField === field;
110229
+ const arrow = isActive2 ? sortOrder === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
109658
110230
  return `
109659
110231
  <div id="${modalId}-sort-col-${col2}" data-sort-field="${field}" style="
109660
110232
  width: ${width}px; padding: 0 6px; display: flex; align-items: center; justify-content: space-between;
109661
110233
  border-right: 1px solid ${colors2.border}; cursor: pointer; user-select: none;
109662
- ${isActive ? `background: rgba(62,26,125,0.1);` : ""}
110234
+ ${isActive2 ? `background: rgba(62,26,125,0.1);` : ""}
109663
110235
  ">
109664
110236
  <span>${label}</span>
109665
- <span style="font-size: 8px; color: ${isActive ? MYIO_PURPLE : colors2.textMuted};">${arrow}</span>
110237
+ <span style="font-size: 8px; color: ${isActive2 ? MYIO_PURPLE : colors2.textMuted};">${arrow}</span>
109666
110238
  </div>
109667
110239
  `;
109668
110240
  };
@@ -109945,10 +110517,10 @@ function renderStep2(state6, modalId, colors2, t) {
109945
110517
  });
109946
110518
  const colSpan = multiCol ? 16 : 15;
109947
110519
  const cfSortHeader = (field, label, rowspan = 1, extraStyle = "") => {
109948
- const isActive = state6.checkFixSort.field === field;
109949
- const arrow = isActive ? state6.checkFixSort.order === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
109950
- return `<th ${rowspan > 1 ? `rowspan="${rowspan}"` : ""} id="${modalId}-cf-sort-${field}" data-cf-sort="${field}" style="${thStyle(extraStyle)} cursor:pointer; user-select:none; ${isActive ? `background:rgba(62,26,125,0.18);` : ""}">
109951
- <span style="display:flex;align-items:center;gap:3px;white-space:nowrap;">${label}<span style="font-size:7px;color:${isActive ? MYIO_PURPLE : colors2.textMuted};">${arrow}</span></span>
110520
+ const isActive2 = state6.checkFixSort.field === field;
110521
+ const arrow = isActive2 ? state6.checkFixSort.order === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
110522
+ return `<th ${rowspan > 1 ? `rowspan="${rowspan}"` : ""} id="${modalId}-cf-sort-${field}" data-cf-sort="${field}" style="${thStyle(extraStyle)} cursor:pointer; user-select:none; ${isActive2 ? `background:rgba(62,26,125,0.18);` : ""}">
110523
+ <span style="display:flex;align-items:center;gap:3px;white-space:nowrap;">${label}<span style="font-size:7px;color:${isActive2 ? MYIO_PURPLE : colors2.textMuted};">${arrow}</span></span>
109952
110524
  </th>`;
109953
110525
  };
109954
110526
  const allDomains = [...new Set(state6.checkFixReport.records.map((r) => r.domain || "null"))].sort();
@@ -116222,9 +116794,9 @@ function openMyioGcdrLoginModal(options) {
116222
116794
  }
116223
116795
 
116224
116796
  // src/components/img-gallery/ScrollableTabs.ts
116225
- var STYLE_ID11 = "myio-tabs-styles";
116797
+ var STYLE_ID13 = "myio-tabs-styles";
116226
116798
  var FONT_LINK_ID3 = "myio-dialog-font-nunito";
116227
- function escapeHtml11(value) {
116799
+ function escapeHtml12(value) {
116228
116800
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
116229
116801
  }
116230
116802
  function injectStyles13() {
@@ -116235,9 +116807,9 @@ function injectStyles13() {
116235
116807
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
116236
116808
  document.head.appendChild(link);
116237
116809
  }
116238
- if (document.getElementById(STYLE_ID11)) return;
116810
+ if (document.getElementById(STYLE_ID13)) return;
116239
116811
  const style = document.createElement("style");
116240
- style.id = STYLE_ID11;
116812
+ style.id = STYLE_ID13;
116241
116813
  style.textContent = `
116242
116814
  .myio-tabs {
116243
116815
  display: flex;
@@ -116338,10 +116910,10 @@ function createScrollableTabs(options) {
116338
116910
  root.appendChild(left);
116339
116911
  root.appendChild(scroll);
116340
116912
  root.appendChild(right);
116341
- function styleTab(btn, isActive) {
116342
- btn.classList.toggle("myio-tabs__tab--active", isActive);
116343
- btn.setAttribute("aria-selected", isActive ? "true" : "false");
116344
- if (isActive) {
116913
+ function styleTab(btn, isActive2) {
116914
+ btn.classList.toggle("myio-tabs__tab--active", isActive2);
116915
+ btn.setAttribute("aria-selected", isActive2 ? "true" : "false");
116916
+ if (isActive2) {
116345
116917
  btn.style.background = accent;
116346
116918
  btn.style.color = "#fff";
116347
116919
  btn.style.borderColor = accent;
@@ -116360,7 +116932,7 @@ function createScrollableTabs(options) {
116360
116932
  btn.setAttribute("role", "tab");
116361
116933
  btn.dataset.key = t.key;
116362
116934
  if (t.disabled) btn.disabled = true;
116363
- btn.innerHTML = `${t.icon ? `<span aria-hidden="true">${t.icon}</span>` : ""}<span>${escapeHtml11(t.label)}</span>`;
116935
+ btn.innerHTML = `${t.icon ? `<span aria-hidden="true">${t.icon}</span>` : ""}<span>${escapeHtml12(t.label)}</span>`;
116364
116936
  styleTab(btn, t.key === active);
116365
116937
  btn.addEventListener("click", () => {
116366
116938
  if (t.disabled || t.key === active) return;
@@ -116445,9 +117017,9 @@ function createScrollableTabs(options) {
116445
117017
  }
116446
117018
 
116447
117019
  // src/components/img-gallery/ImgGallery.ts
116448
- var STYLE_ID12 = "myio-gallery-styles";
117020
+ var STYLE_ID14 = "myio-gallery-styles";
116449
117021
  var FONT_LINK_ID4 = "myio-dialog-font-nunito";
116450
- function escapeHtml12(value) {
117022
+ function escapeHtml13(value) {
116451
117023
  return String(value == null ? "" : value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
116452
117024
  }
116453
117025
  var PRM = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
@@ -116459,9 +117031,9 @@ function injectStyles14() {
116459
117031
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
116460
117032
  document.head.appendChild(link);
116461
117033
  }
116462
- if (document.getElementById(STYLE_ID12)) return;
117034
+ if (document.getElementById(STYLE_ID14)) return;
116463
117035
  const style = document.createElement("style");
116464
- style.id = STYLE_ID12;
117036
+ style.id = STYLE_ID14;
116465
117037
  style.textContent = `
116466
117038
  .myio-gallery {
116467
117039
  font-family: 'Nunito', system-ui, sans-serif;
@@ -116671,10 +117243,10 @@ function createImgGallery(options) {
116671
117243
  root.appendChild(grid);
116672
117244
  function detailsHtml(img) {
116673
117245
  const lines = [];
116674
- if (img.filename) lines.push(`<span title="${escapeHtml12(img.filename)}">${escapeHtml12(img.filename)}</span>`);
116675
- if (typeof img.sizeBytes === "number") lines.push(`<span>${escapeHtml12(formatSize(img.sizeBytes))}</span>`);
117246
+ if (img.filename) lines.push(`<span title="${escapeHtml13(img.filename)}">${escapeHtml13(img.filename)}</span>`);
117247
+ if (typeof img.sizeBytes === "number") lines.push(`<span>${escapeHtml13(formatSize(img.sizeBytes))}</span>`);
116676
117248
  const dims = typeof img.width === "number" && typeof img.height === "number" ? `${img.width} \xD7 ${img.height}px` : "";
116677
- lines.push(`<span data-dims>${escapeHtml12(dims)}</span>`);
117249
+ lines.push(`<span data-dims>${escapeHtml13(dims)}</span>`);
116678
117250
  return lines.join("");
116679
117251
  }
116680
117252
  function renderDescription(body, img, index) {
@@ -123888,10 +124460,10 @@ var MenuView = class {
123888
124460
  </div>
123889
124461
  <div class="myio-unified-column-options">
123890
124462
  ${tab.contexts.map((ctx) => {
123891
- const isActive = isActiveTab && ctx.id === currentContextId;
124463
+ const isActive2 = isActiveTab && ctx.id === currentContextId;
123892
124464
  return `
123893
124465
  <button
123894
- class="myio-unified-option ${tab.id} ${isActive ? "is-active" : ""}"
124466
+ class="myio-unified-option ${tab.id} ${isActive2 ? "is-active" : ""}"
123895
124467
  data-tab-id="${tab.id}"
123896
124468
  data-context-id="${ctx.id}"
123897
124469
  data-target="${ctx.target}"
@@ -123914,20 +124486,20 @@ var MenuView = class {
123914
124486
  * Only active tab shows context detail, others show only domain label
123915
124487
  */
123916
124488
  buildTabHTML(tab) {
123917
- const isActive = tab.id === this.activeTabId;
123918
- const label = this.getTabLabel(tab.id, isActive);
124489
+ const isActive2 = tab.id === this.activeTabId;
124490
+ const label = this.getTabLabel(tab.id, isActive2);
123919
124491
  return `
123920
124492
  <button
123921
124493
  id="menuTab_${tab.id}"
123922
- class="tab ${isActive ? "is-active" : ""}"
124494
+ class="tab ${isActive2 ? "is-active" : ""}"
123923
124495
  data-tab-id="${tab.id}"
123924
124496
  role="tab"
123925
- aria-selected="${isActive}"
124497
+ aria-selected="${isActive2}"
123926
124498
  aria-controls="menuContextModal_${tab.id}"
123927
124499
  >
123928
124500
  <span class="ico">${tab.icon}</span>
123929
124501
  <span class="tab-label">${label}</span>
123930
- ${isActive ? '<span class="dropdown-arrow">\u25BC</span>' : ""}
124502
+ ${isActive2 ? '<span class="dropdown-arrow">\u25BC</span>' : ""}
123931
124503
  </button>
123932
124504
  `;
123933
124505
  }
@@ -123936,10 +124508,10 @@ var MenuView = class {
123936
124508
  * Active tab: "Domain: Context" (e.g., "Energia: Equipamentos")
123937
124509
  * Inactive tab: "Domain" only (e.g., "Agua")
123938
124510
  */
123939
- getTabLabel(tabId, isActive) {
124511
+ getTabLabel(tabId, isActive2) {
123940
124512
  const tab = this.tabs.find((t) => t.id === tabId);
123941
124513
  if (!tab) return "";
123942
- if (isActive) {
124514
+ if (isActive2) {
123943
124515
  const currentContextId = this.contextsByTab.get(tabId) ?? tab.defaultContext ?? tab.contexts[0]?.id;
123944
124516
  const currentContext = tab.contexts.find((c) => c.id === currentContextId);
123945
124517
  return currentContext ? `${tab.label}: ${currentContext.title}` : tab.label;
@@ -123951,20 +124523,20 @@ var MenuView = class {
123951
124523
  */
123952
124524
  updateAllTabLabels() {
123953
124525
  this.tabs.forEach((tab) => {
123954
- const isActive = tab.id === this.activeTabId;
124526
+ const isActive2 = tab.id === this.activeTabId;
123955
124527
  const tabEl = this.root.querySelector(`#menuTab_${tab.id}`);
123956
124528
  if (!tabEl) return;
123957
124529
  const labelEl = tabEl.querySelector(".tab-label");
123958
124530
  if (labelEl) {
123959
- labelEl.textContent = this.getTabLabel(tab.id, isActive);
124531
+ labelEl.textContent = this.getTabLabel(tab.id, isActive2);
123960
124532
  }
123961
124533
  const arrowEl = tabEl.querySelector(".dropdown-arrow");
123962
- if (isActive && !arrowEl) {
124534
+ if (isActive2 && !arrowEl) {
123963
124535
  const arrow = document.createElement("span");
123964
124536
  arrow.className = "dropdown-arrow";
123965
124537
  arrow.textContent = "\u25BC";
123966
124538
  tabEl.appendChild(arrow);
123967
- } else if (!isActive && arrowEl) {
124539
+ } else if (!isActive2 && arrowEl) {
123968
124540
  arrowEl.remove();
123969
124541
  }
123970
124542
  });
@@ -123998,10 +124570,10 @@ var MenuView = class {
123998
124570
  /**
123999
124571
  * Build a single context option HTML
124000
124572
  */
124001
- buildContextOptionHTML(tab, ctx, isActive) {
124573
+ buildContextOptionHTML(tab, ctx, isActive2) {
124002
124574
  return `
124003
124575
  <button
124004
- class="myio-menu-context-option ${tab.id} ${isActive ? "is-active" : ""}"
124576
+ class="myio-menu-context-option ${tab.id} ${isActive2 ? "is-active" : ""}"
124005
124577
  data-tab-id="${tab.id}"
124006
124578
  data-context-id="${ctx.id}"
124007
124579
  data-target="${ctx.target}"
@@ -124060,13 +124632,13 @@ var MenuView = class {
124060
124632
  * Build Mobile Tab HTML (for mobile drawer)
124061
124633
  */
124062
124634
  buildMobileTabHTML(tab) {
124063
- const isActive = tab.id === this.activeTabId;
124635
+ const isActive2 = tab.id === this.activeTabId;
124064
124636
  const currentContextId = this.contextsByTab.get(tab.id) ?? tab.defaultContext ?? tab.contexts[0]?.id;
124065
124637
  const currentContext = tab.contexts.find((c) => c.id === currentContextId);
124066
124638
  const contextTitle = currentContext ? currentContext.title : "";
124067
124639
  return `
124068
124640
  <button
124069
- class="tab ${isActive ? "is-active" : ""}"
124641
+ class="tab ${isActive2 ? "is-active" : ""}"
124070
124642
  data-tab-id="${tab.id}"
124071
124643
  data-mobile-tab="true"
124072
124644
  >
@@ -124671,8 +125243,8 @@ var MenuView = class {
124671
125243
  const contextId = el2.dataset.contextId;
124672
125244
  const currentContextId = this.contextsByTab.get(tabId);
124673
125245
  const isActiveTab = tabId === this.activeTabId;
124674
- const isActive = isActiveTab && contextId === currentContextId;
124675
- el2.classList.toggle("is-active", isActive);
125246
+ const isActive2 = isActiveTab && contextId === currentContextId;
125247
+ el2.classList.toggle("is-active", isActive2);
124676
125248
  });
124677
125249
  this.root.querySelectorAll(".myio-unified-column").forEach((col2) => {
124678
125250
  const tabId = col2.classList.contains("energy") ? "energy" : col2.classList.contains("water") ? "water" : col2.classList.contains("temperature") ? "temperature" : "";
@@ -131180,7 +131752,7 @@ function createCustomerCardV1(params) {
131180
131752
  }
131181
131753
 
131182
131754
  // src/components/cards/customer-goals/v1.0.0/styles.ts
131183
- var STYLE_ID13 = "myio-customer-goals-card-css";
131755
+ var STYLE_ID15 = "myio-customer-goals-card-css";
131184
131756
  var CSS4 = `
131185
131757
  .myio-cgc{
131186
131758
  --cgc-surface:#ffffff;
@@ -131281,9 +131853,9 @@ var CSS4 = `
131281
131853
  `;
131282
131854
  function injectCustomerGoalsCardStyles() {
131283
131855
  if (typeof document === "undefined") return;
131284
- if (document.getElementById(STYLE_ID13)) return;
131856
+ if (document.getElementById(STYLE_ID15)) return;
131285
131857
  const tag = document.createElement("style");
131286
- tag.id = STYLE_ID13;
131858
+ tag.id = STYLE_ID15;
131287
131859
  tag.textContent = CSS4;
131288
131860
  document.head.appendChild(tag);
131289
131861
  }
@@ -134133,7 +134705,7 @@ var WATER_FIXTURES = {
134133
134705
  var DEFAULT_FIXTURES = ENERGY_FIXTURES;
134134
134706
 
134135
134707
  // src/components/metas-guide/openMetasGuide.ts
134136
- var STYLE_ID14 = "myio-metas-guide-styles";
134708
+ var STYLE_ID16 = "myio-metas-guide-styles";
134137
134709
  var ROOT_ID = "myio-metas-guide-root";
134138
134710
  var FALLBACK_THEME = {
134139
134711
  accent: "#6c5ce7",
@@ -134141,7 +134713,7 @@ var FALLBACK_THEME = {
134141
134713
  accentText: "#ffffff",
134142
134714
  mode: "light"
134143
134715
  };
134144
- function escapeHtml13(value) {
134716
+ function escapeHtml14(value) {
134145
134717
  return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
134146
134718
  }
134147
134719
  var nfInt = new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 0 });
@@ -134169,7 +134741,7 @@ function legendHtml() {
134169
134741
  [SERIES_COLORS.orcado, "Or\xE7ado"]
134170
134742
  ];
134171
134743
  return `<div class="myio-mg-legend">${items.map(
134172
- ([c, l]) => `<span class="myio-mg-legend__item"><span class="myio-mg-legend__dot" style="background:${c}" aria-hidden="true"></span>${escapeHtml13(
134744
+ ([c, l]) => `<span class="myio-mg-legend__item"><span class="myio-mg-legend__dot" style="background:${c}" aria-hidden="true"></span>${escapeHtml14(
134173
134745
  l
134174
134746
  )}</span>`
134175
134747
  ).join("")}</div>`;
@@ -134209,7 +134781,7 @@ function miniChartSvg(s) {
134209
134781
  const pts = data.map((v, i) => `${(i * bandW + bandW / 2).toFixed(1)},${y(v).toFixed(1)}`).join(" ");
134210
134782
  return `<polyline points="${pts}" fill="none" stroke="${color}" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"></polyline>`;
134211
134783
  };
134212
- return `<svg class="myio-mg-chart" viewBox="0 0 ${W} ${H}" role="img" aria-label="Gr\xE1fico ilustrativo de ${escapeHtml13(
134784
+ return `<svg class="myio-mg-chart" viewBox="0 0 ${W} ${H}" role="img" aria-label="Gr\xE1fico ilustrativo de ${escapeHtml14(
134213
134785
  s.name
134214
134786
  )}" preserveAspectRatio="none">
134215
134787
  ${bars}
@@ -134226,8 +134798,8 @@ function kpiRowHtml(s, unit) {
134226
134798
  ];
134227
134799
  return `<div class="myio-mg-kpis">${kpis.map(
134228
134800
  ([label, val, color]) => `<div class="myio-mg-kpi">
134229
- <span class="myio-mg-kpi__label" style="color:${color}">${escapeHtml13(label)}</span>
134230
- <span class="myio-mg-kpi__value">${fmtInt(val)} <small>${escapeHtml13(unit)}</small></span>
134801
+ <span class="myio-mg-kpi__label" style="color:${color}">${escapeHtml14(label)}</span>
134802
+ <span class="myio-mg-kpi__value">${fmtInt(val)} <small>${escapeHtml14(unit)}</small></span>
134231
134803
  </div>`
134232
134804
  ).join("")}</div>`;
134233
134805
  }
@@ -134235,7 +134807,7 @@ function chipsHtml(s) {
134235
134807
  const c = computeChips(s);
134236
134808
  const chip = (label, ratio) => {
134237
134809
  const cls = ratio > 0 ? "is-up" : ratio < 0 ? "is-down" : "is-flat";
134238
- return `<span class="myio-mg-chip ${cls}">${escapeHtml13(label)} <strong>${escapeHtml13(
134810
+ return `<span class="myio-mg-chip ${cls}">${escapeHtml14(label)} <strong>${escapeHtml14(
134239
134811
  fmtPct4(ratio)
134240
134812
  )}</strong></span>`;
134241
134813
  };
@@ -134250,7 +134822,7 @@ function miniCardHtml(s, unit, opts) {
134250
134822
  const showKpis = opts?.kpis !== false;
134251
134823
  const showChips = opts?.chips !== false;
134252
134824
  return `<div class="myio-mg-card">
134253
- <h5 class="myio-mg-card__title">${escapeHtml13(s.name)}</h5>
134825
+ <h5 class="myio-mg-card__title">${escapeHtml14(s.name)}</h5>
134254
134826
  ${showChart ? legendHtml() + miniChartSvg(s) : ""}
134255
134827
  ${showKpis ? kpiRowHtml(s, unit) : ""}
134256
134828
  ${showChips ? chipsHtml(s) : ""}
@@ -134260,7 +134832,7 @@ function miniSidebarHtml(shoppings, unit, prevY, curY) {
134260
134832
  const total = deriveTotal({ shoppings });
134261
134833
  const row = (name, a, r, o, m, isTotal) => `
134262
134834
  <div class="myio-mg-side__row${isTotal ? " is-total" : ""}">
134263
- <span class="myio-mg-side__name">${escapeHtml13(name)}</span>
134835
+ <span class="myio-mg-side__name">${escapeHtml14(name)}</span>
134264
134836
  <span class="myio-mg-side__vals">
134265
134837
  <b style="color:${SERIES_COLORS.aMinus1}">${fmtInt(a)}</b>
134266
134838
  <b style="color:${SERIES_COLORS.realizado}">${fmtInt(r)}</b>
@@ -134271,7 +134843,7 @@ function miniSidebarHtml(shoppings, unit, prevY, curY) {
134271
134843
  return `<div class="myio-mg-side">
134272
134844
  <div class="myio-mg-side__head">
134273
134845
  <span>Resumo por shopping</span>
134274
- <span class="myio-mg-side__unit">${escapeHtml13(unit)}</span>
134846
+ <span class="myio-mg-side__unit">${escapeHtml14(unit)}</span>
134275
134847
  </div>
134276
134848
  <div class="myio-mg-side__cols">
134277
134849
  <span>Shopping</span>
@@ -134298,10 +134870,10 @@ function miniToolbarHtml(prevY, curY, highlight) {
134298
134870
  </div>`;
134299
134871
  }
134300
134872
  function bannerHtml(text2) {
134301
- return `<p class="myio-mg-banner">${escapeHtml13(text2)}</p>`;
134873
+ return `<p class="myio-mg-banner">${escapeHtml14(text2)}</p>`;
134302
134874
  }
134303
134875
  function paras(sentences) {
134304
- return `<div class="myio-mg-copy">${sentences.map((s) => `<p>${escapeHtml13(s)}</p>`).join("")}</div>`;
134876
+ return `<div class="myio-mg-copy">${sentences.map((s) => `<p>${escapeHtml14(s)}</p>`).join("")}</div>`;
134305
134877
  }
134306
134878
  function buildSections(ctx) {
134307
134879
  const { energy, water, curY, prevY } = ctx;
@@ -134326,8 +134898,8 @@ function buildSections(ctx) {
134326
134898
  "A r\xE9gua da meta muda por dom\xEDnio: em Energia a refer\xEAncia \xE9 a ENTRADA; em \xC1gua, os hidr\xF4metros.",
134327
134899
  "Os n\xFAmeros e a unidade de cada card acompanham o dom\xEDnio selecionado."
134328
134900
  ]) + miniToolbarHtml(prevY, curY, "domain") + `<div class="myio-mg-two">
134329
- <div><div class="myio-mg-two__tag">\u26A1 Energia \xB7 ${escapeHtml13(energy.unit)}</div>${miniCardHtml(e0, energy.unit, { chips: false })}</div>
134330
- <div><div class="myio-mg-two__tag">\u{1F4A7} \xC1gua \xB7 ${escapeHtml13(water.unit)}</div>${miniCardHtml(w0, water.unit, { chips: false })}</div>
134901
+ <div><div class="myio-mg-two__tag">\u26A1 Energia \xB7 ${escapeHtml14(energy.unit)}</div>${miniCardHtml(e0, energy.unit, { chips: false })}</div>
134902
+ <div><div class="myio-mg-two__tag">\u{1F4A7} \xC1gua \xB7 ${escapeHtml14(water.unit)}</div>${miniCardHtml(w0, water.unit, { chips: false })}</div>
134331
134903
  </div>`
134332
134904
  },
134333
134905
  {
@@ -134398,7 +134970,7 @@ function buildSections(ctx) {
134398
134970
  ]) + `<div class="myio-mg-order">
134399
134971
  <span class="myio-mg-order__btn">Data de Inaugura\xE7\xE3o \u2191 \xB7 \u2699\uFE0F</span>
134400
134972
  <span class="myio-mg-order__btn">\u25BD Filtros</span>
134401
- </div><ul class="myio-mg-order__list">${energy.shoppings.slice().sort((a, b) => a.inaugurationDate.localeCompare(b.inaugurationDate)).map((s) => `<li><b>${escapeHtml13(s.name)}</b> <span>inaugurado em ${escapeHtml13(s.inaugurationDate)}</span></li>`).join("")}</ul>`
134973
+ </div><ul class="myio-mg-order__list">${energy.shoppings.slice().sort((a, b) => a.inaugurationDate.localeCompare(b.inaugurationDate)).map((s) => `<li><b>${escapeHtml14(s.name)}</b> <span>inaugurado em ${escapeHtml14(s.inaugurationDate)}</span></li>`).join("")}</ul>`
134402
134974
  },
134403
134975
  {
134404
134976
  id: "engine",
@@ -134427,9 +134999,9 @@ function buildSections(ctx) {
134427
134999
  ];
134428
135000
  }
134429
135001
  function injectStyles16() {
134430
- if (document.getElementById(STYLE_ID14)) return;
135002
+ if (document.getElementById(STYLE_ID16)) return;
134431
135003
  const style = document.createElement("style");
134432
- style.id = STYLE_ID14;
135004
+ style.id = STYLE_ID16;
134433
135005
  style.textContent = `
134434
135006
  #${ROOT_ID}{position:fixed;inset:0;z-index:100001;display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(15,23,42,.6);backdrop-filter:blur(4px);font-family:'Nunito',system-ui,sans-serif;}
134435
135007
  #${ROOT_ID} *{box-sizing:border-box;}
@@ -134537,9 +135109,9 @@ function openMetasGuide(options = {}) {
134537
135109
  root.innerHTML = `
134538
135110
  <div class="myio-mg-modal${theme.mode === "dark" ? " is-dark" : ""}" role="dialog" aria-modal="true"
134539
135111
  aria-labelledby="myio-mg-title"
134540
- style="--mg-accent:${escapeHtml13(theme.accent)};--mg-accent-dark:${escapeHtml13(
135112
+ style="--mg-accent:${escapeHtml14(theme.accent)};--mg-accent-dark:${escapeHtml14(
134541
135113
  theme.accentDark
134542
- )};--mg-accent-text:${escapeHtml13(theme.accentText)};">
135114
+ )};--mg-accent-text:${escapeHtml14(theme.accentText)};">
134543
135115
  <div class="myio-mg-header">
134544
135116
  <div class="myio-mg-header__l">
134545
135117
  <span class="myio-mg-header__logo" aria-hidden="true">\u{1F393}</span>
@@ -144765,7 +145337,7 @@ var DeviceOperationalCardView = class {
144765
145337
  }
144766
145338
  renderCard(alarm) {
144767
145339
  const severityConfig = SEVERITY_CONFIG[alarm.severity];
144768
- const isActive = isAlarmActive(alarm.state);
145340
+ const isActive2 = isAlarmActive(alarm.state);
144769
145341
  const isCritical = alarm.severity === "CRITICAL" && alarm.state === "OPEN";
144770
145342
  const severityChipClass = this.getSeverityChipClass(alarm.severity);
144771
145343
  const stateChipClass = this.getStateChipClass(alarm.state);
@@ -144840,7 +145412,7 @@ var DeviceOperationalCardView = class {
144840
145412
 
144841
145413
  <!-- Actions -->
144842
145414
  <div class="myio-alarm-card-actions">
144843
- ${isActive ? `
145415
+ ${isActive2 ? `
144844
145416
  <button class="btn-ack" data-action="acknowledge">Reconhecer</button>
144845
145417
  ` : ""}
144846
145418
  <button class="btn-details" data-action="details">Detalhes</button>
@@ -148731,15 +149303,15 @@ var AlarmsNotificationsPanelView = class {
148731
149303
  const rows = alarms.map((alarm) => {
148732
149304
  const sev = SEVERITY_CONFIG[alarm.severity];
148733
149305
  const st = STATE_CONFIG[alarm.state];
148734
- const isActive = alarm.state !== "CLOSED";
149306
+ const isActive2 = alarm.state !== "CLOSED";
148735
149307
  const sel = this.selectedIds.has(alarm.id);
148736
149308
  const escTitle = this.esc(alarm.title);
148737
149309
  const escCustomer = this.esc(alarm.customerName || "-");
148738
149310
  const escSource = this.esc(alarm.source || "-");
148739
149311
  const actionBtns = `
148740
149312
  ${this.isAlarmActionAllowed("acknowledge") && alarm.state === "OPEN" ? `<button class="atbl-btn atbl-btn--ack" data-action="acknowledge" data-alarm-id="${alarm.id}" title="Reconhecer"><svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor"><path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg></button>` : ""}
148741
- ${this.isAlarmActionAllowed("snooze") && isActive ? `<button class="atbl-btn atbl-btn--snooze" data-action="snooze" data-alarm-id="${alarm.id}" title="Adiar"><svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67V7z"/></svg></button>` : ""}
148742
- ${this.isAlarmActionAllowed("escalate") && isActive ? `<button class="atbl-btn atbl-btn--escalate" data-action="escalate" data-alarm-id="${alarm.id}" title="Escalar"><svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor"><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg></button>` : ""}
149313
+ ${this.isAlarmActionAllowed("snooze") && isActive2 ? `<button class="atbl-btn atbl-btn--snooze" data-action="snooze" data-alarm-id="${alarm.id}" title="Adiar"><svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor"><path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67V7z"/></svg></button>` : ""}
149314
+ ${this.isAlarmActionAllowed("escalate") && isActive2 ? `<button class="atbl-btn atbl-btn--escalate" data-action="escalate" data-alarm-id="${alarm.id}" title="Escalar"><svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor"><path d="M4 12l1.41 1.41L11 7.83V20h2V7.83l5.58 5.59L20 12l-8-8-8 8z"/></svg></button>` : ""}
148743
149315
  <button class="atbl-btn atbl-btn--details" data-action="details" data-alarm-id="${alarm.id}" title="Detalhes"><svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/></svg></button>
148744
149316
  `;
148745
149317
  const tiposHtml = isPorDispositivo && alarm._alarmTypes?.length ? alarm._alarmTypes.slice(0, 2).map(
@@ -152635,8 +153207,8 @@ function renderDowntimeList(downtimeList) {
152635
153207
  <div class="downtime-item">
152636
153208
  <span class="rank">${index + 1}</span>
152637
153209
  <div class="item-info">
152638
- <span class="item-name">${escapeHtml14(item.name)}</span>
152639
- <span class="item-location">${escapeHtml14(item.location)}</span>
153210
+ <span class="item-name">${escapeHtml15(item.name)}</span>
153211
+ <span class="item-location">${escapeHtml15(item.location)}</span>
152640
153212
  </div>
152641
153213
  <div class="item-metrics">
152642
153214
  <span class="downtime-hours">${item.downtime}h</span>
@@ -152649,7 +153221,7 @@ function renderDowntimeList(downtimeList) {
152649
153221
  `
152650
153222
  ).join("");
152651
153223
  }
152652
- function escapeHtml14(text2) {
153224
+ function escapeHtml15(text2) {
152653
153225
  const div = document.createElement("div");
152654
153226
  div.textContent = text2;
152655
153227
  return div.innerHTML;
@@ -157232,7 +157804,7 @@ function removeSchedulingSharedStyles() {
157232
157804
  }
157233
157805
 
157234
157806
  // src/components/scheduling-shared/view-helpers.ts
157235
- function escapeHtml15(str) {
157807
+ function escapeHtml16(str) {
157236
157808
  const div = document.createElement("div");
157237
157809
  div.textContent = str;
157238
157810
  return div.innerHTML;
@@ -157393,7 +157965,7 @@ function showConfirmModal(container, title, message) {
157393
157965
  overlay.innerHTML = `
157394
157966
  <div class="${SCHED_CSS_PREFIX}__modal-backdrop"></div>
157395
157967
  <div class="${SCHED_CSS_PREFIX}__modal-content">
157396
- <h3>${escapeHtml15(title)}</h3>
157968
+ <h3>${escapeHtml16(title)}</h3>
157397
157969
  <p>${message}</p>
157398
157970
  <div class="${SCHED_CSS_PREFIX}__modal-actions">
157399
157971
  <button class="${SCHED_CSS_PREFIX}__modal-btn-cancel">Cancelar</button>
@@ -157427,8 +157999,8 @@ function showNotificationModal(container, type, message, autoCloseMs = 6e3) {
157427
157999
  overlay.innerHTML = `
157428
158000
  <div class="${SCHED_CSS_PREFIX}__modal-backdrop"></div>
157429
158001
  <div class="${SCHED_CSS_PREFIX}__modal-content">
157430
- <h3>${escapeHtml15(title)}</h3>
157431
- <p>${escapeHtml15(message)}</p>
158002
+ <h3>${escapeHtml16(title)}</h3>
158003
+ <p>${escapeHtml16(message)}</p>
157432
158004
  <div class="${SCHED_CSS_PREFIX}__modal-actions">
157433
158005
  <button class="${SCHED_CSS_PREFIX}__modal-btn-close">Fechar</button>
157434
158006
  </div>
@@ -159149,10 +159721,10 @@ var DeviceGridV6View = class {
159149
159721
  }
159150
159722
  toggleSearch() {
159151
159723
  if (!this.searchWrapEl) return;
159152
- const isActive = this.searchWrapEl.classList.toggle("active");
159153
- if (isActive && this.searchInputEl) {
159724
+ const isActive2 = this.searchWrapEl.classList.toggle("active");
159725
+ if (isActive2 && this.searchInputEl) {
159154
159726
  this.searchInputEl.focus();
159155
- } else if (!isActive && this.searchInputEl) {
159727
+ } else if (!isActive2 && this.searchInputEl) {
159156
159728
  this.searchInputEl.value = "";
159157
159729
  this.controller.setSearchTerm("");
159158
159730
  this.renderCards();
@@ -160694,7 +161266,7 @@ var DEFAULT_CONFIG4 = {
160694
161266
  off: "Desligado"
160695
161267
  }
160696
161268
  };
160697
- function formatDuration2(minutes) {
161269
+ function formatDuration3(minutes) {
160698
161270
  if (minutes < 60) {
160699
161271
  return `${Math.round(minutes)}min`;
160700
161272
  }
@@ -160764,7 +161336,7 @@ function renderTimelineSVG(data, config2) {
160764
161336
  text-anchor="middle"
160765
161337
  class="${ONOFF_TIMELINE_CSS_PREFIX}__duration-label"
160766
161338
  >
160767
- ${formatDuration2(seg.durationMinutes)}
161339
+ ${formatDuration3(seg.durationMinutes)}
160768
161340
  </text>
160769
161341
  `;
160770
161342
  }
@@ -160790,7 +161362,7 @@ function renderTimelineSVG(data, config2) {
160790
161362
  data-state="${stateClass}"
160791
161363
  data-start="${formatDateTime4(seg.startTime)}"
160792
161364
  data-end="${formatDateTime4(seg.endTime)}"
160793
- data-duration="${formatDuration2(seg.durationMinutes)}"
161365
+ data-duration="${formatDuration3(seg.durationMinutes)}"
160794
161366
  data-source="${seg.source || "unknown"}"
160795
161367
  />
160796
161368
  `;
@@ -160887,7 +161459,7 @@ function renderSummary(data, labels) {
160887
161459
  </div>
160888
161460
  <div class="${ONOFF_TIMELINE_CSS_PREFIX}__summary-item">
160889
161461
  <span class="${ONOFF_TIMELINE_CSS_PREFIX}__summary-value">
160890
- ${formatDuration2(data.totalOnMinutes)}
161462
+ ${formatDuration3(data.totalOnMinutes)}
160891
161463
  </span>
160892
161464
  <span class="${ONOFF_TIMELINE_CSS_PREFIX}__summary-label">Tempo ${labels.on || "ON"}</span>
160893
161465
  </div>
@@ -165901,8 +166473,8 @@ var SidebarMenuView = class {
165901
166473
  `;
165902
166474
  }
165903
166475
  renderItem(item, section) {
165904
- const isActive = this.activeItemId === item.id;
165905
- const activeClass = isActive ? "active" : "";
166476
+ const isActive2 = this.activeItemId === item.id;
166477
+ const activeClass = isActive2 ? "active" : "";
165906
166478
  const disabledClass = item.disabled ? "disabled" : "";
165907
166479
  return `
165908
166480
  <div
@@ -165912,7 +166484,7 @@ var SidebarMenuView = class {
165912
166484
  data-action="item-click"
165913
166485
  role="menuitem"
165914
166486
  tabindex="${item.disabled ? -1 : 0}"
165915
- aria-current="${isActive ? "page" : "false"}"
166487
+ aria-current="${isActive2 ? "page" : "false"}"
165916
166488
  ${item.disabled ? 'aria-disabled="true"' : ""}
165917
166489
  >
165918
166490
  <span class="${SIDEBAR_MENU_CSS_PREFIX}__item-icon">
@@ -168255,7 +168827,7 @@ var DAY_NAMES = {
168255
168827
  "5": "Sex",
168256
168828
  "6": "S\xE1b"
168257
168829
  };
168258
- function formatDuration3(ms) {
168830
+ function formatDuration4(ms) {
168259
168831
  if (!ms) return "";
168260
168832
  const min = Math.round(ms / 6e4);
168261
168833
  if (min < 60) return `${min} min`;
@@ -168276,7 +168848,7 @@ function renderRuleDetailContent(rule) {
168276
168848
  }
168277
168849
  function renderRuleChips(rule) {
168278
168850
  const op = OPERATOR_LABELS2[rule.operator] ?? rule.operator;
168279
- const dur = formatDuration3(rule.duration);
168851
+ const dur = formatDuration4(rule.duration);
168280
168852
  const time = rule.startAt && rule.endAt ? `${rule.startAt} \u2013 ${rule.endAt}` : "";
168281
168853
  const agg = rule.aggregation ?? "";
168282
168854
  const chips = [
@@ -170042,11 +170614,11 @@ function _esc(s) {
170042
170614
  const str = s == null ? "" : String(s);
170043
170615
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
170044
170616
  }
170045
- var STYLE_ID15 = "ntw-styles";
170617
+ var STYLE_ID17 = "ntw-styles";
170046
170618
  function _injectStyles2() {
170047
- if (document.getElementById(STYLE_ID15)) return;
170619
+ if (document.getElementById(STYLE_ID17)) return;
170048
170620
  const s = document.createElement("style");
170049
- s.id = STYLE_ID15;
170621
+ s.id = STYLE_ID17;
170050
170622
  s.textContent = NTW_CSS;
170051
170623
  document.head.appendChild(s);
170052
170624
  }
@@ -172747,7 +173319,7 @@ var IMPORTANCE_COLORS4 = {
172747
173319
  // red
172748
173320
  };
172749
173321
  var ITEM_TEXT_MAX = 120;
172750
- function escapeHtml16(input) {
173322
+ function escapeHtml17(input) {
172751
173323
  if (input == null) return "";
172752
173324
  return String(input).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
172753
173325
  }
@@ -172785,24 +173357,24 @@ function renderAnnotationItemCard(device, annotation, searchTerm) {
172785
173357
  const domainIcon = DOMAIN_ICONS3[device.domain] ?? DOMAIN_ICONS3.unknown;
172786
173358
  const typeIcon = TYPE_ICONS[annotation.type] ?? "\xB7";
172787
173359
  const importance = Math.max(1, Math.min(5, annotation.importance || 1));
172788
- const textEscaped = escapeHtml16(truncate2(annotation.text || "", ITEM_TEXT_MAX));
172789
- const deviceLabelEscaped = escapeHtml16(device.label || device.name || device.deviceId);
172790
- const author = escapeHtml16(annotation.createdBy?.name || "sem autor");
172791
- const when = escapeHtml16(formatRelative(annotation.createdAt));
173360
+ const textEscaped = escapeHtml17(truncate2(annotation.text || "", ITEM_TEXT_MAX));
173361
+ const deviceLabelEscaped = escapeHtml17(device.label || device.name || device.deviceId);
173362
+ const author = escapeHtml17(annotation.createdBy?.name || "sem autor");
173363
+ const when = escapeHtml17(formatRelative(annotation.createdAt));
172792
173364
  const overdueTag = isOverdue(annotation) ? '<span class="myio-annotations-overdue">Vencida</span>' : "";
172793
173365
  const text2 = searchTerm ? highlightMatches(textEscaped, searchTerm) : textEscaped;
172794
173366
  const deviceLabel = searchTerm ? highlightMatches(deviceLabelEscaped, searchTerm) : deviceLabelEscaped;
172795
- const identifierEscaped = device.identifier ? escapeHtml16(device.identifier) : "";
173367
+ const identifierEscaped = device.identifier ? escapeHtml17(device.identifier) : "";
172796
173368
  const identifierHighlighted = searchTerm && identifierEscaped ? highlightMatches(identifierEscaped, searchTerm) : identifierEscaped;
172797
173369
  const identifierTag = device.identifier ? `<span class="myio-annotations-item-device">${identifierHighlighted}</span>` : "";
172798
173370
  return `
172799
173371
  <button
172800
173372
  class="myio-annotations-item"
172801
173373
  type="button"
172802
- data-device-id="${escapeHtml16(device.deviceId)}"
172803
- data-annotation-id="${escapeHtml16(annotation.id)}"
173374
+ data-device-id="${escapeHtml17(device.deviceId)}"
173375
+ data-annotation-id="${escapeHtml17(annotation.id)}"
172804
173376
  tabindex="0"
172805
- aria-label="${escapeHtml16(annotation.text)} \u2014 ${deviceLabel}"
173377
+ aria-label="${escapeHtml17(annotation.text)} \u2014 ${deviceLabel}"
172806
173378
  >
172807
173379
  <span class="myio-annotations-item-icon" aria-hidden="true">${typeIcon}</span>
172808
173380
  <div class="myio-annotations-item-body">
@@ -173779,8 +174351,8 @@ var HeaderAnnotationsPanel = class _HeaderAnnotationsPanel {
173779
174351
  // group header
173780
174352
  render: () => `
173781
174353
  <header class="myio-annotations-group-header ${groupClass}">
173782
- ${g.icon ? `<span class="myio-annotations-group-icon" aria-hidden="true">${escapeHtml16(g.icon)}</span>` : ""}
173783
- <span class="myio-annotations-group-label">${escapeHtml16(g.label)}</span>
174354
+ ${g.icon ? `<span class="myio-annotations-group-icon" aria-hidden="true">${escapeHtml17(g.icon)}</span>` : ""}
174355
+ <span class="myio-annotations-group-label">${escapeHtml17(g.label)}</span>
173784
174356
  <span class="myio-annotations-group-count">${g.totalAnnotations}</span>
173785
174357
  </header>`
173786
174358
  });
@@ -173905,9 +174477,9 @@ ${this._renderToolbar(filteredCount, totalAllUnfiltered)}
173905
174477
  }
173906
174478
  _renderToolbar(filteredCount, totalCount) {
173907
174479
  const sortOptions = SORT_OPTIONS.map(
173908
- (o) => `<option value="${o.key}" ${o.key === this.sortBy ? "selected" : ""}>${escapeHtml16(o.label)}</option>`
174480
+ (o) => `<option value="${o.key}" ${o.key === this.sortBy ? "selected" : ""}>${escapeHtml17(o.label)}</option>`
173909
174481
  ).join("");
173910
- const term = escapeHtml16(this.filter.searchTerm || "");
174482
+ const term = escapeHtml17(this.filter.searchTerm || "");
173911
174483
  const filtersActiveCount = this._activeFilterCount();
173912
174484
  const filterIndicator = filtersActiveCount > 0 ? `<span class="myio-annotations-group-count">${filtersActiveCount}</span>` : "";
173913
174485
  const showingHtml = filteredCount === totalCount ? `${totalCount} anota\xE7\xF5es` : `${filteredCount} de ${totalCount} anota\xE7\xF5es`;
@@ -173948,13 +174520,13 @@ ${this._renderToolbar(filteredCount, totalAllUnfiltered)}
173948
174520
  const typesHtml = FILTER_TYPE_OPTIONS.map(
173949
174521
  (t) => `<label class="myio-annotations-filter-chip ${this.filter.types.has(t.id) ? "is-on" : ""}">
173950
174522
  <input type="checkbox" data-filter="type" value="${t.id}" ${this.filter.types.has(t.id) ? "checked" : ""} />
173951
- <span>${t.icon} ${escapeHtml16(t.label)}</span>
174523
+ <span>${t.icon} ${escapeHtml17(t.label)}</span>
173952
174524
  </label>`
173953
174525
  ).join("");
173954
174526
  const statusHtml = FILTER_STATUS_OPTIONS.map(
173955
174527
  (s) => `<label class="myio-annotations-filter-chip ${this.filter.statuses.has(s.id) ? "is-on" : ""}">
173956
174528
  <input type="checkbox" data-filter="status" value="${s.id}" ${this.filter.statuses.has(s.id) ? "checked" : ""} />
173957
- <span>${escapeHtml16(s.label)}</span>
174529
+ <span>${escapeHtml17(s.label)}</span>
173958
174530
  </label>`
173959
174531
  ).join("");
173960
174532
  const impHtml = [1, 2, 3, 4, 5].map(
@@ -174031,12 +174603,12 @@ ${this._renderToolbar(filteredCount, totalAllUnfiltered)}
174031
174603
  return `
174032
174604
  <section class="${groupClass}">
174033
174605
  <header class="myio-annotations-group-header" role="button" tabindex="0"
174034
- data-group-toggle="${escapeHtml16(group.key)}"
174606
+ data-group-toggle="${escapeHtml17(group.key)}"
174035
174607
  aria-expanded="${!isCollapsed}"
174036
174608
  title="${isCollapsed ? "Expandir grupo" : "Recolher grupo"}">
174037
174609
  <span class="myio-annotations-group-chevron" aria-hidden="true">${isCollapsed ? "\u25B6" : "\u25BC"}</span>
174038
- ${group.icon ? `<span class="myio-annotations-group-icon" aria-hidden="true">${escapeHtml16(group.icon)}</span>` : ""}
174039
- <span class="myio-annotations-group-label">${escapeHtml16(group.label)}</span>
174610
+ ${group.icon ? `<span class="myio-annotations-group-icon" aria-hidden="true">${escapeHtml17(group.icon)}</span>` : ""}
174611
+ <span class="myio-annotations-group-label">${escapeHtml17(group.label)}</span>
174040
174612
  <span class="myio-annotations-group-count">${group.totalAnnotations}</span>
174041
174613
  </header>
174042
174614
  ${itemsHtml}
@@ -174697,7 +175269,7 @@ function validateDeviceProductCode(code) {
174697
175269
  }
174698
175270
 
174699
175271
  // src/components/cards/central-status/v1.0.0/styles.ts
174700
- var STYLE_ID16 = "myio-central-status-card-styles";
175272
+ var STYLE_ID18 = "myio-central-status-card-styles";
174701
175273
  var CSS5 = `
174702
175274
  .myio-cscard{
174703
175275
  --cscard-surface:#ffffff;
@@ -175000,9 +175572,9 @@ var CSS5 = `
175000
175572
  `;
175001
175573
  function injectCentralStatusCardStyles() {
175002
175574
  if (typeof document === "undefined") return;
175003
- if (document.getElementById(STYLE_ID16)) return;
175575
+ if (document.getElementById(STYLE_ID18)) return;
175004
175576
  const tag = document.createElement("style");
175005
- tag.id = STYLE_ID16;
175577
+ tag.id = STYLE_ID18;
175006
175578
  tag.textContent = CSS5;
175007
175579
  document.head.appendChild(tag);
175008
175580
  }
@@ -175062,7 +175634,7 @@ function deriveCentralConnectivity(ev, opts) {
175062
175634
  }
175063
175635
 
175064
175636
  // src/components/cards/central-status/v1.0.0/TimelineModal.ts
175065
- var STYLE_ID17 = "myio-cscard-timeline-styles";
175637
+ var STYLE_ID19 = "myio-cscard-timeline-styles";
175066
175638
  var DEFAULT_PERIODS = [1, 7, 30, 90];
175067
175639
  function escAttr5(s) {
175068
175640
  return String(s ?? "").replace(
@@ -175071,9 +175643,9 @@ function escAttr5(s) {
175071
175643
  );
175072
175644
  }
175073
175645
  function injectTimelineModalStyles() {
175074
- if (typeof document === "undefined" || document.getElementById(STYLE_ID17)) return;
175646
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID19)) return;
175075
175647
  const tag = document.createElement("style");
175076
- tag.id = STYLE_ID17;
175648
+ tag.id = STYLE_ID19;
175077
175649
  tag.textContent = `
175078
175650
  .myio-tlmodal{
175079
175651
  --tl-online:#3b82f6;
@@ -175412,7 +175984,7 @@ function formatSince(iso, nowMs, language) {
175412
175984
  else rel = `${Math.round(s / 86400)}d`;
175413
175985
  return `${abs} (${rel})`;
175414
175986
  }
175415
- function formatDuration4(ms) {
175987
+ function formatDuration5(ms) {
175416
175988
  const totalMin = Math.max(0, Math.round(ms / 6e4));
175417
175989
  const hours = Math.floor(totalMin / 60);
175418
175990
  const minutes = totalMin % 60;
@@ -175750,7 +176322,7 @@ var CentralStatusCard = class _CentralStatusCard {
175750
176322
  this.el.removeAttribute("draggable");
175751
176323
  }
175752
176324
  this.el.style.zoom = p.scale && p.scale !== 1 ? String(p.scale) : "";
175753
- const connLabel = l.connectivityValue?.[connectivity] || (pastHard && sinceSuccessMs != null ? `${CONNECTIVITY_VALUE_DEFAULT.OFFLINE} ${formatDuration4(sinceSuccessMs)}` : CONNECTIVITY_VALUE_DEFAULT[connectivity]);
176325
+ const connLabel = l.connectivityValue?.[connectivity] || (pastHard && sinceSuccessMs != null ? `${CONNECTIVITY_VALUE_DEFAULT.OFFLINE} ${formatDuration5(sinceSuccessMs)}` : CONNECTIVITY_VALUE_DEFAULT[connectivity]);
175754
176326
  const staleBadge = stale ? `<span class="myio-cscard__stale">${STALE_BADGE_TEXT[this.language()]}</span>` : "";
175755
176327
  const divergenceGlyph = (() => {
175756
176328
  const o = p.icons?.divergence;
@@ -176412,6 +176984,7 @@ var version = package_default.version || "0.0.0";
176412
176984
  POWER_LIMITS_DEVICE_TYPES,
176413
176985
  POWER_LIMITS_STATUS_CONFIG,
176414
176986
  POWER_LIMITS_TELEMETRY_TYPES,
176987
+ PUMP_POWER_KEY,
176415
176988
  REPORT_MONEY_HEADER,
176416
176989
  SCHEDULE_HOLIDAY_CSS_PREFIX,
176417
176990
  SCHEDULE_IR_CSS_PREFIX,
@@ -176464,6 +177037,7 @@ var version = package_default.version || "0.0.0";
176464
177037
  TempSensorSummaryTooltip,
176465
177038
  Temperature,
176466
177039
  UsersSummaryTooltip,
177040
+ VALVE_STATE_KEYS,
176467
177041
  VARIANCE_LABEL_ABOVE,
176468
177042
  VARIANCE_LABEL_BELOW,
176469
177043
  VARIANCE_LABEL_ONTARGET,
@@ -176586,6 +177160,7 @@ var version = package_default.version || "0.0.0";
176586
177160
  createDistributionChartWidget,
176587
177161
  createDivCard,
176588
177162
  createEnergyPanelComponent,
177163
+ createEquipmentIndicatorStrip,
176589
177164
  createErrorSpan,
176590
177165
  createExportButton,
176591
177166
  createFakeDeviceCategoryPort,
@@ -176812,6 +177387,7 @@ var version = package_default.version || "0.0.0";
176812
177387
  hasCoverageGaps,
176813
177388
  hasSelectedDays,
176814
177389
  highlightAnnotationMatches,
177390
+ indicatorsFromModalData,
176815
177391
  initMyIOAuthContext,
176816
177392
  initOnOffTimelineTooltips,
176817
177393
  injectActionButtonStyles,
@@ -176848,6 +177424,7 @@ var version = package_default.version || "0.0.0";
176848
177424
  injectSolenoidControlStyles,
176849
177425
  injectSwitchControlStyles,
176850
177426
  interpolateTemperature,
177427
+ intervalsFromTelemetry,
176851
177428
  inventory,
176852
177429
  isAlarmActive,
176853
177430
  isAnnotationOverdue,
@@ -176877,6 +177454,7 @@ var version = package_default.version || "0.0.0";
176877
177454
  isValidTimeFormat,
176878
177455
  isWaterCategory,
176879
177456
  latestHourlyTemperature,
177457
+ latestPowerKw,
176880
177458
  liftProfileToTree,
176881
177459
  listDeviceProductTypes,
176882
177460
  listDomains,
@@ -176945,10 +177523,12 @@ var version = package_default.version || "0.0.0";
176945
177523
  openUpsellModal,
176946
177524
  openUserManagementModal,
176947
177525
  openWelcomeModal,
177526
+ openWellPumpsModal,
176948
177527
  overlayWithholdsVerdict,
176949
177528
  panelCategoryToWire,
176950
177529
  panelDomainToWire,
176951
177530
  panelTermToDeviceCategory,
177531
+ parseBinaryState,
176952
177532
  parseClassificationEntities,
176953
177533
  parseGcdrEnergyRoot,
176954
177534
  parseGcdrEntityForest,
@@ -176956,6 +177536,7 @@ var version = package_default.version || "0.0.0";
176956
177536
  parseLogAnnotations,
176957
177537
  periodKey,
176958
177538
  pickUniqueCustomerCode,
177539
+ pumpHistoryFromConsumption,
176959
177540
  readFreshdeskTicketsFromTB,
176960
177541
  recalculateDeviceStatus,
176961
177542
  recomputeDeviceGridPercentages,
@@ -176983,6 +177564,8 @@ var version = package_default.version || "0.0.0";
176983
177564
  renderDashboardDowntimeList,
176984
177565
  renderDeviceGridList,
176985
177566
  renderDualLineChart,
177567
+ renderEquipmentShortcutHTML,
177568
+ renderEquipmentTilesHTML,
176986
177569
  renderFinancialIndicators,
176987
177570
  renderGatedMoney,
176988
177571
  renderKPICards,