myio-js-library 0.1.564 → 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
@@ -130,6 +130,7 @@ __export(src_exports, {
130
130
  DEFAULT_SIDEBAR_CONFIG: () => DEFAULT_SIDEBAR_CONFIG,
131
131
  DEFAULT_SOLENOID_SETTINGS: () => DEFAULT_SOLENOID_SETTINGS,
132
132
  DEFAULT_SOLENOID_STATE: () => DEFAULT_SOLENOID_STATE,
133
+ DEFAULT_STORE_SEGMENTS: () => DEFAULT_STORE_SEGMENTS,
133
134
  DEFAULT_SWITCH_SETTINGS: () => DEFAULT_SWITCH_SETTINGS,
134
135
  DEFAULT_SWITCH_STATE: () => DEFAULT_SWITCH_STATE,
135
136
  DEFAULT_TABS: () => DEFAULT_TABS,
@@ -275,6 +276,7 @@ __export(src_exports, {
275
276
  POWER_LIMITS_DEVICE_TYPES: () => DEVICE_TYPES,
276
277
  POWER_LIMITS_STATUS_CONFIG: () => STATUS_CONFIG,
277
278
  POWER_LIMITS_TELEMETRY_TYPES: () => TELEMETRY_TYPES,
279
+ PUMP_POWER_KEY: () => PUMP_POWER_KEY,
278
280
  REPORT_MONEY_HEADER: () => REPORT_MONEY_HEADER,
279
281
  SCHEDULE_HOLIDAY_CSS_PREFIX: () => SCHEDULE_HOLIDAY_CSS_PREFIX,
280
282
  SCHEDULE_IR_CSS_PREFIX: () => SCHEDULE_IR_CSS_PREFIX,
@@ -327,6 +329,7 @@ __export(src_exports, {
327
329
  TempSensorSummaryTooltip: () => TempSensorSummaryTooltip,
328
330
  Temperature: () => Temperature,
329
331
  UsersSummaryTooltip: () => UsersSummaryTooltip,
332
+ VALVE_STATE_KEYS: () => VALVE_STATE_KEYS,
330
333
  VARIANCE_LABEL_ABOVE: () => VARIANCE_LABEL_ABOVE,
331
334
  VARIANCE_LABEL_BELOW: () => VARIANCE_LABEL_BELOW,
332
335
  VARIANCE_LABEL_ONTARGET: () => VARIANCE_LABEL_ONTARGET,
@@ -449,6 +452,7 @@ __export(src_exports, {
449
452
  createDistributionChartWidget: () => createDistributionChartWidget,
450
453
  createDivCard: () => createDivCard,
451
454
  createEnergyPanelComponent: () => createEnergyPanelComponent,
455
+ createEquipmentIndicatorStrip: () => createEquipmentIndicatorStrip,
452
456
  createErrorSpan: () => createErrorSpan,
453
457
  createExportButton: () => createExportButton,
454
458
  createFakeDeviceCategoryPort: () => createFakeDeviceCategoryPort,
@@ -543,7 +547,7 @@ __export(src_exports, {
543
547
  doSchedulesOverlap: () => doSchedulesOverlap,
544
548
  downloadAnnotationsTextFile: () => downloadTextFile,
545
549
  encodeDeviceProductCode: () => encodeDeviceProductCode,
546
- escapeAnnotationHtml: () => escapeHtml16,
550
+ escapeAnnotationHtml: () => escapeHtml17,
547
551
  evaluateDeviceStatus: () => evaluateDeviceStatus,
548
552
  expandBandHours: () => expandBandHours,
549
553
  expandBandToHourBucketsByYear: () => expandBandToHourBucketsByYear,
@@ -675,6 +679,7 @@ __export(src_exports, {
675
679
  hasCoverageGaps: () => hasCoverageGaps,
676
680
  hasSelectedDays: () => hasSelectedDays,
677
681
  highlightAnnotationMatches: () => highlightMatches,
682
+ indicatorsFromModalData: () => indicatorsFromModalData,
678
683
  initMyIOAuthContext: () => initMyIOAuthContext,
679
684
  initOnOffTimelineTooltips: () => initOnOffTimelineTooltips,
680
685
  injectActionButtonStyles: () => injectActionButtonStyles,
@@ -711,6 +716,7 @@ __export(src_exports, {
711
716
  injectSolenoidControlStyles: () => injectSolenoidControlStyles,
712
717
  injectSwitchControlStyles: () => injectSwitchControlStyles,
713
718
  interpolateTemperature: () => interpolateTemperature,
719
+ intervalsFromTelemetry: () => intervalsFromTelemetry,
714
720
  inventory: () => inventory_exports,
715
721
  isAlarmActive: () => isAlarmActive,
716
722
  isAnnotationOverdue: () => isOverdue,
@@ -740,6 +746,7 @@ __export(src_exports, {
740
746
  isValidTimeFormat: () => isValidTimeFormat,
741
747
  isWaterCategory: () => isWaterCategory,
742
748
  latestHourlyTemperature: () => latestHourlyTemperature,
749
+ latestPowerKw: () => latestPowerKw,
743
750
  liftProfileToTree: () => liftProfileToTree,
744
751
  listDeviceProductTypes: () => listDeviceProductTypes,
745
752
  listDomains: () => listDomains,
@@ -808,10 +815,12 @@ __export(src_exports, {
808
815
  openUpsellModal: () => openUpsellModal,
809
816
  openUserManagementModal: () => openUserManagementModal,
810
817
  openWelcomeModal: () => openWelcomeModal,
818
+ openWellPumpsModal: () => openWellPumpsModal,
811
819
  overlayWithholdsVerdict: () => overlayWithholdsVerdict,
812
820
  panelCategoryToWire: () => panelCategoryToWire,
813
821
  panelDomainToWire: () => panelDomainToWire,
814
822
  panelTermToDeviceCategory: () => panelTermToDeviceCategory,
823
+ parseBinaryState: () => parseBinaryState,
815
824
  parseClassificationEntities: () => parseClassificationEntities,
816
825
  parseGcdrEnergyRoot: () => parseGcdrEnergyRoot,
817
826
  parseGcdrEntityForest: () => parseGcdrEntityForest,
@@ -819,6 +828,7 @@ __export(src_exports, {
819
828
  parseLogAnnotations: () => parseLogAnnotations,
820
829
  periodKey: () => periodKey,
821
830
  pickUniqueCustomerCode: () => pickUniqueCustomerCode,
831
+ pumpHistoryFromConsumption: () => pumpHistoryFromConsumption,
822
832
  readFreshdeskTicketsFromTB: () => readFreshdeskTicketsFromTB,
823
833
  recalculateDeviceStatus: () => recalculateDeviceStatus,
824
834
  recomputeDeviceGridPercentages: () => recomputePercentages,
@@ -846,6 +856,8 @@ __export(src_exports, {
846
856
  renderDashboardDowntimeList: () => renderDowntimeList,
847
857
  renderDeviceGridList: () => renderList,
848
858
  renderDualLineChart: () => renderDualLineChart,
859
+ renderEquipmentShortcutHTML: () => renderEquipmentShortcutHTML,
860
+ renderEquipmentTilesHTML: () => renderEquipmentTilesHTML,
849
861
  renderFinancialIndicators: () => renderFinancialIndicators,
850
862
  renderGatedMoney: () => renderGatedMoney,
851
863
  renderKPICards: () => renderKPICards,
@@ -874,7 +886,7 @@ __export(src_exports, {
874
886
  schedCreateNumberInput: () => createNumberInput,
875
887
  schedCreateSelect: () => createSelect,
876
888
  schedCreateTimeInput: () => createTimeInput,
877
- schedEscapeHtml: () => escapeHtml15,
889
+ schedEscapeHtml: () => escapeHtml16,
878
890
  schedShowConfirmModal: () => showConfirmModal,
879
891
  schedShowNotificationModal: () => showNotificationModal,
880
892
  selectBreakdownItems: () => selectBreakdownItems,
@@ -922,7 +934,7 @@ module.exports = __toCommonJS(src_exports);
922
934
  // package.json
923
935
  var package_default = {
924
936
  name: "myio-js-library",
925
- version: "0.1.564",
937
+ version: "0.1.566",
926
938
  description: "A clean, standalone JS SDK for MYIO projects",
927
939
  license: "MIT",
928
940
  repository: "github:gh-myio/myio-js-library",
@@ -2306,6 +2318,7 @@ var DeviceIconType = {
2306
2318
  BOMBA_CAG: "BOMBA_CAG",
2307
2319
  BOMBA_INCENDIO: "BOMBA_INCENDIO",
2308
2320
  BOMBA: "BOMBA",
2321
+ BOMBA_POCO: "BOMBA_POCO",
2309
2322
  MEDIDOR_3F: "3F_MEDIDOR",
2310
2323
  RELOGIO: "RELOGIO",
2311
2324
  ENTRADA: "ENTRADA",
@@ -2317,6 +2330,8 @@ var DeviceIconType = {
2317
2330
  HIDROMETRO_AREA_COMUM: "HIDROMETRO_AREA_COMUM",
2318
2331
  HIDROMETRO_SHOPPING: "HIDROMETRO_SHOPPING",
2319
2332
  CAIXA_DAGUA: "CAIXA_DAGUA",
2333
+ CISTERNA: "CISTERNA",
2334
+ CISTERNA_ENTRADA: "CISTERNA_ENTRADA",
2320
2335
  TERMOSTATO: "TERMOSTATO",
2321
2336
  COMPRESSOR: "COMPRESSOR",
2322
2337
  VENTILADOR: "VENTILADOR",
@@ -2326,6 +2341,11 @@ var DeviceIconType = {
2326
2341
  };
2327
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>';
2328
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);
2329
2349
  var deviceIcons = {
2330
2350
  ESCADA_ROLANTE: "https://dashboard.myio-bas.com/api/images/public/EJ997iB2HD1AYYUHwIloyQOOszeqb2jp",
2331
2351
  ELEVADOR: "https://dashboard.myio-bas.com/api/images/public/rAjOvdsYJLGah6w6BABPJSD9znIyrkJX",
@@ -2334,6 +2354,8 @@ var deviceIcons = {
2334
2354
  BOMBA_CAG: "https://dashboard.myio-bas.com/api/images/public/rbO2wQb6iKBtX0Ec04DFDcO3Qg04EOoD",
2335
2355
  BOMBA_INCENDIO: "https://dashboard.myio-bas.com/api/images/public/YJkELCk9kluQSM6QXaFINX6byQWI7vbB",
2336
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",
2337
2359
  "3F_MEDIDOR": "https://dashboard.myio-bas.com/api/images/public/f9Ce4meybsdaAhAkUlAfy5ei3I4kcN4k",
2338
2360
  RELOGIO: "https://dashboard.myio-bas.com/api/images/public/ljHZostWg0G5AfKiyM8oZixWRIIGRASB",
2339
2361
  ENTRADA: "https://dashboard.myio-bas.com/api/images/public/TQHPFqiejMW6lOSVsb8Pi85WtC0QKOLU",
@@ -2348,6 +2370,10 @@ var deviceIcons = {
2348
2370
  HIDROMETRO_AREA_COMUM: "https://dashboard.myio-bas.com/api/images/public/IbEhjsvixAxwKg1ntGGZc5xZwwvGKv2t",
2349
2371
  HIDROMETRO_SHOPPING: "https://dashboard.myio-bas.com/api/images/public/OIMmvN4ZTKYDvrpPGYY5agqMRoSaWNTI",
2350
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,
2351
2377
  TERMOSTATO: "https://dashboard.myio-bas.com/api/images/public/rtCcq6kZZVCD7wgJywxEurRZwR8LA7Q7",
2352
2378
  // COMPRESSOR shares FANCOIL art; VENTILADOR shares MOTOR/BOMBA art (single static icons, no on/off variation).
2353
2379
  COMPRESSOR: "https://dashboard.myio-bas.com/api/images/public/4BWMuVIFHnsfqatiV86DmTrOB7IF0X8Y",
@@ -2368,6 +2394,7 @@ var deviceIconLabels = {
2368
2394
  BOMBA_CAG: "Bomba CAG",
2369
2395
  BOMBA_INCENDIO: "Bomba Inc\xEAndio",
2370
2396
  BOMBA: "Bomba",
2397
+ BOMBA_POCO: "Bomba de Po\xE7o",
2371
2398
  "3F_MEDIDOR": "Medidor 3F",
2372
2399
  RELOGIO: "Rel\xF3gio",
2373
2400
  ENTRADA: "Entrada",
@@ -2379,6 +2406,8 @@ var deviceIconLabels = {
2379
2406
  HIDROMETRO_AREA_COMUM: "Hidr\xF4metro \xC1rea Comum",
2380
2407
  HIDROMETRO_SHOPPING: "Hidr\xF4metro Shopping",
2381
2408
  CAIXA_DAGUA: "Caixa d'\xC1gua",
2409
+ CISTERNA: "Cisterna",
2410
+ CISTERNA_ENTRADA: "Cisterna (Entrada)",
2382
2411
  TERMOSTATO: "Termostato",
2383
2412
  COMPRESSOR: "Compressor",
2384
2413
  VENTILADOR: "Ventilador",
@@ -2421,6 +2450,11 @@ var DEVICE_TYPE_CONFIG = {
2421
2450
  HIDROMETRO_AREA_COMUM: { category: "water", image: deviceIcons.HIDROMETRO_AREA_COMUM },
2422
2451
  HIDROMETRO_SHOPPING: { category: "water", image: deviceIcons.HIDROMETRO_SHOPPING },
2423
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)
2424
2458
  // Tank devices (dynamic images based on level)
2425
2459
  TANK: { category: "tank", image: null },
2426
2460
  // Temperature devices (dynamic images based on status)
@@ -20780,6 +20814,234 @@ function resolvePercentDecimals(explicit) {
20780
20814
  return 2;
20781
20815
  }
20782
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
+
20783
21045
  // src/components/cards/main-view/v5.2.0/template-card-v5.js
20784
21046
  var LABEL_CHAR_LIMIT2 = 18;
20785
21047
  var ENERGY_DEVICE_TYPES = getTypesByCategory("energy");
@@ -20814,7 +21076,9 @@ function renderCardComponentV5({
20814
21076
  // Tooltip on device image for temperature devices
20815
21077
  // Decimal places for the % badge. Resolved at render time so it can be changed
20816
21078
  // without rebuilding the lib: this prop > window.MyIOUtils.percentDecimals > 2.
20817
- percentDecimals
21079
+ percentDecimals,
21080
+ // ED-1354: clique na coluna B1/B2/S (entityObject.equipmentIndicators) — ex.: abre a modal das bombas
21081
+ handleActionEquipment
20818
21082
  }) {
20819
21083
  const {
20820
21084
  entityId,
@@ -20863,7 +21127,9 @@ function renderCardComponentV5({
20863
21127
  excludeGroupsTotals,
20864
21128
  // Card já desenhado, telemetria (valor/status) ainda chegando → spinner no valor, sem selo,
20865
21129
  // status neutro (não marca offline nem pisca enquanto carrega)
20866
- dataLoading = false
21130
+ dataLoading = false,
21131
+ // ED-1354: indicadores B1/B2/S (bombas MOTOR + solenoide) no card do poço
21132
+ equipmentIndicators
20867
21133
  } = entityObject;
20868
21134
  const deviceStatus = dataLoading ? "loading" : rawDeviceStatus;
20869
21135
  const deviceType = deviceProfile || legacyDeviceType || "";
@@ -21018,7 +21284,7 @@ function renderCardComponentV5({
21018
21284
  };
21019
21285
  const isEnergyDevice2 = (deviceType2) => isEnergyDeviceType(deviceType2);
21020
21286
  const isTemperatureDevice2 = (deviceType2) => isTemperatureDeviceType(deviceType2);
21021
- const isTankDevice2 = deviceType === "TANK" || deviceType === "CAIXA_DAGUA";
21287
+ const isTankDevice2 = deviceType === "TANK" || deviceType === "CAIXA_DAGUA" || deviceType === "CISTERNA" || deviceType === "CISTERNA_ENTRADA";
21022
21288
  const percentageForDisplay = isTankDevice2 ? (waterPercentage || 0) * 100 : perc;
21023
21289
  const tankLevelCm = isTankDevice2 ? Number(waterLevel ?? val) : null;
21024
21290
  const _pctDecimals = resolvePercentDecimals(percentDecimals);
@@ -21454,6 +21720,13 @@ function renderCardComponentV5({
21454
21720
  `;
21455
21721
  container.innerHTML = cardHTML;
21456
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
+ }
21457
21730
  try {
21458
21731
  const _excl = typeof excludeGroupsTotals === "string" ? JSON.parse(excludeGroupsTotals) : excludeGroupsTotals;
21459
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));
@@ -27317,7 +27590,7 @@ var TOAST_TYPE_META = {
27317
27590
  warning: { icon: "\u26A0\uFE0F", title: "Aviso" },
27318
27591
  error: { icon: "\u{1F6AB}", title: "Erro" }
27319
27592
  };
27320
- function escapeHtml2(text2) {
27593
+ function escapeHtml3(text2) {
27321
27594
  const div = document.createElement("div");
27322
27595
  div.textContent = text2 == null ? "" : String(text2);
27323
27596
  return div.innerHTML;
@@ -27514,7 +27787,7 @@ var MyIOToast = (function() {
27514
27787
  InfoTooltip_default.show(expandBtn, {
27515
27788
  icon: meta.icon,
27516
27789
  title: meta.title,
27517
- content: escapeHtml2(fullMessage).replace(/\n/g, "<br>")
27790
+ content: escapeHtml3(fullMessage).replace(/\n/g, "<br>")
27518
27791
  });
27519
27792
  });
27520
27793
  toastEl.appendChild(expandBtn);
@@ -35758,7 +36031,7 @@ function paletteColor(base, index, dark) {
35758
36031
  }
35759
36032
  var defaultFormatValue = (v) => Number(v || 0).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
35760
36033
  var fmtPct = (pct) => `${pct.toLocaleString("pt-BR", { minimumFractionDigits: 0, maximumFractionDigits: 1 })}%`;
35761
- function escapeHtml3(s) {
36034
+ function escapeHtml4(s) {
35762
36035
  return String(s).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
35763
36036
  }
35764
36037
  function slugify2(s) {
@@ -35923,7 +36196,7 @@ function createParticipationChart(container, params) {
35923
36196
  content: `
35924
36197
  <div class="myio-info-tooltip__section" style="min-width:180px;">
35925
36198
  <div style="font-size:12px;line-height:1.6;">
35926
- <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>
35927
36200
  <div><strong>Participa\xE7\xE3o:</strong> ${fmtPct(pct)}</div>
35928
36201
  </div>
35929
36202
  </div>
@@ -41005,6 +41278,9 @@ var WaterTankModalView = class {
41005
41278
  * Get tank image URL based on level percentage (same logic as device card)
41006
41279
  */
41007
41280
  getTankImageUrl(percentage) {
41281
+ if (/^CISTERNA(_ENTRADA)?$/.test(String(this.config.params.deviceType || "").toUpperCase())) {
41282
+ return deviceIcons.CISTERNA;
41283
+ }
41008
41284
  if (percentage >= 70) {
41009
41285
  return "https://dashboard.myio-bas.com/api/images/public/3t6WVhMQJFsrKA8bSZmrngDsNPkZV7fq";
41010
41286
  } else if (percentage >= 40) {
@@ -41042,10 +41318,10 @@ var WaterTankModalView = class {
41042
41318
  */
41043
41319
  render() {
41044
41320
  const { params } = this.config;
41045
- const STYLE_ID18 = "myio-water-tank-modal-styles";
41046
- if (!document.getElementById(STYLE_ID18)) {
41321
+ const STYLE_ID20 = "myio-water-tank-modal-styles";
41322
+ if (!document.getElementById(STYLE_ID20)) {
41047
41323
  const style = document.createElement("style");
41048
- style.id = STYLE_ID18;
41324
+ style.id = STYLE_ID20;
41049
41325
  style.textContent = `
41050
41326
  @media (max-width: 640px) {
41051
41327
  .myio-water-tank-modal { width: 100vw !important; max-width: 100vw !important; max-height: 100vh !important; border-radius: 0 !important; }
@@ -41058,6 +41334,7 @@ var WaterTankModalView = class {
41058
41334
  `;
41059
41335
  document.head.appendChild(style);
41060
41336
  }
41337
+ if (params.equipmentIndicators?.length || params.headerActions?.length) ensureEquipmentIndicatorStyles();
41061
41338
  this.overlay = document.createElement("div");
41062
41339
  this.overlay.className = "myio-water-tank-modal-overlay";
41063
41340
  this.overlay.style.cssText = `
@@ -41121,6 +41398,7 @@ var WaterTankModalView = class {
41121
41398
  line-height: 2;
41122
41399
  ">\u{1F4A7} ${title}</h2>
41123
41400
  <div style="display: flex; gap: 4px; align-items: center;">
41401
+ ${this.renderHeaderActions()}
41124
41402
  <button class="myio-water-tank-modal-close" title="${this.i18n.close}" style="
41125
41403
  background: none;
41126
41404
  border: none;
@@ -41135,6 +41413,46 @@ var WaterTankModalView = class {
41135
41413
  </div>
41136
41414
  `;
41137
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
+ }
41138
41456
  /**
41139
41457
  * RFC-0107: Render modal body with new layout
41140
41458
  * Left side: Tank visualization with percentage
@@ -41293,6 +41611,7 @@ var WaterTankModalView = class {
41293
41611
  height: auto;
41294
41612
  filter: drop-shadow(0 4px 8px rgba(0,0,0,0.1));
41295
41613
  "/>
41614
+ ${this.renderEquipmentTiles()}
41296
41615
  <div style="
41297
41616
  font-size: 42px;
41298
41617
  font-weight: 700;
@@ -41755,6 +42074,17 @@ var WaterTankModalView = class {
41755
42074
  if (closeBtn) {
41756
42075
  closeBtn.addEventListener("click", () => this.config.onClose());
41757
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
+ });
41758
42088
  const exportBtn = this.modal.querySelector(".myio-water-tank-export-btn");
41759
42089
  if (exportBtn) {
41760
42090
  exportBtn.addEventListener("click", () => this.config.onExport());
@@ -42400,7 +42730,9 @@ var WaterTankModal = class {
42400
42730
  }
42401
42731
  dbg5("[WaterTankModal] Modal opened successfully");
42402
42732
  return {
42403
- 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)
42404
42736
  };
42405
42737
  } catch (error) {
42406
42738
  console.error("[WaterTankModal] Failed to show modal:", error);
@@ -50985,8 +51317,8 @@ var AnnotationsTab = class {
50985
51317
  */
50986
51318
  toggleTypeFilter(type) {
50987
51319
  if (type === "archived") {
50988
- const isActive = this.filters.statusList?.includes("archived") || false;
50989
- this.filters.statusList = isActive ? [] : ["archived"];
51320
+ const isActive2 = this.filters.statusList?.includes("archived") || false;
51321
+ this.filters.statusList = isActive2 ? [] : ["archived"];
50990
51322
  this.applyFilters();
50991
51323
  return;
50992
51324
  }
@@ -53659,24 +53991,24 @@ var BUILDING_ICON = `<svg xmlns="http://www.w3.org/2000/svg" width="14" height="
53659
53991
  function renderAlarmCard(alarm, _params) {
53660
53992
  const severityConfig = SEVERITY_CONFIG[alarm.severity];
53661
53993
  const stateConfig = STATE_CONFIG[alarm.state];
53662
- const isActive = isAlarmActive(alarm.state);
53994
+ const isActive2 = isAlarmActive(alarm.state);
53663
53995
  const firstSeenRelative = formatRelativeTimeShort(alarm.firstOccurrence);
53664
53996
  const lastSeenRelative = formatRelativeTimeShort(alarm.lastOccurrence);
53665
53997
  const isSelected = _params?.selected ?? false;
53666
53998
  const rawTitle = alarm.title || "Sem t\xEDtulo";
53667
53999
  const truncatedTitle = rawTitle.length > 42 ? rawTitle.substring(0, 42) + "\u2026" : rawTitle;
53668
- const safeTitle = escapeHtml4(truncatedTitle);
53669
- const safeTitleFull = escapeHtml4(rawTitle);
53670
- 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");
53671
54003
  const safeOccurrences = alarm.occurrenceCount || 1;
53672
54004
  const showCustomer = _params?.showCustomerName ?? true;
53673
54005
  const showDeviceBadge = _params?.showDeviceBadge ?? false;
53674
- const safeSource = escapeHtml4(alarm.source || "");
54006
+ const safeSource = escapeHtml5(alarm.source || "");
53675
54007
  const alarmTypes = _params?.alarmTypes ?? [];
53676
54008
  const typeChipsHtml = alarmTypes.length > 0 ? `<div class="alarm-card-type-scroll">
53677
54009
  <button class="alarm-type-scroll-btn alarm-type-scroll-btn--left" tabindex="-1" aria-hidden="true">&#8249;</button>
53678
54010
  <div class="alarm-card-type-list">${alarmTypes.map(
53679
- (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>`
53680
54012
  ).join("")}</div>
53681
54013
  <button class="alarm-type-scroll-btn alarm-type-scroll-btn--right" tabindex="-1" aria-hidden="true">&#8250;</button>
53682
54014
  </div>` : "";
@@ -53686,7 +54018,7 @@ function renderAlarmCard(alarm, _params) {
53686
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}">
53687
54019
  <header class="alarm-card-header">
53688
54020
  ${!hideSelect ? `<label class="alarm-card-checkbox-wrap" title="Selecionar para a\xE7\xE3o em lote" onclick="event.stopPropagation()">
53689
- <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" : ""}>
53690
54022
  </label>` : ""}
53691
54023
  ${showDeviceBadge && safeSource ? `<span class="alarm-card-device-badge" title="${safeSource}">${safeSource}</span>` : ""}
53692
54024
  <div class="alarm-card-badges">
@@ -53714,7 +54046,7 @@ function renderAlarmCard(alarm, _params) {
53714
54046
  </div>
53715
54047
  </div>
53716
54048
  <footer class="alarm-card-footer">
53717
- ${!_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>` : ""}
53718
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>` : ""}
53719
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>` : ""}
53720
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>` : ""}
@@ -53842,7 +54174,7 @@ function _attachAnnotationBadges(card, alarmId) {
53842
54174
  if (!addedAny) return;
53843
54175
  card.appendChild(container);
53844
54176
  }
53845
- function escapeHtml4(text2) {
54177
+ function escapeHtml5(text2) {
53846
54178
  const div = document.createElement("div");
53847
54179
  div.textContent = text2;
53848
54180
  return div.innerHTML;
@@ -55109,7 +55441,7 @@ function openAlarmDetailsModal(alarm, themeMode = "light", groupMode, onAction)
55109
55441
  }
55110
55442
  const showDevice = !isSeparado && devices.length > 0;
55111
55443
  const showAlarm = groupMode === "porDispositivo" && (alarm._groupAlarmIds?.length || 0) > 1;
55112
- const isActive = alarm.state === "OPEN" || alarm.state === "ESCALATED";
55444
+ const isActive2 = alarm.state === "OPEN" || alarm.state === "ESCALATED";
55113
55445
  const isClosed = alarm.state === "CLOSED";
55114
55446
  const occIndex = /* @__PURE__ */ new Map();
55115
55447
  occEvents().forEach((e, i) => occIndex.set(e, i + 1));
@@ -55158,7 +55490,7 @@ function openAlarmDetailsModal(alarm, themeMode = "light", groupMode, onAction)
55158
55490
  <td class="adm-rpt-cell adm-tl-action-cell">
55159
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>
55160
55492
  <div class="adm-tl-row-btns" data-row-btns>
55161
- ${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>` : ""}
55162
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>` : ""}
55163
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>` : ""}
55164
55496
  </div>` : ""}
@@ -63549,10 +63881,10 @@ ${this._formatFileSize(f.size)} \xB7 ${f.type || "arquivo"}`;
63549
63881
  // Styles
63550
63882
  // ==========================================================================
63551
63883
  injectStyles() {
63552
- const STYLE_ID18 = "myio-tickets-tab-styles";
63553
- if (document.getElementById(STYLE_ID18)) return;
63884
+ const STYLE_ID20 = "myio-tickets-tab-styles";
63885
+ if (document.getElementById(STYLE_ID20)) return;
63554
63886
  const style = document.createElement("style");
63555
- style.id = STYLE_ID18;
63887
+ style.id = STYLE_ID20;
63556
63888
  style.textContent = `
63557
63889
  /* ===== TicketsTab layout ===== */
63558
63890
  .ct-tab {
@@ -63935,6 +64267,171 @@ function createTicketsTab(config2) {
63935
64267
  return { destroy: () => tab.destroy() };
63936
64268
  }
63937
64269
 
64270
+ // src/components/premium-modals/settings/commercialCatalog.ts
64271
+ var DEFAULT_STORE_SEGMENTS = [
64272
+ {
64273
+ segment: "Conveni\xEAncia / Servi\xE7os",
64274
+ activities: [
64275
+ "Ag\xEAncias De Viagens",
64276
+ "Alimentos Especias",
64277
+ "Consertos",
64278
+ "Correio",
64279
+ "Educa\xE7\xE3o/Ensino",
64280
+ "Emp\xF3rios",
64281
+ "Farm\xE1cias E Drogarias",
64282
+ "Foto Revela\xE7\xE3o",
64283
+ "Lavanderia",
64284
+ "Lot\xE9rica",
64285
+ "Outros Servi\xE7os",
64286
+ "Pet Shop",
64287
+ "Servi\xE7os Automotivos",
64288
+ "Servi\xE7os Est\xE9ticos",
64289
+ "Servi\xE7os Financeiros",
64290
+ "Servi\xE7os Gr\xE1ficos",
64291
+ "Servi\xE7os M\xE9dicos(Cl\xEDnicas/Laborat\xF3rios)",
64292
+ "Servi\xE7os P\xFAblicos",
64293
+ "Tatuagem/Piercing",
64294
+ "Venda E Loca\xE7\xE3o De Ve\xEDculos"
64295
+ ]
64296
+ },
64297
+ {
64298
+ segment: "Entretenimento",
64299
+ activities: [
64300
+ "Arena Gamer",
64301
+ "Boliche",
64302
+ "Cinemas",
64303
+ "Outros(Museu,Espa\xE7o Cultural,Etc)",
64304
+ "Parques E Games"
64305
+ ]
64306
+ },
64307
+ {
64308
+ segment: "Lojas \xC2ncoras",
64309
+ activities: [
64310
+ "Academias",
64311
+ "Artigos Esportivos",
64312
+ "Centros Educacionais / Escolas / Faculdades / Universidades",
64313
+ "Constru\xE7\xE3o E Decora\xE7\xE3o",
64314
+ "Eletrodom\xE9sticos, Eletr\xF4nicos",
64315
+ "Hipermercado / Supermercado / Atacarejo",
64316
+ "Magazines E/Ou Utens\xEDlios Para O Lar E Conveni\xEAncia",
64317
+ "Moda",
64318
+ "Outros"
64319
+ ]
64320
+ },
64321
+ {
64322
+ segment: "Lojas Sat\xE9lites",
64323
+ activities: [
64324
+ "Acess\xF3rios",
64325
+ "Acess\xF3rios E Artigos Para Viagens",
64326
+ "Artigos Eletr\xF4nicos/Tecnologia Da Informa\xE7\xE3o(Ti)",
64327
+ "Brinquedos",
64328
+ "Caf\xE9s, Bares E Ch\xE1s",
64329
+ "Cal\xE7ados Esportivos",
64330
+ "Cal\xE7ados Feminimos",
64331
+ "Cal\xE7ados Geral",
64332
+ "Cal\xE7ados Infantis",
64333
+ "Cal\xE7ados Masculinos",
64334
+ "Cama/Mesa/Banho",
64335
+ "Colch\xF5es",
64336
+ "Docerias",
64337
+ "Fast-Food",
64338
+ "Livraria",
64339
+ "Moda Esportiva",
64340
+ "Moda Feminina",
64341
+ "Moda Geral",
64342
+ "Moda Infantil",
64343
+ "Moda \xCDntima E Roupas Para Dormir",
64344
+ "Moda Masculina",
64345
+ "Moda Praia",
64346
+ "Moda Unissex",
64347
+ "\xD3ticas",
64348
+ "Outros",
64349
+ "Perfumaria, Maquiagem E Cosm\xE9ticos",
64350
+ "Puericultura",
64351
+ "Relojoarias, Joalherias",
64352
+ "Restaurantes Com Servi\xE7os",
64353
+ "Restaurantes Sem Servi\xE7os",
64354
+ "Surfewear / Streetwear",
64355
+ "Telefonia Geral",
64356
+ "Utens\xEDlios P/ Lar, Acess\xF3rios P/ Decora\xE7\xE3o E Presentes"
64357
+ ]
64358
+ },
64359
+ {
64360
+ segment: "Mall E Merchandising",
64361
+ activities: [
64362
+ "Acess\xF3rios",
64363
+ "Alimenta\xE7\xE3o E Bebidas",
64364
+ "Antenas De Operadoras",
64365
+ "Artigos Esportivos",
64366
+ "Artigos Para O Lar",
64367
+ "Brinquedos",
64368
+ "Cal\xE7ados",
64369
+ "Conveni\xEAncia / Servi\xE7os",
64370
+ "Eletr\xF4nicos",
64371
+ "Eventos",
64372
+ "Geek",
64373
+ "Livraria",
64374
+ "M\xEDdia",
64375
+ "\xD3ticas",
64376
+ "Outros",
64377
+ "Papelaria",
64378
+ "Perfumaria, Maquiagem E Cosm\xE9ticos",
64379
+ "Relojoarias E Joalherias",
64380
+ "Telefonia E Acess\xF3rios",
64381
+ "Vending Machines",
64382
+ "Vestu\xE1rio"
64383
+ ]
64384
+ },
64385
+ {
64386
+ segment: "Megalojas",
64387
+ activities: [
64388
+ "Alimenta\xE7\xE3o E Bebidas",
64389
+ "Artigos Esportivos",
64390
+ "Brinquedos",
64391
+ "Centros Educacionais / Escolas / Faculdades / Universidades",
64392
+ "Constru\xE7\xE3o, Decora\xE7\xE3o",
64393
+ "Eletrodom\xE9sticos, Eletr\xF4nicos, Magazines E/Ou Utens. P/Lar",
64394
+ "Livrarias",
64395
+ "Magazines E/Ou Utens\xEDlios Para O Lar E Conveni\xEAncia",
64396
+ "Material De Escrit\xF3rio / Papelaria / Inform\xE1tica",
64397
+ "Moda",
64398
+ "Outros",
64399
+ "Puericultura"
64400
+ ]
64401
+ },
64402
+ {
64403
+ segment: "Semi-\xC2ncoras",
64404
+ activities: [
64405
+ "Academias",
64406
+ "Alimenta\xE7\xE3o E Bebidas",
64407
+ "Artigos Esportivos",
64408
+ "Brinquedos",
64409
+ "Centros Educacionais / Escolas / Faculdades / Universidades",
64410
+ "Eletrodom\xE9sticos, Eletr\xF4nicos, Magazines E/Ou Utens. P/Lar",
64411
+ "Livrarias",
64412
+ "Magazines E/Ou Utens\xEDlios Para O Lar E Conveni\xEAncia",
64413
+ "Material De Escrit\xF3rio / Papelaria / Inform\xE1tica",
64414
+ "Moda",
64415
+ "Outros"
64416
+ ]
64417
+ }
64418
+ ];
64419
+ async function loadStoreSegmentCatalog(source) {
64420
+ if (!source) return DEFAULT_STORE_SEGMENTS;
64421
+ try {
64422
+ const list = typeof source === "function" ? await source() : source;
64423
+ return Array.isArray(list) && list.length > 0 ? list : DEFAULT_STORE_SEGMENTS;
64424
+ } catch (err) {
64425
+ console.warn("[SettingsModal] segmentCatalog loader falhou \u2014 usando cat\xE1logo padr\xE3o:", err);
64426
+ return DEFAULT_STORE_SEGMENTS;
64427
+ }
64428
+ }
64429
+ function activitiesForSegment(catalog, segment, currentActivity) {
64430
+ const list = catalog.find((s) => s.segment === segment)?.activities ?? [];
64431
+ if (currentActivity && !list.includes(currentActivity)) return [...list, currentActivity];
64432
+ return list;
64433
+ }
64434
+
63938
64435
  // src/components/createInputDateRangePickerInsideDIV.ts
63939
64436
  var PREMIUM_STYLES = `
63940
64437
  .myio-daterange-wrapper {
@@ -64283,6 +64780,9 @@ var SettingsModalView = class _SettingsModalView {
64283
64780
  if (lastUpdatedEl) {
64284
64781
  lastUpdatedEl.textContent = formData.lastUpdatedTime ? this.formatTs(formData.lastUpdatedTime) : "\u2014";
64285
64782
  }
64783
+ if (this.isSuperAdmin()) {
64784
+ this.initCommercialFields(formData);
64785
+ }
64286
64786
  if (!this.config.gcdrDeviceId && formData.gcdrDeviceId) {
64287
64787
  this.config.gcdrDeviceId = formData.gcdrDeviceId;
64288
64788
  }
@@ -64916,6 +65416,7 @@ var SettingsModalView = class _SettingsModalView {
64916
65416
  </div>
64917
65417
 
64918
65418
  </div>
65419
+ ${this.isSuperAdmin() ? this.getCommercialFieldsHTML() : ""}
64919
65420
  </div>
64920
65421
 
64921
65422
  <!-- Central/gateway identity+telemetry \u2014 only for CentralSettingsModal (isGateway);
@@ -64933,6 +65434,71 @@ var SettingsModalView = class _SettingsModalView {
64933
65434
  </div>
64934
65435
  `;
64935
65436
  }
65437
+ /**
65438
+ * Campos comerciais — só @myio / superadmin (o bloco nem é renderizado para os demais,
65439
+ * então getFormData não envia essas chaves e o save não as sobrescreve).
65440
+ * Linha 1: ABL + Contrato (texto). Linha 2: Segmento → Atividade (selects em cascata,
65441
+ * opções preenchidas em initCommercialFields após carregar o catálogo).
65442
+ */
65443
+ getCommercialFieldsHTML() {
65444
+ const customerName = String(
65445
+ this.config.customerName || window.MyIOUtils?.customerName || ""
65446
+ ).trim();
65447
+ const escName = customerName.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
65448
+ return `
65449
+ <div class="commercial-block">
65450
+ <div class="commercial-title">Dados de Cadastro${escName ? ` <span class="commercial-sep">|</span> <span class="commercial-customer">${escName.toLocaleUpperCase("pt-BR")}</span>` : ""}</div>
65451
+ <div class="commercial-grid">
65452
+ <div class="commercial-field">
65453
+ <label class="identity-field-label" for="abl">ABL</label>
65454
+ <input type="text" id="abl" name="abl" class="identity-input" maxlength="50" placeholder="Ex.: 120,50 m\xB2">
65455
+ </div>
65456
+ <div class="commercial-field">
65457
+ <label class="identity-field-label" for="contract">Contrato</label>
65458
+ <input type="text" id="contract" name="contract" class="identity-input" maxlength="100" placeholder="N\xBA / identifica\xE7\xE3o do contrato">
65459
+ </div>
65460
+ <div class="commercial-field">
65461
+ <label class="identity-field-label" for="segment">Segmento</label>
65462
+ <select id="segment" name="segment" class="identity-input" disabled>
65463
+ <option value="">Carregando segmentos\u2026</option>
65464
+ </select>
65465
+ </div>
65466
+ <div class="commercial-field">
65467
+ <label class="identity-field-label" for="activity">Atividade</label>
65468
+ <select id="activity" name="activity" class="identity-input" disabled>
65469
+ <option value="">Selecione o segmento primeiro</option>
65470
+ </select>
65471
+ </div>
65472
+ </div>
65473
+ </div>
65474
+ `;
65475
+ }
65476
+ /** Carrega o catálogo de segmentos e liga a cascata Segmento → Atividade, restaurando os valores salvos. */
65477
+ async initCommercialFields(saved) {
65478
+ const segmentEl = this.modal.querySelector("#segment");
65479
+ const activityEl = this.modal.querySelector("#activity");
65480
+ if (!segmentEl || !activityEl) return;
65481
+ const esc9 = (s) => s.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
65482
+ const options = (values, selected, placeholder) => `<option value="">${placeholder}</option>` + values.map((v) => `<option value="${esc9(v)}"${v === selected ? " selected" : ""}>${esc9(v)}</option>`).join("");
65483
+ const catalog = await loadStoreSegmentCatalog(this.config.segmentCatalog);
65484
+ const savedSegment = String(saved.segment || "");
65485
+ const savedActivity = String(saved.activity || "");
65486
+ const segments = catalog.map((s) => s.segment);
65487
+ if (savedSegment && !segments.includes(savedSegment)) segments.push(savedSegment);
65488
+ segmentEl.innerHTML = options(segments, savedSegment, "Selecione\u2026");
65489
+ segmentEl.disabled = false;
65490
+ const fillActivities = (segment, selected) => {
65491
+ if (!segment) {
65492
+ activityEl.innerHTML = options([], "", "Selecione o segmento primeiro");
65493
+ activityEl.disabled = true;
65494
+ return;
65495
+ }
65496
+ activityEl.innerHTML = options(activitiesForSegment(catalog, segment, selected), selected, "Selecione\u2026");
65497
+ activityEl.disabled = false;
65498
+ };
65499
+ fillActivities(savedSegment, savedActivity);
65500
+ segmentEl.addEventListener("change", () => fillActivities(segmentEl.value, ""));
65501
+ }
64936
65502
  /** RFC-0171: Offset de Temperatura — sempre visível para domain=temperature; editável só para @myio.com.br */
64937
65503
  getTemperatureOffsetHTML() {
64938
65504
  const superAdmin = this.isSuperAdmin();
@@ -66616,6 +67182,49 @@ var SettingsModalView = class _SettingsModalView {
66616
67182
  cursor: default;
66617
67183
  }
66618
67184
 
67185
+ /* Campos comerciais (s\xF3 @myio / superadmin) */
67186
+ .commercial-block {
67187
+ margin-top: 14px;
67188
+ padding-top: 12px;
67189
+ border-top: 1px dashed #e5e7eb;
67190
+ }
67191
+ .commercial-title {
67192
+ display: flex;
67193
+ align-items: center;
67194
+ gap: 8px;
67195
+ font-size: 12px;
67196
+ font-weight: 700;
67197
+ color: #495057;
67198
+ margin-bottom: 8px;
67199
+ }
67200
+ .commercial-sep {
67201
+ color: #ced4da;
67202
+ font-weight: 400;
67203
+ }
67204
+ .commercial-customer {
67205
+ color: var(--myio-brand-700, #3e1a7d);
67206
+ letter-spacing: 0.3px;
67207
+ }
67208
+ .commercial-grid {
67209
+ display: grid;
67210
+ grid-template-columns: 1fr 1fr;
67211
+ gap: 10px 16px;
67212
+ }
67213
+ .commercial-field {
67214
+ display: flex;
67215
+ flex-direction: column;
67216
+ gap: 5px;
67217
+ }
67218
+ select.identity-input {
67219
+ height: 30px;
67220
+ cursor: pointer;
67221
+ }
67222
+ select.identity-input:disabled {
67223
+ background: #f8f9fa;
67224
+ color: #9ca3af;
67225
+ cursor: not-allowed;
67226
+ }
67227
+
66619
67228
  /* Col 3: date info block */
66620
67229
  .identity-dates-block {
66621
67230
  grid-column: 3;
@@ -67614,6 +68223,11 @@ var SettingsModalView = class _SettingsModalView {
67614
68223
  color: #6c757d;
67615
68224
  border-color: #373a40;
67616
68225
  }
68226
+ .theme-dark .commercial-block { border-top-color: #373a40; }
68227
+ .theme-dark .commercial-title { color: #ced4da; }
68228
+ .theme-dark .commercial-sep { color: #495057; }
68229
+ .theme-dark .commercial-customer { color: #c4b5fd; }
68230
+ .theme-dark select.identity-input:disabled { background: #1a1b1e; color: #6c757d; }
67617
68231
  .theme-dark .device-name-subtitle {
67618
68232
  color: #6c757d;
67619
68233
  }
@@ -68323,11 +68937,11 @@ function connectivityFieldsetHtml(data, l, language, errors) {
68323
68937
  </div>
68324
68938
  `;
68325
68939
  }
68326
- var STYLE_ID4 = "myio-central-settings-modal-styles";
68940
+ var STYLE_ID5 = "myio-central-settings-modal-styles";
68327
68941
  function injectStyles9() {
68328
- if (typeof document === "undefined" || document.getElementById(STYLE_ID4)) return;
68942
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID5)) return;
68329
68943
  const tag = document.createElement("style");
68330
- tag.id = STYLE_ID4;
68944
+ tag.id = STYLE_ID5;
68331
68945
  tag.textContent = `
68332
68946
  .myio-csettings__input{
68333
68947
  font:600 13px 'Nunito', system-ui, sans-serif;padding:6px 8px;border-radius:6px;
@@ -74317,14 +74931,14 @@ var DEFAULT_CONFIG_TEMPLATE2 = {
74317
74931
  };
74318
74932
 
74319
74933
  // src/components/footer/styles.ts
74320
- var STYLE_ID5 = "myio-footer-component-styles";
74934
+ var STYLE_ID6 = "myio-footer-component-styles";
74321
74935
  function areStylesInjected() {
74322
- return !!document.getElementById(STYLE_ID5);
74936
+ return !!document.getElementById(STYLE_ID6);
74323
74937
  }
74324
74938
  function injectStyles10() {
74325
74939
  if (areStylesInjected()) return;
74326
74940
  const style = document.createElement("style");
74327
- style.id = STYLE_ID5;
74941
+ style.id = STYLE_ID6;
74328
74942
  style.textContent = getStyles();
74329
74943
  document.head.appendChild(style);
74330
74944
  }
@@ -75642,10 +76256,10 @@ function render(container, modalId, state6) {
75642
76256
  <div class="alarm-list">
75643
76257
  ${state6.alarms.map((a) => `
75644
76258
  <div class="alarm-row">
75645
- <div class="alarm-title">${escapeHtml5(a.title || a.id)}</div>
75646
- <div class="alarm-meta">${escapeHtml5(a.customerName || "")}</div>
75647
- <div class="alarm-meta">${escapeHtml5(a.severity)}</div>
75648
- <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>
75649
76263
  <div class="alarm-meta">${formatDate2(a.lastOccurrence, state6.locale, true)}</div>
75650
76264
  </div>
75651
76265
  `).join("")}
@@ -75832,7 +76446,7 @@ function buildBars(data, order, colors2) {
75832
76446
  const pct = Math.round(value / maxVal * 100);
75833
76447
  return `
75834
76448
  <div class="bar-row">
75835
- <span class="bar-label">${escapeHtml5(String(key))}</span>
76449
+ <span class="bar-label">${escapeHtml6(String(key))}</span>
75836
76450
  <div class="bar-track"><div class="bar-fill" style="width:${pct}%"></div></div>
75837
76451
  <span class="bar-value">${value}</span>
75838
76452
  </div>
@@ -75862,7 +76476,7 @@ function toTime(value) {
75862
76476
  const parsed = new Date(value).getTime();
75863
76477
  return Number.isNaN(parsed) ? 0 : parsed;
75864
76478
  }
75865
- function escapeHtml5(text2) {
76479
+ function escapeHtml6(text2) {
75866
76480
  const div = document.createElement("div");
75867
76481
  div.textContent = text2 || "";
75868
76482
  return div.innerHTML;
@@ -76049,8 +76663,8 @@ function render2(container, modalId, state6) {
76049
76663
  </div>
76050
76664
  ${state6.devices.map((d) => `
76051
76665
  <div class="device-table-row">
76052
- <div class="col-name">${escapeHtml6(d.name)}</div>
76053
- <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>
76054
76668
  <div class="col-status">
76055
76669
  <span class="status-badge" style="background: ${STATUS_COLORS3[d.status] || "#6b7280"}20; color: ${STATUS_COLORS3[d.status] || "#6b7280"};">
76056
76670
  ${STATUS_LABELS5[d.status] || d.status}
@@ -76297,7 +76911,7 @@ function buildHorizontalBarChart(devices, metric, unit, colors2, getColor, inver
76297
76911
  const displayValue = metric === "availability" ? value.toFixed(1) : value.toFixed(metric === "mttr" ? 1 : 0);
76298
76912
  return `
76299
76913
  <div class="bar-row">
76300
- <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>
76301
76915
  <div class="bar-track">
76302
76916
  <div class="bar-fill" style="width:${pct}%; background:${color};"></div>
76303
76917
  </div>
@@ -76328,7 +76942,7 @@ function formatDate3(value, locale) {
76328
76942
  if (isNaN(d.getTime())) return "-";
76329
76943
  return d.toLocaleDateString(locale, { day: "2-digit", month: "2-digit", year: "numeric" });
76330
76944
  }
76331
- function escapeHtml6(text2) {
76945
+ function escapeHtml7(text2) {
76332
76946
  const div = document.createElement("div");
76333
76947
  div.textContent = text2 || "";
76334
76948
  return div.innerHTML;
@@ -78101,6 +78715,8 @@ var DefaultSettingsFetcher = class _DefaultSettingsFetcher {
78101
78715
  attributes.lastUpdatedTime = attr.value;
78102
78716
  } else if (attr.key === "gcdrDeviceId") {
78103
78717
  attributes.gcdrDeviceId = attr.value;
78718
+ } else if (["abl", "contract", "segment", "activity"].includes(attr.key)) {
78719
+ attributes[attr.key] = String(attr.value);
78104
78720
  }
78105
78721
  }
78106
78722
  }
@@ -78130,7 +78746,12 @@ var DefaultSettingsFetcher = class _DefaultSettingsFetcher {
78130
78746
  const stringFields = [
78131
78747
  "label",
78132
78748
  "floor",
78133
- "identifier"
78749
+ "identifier",
78750
+ // Campos comerciais (só @myio / superadmin no modal)
78751
+ "abl",
78752
+ "contract",
78753
+ "segment",
78754
+ "activity"
78134
78755
  ];
78135
78756
  for (const field of stringFields) {
78136
78757
  if (data[field] && typeof data[field] === "string") {
@@ -78240,6 +78861,7 @@ var SettingsController = class {
78240
78861
  superadmin: params.superadmin,
78241
78862
  userEmail: params.userEmail || window.MyIOUtils?.currentUserEmail || null,
78242
78863
  holdingAdmin: params.holdingAdmin ?? window.MyIOUtils?.HoldingAdmin ?? false,
78864
+ segmentCatalog: params.segmentCatalog,
78243
78865
  // RFC-0144: Pass enableAnnotationsOnboarding flag for onboarding control
78244
78866
  enableAnnotationsOnboarding: params.enableAnnotationsOnboarding ?? false,
78245
78867
  // RFC-0180: Raw device name + GCDR identifiers for Alarms tab
@@ -78563,6 +79185,12 @@ var SettingsController = class {
78563
79185
  if (formData.floor && formData.floor.length > 50) {
78564
79186
  errors.push("Floor must be 50 characters or less");
78565
79187
  }
79188
+ if (formData.abl && formData.abl.length > 50) {
79189
+ errors.push("ABL must be 50 characters or less");
79190
+ }
79191
+ if (formData.contract && formData.contract.length > 100) {
79192
+ errors.push("Contract must be 100 characters or less");
79193
+ }
78566
79194
  if (formData.storeNumber && formData.storeNumber.length > 20) {
78567
79195
  errors.push("Store number must be 20 characters or less");
78568
79196
  }
@@ -78616,6 +79244,247 @@ async function openDashboardPopupSettings(params) {
78616
79244
  }
78617
79245
  }
78618
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
+
78619
79488
  // src/utils/telemetryUtils.ts
78620
79489
  function detectTelemetryType(keys) {
78621
79490
  if (!keys) {
@@ -80273,7 +81142,7 @@ async function openDemandModal(params) {
80273
81142
 
80274
81143
  // src/components/premium-modals/dialog/styles.ts
80275
81144
  var FONT_LINK_ID = "myio-dialog-font-nunito";
80276
- var STYLE_ID6 = "myio-dialog-styles";
81145
+ var STYLE_ID8 = "myio-dialog-styles";
80277
81146
  function injectDialogStyles() {
80278
81147
  if (!document.getElementById(FONT_LINK_ID)) {
80279
81148
  const link = document.createElement("link");
@@ -80282,9 +81151,9 @@ function injectDialogStyles() {
80282
81151
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
80283
81152
  document.head.appendChild(link);
80284
81153
  }
80285
- if (document.getElementById(STYLE_ID6)) return;
81154
+ if (document.getElementById(STYLE_ID8)) return;
80286
81155
  const style = document.createElement("style");
80287
- style.id = STYLE_ID6;
81156
+ style.id = STYLE_ID8;
80288
81157
  style.textContent = `
80289
81158
  .myio-dialog-overlay {
80290
81159
  position: fixed;
@@ -80423,11 +81292,11 @@ function injectDialogStyles() {
80423
81292
  // src/components/premium-modals/dialog/openDialog.ts
80424
81293
  var BASE_Z_INDEX = 10500;
80425
81294
  var openCount = 0;
80426
- function escapeHtml7(value) {
81295
+ function escapeHtml8(value) {
80427
81296
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
80428
81297
  }
80429
81298
  function escapeMessage(value) {
80430
- return escapeHtml7(value).replace(/\n/g, "<br>");
81299
+ return escapeHtml8(value).replace(/\n/g, "<br>");
80431
81300
  }
80432
81301
  function cssWidth(width) {
80433
81302
  if (width == null) return "420px";
@@ -80452,7 +81321,7 @@ function openDialog(params) {
80452
81321
  overlay.style.zIndex = String(BASE_Z_INDEX + openCount);
80453
81322
  const buttonsHtml = params.buttons.map((btn, i) => {
80454
81323
  const variant = btn.variant ?? "secondary";
80455
- 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>`;
80456
81325
  }).join("");
80457
81326
  overlay.innerHTML = `
80458
81327
  <div class="myio-dialog${params.modifier ? ` ${params.modifier}` : ""}"
@@ -80462,7 +81331,7 @@ function openDialog(params) {
80462
81331
  <div class="myio-dialog__accent"></div>
80463
81332
  <div class="myio-dialog__header">
80464
81333
  ${params.icon ? `<span class="myio-dialog__icon" aria-hidden="true">${params.icon}</span>` : ""}
80465
- <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>
80466
81335
  ${dismissible ? `<button type="button" class="myio-dialog__close" aria-label="Fechar">\u2715</button>` : ""}
80467
81336
  </div>
80468
81337
  <p class="myio-dialog__message" id="${idBase}-message">${escapeMessage(params.message)}</p>
@@ -80554,11 +81423,11 @@ function openMessageDialog(params) {
80554
81423
  }
80555
81424
 
80556
81425
  // src/components/premium-modals/dialog/openGenericModal.ts
80557
- var STYLE_ID7 = "myio-genmodal-styles";
81426
+ var STYLE_ID9 = "myio-genmodal-styles";
80558
81427
  var FONT_LINK_ID2 = "myio-dialog-font-nunito";
80559
81428
  var BASE_Z_INDEX2 = 10600;
80560
81429
  var openCount2 = 0;
80561
- function escapeHtml8(value) {
81430
+ function escapeHtml9(value) {
80562
81431
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
80563
81432
  }
80564
81433
  function cssSize(v, fallback) {
@@ -80573,9 +81442,9 @@ function injectGenericModalStyles() {
80573
81442
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
80574
81443
  document.head.appendChild(link);
80575
81444
  }
80576
- if (document.getElementById(STYLE_ID7)) return;
81445
+ if (document.getElementById(STYLE_ID9)) return;
80577
81446
  const style = document.createElement("style");
80578
- style.id = STYLE_ID7;
81447
+ style.id = STYLE_ID9;
80579
81448
  style.textContent = `
80580
81449
  .myio-genmodal-overlay {
80581
81450
  position: fixed;
@@ -80708,17 +81577,17 @@ function openGenericModal(params) {
80708
81577
  overlay.style.zIndex = String(BASE_Z_INDEX2 + openCount2);
80709
81578
  const buttonsHtml = buttons.map((btn, i) => {
80710
81579
  const variant = btn.variant ?? "secondary";
80711
- 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>`;
80712
81581
  }).join("");
80713
81582
  overlay.innerHTML = `
80714
- <div class="myio-genmodal${params.className ? ` ${escapeHtml8(params.className)}` : ""}"
81583
+ <div class="myio-genmodal${params.className ? ` ${escapeHtml9(params.className)}` : ""}"
80715
81584
  role="dialog" aria-modal="true"
80716
81585
  aria-labelledby="${idBase}-title"
80717
81586
  style="width:${cssSize(params.width, "560px")}">
80718
81587
  <div class="myio-genmodal__accent"></div>
80719
81588
  <div class="myio-genmodal__header">
80720
81589
  ${params.icon ? `<span class="myio-genmodal__icon" aria-hidden="true">${params.icon}</span>` : ""}
80721
- <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>
80722
81591
  ${dismissible ? `<button type="button" class="myio-genmodal__close" aria-label="Fechar">\u2715</button>` : ""}
80723
81592
  </div>
80724
81593
  <div class="myio-genmodal__body" id="${idBase}-body" style="max-height:${cssSize(params.bodyMaxHeight, "70vh")}"></div>
@@ -80956,7 +81825,7 @@ function telemetriesInCatalogOrder(keys) {
80956
81825
 
80957
81826
  // src/utils/reports/demand/period.ts
80958
81827
  var SP_OFFSET_MS2 = -3 * 36e5;
80959
- var DAY_MS = 864e5;
81828
+ var DAY_MS2 = 864e5;
80960
81829
  var END_TOLERANCE_MS = 5 * 6e4;
80961
81830
  var MIN_PERIOD_START = "2019-03-01";
80962
81831
  var MIN_PERIOD_START_MS = Date.UTC(2019, 2, 1) - SP_OFFSET_MS2;
@@ -81008,7 +81877,7 @@ function localMidnightOf(ms) {
81008
81877
  }
81009
81878
  function bucketCount(start, end, resolution) {
81010
81879
  if (!(end > start)) return 0;
81011
- 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;
81012
81881
  return Math.ceil((end - start) / RESOLUTION_BY_ID[resolution].ms);
81013
81882
  }
81014
81883
  function finestFittingResolution(range, limits) {
@@ -81016,7 +81885,7 @@ function finestFittingResolution(range, limits) {
81016
81885
  const len = range.end - range.start;
81017
81886
  return RESOLUTIONS.find((r) => {
81018
81887
  const d = limits.maxDaysByResolution[r.id];
81019
- return d != null && len <= d * DAY_MS;
81888
+ return d != null && len <= d * DAY_MS2;
81020
81889
  })?.id ?? null;
81021
81890
  }
81022
81891
  function maxPeriodDays(resolution, limits) {
@@ -81030,7 +81899,7 @@ function periodErrors(range, resolution, now, limits = null) {
81030
81899
  if (range.start > now) errs.push("O in\xEDcio est\xE1 no futuro.");
81031
81900
  if (range.end > now + END_TOLERANCE_MS) errs.push("O fim n\xE3o pode estar no futuro.");
81032
81901
  const maxDays = maxPeriodDays(resolution, limits);
81033
- if (maxDays != null && range.end - range.start > maxDays * DAY_MS) {
81902
+ if (maxDays != null && range.end - range.start > maxDays * DAY_MS2) {
81034
81903
  errs.push(`Com intervalos de ${RESOLUTION_BY_ID[resolution].label}, o per\xEDodo m\xE1ximo \xE9 ${maxDays} dia(s).`);
81035
81904
  }
81036
81905
  if (resolution === "1d" && !isLocalMidnight(range.start)) {
@@ -91753,13 +92622,13 @@ var COLUMN_SUMMARY_CSS = `
91753
92622
  var _cssInjected2 = false;
91754
92623
  function injectCSS10() {
91755
92624
  if (_cssInjected2 || typeof document === "undefined") return;
91756
- const STYLE_ID18 = "myio-column-summary-tooltip-css";
91757
- if (document.getElementById(STYLE_ID18)) {
92625
+ const STYLE_ID20 = "myio-column-summary-tooltip-css";
92626
+ if (document.getElementById(STYLE_ID20)) {
91758
92627
  _cssInjected2 = true;
91759
92628
  return;
91760
92629
  }
91761
92630
  const style = document.createElement("style");
91762
- style.id = STYLE_ID18;
92631
+ style.id = STYLE_ID20;
91763
92632
  style.textContent = COLUMN_SUMMARY_CSS;
91764
92633
  document.head.appendChild(style);
91765
92634
  _cssInjected2 = true;
@@ -99570,12 +100439,12 @@ function createConsumptionChartWidget(config2) {
99570
100439
  }
99571
100440
 
99572
100441
  // src/components/tooltips/goals-bar-tooltip/createGoalsBarTooltip.ts
99573
- var STYLE_ID8 = "myio-goals-bar-tooltip-styles";
100442
+ var STYLE_ID10 = "myio-goals-bar-tooltip-styles";
99574
100443
  var DEFAULT_ACCENT = "#6c5ce7";
99575
100444
  function injectStyles12(doc) {
99576
- if (doc.getElementById(STYLE_ID8)) return;
100445
+ if (doc.getElementById(STYLE_ID10)) return;
99577
100446
  const s = doc.createElement("style");
99578
- s.id = STYLE_ID8;
100447
+ s.id = STYLE_ID10;
99579
100448
  s.textContent = `
99580
100449
  .myio-gbt {
99581
100450
  position: fixed;
@@ -100684,11 +101553,11 @@ function _rerenderFromCache() {
100684
101553
  const { labels, totals, goalLine, prevTotals, domain } = _lastRender;
100685
101554
  _renderChart(canvas, labels, totals, goalLine, domain, prevTotals);
100686
101555
  }
100687
- var STYLE_ID9 = "myio-goals-modal-v2-styles";
101556
+ var STYLE_ID11 = "myio-goals-modal-v2-styles";
100688
101557
  function _injectStyles(topDoc) {
100689
- if (topDoc.getElementById(STYLE_ID9)) return;
101558
+ if (topDoc.getElementById(STYLE_ID11)) return;
100690
101559
  const s = topDoc.createElement("style");
100691
- s.id = STYLE_ID9;
101560
+ s.id = STYLE_ID11;
100692
101561
  s.textContent = `
100693
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;}
100694
101563
  .gm-overlay.show{opacity:1;}
@@ -103539,7 +104408,7 @@ function createMyIOTheme(settings, mode) {
103539
104408
  // src/components/settings-hub/openSettingsHubModal.ts
103540
104409
  var ROUTE_DELAY_MS = 250;
103541
104410
  var MODAL_ID2 = "myio-conf-picker";
103542
- var STYLE_ID10 = "myio-conf-picker-styles";
104411
+ var STYLE_ID12 = "myio-conf-picker-styles";
103543
104412
  var HUB_OPTIONS = [
103544
104413
  {
103545
104414
  action: "temperature",
@@ -103730,7 +104599,7 @@ var HUB_CSS = `
103730
104599
  color: var(--myio-brand-700, #7B2FF7);
103731
104600
  }
103732
104601
  `;
103733
- function escapeHtml9(value) {
104602
+ function escapeHtml10(value) {
103734
104603
  return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
103735
104604
  }
103736
104605
  function resolveTopDocument() {
@@ -103750,9 +104619,9 @@ function resolveHubThemeVars(explicit) {
103750
104619
  function openSettingsHubModal(options) {
103751
104620
  const { customerName = "", isSuperAdmin: isSuperAdmin2 = false, handlers } = options;
103752
104621
  const doc = options.targetDocument || resolveTopDocument();
103753
- if (!doc.getElementById(STYLE_ID10)) {
104622
+ if (!doc.getElementById(STYLE_ID12)) {
103754
104623
  const style = doc.createElement("style");
103755
- style.id = STYLE_ID10;
104624
+ style.id = STYLE_ID12;
103756
104625
  style.textContent = HUB_CSS;
103757
104626
  doc.head.appendChild(style);
103758
104627
  }
@@ -103777,7 +104646,7 @@ function openSettingsHubModal(options) {
103777
104646
  <div class="myio-conf-picker__overlay"></div>
103778
104647
  <div class="myio-conf-picker__content">
103779
104648
  <div class="myio-conf-picker__header">
103780
- <h3>\u2699\uFE0F Configura\xE7\xF5es${customerName ? ` \u2014 ${escapeHtml9(customerName)}` : ""}</h3>
104649
+ <h3>\u2699\uFE0F Configura\xE7\xF5es${customerName ? ` \u2014 ${escapeHtml10(customerName)}` : ""}</h3>
103781
104650
  <button class="myio-conf-picker__close" aria-label="Fechar">&times;</button>
103782
104651
  </div>
103783
104652
  <div class="myio-conf-picker__body">${cardsHtml}
@@ -104972,7 +105841,7 @@ function createTariffApiAdapter(client, opts) {
104972
105841
 
104973
105842
  // src/components/pricing-panel/openPricingPanel.ts
104974
105843
  var MODAL_ID3 = "myio-pricing-panel";
104975
- function escapeHtml10(value) {
105844
+ function escapeHtml11(value) {
104976
105845
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
104977
105846
  }
104978
105847
  function resolveTopDocument2() {
@@ -105127,7 +105996,7 @@ function openPricingPanel(params) {
105127
105996
  }
105128
105997
  const initDomain = params.domain || "energy";
105129
105998
  const initCategory = params.category || "lojas";
105130
- 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("");
105131
106000
  modal.innerHTML = `
105132
106001
  <div class="myio-pricing__overlay"></div>
105133
106002
  <div class="myio-pricing__content">
@@ -105342,9 +106211,9 @@ function openPricingPanel(params) {
105342
106211
  const pushAudit = (rec) => {
105343
106212
  if (rec) auditLog = [rec, ...auditLog];
105344
106213
  };
105345
- 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(
105346
106215
  DOMAIN_LABEL[domain]
105347
- )} \xB7 ${escapeHtml10(CATEGORY_LABEL[category])}</span>`;
106216
+ )} \xB7 ${escapeHtml11(CATEGORY_LABEL[category])}</span>`;
105348
106217
  const renderList2 = () => {
105349
106218
  const customerId = customerSel.value;
105350
106219
  const rows = entries.filter((e) => e.customerId === customerId).sort((a, b) => {
@@ -105357,15 +106226,15 @@ function openPricingPanel(params) {
105357
106226
  const boundsKey = b ? `${b.start}__${b.end}` : "";
105358
106227
  return `
105359
106228
  <li class="myio-pricing__item">
105360
- <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(
105361
106230
  formatPeriodLabel(e)
105362
106231
  )}</span>
105363
- <span class="myio-pricing__item-price">${escapeHtml10(formatBRL2(e.pricePerKwh))} ${escapeHtml10(
106232
+ <span class="myio-pricing__item-price">${escapeHtml11(formatBRL2(e.pricePerKwh))} ${escapeHtml11(
105364
106233
  unitLabel(e.domain)
105365
106234
  )}</span>
105366
- <button class="myio-pricing__remove" data-remove="${escapeHtml10(e.domain)}|${escapeHtml10(
106235
+ <button class="myio-pricing__remove" data-remove="${escapeHtml11(e.domain)}|${escapeHtml11(
105367
106236
  e.category
105368
- )}|${escapeHtml10(boundsKey)}" aria-label="Remover" type="button">\u2715</button>
106237
+ )}|${escapeHtml11(boundsKey)}" aria-label="Remover" type="button">\u2715</button>
105369
106238
  </li>`;
105370
106239
  }).join("");
105371
106240
  emptyEl.style.display = rows.length ? "none" : "";
@@ -105464,8 +106333,8 @@ function openPricingPanel(params) {
105464
106333
  kpiEl.innerHTML = cards.map(
105465
106334
  (c) => `
105466
106335
  <div class="myio-pricing__kpi">
105467
- <div class="myio-pricing__kpi-value">${escapeHtml10(c.value)}</div>
105468
- <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>
105469
106338
  </div>`
105470
106339
  ).join("");
105471
106340
  renderReport();
@@ -105484,11 +106353,11 @@ function openPricingPanel(params) {
105484
106353
  reportBody.innerHTML = rows.length ? rows.map(
105485
106354
  (e) => `
105486
106355
  <tr>
105487
- <td>${escapeHtml10(customerTitle(e.customerId))}</td>
105488
- <td>${escapeHtml10(DOMAIN_LABEL[e.domain])}</td>
105489
- <td>${escapeHtml10(CATEGORY_LABEL[e.category])}</td>
105490
- <td>${escapeHtml10(formatPeriodLabel(e))}</td>
105491
- <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>
105492
106361
  </tr>`
105493
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>`;
105494
106363
  }
@@ -105498,15 +106367,15 @@ function openPricingPanel(params) {
105498
106367
  return `
105499
106368
  <li class="myio-pricing__history-item">
105500
106369
  <div class="myio-pricing__history-head">
105501
- <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(
105502
106371
  rec.action
105503
106372
  )}</span>
105504
106373
  ${badge(rec.domain, rec.category)}
105505
- <span>${escapeHtml10(rec.periodLabel)}${escapeHtml10(priceInfo)}</span>
106374
+ <span>${escapeHtml11(rec.periodLabel)}${escapeHtml11(priceInfo)}</span>
105506
106375
  </div>
105507
- <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(
105508
106377
  rec.by || "\u2014"
105509
- )} \xB7 ${escapeHtml10(fmtTimestamp(rec.at))}</div>
106378
+ )} \xB7 ${escapeHtml11(fmtTimestamp(rec.at))}</div>
105510
106379
  </li>`;
105511
106380
  }).join("");
105512
106381
  historyEmpty.style.display = auditLog.length ? "none" : "";
@@ -109084,11 +109953,11 @@ function renderModal6(container, state6, modalId, t, error) {
109084
109953
  setupEventListeners5(container, state6, modalId, t);
109085
109954
  }
109086
109955
  function renderStepIndicator(step, label, currentStep, colors2) {
109087
- const isActive = step === currentStep;
109956
+ const isActive2 = step === currentStep;
109088
109957
  const isCompleted = step < currentStep;
109089
- const bgColor = isActive ? MYIO_PURPLE : isCompleted ? colors2.success : colors2.cardBg;
109090
- const textColor = isActive || isCompleted ? "white" : colors2.textMuted;
109091
- 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;
109092
109961
  return `
109093
109962
  <div style="
109094
109963
  display: flex; align-items: center; gap: 8px;
@@ -109128,10 +109997,10 @@ function renderStep1(state6, modalId, colors2, t) {
109128
109997
  const { field: sortField, order: sortOrder } = state6.customerSort;
109129
109998
  const sortedCustomers = sortCustomers(state6.customers, sortField, sortOrder, state6.customerNameMap);
109130
109999
  const sortIcon = sortOrder === "asc" ? "\u2191" : "\u2193";
109131
- const btnStyle = (isActive) => `
109132
- background: ${isActive ? MYIO_PURPLE : colors2.cardBg};
109133
- color: ${isActive ? "white" : colors2.text};
109134
- 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};
109135
110004
  padding: 6px 12px; border-radius: 6px; cursor: pointer;
109136
110005
  font-size: 12px; font-weight: 500; display: flex; align-items: center; gap: 4px;
109137
110006
  `;
@@ -109356,16 +110225,16 @@ function renderStep2(state6, modalId, colors2, t) {
109356
110225
  const gridHeight = state6.isMaximized ? "calc(100vh - 340px)" : "360px";
109357
110226
  const hasActiveFilters = filterTypes.length > 0 || filterDeviceTypes.length > 0 || filterDeviceProfiles.length > 0 || filterStatuses.length > 0 || filterTelemetryKeys.length > 0;
109358
110227
  const renderSortableHeader = (col2, label, field, width) => {
109359
- const isActive = sortField === field;
109360
- const arrow = isActive ? sortOrder === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
110228
+ const isActive2 = sortField === field;
110229
+ const arrow = isActive2 ? sortOrder === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
109361
110230
  return `
109362
110231
  <div id="${modalId}-sort-col-${col2}" data-sort-field="${field}" style="
109363
110232
  width: ${width}px; padding: 0 6px; display: flex; align-items: center; justify-content: space-between;
109364
110233
  border-right: 1px solid ${colors2.border}; cursor: pointer; user-select: none;
109365
- ${isActive ? `background: rgba(62,26,125,0.1);` : ""}
110234
+ ${isActive2 ? `background: rgba(62,26,125,0.1);` : ""}
109366
110235
  ">
109367
110236
  <span>${label}</span>
109368
- <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>
109369
110238
  </div>
109370
110239
  `;
109371
110240
  };
@@ -109648,10 +110517,10 @@ function renderStep2(state6, modalId, colors2, t) {
109648
110517
  });
109649
110518
  const colSpan = multiCol ? 16 : 15;
109650
110519
  const cfSortHeader = (field, label, rowspan = 1, extraStyle = "") => {
109651
- const isActive = state6.checkFixSort.field === field;
109652
- const arrow = isActive ? state6.checkFixSort.order === "asc" ? "\u25B2" : "\u25BC" : "\u25BD";
109653
- 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);` : ""}">
109654
- <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>
109655
110524
  </th>`;
109656
110525
  };
109657
110526
  const allDomains = [...new Set(state6.checkFixReport.records.map((r) => r.domain || "null"))].sort();
@@ -115925,9 +116794,9 @@ function openMyioGcdrLoginModal(options) {
115925
116794
  }
115926
116795
 
115927
116796
  // src/components/img-gallery/ScrollableTabs.ts
115928
- var STYLE_ID11 = "myio-tabs-styles";
116797
+ var STYLE_ID13 = "myio-tabs-styles";
115929
116798
  var FONT_LINK_ID3 = "myio-dialog-font-nunito";
115930
- function escapeHtml11(value) {
116799
+ function escapeHtml12(value) {
115931
116800
  return String(value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
115932
116801
  }
115933
116802
  function injectStyles13() {
@@ -115938,9 +116807,9 @@ function injectStyles13() {
115938
116807
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
115939
116808
  document.head.appendChild(link);
115940
116809
  }
115941
- if (document.getElementById(STYLE_ID11)) return;
116810
+ if (document.getElementById(STYLE_ID13)) return;
115942
116811
  const style = document.createElement("style");
115943
- style.id = STYLE_ID11;
116812
+ style.id = STYLE_ID13;
115944
116813
  style.textContent = `
115945
116814
  .myio-tabs {
115946
116815
  display: flex;
@@ -116041,10 +116910,10 @@ function createScrollableTabs(options) {
116041
116910
  root.appendChild(left);
116042
116911
  root.appendChild(scroll);
116043
116912
  root.appendChild(right);
116044
- function styleTab(btn, isActive) {
116045
- btn.classList.toggle("myio-tabs__tab--active", isActive);
116046
- btn.setAttribute("aria-selected", isActive ? "true" : "false");
116047
- 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) {
116048
116917
  btn.style.background = accent;
116049
116918
  btn.style.color = "#fff";
116050
116919
  btn.style.borderColor = accent;
@@ -116063,7 +116932,7 @@ function createScrollableTabs(options) {
116063
116932
  btn.setAttribute("role", "tab");
116064
116933
  btn.dataset.key = t.key;
116065
116934
  if (t.disabled) btn.disabled = true;
116066
- 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>`;
116067
116936
  styleTab(btn, t.key === active);
116068
116937
  btn.addEventListener("click", () => {
116069
116938
  if (t.disabled || t.key === active) return;
@@ -116148,9 +117017,9 @@ function createScrollableTabs(options) {
116148
117017
  }
116149
117018
 
116150
117019
  // src/components/img-gallery/ImgGallery.ts
116151
- var STYLE_ID12 = "myio-gallery-styles";
117020
+ var STYLE_ID14 = "myio-gallery-styles";
116152
117021
  var FONT_LINK_ID4 = "myio-dialog-font-nunito";
116153
- function escapeHtml12(value) {
117022
+ function escapeHtml13(value) {
116154
117023
  return String(value == null ? "" : value).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
116155
117024
  }
116156
117025
  var PRM = () => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
@@ -116162,9 +117031,9 @@ function injectStyles14() {
116162
117031
  link.href = "https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap";
116163
117032
  document.head.appendChild(link);
116164
117033
  }
116165
- if (document.getElementById(STYLE_ID12)) return;
117034
+ if (document.getElementById(STYLE_ID14)) return;
116166
117035
  const style = document.createElement("style");
116167
- style.id = STYLE_ID12;
117036
+ style.id = STYLE_ID14;
116168
117037
  style.textContent = `
116169
117038
  .myio-gallery {
116170
117039
  font-family: 'Nunito', system-ui, sans-serif;
@@ -116374,10 +117243,10 @@ function createImgGallery(options) {
116374
117243
  root.appendChild(grid);
116375
117244
  function detailsHtml(img) {
116376
117245
  const lines = [];
116377
- if (img.filename) lines.push(`<span title="${escapeHtml12(img.filename)}">${escapeHtml12(img.filename)}</span>`);
116378
- 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>`);
116379
117248
  const dims = typeof img.width === "number" && typeof img.height === "number" ? `${img.width} \xD7 ${img.height}px` : "";
116380
- lines.push(`<span data-dims>${escapeHtml12(dims)}</span>`);
117249
+ lines.push(`<span data-dims>${escapeHtml13(dims)}</span>`);
116381
117250
  return lines.join("");
116382
117251
  }
116383
117252
  function renderDescription(body, img, index) {
@@ -123591,10 +124460,10 @@ var MenuView = class {
123591
124460
  </div>
123592
124461
  <div class="myio-unified-column-options">
123593
124462
  ${tab.contexts.map((ctx) => {
123594
- const isActive = isActiveTab && ctx.id === currentContextId;
124463
+ const isActive2 = isActiveTab && ctx.id === currentContextId;
123595
124464
  return `
123596
124465
  <button
123597
- class="myio-unified-option ${tab.id} ${isActive ? "is-active" : ""}"
124466
+ class="myio-unified-option ${tab.id} ${isActive2 ? "is-active" : ""}"
123598
124467
  data-tab-id="${tab.id}"
123599
124468
  data-context-id="${ctx.id}"
123600
124469
  data-target="${ctx.target}"
@@ -123617,20 +124486,20 @@ var MenuView = class {
123617
124486
  * Only active tab shows context detail, others show only domain label
123618
124487
  */
123619
124488
  buildTabHTML(tab) {
123620
- const isActive = tab.id === this.activeTabId;
123621
- const label = this.getTabLabel(tab.id, isActive);
124489
+ const isActive2 = tab.id === this.activeTabId;
124490
+ const label = this.getTabLabel(tab.id, isActive2);
123622
124491
  return `
123623
124492
  <button
123624
124493
  id="menuTab_${tab.id}"
123625
- class="tab ${isActive ? "is-active" : ""}"
124494
+ class="tab ${isActive2 ? "is-active" : ""}"
123626
124495
  data-tab-id="${tab.id}"
123627
124496
  role="tab"
123628
- aria-selected="${isActive}"
124497
+ aria-selected="${isActive2}"
123629
124498
  aria-controls="menuContextModal_${tab.id}"
123630
124499
  >
123631
124500
  <span class="ico">${tab.icon}</span>
123632
124501
  <span class="tab-label">${label}</span>
123633
- ${isActive ? '<span class="dropdown-arrow">\u25BC</span>' : ""}
124502
+ ${isActive2 ? '<span class="dropdown-arrow">\u25BC</span>' : ""}
123634
124503
  </button>
123635
124504
  `;
123636
124505
  }
@@ -123639,10 +124508,10 @@ var MenuView = class {
123639
124508
  * Active tab: "Domain: Context" (e.g., "Energia: Equipamentos")
123640
124509
  * Inactive tab: "Domain" only (e.g., "Agua")
123641
124510
  */
123642
- getTabLabel(tabId, isActive) {
124511
+ getTabLabel(tabId, isActive2) {
123643
124512
  const tab = this.tabs.find((t) => t.id === tabId);
123644
124513
  if (!tab) return "";
123645
- if (isActive) {
124514
+ if (isActive2) {
123646
124515
  const currentContextId = this.contextsByTab.get(tabId) ?? tab.defaultContext ?? tab.contexts[0]?.id;
123647
124516
  const currentContext = tab.contexts.find((c) => c.id === currentContextId);
123648
124517
  return currentContext ? `${tab.label}: ${currentContext.title}` : tab.label;
@@ -123654,20 +124523,20 @@ var MenuView = class {
123654
124523
  */
123655
124524
  updateAllTabLabels() {
123656
124525
  this.tabs.forEach((tab) => {
123657
- const isActive = tab.id === this.activeTabId;
124526
+ const isActive2 = tab.id === this.activeTabId;
123658
124527
  const tabEl = this.root.querySelector(`#menuTab_${tab.id}`);
123659
124528
  if (!tabEl) return;
123660
124529
  const labelEl = tabEl.querySelector(".tab-label");
123661
124530
  if (labelEl) {
123662
- labelEl.textContent = this.getTabLabel(tab.id, isActive);
124531
+ labelEl.textContent = this.getTabLabel(tab.id, isActive2);
123663
124532
  }
123664
124533
  const arrowEl = tabEl.querySelector(".dropdown-arrow");
123665
- if (isActive && !arrowEl) {
124534
+ if (isActive2 && !arrowEl) {
123666
124535
  const arrow = document.createElement("span");
123667
124536
  arrow.className = "dropdown-arrow";
123668
124537
  arrow.textContent = "\u25BC";
123669
124538
  tabEl.appendChild(arrow);
123670
- } else if (!isActive && arrowEl) {
124539
+ } else if (!isActive2 && arrowEl) {
123671
124540
  arrowEl.remove();
123672
124541
  }
123673
124542
  });
@@ -123701,10 +124570,10 @@ var MenuView = class {
123701
124570
  /**
123702
124571
  * Build a single context option HTML
123703
124572
  */
123704
- buildContextOptionHTML(tab, ctx, isActive) {
124573
+ buildContextOptionHTML(tab, ctx, isActive2) {
123705
124574
  return `
123706
124575
  <button
123707
- class="myio-menu-context-option ${tab.id} ${isActive ? "is-active" : ""}"
124576
+ class="myio-menu-context-option ${tab.id} ${isActive2 ? "is-active" : ""}"
123708
124577
  data-tab-id="${tab.id}"
123709
124578
  data-context-id="${ctx.id}"
123710
124579
  data-target="${ctx.target}"
@@ -123763,13 +124632,13 @@ var MenuView = class {
123763
124632
  * Build Mobile Tab HTML (for mobile drawer)
123764
124633
  */
123765
124634
  buildMobileTabHTML(tab) {
123766
- const isActive = tab.id === this.activeTabId;
124635
+ const isActive2 = tab.id === this.activeTabId;
123767
124636
  const currentContextId = this.contextsByTab.get(tab.id) ?? tab.defaultContext ?? tab.contexts[0]?.id;
123768
124637
  const currentContext = tab.contexts.find((c) => c.id === currentContextId);
123769
124638
  const contextTitle = currentContext ? currentContext.title : "";
123770
124639
  return `
123771
124640
  <button
123772
- class="tab ${isActive ? "is-active" : ""}"
124641
+ class="tab ${isActive2 ? "is-active" : ""}"
123773
124642
  data-tab-id="${tab.id}"
123774
124643
  data-mobile-tab="true"
123775
124644
  >
@@ -124374,8 +125243,8 @@ var MenuView = class {
124374
125243
  const contextId = el2.dataset.contextId;
124375
125244
  const currentContextId = this.contextsByTab.get(tabId);
124376
125245
  const isActiveTab = tabId === this.activeTabId;
124377
- const isActive = isActiveTab && contextId === currentContextId;
124378
- el2.classList.toggle("is-active", isActive);
125246
+ const isActive2 = isActiveTab && contextId === currentContextId;
125247
+ el2.classList.toggle("is-active", isActive2);
124379
125248
  });
124380
125249
  this.root.querySelectorAll(".myio-unified-column").forEach((col2) => {
124381
125250
  const tabId = col2.classList.contains("energy") ? "energy" : col2.classList.contains("water") ? "water" : col2.classList.contains("temperature") ? "temperature" : "";
@@ -130883,7 +131752,7 @@ function createCustomerCardV1(params) {
130883
131752
  }
130884
131753
 
130885
131754
  // src/components/cards/customer-goals/v1.0.0/styles.ts
130886
- var STYLE_ID13 = "myio-customer-goals-card-css";
131755
+ var STYLE_ID15 = "myio-customer-goals-card-css";
130887
131756
  var CSS4 = `
130888
131757
  .myio-cgc{
130889
131758
  --cgc-surface:#ffffff;
@@ -130984,9 +131853,9 @@ var CSS4 = `
130984
131853
  `;
130985
131854
  function injectCustomerGoalsCardStyles() {
130986
131855
  if (typeof document === "undefined") return;
130987
- if (document.getElementById(STYLE_ID13)) return;
131856
+ if (document.getElementById(STYLE_ID15)) return;
130988
131857
  const tag = document.createElement("style");
130989
- tag.id = STYLE_ID13;
131858
+ tag.id = STYLE_ID15;
130990
131859
  tag.textContent = CSS4;
130991
131860
  document.head.appendChild(tag);
130992
131861
  }
@@ -133836,7 +134705,7 @@ var WATER_FIXTURES = {
133836
134705
  var DEFAULT_FIXTURES = ENERGY_FIXTURES;
133837
134706
 
133838
134707
  // src/components/metas-guide/openMetasGuide.ts
133839
- var STYLE_ID14 = "myio-metas-guide-styles";
134708
+ var STYLE_ID16 = "myio-metas-guide-styles";
133840
134709
  var ROOT_ID = "myio-metas-guide-root";
133841
134710
  var FALLBACK_THEME = {
133842
134711
  accent: "#6c5ce7",
@@ -133844,7 +134713,7 @@ var FALLBACK_THEME = {
133844
134713
  accentText: "#ffffff",
133845
134714
  mode: "light"
133846
134715
  };
133847
- function escapeHtml13(value) {
134716
+ function escapeHtml14(value) {
133848
134717
  return String(value ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
133849
134718
  }
133850
134719
  var nfInt = new Intl.NumberFormat("pt-BR", { maximumFractionDigits: 0 });
@@ -133872,7 +134741,7 @@ function legendHtml() {
133872
134741
  [SERIES_COLORS.orcado, "Or\xE7ado"]
133873
134742
  ];
133874
134743
  return `<div class="myio-mg-legend">${items.map(
133875
- ([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(
133876
134745
  l
133877
134746
  )}</span>`
133878
134747
  ).join("")}</div>`;
@@ -133912,7 +134781,7 @@ function miniChartSvg(s) {
133912
134781
  const pts = data.map((v, i) => `${(i * bandW + bandW / 2).toFixed(1)},${y(v).toFixed(1)}`).join(" ");
133913
134782
  return `<polyline points="${pts}" fill="none" stroke="${color}" stroke-width="2" stroke-linejoin="round" stroke-linecap="round"></polyline>`;
133914
134783
  };
133915
- 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(
133916
134785
  s.name
133917
134786
  )}" preserveAspectRatio="none">
133918
134787
  ${bars}
@@ -133929,8 +134798,8 @@ function kpiRowHtml(s, unit) {
133929
134798
  ];
133930
134799
  return `<div class="myio-mg-kpis">${kpis.map(
133931
134800
  ([label, val, color]) => `<div class="myio-mg-kpi">
133932
- <span class="myio-mg-kpi__label" style="color:${color}">${escapeHtml13(label)}</span>
133933
- <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>
133934
134803
  </div>`
133935
134804
  ).join("")}</div>`;
133936
134805
  }
@@ -133938,7 +134807,7 @@ function chipsHtml(s) {
133938
134807
  const c = computeChips(s);
133939
134808
  const chip = (label, ratio) => {
133940
134809
  const cls = ratio > 0 ? "is-up" : ratio < 0 ? "is-down" : "is-flat";
133941
- return `<span class="myio-mg-chip ${cls}">${escapeHtml13(label)} <strong>${escapeHtml13(
134810
+ return `<span class="myio-mg-chip ${cls}">${escapeHtml14(label)} <strong>${escapeHtml14(
133942
134811
  fmtPct4(ratio)
133943
134812
  )}</strong></span>`;
133944
134813
  };
@@ -133953,7 +134822,7 @@ function miniCardHtml(s, unit, opts) {
133953
134822
  const showKpis = opts?.kpis !== false;
133954
134823
  const showChips = opts?.chips !== false;
133955
134824
  return `<div class="myio-mg-card">
133956
- <h5 class="myio-mg-card__title">${escapeHtml13(s.name)}</h5>
134825
+ <h5 class="myio-mg-card__title">${escapeHtml14(s.name)}</h5>
133957
134826
  ${showChart ? legendHtml() + miniChartSvg(s) : ""}
133958
134827
  ${showKpis ? kpiRowHtml(s, unit) : ""}
133959
134828
  ${showChips ? chipsHtml(s) : ""}
@@ -133963,7 +134832,7 @@ function miniSidebarHtml(shoppings, unit, prevY, curY) {
133963
134832
  const total = deriveTotal({ shoppings });
133964
134833
  const row = (name, a, r, o, m, isTotal) => `
133965
134834
  <div class="myio-mg-side__row${isTotal ? " is-total" : ""}">
133966
- <span class="myio-mg-side__name">${escapeHtml13(name)}</span>
134835
+ <span class="myio-mg-side__name">${escapeHtml14(name)}</span>
133967
134836
  <span class="myio-mg-side__vals">
133968
134837
  <b style="color:${SERIES_COLORS.aMinus1}">${fmtInt(a)}</b>
133969
134838
  <b style="color:${SERIES_COLORS.realizado}">${fmtInt(r)}</b>
@@ -133974,7 +134843,7 @@ function miniSidebarHtml(shoppings, unit, prevY, curY) {
133974
134843
  return `<div class="myio-mg-side">
133975
134844
  <div class="myio-mg-side__head">
133976
134845
  <span>Resumo por shopping</span>
133977
- <span class="myio-mg-side__unit">${escapeHtml13(unit)}</span>
134846
+ <span class="myio-mg-side__unit">${escapeHtml14(unit)}</span>
133978
134847
  </div>
133979
134848
  <div class="myio-mg-side__cols">
133980
134849
  <span>Shopping</span>
@@ -134001,10 +134870,10 @@ function miniToolbarHtml(prevY, curY, highlight) {
134001
134870
  </div>`;
134002
134871
  }
134003
134872
  function bannerHtml(text2) {
134004
- return `<p class="myio-mg-banner">${escapeHtml13(text2)}</p>`;
134873
+ return `<p class="myio-mg-banner">${escapeHtml14(text2)}</p>`;
134005
134874
  }
134006
134875
  function paras(sentences) {
134007
- 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>`;
134008
134877
  }
134009
134878
  function buildSections(ctx) {
134010
134879
  const { energy, water, curY, prevY } = ctx;
@@ -134029,8 +134898,8 @@ function buildSections(ctx) {
134029
134898
  "A r\xE9gua da meta muda por dom\xEDnio: em Energia a refer\xEAncia \xE9 a ENTRADA; em \xC1gua, os hidr\xF4metros.",
134030
134899
  "Os n\xFAmeros e a unidade de cada card acompanham o dom\xEDnio selecionado."
134031
134900
  ]) + miniToolbarHtml(prevY, curY, "domain") + `<div class="myio-mg-two">
134032
- <div><div class="myio-mg-two__tag">\u26A1 Energia \xB7 ${escapeHtml13(energy.unit)}</div>${miniCardHtml(e0, energy.unit, { chips: false })}</div>
134033
- <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>
134034
134903
  </div>`
134035
134904
  },
134036
134905
  {
@@ -134101,7 +134970,7 @@ function buildSections(ctx) {
134101
134970
  ]) + `<div class="myio-mg-order">
134102
134971
  <span class="myio-mg-order__btn">Data de Inaugura\xE7\xE3o \u2191 \xB7 \u2699\uFE0F</span>
134103
134972
  <span class="myio-mg-order__btn">\u25BD Filtros</span>
134104
- </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>`
134105
134974
  },
134106
134975
  {
134107
134976
  id: "engine",
@@ -134130,9 +134999,9 @@ function buildSections(ctx) {
134130
134999
  ];
134131
135000
  }
134132
135001
  function injectStyles16() {
134133
- if (document.getElementById(STYLE_ID14)) return;
135002
+ if (document.getElementById(STYLE_ID16)) return;
134134
135003
  const style = document.createElement("style");
134135
- style.id = STYLE_ID14;
135004
+ style.id = STYLE_ID16;
134136
135005
  style.textContent = `
134137
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;}
134138
135007
  #${ROOT_ID} *{box-sizing:border-box;}
@@ -134240,9 +135109,9 @@ function openMetasGuide(options = {}) {
134240
135109
  root.innerHTML = `
134241
135110
  <div class="myio-mg-modal${theme.mode === "dark" ? " is-dark" : ""}" role="dialog" aria-modal="true"
134242
135111
  aria-labelledby="myio-mg-title"
134243
- style="--mg-accent:${escapeHtml13(theme.accent)};--mg-accent-dark:${escapeHtml13(
135112
+ style="--mg-accent:${escapeHtml14(theme.accent)};--mg-accent-dark:${escapeHtml14(
134244
135113
  theme.accentDark
134245
- )};--mg-accent-text:${escapeHtml13(theme.accentText)};">
135114
+ )};--mg-accent-text:${escapeHtml14(theme.accentText)};">
134246
135115
  <div class="myio-mg-header">
134247
135116
  <div class="myio-mg-header__l">
134248
135117
  <span class="myio-mg-header__logo" aria-hidden="true">\u{1F393}</span>
@@ -144468,7 +145337,7 @@ var DeviceOperationalCardView = class {
144468
145337
  }
144469
145338
  renderCard(alarm) {
144470
145339
  const severityConfig = SEVERITY_CONFIG[alarm.severity];
144471
- const isActive = isAlarmActive(alarm.state);
145340
+ const isActive2 = isAlarmActive(alarm.state);
144472
145341
  const isCritical = alarm.severity === "CRITICAL" && alarm.state === "OPEN";
144473
145342
  const severityChipClass = this.getSeverityChipClass(alarm.severity);
144474
145343
  const stateChipClass = this.getStateChipClass(alarm.state);
@@ -144543,7 +145412,7 @@ var DeviceOperationalCardView = class {
144543
145412
 
144544
145413
  <!-- Actions -->
144545
145414
  <div class="myio-alarm-card-actions">
144546
- ${isActive ? `
145415
+ ${isActive2 ? `
144547
145416
  <button class="btn-ack" data-action="acknowledge">Reconhecer</button>
144548
145417
  ` : ""}
144549
145418
  <button class="btn-details" data-action="details">Detalhes</button>
@@ -148434,15 +149303,15 @@ var AlarmsNotificationsPanelView = class {
148434
149303
  const rows = alarms.map((alarm) => {
148435
149304
  const sev = SEVERITY_CONFIG[alarm.severity];
148436
149305
  const st = STATE_CONFIG[alarm.state];
148437
- const isActive = alarm.state !== "CLOSED";
149306
+ const isActive2 = alarm.state !== "CLOSED";
148438
149307
  const sel = this.selectedIds.has(alarm.id);
148439
149308
  const escTitle = this.esc(alarm.title);
148440
149309
  const escCustomer = this.esc(alarm.customerName || "-");
148441
149310
  const escSource = this.esc(alarm.source || "-");
148442
149311
  const actionBtns = `
148443
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>` : ""}
148444
- ${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>` : ""}
148445
- ${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>` : ""}
148446
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>
148447
149316
  `;
148448
149317
  const tiposHtml = isPorDispositivo && alarm._alarmTypes?.length ? alarm._alarmTypes.slice(0, 2).map(
@@ -152338,8 +153207,8 @@ function renderDowntimeList(downtimeList) {
152338
153207
  <div class="downtime-item">
152339
153208
  <span class="rank">${index + 1}</span>
152340
153209
  <div class="item-info">
152341
- <span class="item-name">${escapeHtml14(item.name)}</span>
152342
- <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>
152343
153212
  </div>
152344
153213
  <div class="item-metrics">
152345
153214
  <span class="downtime-hours">${item.downtime}h</span>
@@ -152352,7 +153221,7 @@ function renderDowntimeList(downtimeList) {
152352
153221
  `
152353
153222
  ).join("");
152354
153223
  }
152355
- function escapeHtml14(text2) {
153224
+ function escapeHtml15(text2) {
152356
153225
  const div = document.createElement("div");
152357
153226
  div.textContent = text2;
152358
153227
  return div.innerHTML;
@@ -156935,7 +157804,7 @@ function removeSchedulingSharedStyles() {
156935
157804
  }
156936
157805
 
156937
157806
  // src/components/scheduling-shared/view-helpers.ts
156938
- function escapeHtml15(str) {
157807
+ function escapeHtml16(str) {
156939
157808
  const div = document.createElement("div");
156940
157809
  div.textContent = str;
156941
157810
  return div.innerHTML;
@@ -157096,7 +157965,7 @@ function showConfirmModal(container, title, message) {
157096
157965
  overlay.innerHTML = `
157097
157966
  <div class="${SCHED_CSS_PREFIX}__modal-backdrop"></div>
157098
157967
  <div class="${SCHED_CSS_PREFIX}__modal-content">
157099
- <h3>${escapeHtml15(title)}</h3>
157968
+ <h3>${escapeHtml16(title)}</h3>
157100
157969
  <p>${message}</p>
157101
157970
  <div class="${SCHED_CSS_PREFIX}__modal-actions">
157102
157971
  <button class="${SCHED_CSS_PREFIX}__modal-btn-cancel">Cancelar</button>
@@ -157130,8 +157999,8 @@ function showNotificationModal(container, type, message, autoCloseMs = 6e3) {
157130
157999
  overlay.innerHTML = `
157131
158000
  <div class="${SCHED_CSS_PREFIX}__modal-backdrop"></div>
157132
158001
  <div class="${SCHED_CSS_PREFIX}__modal-content">
157133
- <h3>${escapeHtml15(title)}</h3>
157134
- <p>${escapeHtml15(message)}</p>
158002
+ <h3>${escapeHtml16(title)}</h3>
158003
+ <p>${escapeHtml16(message)}</p>
157135
158004
  <div class="${SCHED_CSS_PREFIX}__modal-actions">
157136
158005
  <button class="${SCHED_CSS_PREFIX}__modal-btn-close">Fechar</button>
157137
158006
  </div>
@@ -158852,10 +159721,10 @@ var DeviceGridV6View = class {
158852
159721
  }
158853
159722
  toggleSearch() {
158854
159723
  if (!this.searchWrapEl) return;
158855
- const isActive = this.searchWrapEl.classList.toggle("active");
158856
- if (isActive && this.searchInputEl) {
159724
+ const isActive2 = this.searchWrapEl.classList.toggle("active");
159725
+ if (isActive2 && this.searchInputEl) {
158857
159726
  this.searchInputEl.focus();
158858
- } else if (!isActive && this.searchInputEl) {
159727
+ } else if (!isActive2 && this.searchInputEl) {
158859
159728
  this.searchInputEl.value = "";
158860
159729
  this.controller.setSearchTerm("");
158861
159730
  this.renderCards();
@@ -160397,7 +161266,7 @@ var DEFAULT_CONFIG4 = {
160397
161266
  off: "Desligado"
160398
161267
  }
160399
161268
  };
160400
- function formatDuration2(minutes) {
161269
+ function formatDuration3(minutes) {
160401
161270
  if (minutes < 60) {
160402
161271
  return `${Math.round(minutes)}min`;
160403
161272
  }
@@ -160467,7 +161336,7 @@ function renderTimelineSVG(data, config2) {
160467
161336
  text-anchor="middle"
160468
161337
  class="${ONOFF_TIMELINE_CSS_PREFIX}__duration-label"
160469
161338
  >
160470
- ${formatDuration2(seg.durationMinutes)}
161339
+ ${formatDuration3(seg.durationMinutes)}
160471
161340
  </text>
160472
161341
  `;
160473
161342
  }
@@ -160493,7 +161362,7 @@ function renderTimelineSVG(data, config2) {
160493
161362
  data-state="${stateClass}"
160494
161363
  data-start="${formatDateTime4(seg.startTime)}"
160495
161364
  data-end="${formatDateTime4(seg.endTime)}"
160496
- data-duration="${formatDuration2(seg.durationMinutes)}"
161365
+ data-duration="${formatDuration3(seg.durationMinutes)}"
160497
161366
  data-source="${seg.source || "unknown"}"
160498
161367
  />
160499
161368
  `;
@@ -160590,7 +161459,7 @@ function renderSummary(data, labels) {
160590
161459
  </div>
160591
161460
  <div class="${ONOFF_TIMELINE_CSS_PREFIX}__summary-item">
160592
161461
  <span class="${ONOFF_TIMELINE_CSS_PREFIX}__summary-value">
160593
- ${formatDuration2(data.totalOnMinutes)}
161462
+ ${formatDuration3(data.totalOnMinutes)}
160594
161463
  </span>
160595
161464
  <span class="${ONOFF_TIMELINE_CSS_PREFIX}__summary-label">Tempo ${labels.on || "ON"}</span>
160596
161465
  </div>
@@ -165604,8 +166473,8 @@ var SidebarMenuView = class {
165604
166473
  `;
165605
166474
  }
165606
166475
  renderItem(item, section) {
165607
- const isActive = this.activeItemId === item.id;
165608
- const activeClass = isActive ? "active" : "";
166476
+ const isActive2 = this.activeItemId === item.id;
166477
+ const activeClass = isActive2 ? "active" : "";
165609
166478
  const disabledClass = item.disabled ? "disabled" : "";
165610
166479
  return `
165611
166480
  <div
@@ -165615,7 +166484,7 @@ var SidebarMenuView = class {
165615
166484
  data-action="item-click"
165616
166485
  role="menuitem"
165617
166486
  tabindex="${item.disabled ? -1 : 0}"
165618
- aria-current="${isActive ? "page" : "false"}"
166487
+ aria-current="${isActive2 ? "page" : "false"}"
165619
166488
  ${item.disabled ? 'aria-disabled="true"' : ""}
165620
166489
  >
165621
166490
  <span class="${SIDEBAR_MENU_CSS_PREFIX}__item-icon">
@@ -167958,7 +168827,7 @@ var DAY_NAMES = {
167958
168827
  "5": "Sex",
167959
168828
  "6": "S\xE1b"
167960
168829
  };
167961
- function formatDuration3(ms) {
168830
+ function formatDuration4(ms) {
167962
168831
  if (!ms) return "";
167963
168832
  const min = Math.round(ms / 6e4);
167964
168833
  if (min < 60) return `${min} min`;
@@ -167979,7 +168848,7 @@ function renderRuleDetailContent(rule) {
167979
168848
  }
167980
168849
  function renderRuleChips(rule) {
167981
168850
  const op = OPERATOR_LABELS2[rule.operator] ?? rule.operator;
167982
- const dur = formatDuration3(rule.duration);
168851
+ const dur = formatDuration4(rule.duration);
167983
168852
  const time = rule.startAt && rule.endAt ? `${rule.startAt} \u2013 ${rule.endAt}` : "";
167984
168853
  const agg = rule.aggregation ?? "";
167985
168854
  const chips = [
@@ -169745,11 +170614,11 @@ function _esc(s) {
169745
170614
  const str = s == null ? "" : String(s);
169746
170615
  return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
169747
170616
  }
169748
- var STYLE_ID15 = "ntw-styles";
170617
+ var STYLE_ID17 = "ntw-styles";
169749
170618
  function _injectStyles2() {
169750
- if (document.getElementById(STYLE_ID15)) return;
170619
+ if (document.getElementById(STYLE_ID17)) return;
169751
170620
  const s = document.createElement("style");
169752
- s.id = STYLE_ID15;
170621
+ s.id = STYLE_ID17;
169753
170622
  s.textContent = NTW_CSS;
169754
170623
  document.head.appendChild(s);
169755
170624
  }
@@ -172450,7 +173319,7 @@ var IMPORTANCE_COLORS4 = {
172450
173319
  // red
172451
173320
  };
172452
173321
  var ITEM_TEXT_MAX = 120;
172453
- function escapeHtml16(input) {
173322
+ function escapeHtml17(input) {
172454
173323
  if (input == null) return "";
172455
173324
  return String(input).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
172456
173325
  }
@@ -172488,24 +173357,24 @@ function renderAnnotationItemCard(device, annotation, searchTerm) {
172488
173357
  const domainIcon = DOMAIN_ICONS3[device.domain] ?? DOMAIN_ICONS3.unknown;
172489
173358
  const typeIcon = TYPE_ICONS[annotation.type] ?? "\xB7";
172490
173359
  const importance = Math.max(1, Math.min(5, annotation.importance || 1));
172491
- const textEscaped = escapeHtml16(truncate2(annotation.text || "", ITEM_TEXT_MAX));
172492
- const deviceLabelEscaped = escapeHtml16(device.label || device.name || device.deviceId);
172493
- const author = escapeHtml16(annotation.createdBy?.name || "sem autor");
172494
- 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));
172495
173364
  const overdueTag = isOverdue(annotation) ? '<span class="myio-annotations-overdue">Vencida</span>' : "";
172496
173365
  const text2 = searchTerm ? highlightMatches(textEscaped, searchTerm) : textEscaped;
172497
173366
  const deviceLabel = searchTerm ? highlightMatches(deviceLabelEscaped, searchTerm) : deviceLabelEscaped;
172498
- const identifierEscaped = device.identifier ? escapeHtml16(device.identifier) : "";
173367
+ const identifierEscaped = device.identifier ? escapeHtml17(device.identifier) : "";
172499
173368
  const identifierHighlighted = searchTerm && identifierEscaped ? highlightMatches(identifierEscaped, searchTerm) : identifierEscaped;
172500
173369
  const identifierTag = device.identifier ? `<span class="myio-annotations-item-device">${identifierHighlighted}</span>` : "";
172501
173370
  return `
172502
173371
  <button
172503
173372
  class="myio-annotations-item"
172504
173373
  type="button"
172505
- data-device-id="${escapeHtml16(device.deviceId)}"
172506
- data-annotation-id="${escapeHtml16(annotation.id)}"
173374
+ data-device-id="${escapeHtml17(device.deviceId)}"
173375
+ data-annotation-id="${escapeHtml17(annotation.id)}"
172507
173376
  tabindex="0"
172508
- aria-label="${escapeHtml16(annotation.text)} \u2014 ${deviceLabel}"
173377
+ aria-label="${escapeHtml17(annotation.text)} \u2014 ${deviceLabel}"
172509
173378
  >
172510
173379
  <span class="myio-annotations-item-icon" aria-hidden="true">${typeIcon}</span>
172511
173380
  <div class="myio-annotations-item-body">
@@ -173482,8 +174351,8 @@ var HeaderAnnotationsPanel = class _HeaderAnnotationsPanel {
173482
174351
  // group header
173483
174352
  render: () => `
173484
174353
  <header class="myio-annotations-group-header ${groupClass}">
173485
- ${g.icon ? `<span class="myio-annotations-group-icon" aria-hidden="true">${escapeHtml16(g.icon)}</span>` : ""}
173486
- <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>
173487
174356
  <span class="myio-annotations-group-count">${g.totalAnnotations}</span>
173488
174357
  </header>`
173489
174358
  });
@@ -173608,9 +174477,9 @@ ${this._renderToolbar(filteredCount, totalAllUnfiltered)}
173608
174477
  }
173609
174478
  _renderToolbar(filteredCount, totalCount) {
173610
174479
  const sortOptions = SORT_OPTIONS.map(
173611
- (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>`
173612
174481
  ).join("");
173613
- const term = escapeHtml16(this.filter.searchTerm || "");
174482
+ const term = escapeHtml17(this.filter.searchTerm || "");
173614
174483
  const filtersActiveCount = this._activeFilterCount();
173615
174484
  const filterIndicator = filtersActiveCount > 0 ? `<span class="myio-annotations-group-count">${filtersActiveCount}</span>` : "";
173616
174485
  const showingHtml = filteredCount === totalCount ? `${totalCount} anota\xE7\xF5es` : `${filteredCount} de ${totalCount} anota\xE7\xF5es`;
@@ -173651,13 +174520,13 @@ ${this._renderToolbar(filteredCount, totalAllUnfiltered)}
173651
174520
  const typesHtml = FILTER_TYPE_OPTIONS.map(
173652
174521
  (t) => `<label class="myio-annotations-filter-chip ${this.filter.types.has(t.id) ? "is-on" : ""}">
173653
174522
  <input type="checkbox" data-filter="type" value="${t.id}" ${this.filter.types.has(t.id) ? "checked" : ""} />
173654
- <span>${t.icon} ${escapeHtml16(t.label)}</span>
174523
+ <span>${t.icon} ${escapeHtml17(t.label)}</span>
173655
174524
  </label>`
173656
174525
  ).join("");
173657
174526
  const statusHtml = FILTER_STATUS_OPTIONS.map(
173658
174527
  (s) => `<label class="myio-annotations-filter-chip ${this.filter.statuses.has(s.id) ? "is-on" : ""}">
173659
174528
  <input type="checkbox" data-filter="status" value="${s.id}" ${this.filter.statuses.has(s.id) ? "checked" : ""} />
173660
- <span>${escapeHtml16(s.label)}</span>
174529
+ <span>${escapeHtml17(s.label)}</span>
173661
174530
  </label>`
173662
174531
  ).join("");
173663
174532
  const impHtml = [1, 2, 3, 4, 5].map(
@@ -173734,12 +174603,12 @@ ${this._renderToolbar(filteredCount, totalAllUnfiltered)}
173734
174603
  return `
173735
174604
  <section class="${groupClass}">
173736
174605
  <header class="myio-annotations-group-header" role="button" tabindex="0"
173737
- data-group-toggle="${escapeHtml16(group.key)}"
174606
+ data-group-toggle="${escapeHtml17(group.key)}"
173738
174607
  aria-expanded="${!isCollapsed}"
173739
174608
  title="${isCollapsed ? "Expandir grupo" : "Recolher grupo"}">
173740
174609
  <span class="myio-annotations-group-chevron" aria-hidden="true">${isCollapsed ? "\u25B6" : "\u25BC"}</span>
173741
- ${group.icon ? `<span class="myio-annotations-group-icon" aria-hidden="true">${escapeHtml16(group.icon)}</span>` : ""}
173742
- <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>
173743
174612
  <span class="myio-annotations-group-count">${group.totalAnnotations}</span>
173744
174613
  </header>
173745
174614
  ${itemsHtml}
@@ -174400,7 +175269,7 @@ function validateDeviceProductCode(code) {
174400
175269
  }
174401
175270
 
174402
175271
  // src/components/cards/central-status/v1.0.0/styles.ts
174403
- var STYLE_ID16 = "myio-central-status-card-styles";
175272
+ var STYLE_ID18 = "myio-central-status-card-styles";
174404
175273
  var CSS5 = `
174405
175274
  .myio-cscard{
174406
175275
  --cscard-surface:#ffffff;
@@ -174703,9 +175572,9 @@ var CSS5 = `
174703
175572
  `;
174704
175573
  function injectCentralStatusCardStyles() {
174705
175574
  if (typeof document === "undefined") return;
174706
- if (document.getElementById(STYLE_ID16)) return;
175575
+ if (document.getElementById(STYLE_ID18)) return;
174707
175576
  const tag = document.createElement("style");
174708
- tag.id = STYLE_ID16;
175577
+ tag.id = STYLE_ID18;
174709
175578
  tag.textContent = CSS5;
174710
175579
  document.head.appendChild(tag);
174711
175580
  }
@@ -174765,7 +175634,7 @@ function deriveCentralConnectivity(ev, opts) {
174765
175634
  }
174766
175635
 
174767
175636
  // src/components/cards/central-status/v1.0.0/TimelineModal.ts
174768
- var STYLE_ID17 = "myio-cscard-timeline-styles";
175637
+ var STYLE_ID19 = "myio-cscard-timeline-styles";
174769
175638
  var DEFAULT_PERIODS = [1, 7, 30, 90];
174770
175639
  function escAttr5(s) {
174771
175640
  return String(s ?? "").replace(
@@ -174774,9 +175643,9 @@ function escAttr5(s) {
174774
175643
  );
174775
175644
  }
174776
175645
  function injectTimelineModalStyles() {
174777
- if (typeof document === "undefined" || document.getElementById(STYLE_ID17)) return;
175646
+ if (typeof document === "undefined" || document.getElementById(STYLE_ID19)) return;
174778
175647
  const tag = document.createElement("style");
174779
- tag.id = STYLE_ID17;
175648
+ tag.id = STYLE_ID19;
174780
175649
  tag.textContent = `
174781
175650
  .myio-tlmodal{
174782
175651
  --tl-online:#3b82f6;
@@ -175115,7 +175984,7 @@ function formatSince(iso, nowMs, language) {
175115
175984
  else rel = `${Math.round(s / 86400)}d`;
175116
175985
  return `${abs} (${rel})`;
175117
175986
  }
175118
- function formatDuration4(ms) {
175987
+ function formatDuration5(ms) {
175119
175988
  const totalMin = Math.max(0, Math.round(ms / 6e4));
175120
175989
  const hours = Math.floor(totalMin / 60);
175121
175990
  const minutes = totalMin % 60;
@@ -175453,7 +176322,7 @@ var CentralStatusCard = class _CentralStatusCard {
175453
176322
  this.el.removeAttribute("draggable");
175454
176323
  }
175455
176324
  this.el.style.zoom = p.scale && p.scale !== 1 ? String(p.scale) : "";
175456
- 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]);
175457
176326
  const staleBadge = stale ? `<span class="myio-cscard__stale">${STALE_BADGE_TEXT[this.language()]}</span>` : "";
175458
176327
  const divergenceGlyph = (() => {
175459
176328
  const o = p.icons?.divergence;
@@ -175969,6 +176838,7 @@ var version = package_default.version || "0.0.0";
175969
176838
  DEFAULT_SIDEBAR_CONFIG,
175970
176839
  DEFAULT_SOLENOID_SETTINGS,
175971
176840
  DEFAULT_SOLENOID_STATE,
176841
+ DEFAULT_STORE_SEGMENTS,
175972
176842
  DEFAULT_SWITCH_SETTINGS,
175973
176843
  DEFAULT_SWITCH_STATE,
175974
176844
  DEFAULT_TABS,
@@ -176114,6 +176984,7 @@ var version = package_default.version || "0.0.0";
176114
176984
  POWER_LIMITS_DEVICE_TYPES,
176115
176985
  POWER_LIMITS_STATUS_CONFIG,
176116
176986
  POWER_LIMITS_TELEMETRY_TYPES,
176987
+ PUMP_POWER_KEY,
176117
176988
  REPORT_MONEY_HEADER,
176118
176989
  SCHEDULE_HOLIDAY_CSS_PREFIX,
176119
176990
  SCHEDULE_IR_CSS_PREFIX,
@@ -176166,6 +177037,7 @@ var version = package_default.version || "0.0.0";
176166
177037
  TempSensorSummaryTooltip,
176167
177038
  Temperature,
176168
177039
  UsersSummaryTooltip,
177040
+ VALVE_STATE_KEYS,
176169
177041
  VARIANCE_LABEL_ABOVE,
176170
177042
  VARIANCE_LABEL_BELOW,
176171
177043
  VARIANCE_LABEL_ONTARGET,
@@ -176288,6 +177160,7 @@ var version = package_default.version || "0.0.0";
176288
177160
  createDistributionChartWidget,
176289
177161
  createDivCard,
176290
177162
  createEnergyPanelComponent,
177163
+ createEquipmentIndicatorStrip,
176291
177164
  createErrorSpan,
176292
177165
  createExportButton,
176293
177166
  createFakeDeviceCategoryPort,
@@ -176514,6 +177387,7 @@ var version = package_default.version || "0.0.0";
176514
177387
  hasCoverageGaps,
176515
177388
  hasSelectedDays,
176516
177389
  highlightAnnotationMatches,
177390
+ indicatorsFromModalData,
176517
177391
  initMyIOAuthContext,
176518
177392
  initOnOffTimelineTooltips,
176519
177393
  injectActionButtonStyles,
@@ -176550,6 +177424,7 @@ var version = package_default.version || "0.0.0";
176550
177424
  injectSolenoidControlStyles,
176551
177425
  injectSwitchControlStyles,
176552
177426
  interpolateTemperature,
177427
+ intervalsFromTelemetry,
176553
177428
  inventory,
176554
177429
  isAlarmActive,
176555
177430
  isAnnotationOverdue,
@@ -176579,6 +177454,7 @@ var version = package_default.version || "0.0.0";
176579
177454
  isValidTimeFormat,
176580
177455
  isWaterCategory,
176581
177456
  latestHourlyTemperature,
177457
+ latestPowerKw,
176582
177458
  liftProfileToTree,
176583
177459
  listDeviceProductTypes,
176584
177460
  listDomains,
@@ -176647,10 +177523,12 @@ var version = package_default.version || "0.0.0";
176647
177523
  openUpsellModal,
176648
177524
  openUserManagementModal,
176649
177525
  openWelcomeModal,
177526
+ openWellPumpsModal,
176650
177527
  overlayWithholdsVerdict,
176651
177528
  panelCategoryToWire,
176652
177529
  panelDomainToWire,
176653
177530
  panelTermToDeviceCategory,
177531
+ parseBinaryState,
176654
177532
  parseClassificationEntities,
176655
177533
  parseGcdrEnergyRoot,
176656
177534
  parseGcdrEntityForest,
@@ -176658,6 +177536,7 @@ var version = package_default.version || "0.0.0";
176658
177536
  parseLogAnnotations,
176659
177537
  periodKey,
176660
177538
  pickUniqueCustomerCode,
177539
+ pumpHistoryFromConsumption,
176661
177540
  readFreshdeskTicketsFromTB,
176662
177541
  recalculateDeviceStatus,
176663
177542
  recomputeDeviceGridPercentages,
@@ -176685,6 +177564,8 @@ var version = package_default.version || "0.0.0";
176685
177564
  renderDashboardDowntimeList,
176686
177565
  renderDeviceGridList,
176687
177566
  renderDualLineChart,
177567
+ renderEquipmentShortcutHTML,
177568
+ renderEquipmentTilesHTML,
176688
177569
  renderFinancialIndicators,
176689
177570
  renderGatedMoney,
176690
177571
  renderKPICards,