iobroker.mywebui 1.120.0 → 1.122.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (290) hide show
  1. package/default-controls/controls/plantpax/ain-faceplate.control +2 -2
  2. package/default-controls/controls/plantpax/alarm-faceplate.control +1 -1
  3. package/default-controls/controls/plantpax/cmdsrc-faceplate.control +1 -1
  4. package/default-controls/controls/plantpax/components/alarm-row.control +3 -3
  5. package/default-controls/controls/plantpax/dbc-faceplate.control +1 -1
  6. package/default-controls/controls/plantpax/din-faceplate.control +1 -1
  7. package/default-controls/controls/plantpax/dose-faceplate.control +1 -1
  8. package/default-controls/controls/plantpax/dout-faceplate.control +1 -1
  9. package/default-controls/controls/plantpax/gate-faceplate.control +1 -1
  10. package/default-controls/controls/plantpax/hilosel-faceplate.control +1 -1
  11. package/default-controls/controls/plantpax/intlk-faceplate.control +1 -1
  12. package/default-controls/controls/plantpax/logic-faceplate.control +1 -1
  13. package/default-controls/controls/plantpax/meta-faceplate.control +1 -1
  14. package/default-controls/controls/plantpax/motor-faceplate.control +1 -1
  15. package/default-controls/controls/plantpax/motor2spd-faceplate.control +1 -1
  16. package/default-controls/controls/plantpax/motorrev-faceplate.control +1 -1
  17. package/default-controls/controls/plantpax/npos-faceplate.control +1 -1
  18. package/default-controls/controls/plantpax/perm-faceplate.control +1 -1
  19. package/default-controls/controls/plantpax/pide-faceplate.control +1 -1
  20. package/default-controls/controls/plantpax/valvec-faceplate.control +1 -1
  21. package/default-controls/controls/plantpax/valvemo-faceplate.control +1 -1
  22. package/default-controls/controls/plantpax/valvemp-faceplate.control +1 -1
  23. package/default-controls/controls/plantpax/valveso-faceplate.control +1 -1
  24. package/default-controls/controls/plantpax/vsd-faceplate.control +1 -1
  25. package/dist/backend/3d-editor-integration.js +1 -1
  26. package/dist/backend/ImportmapCreator.js +1 -1
  27. package/dist/backend/UploadHelper.js +1 -1
  28. package/dist/backend/main.js +1 -1
  29. package/io-package.json +1 -1
  30. package/package.json +1 -1
  31. package/scripts/_build_plantpax.py +9 -4
  32. package/scripts/_build_plantpax_components.py +32 -20
  33. package/scripts/pp_icons.json +22 -0
  34. package/www/3d-editor/js/Animation.js +1 -1
  35. package/www/3d-editor/js/AnimationResizer.js +1 -1
  36. package/www/3d-editor/js/Command.js +1 -1
  37. package/www/3d-editor/js/Config.js +1 -1
  38. package/www/3d-editor/js/Editor.js +1 -1
  39. package/www/3d-editor/js/EditorControls.js +1 -1
  40. package/www/3d-editor/js/GLTFImportDialog.js +1 -1
  41. package/www/3d-editor/js/History.js +1 -1
  42. package/www/3d-editor/js/Loader.js +1 -1
  43. package/www/3d-editor/js/LoaderUtils.js +1 -1
  44. package/www/3d-editor/js/Menubar.Add.js +1 -1
  45. package/www/3d-editor/js/Menubar.Edit.js +1 -1
  46. package/www/3d-editor/js/Menubar.File.js +1 -1
  47. package/www/3d-editor/js/Menubar.Help.js +1 -1
  48. package/www/3d-editor/js/Menubar.Render.js +1 -1
  49. package/www/3d-editor/js/Menubar.Status.js +1 -1
  50. package/www/3d-editor/js/Menubar.View.js +1 -1
  51. package/www/3d-editor/js/Menubar.js +1 -1
  52. package/www/3d-editor/js/Player.js +1 -1
  53. package/www/3d-editor/js/Resizer.js +1 -1
  54. package/www/3d-editor/js/Script.js +1 -1
  55. package/www/3d-editor/js/Selector.js +1 -1
  56. package/www/3d-editor/js/Sidebar.Geometry.BoxGeometry.js +1 -1
  57. package/www/3d-editor/js/Sidebar.Geometry.BufferGeometry.js +1 -1
  58. package/www/3d-editor/js/Sidebar.Geometry.CapsuleGeometry.js +1 -1
  59. package/www/3d-editor/js/Sidebar.Geometry.CircleGeometry.js +1 -1
  60. package/www/3d-editor/js/Sidebar.Geometry.CylinderGeometry.js +1 -1
  61. package/www/3d-editor/js/Sidebar.Geometry.DodecahedronGeometry.js +1 -1
  62. package/www/3d-editor/js/Sidebar.Geometry.ExtrudeGeometry.js +1 -1
  63. package/www/3d-editor/js/Sidebar.Geometry.IcosahedronGeometry.js +1 -1
  64. package/www/3d-editor/js/Sidebar.Geometry.LatheGeometry.js +1 -1
  65. package/www/3d-editor/js/Sidebar.Geometry.Modifiers.js +1 -1
  66. package/www/3d-editor/js/Sidebar.Geometry.OctahedronGeometry.js +1 -1
  67. package/www/3d-editor/js/Sidebar.Geometry.PlaneGeometry.js +1 -1
  68. package/www/3d-editor/js/Sidebar.Geometry.RingGeometry.js +1 -1
  69. package/www/3d-editor/js/Sidebar.Geometry.ShapeGeometry.js +1 -1
  70. package/www/3d-editor/js/Sidebar.Geometry.SphereGeometry.js +1 -1
  71. package/www/3d-editor/js/Sidebar.Geometry.TetrahedronGeometry.js +1 -1
  72. package/www/3d-editor/js/Sidebar.Geometry.TextGeometry.js +1 -1
  73. package/www/3d-editor/js/Sidebar.Geometry.TorusGeometry.js +1 -1
  74. package/www/3d-editor/js/Sidebar.Geometry.TorusKnotGeometry.js +1 -1
  75. package/www/3d-editor/js/Sidebar.Geometry.TubeGeometry.js +1 -1
  76. package/www/3d-editor/js/Sidebar.Geometry.js +1 -1
  77. package/www/3d-editor/js/Sidebar.Material.BooleanProperty.js +1 -1
  78. package/www/3d-editor/js/Sidebar.Material.ColorProperty.js +1 -1
  79. package/www/3d-editor/js/Sidebar.Material.ConstantProperty.js +1 -1
  80. package/www/3d-editor/js/Sidebar.Material.MapProperty.js +1 -1
  81. package/www/3d-editor/js/Sidebar.Material.NumberProperty.js +1 -1
  82. package/www/3d-editor/js/Sidebar.Material.Program.js +1 -1
  83. package/www/3d-editor/js/Sidebar.Material.RangeValueProperty.js +1 -1
  84. package/www/3d-editor/js/Sidebar.Material.js +1 -1
  85. package/www/3d-editor/js/Sidebar.Object.js +1 -1
  86. package/www/3d-editor/js/Sidebar.Project.App.js +1 -1
  87. package/www/3d-editor/js/Sidebar.Project.Materials.js +1 -1
  88. package/www/3d-editor/js/Sidebar.Project.Renderer.js +1 -1
  89. package/www/3d-editor/js/Sidebar.Project.Resources.js +1 -1
  90. package/www/3d-editor/js/Sidebar.Project.js +1 -1
  91. package/www/3d-editor/js/Sidebar.Properties.js +1 -1
  92. package/www/3d-editor/js/Sidebar.Scene.js +1 -1
  93. package/www/3d-editor/js/Sidebar.Script.js +1 -1
  94. package/www/3d-editor/js/Sidebar.Settings.History.js +1 -1
  95. package/www/3d-editor/js/Sidebar.Settings.Shortcuts.js +1 -1
  96. package/www/3d-editor/js/Sidebar.Settings.js +1 -1
  97. package/www/3d-editor/js/Sidebar.js +1 -1
  98. package/www/3d-editor/js/Storage.js +1 -1
  99. package/www/3d-editor/js/Strings.js +1 -1
  100. package/www/3d-editor/js/TextureParametersDialog.js +1 -1
  101. package/www/3d-editor/js/Toolbar.js +1 -1
  102. package/www/3d-editor/js/Viewport.Controls.js +1 -1
  103. package/www/3d-editor/js/Viewport.Info.js +1 -1
  104. package/www/3d-editor/js/Viewport.Pathtracer.js +1 -1
  105. package/www/3d-editor/js/Viewport.ViewHelper.js +1 -1
  106. package/www/3d-editor/js/Viewport.XR.js +1 -1
  107. package/www/3d-editor/js/Viewport.js +1 -1
  108. package/www/3d-editor/js/commands/AddObjectCommand.js +1 -1
  109. package/www/3d-editor/js/commands/AddScriptCommand.js +1 -1
  110. package/www/3d-editor/js/commands/Commands.js +1 -1
  111. package/www/3d-editor/js/commands/MoveObjectCommand.js +1 -1
  112. package/www/3d-editor/js/commands/MultiCmdsCommand.js +1 -1
  113. package/www/3d-editor/js/commands/RemoveObjectCommand.js +1 -1
  114. package/www/3d-editor/js/commands/RemoveScriptCommand.js +1 -1
  115. package/www/3d-editor/js/commands/SetColorCommand.js +1 -1
  116. package/www/3d-editor/js/commands/SetGeometryCommand.js +1 -1
  117. package/www/3d-editor/js/commands/SetGeometryValueCommand.js +1 -1
  118. package/www/3d-editor/js/commands/SetMaterialColorCommand.js +1 -1
  119. package/www/3d-editor/js/commands/SetMaterialCommand.js +1 -1
  120. package/www/3d-editor/js/commands/SetMaterialMapCommand.js +1 -1
  121. package/www/3d-editor/js/commands/SetMaterialRangeCommand.js +1 -1
  122. package/www/3d-editor/js/commands/SetMaterialValueCommand.js +1 -1
  123. package/www/3d-editor/js/commands/SetMaterialVectorCommand.js +1 -1
  124. package/www/3d-editor/js/commands/SetPositionCommand.js +1 -1
  125. package/www/3d-editor/js/commands/SetRotationCommand.js +1 -1
  126. package/www/3d-editor/js/commands/SetScaleCommand.js +1 -1
  127. package/www/3d-editor/js/commands/SetSceneCommand.js +1 -1
  128. package/www/3d-editor/js/commands/SetScriptValueCommand.js +1 -1
  129. package/www/3d-editor/js/commands/SetShadowValueCommand.js +1 -1
  130. package/www/3d-editor/js/commands/SetTextureParametersCommand.js +1 -1
  131. package/www/3d-editor/js/commands/SetUuidCommand.js +1 -1
  132. package/www/3d-editor/js/commands/SetValueCommand.js +1 -1
  133. package/www/dist/frontend/bundle/chunk-34JJK367.js +3 -3
  134. package/www/dist/frontend/bundle/chunk-3AS7GRBW.js +3 -3
  135. package/www/dist/frontend/bundle/chunk-3C6XC7RW.js +1 -1
  136. package/www/dist/frontend/bundle/chunk-3R27DWVW.js +3 -3
  137. package/www/dist/frontend/bundle/chunk-3WGNLIWJ.js +3 -3
  138. package/www/dist/frontend/bundle/chunk-3YK3Y2SJ.js +1 -1
  139. package/www/dist/frontend/bundle/chunk-43HEBO5G.js +3 -3
  140. package/www/dist/frontend/bundle/chunk-5MUGMRXU.js +1 -1
  141. package/www/dist/frontend/bundle/chunk-5UBRCTRX.js +3 -3
  142. package/www/dist/frontend/bundle/chunk-65A3PNMG.js +1 -1
  143. package/www/dist/frontend/bundle/chunk-66EU64WD.js +1 -1
  144. package/www/dist/frontend/bundle/chunk-6BL3X2VD.js +3 -3
  145. package/www/dist/frontend/bundle/chunk-6L2YCGEX.js +1 -1
  146. package/www/dist/frontend/bundle/chunk-7CWDQGAG.js +3 -3
  147. package/www/dist/frontend/bundle/chunk-7PT7IGUJ.js +2 -2
  148. package/www/dist/frontend/bundle/chunk-AI5PDLDE.js +3 -3
  149. package/www/dist/frontend/bundle/chunk-AUTVRE23.js +1 -1
  150. package/www/dist/frontend/bundle/chunk-AWKVUUKN.js +3 -3
  151. package/www/dist/frontend/bundle/chunk-B6NXWGSB.js +1 -1
  152. package/www/dist/frontend/bundle/chunk-BHSHNRXW.js +1 -1
  153. package/www/dist/frontend/bundle/chunk-BVONDEOL.js +3 -3
  154. package/www/dist/frontend/bundle/chunk-C7OGVQZC.js +1 -1
  155. package/www/dist/frontend/bundle/chunk-CHDKROX5.js +3 -3
  156. package/www/dist/frontend/bundle/chunk-DNCD2F6X.js +3 -3
  157. package/www/dist/frontend/bundle/chunk-FFW7WOVM.js +1 -1
  158. package/www/dist/frontend/bundle/chunk-FHF6DL5U.js +1 -1
  159. package/www/dist/frontend/bundle/chunk-FO56TEZH.js +3 -3
  160. package/www/dist/frontend/bundle/chunk-FRCSTZQC.js +3 -3
  161. package/www/dist/frontend/bundle/chunk-FSHAYPVR.js +2 -2
  162. package/www/dist/frontend/bundle/chunk-FSRRPQMX.js +3 -3
  163. package/www/dist/frontend/bundle/chunk-GLQNGCFL.js +1 -1
  164. package/www/dist/frontend/bundle/chunk-HC7GL5JY.js +1 -1
  165. package/www/dist/frontend/bundle/chunk-HXNIU7FI.js +3 -3
  166. package/www/dist/frontend/bundle/chunk-JBDSDK2C.js +2 -2
  167. package/www/dist/frontend/bundle/chunk-JSC66ZLQ.js +1 -1
  168. package/www/dist/frontend/bundle/chunk-JVPUFDR5.js +3 -3
  169. package/www/dist/frontend/bundle/chunk-K6IV7LKW.js +1 -1
  170. package/www/dist/frontend/bundle/chunk-KJU5I76S.js +3 -3
  171. package/www/dist/frontend/bundle/chunk-KY73TL6O.js +2 -2
  172. package/www/dist/frontend/bundle/chunk-LKS3S4WX.js +1 -1
  173. package/www/dist/frontend/bundle/chunk-M6VVTDVX.js +2 -2
  174. package/www/dist/frontend/bundle/chunk-MECWXZRN.js +1 -1
  175. package/www/dist/frontend/bundle/chunk-N2YIZTB2.js +1 -1
  176. package/www/dist/frontend/bundle/chunk-NQ7L7KNT.js +3 -3
  177. package/www/dist/frontend/bundle/chunk-O2AJL747.js +2 -2
  178. package/www/dist/frontend/bundle/chunk-P7EOR36H.js +1 -1
  179. package/www/dist/frontend/bundle/chunk-PJYK24KZ.js +1 -1
  180. package/www/dist/frontend/bundle/chunk-PYLAW6UA.js +3 -3
  181. package/www/dist/frontend/bundle/chunk-QJJGP23I.js +1 -1
  182. package/www/dist/frontend/bundle/chunk-QV4IBWXA.js +1 -1
  183. package/www/dist/frontend/bundle/chunk-R6IQDPAP.js +3 -3
  184. package/www/dist/frontend/bundle/chunk-RRFSEMFS.js +3 -3
  185. package/www/dist/frontend/bundle/chunk-RTTBZOQU.js +3 -3
  186. package/www/dist/frontend/bundle/chunk-S4TLNW5D.js +1 -1
  187. package/www/dist/frontend/bundle/chunk-S7P222YS.js +1 -1
  188. package/www/dist/frontend/bundle/chunk-SE6N4ZEN.js +1 -1
  189. package/www/dist/frontend/bundle/chunk-SQHXO2IT.js +3 -3
  190. package/www/dist/frontend/bundle/chunk-T4AIQBBH.js +3 -3
  191. package/www/dist/frontend/bundle/chunk-TWQQHCU7.js +2 -2
  192. package/www/dist/frontend/bundle/chunk-U5Q332OH.js +1 -1
  193. package/www/dist/frontend/bundle/chunk-UIP324PP.js +1 -1
  194. package/www/dist/frontend/bundle/chunk-V27IRYSL.js +1 -1
  195. package/www/dist/frontend/bundle/chunk-V4C5FGJL.js +3 -3
  196. package/www/dist/frontend/bundle/chunk-V5CHFTYG.js +3 -3
  197. package/www/dist/frontend/bundle/chunk-VHXWCBNP.js +1 -1
  198. package/www/dist/frontend/bundle/chunk-W2KWSW4M.js +1 -1
  199. package/www/dist/frontend/bundle/chunk-W5QV7JN5.js +1 -1
  200. package/www/dist/frontend/bundle/chunk-WED7CGWA.js +3 -3
  201. package/www/dist/frontend/bundle/chunk-WQ5H5LTG.js +3 -3
  202. package/www/dist/frontend/bundle/chunk-WU54NCEU.js +1 -1
  203. package/www/dist/frontend/bundle/chunk-XCRSZKUF.js +1 -1
  204. package/www/dist/frontend/bundle/chunk-XFO5FUCN.js +1 -1
  205. package/www/dist/frontend/bundle/chunk-XWAQ2BWM.js +3 -3
  206. package/www/dist/frontend/bundle/chunk-YTQCHNRQ.js +3 -3
  207. package/www/dist/frontend/bundle/chunk-YUSK4FN3.js +3 -3
  208. package/www/dist/frontend/bundle/chunk-Z34BSG5O.js +3 -3
  209. package/www/dist/frontend/bundle/common/IobrokerHandler.js +1 -1
  210. package/www/dist/frontend/bundle/runtime/CustomControls.js +1 -1
  211. package/www/dist/frontend/bundle/runtime/ScreenViewer.js +1 -1
  212. package/www/dist/frontend/bundle/runtime/controls.js +4 -4
  213. package/www/dist/frontend/bundle/runtime/init.js +3 -3
  214. package/www/dist/frontend/common/Common.globals.js +1 -1
  215. package/www/dist/frontend/common/IobrokerHandler.js +1 -1
  216. package/www/dist/frontend/common/PlantPaxResolve.js +1 -1
  217. package/www/dist/frontend/common/Runtime.js +1 -1
  218. package/www/dist/frontend/config/CommandHandling.js +1 -1
  219. package/www/dist/frontend/config/ConfigureWebcomponentDesigner.js +1 -1
  220. package/www/dist/frontend/config/DockHelper.js +1 -1
  221. package/www/dist/frontend/config/IobrokerWebui3DDriveEngine.js +1 -1
  222. package/www/dist/frontend/config/IobrokerWebui3DScreenEditor.js +3 -3
  223. package/www/dist/frontend/config/IobrokerWebui3DScreenPropertiesPanel.js +2 -2
  224. package/www/dist/frontend/config/IobrokerWebui3DScreenViewer.js +3 -3
  225. package/www/dist/frontend/config/IobrokerWebuiAppShell.js +2 -2
  226. package/www/dist/frontend/config/IobrokerWebuiBindingsEditor.js +1 -1
  227. package/www/dist/frontend/config/IobrokerWebuiConfirmationWrapper.js +3 -3
  228. package/www/dist/frontend/config/IobrokerWebuiControlPropertiesEditor.js +3 -3
  229. package/www/dist/frontend/config/IobrokerWebuiDynamicPropsEditor.js +1 -1
  230. package/www/dist/frontend/config/IobrokerWebuiEventAssignment.js +1 -1
  231. package/www/dist/frontend/config/IobrokerWebuiIconsView.js +3 -3
  232. package/www/dist/frontend/config/IobrokerWebuiMonacoEditor.js +3 -3
  233. package/www/dist/frontend/config/IobrokerWebuiPlantPaxTypesEditor.js +1 -1
  234. package/www/dist/frontend/config/IobrokerWebuiPropertyGrid.js +1 -1
  235. package/www/dist/frontend/config/IobrokerWebuiScreenEditor.js +1 -1
  236. package/www/dist/frontend/config/IobrokerWebuiScreensView.js +3 -3
  237. package/www/dist/frontend/config/IobrokerWebuiSecurityEditor.js +1 -1
  238. package/www/dist/frontend/config/IobrokerWebuiSignalPropertyEditor.js +1 -1
  239. package/www/dist/frontend/config/IobrokerWebuiSolutionExplorer.js +2 -2
  240. package/www/dist/frontend/config/IobrokerWebuiTranslationEditor.js +1 -1
  241. package/www/dist/frontend/config/IobrokerWebuiWidgetGallery.js +2 -2
  242. package/www/dist/frontend/helper/DialogHelper.js +2 -2
  243. package/www/dist/frontend/helper/EsprimaHelper.js +1 -1
  244. package/www/dist/frontend/helper/Helper.js +1 -1
  245. package/www/dist/frontend/helper/LayoutHelper.js +1 -1
  246. package/www/dist/frontend/helper/XmlHelper.js +1 -1
  247. package/www/dist/frontend/helper/ZipHelper.js +1 -1
  248. package/www/dist/frontend/runtime/AnimationService.js +1 -1
  249. package/www/dist/frontend/runtime/CustomControls.js +1 -1
  250. package/www/dist/frontend/runtime/DynamicElementProperties.js +1 -1
  251. package/www/dist/frontend/runtime/HabPanelLikeMenu.js +2 -2
  252. package/www/dist/frontend/runtime/NavigationShell.js +1 -1
  253. package/www/dist/frontend/runtime/RuntimeTheme.js +1 -1
  254. package/www/dist/frontend/runtime/ScreenViewer.js +3 -3
  255. package/www/dist/frontend/runtime/TranslateableText.js +2 -2
  256. package/www/dist/frontend/runtime/VisibilityService.js +1 -1
  257. package/www/dist/frontend/runtime/controls.js +1 -1
  258. package/www/dist/frontend/runtime/init.js +1 -1
  259. package/www/dist/frontend/scripting/IobrokerWebuiScriptSystem.js +1 -1
  260. package/www/dist/frontend/scripting/blockly/OpenScreen.js +1 -1
  261. package/www/dist/frontend/scripting/blockly/webuiBlocklyToolbox.js +1 -1
  262. package/www/dist/frontend/services/DynamicPropertiesHelper.js +1 -1
  263. package/www/dist/frontend/services/IobrokerWebuiBindableLocalObjectsService.js +1 -1
  264. package/www/dist/frontend/services/IobrokerWebuiBindableObjectDragDropService.js +1 -1
  265. package/www/dist/frontend/services/IobrokerWebuiBindableObjectsForPropertiesService.js +1 -1
  266. package/www/dist/frontend/services/IobrokerWebuiBindableObjectsService.js +1 -1
  267. package/www/dist/frontend/services/IobrokerWebuiConfigButtonProvider.js +1 -1
  268. package/www/dist/frontend/services/IobrokerWebuiCopyPasteService.js +1 -1
  269. package/www/dist/frontend/services/IobrokerWebuiCustomControlEventsService.js +1 -1
  270. package/www/dist/frontend/services/IobrokerWebuiCustomElementContextMenu.js +1 -1
  271. package/www/dist/frontend/services/IobrokerWebuiDemoProviderService.js +1 -1
  272. package/www/dist/frontend/services/IobrokerWebuiDynamicPropertiesService.js +1 -1
  273. package/www/dist/frontend/services/IobrokerWebuiEventsService.js +1 -1
  274. package/www/dist/frontend/services/IobrokerWebuiExternalDragDropService.js +1 -1
  275. package/www/dist/frontend/services/IobrokerWebuiLitPropertiesService.js +1 -1
  276. package/www/dist/frontend/services/IobrokerWebuiPropertiesService.js +1 -1
  277. package/www/dist/frontend/services/IobrokerWebuiPropertyGroupsService.js +1 -1
  278. package/www/dist/frontend/services/IobrokerWebuiRefactorService.js +1 -1
  279. package/www/dist/frontend/services/IobrokerWebuiScreenContextMenu.js +1 -1
  280. package/www/dist/frontend/services/IobrokerWebuiSpecialPropertiesService.js +1 -1
  281. package/www/dist/frontend/services/IobrokerWebuiSpectrumEditorService.js +1 -1
  282. package/www/dist/frontend/services/IobrokerWebuiVisibilityPropertiesService.js +1 -1
  283. package/www/dist/frontend/services/LayoutComponentsPropertiesService.js +1 -1
  284. package/www/dist/frontend/widgets/OrthoFlowLineTool.js +1 -1
  285. package/www/dist/frontend/widgets/customElementsObserver.js +1 -1
  286. package/www/dist/frontend/widgets/importWidgetFiles.js +1 -1
  287. package/www/dist/frontend/widgets/importWidgetFilesRuntime.js +1 -1
  288. package/www/dist/frontend/widgets/layout-components.js +1 -1
  289. package/www/dist/frontend/widgets/layout-placement-services.js +1 -1
  290. package/www/dist/frontend/widgets/testElement.js +1 -1
@@ -17,7 +17,7 @@
17
17
  "width": "520px",
18
18
  "height": "600px"
19
19
  },
20
- "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-adv-btn\" title=\"Advanced\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M4 6h10M4 12h16M4 18h7\"/><circle cx=\"17\" cy=\"6\" r=\"2\"/><circle cx=\"14\" cy=\"18\" r=\"2\"/></svg></button><button class=\"fp-x\">✕</button></div><div class=\"fp-desc\">Analog Input &nbsp;&#183;&nbsp; EU: [[this.unit||'&#8212;']]</div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Diagnostics\" title=\"Diagnostics\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M6 3v6a4 4 0 008 0V3\"/><path d=\"M10 15v2a4 4 0 008 0v-1\"/><circle cx=\"18\" cy=\"14\" r=\"2\"/></svg><span class=\"fp-tab-cap\">Diag</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-badge\" bind-css:display=\"[[this.anyAlarm?'':'none']]\"></span></button><button class=\"fp-tab\" data-tab=\"Trend\" title=\"Trend\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 17l5-6 4 3 6-8\"/><path d=\"M3 21h18\"/></svg><span class=\"fp-tab-cap\">Trend</span></button></div><div class=\"fp-tabs hidden\" data-group=\"advanced\"><button class=\"fp-tab\" data-tab=\"Main\" title=\"Back to Main\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M15 6l-6 6 6 6\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button><button class=\"fp-tab\" data-tab=\"Engineering\" title=\"Engineering\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1\"/></svg></button><button class=\"fp-tab\" data-tab=\"HMI\" title=\"HMI Config\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"14\" rx=\"1\"/><path d=\"M3 8h18\"/></svg></button><button class=\"fp-tab\" data-tab=\"Faults\" title=\"Faults\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M12 4v10\"/><circle cx=\"12\" cy=\"19\" r=\"0.6\"/></svg></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"fp-mai\"><webui-plantpax-components-level-bar id=\"lbar\"></webui-plantpax-components-level-bar><div class=\"fp-pv\"><div class=\"pv-big\">[[this.pv==null?'--':this.pv]]</div><div class=\"pv-eu\">[[this.unit||'']] &nbsp;·&nbsp; <span class=\"pv-mem\">Inp_PV</span></div><div class=\"fp-row\"><span class=\"lbl\">Quality</span><span bind-attr:class=\"[[this.pvBad?'qual bad':(this.pvUncertain?'qual unc':'qual good')]]\">[[this.pvBad?'BAD':(this.pvUncertain?'UNCERTAIN':'GOOD')]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Source</span><span>[[this.substActive?'Substitute':'Input']]</span></div><div class=\"fp-row\"><span class=\"lbl\">Range</span><span>[[this.pvEuMin==null?'--':this.pvEuMin]] &#8212; [[this.pvEuMax==null?'--':this.pvEuMax]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Substitute</span><span>[[this.substActive?'On':'Off']]</span></div></div></div><div class=\"fp-flags\"><webui-plantpax-components-status-flag data-pp=\"1\" field=\"sim\" label=\"Sim\" tone=\"warn\"></webui-plantpax-components-status-flag><webui-plantpax-components-status-flag data-pp=\"1\" field=\"maintByp\" label=\"Maint Byp\" tone=\"warn\"></webui-plantpax-components-status-flag><webui-plantpax-components-status-flag data-pp=\"1\" field=\"substActive\" label=\"Substitute\" tone=\"warn\"></webui-plantpax-components-status-flag><webui-plantpax-components-status-flag data-pp=\"1\" field=\"failAlarm\" label=\"Input Fail\" tone=\"crit\"></webui-plantpax-components-status-flag></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-mrow head\"><span class=\"mnm\"></span><span class=\"mh\">Threshold</span><span class=\"mh\">Deadband</span></div><div class=\"fp-mrow\"><span class=\"mnm\">HiHi</span><input type=\"number\" class=\"mnum\" data-field=\"hiHiLim\" bind-prop:value=\"[[this.hiHiLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"hiHiDB\" bind-prop:value=\"[[this.hiHiDB]]\" placeholder=\"db\"></div><div class=\"fp-mrow\"><span class=\"mnm\">Hi</span><input type=\"number\" class=\"mnum\" data-field=\"hiLim\" bind-prop:value=\"[[this.hiLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"hiDB\" bind-prop:value=\"[[this.hiDB]]\" placeholder=\"db\"></div><div class=\"fp-mrow\"><span class=\"mnm\">Lo</span><input type=\"number\" class=\"mnum\" data-field=\"loLim\" bind-prop:value=\"[[this.loLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"loDB\" bind-prop:value=\"[[this.loDB]]\" placeholder=\"db\"></div><div class=\"fp-mrow\"><span class=\"mnm\">LoLo</span><input type=\"number\" class=\"mnum\" data-field=\"loLoLim\" bind-prop:value=\"[[this.loLoLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"loLoDB\" bind-prop:value=\"[[this.loLoDB]]\" placeholder=\"db\"></div><div class=\"fp-row\" style=\"margin-top:10px\"><span class=\"lbl\">Substitute PV</span><button class=\"fp-btn\" data-subst=\"1\">[[this.substActive?'Use Input':'Use Substitute']]</button></div></div><div data-pane=\"Engineering\" class=\"hidden\"><div class=\"fp-sec\">Raw Input Scaling</div><webui-plantpax-components-scaling-widget data-pp=\"1\" raw-min-field=\"inpRawMin\" raw-max-field=\"inpRawMax\" eu-min-field=\"pvEuMin\" eu-max-field=\"pvEuMax\"></webui-plantpax-components-scaling-widget><div class=\"fp-sec\">PV Source &amp; Quality</div><label class=\"fp-chk\"><input type=\"checkbox\" data-fieldb=\"useChanSrcQ\"><span>Use channel source quality</span><span class=\"m\">Cfg_UseChanSrcQ</span></label><label class=\"fp-chk\"><input type=\"checkbox\" data-fieldb=\"noSubstPV\"><span>Disable substitute PV selection</span><span class=\"m\">Cfg_NoSubstPV</span></label><div class=\"fp-row\"><span class=\"lbl cfg\"><b>Substitute PV value</b><span class=\"cfgmem\">Set_SubstPV</span></span><input type=\"number\" data-field=\"substPvSet\" bind-prop:value=\"[[this.substPvSet]]\"></div><div class=\"fp-sec\">Filtering &amp; Thresholds</div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>PV filter time constant</b><span class=\"cfgmem\">Cfg_PVFiltTC</span></span><input type=\"number\" data-field=\"filtTC\" bind-prop:value=\"[[this.filtTC]]\"><span class=\"cfgunit\">s</span></div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>Fail High limit</b><span class=\"cfgmem\">Cfg_FailHiLim</span></span><input type=\"number\" data-field=\"failHiLim\" bind-prop:value=\"[[this.failHiLim]]\"></div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>Fail Low limit</b><span class=\"cfgmem\">Cfg_FailLoLim</span></span><input type=\"number\" data-field=\"failLoLim\" bind-prop:value=\"[[this.failLoLim]]\"></div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>PV decimal places</b><span class=\"cfgmem\">Cfg_PVDecPlcs</span></span><input type=\"number\" data-field=\"pvDecPlcs\" bind-prop:value=\"[[this.pvDecPlcs]]\"></div></div><div data-pane=\"Trend\" class=\"hidden\"><div class=\"fp-sec\">PV Trend</div><webui-plantpax-components-sparkline id=\"sparkbig\" style=\"display:block;height:160px\" bind-prop:points=\"120\"></webui-plantpax-components-sparkline><div class=\"fp-row\" style=\"margin-top:6px\"><span class=\"lbl\">Current</span><span>[[this.pv==null?'--':this.pv]] [[this.unit||'']]</span></div></div><div data-pane=\"Diagnostics\" class=\"hidden\"><div class=\"fp-sec\">Signal Chain</div><div class=\"fp-row\"><span class=\"lbl\">Raw / Scaled Input</span><span>[[this.valInpPV==null?'--':this.valInpPV]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Scaled PV (EU)</span><span>[[this.pv==null?'--':this.pv]] [[this.unit||'']]</span></div><div class=\"fp-row\"><span class=\"lbl\">PV Quality</span><span bind-attr:class=\"[[this.pvBad?'qual bad':(this.pvUncertain?'qual unc':'qual good')]]\">[[this.pvBad?'BAD':(this.pvUncertain?'UNCERTAIN':'GOOD')]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Substitute Active</span><span>[[this.substActive?'YES':'no']]</span></div></div><div data-pane=\"Alarms\" class=\"hidden\"><div class=\"fp-almbar\"><span class=\"fp-unack\" bind-css:display=\"[[(this.unackCount||0)>0?'':'none']]\">[[this.unackCount||0]] unacked</span><span class=\"fp-grow\"></span><button class=\"fp-btn\" data-ackall=\"1\">Ack All</button><button class=\"fp-btn ghost\" data-cmd=\"resetAckAll\">Reset &amp; Ack</button><button class=\"fp-btn ghost\" data-cmd=\"resetAll\">Reset</button></div><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"HiHi\" member=\"HiHi.Alm &#183; HiHi.Ack\" alarm-field=\"hiHiAlarm\" ack-field=\"hiHiAck\" severity=\"1000\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"Hi\" member=\"Hi.Alm &#183; Hi.Ack\" alarm-field=\"hiAlarm\" ack-field=\"hiAck\" severity=\"500\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"Lo\" member=\"Lo.Alm &#183; Lo.Ack\" alarm-field=\"loAlarm\" ack-field=\"loAck\" severity=\"500\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"LoLo\" member=\"LoLo.Alm &#183; LoLo.Ack\" alarm-field=\"loLoAlarm\" ack-field=\"loLoAck\" severity=\"1000\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"Fail\" member=\"Fail.Alm &#183; Fail.Ack\" alarm-field=\"failAlarm\" ack-field=\"failAck\" severity=\"1500\"></webui-plantpax-components-alarm-row></div><div data-pane=\"HMI\" class=\"hidden\"><div class=\"fp-sec\">HMI Configuration</div><div class=\"fp-row\"><span class=\"lbl\">Instance</span><span style=\"font-size:11px;word-break:break-all\">[[this.root]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Type</span><span>[[this.type]]</span></div><div class=\"fp-row\"><span class=\"lbl\">EU Units</span><span>[[this.unit||'—']]</span></div></div><div data-pane=\"Faults\" class=\"hidden\"><div class=\"fp-sec\">Faults &amp; Status</div><div class=\"fp-alm\" bind-attr:class=\"[[this.failAlarm?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Input Fail</span></div><div class=\"fp-row\"><span class=\"lbl\">PV Bad</span><span>[[this.pvBad?'YES':'no']]</span></div><div class=\"fp-row\"><span class=\"lbl\">PV Uncertain</span><span>[[this.pvUncertain?'YES':'no']]</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}",
20
+ "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-adv-btn\" title=\"Advanced\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M4 6h10M4 12h16M4 18h7\"/><circle cx=\"17\" cy=\"6\" r=\"2\"/><circle cx=\"14\" cy=\"18\" r=\"2\"/></svg></button><button class=\"fp-x\">✕</button></div><div class=\"fp-desc\">Analog Input &nbsp;&#183;&nbsp; EU: [[this.unit||'&#8212;']]</div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Diagnostics\" title=\"Diagnostics\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M6 3v6a4 4 0 008 0V3\"/><path d=\"M10 15v2a4 4 0 008 0v-1\"/><circle cx=\"18\" cy=\"14\" r=\"2\"/></svg><span class=\"fp-tab-cap\">Diag</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-badge\" bind-css:display=\"[[this.anyAlarm?'':'none']]\"></span></button><button class=\"fp-tab\" data-tab=\"Trend\" title=\"Trend\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 17l5-6 4 3 6-8\"/><path d=\"M3 21h18\"/></svg><span class=\"fp-tab-cap\">Trend</span></button></div><div class=\"fp-tabs hidden\" data-group=\"advanced\"><button class=\"fp-tab\" data-tab=\"Main\" title=\"Back to Main\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M15 6l-6 6 6 6\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button><button class=\"fp-tab\" data-tab=\"Engineering\" title=\"Engineering\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><path d=\"M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1\"/></svg></button><button class=\"fp-tab\" data-tab=\"HMI\" title=\"HMI Config\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"14\" rx=\"1\"/><path d=\"M3 8h18\"/></svg></button><button class=\"fp-tab\" data-tab=\"Faults\" title=\"Faults\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M12 4v10\"/><circle cx=\"12\" cy=\"19\" r=\"0.6\"/></svg></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"fp-mai\"><webui-plantpax-components-level-bar id=\"lbar\"></webui-plantpax-components-level-bar><div class=\"fp-pv\"><div class=\"pv-big\">[[this.pv==null?'--':this.pv]]</div><div class=\"pv-eu\">[[this.unit||'']] &nbsp;·&nbsp; <span class=\"pv-mem\">Inp_PV</span></div><div class=\"fp-row\"><span class=\"lbl\">Quality</span><span bind-attr:class=\"[[this.pvBad?'qual bad':(this.pvUncertain?'qual unc':'qual good')]]\">[[this.pvBad?'BAD':(this.pvUncertain?'UNCERTAIN':'GOOD')]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Source</span><span>[[this.substActive?'Substitute':'Input']]</span></div><div class=\"fp-row\"><span class=\"lbl\">Range</span><span>[[this.pvEuMin==null?'--':this.pvEuMin]] &#8212; [[this.pvEuMax==null?'--':this.pvEuMax]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Substitute</span><span>[[this.substActive?'On':'Off']]</span></div></div></div><div class=\"fp-flags\"><webui-plantpax-components-status-flag data-pp=\"1\" field=\"sim\" label=\"Sim\" tone=\"warn\"></webui-plantpax-components-status-flag><webui-plantpax-components-status-flag data-pp=\"1\" field=\"maintByp\" label=\"Maint Byp\" tone=\"warn\"></webui-plantpax-components-status-flag><webui-plantpax-components-status-flag data-pp=\"1\" field=\"substActive\" label=\"Substitute\" tone=\"warn\"></webui-plantpax-components-status-flag><webui-plantpax-components-status-flag data-pp=\"1\" field=\"failAlarm\" label=\"Input Fail\" tone=\"crit\"></webui-plantpax-components-status-flag></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-mrow head\"><span class=\"mnm\"></span><span class=\"mh\">Threshold</span><span class=\"mh\">Deadband</span></div><div class=\"fp-mrow\"><span class=\"mnm\">HiHi</span><input type=\"number\" class=\"mnum\" data-field=\"hiHiLim\" bind-prop:value=\"[[this.hiHiLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"hiHiDB\" bind-prop:value=\"[[this.hiHiDB]]\" placeholder=\"db\"></div><div class=\"fp-mrow\"><span class=\"mnm\">Hi</span><input type=\"number\" class=\"mnum\" data-field=\"hiLim\" bind-prop:value=\"[[this.hiLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"hiDB\" bind-prop:value=\"[[this.hiDB]]\" placeholder=\"db\"></div><div class=\"fp-mrow\"><span class=\"mnm\">Lo</span><input type=\"number\" class=\"mnum\" data-field=\"loLim\" bind-prop:value=\"[[this.loLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"loDB\" bind-prop:value=\"[[this.loDB]]\" placeholder=\"db\"></div><div class=\"fp-mrow\"><span class=\"mnm\">LoLo</span><input type=\"number\" class=\"mnum\" data-field=\"loLoLim\" bind-prop:value=\"[[this.loLoLim]]\" placeholder=\"limit\"><input type=\"number\" class=\"mnum\" data-field=\"loLoDB\" bind-prop:value=\"[[this.loLoDB]]\" placeholder=\"db\"></div><div class=\"fp-row\" style=\"margin-top:10px\"><span class=\"lbl\">Substitute PV</span><button class=\"fp-btn\" data-subst=\"1\">[[this.substActive?'Use Input':'Use Substitute']]</button></div></div><div data-pane=\"Engineering\" class=\"hidden\"><div class=\"fp-sec\">Raw Input Scaling</div><webui-plantpax-components-scaling-widget data-pp=\"1\" raw-min-field=\"inpRawMin\" raw-max-field=\"inpRawMax\" eu-min-field=\"pvEuMin\" eu-max-field=\"pvEuMax\"></webui-plantpax-components-scaling-widget><div class=\"fp-sec\">PV Source &amp; Quality</div><label class=\"fp-chk\"><input type=\"checkbox\" data-fieldb=\"useChanSrcQ\"><span>Use channel source quality</span><span class=\"m\">Cfg_UseChanSrcQ</span></label><label class=\"fp-chk\"><input type=\"checkbox\" data-fieldb=\"noSubstPV\"><span>Disable substitute PV selection</span><span class=\"m\">Cfg_NoSubstPV</span></label><div class=\"fp-row\"><span class=\"lbl cfg\"><b>Substitute PV value</b><span class=\"cfgmem\">Set_SubstPV</span></span><input type=\"number\" data-field=\"substPvSet\" bind-prop:value=\"[[this.substPvSet]]\"></div><div class=\"fp-sec\">Filtering &amp; Thresholds</div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>PV filter time constant</b><span class=\"cfgmem\">Cfg_PVFiltTC</span></span><input type=\"number\" data-field=\"filtTC\" bind-prop:value=\"[[this.filtTC]]\"><span class=\"cfgunit\">s</span></div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>Fail High limit</b><span class=\"cfgmem\">Cfg_FailHiLim</span></span><input type=\"number\" data-field=\"failHiLim\" bind-prop:value=\"[[this.failHiLim]]\"></div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>Fail Low limit</b><span class=\"cfgmem\">Cfg_FailLoLim</span></span><input type=\"number\" data-field=\"failLoLim\" bind-prop:value=\"[[this.failLoLim]]\"></div><div class=\"fp-row\"><span class=\"lbl cfg\"><b>PV decimal places</b><span class=\"cfgmem\">Cfg_PVDecPlcs</span></span><input type=\"number\" data-field=\"pvDecPlcs\" bind-prop:value=\"[[this.pvDecPlcs]]\"></div></div><div data-pane=\"Trend\" class=\"hidden\"><div class=\"fp-sec\">PV Trend</div><webui-plantpax-components-sparkline id=\"sparkbig\" style=\"display:block;height:160px\" bind-prop:points=\"120\"></webui-plantpax-components-sparkline><div class=\"fp-row\" style=\"margin-top:6px\"><span class=\"lbl\">Current</span><span>[[this.pv==null?'--':this.pv]] [[this.unit||'']]</span></div></div><div data-pane=\"Diagnostics\" class=\"hidden\"><div class=\"fp-sec\">Signal Chain</div><div class=\"fp-row\"><span class=\"lbl\">Raw / Scaled Input</span><span>[[this.valInpPV==null?'--':this.valInpPV]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Scaled PV (EU)</span><span>[[this.pv==null?'--':this.pv]] [[this.unit||'']]</span></div><div class=\"fp-row\"><span class=\"lbl\">PV Quality</span><span bind-attr:class=\"[[this.pvBad?'qual bad':(this.pvUncertain?'qual unc':'qual good')]]\">[[this.pvBad?'BAD':(this.pvUncertain?'UNCERTAIN':'GOOD')]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Substitute Active</span><span>[[this.substActive?'YES':'no']]</span></div></div><div data-pane=\"Alarms\" class=\"hidden\"><div class=\"fp-almbar\"><span class=\"fp-unack\" bind-css:display=\"[[(this.unackCount||0)>0?'':'none']]\">[[this.unackCount||0]] unacked</span><span class=\"fp-grow\"></span><img class=\"fp-cmdimg\" data-ackall=\"1\" title=\"Acknowledge All\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAB4ElEQVRYhcWWvXXjMBCEv/spgNeBSrAC+TmUOpA6OIVeJFYFtiuwEmxKdWB1YOUKjh2cQztTCQ6weNKDfkjaIL0ZCUAzGuwMF76hRNxAxF0B/P4OcOCfPf752TcB4BkogBVArwRE3ANwBVTAI8CPHsHHwIs9DlV9BT0pIOIKoLTHRQTvjQDwBAyAjapfHi50TkDETYG/wA6Yp+ud9sCB5QpgpurX6Z6uFSgNfHUKvFMCZrkx8Aoszu3r5AosZmPaDQ+7Pq3sCiSWe7wE3gkB4B5LO1X/ULc5KwGz3B3BcrMmZ7L1gEn/n9D1c1W/anIupwLxK7duCp6NgIi7Y2+5o7S7VF++ArPcC+HfT1T9ps35HArEtFu2BQdTQMTF0Jio+l3TwyLuidD1laoftgWHvQI7gnfLC3tT8DF7y7W691MEZvZDU8vwOvCC0PXQIO1qCZjsE3t3b4FyqeK9r9MB41MEjETFXsoyzu1pmeWmfFH6WEc2FHElYYJ5JXzJdgdrA2oGjLZ1ZENVPwc2hBnuOVmOabfMAX6SgNWMoMDYrHZyps9RZ5MwSbglwXJQM2C0rV/nFrbb7dtodP1OaLgbe73IJX0tASNRjUbXhRHYqPrbnODQ4Fug6heEjGg0YLStD2XTpfneGuMxAAAAAElFTkSuQmCC\"><img class=\"fp-cmdimg\" data-cmd=\"resetAckAll\" title=\"Reset and Acknowledge All\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAACzElEQVRYhc2Xy3naQBSFf/tzAbgDpQKLCiIqiFxBzHa0AFdgUwH2QrM1qQBcAaQCKxVEHYQSspgzaCSEEPIiuZtBw8w9R/ct+MdydclhY7IISIA7IAYerc2LzxC46Qn8AMwEGkoMFI2zS2DeOLdvngOm1uZlJwFjshRYApG2CuAd2AGFtfm+zwuIQNLYG8EJCxiTjQT8oK0VsLA2L3uA/cRZoKROfNxG+PoE+Fbg/uK0Jzg464B767F0pMBWursJAGsq304uDTK9ZSEdJTAJnt86CRiTPeN85cH7+rgpO62JdHgSqTFZLUAPBJRiTzjT3X8CHFwcAHyFg1XupftJWHUCAof+wXZSrM03+hkHeyXwiot+j1UjkAJ7a/OXz4AHMgV+NPZecFZIfUBewyHfR7h0GyzGZB/GZGsAa/OVtXlNn1yxElZyIIB8ReW7IeBLnMnPxc671m8hAe+r3UDwBFd89sBj11lrc48RhQQinP8vjnz5cq3HvtlTopcOCQztam84n74Eb9eHQBWEfcWYLFXA+uc5LnsKa/NO058S34z2VI2jS2ZAYkw20Z2l1umFuL5MHyxQ9CTwqnVNVdcXl/QLxcyoSaDUn0nXZVW4hRTEwGZA4fIYRUiglptnSDzjiknJ5aaHRs25goNZfuuPL2EqaRyjWdWGSIhjbX4LsoAANzjTNue577T08YEyF4ZvVrU0XOAieha2S+SrMP2GiHTOhLE4IqB26QNsHYxPtd4+ENxXyxHwGrb7o+8CdbMUTUXa/oMrNuOB4Ftc1uyszSfh/22VcEo1w22pynTcNlSeAfc6/Ix53zxzRCCY4Ta6+IHqNsez/SngyJjsTXdjXNq2zpg3/gLdkR5pjQkiOAD0hSnB1RLf3kvc59vRnRoBqsp2zsR3LeAPHJMvcMG2OqPPEVAtv21RHlHvEW01v0CfasAvXKCV54D/G/kL1vcb60D2msYAAAAASUVORK5CYII=\"><img class=\"fp-cmdimg\" data-cmd=\"resetAll\" title=\"Reset\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAACP0lEQVRYhe2XzXHbMBCFv3hUANOBS6ArCFWBlAocX4FD7ApsV2DlQFwdVxCqAjEVWCWoBJaQA3cpEAIpKJQdH7IzGgwhYN/DYv8A/1g+pS40xl4CS2AB5EAGrJwr7yLrLsP9zpV1TO8sATgH7gU8RZ6BIqLH/2yAK+fK3SgBY+wTcOtNbYEXYDt0okTJ5Be3gDE2Aza0pgaogcdE0N8cWmALzJ0rm3DxxRHwBrhxrpyfcGJd1wA3MubARnSPEwjA586VPxOBgZ6zZcjJfRKjBOTOffDtKeCeKIlCdHQkBOOQgHi7OtzdBHBo/QDgC4Do0nC9Faw+AUCZ1aeaPSK1jIVOiE6d76xwAV3y0MWPE8HVDyrgR/CX6i4Es7OAJpmp8e2T+Opc+RAhple79AksZHw5B/gRUYyFT0CdYorjpYpi5D6BDIYLxjklyBPRRPSu8p+AEmgAjLHFWwN6GI1PoOeZbyy9iFMCaxmv34GAYqx9ApWMeXgNxtgHY+yvcyCLbrVA1RFwrtyxLxT3wb7vwPJM/qG6a8HsRYGWy8IY+82bV2KTCIhO1dF10h0Bqdkr+Xzyanavtv8leM6+BK/8XuPgXWCMfcXrimT6VUgmvyMC8A3SojlXXvn/xxLRnDZEwub05DwhZu/A2R9omIC0zj6JZxkh0Q+MsYUxduPt3THQls9kQ46Y+YgM+oEXYtf0E9rB8+2AAK2JG/YnTZbI60mlon3MjPYYM+jywOdAcRFZvxvR1dBe2xqoNM4/vPwBFavdGFxFMCwAAAAASUVORK5CYII=\"></div><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"HiHi\" member=\"HiHi.Alm &#183; HiHi.Ack\" alarm-field=\"hiHiAlarm\" ack-field=\"hiHiAck\" severity=\"1000\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"Hi\" member=\"Hi.Alm &#183; Hi.Ack\" alarm-field=\"hiAlarm\" ack-field=\"hiAck\" severity=\"500\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"Lo\" member=\"Lo.Alm &#183; Lo.Ack\" alarm-field=\"loAlarm\" ack-field=\"loAck\" severity=\"500\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"LoLo\" member=\"LoLo.Alm &#183; LoLo.Ack\" alarm-field=\"loLoAlarm\" ack-field=\"loLoAck\" severity=\"1000\"></webui-plantpax-components-alarm-row><webui-plantpax-components-alarm-row data-pp=\"1\" name=\"Fail\" member=\"Fail.Alm &#183; Fail.Ack\" alarm-field=\"failAlarm\" ack-field=\"failAck\" severity=\"1500\"></webui-plantpax-components-alarm-row></div><div data-pane=\"HMI\" class=\"hidden\"><div class=\"fp-sec\">HMI Configuration</div><div class=\"fp-row\"><span class=\"lbl\">Instance</span><span style=\"font-size:11px;word-break:break-all\">[[this.root]]</span></div><div class=\"fp-row\"><span class=\"lbl\">Type</span><span>[[this.type]]</span></div><div class=\"fp-row\"><span class=\"lbl\">EU Units</span><span>[[this.unit||'—']]</span></div></div><div data-pane=\"Faults\" class=\"hidden\"><div class=\"fp-sec\">Faults &amp; Status</div><div class=\"fp-alm\" bind-attr:class=\"[[this.failAlarm?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Input Fail</span></div><div class=\"fp-row\"><span class=\"lbl\">PV Bad</span><span>[[this.pvBad?'YES':'no']]</span></div><div class=\"fp-row\"><span class=\"lbl\">PV Uncertain</span><span>[[this.pvUncertain?'YES':'no']]</span></div></div></div></div>",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n instance.pv=null; instance.pvBad=false; instance.pvUncertain=false; instance.substActive=false;\n instance.anyAlarm=false;\n const ALM=[\"hiHiAlarm\", \"hiAlarm\", \"loAlarm\", \"loLoAlarm\", \"failAlarm\"];\n const recomputeAlm=function(){ let any=false; for(const a of ALM){ if(instance[a]===true||instance[a]==='true'||instance[a]===1){ any=true; break; } } instance.anyAlarm=any; try{ instance._bindingsRefresh&&instance._bindingsRefresh(); }catch(e){} };\n const subs=[\"pv\", \"pvBad\", \"pvUncertain\", \"substActive\", \"valInpPV\", \"unackCount\", \"hiHiLim\", \"hiHiDB\", \"hiLim\", \"hiDB\", \"loLim\", \"loDB\", \"loLoLim\", \"loLoDB\", \"inpRawMax\", \"inpRawMin\", \"pvEuMax\", \"pvEuMin\", \"filtTC\", \"noSubstPV\", \"hiHiAlarm\", \"hiAlarm\", \"loAlarm\", \"loLoAlarm\", \"failAlarm\", \"useChanSrcQ\", \"substPvSet\", \"failHiLim\", \"failLoLim\", \"pvDecPlcs\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){\n if(field==='pvBad'||field==='pvUncertain'||field==='substActive'){ instance[field]=(v===true||v==='true'||v===1); }\n else { instance[field]=v; }\n if(field==='pv') instance.pv=v;\n if(ALM.indexOf(field)>=0){ instance[field]=(v===true||v==='true'||v===1); recomputeAlm(); }\n }); })(f); }\n // reflect boolean checkbox states from live values\n const setChecks=function(){ for(const cb of instance._getDomElements('[data-fieldb]')){ const f=cb.getAttribute('data-fieldb'); cb.checked=(instance[f]===true||instance[f]==='true'||instance[f]===1); } };\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n if(name==='Engineering') setChecks();\n };\n // switch to the Advanced icon-strip (Engineering/HMI/Faults) and back to Main\n instance._adv=function(){\n for(const g of instance._getDomElements('[data-group]')) g.classList.toggle('hidden', g.getAttribute('data-group')!=='advanced');\n instance._tab('Engineering');\n };\n instance._main=function(){\n for(const g of instance._getDomElements('[data-group]')) g.classList.toggle('hidden', g.getAttribute('data-group')!=='main');\n instance._tab('Home');\n };\n ppWireHeader(instance);\n instance._tab('Home');\n // wire nested components by id (level-bar + sparklines get the EU unit too)\n (function(){ for(const cid of ['lbar','spark','sparkbig']){ const c=instance._getDomElement(cid); if(c){ c.root=instance.root; c.type=instance.type; c.unit=instance.unit;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } } } })();\n // wire composed [data-pp] components (alarm-row / scaling-widget / status-flag): give root/type + start\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n const can=function(action){ return (window.IOB && typeof window.IOB.secCan==='function') ? window.IOB.secCan(action,instance) : true; };\n const gate=function(){\n const cfg=can('configure'), mnt=can('maintenance'), ack=can('ackAlarm');\n for(const i of instance._getDomElements('[data-field],[data-fieldb]')) i.disabled=!cfg;\n for(const b of instance._getDomElements('[data-subst]')) b.classList.toggle('hidden',!mnt);\n for(const b of instance._getDomElements('[data-ack],[data-ackall]')) b.classList.toggle('hidden',!ack);\n for(const i of instance._getDomElements('.fp-mrow input')) i.disabled=!mnt;\n };\n gate();\n try{ window.IOB && window.IOB.securityChanged && window.IOB.securityChanged.on && window.IOB.securityChanged.on(gate); }catch(e){}\n // numeric config writes\n for(const i of instance._getDomElements('[data-field]')){\n (function(inp){ inp.addEventListener('change',function(){ ppWrite(instance,inp.getAttribute('data-field'),Number(inp.value),'configure'); }); })(i);\n }\n // boolean checkbox writes\n for(const cb of instance._getDomElements('[data-fieldb]')){\n (function(box){ box.addEventListener('change',function(){ ppWrite(instance,box.getAttribute('data-fieldb'),box.checked,'configure'); }); })(cb);\n }\n // substitute PV source toggle (maintenance)\n for(const b of instance._getDomElements('[data-subst]')){\n b.addEventListener('click',function(){ if(instance.substActive){ ppWrite(instance,'cmdInpPV',1,'maintenance'); } else { ppWrite(instance,'cmdSubstPV',1,'maintenance'); } });\n }\n // alarm ack\n const ackMap={\"HiHi\": \"hiHiAck\", \"Hi\": \"hiAck\", \"Lo\": \"loAck\", \"LoLo\": \"loLoAck\", \"Fail\": \"failAck\"};\n for(const b of instance._getDomElements('[data-ack]')){\n (function(btn){ btn.addEventListener('click',function(){ const nm=btn.closest('.fp-alm').querySelector('.nm').textContent; ppWrite(instance,ackMap[nm]||btn.getAttribute('data-ack'),1,'ackAlarm'); }); })(b);\n }\n for(const b of instance._getDomElements('[data-ackall]')){\n b.addEventListener('click',function(){ for(const k in ackMap) ppWrite(instance,ackMap[k],1,'ackAlarm'); });\n }\n // global alarm-set commands (Reset & Ack All / Reset)\n for(const b of instance._getDomElements('[data-cmd]')){\n (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'ackAlarm'); }); })(b);\n }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"alarm\" label=\"In Alarm\" oncolor=\"var(--ui-error,#e5484d)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"ack\" label=\"Acked\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"shelved\" label=\"Shelved\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"suppressed\" label=\"Suppressed\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"disabled\" label=\"Disabled\" oncolor=\"var(--ui-dim,#9aa3b0)\"></webui-plantpax-components-status-lamp></div><div class=\"fp-row\"><span class=\"lbl\">Severity</span><span>[[this.severity==null?'--':this.severity]]</span></div><div class=\"mt-cmds\"><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdAck\" label=\"Ack\" value=\"1\" action=\"ackAlarm\"></webui-plantpax-components-command-button><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdShelve\" label=\"Shelve\" value=\"1\" action=\"ackAlarm\"></webui-plantpax-components-command-button><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdDisable\" label=\"Disable\" value=\"1\" action=\"disableAlarm\"></webui-plantpax-components-command-button></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Shelved</span><span>[[this.shelved?'YES':'no']]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-alm\" bind-attr:class=\"[[this.alarm?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Alarm Active</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"alarm\", \"ack\", \"shelved\", \"suppressed\", \"disabled\", \"severity\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"operator\" label=\"Operator\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"program\" label=\"Program\" oncolor=\"var(--accent,#2680eb)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"override\" label=\"Override\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"maint\" label=\"Maintenance\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"local\" label=\"Local\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"extReq\" label=\"External\" oncolor=\"var(--ui-dim,#9aa3b0)\"></webui-plantpax-components-status-lamp></div><div class=\"mt-cmds\"><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdOper\" label=\"Take Operator\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdProg\" label=\"Give Program\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Owner</span><span>[[this.operator?'Operator':(this.program?'Program':'—')]]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-alm\" bind-attr:class=\"[[this.override?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Override Active</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"operator\", \"program\", \"override\", \"maint\", \"local\", \"extReq\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -45,7 +45,7 @@
45
45
  "width": "100%",
46
46
  "height": "auto"
47
47
  },
48
- "html": "<div id=\"ar\" class=\"ar\"><span id=\"sev\" class=\"ar-sev\"></span><span class=\"ar-nm\"><b id=\"nm\"></b><span id=\"mem\" class=\"ar-mem\"></span></span><span id=\"chip\" class=\"ar-chip\"></span><button id=\"ack\" class=\"ar-btn\">ACK</button><button id=\"shelve\" class=\"ar-btn ghost\">Shelve</button></div>",
49
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.ar{display:flex;align-items:center;gap:9px;padding:8px 9px;border:1px solid var(--ui-border,#4a5570);border-radius:6px;margin-bottom:6px;background:var(--ui-surface-2,#2f3545);}.ar-sev{width:10px;height:10px;border-radius:50%;flex:none;background:var(--ui-ok,#30a46c);}.ar.crit{border-left:3px solid var(--ui-error,#e5484d);} .ar.crit .ar-sev{background:var(--ui-error,#e5484d);}.ar.warn{border-left:3px solid var(--ui-warn,#f6b73c);} .ar.warn .ar-sev{background:var(--ui-warn,#f6b73c);}.ar-nm{flex:1;font-size:12px;} .ar-nm b{display:block;} .ar-mem{font:10px monospace;color:var(--ui-dim,#9aa4b2);}.ar-chip{font:10px monospace;padding:2px 7px;border-radius:10px;}.ar-chip.unack{background:rgba(229,72,77,.16);color:var(--ui-error,#e5484d);}.ar-chip.ackd{background:rgba(48,164,108,.16);color:var(--ui-ok,#30a46c);}.ar-chip.shelv,.ar-chip.supp{background:rgba(59,125,216,.16);color:var(--ui-info,#3b7dd8);}.ar-btn{font-size:11px;padding:5px 10px;border-radius:5px;border:1px solid var(--ui-border,#4a5570);background:var(--accent,#2680eb);color:#fff;cursor:pointer;}.ar-btn.ghost{background:transparent;color:var(--ui-text,#e8e8ea);}.ar-btn[disabled]{opacity:.4;cursor:default;}",
50
- "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nfunction ppNum(v){ v=Number(v); return isFinite(v)&&Math.abs(v)<1e30 ? v : null; }\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action||'operate',element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\nfunction ppGate(instance,el,action){\n const g=function(){ const ok=(window.IOB&&typeof window.IOB.secCan==='function')?window.IOB.secCan(action||'operate',instance):true; el.disabled=!ok; el.classList.toggle('pp-nogate',!ok); };\n g(); try{ window.IOB&&window.IOB.securityChanged&&window.IOB.securityChanged.on&&window.IOB.securityChanged.on(g); }catch(e){}\n}\n\nfunction arApply(instance){\n const nm=instance._getDomElement('nm'), mem=instance._getDomElement('mem'), chip=instance._getDomElement('chip'),\n ar=instance._getDomElement('ar'), sh=instance._getDomElement('shelve');\n if(nm) nm.textContent=instance.name||'';\n if(mem) mem.innerHTML=(instance.member||instance.alarmField||'');\n const active=instance.__active===true, ackd=instance.__ackd===true,\n shelved=instance.__shelved===true, supp=instance.__supp===true, dis=instance.__dis===true;\n const sev=(instance.severity|0);\n if(ar){ ar.classList.toggle('crit', sev>=750 || (active&&sev>=500)); ar.classList.toggle('warn', sev>0 && sev<750 && !(sev>=750)); }\n if(chip){\n let s='ackd',t='OK';\n if(dis){s='supp';t='DISABLED';} else if(supp){s='supp';t='SUPPRESSED';}\n else if(shelved){s='shelv';t='SHELVED';} else if(active&&!ackd){s='unack';t='UNACK';}\n else if(active){s='ackd';t='ACTIVE';}\n chip.className='ar-chip '+s; chip.textContent=t;\n }\n if(sh) sh.style.display = instance.__allowShelve ? '' : 'none';\n}\nfunction arStart(instance){\n ppCleanup(instance);\n if(!instance.root){ arApply(instance); return; }\n const sub=(f,k)=>{ if(!instance[f]) return; ppSubscribe(instance,instance[f],function(v){ instance[k]=(v===true||v==='true'||v===1); arApply(instance); }); };\n if(instance.alarmField) ppSubscribe(instance,instance.alarmField,function(v){ instance.__active=(v===true||v==='true'||v===1); arApply(instance); });\n sub('ackField','__ackd'); sub('shelveField','__shelved'); sub('suppressField','__supp'); sub('disableField','__dis');\n arApply(instance);\n}\nexport function init(instance){\n if(!instance||typeof instance._getDomElement!=='function') return;\n instance.__allowShelve = !!instance.shelveField;\n instance._ppReinit=function(){ arStart(instance); };\n const ack=instance._getDomElement('ack'), sh=instance._getDomElement('shelve');\n if(ack) ack.addEventListener('click',function(){ if(instance.ackField) ppWrite(instance,instance.ackField,1,'ackAlarm'); });\n if(sh) sh.addEventListener('click',function(){ if(instance.shelveField) ppWrite(instance,instance.shelveField,1,'ackAlarm'); });\n arStart(instance);\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
48
+ "html": "<div id=\"ar\" class=\"ar\"><img id=\"ico\" class=\"ar-ico\" alt=\"\"><span class=\"ar-nm\"><b id=\"nm\"></b><span id=\"mem\" class=\"ar-mem\"></span></span><span id=\"chip\" class=\"ar-chip\"></span><img id=\"ack\" class=\"ar-ackimg\" alt=\"Ack\" title=\"Acknowledge alarm\"><button id=\"shelve\" class=\"ar-btn ghost\">Shelve</button></div>",
49
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.ar{display:flex;align-items:center;gap:9px;padding:7px 9px;border:1px solid var(--ui-border,#4a5570);border-radius:6px;margin-bottom:6px;background:var(--ui-surface-2,#2f3545);}.ar-ico{width:18px;height:18px;flex:none;object-fit:contain;}.ar.crit{border-left:3px solid var(--ui-error,#e5484d);}.ar.warn{border-left:3px solid var(--ui-warn,#f6b73c);}.ar-nm{flex:1;font-size:12px;} .ar-nm b{display:block;} .ar-mem{font:10px monospace;color:var(--ui-dim,#9aa4b2);}.ar-chip{font:10px monospace;padding:2px 7px;border-radius:10px;}.ar-chip.unack{background:rgba(229,72,77,.16);color:var(--ui-error,#e5484d);}.ar-chip.ackd{background:rgba(48,164,108,.16);color:var(--ui-ok,#30a46c);}.ar-chip.shelv,.ar-chip.supp{background:rgba(59,125,216,.16);color:var(--ui-info,#3b7dd8);}.ar-ackimg{width:32px;height:32px;flex:none;cursor:pointer;}.ar-ackimg.off{opacity:.35;cursor:default;pointer-events:none;}.ar-btn{font-size:11px;padding:5px 10px;border-radius:5px;border:1px solid var(--ui-border,#4a5570);background:transparent;color:var(--ui-text,#e8e8ea);cursor:pointer;}",
50
+ "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nfunction ppNum(v){ v=Number(v); return isFinite(v)&&Math.abs(v)<1e30 ? v : null; }\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action||'operate',element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\nfunction ppGate(instance,el,action){\n const g=function(){ const ok=(window.IOB&&typeof window.IOB.secCan==='function')?window.IOB.secCan(action||'operate',instance):true; el.disabled=!ok; el.classList.toggle('pp-nogate',!ok); };\n g(); try{ window.IOB&&window.IOB.securityChanged&&window.IOB.securityChanged.on&&window.IOB.securityChanged.on(g); }catch(e){}\n}\nconst AR_ICO={\"prio-urg\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA7ElEQVQ4ja2TPQrCQBCFvyyKqPjTK0vKxUobsUwR7AX7iK2CVzIn8Ah6A1OmXHIC8QBi4Sas6//P6+btvMfbYcbDQearGRABgfO0A2Kp07VNepbQBzZA3zV1kAATqVNdGBjxHmi/EOc4AAOpUy0MsbHF5Z5CNBtFd2U0dA3aRoMwf76KXRuHNOZRUbdWi3sp+pmvZoLLwL5FJLid9icIxOue5/jZoHSPPB2Pbxt4ma+2fD+HnQDim1jdztUelHvqkUEszG4nNlufTqiOw6JurZaUuh1XnEidrv+zyuYwBm6SB0hyMVjXmOPTcz4D2MM/n+vtA34AAAAASUVORK5CYII=\", \"prio-hi\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAAuElEQVQ4ja2TPQ6CQBBG344SbRQKEgsSbbWz0Z5rcQCvxRXoOIGdBbGzMFq4ayCz6wbD1y077+3fYAjkdjkcgdoOy7xqG1+dicCZ/dSFJErggV28EvkFS1qQbM9uOgNqW6MFvpVnaUGyO/XrlUQi2/ZlIJGRsJLIH/BAItGySAQo+TyRyutx59ldQ2wHlAZGX+IXzqu2EQDbHGon882+3wcKdkcgJDGLNWa5CsIwQStP/zN5JIRggDfwqlYRazv8jwAAAABJRU5ErkJggg==\", \"prio-med\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA5ElEQVQ4jZ2SvQ3CMBSEvyC6IJTeRcIIbJARMkLYIBswAmICoKShYw5KJBpwkZooinsKnkJ+HEM4yYX17u6d5QMHjFaJ0SpxcTyHOADucl34YV7YeBOHeQYEcrJRCYxWEXARMUABLP0wf/yaYA0EZQVlBWK0thF7BrI9Bbje4HCsR6nMvibYDKSyzloGRqsYcH1bIpzBBNZ3uji1gRQm7rItiJvlaiZwvb2LmuvJ9hTY2ZhlBfOZ1WTlh/nek8pegMgmhkGDB7Cc8K5pTwxwOrd60EUEZJ7R6smnsmNRTIHtn2IAXjXIP+KmEHb7AAAAAElFTkSuQmCC\", \"prio-lo\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAAr0lEQVQ4jWNkgIKJWWsTGBgY5jMQBxLzpwUvYGBgYGBBEoz3SbNgUNKXwqvz3sVnDFtmnYhnYGBYwMDAwMCELMnOxUbQanQ1TDjUMTAwMDDsXnyWYcusE3gNZMEn+fntN4IuwusCYsBwN4CNi5WgAXhjwTXWmOHnt9/ku+DC/jsM108+JN8FT2+9gTC8yDQgqMAWr+0MDGhe+PntF0EN6GqQXbBwy6wTDgRNgKqFMQBgfyntJ+szPQAAAABJRU5ErkJggg==\", \"alm-active\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA7klEQVQ4y52TwU0DMRREHyvm7g7YVIA7IFRAStgO2BJoIRVsCYgKNiWkA9JBfPchXMbBisLGYSTLtjwz/+trDICkKOlb0sgNSBrNjQCdpADMwNaEfkFc3rbALCk8SJqAAByANfAKRODdO8Deor2L7YAeSEg6Stp4D5IGSac/1mDOWdO5OnYNwLQwgtLtzvfQufUEfAEbbmNtbgIOjznnVTWkjwaDPudceKvu4vGJO3Fp0Ddonq8aOA+xwSCa+2tQhSm0zKCEqO5gbKx+7gIYaoMX7sdbbZD+YZCWftzkP4Kj+1nuTbBoduaPPl8d8A9arze4rxI+6AAAAABJRU5ErkJggg==\", \"alm-ackd\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABMUlEQVQ4y42TzW3CQBCFPyy9c3zhjEvg4AKSDoioAOF7IhoIooFIPiOhVBBSgXEFuIO4A/vuw+SQMTLG/DxptdrVmzezb2YBkDSV9CtpzR1IWjt3ChBICoEMOAC1pOhGcATUzs0khSNJOyAESuAZeAWmwJufAfbAF1AA3y7wLyapkjTzPfIS7cp6d84pJvDsuCrAxw0LPnvcMPA3AfwAM+5j5lw6sWcOX5Q+n8+tqqr2fNapoKf+1E83mUzYbrckSXK/NklZP3ue55amafcuuxYcuruW57nFcWybzcaKorDxeNwVqHx2LoKPLWm1WllZlmZmFsfxUDuPZyJD5qVpasvl0m7NBMCofXtn6h7FoWmal2Cwn4+hPlUwYGj7PxZ+tQPqpmkWD0m7qd2WZhfOO/4AYcyI1qa9e8YAAAAASUVORK5CYII=\", \"alm-ackreqd\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABIUlEQVQ4jZWTPW6DQBCFH1FqRP1EQbnSFnELFc2eIxInICeIcwEuQOGaKu64AZR2QR+LgtbiBJPC5idkQfYnrbTa3fdmNDPrwALJPYB3AMHs+Ajgq+u6s00zF5+UUlIUhbRtKyIiZVlKkiRC8kpytyVOlVLSNI3YSNNUSP5sRs/z3CoWEen7XkgKyXjQvCw8dlrr1QCu6yIMQwBYNcCWgY3RgKQ3RNkiiiK7AYD16v7nzWYQP5K+7/sAEA8ZA5jaV5blagfmGGOE5ImkB5IBSamq6iHxwuQAkntjzFNikdt0kry+ArfKZ1n2RA1HPOc+VZ+Li1hr/aeldV0DwOW+Bub7CZIHY8z4mfI8H0Y4WL51Vgw8AN+YRvYC4KPruuPy7S/oGxMb+o3kHQAAAABJRU5ErkJggg==\", \"alm-inactive\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA+0lEQVQ4ja2S0VHDMBBEnzMpwHTgdOAOMAXcQCoglKAO6CCTCnAJyWwB0AHpwO4AdxA+dICRBeiDndHPandvR7qKBJJqYA/cAbXTE3AEgplNc/0qYx6AFgjAlZ/g3OCaT6yTAntgBG6SSb2kI/DsmodsA2CXqwngXHDNEpI6SZfs5XfdRVL3U4Pxr4BU868BXYF5oZ0HXAPnAvPZtV8Bkp6ABjgUBByA1j1UknbEv93kvi8HSQ3wCoQVcAv0pWYAMxuBHrhfE/e9lvRYGuCoIa7yyVs0s4uW+FjTLxzAqcpFSxqAF+LqQnyjzsw2qTZdpA9sfeKbn9a5Bd4B5A5T5qcv+BsAAAAASUVORK5CYII=\", \"alm-shelved\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA0UlEQVQ4jZ2SsW3DMBBFnxwXbg5R2j9BtpC9iTKBnU28gWbIBLY20AZKdTUBNe7swqQRGBFI6wEESOLex+FwFYCkFui48wucgW93D2Sonj8kbYE9sAV27j7kQv5FUidpXCT/CRljR7O8zYi1mW2AT+DDzAYz20zTdHmuXc0Et8AJCMB7vLfFrccuOknXeLq8MR+yTC6lklRzX6L6RTcAX+v4SHJfKDfJWbt7kPQD4O7HElvSIdZnVz1LmsFhoX9Mi9TEU8qjPs2gB8KLM6jdPdwA/uA+o1bOYrQAAAAASUVORK5CYII=\", \"alm-supp\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA9klEQVQ4jaWTMa6DMBBEJyi1DzASEqUlLvFvAgXufRGfAIr8mhPQcQMan8AFbWQusGkgSpD5Ij+vtWZ217N7wQ6SNYAKwM/uaQTwO8/zba/ZhAXJSWstzjkJIciG917athWttZCcSBYp8d1aKzFGOSLGKNZaIXl/MyE5WWsPhXtWk+k5s9b6z8qpTtZx6gxAZYyBUir5NymUUjDGAEAFkuK9P119I4QgJOUKAGVZYlkWdF13qoOmaZDnOQAgO933ESTfMj+L915ISgZg7Pv+48LDMADA+HWM2xj/X6TV4LtVfjF5HtPrboQQxDmXPKZLIpUaH5zzA+va1+Bf11DpAAAAAElFTkSuQmCC\", \"alm-disabled\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAABzUlEQVQ4jXWTMW7iUBRFD6MsgPp9IVEhJIphKmSaQEHNIBYASCzAEQvIzAJssgAka1ZACjoKJg0tjGTqjLBs0aBgNvBSYEeOIVey9PX97v33//tegRxEpAhMgZ9AMdn+D/wBnqIoOmVq7UKOXAY2tVqtOB6PsSyL8/nMbrfDdV2CINgC7aR8lT8cEZl3Oh2N41jziONYu93uRkTqIrJJvmKWXBQR9X3/ipzAS8hvIjJPyXcZA3WAWq125Qx4Msa8JLafoygapT++Zassy7pFHhlj/gFz4DfwIiL1WwLlHPEE9Iwx3wEPGIVhSLL+uPtXAiegbYzpAkPgRxiG98A0ueJNgftmswmwXSwWbWOMB7Qsy+qFYfiYCFEqlQAGn7yKyKrRaOjxeNw4jlNOY3Icp6yqm2wUvu9rtVpVEfFS8rBarerhcPD6/X4rjWm9XrdU9fVWnr7vq4ioiLQQkdVgMPBEJCV7qlpX1bevGkJV1bZtFRHvDnhYLpd1Lhk/VCqVk+u6mxtxfkIQBADlgoj8Ah6BEfDMZZCGk8nkoziOY2azGVz6IIstie1W7lFfbdvW/X6v+/1eO52Oisj18ACFW5tJp02BVPgv0MuOcop37BYZdtrxCIQAAAAASUVORK5CYII=\", \"cmd-ack\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAAB4ElEQVRYhcWWvXXjMBCEv/spgNeBSrAC+TmUOpA6OIVeJFYFtiuwEmxKdWB1YOUKjh2cQztTCQ6weNKDfkjaIL0ZCUAzGuwMF76hRNxAxF0B/P4OcOCfPf752TcB4BkogBVArwRE3ANwBVTAI8CPHsHHwIs9DlV9BT0pIOIKoLTHRQTvjQDwBAyAjapfHi50TkDETYG/wA6Yp+ud9sCB5QpgpurX6Z6uFSgNfHUKvFMCZrkx8Aoszu3r5AosZmPaDQ+7Pq3sCiSWe7wE3gkB4B5LO1X/ULc5KwGz3B3BcrMmZ7L1gEn/n9D1c1W/anIupwLxK7duCp6NgIi7Y2+5o7S7VF++ArPcC+HfT1T9ps35HArEtFu2BQdTQMTF0Jio+l3TwyLuidD1laoftgWHvQI7gnfLC3tT8DF7y7W691MEZvZDU8vwOvCC0PXQIO1qCZjsE3t3b4FyqeK9r9MB41MEjETFXsoyzu1pmeWmfFH6WEc2FHElYYJ5JXzJdgdrA2oGjLZ1ZENVPwc2hBnuOVmOabfMAX6SgNWMoMDYrHZyps9RZ5MwSbglwXJQM2C0rV/nFrbb7dtodP1OaLgbe73IJX0tASNRjUbXhRHYqPrbnODQ4Fug6heEjGg0YLStD2XTpfneGuMxAAAAAElFTkSuQmCC\", \"cmd-ack-disa\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAACXBIWXMAAAsSAAALEgHS3X78AAABvUlEQVRYhcWWbXnCQBCE3/apAOoACeBgcAAOigNQACgAB8EBOGAdFAdFQiT0x+090OMjSbmE/RfujpnM7UwWXlBm1jezAcDHK8CBb3/8fO+aALADesAWoFMCZrYEBsARWAG8dQgu4OCPQ0lH6EgBM+sBhT/OI3hnBIA10AdM0uZyoXUCZjYGvoASmKbrrfbAheV6wETSPt3TtgKFg29vgbdKwC0n4ATM7+1r5Qo8ZmPaDS+7Pq3sCiSWWz0Cb4UAsMDTTtKyanNWAm65GcFykzpnsvWAS/9D6PqppG2dczkViF+5fV3wbATMbMbZcldp96ievgK33IHw9iNJ1uR8DgVi2m2agoMrYGYxNEaSyrqHzWxN6PqjpGFTcDgrUBK8WzzYm4KLs+Ua3fstAhP/o7FneBV4j9D1UCPtKgm47CP/beGB8qjive/TAeNfBJzEkbOURZzb03LLjXlS+lhXNjSzgjDBnAhfsvJirU/FgNG0rmwoaQoYYYbbJcsx7TY5wG8S8JoQFJBb7eZMn6PuJmGScBuC5aBiwMhGwEl88Tcb5s92fSMCTiKmnUkaVe1vWpXfAklzQkbUGjCa1i8+T6S6pgvcmgAAAABJRU5ErkJggg==\"};\n\nfunction arApply(instance){\n const ico=instance._getDomElement('ico'), nm=instance._getDomElement('nm'), mem=instance._getDomElement('mem'),\n chip=instance._getDomElement('chip'), ar=instance._getDomElement('ar'),\n ack=instance._getDomElement('ack'), sh=instance._getDomElement('shelve');\n if(nm) nm.textContent=instance.name||'';\n if(mem) mem.innerHTML=(instance.member||instance.alarmField||'');\n const active=instance.__active===true, ackd=instance.__ackd===true,\n shelved=instance.__shelved===true, supp=instance.__supp===true, dis=instance.__dis===true;\n const sev=(instance.severity|0);\n if(ar){ ar.classList.toggle('crit', sev>=750 || (active&&sev>=500)); ar.classList.toggle('warn', sev>0 && sev<750); }\n // real Rockwell alarm-state icon\n let icoKey='alm-inactive', s='ackd', t='OK';\n if(dis){ icoKey='alm-disabled'; s='supp'; t='DISABLED'; }\n else if(supp){ icoKey='alm-supp'; s='supp'; t='SUPPRESSED'; }\n else if(shelved){ icoKey='alm-shelved'; s='shelv'; t='SHELVED'; }\n else if(active&&!ackd){ icoKey=(sev>=1000?'prio-urg':(sev>=750?'prio-hi':(sev>=250?'prio-med':'prio-lo'))); s='unack'; t='UNACK'; }\n else if(active){ icoKey='alm-ackd'; s='ackd'; t='ACTIVE'; }\n if(ico && AR_ICO[icoKey]) ico.src=AR_ICO[icoKey];\n if(chip){ chip.className='ar-chip '+s; chip.textContent=t; }\n // real ACK command button graphic; dim when nothing to ack\n if(ack){ const needAck=active&&!ackd; ack.src=AR_ICO[needAck?'cmd-ack':'cmd-ack-disa']||''; ack.classList.toggle('off',!needAck); }\n if(sh) sh.style.display = instance.__allowShelve ? '' : 'none';\n}\nfunction arStart(instance){\n ppCleanup(instance);\n if(!instance.root){ arApply(instance); return; }\n const sub=(f,k)=>{ if(!instance[f]) return; ppSubscribe(instance,instance[f],function(v){ instance[k]=(v===true||v==='true'||v===1); arApply(instance); }); };\n if(instance.alarmField) ppSubscribe(instance,instance.alarmField,function(v){ instance.__active=(v===true||v==='true'||v===1); arApply(instance); });\n sub('ackField','__ackd'); sub('shelveField','__shelved'); sub('suppressField','__supp'); sub('disableField','__dis');\n arApply(instance);\n}\nexport function init(instance){\n if(!instance||typeof instance._getDomElement!=='function') return;\n instance.__allowShelve = !!instance.shelveField;\n instance._ppReinit=function(){ arStart(instance); };\n const ack=instance._getDomElement('ack'), sh=instance._getDomElement('shelve');\n if(ack) ack.addEventListener('click',function(){ if(instance.ackField) ppWrite(instance,instance.ackField,1,'ackAlarm'); });\n if(sh) sh.addEventListener('click',function(){ if(instance.shelveField) ppWrite(instance,instance.shelveField,1,'ackAlarm'); });\n arStart(instance);\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
51
51
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"available\" label=\"Available\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp></div><div class=\"fp-row\"><span class=\"lbl\">Process Value</span><span>[[this.pv==null?'--':this.pv]]</span></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Available</span><span>[[this.available?'YES':'no']]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-row\"><span class=\"lbl\">No alarms configured</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"available\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"pv\" label=\"Input On\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"substActive\" label=\"Substitute\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"sim\" label=\"Simulation\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"maintByp\" label=\"Maint Byp\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Substitute</span><span>[[this.substActive?'Active':'—']]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-alm\" bind-attr:class=\"[[this.tgtDisagree?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Target Disagree</span></div><div class=\"fp-alm\" bind-attr:class=\"[[this.ioFault?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">I/O Fault</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"pv\", \"substActive\", \"sim\", \"maintByp\", \"tgtDisagree\", \"ioFault\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"available\" label=\"Available\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"notRdy\" label=\"Not Ready\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp></div><div class=\"mt-cmds\"><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdStart\" label=\"Start\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdStop\" label=\"Stop\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Available</span><span>[[this.available?'YES':'no']]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-alm\" bind-attr:class=\"[[this.ioFault?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">I/O Fault</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"available\", \"notRdy\", \"ioFault\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"pv\" label=\"Output On\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"fdbk\" label=\"Feedback\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"substActive\" label=\"Substitute\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"maintByp\" label=\"Maint Byp\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp></div><div class=\"mt-cmds\"><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdOn\" label=\"On\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdOff\" label=\"Off\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Substitute</span><span>[[this.substActive?'Active':'—']]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-alm\" bind-attr:class=\"[[this.ioFault?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">I/O Fault</span></div><div class=\"fp-alm\" bind-attr:class=\"[[this.fdbkDisagree?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Feedback Disagree</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"pv\", \"fdbk\", \"substActive\", \"maintByp\", \"ioFault\", \"fdbkDisagree\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }
@@ -18,6 +18,6 @@
18
18
  "height": "460px"
19
19
  },
20
20
  "html": "<div class=\"fp\"><div class=\"fp-hdr\"><span class=\"fp-title\">[[this.root]]</span><button class=\"fp-x\">✕</button></div><div class=\"fp-tabs\" data-group=\"main\"><button class=\"fp-tab\" data-tab=\"Home\" title=\"Home\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M3 11l9-8 9 8\"/><path d=\"M5 10v10h14V10\"/></svg><span class=\"fp-tab-cap\">Home</span></button><button class=\"fp-tab\" data-tab=\"Maintenance\" title=\"Maintenance\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M14 6a3.5 3.5 0 00-4.8 4.2l-5 5 1.4 1.4 5-5A3.5 3.5 0 0014 6z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\"1.2\"/></svg><span class=\"fp-tab-cap\">Maint</span></button><button class=\"fp-tab\" data-tab=\"Alarms\" title=\"Alarms\"><svg viewBox=\"0 0 24 24\" class=\"fp-ic\"><path d=\"M18 8a6 6 0 10-12 0c0 7-3 9-3 9h18s-3-2-3-9\"/><path d=\"M13.7 21a2 2 0 01-3.4 0\"/></svg><span class=\"fp-tab-cap\">Alarm</span></button></div><div class=\"fp-body\"><div data-pane=\"Home\"><div class=\"mt-lamps\"><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"inp\" label=\"Input\" oncolor=\"var(--accent,#2680eb)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"out\" label=\"Output\" oncolor=\"var(--ui-ok,#30a46c)\"></webui-plantpax-components-status-lamp><webui-plantpax-components-status-lamp data-pp=\"1\" field=\"gated\" label=\"Gated\" oncolor=\"var(--ui-warn,#f6b73c)\"></webui-plantpax-components-status-lamp></div><div class=\"mt-cmds\"><webui-plantpax-components-command-button data-pp=\"1\" field=\"cmdReset\" label=\"Reset\" value=\"1\" action=\"operate\"></webui-plantpax-components-command-button></div></div><div data-pane=\"Maintenance\" class=\"hidden\"><div class=\"fp-row\"><span class=\"lbl\">Gated</span><span>[[this.gated?'YES':'no']]</span></div><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-top:8px\">Reset &amp; Ack All</button></div><div data-pane=\"Alarms\" class=\"hidden\"><button class=\"fp-btn\" data-cmd=\"resetAckAll\" style=\"margin-bottom:8px\">Reset &amp; Ack All</button><div class=\"fp-alm\" bind-attr:class=\"[[this.gated?'fp-alm active':'fp-alm']]\"><span class=\"fp-chip\"></span><span class=\"nm\">Gate Active</span></div></div></div></div>",
21
- "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
21
+ "style": ":host{display:block;font-family:'Segoe UI',sans-serif;color:var(--ui-text,#e8e8ea);}.fp{display:flex;flex-direction:column;min-width:340px;font-size:13px;background:var(--ui-surface,#1a212b);border-radius:8px;overflow:hidden;}.fp-hdr{display:flex;align-items:center;gap:8px;padding:11px 13px;background:var(--ui-surface-2,#232e3d);}.fp-title{font-weight:640;flex:1;font-size:13px;font-family:monospace;letter-spacing:.01em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.fp-x{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);font-size:15px;opacity:.85;padding:2px 7px;border-radius:4px;}.fp-x:hover{background:rgba(255,255,255,.1);}.fp-adv-btn{cursor:pointer;background:none;border:none;color:var(--ui-text,#e8e8ea);opacity:.85;padding:3px;display:flex;border-radius:4px;}.fp-adv-btn:hover{background:rgba(255,255,255,.1);}.fp-desc{padding:6px 13px;font-size:11.5px;color:var(--ui-dim,#9aa4b2);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tabs{display:flex;background:var(--ui-surface-2,#1e2732);border-bottom:1px solid var(--ui-border,#2b3542);}.fp-tab{flex:1;position:relative;padding:8px 2px;cursor:pointer;background:none;border:none;color:var(--ui-dim,#9aa4b2);display:flex;flex-direction:column;align-items:center;gap:3px;border-right:1px solid var(--ui-border,#222b36);}.fp-tab:last-child{border-right:none;}.fp-tab:hover{color:var(--ui-text,#e8e8ea);}.fp-tab.sel{color:var(--accent,#5b9bff);background:var(--ui-surface,#1a212b);}.fp-tab.sel::after{content:'';position:absolute;bottom:-1px;left:0;right:0;height:2px;background:var(--accent,#5b9bff);}.fp-tab-cap{font-size:9px;letter-spacing:.02em;}.fp-ic{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}.fp-tab-badge{position:absolute;top:5px;right:calc(50% - 15px);width:7px;height:7px;border-radius:50%;background:var(--ui-error,#e5484d);}.fp-body{padding:14px 15px;}.fp-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-top:1px solid var(--ui-border,#222b36);font-size:12.5px;}.fp-row:first-child{border-top:none;}.fp-row .lbl{opacity:.7;}.fp-row input{width:90px;flex:none;text-align:right;padding:4px 8px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-family:monospace;}.fp-btn{padding:5px 11px;background:var(--accent,#2680eb);color:#fff;border:none;border-radius:5px;cursor:pointer;font-size:11px;}.fp-btn.ghost{background:none;border:1px solid var(--ui-border,#4a5570);color:var(--ui-text,#e8e8ea);}.fp-alm{display:flex;align-items:center;gap:8px;margin-bottom:6px;}.fp-chip{width:12px;height:12px;border-radius:50%;background:var(--ui-ok,#30a46c);}.fp-alm.active .fp-chip{background:var(--ui-error,#e5484d);}.fp-alm .nm{flex:1;font-size:12px;}.fp-mai{display:flex;gap:16px;align-items:stretch;}.fp-mai webui-plantpax-components-level-bar{flex:none;}.fp-pv{flex:1;display:flex;flex-direction:column;}.pv-big{font-size:36px;font-weight:710;letter-spacing:-.02em;line-height:1;}.pv-eu{font-size:12px;opacity:.7;margin:3px 0 8px;}.pv-mem{font-family:monospace;font-size:10px;color:var(--accent,#5b9bff);opacity:.8;}.fp-flags{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px;}.fp-sec{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--ui-dim,#9aa4b2);margin:14px 0 8px;padding-bottom:5px;border-bottom:1px solid var(--ui-border,#222b36);}.fp-sec:first-child{margin-top:2px;}.fp-mrow{display:flex;align-items:center;gap:8px;margin-bottom:5px;}.fp-mrow .mnm{width:44px;font-size:12px;opacity:.8;}.fp-mrow .mh{flex:1;text-align:center;font-size:10px;opacity:.6;text-transform:uppercase;}.fp-mrow.head{margin-bottom:6px;}.fp-mrow input.mnum{flex:1;width:0;padding:4px;background:var(--ui-surface-2,#2f3545);color:var(--ui-text,#e8e8ea);border:1px solid var(--ui-border,#4a5570);border-radius:4px;font-size:12px;}.fp-chk{display:flex;align-items:center;gap:8px;font-size:12.5px;margin:8px 0;cursor:pointer;}.fp-chk .m{margin-left:auto;font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.fp-row .lbl.cfg{display:flex;flex-direction:column;gap:1px;opacity:1;}.fp-row .lbl.cfg b{font-weight:500;font-size:12.5px;}.cfgmem{font-family:monospace;font-size:9.5px;color:var(--accent,#5b9bff);opacity:.75;}.cfgunit{font-family:monospace;font-size:11px;color:var(--ui-dim,#9aa4b2);margin-left:6px;}.fp-almbar{display:flex;align-items:center;gap:8px;margin-bottom:12px;}.fp-grow{flex:1;}.fp-unack{font-size:12px;color:var(--ui-error,#e5484d);font-weight:600;}.fp-cmdimg{width:34px;height:34px;cursor:pointer;flex:none;margin-left:4px;border-radius:4px;}.fp-cmdimg:hover{background:rgba(255,255,255,.08);}.qual{font-weight:600;font-size:12px;display:inline-flex;align-items:center;gap:6px;}.qual::after{content:'';width:8px;height:8px;border-radius:50%;background:currentColor;order:2;}.qual.good{color:var(--ui-ok,#30a46c);}.qual.unc{color:var(--ui-warn,#f6b73c);}.qual.bad{color:var(--ui-error,#e5484d);}.hidden{display:none!important;}.mt-lamps{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:14px;}.mt-cmds{display:flex;gap:10px;margin:10px 0;}.mt-cmds webui-plantpax-components-command-button{flex:1;}.mt-mode{display:flex;align-items:center;gap:8px;font-size:12px;margin-top:8px;}.mt-mode .badge{padding:3px 10px;border-radius:10px;font-weight:700;font-size:11px;background:var(--ui-surface-2,#2f3545);}",
22
22
  "script": "\nfunction ppResolve(instance,field){ try{ return window.IOB.resolvePlantPaxField(instance.type,instance.root,field); }catch(e){ return null; } }\nfunction ppSubscribe(instance,field,onVal){\n const id=ppResolve(instance,field); if(!id) return;\n instance.__ppSubs=instance.__ppSubs||[];\n const cb=(_i,s)=>{ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} };\n try{ window.IOB.getState(id).then(function(s){ onVal(s&&s.val); try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }).catch(function(){}); }catch(e){}\n try{ window.IOB.subscribeState(id,cb); instance.__ppSubs.push([id,cb]); }catch(e){}\n}\nfunction ppCleanup(instance){\n for(const pair of (instance.__ppSubs||[])){ try{ window.IOB.unsubscribeState(pair[0],pair[1]); }catch(e){} }\n instance.__ppSubs=[];\n}\nasync function ppWrite(instance,field,val,action){\n const id=ppResolve(instance,field); if(!id) return;\n try{ await window.IOB.secWriteState(id,val,{action:action,element:instance}); }catch(e){ console.warn('[plantpax] write failed',field,e); }\n}\n// wire symbol click -> open faceplate (event bindings can't eval expressions here, so bind imperatively)\nfunction ppWireSymbol(instance){\n const el=instance._getDomElement&&instance._getDomElement('sym'); if(!el) return;\n el.addEventListener('click',function(){ try{ window.IOB && window.IOB.openFaceplate && window.IOB.openFaceplate(instance.type,instance.root); }catch(e){} });\n}\n// wire faceplate header + icon tab-strip clicks imperatively\nfunction ppWireHeader(instance){\n if(!instance._getDomElements) return;\n for(const b of instance._getDomElements('.fp-x')){ b.addEventListener('click',function(){ try{ window.IOB && window.IOB.closeFaceplate && window.IOB.closeFaceplate(); }catch(e){} }); }\n for(const b of instance._getDomElements('.fp-adv-btn')){ b.addEventListener('click',function(){ instance._adv&&instance._adv(); }); }\n for(const t of instance._getDomElements('.fp-tab')){ (function(btn){ btn.addEventListener('click',function(){ const n=btn.getAttribute('data-tab'); if(n==='Main'){ instance._main&&instance._main(); } else { instance._tab&&instance._tab(n); } }); })(t); }\n}\n\nexport function init(instance){\n if(!instance || typeof instance._getDomElement!=='function' || typeof instance._getDomElements!=='function') return;\n const subs=[\"inp\", \"out\", \"gated\"];\n for(const f of subs){ (function(field){ ppSubscribe(instance,field,function(v){ instance[field]=v; try{instance._bindingsRefresh&&instance._bindingsRefresh();}catch(e){} }); })(f); }\n instance._tab=function(name){\n for(const p of instance._getDomElements('[data-pane]')) p.classList.toggle('hidden', p.getAttribute('data-pane')!==name);\n for(const t of instance._getDomElements('.fp-tab')) t.classList.toggle('sel', t.getAttribute('data-tab')===name);\n };\n ppWireHeader(instance);\n instance._tab('Home');\n for(const c of instance._getDomElements('[data-pp]')){ c.root=instance.root; c.type=instance.type;\n if(typeof c._ppReinit==='function'){ c._ppReinit(); } else { (function(cc){ setTimeout(function(){ cc._ppReinit&&cc._ppReinit(); },200); })(c); } }\n for(const b of instance._getDomElements('[data-cmd]')){ (function(btn){ btn.addEventListener('click',function(){ ppWrite(instance,btn.getAttribute('data-cmd'),1,'maintenance'); }); })(b); }\n}\nexport function disconnectedCallback(instance){ ppCleanup(instance); }\n"
23
23
  }