@siliconst/metaui 1.4.21 → 1.4.37

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 (555) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator-dbg.js +22 -20
  4. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator-dbg.js.map +1 -1
  5. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator.d.ts +3 -3
  6. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator.d.ts.map +1 -1
  7. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator.js +1 -1
  8. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator.js.map +1 -1
  9. package/src/nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator.ts +24 -16
  10. package/src/nz/co/siliconst/ui5/metaui/ai/RestLLMProxy-dbg.js.map +1 -1
  11. package/src/nz/co/siliconst/ui5/metaui/ai/RestLLMProxy.js.map +1 -1
  12. package/src/nz/co/siliconst/ui5/metaui/ai/RestLLMProxy.ts +2 -2
  13. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants-dbg.js +111 -0
  14. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants-dbg.js.map +1 -0
  15. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants.d.ts +95 -0
  16. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants.d.ts.map +1 -0
  17. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants.js +2 -0
  18. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants.js.map +1 -0
  19. package/src/nz/co/siliconst/ui5/metaui/constants/MetaUIConstants.ts +101 -0
  20. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControl-dbg.js.map +1 -1
  21. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControl.js.map +1 -1
  22. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControl.ts +1 -1
  23. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControlRenderer-dbg.js.map +1 -1
  24. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControlRenderer.d.ts.map +1 -1
  25. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControlRenderer.js.map +1 -1
  26. package/src/nz/co/siliconst/ui5/metaui/controls/BaseHardwareControlRenderer.ts +2 -1
  27. package/src/nz/co/siliconst/ui5/metaui/controls/CameraControl-dbg.js +2 -2
  28. package/src/nz/co/siliconst/ui5/metaui/controls/CameraControl-dbg.js.map +1 -1
  29. package/src/nz/co/siliconst/ui5/metaui/controls/CameraControl.js +1 -1
  30. package/src/nz/co/siliconst/ui5/metaui/controls/CameraControl.js.map +1 -1
  31. package/src/nz/co/siliconst/ui5/metaui/controls/CameraControl.ts +3 -3
  32. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js +47 -47
  33. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost-dbg.js.map +1 -1
  34. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts +6 -2
  35. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.d.ts.map +1 -1
  36. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js +1 -1
  37. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.js.map +1 -1
  38. package/src/nz/co/siliconst/ui5/metaui/controls/DynamicHost.ts +62 -66
  39. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl-dbg.js +0 -9
  40. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl-dbg.js.map +1 -1
  41. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl.d.ts +0 -9
  42. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl.d.ts.map +1 -1
  43. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl.js +1 -1
  44. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl.js.map +1 -1
  45. package/src/nz/co/siliconst/ui5/metaui/controls/GeolocationControl.ts +3 -9
  46. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl-dbg.js +0 -11
  47. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl-dbg.js.map +1 -1
  48. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl.d.ts +0 -11
  49. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl.d.ts.map +1 -1
  50. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl.js +1 -1
  51. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl.js.map +1 -1
  52. package/src/nz/co/siliconst/ui5/metaui/controls/RichTextControl.ts +2 -9
  53. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl-dbg.js +2 -7
  54. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl-dbg.js.map +1 -1
  55. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl.d.ts +0 -5
  56. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl.d.ts.map +1 -1
  57. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl.js +1 -1
  58. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl.js.map +1 -1
  59. package/src/nz/co/siliconst/ui5/metaui/controls/SignatureControl.ts +3 -7
  60. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl-dbg.js +1 -6
  61. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl-dbg.js.map +1 -1
  62. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl.d.ts +0 -5
  63. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl.d.ts.map +1 -1
  64. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl.js +1 -1
  65. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl.js.map +1 -1
  66. package/src/nz/co/siliconst/ui5/metaui/controls/VoiceInputControl.ts +9 -12
  67. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js +170 -74
  68. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost-dbg.js.map +1 -1
  69. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts +29 -4
  70. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.d.ts.map +1 -1
  71. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js +1 -1
  72. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.js.map +1 -1
  73. package/src/nz/co/siliconst/ui5/metaui/controls/host/GeneratorHost.ts +179 -79
  74. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate-dbg.js +41 -38
  75. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate-dbg.js.map +1 -1
  76. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.d.ts +5 -3
  77. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.d.ts.map +1 -1
  78. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.js +1 -1
  79. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.js.map +1 -1
  80. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DataSyncDelegate.ts +46 -38
  81. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate-dbg.js +41 -2
  82. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate-dbg.js.map +1 -1
  83. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.d.ts +6 -2
  84. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.d.ts.map +1 -1
  85. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.js +1 -1
  86. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.js.map +1 -1
  87. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/DialogDelegate.ts +47 -2
  88. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate-dbg.js.map +1 -1
  89. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts +1 -1
  90. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.d.ts.map +1 -1
  91. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.js.map +1 -1
  92. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ODataDelegate.ts +8 -7
  93. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate-dbg.js +7 -2
  94. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate-dbg.js.map +1 -1
  95. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.d.ts +5 -2
  96. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.d.ts.map +1 -1
  97. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.js +1 -1
  98. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.js.map +1 -1
  99. package/src/nz/co/siliconst/ui5/metaui/controls/host/delegates/ValidationDelegate.ts +10 -5
  100. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js +215 -38
  101. package/src/nz/co/siliconst/ui5/metaui/core/Engine-dbg.js.map +1 -1
  102. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts +21 -3
  103. package/src/nz/co/siliconst/ui5/metaui/core/Engine.d.ts.map +1 -1
  104. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js +1 -1
  105. package/src/nz/co/siliconst/ui5/metaui/core/Engine.js.map +1 -1
  106. package/src/nz/co/siliconst/ui5/metaui/core/Engine.ts +218 -40
  107. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator-dbg.js +86 -0
  108. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator-dbg.js.map +1 -0
  109. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator.d.ts +16 -0
  110. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator.d.ts.map +1 -0
  111. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator.js +2 -0
  112. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator.js.map +1 -0
  113. package/src/nz/co/siliconst/ui5/metaui/core/LayoutMutator.ts +82 -0
  114. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer-dbg.js +142 -0
  115. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer-dbg.js.map +1 -0
  116. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer.d.ts +24 -0
  117. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer.d.ts.map +1 -0
  118. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer.js +2 -0
  119. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer.js.map +1 -0
  120. package/src/nz/co/siliconst/ui5/metaui/core/LayoutScorer.ts +147 -0
  121. package/src/nz/co/siliconst/ui5/metaui/core/PipelineManager-dbg.js +8 -0
  122. package/src/nz/co/siliconst/ui5/metaui/core/PipelineManager-dbg.js.map +1 -1
  123. package/src/nz/co/siliconst/ui5/metaui/core/PipelineManager.d.ts.map +1 -1
  124. package/src/nz/co/siliconst/ui5/metaui/core/PipelineManager.js +1 -1
  125. package/src/nz/co/siliconst/ui5/metaui/core/PipelineManager.js.map +1 -1
  126. package/src/nz/co/siliconst/ui5/metaui/core/PipelineManager.ts +7 -0
  127. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry-dbg.js +153 -50
  128. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry-dbg.js.map +1 -1
  129. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.d.ts +15 -0
  130. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.d.ts.map +1 -1
  131. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.js +1 -1
  132. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.js.map +1 -1
  133. package/src/nz/co/siliconst/ui5/metaui/core/PluginRegistry.ts +164 -53
  134. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine-dbg.js +310 -0
  135. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine-dbg.js.map +1 -0
  136. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine.d.ts +73 -0
  137. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine.d.ts.map +1 -0
  138. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine.js +2 -0
  139. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine.js.map +1 -0
  140. package/src/nz/co/siliconst/ui5/metaui/core/PolicyEngine.ts +307 -0
  141. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js +35 -14
  142. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer-dbg.js.map +1 -1
  143. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.d.ts.map +1 -1
  144. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js +1 -1
  145. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.js.map +1 -1
  146. package/src/nz/co/siliconst/ui5/metaui/core/SchemaNormalizer.ts +40 -15
  147. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator-dbg.js +15 -3
  148. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator-dbg.js.map +1 -1
  149. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.d.ts.map +1 -1
  150. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.js +1 -1
  151. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.js.map +1 -1
  152. package/src/nz/co/siliconst/ui5/metaui/core/SchemaValidator.ts +15 -1
  153. package/src/nz/co/siliconst/ui5/metaui/core/StateManager-dbg.js +82 -16
  154. package/src/nz/co/siliconst/ui5/metaui/core/StateManager-dbg.js.map +1 -1
  155. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.d.ts +16 -0
  156. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.d.ts.map +1 -1
  157. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.js +1 -1
  158. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.js.map +1 -1
  159. package/src/nz/co/siliconst/ui5/metaui/core/StateManager.ts +89 -17
  160. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin-dbg.js.map +1 -1
  161. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.d.ts +12 -1
  162. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.d.ts.map +1 -1
  163. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPlugin.ts +13 -1
  164. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin-dbg.js +2 -0
  165. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin-dbg.js.map +1 -0
  166. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin.d.ts +50 -0
  167. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin.d.ts.map +1 -0
  168. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin.js +2 -0
  169. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin.js.map +1 -0
  170. package/src/nz/co/siliconst/ui5/metaui/interfaces/IPolicyPlugin.ts +49 -0
  171. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema-dbg.js.map +1 -1
  172. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.d.ts +23 -1
  173. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.d.ts.map +1 -1
  174. package/src/nz/co/siliconst/ui5/metaui/interfaces/ISchema.ts +27 -1
  175. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js +31 -36
  176. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout-dbg.js.map +1 -1
  177. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.d.ts.map +1 -1
  178. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js +1 -1
  179. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.js.map +1 -1
  180. package/src/nz/co/siliconst/ui5/metaui/layouts/FormLayout.ts +26 -29
  181. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js +47 -11
  182. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout-dbg.js.map +1 -1
  183. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.d.ts.map +1 -1
  184. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js +1 -1
  185. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.js.map +1 -1
  186. package/src/nz/co/siliconst/ui5/metaui/layouts/TableLayout.ts +48 -12
  187. package/src/nz/co/siliconst/ui5/metaui/library-preload.js +74 -58
  188. package/src/nz/co/siliconst/ui5/metaui/library-preload.js.map +1 -1
  189. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiParserFactory-dbg.js +3 -2
  190. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiParserFactory-dbg.js.map +1 -1
  191. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiParserFactory.d.ts.map +1 -1
  192. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiParserFactory.js +1 -1
  193. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiParserFactory.js.map +1 -1
  194. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiParserFactory.ts +3 -2
  195. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiRefResolver-dbg.js.map +1 -1
  196. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiRefResolver.js.map +1 -1
  197. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiRefResolver.ts +3 -3
  198. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper-dbg.js +2 -1
  199. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper-dbg.js.map +1 -1
  200. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper.d.ts +1 -1
  201. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper.d.ts.map +1 -1
  202. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper.js +1 -1
  203. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper.js.map +1 -1
  204. package/src/nz/co/siliconst/ui5/metaui/openapi/OpenApiUIMapper.ts +4 -3
  205. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/OpenApiHeuristicEngine-dbg.js +2 -2
  206. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/OpenApiHeuristicEngine-dbg.js.map +1 -1
  207. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/OpenApiHeuristicEngine.js.map +1 -1
  208. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/OpenApiHeuristicEngine.ts +2 -2
  209. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/plugins/ProtobufVariantHeuristic-dbg.js +12 -8
  210. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/plugins/ProtobufVariantHeuristic-dbg.js.map +1 -1
  211. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/plugins/ProtobufVariantHeuristic.d.ts.map +1 -1
  212. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/plugins/ProtobufVariantHeuristic.js +1 -1
  213. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/plugins/ProtobufVariantHeuristic.js.map +1 -1
  214. package/src/nz/co/siliconst/ui5/metaui/openapi/heuristics/plugins/ProtobufVariantHeuristic.ts +15 -11
  215. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser-dbg.js +20 -12
  216. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser-dbg.js.map +1 -1
  217. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser.d.ts +4 -4
  218. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser.d.ts.map +1 -1
  219. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser.js +1 -1
  220. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser.js.map +1 -1
  221. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi2Parser.ts +24 -16
  222. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser-dbg.js +18 -11
  223. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser-dbg.js.map +1 -1
  224. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser.d.ts +4 -4
  225. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser.d.ts.map +1 -1
  226. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser.js +1 -1
  227. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser.js.map +1 -1
  228. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApi3Parser.ts +22 -15
  229. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper-dbg.js +24 -100
  230. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper-dbg.js.map +1 -1
  231. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper.d.ts +8 -72
  232. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper.d.ts.map +1 -1
  233. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper.js +1 -1
  234. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper.js.map +1 -1
  235. package/src/nz/co/siliconst/ui5/metaui/openapi/parsers/OpenApiPropertyMapper.ts +45 -108
  236. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin-dbg.js.map +1 -1
  237. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin.d.ts.map +1 -1
  238. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin.js.map +1 -1
  239. package/src/nz/co/siliconst/ui5/metaui/plugins/actions/ClearFormActionPlugin.ts +2 -1
  240. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js +24 -18
  241. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin-dbg.js.map +1 -1
  242. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.d.ts +1 -1
  243. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.d.ts.map +1 -1
  244. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js +1 -1
  245. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.js.map +1 -1
  246. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin.ts +23 -21
  247. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin-dbg.js +5 -5
  248. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin-dbg.js.map +1 -1
  249. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.d.ts +1 -1
  250. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.d.ts.map +1 -1
  251. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.js +1 -1
  252. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.js.map +1 -1
  253. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin.ts +7 -7
  254. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin-dbg.js +129 -9
  255. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin-dbg.js.map +1 -1
  256. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.d.ts +46 -10
  257. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.d.ts.map +1 -1
  258. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.js +1 -1
  259. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.js.map +1 -1
  260. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BasePlugin.ts +145 -15
  261. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin-dbg.js +35 -14
  262. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin-dbg.js.map +1 -1
  263. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.d.ts +1 -1
  264. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.d.ts.map +1 -1
  265. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.js +1 -1
  266. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.js.map +1 -1
  267. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin.ts +38 -14
  268. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin-dbg.js +4 -4
  269. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin-dbg.js.map +1 -1
  270. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.d.ts +1 -1
  271. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.d.ts.map +1 -1
  272. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.js +1 -1
  273. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.js.map +1 -1
  274. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin.ts +5 -5
  275. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js +69 -20
  276. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin-dbg.js.map +1 -1
  277. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.d.ts +2 -1
  278. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.d.ts.map +1 -1
  279. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js +1 -1
  280. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.js.map +1 -1
  281. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin.ts +77 -21
  282. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin-dbg.js +3 -3
  283. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin-dbg.js.map +1 -1
  284. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.d.ts +1 -1
  285. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.d.ts.map +1 -1
  286. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.js +1 -1
  287. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.js.map +1 -1
  288. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin.ts +5 -5
  289. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin-dbg.js +3 -3
  290. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin-dbg.js.map +1 -1
  291. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.d.ts +1 -1
  292. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.d.ts.map +1 -1
  293. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.js +1 -1
  294. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.js.map +1 -1
  295. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin.ts +5 -5
  296. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin-dbg.js +1 -0
  297. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin-dbg.js.map +1 -1
  298. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin.d.ts.map +1 -1
  299. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin.js +1 -1
  300. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin.js.map +1 -1
  301. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin.ts +6 -5
  302. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin-dbg.js +8 -3
  303. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin-dbg.js.map +1 -1
  304. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.d.ts +1 -1
  305. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.d.ts.map +1 -1
  306. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.js +1 -1
  307. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.js.map +1 -1
  308. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin.ts +10 -5
  309. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin-dbg.js +3 -3
  310. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin-dbg.js.map +1 -1
  311. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin.d.ts +1 -1
  312. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin.d.ts.map +1 -1
  313. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin.js +1 -1
  314. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin.js.map +1 -1
  315. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin.ts +4 -4
  316. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin-dbg.js +3 -3
  317. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin-dbg.js.map +1 -1
  318. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.d.ts +1 -1
  319. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.d.ts.map +1 -1
  320. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.js +1 -1
  321. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.js.map +1 -1
  322. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin.ts +5 -5
  323. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin-dbg.js +4 -4
  324. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin-dbg.js.map +1 -1
  325. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.d.ts +1 -1
  326. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.d.ts.map +1 -1
  327. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.js +1 -1
  328. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.js.map +1 -1
  329. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin.ts +5 -5
  330. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin-dbg.js +3 -3
  331. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin-dbg.js.map +1 -1
  332. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin.d.ts +1 -1
  333. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin.d.ts.map +1 -1
  334. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin.js +1 -1
  335. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin.js.map +1 -1
  336. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin.ts +4 -4
  337. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin-dbg.js.map +1 -1
  338. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin.d.ts +1 -1
  339. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin.d.ts.map +1 -1
  340. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin.js.map +1 -1
  341. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin.ts +1 -1
  342. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin-dbg.js +7 -6
  343. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin-dbg.js.map +1 -1
  344. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.d.ts +1 -1
  345. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.d.ts.map +1 -1
  346. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.js +1 -1
  347. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.js.map +1 -1
  348. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin.ts +9 -8
  349. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin-dbg.js +2 -2
  350. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin-dbg.js.map +1 -1
  351. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.d.ts +1 -1
  352. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.d.ts.map +1 -1
  353. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.js +1 -1
  354. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.js.map +1 -1
  355. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin.ts +3 -3
  356. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin-dbg.js +36 -21
  357. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin-dbg.js.map +1 -1
  358. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.d.ts +1 -1
  359. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.d.ts.map +1 -1
  360. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.js +1 -1
  361. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.js.map +1 -1
  362. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin.ts +40 -23
  363. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js +9 -6
  364. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin-dbg.js.map +1 -1
  365. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.d.ts +1 -1
  366. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.d.ts.map +1 -1
  367. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js +1 -1
  368. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.js.map +1 -1
  369. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin.ts +10 -8
  370. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin-dbg.js +3 -3
  371. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin-dbg.js.map +1 -1
  372. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin.d.ts +1 -1
  373. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin.d.ts.map +1 -1
  374. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin.js +1 -1
  375. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin.js.map +1 -1
  376. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin.ts +4 -4
  377. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin-dbg.js +3 -3
  378. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin-dbg.js.map +1 -1
  379. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.d.ts +1 -1
  380. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.d.ts.map +1 -1
  381. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.js +1 -1
  382. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.js.map +1 -1
  383. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin.ts +5 -5
  384. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin-dbg.js +29 -12
  385. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin-dbg.js.map +1 -1
  386. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin.d.ts +5 -1
  387. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin.d.ts.map +1 -1
  388. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin.js +1 -1
  389. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin.js.map +1 -1
  390. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin.ts +30 -10
  391. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin-dbg.js +4 -4
  392. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin-dbg.js.map +1 -1
  393. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.d.ts +1 -1
  394. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.d.ts.map +1 -1
  395. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.js +1 -1
  396. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.js.map +1 -1
  397. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin.ts +5 -5
  398. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin-dbg.js +4 -4
  399. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin-dbg.js.map +1 -1
  400. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.d.ts +1 -1
  401. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.d.ts.map +1 -1
  402. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.js +1 -1
  403. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.js.map +1 -1
  404. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin.ts +5 -5
  405. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin-dbg.js +3 -3
  406. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin-dbg.js.map +1 -1
  407. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.d.ts +1 -1
  408. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.d.ts.map +1 -1
  409. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.js +1 -1
  410. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.js.map +1 -1
  411. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin.ts +4 -4
  412. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin-dbg.js +3 -3
  413. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin-dbg.js.map +1 -1
  414. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin.d.ts +1 -1
  415. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin.d.ts.map +1 -1
  416. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin.js +1 -1
  417. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin.js.map +1 -1
  418. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin.ts +5 -5
  419. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin-dbg.js +3 -3
  420. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin-dbg.js.map +1 -1
  421. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.d.ts +1 -1
  422. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.d.ts.map +1 -1
  423. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.js +1 -1
  424. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.js.map +1 -1
  425. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin.ts +4 -4
  426. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin-dbg.js +2 -2
  427. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin-dbg.js.map +1 -1
  428. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.d.ts +1 -1
  429. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.d.ts.map +1 -1
  430. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.js +1 -1
  431. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.js.map +1 -1
  432. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin.ts +3 -3
  433. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js +58 -56
  434. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin-dbg.js.map +1 -1
  435. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.d.ts +2 -5
  436. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.d.ts.map +1 -1
  437. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js +1 -1
  438. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.js.map +1 -1
  439. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin.ts +66 -55
  440. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin-dbg.js +3 -3
  441. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin-dbg.js.map +1 -1
  442. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.d.ts +1 -1
  443. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.d.ts.map +1 -1
  444. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.js +1 -1
  445. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.js.map +1 -1
  446. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin.ts +4 -4
  447. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin-dbg.js +4 -4
  448. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin-dbg.js.map +1 -1
  449. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.d.ts +1 -1
  450. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.d.ts.map +1 -1
  451. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.js +1 -1
  452. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.js.map +1 -1
  453. package/src/nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin.ts +5 -5
  454. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin-dbg.js.map +1 -1
  455. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin.d.ts.map +1 -1
  456. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin.js.map +1 -1
  457. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin.ts +5 -3
  458. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin-dbg.js +2 -1
  459. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin-dbg.js.map +1 -1
  460. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin.d.ts.map +1 -1
  461. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin.js +1 -1
  462. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin.js.map +1 -1
  463. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin.ts +6 -3
  464. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin-dbg.js +30 -9
  465. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin-dbg.js.map +1 -1
  466. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.d.ts +2 -2
  467. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.d.ts.map +1 -1
  468. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.js +1 -1
  469. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.js.map +1 -1
  470. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin.ts +41 -13
  471. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin-dbg.js.map +1 -1
  472. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin.d.ts.map +1 -1
  473. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin.js.map +1 -1
  474. package/src/nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin.ts +5 -3
  475. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin-dbg.js +41 -0
  476. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin-dbg.js.map +1 -0
  477. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin.d.ts +24 -0
  478. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin.d.ts.map +1 -0
  479. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin.js +2 -0
  480. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin.js.map +1 -0
  481. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin.ts +34 -0
  482. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin-dbg.js +41 -0
  483. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin-dbg.js.map +1 -0
  484. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin.d.ts +24 -0
  485. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin.d.ts.map +1 -0
  486. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin.js +2 -0
  487. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin.js.map +1 -0
  488. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin.ts +34 -0
  489. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin-dbg.js +52 -0
  490. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin-dbg.js.map +1 -0
  491. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin.d.ts +30 -0
  492. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin.d.ts.map +1 -0
  493. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin.js +2 -0
  494. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin.js.map +1 -0
  495. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin.ts +45 -0
  496. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin-dbg.js +52 -0
  497. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin-dbg.js.map +1 -0
  498. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin.d.ts +30 -0
  499. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin.d.ts.map +1 -0
  500. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin.js +2 -0
  501. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin.js.map +1 -0
  502. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin.ts +45 -0
  503. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin-dbg.js +41 -0
  504. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin-dbg.js.map +1 -0
  505. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin.d.ts +24 -0
  506. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin.d.ts.map +1 -0
  507. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin.js +2 -0
  508. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin.js.map +1 -0
  509. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin.ts +34 -0
  510. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin-dbg.js +40 -0
  511. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin-dbg.js.map +1 -0
  512. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin.d.ts +28 -0
  513. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin.d.ts.map +1 -0
  514. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin.js +2 -0
  515. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin.js.map +1 -0
  516. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin.ts +34 -0
  517. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin-dbg.js +40 -0
  518. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin-dbg.js.map +1 -0
  519. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin.d.ts +28 -0
  520. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin.d.ts.map +1 -0
  521. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin.js +2 -0
  522. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin.js.map +1 -0
  523. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin.ts +34 -0
  524. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin-dbg.js +40 -0
  525. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin-dbg.js.map +1 -0
  526. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin.d.ts +28 -0
  527. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin.d.ts.map +1 -0
  528. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin.js +2 -0
  529. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin.js.map +1 -0
  530. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin.ts +34 -0
  531. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin-dbg.js +40 -0
  532. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin-dbg.js.map +1 -0
  533. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin.d.ts +28 -0
  534. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin.d.ts.map +1 -0
  535. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin.js +2 -0
  536. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin.js.map +1 -0
  537. package/src/nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin.ts +34 -0
  538. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider-dbg.js +33 -0
  539. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider-dbg.js.map +1 -0
  540. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider.d.ts +14 -0
  541. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider.d.ts.map +1 -0
  542. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider.js +2 -0
  543. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider.js.map +1 -0
  544. package/src/nz/co/siliconst/ui5/metaui/services/SchemaProvider.ts +24 -0
  545. package/src/nz/co/siliconst/ui5/metaui/utils/Logger-dbg.js.map +1 -1
  546. package/src/nz/co/siliconst/ui5/metaui/utils/Logger.d.ts.map +1 -1
  547. package/src/nz/co/siliconst/ui5/metaui/utils/Logger.js.map +1 -1
  548. package/src/nz/co/siliconst/ui5/metaui/utils/Logger.ts +1 -1
  549. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine-dbg.js +0 -75
  550. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine-dbg.js.map +0 -1
  551. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.d.ts +0 -47
  552. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.d.ts.map +0 -1
  553. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.js +0 -2
  554. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.js.map +0 -1
  555. package/src/nz/co/siliconst/ui5/metaui/core/ConditionEngine.ts +0 -72
@@ -1 +1 @@
1
- {"version":3,"file":"library-preload.js","sections":[{"offset":{"line":1,"column":0},"map":{"version":3,"names":["MockLLMProxy","___MockLLMProxy","AIConfig","static","setProxy","proxy","this","activeProxy","getProxy","setEndpointUrl","url","endpointUrl","getEndpointUrl","__exports","__esModule"],"sources":["AIConfig.ts"],"sourcesContent":["/**\n * @file AIConfig.ts\n * @description Global configuration singleton for AI Inference integrations.\n */\nimport { BaseAIGenerator } from \"./BaseAIGenerator\";\nimport { MockLLMProxy } from \"./MockLLMProxy\";\n\nexport class AIConfig {\n private static activeProxy: BaseAIGenerator = new MockLLMProxy();\n private static endpointUrl: string = \"/api/mock/ai\";\n\n /**\n * Sets the active proxy instance (e.g. Mock vs Rest).\n */\n public static setProxy(proxy: BaseAIGenerator): void {\n this.activeProxy = proxy;\n }\n\n /**\n * Gets the current active proxy.\n */\n public static getProxy(): BaseAIGenerator {\n return this.activeProxy;\n }\n\n /**\n * Configures the remote URL for the REST LLM Proxy to hit.\n */\n public static setEndpointUrl(url: string): void {\n this.endpointUrl = url;\n }\n\n /**\n * Gets the configured remote URL.\n */\n public static getEndpointUrl(): string {\n return this.endpointUrl;\n }\n}\n"],"mappings":"AAAA,uGAAA,MAKSA,EAAYC,EAAA,gBAEd,MAAMC,EACTC,mBAA8C,IAAIH,EAClDG,mBAAqC,eAKrC,eAAcC,CAASC,GACnBC,KAAKC,YAAcF,CACvB,CAKA,eAAcG,GACV,OAAOF,KAAKC,WAChB,CAKA,qBAAcE,CAAeC,GACzBJ,KAAKK,YAAcD,CACvB,CAKA,qBAAcE,GACV,OAAON,KAAKK,WAChB,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAX,WAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":2,"column":0},"map":{"version":3,"names":["BaseAIGenerator","generateSchema","data","partialSchema","dataSkeleton","this","buildDataSkeleton","Object","keys","length","type","properties","llmGeneratedSchema","callLLM","deepMergeSchemas","skeleton","definedKeys","key","includes","base","override","merged","overrideVal","baseVal","Array","isArray","__exports","__esModule"],"sources":["BaseAIGenerator.ts"],"sourcesContent":["/**\n * @file BaseAIGenerator.ts\n * @description Abstract base class defining the contract for AI Schema Generation Proxies.\n */\nimport { ISchema } from \"../interfaces/ISchema\";\n\nexport abstract class BaseAIGenerator {\n\n /**\n * Generates a schema dynamically for the provided data payload.\n * @param data The raw data to infer from.\n * @param partialSchema The manual overrides provided by the developer.\n * @returns A promise resolving to the final merged schema.\n */\n public async generateSchema(data: object, partialSchema?: ISchema): Promise<ISchema> {\n // 1. Build a structural skeleton of the data (no real values).\n const dataSkeleton = this.buildDataSkeleton(data, partialSchema);\n\n if (Object.keys(dataSkeleton).length === 0) {\n // Nothing to infer, the partial schema covered everything.\n return partialSchema || { type: \"object\", properties: {} };\n }\n\n // 2. Delegate to the subclass to get the schema from the LLM.\n const llmGeneratedSchema = await this.callLLM(dataSkeleton);\n\n // 3. Deep merge the partial schema over the LLM schema.\n return this.deepMergeSchemas(llmGeneratedSchema, partialSchema);\n }\n\n /**\n * Abstract method implemented by proxies to handle network/mock calls.\n * @param dataSkeleton The structure of unknown fields.\n */\n protected abstract callLLM(dataSkeleton: Record<string, string>): Promise<ISchema>;\n\n /**\n * Strips actual values and ignores fields already defined in the partial schema.\n */\n private buildDataSkeleton(data: unknown, partialSchema?: ISchema): Record<string, string> {\n const skeleton: Record<string, string> = {};\n if (!data || typeof data !== \"object\") return skeleton;\n\n const definedKeys = partialSchema?.properties ? Object.keys(partialSchema.properties) : [];\n\n for (const key of Object.keys(data)) {\n if (!definedKeys.includes(key)) {\n skeleton[key] = `type: ${typeof data[key]}`;\n }\n }\n return skeleton;\n }\n\n /**\n * Merges a manual partial schema over the LLM generated schema.\n */\n private deepMergeSchemas(base: ISchema, override?: ISchema): ISchema {\n if (!override) return base;\n \n const merged: Record<string, unknown> = { ...base };\n for (const key of Object.keys(override)) {\n const overrideVal = (override as any)[key];\n const baseVal = merged[key];\n\n if (baseVal && typeof baseVal === \"object\" && !Array.isArray(baseVal) &&\n overrideVal && typeof overrideVal === \"object\" && !Array.isArray(overrideVal)) {\n merged[key] = { ...baseVal, ...overrideVal };\n } else {\n merged[key] = overrideVal;\n }\n }\n return merged;\n }\n}\n"],"mappings":"AAAA,6FAMO,MAAeA,EAQlB,oBAAaC,CAAeC,EAAcC,GAEtC,MAAMC,EAAeC,KAAKC,kBAAkBJ,EAAMC,GAElD,GAAII,OAAOC,KAAKJ,GAAcK,SAAW,EAAG,CAExC,OAAON,GAAiB,CAAEO,KAAM,SAAUC,WAAY,CAAC,EAC3D,CAGA,MAAMC,QAA2BP,KAAKQ,QAAQT,GAG9C,OAAOC,KAAKS,iBAAiBF,EAAoBT,EACrD,CAWQG,kBAAkBJ,EAAeC,GACrC,MAAMY,EAAmC,CAAC,EAC1C,IAAKb,UAAeA,IAAS,SAAU,OAAOa,EAE9C,MAAMC,EAAcb,GAAeQ,WAAaJ,OAAOC,KAAKL,EAAcQ,YAAc,GAExF,IAAK,MAAMM,KAAOV,OAAOC,KAAKN,GAAO,CACjC,IAAKc,EAAYE,SAASD,GAAM,CAC5BF,EAASE,GAAO,gBAAgBf,EAAKe,IACzC,CACJ,CACA,OAAOF,CACX,CAKQD,iBAAiBK,EAAeC,GACpC,IAAKA,EAAU,OAAOD,EAEtB,MAAME,EAAkC,IAAKF,GAC7C,IAAK,MAAMF,KAAOV,OAAOC,KAAKY,GAAW,CACrC,MAAME,EAAeF,EAAiBH,GACtC,MAAMM,EAAUF,EAAOJ,GAEvB,GAAIM,UAAkBA,IAAY,WAAaC,MAAMC,QAAQF,IACzDD,UAAsBA,IAAgB,WAAaE,MAAMC,QAAQH,GAAc,CAC/ED,EAAOJ,GAAO,IAAKM,KAAYD,EACnC,KAAO,CACHD,EAAOJ,GAAOK,CAClB,CACJ,CACA,OAAOD,CACX,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAA1B,kBAAA,OAAA0B,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":3,"column":0},"map":{"version":3,"names":["BaseAIGenerator","___BaseAIGenerator","Logger","___utils_Logger","MockLLMProxy","callLLM","dataSkeleton","Promise","resolve","info","Object","keys","setTimeout","schema","type","properties","key","metadata","includes","ui","label","this","camelCaseToTitle","toLowerCase","widget","format","str","replace","s","toUpperCase","__exports","__esModule"],"sources":["MockLLMProxy.ts"],"sourcesContent":["/**\n * @file MockLLMProxy.ts\n * @description Simulates an LLM backend call with a timeout.\n */\nimport { BaseAIGenerator } from \"./BaseAIGenerator\";\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { Logger } from \"../utils/Logger\";\n\nexport class MockLLMProxy extends BaseAIGenerator {\n \n protected callLLM(dataSkeleton: Record<string, string>): Promise<ISchema> {\n return new Promise((resolve) => {\n Logger.info(\"[MockLLMProxy]\", \"Simulating AI Schema generation for keys:\", Object.keys(dataSkeleton));\n \n setTimeout(() => {\n const schema: ISchema = {\n type: \"object\",\n properties: {}\n };\n\n // Naive mocked mapping for demo purposes.\n // In reality, the LLM provides this enriched schema.\n for (const key of Object.keys(dataSkeleton)) {\n const metadata: IPropertyMetadata = {\n type: dataSkeleton[key].includes(\"number\") ? \"number\" : \"string\",\n ui: {\n label: this.camelCaseToTitle(key)\n }\n };\n\n if (key.toLowerCase().includes(\"email\")) {\n metadata.ui!.widget = \"email\";\n metadata.ui!.format = \"email\";\n } else if (key.toLowerCase().includes(\"phone\")) {\n metadata.ui!.widget = \"phone\";\n metadata.ui!.format = \"phone\";\n } else if (key.toLowerCase().includes(\"date\")) {\n metadata.ui!.widget = \"date\";\n } else if (key.toLowerCase().includes(\"active\") || key.toLowerCase().includes(\"is\")) {\n metadata.type = \"boolean\";\n metadata.ui!.widget = \"switch\";\n } else if (key.toLowerCase().includes(\"limit\") || key.toLowerCase().includes(\"amount\") || key.toLowerCase().includes(\"salary\")) {\n metadata.type = \"number\";\n metadata.ui!.widget = \"currency\";\n }\n\n schema.properties![key] = metadata;\n }\n\n Logger.info(\"[MockLLMProxy]\", \"Schema generation complete.\");\n resolve(schema);\n }, 1500); // Emulate 1.5s network/LLM latency\n });\n }\n\n private camelCaseToTitle(str: string): string {\n return str.replace(/([A-Z])/g, ' $1').replace(/^./, (s) => s.toUpperCase());\n }\n}\n"],"mappings":"AAAA,kIAAA,MAISA,EAAeC,EAAA,yBAEfC,EAAMC,EAAA,UAER,MAAMC,UAAqBJ,EAEpBK,QAAQC,GACd,OAAO,IAAIC,QAASC,IAChBN,EAAOO,KAAK,iBAAkB,4CAA6CC,OAAOC,KAAKL,IAEvFM,WAAW,KACP,MAAMC,EAAkB,CACpBC,KAAM,SACNC,WAAY,CAAC,GAKjB,IAAK,MAAMC,KAAON,OAAOC,KAAKL,GAAe,CACzC,MAAMW,EAA8B,CAChCH,KAAMR,EAAaU,GAAKE,SAAS,UAAY,SAAW,SACxDC,GAAI,CACAC,MAAOC,KAAKC,iBAAiBN,KAIrC,GAAIA,EAAIO,cAAcL,SAAS,SAAU,CACrCD,EAASE,GAAIK,OAAS,QACtBP,EAASE,GAAIM,OAAS,OAC1B,MAAO,GAAIT,EAAIO,cAAcL,SAAS,SAAU,CAC5CD,EAASE,GAAIK,OAAS,QACtBP,EAASE,GAAIM,OAAS,OAC1B,MAAO,GAAIT,EAAIO,cAAcL,SAAS,QAAS,CAC3CD,EAASE,GAAIK,OAAS,MAC1B,MAAO,GAAIR,EAAIO,cAAcL,SAAS,WAAaF,EAAIO,cAAcL,SAAS,MAAO,CACjFD,EAASH,KAAO,UAChBG,EAASE,GAAIK,OAAS,QAC1B,MAAO,GAAIR,EAAIO,cAAcL,SAAS,UAAYF,EAAIO,cAAcL,SAAS,WAAaF,EAAIO,cAAcL,SAAS,UAAW,CAC5HD,EAASH,KAAO,SAChBG,EAASE,GAAIK,OAAS,UAC1B,CAEAX,EAAOE,WAAYC,GAAOC,CAC9B,CAEAf,EAAOO,KAAK,iBAAkB,+BAC9BD,EAAQK,IACT,OAEX,CAEQS,iBAAiBI,GACrB,OAAOA,EAAIC,QAAQ,WAAY,OAAOA,QAAQ,KAAOC,GAAMA,EAAEC,cACjE,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA1B,eAAA,OAAA0B,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":4,"column":0},"map":{"version":3,"names":["BaseAIGenerator","___BaseAIGenerator","Logger","___utils_Logger","AIConfig","___AIConfig","RestLLMProxy","callLLM","dataSkeleton","endpoint","getEndpointUrl","Error","info","response","fetch","method","headers","body","JSON","stringify","skeleton","ok","status","schema","json","e","error","message","type","properties","__exports","__esModule"],"sources":["RestLLMProxy.ts"],"sourcesContent":["/**\n * @file RestLLMProxy.ts\n * @description Real HTTP REST client for communicating with an external LLM generation endpoint.\n */\nimport { BaseAIGenerator } from \"./BaseAIGenerator\";\nimport { ISchema } from \"../interfaces/ISchema\";\nimport { Logger } from \"../utils/Logger\";\nimport { AIConfig } from \"./AIConfig\";\n\nexport class RestLLMProxy extends BaseAIGenerator {\n\n protected async callLLM(dataSkeleton: Record<string, string>): Promise<ISchema> {\n const endpoint = AIConfig.getEndpointUrl();\n if (!endpoint) {\n throw new Error(\"[RestLLMProxy] No AI Endpoint configured in AIConfig.\");\n }\n\n Logger.info(\"[RestLLMProxy]\", `Sending skeleton to ${endpoint}...`);\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n skeleton: dataSkeleton\n })\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const schema: ISchema = await response.json();\n Logger.info(\"[RestLLMProxy]\", \"Successfully received schema from backend.\");\n return schema;\n } catch (e: Error) {\n Logger.error(\"[RestLLMProxy]\", `Failed to fetch LLM schema: ${e.message}`);\n // Fallback to empty schema on error so the app doesn't crash completely\n return { type: \"object\", properties: {} };\n }\n }\n}\n"],"mappings":"AAAA,iJAAA,MAISA,EAAeC,EAAA,yBAEfC,EAAMC,EAAA,gBACNC,EAAQC,EAAA,YAEV,MAAMC,UAAqBN,EAE9B,aAAgBO,CAAQC,GACpB,MAAMC,EAAWL,EAASM,iBAC1B,IAAKD,EAAU,CACX,MAAM,IAAIE,MAAM,wDACpB,CAEAT,EAAOU,KAAK,iBAAkB,uBAAuBH,QAErD,IACI,MAAMI,QAAiBC,MAAML,EAAU,CACnCM,OAAQ,OACRC,QAAS,CACL,eAAgB,oBAEpBC,KAAMC,KAAKC,UAAU,CACjBC,SAAUZ,MAIlB,IAAKK,EAASQ,GAAI,CACd,MAAM,IAAIV,MAAM,uBAAuBE,EAASS,SACpD,CAEA,MAAMC,QAAwBV,EAASW,OACvCtB,EAAOU,KAAK,iBAAkB,8CAC9B,OAAOW,CACX,CAAE,MAAOE,GACLvB,EAAOwB,MAAM,iBAAkB,+BAA+BD,EAAEE,WAEhE,MAAO,CAAEC,KAAM,SAAUC,WAAY,CAAC,EAC1C,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAxB,eAAA,OAAAwB,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":5,"column":0},"map":{"version":3,"names":["BaseHardwareControlRenderer","_interopRequireDefault","__BaseHardwareControlRenderer","BaseHardwareControl","Control","extend","renderer","metadata","properties","value","type","defaultValue","schemaMetadata","readOnly","aggregations","_content","multiple","visibility","events","capture","parameters","setValueAndFire","_setValueAndFire","val","this","setProperty","fireEvent","renderContent","_renderContent","rm","control"],"sources":["BaseHardwareControl.ts"],"sourcesContent":["/**\n * @file BaseHardwareControl.ts\n * @description Foundational UI5 Custom Control for hardware plugins.\n * Exposes a standard 'value' property for pure two-way data binding.\n * \n */\n\nimport Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport BaseHardwareControlRenderer from \"./BaseHardwareControlRenderer\";\n\n/**\n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class BaseHardwareControl extends Control {\n static readonly metadata = {\n properties: {\n /** The raw data value. Two-way bound to the model. */\n value: { type: \"any\", defaultValue: null },\n /** The schema metadata for rendering dynamic hints (like labels/readOnly) */\n schemaMetadata: { type: \"object\", defaultValue: null },\n /** Indicates if the control should be in a read-only state */\n readOnly: { type: \"boolean\", defaultValue: false }\n },\n aggregations: {\n _content: { type: \"sap.m.VBox\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n /** Fired when the hardware successfully captures a value */\n capture: {\n parameters: {\n value: { type: \"any\" }\n }\n }\n }\n };\n\n /**\n * Updates the bound value and fires the capture event.\n */\n public setValueAndFire(val: unknown): void {\n this.setProperty(\"value\", val, true); // true to suppress re-rendering if desired, but we want the binding to update\n this.fireEvent(\"capture\", { value: val });\n }\n\n /**\n * Common renderer for all hardware controls\n */\n static readonly renderer = BaseHardwareControlRenderer;\n\n /**\n * Abstract hook for subclasses to render their specific DOM/Controls.\n */\n public renderContent(rm: RenderManager, control: BaseHardwareControl): void {\n // To be overridden by hardware implementations\n }\n}\n"],"mappings":"AAAA,sPAUOA,EAA2BC,EAAAC,GAElC,MAGqBC,EAA4BC,EAAOC,OAAA,2DAkCpCC,SAAWN,EAjCXO,SAAW,CACvBC,WAAY,CAERC,MAAO,CAAEC,KAAM,MAAOC,aAAc,MAEpCC,eAAgB,CAAEF,KAAM,SAAUC,aAAc,MAEhDE,SAAU,CAAEH,KAAM,UAAWC,aAAc,QAE/CG,aAAc,CACVC,SAAU,CAAEL,KAAM,aAAcM,SAAU,MAAOC,WAAY,WAEjEC,OAAQ,CAEJC,QAAS,CACLC,WAAY,CACRX,MAAO,CAAEC,KAAM,WASxBW,gBAAe,SAAAC,EAACC,GACnBC,KAAKC,YAAY,QAASF,EAAK,MAC/BC,KAAKE,UAAU,UAAW,CAAEjB,MAAOc,GACvC,EAUOI,cAAa,SAAAC,EAACC,EAAmBC,GACpC,IACH,OAzCgB3B,CAAmB","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":6,"column":0},"map":{"version":3,"names":["__exports","apiVersion","render","rm","control","openStart","class","openEnd","content","getAggregation","renderControl","renderContent","close"],"sources":["BaseHardwareControlRenderer.ts"],"sourcesContent":["/**\n * @file BaseHardwareControlRenderer.ts\n * @description Standard renderer for all MetaUI hardware controls.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport BaseHardwareControl from \"./BaseHardwareControl\";\n\nexport default {\n apiVersion: 2,\n render: function (rm: RenderManager, control: BaseHardwareControl) {\n rm.openStart(\"div\", control);\n rm.class(\"sapUiSmallMarginBottom\");\n rm.openEnd();\n \n const content = control.getAggregation(\"_content\") as sap.ui.core.Control;\n if (content) {\n rm.renderControl(content);\n }\n \n if (typeof control.renderContent === \"function\") {\n control.renderContent(rm, control);\n }\n \n rm.close(\"div\");\n }\n};\n"],"mappings":"AAAA,+GAAA,IAAAA,EASe,CACXC,WAAY,EACZC,OAAQ,SAAUC,EAAmBC,GACjCD,EAAGE,UAAU,MAAOD,GACpBD,EAAGG,MAAM,0BACTH,EAAGI,UAEH,MAAMC,EAAUJ,EAAQK,eAAe,YACvC,GAAID,EAAS,CACTL,EAAGO,cAAcF,EACrB,CAEA,UAAWJ,EAAQO,gBAAkB,WAAY,CAC7CP,EAAQO,cAAcR,EAAIC,EAC9B,CAEAD,EAAGS,MAAM,MACb,GACH,OAAAZ,CAAA","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":7,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","Logger","___utils_Logger","CameraControl","static","properties","events","videoEl","mediaStream","init","super","this","videoHtml","HTML","content","afterRendering","onVideoRendered","bind","addStyleClass","previewImage","Image","width","visible","startBtn","Button","icon","text","press","handleStartCameraPress","captureBtn","captureImage","retakeBtn","retakeImage","vBox","VBox","items","setAggregation","domRef","getDomRef","val","getValue","startsWith","showPreview","getVisible","startCamera","setVisible","style","display","navigator","mediaDevices","getUserMedia","video","facingMode","srcObject","err","error","message","MessageToast","show","stopCamera","getTracks","forEach","track","stop","canvas","document","createElement","videoWidth","height","videoHeight","ctx","getContext","drawImage","dataUrl","toDataURL","setValueAndFire","setSrc","setValue","value","exit"],"sources":["CameraControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport Button from \"sap/m/Button\";\nimport VBox from \"sap/m/VBox\";\nimport HTML from \"sap/ui/core/HTML\";\nimport MessageToast from \"sap/m/MessageToast\";\nimport Image from \"sap/m/Image\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * CameraControl\n * Provides a live video feed to capture photos.\n */\nexport default class CameraControl extends BaseHardwareControl {\n static readonly renderer = \"nz.co.siliconst.ui5.metaui.controls.BaseHardwareControlRenderer\";\n static readonly metadata = {\n properties: {},\n events: {}\n };\n\n private startBtn!: Button;\n private vBox!: VBox;\n private captureBtn!: Button;\n private retakeBtn!: Button;\n private videoHtml!: HTML;\n private previewImage!: Image;\n \n private videoEl: HTMLVideoElement | null = null;\n private mediaStream: MediaStream | null = null;\n\n /**\n * Initializes the control and builds the internal camera UI.\n */\n public init(): void {\n super.init();\n\n this.videoHtml = new HTML({\n content: \"<video width='400' height='300' autoplay playsinline style='background-color: #000; display: none;'></video>\",\n afterRendering: this.onVideoRendered.bind(this)\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.previewImage = new Image({\n width: \"400px\",\n visible: false\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.startBtn = new Button({\n icon: \"sap-icon://video\",\n text: \"Start Camera\",\n press: this.handleStartCameraPress.bind(this)\n });\n\n this.captureBtn = new Button({\n icon: \"sap-icon://camera\",\n text: \"Capture\",\n visible: false,\n press: this.captureImage.bind(this)\n });\n\n this.retakeBtn = new Button({\n icon: \"sap-icon://undo\",\n text: \"Retake\",\n visible: false,\n press: this.retakeImage.bind(this)\n });\n\n this.vBox = new VBox({\n items: [this.videoHtml, this.previewImage, this.startBtn, this.captureBtn, this.retakeBtn]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n }\n\n private async onVideoRendered(): void {\n const domRef = this.videoHtml.getDomRef() as HTMLElement;\n if (!domRef) return;\n \n this.videoEl = domRef as HTMLVideoElement;\n \n const val = this.getValue();\n if (val && typeof val === \"string\" && val.startsWith(\"data:image\")) {\n this.showPreview(val);\n } else if (this.captureBtn.getVisible() && this.videoHtml.getVisible()) {\n this.startCamera();\n }\n }\n\n private handleStartCameraPress(): void {\n this.startCamera();\n this.startBtn.setVisible(false);\n this.captureBtn.setVisible(true);\n if (this.videoEl) {\n this.videoEl.style.display = \"block\";\n }\n }\n\n private async startCamera(): Promise<void> {\n try {\n this.mediaStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: \"environment\" } });\n if (this.videoEl) {\n this.videoEl.srcObject = this.mediaStream;\n }\n } catch (err) {\n Logger.error(\"Camera access denied or unavailable\", (err as Error).message, \"CameraControl\");\n MessageToast.show(\"Camera access denied or unavailable.\");\n }\n }\n\n private stopCamera(): void {\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach(track => track.stop());\n this.mediaStream = null;\n }\n }\n\n private captureImage(): void {\n if (!this.videoEl) return;\n \n const canvas = document.createElement(\"canvas\");\n canvas.width = this.videoEl.videoWidth || 400;\n canvas.height = this.videoEl.videoHeight || 300;\n \n const ctx = canvas.getContext(\"2d\");\n if (ctx) {\n ctx.drawImage(this.videoEl, 0, 0, canvas.width, canvas.height);\n const dataUrl = canvas.toDataURL(\"image/jpeg\", 0.8);\n this.setValueAndFire(dataUrl);\n this.showPreview(dataUrl);\n MessageToast.show(\"Image captured successfully.\");\n }\n }\n\n private retakeImage(): void {\n this.setValueAndFire(null);\n this.previewImage.setVisible(false);\n this.videoHtml.setVisible(true);\n this.captureBtn.setVisible(true);\n this.retakeBtn.setVisible(false);\n \n // startCamera is now handled safely by onVideoRendered hook\n }\n\n private showPreview(dataUrl: string): void {\n this.stopCamera();\n this.videoHtml.setVisible(false);\n this.previewImage.setSrc(dataUrl);\n this.previewImage.setVisible(true);\n this.captureBtn.setVisible(false);\n this.retakeBtn.setVisible(true);\n }\n\n /**\n * Sets the value of the control programmatically.\n * @param value The base64 data URL string representing the image.\n */\n public setValue(value: unknown): this {\n super.setValue(value);\n if (value && typeof value === \"string\" && value.startsWith(\"data:image\")) {\n this.showPreview(value);\n } else if (!value) {\n // Only retake if we were showing a preview\n if (this.previewImage.getVisible()) {\n this.retakeImage();\n }\n }\n return this;\n }\n\n /**\n * Cleans up the hardware streams when the control is destroyed.\n */\n public exit(): void {\n this.stopCamera();\n super.exit();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":8,"column":0},"map":{"version":3,"names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","ODataDelegate","___host_delegates_ODataDelegate","SchemaBuilderRegistry","___core_SchemaBuilderRegistry","DynamicHost","Control","extend","constructor","prototype","apply","this","arguments","odataDelegate","_innerHost","_initializedInner","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","schemaDefinitions","schemaTarget","pluginRegistry","schemaBuilderRegistry","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","inferenceStrategy","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","error","exception","initODataDelegate","_initODataDelegate","getBindingInfo","dataBinding","path","oContext","getBindingContext","debug","getPath","requestObject","syncToEngine","Object","keys","setBindingContext","_setBindingContext","sModelName","Control.prototype.setBindingContext.call","bindElement","_bindElement","vPath","mParameters","Control.prototype.bindElement.call","model","undefined","oBinding","getElementBinding","attachChange","onBeforeRendering","_onBeforeRendering","schemaRaw","getProperty","startsWith","self","_fetchingSchema","sap","ui","require","BusyIndicator","MessageToast","show","fetch","then","res","ok","Error","status","json","plugin","getBuilderFor","finalSchema","build","Control.prototype.setProperty.call","definitions","hide","invalidate","catch","err","warn","schema","trim","JSON","parse","e","hasSchema","length","hasData","rawDataObj","trace","AIConfig","proxy","getProxy","generateSchema","generatedSchema","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","isLive","str","stringify","fireEvent","_setProperty","propertyName","suppressInvalidate","openInDialog","_openInDialog","title","submitButtonText","cancelButtonText","dialogWidth","parentView","triggerSubmit","_triggerSubmit","addCustomError","_addCustomError","inner","clearCustomError","_clearCustomError","_getProperty"],"sources":["DynamicHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport GeneratorHost from \"./host/GeneratorHost\";\nimport { Logger } from \"../utils/Logger\";\nimport { ODataDelegate } from \"./host/delegates/ODataDelegate\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\nimport { SchemaBuilderRegistry } from \"../core/SchemaBuilderRegistry\";\n\n/**\n * A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode \n * and Inference Mode based on the presence of a 'schemaDefinition'.\n * \n * This maintains total architectural separation of the modes without forcing developers to \n * use different XML tags.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class DynamicHost extends Control {\n private odataDelegate: ODataDelegate | null = null;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n schemaDefinitions: { type: \"object\", defaultValue: null },\n schemaTarget: { type: \"string\", defaultValue: null },\n pluginRegistry: { type: \"object\", defaultValue: null },\n schemaBuilderRegistry: { type: \"object\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true },\n inferenceStrategy: { type: \"string\", defaultValue: \"RuleBased\" }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } },\n error: { parameters: { message: { type: \"string\" }, exception: { type: \"object\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: DynamicHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Internal reference to the generated inner host instance.\n * @private\n */\n private _innerHost: GeneratorHost | null = null;\n\n /**\n * Flag indicating if the inner host has been initialized.\n * @private\n */\n private _initializedInner: boolean = false;\n\n /**\n * Initializes the OData Delegate if an OData context is detected.\n * This allows DynamicHost to seamlessly synchronize metadata and properties from an OData model.\n * @private\n */\n private initODataDelegate(): void {\n if (!this.odataDelegate) {\n // Guard: If the user explicitly bound dataJson, do not steal the context.\n if (this.getBindingInfo(\"dataJson\")) {\n return;\n }\n\n // Guard: If the user explicitly bound 'data' to a specific property path, do not steal the context.\n const dataBinding = this.getBindingInfo(\"data\") as any;\n if (dataBinding && dataBinding.path && dataBinding.path !== \"\") {\n return;\n }\n\n const oContext = this.getBindingContext(\"odata\") || this.getBindingContext();\n if (oContext) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context found for delegate initialization: ${oContext.getPath()}`, \"DynamicHost\");\n if (oContext && (oContext as ODataV4Context).requestObject && typeof (oContext as ODataV4Context).requestObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as ODataV4Context);\n this.odataDelegate.syncToEngine();\n } else {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, \"DynamicHost\");\n }\n }\n }\n }\n\n /**\n * Standard UI5 method override.\n * Sets the binding context for the control and attempts to initialize the OData delegate\n * if the context points to an OData model.\n * \n * @param {sap.ui.model.Context | null | undefined} oContext The binding context object\n * @param {string} [sModelName] Optional model name\n * @returns {this} The control instance for chaining\n */\n public setBindingContext(oContext: sap.ui.model.Context | null | undefined, sModelName?: string): this {\n super.setBindingContext(oContext, sModelName);\n this.initODataDelegate();\n return this;\n }\n\n /**\n * Standard UI5 method override.\n * Binds the element to the given path and attaches a change listener to re-evaluate\n * the OData delegate when the element binding resolves.\n * \n * @param {string | Record<string, unknown>} vPath The binding path or configuration object\n * @param {object} [mParameters] Optional mapping parameters\n * @returns {this} Reference to this instance for chaining\n */\n public bindElement(vPath: string | Record<string, unknown>, mParameters?: object): this {\n super.bindElement(vPath, mParameters);\n const sModelName = typeof vPath === \"object\" ? vPath.model : undefined;\n const oBinding = this.getElementBinding(sModelName);\n if (oBinding) {\n oBinding.attachChange(() => {\n this.initODataDelegate();\n });\n }\n return this;\n }\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the GeneratorHost.\n * It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners \n * down to the inner host perfectly transparently.\n */\n public onBeforeRendering(): void {\n Logger.debug(\"[MetaUI DynamicHost]\", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, \"DynamicHost\");\n\n this.initODataDelegate();\n\n if (!this._initializedInner) {\n let schemaRaw = this.getProperty(\"schemaDefinition\");\n\n // 1. URL Detection & Fetching\n if (typeof schemaRaw === \"string\" && (schemaRaw.startsWith(\"http://\") || schemaRaw.startsWith(\"https://\"))) {\n const self = this as unknown as { _fetchingSchema?: boolean };\n if (self._fetchingSchema) return; // Prevent re-entry\n self._fetchingSchema = true;\n \n sap.ui.require([\"sap/ui/core/BusyIndicator\", \"sap/m/MessageToast\"], (BusyIndicator: { show: (n: number) => void, hide: () => void }, MessageToast: { show: (s: string) => void }) => {\n BusyIndicator.show(0);\n fetch(schemaRaw as string)\n .then(res => {\n if (!res.ok) throw new Error(\"HTTP \" + res.status);\n return res.json();\n })\n .then(json => {\n const plugin = SchemaBuilderRegistry.getBuilderFor(json);\n const finalSchema = plugin ? plugin.build(json, this.getProperty(\"schemaTarget\")) : json;\n super.setProperty(\"schemaDefinition\", finalSchema, true);\n if (finalSchema.definitions) {\n super.setProperty(\"schemaDefinitions\", finalSchema.definitions, true);\n }\n const self = this as unknown as { _fetchingSchema?: boolean };\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate(); // Force re-render with resolved schema\n })\n .catch(err => {\n const self = this as unknown as { _fetchingSchema?: boolean };\n Logger.warn(\"[MetaUI DynamicHost]\", \"Failed to fetch remote schema: \" + err, \"DynamicHost\");\n if (MessageToast) MessageToast.show(\"Failed to fetch remote schema\");\n super.setProperty(\"schemaDefinition\", null, true); // Fallback to full inference\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate();\n });\n });\n return; // Abort this render cycle until fetch completes\n }\n\n // 2. Local Plugin Detection (Stringified JSON or Raw Object)\n let schema = schemaRaw;\n if (schema && typeof schema === \"string\" && (schema as string).trim().startsWith(\"{\")) {\n try {\n schema = JSON.parse(schema);\n } catch (e) {\n // Ignore, let standard validation catch it\n }\n }\n\n if (schema && typeof schema === \"object\") {\n const plugin = SchemaBuilderRegistry.getBuilderFor(schema);\n if (plugin) {\n schema = plugin.build(schema, this.getProperty(\"schemaTarget\"));\n // Silently update the wrapper property so the inner host gets the final parsed MetaUI format\n super.setProperty(\"schemaDefinition\", schema, true);\n if (schema.definitions) {\n super.setProperty(\"schemaDefinitions\", schema.definitions, true);\n }\n }\n }\n\n const dataJson = this.getProperty(\"dataJson\");\n const data = this.getProperty(\"data\");\n\n let hasSchema = !!schema;\n if (hasSchema && typeof schema === \"object\" && Object.keys(schema).length === 0) {\n hasSchema = false; // Treat empty object as no schema\n }\n\n const hasData = !!dataJson || !!data;\n\n // 3. AI Schema Inference Detection\n if (hasData && this.getProperty(\"inferenceStrategy\") === \"AI\") {\n const self = this as unknown as { _fetchingSchema?: boolean };\n if (self._fetchingSchema) return; // Prevent re-entry\n self._fetchingSchema = true;\n\n let rawDataObj = data;\n if (!rawDataObj && dataJson) {\n try { rawDataObj = JSON.parse(dataJson as string); } catch(e: Error) { Logger.trace(\"[DynamicHost] Ignored invalid dataJson parse: \" + e.message); }\n }\n\n if (rawDataObj) {\n sap.ui.require([\n \"sap/ui/core/BusyIndicator\", \n \"sap/m/MessageToast\",\n \"nz/co/siliconst/ui5/metaui/ai/AIConfig\"\n ], (BusyIndicator: { show: (n: number) => void, hide: () => void }, MessageToast: { show: (s: string) => void }, AIConfig: { getProxy: () => { generateSchema: (d: unknown, s?: unknown) => Promise<unknown> } }) => {\n BusyIndicator.show(0);\n const proxy = AIConfig.getProxy();\n \n proxy.generateSchema(rawDataObj, schema || undefined)\n .then((generatedSchema: unknown) => {\n const self = this as unknown as { _fetchingSchema?: boolean };\n super.setProperty(\"schemaDefinition\", generatedSchema, true);\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate(); // Force re-render with the new schema\n })\n .catch((err: Error) => {\n const self = this as unknown as { _fetchingSchema?: boolean };\n Logger.warn(\"[MetaUI DynamicHost]\", \"AI inference failed, falling back to RuleBased. Error: \" + err.message, \"DynamicHost\");\n if (MessageToast) MessageToast.show(\"AI Inference failed, using fallback.\");\n super.setProperty(\"inferenceStrategy\", \"RuleBased\", true); // Fallback to normal inference\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate(); \n });\n });\n return; // Abort render cycle until AI is done\n }\n }\n\n Logger.debug(\"[MetaUI DynamicHost]\", `Evaluating boot. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n\n // Only boot if we have either a schema or some data to infer from\n if (hasSchema || hasData) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Booting inner host. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n }\n // The architectural Facade router logic:\n // We've simplified this! We no longer use HostFactory or separate subclasses.\n // GeneratorHost is fully capable of inferring the schema if none is provided.\n this._innerHost = new GeneratorHost();\n\n // 1. Forward all static values to the spawned host BEFORE mounting.\n // Since we no longer use bindProperty, it's perfectly safe to set raw properties before mounting.\n const props = this.getMetadata().getProperties();\n for (const propName in props) {\n if (propName === \"inferenceStrategy\") continue;\n const val = super.getProperty(propName);\n if (val !== null && val !== undefined) {\n if (propName === \"schemaDefinitions\") {\n Logger.debug(`[MetaUI DynamicHost] Proxying schemaDefinitions: ${Object.keys(val)}`, \"\", \"DynamicHost\");\n }\n this._innerHost.setProperty(propName, val);\n } else if (propName === \"schemaDefinitions\") {\n Logger.warn(`[MetaUI DynamicHost] Warning: schemaDefinitions is null/undefined in Wrapper. Defaulting to empty object in GeneratorHost.`, \"\", \"DynamicHost\");\n }\n }\n\n // 2. Mount so it inherits models and triggers lifecycle.\n this.setAggregation(\"_content\", this._innerHost);\n\n // 3. Forward all event subscriptions.\n // By proxying the events upwards, the developer can subscribe to `<meta:DynamicHost submit=\"...\">` \n // and perfectly receive the inner host's submission event.\n const events = this.getMetadata().getEvents();\n for (const eventName in events) {\n this._innerHost.attachEvent(eventName, (oEvent: sap.ui.base.Event) => {\n // Natively push updated payload out to any bound Fiori Element properties.\n // Using super.setProperty prevents an infinite loop back down to _innerHost.\n if (eventName === \"submit\" || eventName === \"fieldChange\") {\n const params = oEvent.getParameters();\n if (params.payload) {\n const isLive = this.getProperty(\"liveUpdate\") === true;\n if (eventName === \"submit\" || isLive) {\n super.setProperty(\"data\", params.payload, true);\n\n const str = params.payloadJson || JSON.stringify(params.payload, null, 2);\n super.setProperty(\"dataJson\", str, true);\n }\n }\n }\n this.fireEvent(eventName, oEvent.getParameters());\n });\n }\n\n this._initializedInner = true;\n }\n }\n }\n\n /**\n * Overrides standard UI5 setProperty to act as a transparent proxy.\n * When a property is updated on the wrapper (either programmatically or via a binding update),\n * it instantly mirrors that value down to the inner instantiated host.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\" || propertyName === \"schemaDefinitions\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Wrapper received setProperty: ${propertyName}`, \"DynamicHost\");\n }\n }\n super.setProperty(propertyName, value, suppressInvalidate);\n if (this._innerHost && propertyName !== \"inferenceStrategy\") {\n this._innerHost.setProperty(propertyName, value, suppressInvalidate);\n } else if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\" || propertyName === \"schemaDefinitions\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `_innerHost not yet initialized when ${propertyName} was set. Booting will happen on next render.`, \"DynamicHost\");\n }\n }\n return this;\n }\n\n\n\n\n\n /**\n * Programmatic API support. Routes dialog commands down to the spawned inner host.\n * If the inner host has not booted yet, it forces initialization immediately.\n * \n * @param {string} [title=\"Form\"] The title of the dialog\n * @param {string} [submitButtonText=\"OK\"] The text for the primary action button\n * @param {string} [cancelButtonText=\"Cancel\"] The text for the cancel button\n * @param {string} [dialogWidth=\"auto\"] The width of the dialog\n * @param {sap.ui.core.Control} [parentView] The parent view to attach the dialog to for model inheritance.\n */\n public openInDialog(title?: string, submitButtonText?: string, cancelButtonText?: string, dialogWidth?: string, parentView?: Control): void {\n if (!this._innerHost) {\n this.onBeforeRendering(); // Force init if they bypassed UI5 rendering\n }\n this._innerHost?.openInDialog(title, submitButtonText, cancelButtonText, dialogWidth, parentView);\n }\n\n /**\n * Proxies submission triggering down to the instantiated generator host.\n * Evaluates the internal Engine validation suite and returns true if structurally sound.\n * \n * @returns {boolean} True if the internal payload passes schema validation, false otherwise.\n */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return this._innerHost.triggerSubmit();\n }\n\n /**\n * Injects a custom error message onto a specific field.\n * Useful for injecting custom backend validation errors.\n * \n * @param {string} fieldPath The schema key path to target.\n * @param {string} message The custom error message to display.\n */\n public addCustomError(fieldPath: string, message: string): void {\n const inner = this._innerHost as unknown as { addCustomError?: (p: string, m: string) => void };\n if (inner && typeof inner.addCustomError === \"function\") {\n inner.addCustomError(fieldPath, message);\n }\n }\n\n /**\n * Clears a custom error message from a specific field.\n * \n * @param {string} fieldPath The schema key path to target.\n */\n public clearCustomError(fieldPath: string): void {\n const inner = this._innerHost as unknown as { clearCustomError?: (p: string) => void };\n if (inner && typeof inner.clearCustomError === \"function\") {\n inner.clearCustomError(fieldPath);\n }\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n * Ensures that querying the DynamicHost facade for `data` always yields the freshest payload.\n * \n * @param {string} propertyName The name of the property to retrieve\n * @returns {unknown} The property value\n */\n public getProperty(propertyName: string): unknown {\n if (propertyName === \"outputData\") {\n propertyName = \"data\"; // Forward deprecated outputData to data\n }\n if (this._innerHost && (propertyName === \"data\" || propertyName === \"dataJson\")) {\n return this._innerHost.getProperty(propertyName);\n }\n return super.getProperty(propertyName);\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":9,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","BaseHardwareControlRenderer","__BaseHardwareControlRenderer","GeolocationControl","static","aggregations","_content","type","multiple","visibility","init","super","this","locationBtn","Button","icon","text","press","getLocation","bind","resultInput","Input","editable","visible","vBox","VBox","items","setAggregation","onBeforeRendering","metadata","getProperty","ui","label","setText","readOnly","setEnabled","currentVal","setValue","setVisible","navigator","geolocation","MessageToast","show","getCurrentPosition","position","locStr","coords","latitude","longitude","setValueAndFire","error","__ui5_require_async","then","Logger","message"],"sources":["GeolocationControl.ts"],"sourcesContent":["/**\n * @file GeolocationControl.ts\n * @description Native UI5 Control for GPS capture.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nimport BaseHardwareControl from \"./BaseHardwareControl\";\nimport BaseHardwareControlRenderer from \"./BaseHardwareControlRenderer\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport Button from \"sap/m/Button\";\nimport Input from \"sap/m/Input\";\nimport VBox from \"sap/m/VBox\";\nimport MessageToast from \"sap/m/MessageToast\";\n\nexport default class GeolocationControl extends BaseHardwareControl {\n private vBox: VBox;\n private locationBtn: Button;\n private resultInput: Input;\n\n static readonly renderer = BaseHardwareControlRenderer;\n\n static readonly metadata = {\n aggregations: {\n _content: { type: \"sap.m.VBox\", multiple: false, visibility: \"hidden\" }\n }\n };\n\n /**\n * Initializes the control and builds the internal UI components.\n */\n public init(): void {\n super.init();\n\n this.locationBtn = new Button({\n icon: \"sap-icon://map\",\n text: \"Get Location\",\n press: this.getLocation.bind(this)\n });\n\n this.resultInput = new Input({\n editable: false,\n visible: false\n });\n\n this.vBox = new VBox({\n items: [this.locationBtn, this.resultInput]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n }\n\n /**\n * Lifecycle hook called before the control is rendered to the DOM.\n * Updates button state and sets any existing values.\n */\n public onBeforeRendering(): void {\n const metadata = this.getProperty(\"schemaMetadata\");\n if (metadata && metadata.ui && metadata.ui.label) {\n this.locationBtn.setText(metadata.ui.label);\n }\n\n const readOnly = this.getProperty(\"readOnly\");\n this.locationBtn.setEnabled(!readOnly);\n\n const currentVal = this.getProperty(\"value\");\n if (currentVal) {\n this.resultInput.setValue(currentVal as string);\n this.resultInput.setVisible(true);\n }\n }\n\n private getLocation(): void {\n if (!navigator.geolocation) {\n MessageToast.show(\"Geolocation is not supported by your browser\");\n return;\n }\n\n navigator.geolocation.getCurrentPosition(\n (position) => {\n const locStr = `${position.coords.latitude}, ${position.coords.longitude}`;\n this.resultInput.setValue(locStr);\n this.resultInput.setVisible(true);\n this.setValueAndFire(locStr);\n MessageToast.show(\"Location acquired.\");\n },\n (error) => {\n import(\"../utils/Logger\").then(({ Logger }) => {\n Logger.error(\"[MetaUI] Geolocation failed or denied\", error.message, \"GeolocationControl\");\n });\n MessageToast.show(\"Unable to retrieve your location\");\n }\n );\n }\n\n\n}\n"],"mappings":"AAAA,ojBAAA,MAMOA,EAAmBC,EAAAC,GAAA,MACnBC,EAA2BF,EAAAG,GAOnB,MAAMC,UAA2BL,EAK5CM,gBAA2BH,EAE3BG,gBAA2B,CACvBC,aAAc,CACVC,SAAU,CAAEC,KAAM,aAAcC,SAAU,MAAOC,WAAY,YAO9DC,OACHC,MAAMD,OAENE,KAAKC,YAAc,IAAIC,EAAO,CAC1BC,KAAM,iBACNC,KAAM,eACNC,MAAOL,KAAKM,YAAYC,KAAKP,QAGjCA,KAAKQ,YAAc,IAAIC,EAAM,CACzBC,SAAU,MACVC,QAAS,QAGbX,KAAKY,KAAO,IAAIC,EAAK,CACjBC,MAAO,CAACd,KAAKC,YAAaD,KAAKQ,eAGnCR,KAAKe,eAAe,WAAYf,KAAKY,KACzC,CAMOI,oBACH,MAAMC,EAAWjB,KAAKkB,YAAY,kBAClC,GAAID,GAAYA,EAASE,IAAMF,EAASE,GAAGC,MAAO,CAC9CpB,KAAKC,YAAYoB,QAAQJ,EAASE,GAAGC,MACzC,CAEA,MAAME,EAAWtB,KAAKkB,YAAY,YAClClB,KAAKC,YAAYsB,YAAYD,GAE7B,MAAME,EAAaxB,KAAKkB,YAAY,SACpC,GAAIM,EAAY,CACZxB,KAAKQ,YAAYiB,SAASD,GAC1BxB,KAAKQ,YAAYkB,WAAW,KAChC,CACJ,CAEQpB,cACJ,IAAKqB,UAAUC,YAAa,CACxBC,EAAaC,KAAK,gDAClB,MACJ,CAEAH,UAAUC,YAAYG,mBACjBC,IACG,MAAMC,EAAS,GAAGD,EAASE,OAAOC,aAAaH,EAASE,OAAOE,YAC/DpC,KAAKQ,YAAYiB,SAASQ,GAC1BjC,KAAKQ,YAAYkB,WAAW,MAC5B1B,KAAKqC,gBAAgBJ,GACrBJ,EAAaC,KAAK,uBAErBQ,IACGC,EAAO,mBAAmBC,KAAK,EAAGC,aAC9BA,EAAOH,MAAM,wCAAyCA,EAAMI,QAAS,wBAEzEb,EAAaC,KAAK,qCAG9B,EAGH,OAAAvC,CAAA","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":10,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","BaseHardwareControlRenderer","__BaseHardwareControlRenderer","RichTextControl","extend","metadata","properties","events","aggregations","_content","type","multiple","visibility","renderer","init","_init","BaseHardwareControl.prototype.init.call","this","richTextEditor","RichTextEditor","width","height","showGroupFont","showGroupInsert","tooltip","change","oEvent","val","getParameter","setValueAndFire","vBox","VBox","items","setAggregation","onBeforeRendering","_onBeforeRendering","readOnly","getProperty","setEditable","currentVal","undefined","getValue","setValue","_setValue","setProperty"],"sources":["RichTextControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport BaseHardwareControlRenderer from \"./BaseHardwareControlRenderer\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport VBox from \"sap/m/VBox\";\nimport RichTextEditor from \"sap/ui/richtexteditor/RichTextEditor\";\n\n/**\n * @file RichTextControl.ts\n * @description Native UI5 Control for rich text input.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class RichTextControl extends BaseHardwareControl {\n private vBox!: VBox;\n private richTextEditor!: RichTextEditor;\n\n static readonly renderer = BaseHardwareControlRenderer;\n\n static readonly metadata = {\n properties: {},\n events: {},\n aggregations: {\n _content: { type: \"sap.m.VBox\", multiple: false, visibility: \"hidden\" }\n }\n };\n\n public init(): void {\n super.init();\n\n this.richTextEditor = new RichTextEditor({\n width: \"100%\",\n height: \"300px\",\n showGroupFont: true,\n showGroupInsert: true,\n tooltip: \"Rich Text Editor\",\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"newValue\");\n this.setValueAndFire(val);\n }\n });\n\n this.vBox = new VBox({\n items: [this.richTextEditor]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n }\n\n public onBeforeRendering(): void {\n const readOnly = this.getProperty(\"readOnly\");\n this.richTextEditor.setEditable(!readOnly);\n\n const currentVal = this.getProperty(\"value\");\n if (currentVal !== undefined && currentVal !== null) {\n // Prevent recursive update if the value matches the editor's current value\n if (this.richTextEditor.getValue() !== currentVal) {\n this.richTextEditor.setValue(currentVal as string);\n }\n }\n }\n\n /**\n * Overrides the default property setter to prevent full DOM invalidation.\n * When dataJson pushes updates down to the UI5 models, UI5 typically destroys \n * and recreates the custom control if the property changes. \n * By suppressing re-rendering (true flag) and manually passing the value \n * to the inner RichTextEditor, we prevent TinyMCE from tearing down its iframe\n * and triggering expensive, redundant plugin boot sequences.\n *\n * @param {unknown} val The new string value to bind\n * @returns {this} The control instance for chaining\n */\n public setValue(val: unknown): this {\n this.setProperty(\"value\", val, true); // suppress re-rendering\n if (this.richTextEditor && val !== undefined && val !== null) {\n if (this.richTextEditor.getValue() !== val) {\n this.richTextEditor.setValue(val as string);\n }\n }\n return this;\n }\n}\n"],"mappings":"AAAA,4SAAOA,EAAmBC,EAAAC,GAAA,MACnBC,EAA2BF,EAAAG,GAKlC,MAMqBC,EAAwBL,EAAmBM,OAAA,uDAM5CC,SAAW,CACvBC,WAAY,CAAC,EACbC,OAAQ,CAAC,EACTC,aAAc,CACVC,SAAU,CAAEC,KAAM,aAAcC,SAAU,MAAOC,WAAY,YANrDC,SAAWZ,EAUpBa,KAAI,SAAAC,IACPC,sBAAAC,MAEAA,KAAKC,eAAiB,IAAIC,EAAe,CACrCC,MAAO,OACPC,OAAQ,QACRC,cAAe,KACfC,gBAAiB,KACjBC,QAAS,mBACTC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,YAChCX,KAAKY,gBAAgBF,MAI7BV,KAAKa,KAAO,IAAIC,EAAK,CACjBC,MAAO,CAACf,KAAKC,kBAGjBD,KAAKgB,eAAe,WAAYhB,KAAKa,KACzC,EAEOI,kBAAiB,SAAAC,IACpB,MAAMC,EAAWnB,KAAKoB,YAAY,YAClCpB,KAAKC,eAAeoB,aAAaF,GAEjC,MAAMG,EAAatB,KAAKoB,YAAY,SACpC,GAAIE,IAAeC,WAAaD,IAAe,KAAM,CAEjD,GAAItB,KAAKC,eAAeuB,aAAeF,EAAY,CAC/CtB,KAAKC,eAAewB,SAASH,EACjC,CACJ,CACJ,EAaOG,SAAQ,SAAAC,EAAChB,GACZV,KAAK2B,YAAY,QAASjB,EAAK,MAC/B,GAAIV,KAAKC,gBAAkBS,IAAQa,WAAab,IAAQ,KAAM,CAC1D,GAAIV,KAAKC,eAAeuB,aAAed,EAAK,CACxCV,KAAKC,eAAewB,SAASf,EACjC,CACJ,CACA,OAAOV,IACX,IAAC,OApEgBd,CAAe","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":11,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","SignatureControl","static","properties","events","isDrawing","canvasCtx","canvasEl","init","super","this","canvasHtml","HTML","content","afterRendering","onCanvasRendered","bind","addStyleClass","clearBtn","Button","icon","text","press","clearSignature","vBox","VBox","items","setAggregation","boundStartDrawing","startDrawing","boundDraw","draw","boundStopDrawing","stopDrawing","boundStartDrawingTouch","startDrawingTouch","boundDrawTouch","drawTouch","domRef","getDomRef","getContext","lineWidth","lineCap","strokeStyle","addEventListener","passive","val","getValue","startsWith","loadImageOntoCanvas","dataUrl","img","window","Image","onload","clearRect","width","height","drawImage","src","getCoordinates","e","x","y","rect","getBoundingClientRect","clientX","clientY","type","touches","left","top","preventDefault","pos","lineTo","stroke","beginPath","moveTo","saveSignature","setValueAndFire","MessageToast","show","toDataURL","setValue","value","exit","removeEventListener"],"sources":["SignatureControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport Button from \"sap/m/Button\";\nimport VBox from \"sap/m/VBox\";\nimport HTML from \"sap/ui/core/HTML\";\nimport MessageToast from \"sap/m/MessageToast\";\n\n/**\n * SignatureControl\n * Provides an HTML5 Canvas for capturing signatures.\n */\nexport default class SignatureControl extends BaseHardwareControl {\n static readonly renderer = \"nz.co.siliconst.ui5.metaui.controls.BaseHardwareControlRenderer\";\n static readonly metadata = {\n properties: {},\n events: {}\n };\n\n private vBox!: VBox;\n private clearBtn!: Button;\n private canvasHtml!: HTML;\n private isDrawing = false;\n private canvasCtx: CanvasRenderingContext2D | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n\n private boundStartDrawing!: (e: MouseEvent) => void;\n private boundDraw!: (e: MouseEvent) => void;\n private boundStopDrawing!: (e: MouseEvent | TouchEvent) => void;\n private boundStartDrawingTouch!: (e: TouchEvent) => void;\n private boundDrawTouch!: (e: TouchEvent) => void;\n\n /**\n * Initializes the control and builds the canvas drawing surface.\n */\n public init(): void {\n super.init();\n\n this.canvasHtml = new HTML({\n content: \"<canvas width='400' height='200' style='border: 1px solid #ccc; background-color: #fff; touch-action: none; cursor: crosshair;'></canvas>\",\n afterRendering: this.onCanvasRendered.bind(this)\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.clearBtn = new Button({\n icon: \"sap-icon://sys-cancel\",\n text: \"Clear Signature\",\n press: this.clearSignature.bind(this)\n });\n\n this.vBox = new VBox({\n items: [this.canvasHtml, this.clearBtn]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n\n this.boundStartDrawing = this.startDrawing.bind(this);\n this.boundDraw = this.draw.bind(this);\n this.boundStopDrawing = this.stopDrawing.bind(this);\n this.boundStartDrawingTouch = this.startDrawingTouch.bind(this);\n this.boundDrawTouch = this.drawTouch.bind(this);\n }\n\n private onCanvasRendered(): void {\n const domRef = this.canvasHtml.getDomRef() as HTMLElement;\n if (!domRef) return;\n \n this.canvasEl = domRef as HTMLCanvasElement;\n this.canvasCtx = this.canvasEl.getContext(\"2d\");\n if (this.canvasCtx) {\n this.canvasCtx.lineWidth = 2;\n this.canvasCtx.lineCap = \"round\";\n this.canvasCtx.strokeStyle = \"#000\";\n }\n\n // Mouse events\n this.canvasEl.addEventListener(\"mousedown\", this.boundStartDrawing);\n this.canvasEl.addEventListener(\"mousemove\", this.boundDraw);\n this.canvasEl.addEventListener(\"mouseup\", this.boundStopDrawing);\n this.canvasEl.addEventListener(\"mouseout\", this.boundStopDrawing);\n \n // Touch events\n this.canvasEl.addEventListener(\"touchstart\", this.boundStartDrawingTouch, { passive: false });\n this.canvasEl.addEventListener(\"touchmove\", this.boundDrawTouch, { passive: false });\n this.canvasEl.addEventListener(\"touchend\", this.boundStopDrawing);\n\n // Restore existing signature if any\n const val = this.getValue();\n if (val && typeof val === \"string\" && val.startsWith(\"data:image\")) {\n this.loadImageOntoCanvas(val);\n }\n }\n\n private loadImageOntoCanvas(dataUrl: string): void {\n const img = new window.Image();\n img.onload = () => {\n if (this.canvasCtx && this.canvasEl) {\n this.canvasCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);\n this.canvasCtx.drawImage(img, 0, 0, this.canvasEl.width, this.canvasEl.height);\n }\n };\n img.src = dataUrl;\n }\n\n private getCoordinates(e: MouseEvent | TouchEvent): { x: number, y: number } {\n if (!this.canvasEl) return { x: 0, y: 0 };\n const rect = this.canvasEl.getBoundingClientRect();\n \n let clientX, clientY;\n if (e.type.startsWith(\"touch\")) {\n clientX = (e as TouchEvent).touches[0].clientX;\n clientY = (e as TouchEvent).touches[0].clientY;\n } else {\n clientX = (e as MouseEvent).clientX;\n clientY = (e as MouseEvent).clientY;\n }\n \n return {\n x: clientX - rect.left,\n y: clientY - rect.top\n };\n }\n\n private startDrawing(e: MouseEvent): void {\n this.isDrawing = true;\n this.draw(e);\n }\n\n private startDrawingTouch(e: TouchEvent): void {\n e.preventDefault(); // Prevent scrolling\n this.isDrawing = true;\n this.drawTouch(e);\n }\n\n private draw(e: MouseEvent): void {\n if (!this.isDrawing || !this.canvasCtx) return;\n const pos = this.getCoordinates(e);\n this.canvasCtx.lineTo(pos.x, pos.y);\n this.canvasCtx.stroke();\n this.canvasCtx.beginPath();\n this.canvasCtx.moveTo(pos.x, pos.y);\n }\n\n private drawTouch(e: TouchEvent): void {\n if (!this.isDrawing || !this.canvasCtx) return;\n e.preventDefault(); // Prevent scrolling\n const pos = this.getCoordinates(e);\n this.canvasCtx.lineTo(pos.x, pos.y);\n this.canvasCtx.stroke();\n this.canvasCtx.beginPath();\n this.canvasCtx.moveTo(pos.x, pos.y);\n }\n\n private stopDrawing(): void {\n if (!this.isDrawing) return;\n this.isDrawing = false;\n if (this.canvasCtx) {\n this.canvasCtx.beginPath(); // Reset path\n this.saveSignature();\n }\n }\n\n private clearSignature(): void {\n if (this.canvasCtx && this.canvasEl) {\n this.canvasCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);\n }\n this.setValueAndFire(null);\n MessageToast.show(\"Signature cleared.\");\n }\n\n private saveSignature(): void {\n if (this.canvasEl) {\n const dataUrl = this.canvasEl.toDataURL(\"image/png\");\n this.setValueAndFire(dataUrl);\n }\n }\n\n /**\n * Sets the value of the control programmatically and re-draws the canvas.\n * @param value The base64 data URL string representing the signature image.\n */\n public setValue(value: unknown): this {\n super.setValue(value);\n if (value && typeof value === \"string\" && value.startsWith(\"data:image\")) {\n this.loadImageOntoCanvas(value);\n } else if (!value && this.canvasCtx && this.canvasEl) {\n this.canvasCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);\n }\n return this;\n }\n\n /**\n * Cleans up event listeners to prevent memory leaks when the control is destroyed.\n */\n public exit(): void {\n if (this.canvasEl) {\n this.canvasEl.removeEventListener(\"mousedown\", this.boundStartDrawing as EventListener);\n this.canvasEl.removeEventListener(\"mousemove\", this.boundDraw as EventListener);\n this.canvasEl.removeEventListener(\"mouseup\", this.boundStopDrawing as EventListener);\n this.canvasEl.removeEventListener(\"mouseout\", this.boundStopDrawing as EventListener);\n \n this.canvasEl.removeEventListener(\"touchstart\", this.boundStartDrawingTouch as EventListener);\n this.canvasEl.removeEventListener(\"touchmove\", this.boundDrawTouch as EventListener);\n this.canvasEl.removeEventListener(\"touchend\", this.boundStopDrawing as EventListener);\n }\n this.canvasEl = null;\n this.canvasCtx = null;\n super.exit();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":12,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","Logger","___utils_Logger","VoiceInputControl","static","properties","events","recognition","isRecording","init","super","this","textArea","TextArea","rows","width","placeholder","liveChange","oEvent","setValueAndFire","getParameter","startBtn","Button","icon","text","type","press","toggleDictation","bind","hBox","HBox","items","addStyleClass","vBox","VBox","setAggregation","initSpeechRecognition","stopDictation","startDictation","SpeechRecognitionClass","window","SpeechRecognition","webkitSpeechRecognition","continuous","interimResults","onresult","event","finalTranscript","interimTranscript","i","resultIndex","results","length","isFinal","transcript","currentVal","getValue","newVal","setValue","onstart","setIcon","setText","setType","MessageToast","show","onerror","error","sap","ui","require","MessageBox","onend","warn","setEnabled","setTooltip","start","err","message","String","stop","e","onBeforeRendering","readOnly","getProperty","setEditable","undefined","exit"],"sources":["VoiceInputControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport Button from \"sap/m/Button\";\nimport VBox from \"sap/m/VBox\";\nimport TextArea from \"sap/m/TextArea\";\nimport MessageToast from \"sap/m/MessageToast\";\nimport HBox from \"sap/m/HBox\";\nimport { Logger } from \"../utils/Logger\";\n\ndeclare global {\n interface Window {\n SpeechRecognition: new () => SpeechRecognition;\n webkitSpeechRecognition: new () => SpeechRecognition;\n }\n interface SpeechRecognition {\n continuous: boolean;\n interimResults: boolean;\n onresult: (event: SpeechRecognitionEvent) => void;\n onstart: () => void;\n onerror: (event: SpeechRecognitionErrorEvent) => void;\n onend: () => void;\n start(): void;\n stop(): void;\n }\n interface SpeechRecognitionEvent {\n resultIndex: number;\n results: {\n length: number;\n [index: number]: {\n isFinal: boolean;\n [index: number]: {\n transcript: string;\n };\n };\n };\n }\n interface SpeechRecognitionErrorEvent {\n error: string;\n }\n}\n\n/**\n * VoiceInputControl\n * Provides a UI to dictate text using the browser's native Web Speech API.\n */\nexport default class VoiceInputControl extends BaseHardwareControl {\n static readonly renderer = \"nz.co.siliconst.ui5.metaui.controls.BaseHardwareControlRenderer\";\n static readonly metadata = {\n properties: {},\n events: {}\n };\n\n private vBox!: VBox;\n private textArea!: TextArea;\n private startBtn!: Button;\n private stopBtn!: Button;\n \n private recognition: SpeechRecognition | null = null;\n private isRecording: boolean = false;\n\n /**\n * Initializes the dictation interface and requests Web Speech API setup.\n */\n public init(): void {\n super.init();\n\n this.textArea = new TextArea({\n rows: 3,\n width: \"100%\",\n placeholder: \"Dictated text will appear here...\",\n liveChange: (oEvent: sap.ui.base.Event) => {\n this.setValueAndFire(oEvent.getParameter(\"value\"));\n }\n });\n\n this.startBtn = new Button({\n icon: \"sap-icon://microphone\",\n text: \"Start Dictation\",\n type: \"Emphasized\",\n press: this.toggleDictation.bind(this)\n });\n\n const hBox = new HBox({\n items: [this.startBtn]\n }).addStyleClass(\"sapUiSmallMarginTop\");\n\n this.vBox = new VBox({\n items: [this.textArea, hBox]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n this.initSpeechRecognition();\n }\n\n private toggleDictation(): void {\n if (this.isRecording) {\n this.stopDictation();\n } else {\n this.startDictation();\n }\n }\n\n private initSpeechRecognition(): void {\n const SpeechRecognitionClass = window.SpeechRecognition || window.webkitSpeechRecognition;\n if (SpeechRecognitionClass) {\n this.recognition = new SpeechRecognitionClass();\n this.recognition.continuous = true;\n this.recognition.interimResults = true;\n\n this.recognition.onresult = (event: SpeechRecognitionEvent) => {\n let finalTranscript = \"\";\n let interimTranscript = \"\";\n\n for (let i = event.resultIndex; i < event.results.length; ++i) {\n if (event.results[i].isFinal) {\n finalTranscript += event.results[i][0].transcript;\n } else {\n interimTranscript += event.results[i][0].transcript;\n }\n }\n\n // Append the new final transcript to whatever was already in the textarea\n const currentVal = this.getValue() || \"\";\n const newVal = currentVal ? currentVal + \" \" + finalTranscript : finalTranscript;\n \n if (finalTranscript) {\n this.textArea.setValue(newVal);\n this.setValueAndFire(newVal);\n } else if (interimTranscript) {\n // Just show interim temporarily in textarea without saving to model\n this.textArea.setValue(currentVal ? currentVal + \" \" + interimTranscript : interimTranscript);\n }\n };\n\n this.recognition.onstart = () => {\n this.isRecording = true;\n this.startBtn.setIcon(\"sap-icon://stop\");\n this.startBtn.setText(\"Stop Recording\");\n this.startBtn.setType(\"Reject\");\n MessageToast.show(\"Listening... Please speak now.\");\n };\n\n this.recognition.onerror = (event: SpeechRecognitionErrorEvent) => {\n Logger.error(\"Speech recognition error\", event.error, \"VoiceInputControl\");\n sap.ui.require([\"sap/m/MessageBox\"], (MessageBox: typeof import(\"sap/m/MessageBox\").default) => {\n MessageBox.error(\"Microphone Error: \" + event.error + \"\\n\\nPlease ensure you have a working microphone attached and have not blocked access in your browser settings.\");\n });\n this.stopDictation();\n };\n \n this.recognition.onend = () => {\n // If it ends natively (e.g. timeout), update UI\n this.stopDictation();\n };\n } else {\n Logger.warn(\"Web Speech API not supported in this browser.\", \"\", \"VoiceInputControl\");\n this.startBtn.setEnabled(false);\n this.startBtn.setTooltip(\"Speech Recognition is not supported in this browser.\");\n }\n }\n\n private startDictation(): void {\n if (!this.recognition) return;\n \n try {\n this.recognition.start();\n MessageToast.show(\"Requesting microphone access...\");\n // Provide immediate UI feedback in case browser delays the onstart event\n this.startBtn.setIcon(\"sap-icon://stop\");\n this.startBtn.setText(\"Requesting mic...\");\n this.startBtn.setType(\"Reject\");\n } catch (err) {\n const error = err as Error;\n Logger.error(\"Failed to start speech recognition\", error.message || String(error), \"VoiceInputControl\");\n sap.ui.require([\"sap/m/MessageBox\"], (MessageBox: typeof import(\"sap/m/MessageBox\").default) => {\n MessageBox.error(\"Failed to start dictation. Please ensure you have a working microphone and have granted browser permissions.\\n\\nDetails: \" + (error.message || String(error)));\n });\n this.stopDictation();\n }\n }\n\n private stopDictation(): void {\n if (!this.recognition) return;\n \n try {\n this.recognition.stop();\n } catch(e) {\n Logger.warn(\"Failed to gracefully stop speech recognition.\", String(e), \"VoiceInputControl\");\n }\n \n this.isRecording = false;\n this.startBtn.setIcon(\"sap-icon://microphone\");\n this.startBtn.setText(\"Start Dictation\");\n this.startBtn.setType(\"Emphasized\");\n }\n\n /**\n * Lifecycle hook called before the control is rendered to the DOM.\n * Handles browser support visual state.\n */\n public onBeforeRendering(): void {\n const readOnly = this.getProperty(\"readOnly\");\n this.textArea.setEditable(!readOnly);\n \n // Only enable if it's not readonly AND the browser supports speech recognition\n this.startBtn.setEnabled(!readOnly && !!this.recognition);\n\n const currentVal = this.getProperty(\"value\");\n if (currentVal !== undefined && currentVal !== null) {\n // Only update text area if we aren't currently dictating interim results\n if (!this.isRecording) {\n this.textArea.setValue(currentVal as string);\n }\n }\n }\n\n /**\n * Cleans up hardware event listeners when the control is destroyed.\n */\n public exit(): void {\n this.stopDictation();\n if (this.recognition) {\n this.recognition.onstart = null;\n this.recognition.onresult = null;\n this.recognition.onerror = null;\n this.recognition.onend = null;\n this.recognition = null;\n }\n super.exit();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":13,"column":0},"map":{"version":3,"names":["Logger","____utils_Logger","SchemaNormalizer","____core_SchemaNormalizer","SchemaValidator","____core_SchemaValidator","Engine","____core_Engine","StateManager","____core_StateManager","DataSyncDelegate","___delegates_DataSyncDelegate","ValidationDelegate","___delegates_ValidationDelegate","DialogDelegate","___delegates_DialogDelegate","PluginRegistry","____core_PluginRegistry","GeneratorHost","Control","extend","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","schemaDefinitions","schemaTarget","pluginRegistry","schemaBuilderRegistry","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","error","exception","constructor","_constructor","idOrSettings","settings","Control.prototype.constructor.call","this","stateManager","generatedContent","engine","activeModelName","parsedSchema","_generatePromise","init","_init","Control.prototype.init.call","dataSyncDelegate","validationDelegate","dialogDelegate","onInternalFieldChange","bind","setDebugMode","_setDebugMode","enabled","setProperty","_setProperty","propertyName","suppressInvalidate","Control.prototype.setProperty.call","setUseMessageManager","getStateManager","_getStateManager","getSchemaDefinition","_getSchemaDefinition","refPath","defs","getProperty","undefined","key","startsWith","substring","tearDownGeneratedLayout","_tearDownGeneratedLayout","unregisterObject","destroy","_onInternalFieldChange","fieldKey","errorMessage","controlId","extractPayload","debug","pushToBindings","currentValidity","fireEvent","exit","_exit","getModel","getParsedSchema","_getParsedSchema","onBeforeRendering","_onBeforeRendering","hasSchema","hasData","generate","msg","Error","triggerSubmit","_triggerSubmit","isPrevented","removeAllMessages","applyVisualFallback","errors","validateAll","length","pushMessage","err","JSON","stringify","propertyPath","plugin","getPluginByPath","setVisualValidationState","addCustomError","_addCustomError","clearCustomError","_clearCustomError","schemaValid","validate","setBusy","_setBusy","isBusy","Control.prototype.setBusy.call","_setProperty2","handleInputDataHotSwap","currentVal","setBaseProperty","_setBaseProperty","async","_generate","Promise","resolve","then","_doGenerate","e","internalPayload","rawSchema","isSchemaEmpty","Object","keys","inputData","inputDataJson","parse","finalData","schemaToNormalize","normalizedSchema","normalize","schemaErrors","validateSchemaStructure","errorMsg","join","MessageBox","title","activePluginRegistry","getInstance","pathsToLoad","getPathsToLoad","needsNetworkLoad","Array","from","some","path","sap","ui","require","preloadDependencies","injectSchemaDefaults","getId","setModel","isEditable","host","build","contentContainer","hasProperties","strip","MessageStrip","text","showIcon","showCloseButton","addStyleClass","VBox","items","hasPartialRenderingErrors","setAggregation","registerObject","optimalWidth","calculateOptimalDialogWidth","updateDialogWidthDynamically","mountCrashBoundary","_calculateOptimalDialogWidth","schema","requiresWideDialog","scanProperties","props","prop","fullWidth","widget","openInDialog","_openInDialog","submitButtonText","cancelButtonText","dialogWidth","parentView","isGenerated","finalWidth"],"sources":["GeneratorHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport { Logger } from \"../../utils/Logger\";\nimport { SchemaNormalizer } from \"../../core/SchemaNormalizer\";\nimport { SchemaValidator } from \"../../core/SchemaValidator\";\nimport { Engine } from \"../../core/Engine\";\nimport { StateManager } from \"../../core/StateManager\";\nimport { DataSyncDelegate } from \"./delegates/DataSyncDelegate\";\nimport { ValidationDelegate } from \"./delegates/ValidationDelegate\";\nimport { DialogDelegate } from \"./delegates/DialogDelegate\";\nimport MessageBox from \"sap/m/MessageBox\";\nimport MessageStrip from \"sap/m/MessageStrip\";\nimport VBox from \"sap/m/VBox\";\nimport { PluginRegistry } from \"../../core/PluginRegistry\";\nimport type { ISchema } from \"../../interfaces/ISchema\";\n\n/**\n * Base wrapper element for embedding the dynamic form natively via Explicit Schemas.\n * \n * This class serves as the core rendering engine for standard MetaUI implementations.\n * It manages the lifecycle of the Engine, StateManager, and the delegation of \n * data synchronization, validation, and dialog interactions.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls.host\n */\nexport default class GeneratorHost extends Control {\n\n protected stateManager: StateManager | null = null;\n protected generatedContent: Control | null = null;\n protected engine: Engine | null = null;\n protected activeModelName: string = \"\";\n\n protected dataSyncDelegate!: DataSyncDelegate;\n protected validationDelegate!: ValidationDelegate;\n protected dialogDelegate!: DialogDelegate;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n schemaDefinitions: { type: \"object\", defaultValue: {} },\n schemaTarget: { type: \"string\", defaultValue: null },\n pluginRegistry: { type: \"object\", defaultValue: null },\n schemaBuilderRegistry: { type: \"object\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } },\n error: { parameters: { message: { type: \"string\" }, exception: { type: \"object\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: GeneratorHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Standard UI5 Constructor.\n */\n constructor(idOrSettings?: string | object, settings?: object) {\n super(idOrSettings, settings);\n }\n\n /**\n * Initializes the control and instantiates the composition delegates.\n * Delegates must be initialized here rather than in the constructor so they are \n * available before `applySettings` runs during UI5's control lifecycle.\n */\n public init(): void {\n super.init();\n\n // Initialize Composition Delegates\n this.dataSyncDelegate = new DataSyncDelegate(this);\n this.validationDelegate = new ValidationDelegate(this);\n this.dialogDelegate = new DialogDelegate(this);\n\n this.onInternalFieldChange = this.onInternalFieldChange.bind(this);\n }\n\n /**\n * Enables or disables debug mode.\n */\n public setDebugMode(enabled: boolean): this {\n this.setProperty(\"debugMode\", enabled, true);\n Logger.setDebugMode(enabled);\n return this;\n }\n\n /**\n * Intercepts property updates to dynamically forward them to active delegates/managers.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n super.setProperty(propertyName, value, suppressInvalidate);\n if (propertyName === \"useMessageManager\" && this.stateManager) {\n this.stateManager.setUseMessageManager(value === true);\n }\n return this;\n }\n\n /**\n * Returns the active state manager instance managing the JSON payload.\n */\n public getStateManager(): StateManager | null {\n return this.stateManager;\n }\n\n /**\n * Resolves a reference pointer against the global schema definitions dictionary.\n * @param refPath The string reference path (e.g., \"#/definitions/User\")\n * @returns The resolved ISchema or undefined\n */\n public getSchemaDefinition(refPath: string): ISchema | undefined {\n const defs = this.getProperty(\"schemaDefinitions\") as Record<string, ISchema>;\n if (!defs || !refPath) return undefined;\n let key = refPath;\n if (key.startsWith(\"#/definitions/\")) {\n key = key.substring(14);\n } else if (key.startsWith(\"#/components/schemas/\")) {\n key = key.substring(21);\n }\n return defs[key];\n }\n\n /**\n * Safely destroys the currently generated UI tree and cleans up references.\n * This is called before every regeneration to prevent memory leaks.\n */\n public tearDownGeneratedLayout(): void {\n if (this.generatedContent) {\n this.validationDelegate.unregisterObject(this.generatedContent);\n this.generatedContent.destroy();\n this.generatedContent = null;\n }\n }\n\n /**\n * Internal event handler triggered by the Engine when a field value changes.\n * Coordinates LiveUpdate syncs, validation state tracking, and bubbling the change upwards.\n */\n protected onInternalFieldChange(isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string): void {\n const payload = this.stateManager ? this.stateManager.extractPayload() : {};\n\n if (this.getProperty(\"liveUpdate\") === true) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", \"liveUpdate is enabled, pushing outbound payload.\", \"GeneratorHost\");\n }\n this.dataSyncDelegate.pushToBindings(payload);\n }\n\n const currentValidity = this.getProperty(\"isValid\") as boolean;\n if (isValid !== currentValidity) {\n this.setProperty(\"isValid\", isValid, true);\n this.fireEvent(\"validationStateChanged\", { isValid });\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Validation state shifted to: ${isValid}`, \"GeneratorHost\");\n }\n }\n\n this.fireEvent(\"fieldChange\", {\n fieldPath: fieldKey || \"\",\n value: undefined,\n payload: payload,\n isValid: isValid\n });\n }\n\n /**\n * Standard UI5 Exit Hook. Ensures complete teardown of the engine and state manager.\n */\n public exit(): void {\n if (this.engine) {\n this.engine.destroy();\n this.engine = null;\n }\n\n if (this.stateManager) {\n this.stateManager.getModel().destroy();\n this.stateManager = null;\n }\n\n if (this.generatedContent) {\n this.generatedContent.destroy();\n this.generatedContent = null;\n }\n }\n\n /** Cached schema for intelligent diffing during inference mode hot-swaps */\n protected parsedSchema: Record<string, unknown> | null = null;\n\n /**\n * Exposes the parsed schema to the DataSyncDelegate for diffing.\n */\n public getParsedSchema(): Record<string, unknown> | null {\n return this.parsedSchema;\n }\n\n /**\n * Standard UI5 Rendering Hook.\n * Evaluates whether it possesses a schema or data. If so, triggers the internal engine generation.\n */\n public onBeforeRendering(): void {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI GeneratorHost]\", `onBeforeRendering called. Engine boot state: schemaDefinition exists = ${!!this.getProperty(\"schemaDefinition\")}, data exists = ${!!this.getProperty(\"data\")}, dataJson exists = ${!!this.getProperty(\"dataJson\")}`, \"GeneratorHost\");\n }\n\n if (!this.generatedContent) {\n const hasSchema = !!this.getProperty(\"schemaDefinition\");\n const hasData = !!this.getProperty(\"dataJson\") || !!this.getProperty(\"data\");\n\n if (hasSchema || hasData) {\n this.generate();\n } else {\n const msg = \"GeneratorHost skipped rendering. Neither 'schemaDefinition' nor 'data' was provided.\";\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg });\n throw new Error(msg); // Eradicate silent errors\n }\n }\n }\n\n /**\n * Public API method to manually trigger form submission.\n * Executes all structural validations, clears old messages, and pushes payload to bindings.\n * @returns boolean True if submission succeeded, false if validation failed.\n */\n public triggerSubmit(): boolean {\n if (this.stateManager && this.engine) {\n let isPrevented = false;\n\n this.validationDelegate.removeAllMessages();\n\n // Only apply local fallback visual states if the global MessageManager is explicitly disabled\n const applyVisualFallback = this.getProperty(\"useMessageManager\") !== true;\n const errors = this.engine.validateAll(applyVisualFallback);\n if (errors.length > 0) {\n this.validationDelegate.pushMessage(\"\", \"One or more fields failed schema validation. Please review the highlighted fields.\");\n for (const err of errors) {\n if (err.fieldKey && err.errorMessage) {\n this.validationDelegate.pushMessage(err.fieldKey, err.errorMessage);\n }\n }\n return false;\n }\n\n const payload = this.stateManager.extractPayload();\n const payloadJson = JSON.stringify(payload);\n\n this.fireEvent(\"beforeSubmit\", {\n payload,\n preventDefault: () => { isPrevented = true; },\n addError: (propertyPath: string, errorMessage: string) => {\n isPrevented = true;\n this.validationDelegate.pushMessage(propertyPath, errorMessage);\n if (applyVisualFallback && this.engine) {\n const plugin = this.engine.getPluginByPath(propertyPath);\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n plugin.setVisualValidationState(false, errorMessage);\n }\n }\n }\n });\n\n if (isPrevented) {\n return false;\n }\n\n this.dataSyncDelegate.pushToBindings(payload);\n this.fireEvent(\"submit\", { payload, payloadJson });\n return true;\n }\n return false;\n }\n\n /**\n * Injects a custom error message onto a specific field.\n */\n public addCustomError(fieldPath: string, message: string): void {\n this.validationDelegate.addCustomError(fieldPath, message);\n if (this.getProperty(\"useMessageManager\") !== true && this.engine) {\n const plugin = this.engine.getPluginByPath(fieldPath);\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n plugin.setVisualValidationState(false, message);\n }\n }\n }\n\n /**\n * Clears a custom error message from a specific field.\n */\n public clearCustomError(fieldPath: string): void {\n this.validationDelegate.clearCustomError(fieldPath);\n if (this.getProperty(\"useMessageManager\") !== true && this.engine) {\n const plugin = this.engine.getPluginByPath(fieldPath);\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n const schemaValid = plugin.validate();\n plugin.setVisualValidationState(schemaValid.isValid, schemaValid.errorMessage);\n }\n }\n }\n\n /**\n * Toggles busy state on the host control.\n */\n public setBusy(isBusy: boolean): this {\n super.setBusy(isBusy);\n return this;\n }\n\n /**\n * Intercepts property changes. Hot-swaps data gracefully if it's an inputData change,\n * or forces a full UI teardown if it's a structural property change (like schemaDefinition).\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"dataJson\" || propertyName === \"data\") {\n this.dataSyncDelegate.handleInputDataHotSwap(propertyName, value, suppressInvalidate);\n return this;\n }\n\n if (propertyName === \"editable\" || propertyName === \"debugMode\" || propertyName === \"schemaDefinition\" || propertyName === \"schemaTarget\") {\n const currentVal = this.getProperty(propertyName);\n if (currentVal !== value) {\n super.setProperty(propertyName, value, suppressInvalidate);\n this.tearDownGeneratedLayout();\n }\n return this;\n }\n\n return super.setProperty(propertyName, value, suppressInvalidate);\n }\n\n /**\n * Bypasses the interceptor to write directly to the base UI5 control.\n */\n public setBaseProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n return super.setProperty(propertyName, value, suppressInvalidate);\n }\n\n /**\n * Internal reference to the active generate promise.\n * Prevents concurrent redundant layouts from being generated when properties are set rapidly or DialogDelegate triggers it.\n */\n private _generatePromise: Promise<void> | null = null;\n\n /**\n * The core rendering pipeline entry point.\n * Uses Promise resolution to debounce concurrent or rapid consecutive calls natively without arbitrary timeouts.\n * @returns Promise that resolves when the layout is successfully built and mounted.\n */\n public async generate(): Promise<void> {\n if (this._generatePromise) {\n return this._generatePromise;\n }\n this._generatePromise = Promise.resolve().then(async () => {\n try {\n await this._doGenerate();\n } catch (e) {\n Logger.error(\"[MetaUI]\", \"Error in deferred generate: \" + e, \"GeneratorHost\");\n throw e; // Ensure it bubbles up to awaiters\n } finally {\n this._generatePromise = null;\n }\n });\n return this._generatePromise;\n }\n\n /**\n * The underlying synchronous generator orchestration method.\n * Normalizes the schema, sets up the state manager, loads missing plugins over the network,\n * orchestrates the Engine build, and mounts the generated UI components into the internal tree.\n */\n private async _doGenerate(): Promise<void> {\n try {\n this.tearDownGeneratedLayout();\n\n // CRITICAL FIX: Extract the unsaved internal payload BEFORE destroying the state manager\n // Otherwise, toggling editable (or other structural properties) will wipe user inputs!\n let internalPayload = null;\n if (this.stateManager) {\n internalPayload = this.stateManager.extractPayload();\n }\n\n if (this.engine) {\n this.engine.destroy();\n this.engine = null;\n }\n if (this.stateManager) {\n this.stateManager.getModel().destroy();\n this.stateManager = null;\n }\n\n const rawSchema = this.getProperty(\"schemaDefinition\");\n const isSchemaEmpty = !rawSchema || (typeof rawSchema === \"object\" && Object.keys(rawSchema).length === 0);\n\n let inputData = this.getProperty(\"data\");\n const inputDataJson = this.getProperty(\"dataJson\");\n\n if (inputDataJson) {\n try {\n inputData = JSON.parse(inputDataJson as string);\n } catch (e) {\n const msg = \"Failed to parse inputDataJson string: \" + (e as Error).message;\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg, exception: e });\n throw new Error(msg); // Critical error instead of silent fallback\n }\n } else if (typeof inputData === \"string\") {\n try {\n inputData = JSON.parse(inputData);\n } catch (e) {\n const msg = \"Failed to parse inputData string: \" + (e as Error).message;\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg, exception: e });\n throw new Error(msg); // Critical error instead of silent fallback\n }\n }\n\n // The internal payload represents the user's latest un-extracted edits. It must take priority.\n const finalData = internalPayload || inputData;\n\n if (!finalData || Object.keys(finalData).length === 0) {\n if (isSchemaEmpty) {\n const msg = \"No payload provided and no explicit schema defined. Cannot infer UI.\";\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg });\n throw new Error(msg);\n }\n }\n\n const schemaToNormalize = isSchemaEmpty ? null : rawSchema;\n const normalizedSchema = SchemaNormalizer.normalize(schemaToNormalize, finalData);\n\n // Cache the parsed/inferred schema so DataSyncDelegate can diff against it later\n this.parsedSchema = normalizedSchema as Record<string, unknown>;\n\n if (normalizedSchema) {\n const schemaErrors = SchemaValidator.validateSchemaStructure(normalizedSchema);\n if (schemaErrors.length > 0) {\n const errorMsg = \"Schema Structural Errors Found:\\n- \" + schemaErrors.join(\"\\n- \");\n // Let's log it out loudly regardless of debug mode, so developers can see why it didn't render\n Logger.error(\"[MetaUI]\", errorMsg, \"GeneratorHost\");\n if (this.getProperty(\"debugMode\")) {\n MessageBox.error(errorMsg, { title: \"MetaUI Schema Error\" });\n return;\n }\n }\n }\n\n const activePluginRegistry = this.getProperty(\"pluginRegistry\") || PluginRegistry.getInstance();\n \n const pathsToLoad = activePluginRegistry.getPathsToLoad(normalizedSchema as ISchema);\n const needsNetworkLoad = Array.from(pathsToLoad).some((path: string) => !sap.ui.require(path));\n\n if (needsNetworkLoad) {\n this.setBusy(true);\n await activePluginRegistry.preloadDependencies(normalizedSchema as ISchema);\n this.setBusy(false);\n }\n\n // Inject defaults into empty payload values\n if (normalizedSchema && finalData) {\n this.dataSyncDelegate.injectSchemaDefaults(normalizedSchema, finalData);\n }\n\n this.activeModelName = \"metaUI_\" + this.getId();\n this.stateManager = new StateManager(finalData, normalizedSchema, this.activeModelName);\n this.stateManager.setUseMessageManager(this.getProperty(\"useMessageManager\") === true);\n this.setModel(this.stateManager.getModel(), this.activeModelName);\n\n if (!this.engine) {\n const isEditable = this.getProperty(\"editable\") !== false;\n const useMessageManager = this.getProperty(\"useMessageManager\") === true;\n const activePluginRegistry = this.getProperty(\"pluginRegistry\") || PluginRegistry.getInstance();\n this.engine = new Engine(isEditable, useMessageManager, activePluginRegistry);\n this.engine.host = this;\n }\n\n this.generatedContent = this.engine.build(\n normalizedSchema,\n this.stateManager.getModel(),\n this.activeModelName,\n this.triggerSubmit.bind(this),\n this.getId(),\n this.onInternalFieldChange.bind(this)\n );\n\n let contentContainer = this.generatedContent;\n\n const hasProperties = normalizedSchema && Object.keys(normalizedSchema).length > 0;\n\n if (!hasProperties) {\n const strip = new MessageStrip({\n text: \"Warning: The generated UI is blank. Reason: The schema (or inferred schema) contains no valid properties to render.\",\n type: \"Warning\",\n showIcon: true,\n showCloseButton: false\n });\n strip.addStyleClass(\"sapUiSmallMarginBottom\");\n contentContainer = new VBox({\n items: [strip, this.generatedContent]\n });\n } else if (this.engine.hasPartialRenderingErrors) {\n const strip = new MessageStrip({\n text: \"Layout partially rendered. Some fields failed to generate due to configuration errors.\",\n type: \"Warning\",\n showIcon: true,\n showCloseButton: true\n });\n strip.addStyleClass(\"sapUiSmallMarginBottom\");\n contentContainer = new VBox({\n items: [strip, this.generatedContent]\n });\n }\n\n this.setAggregation(\"_content\", contentContainer);\n this.validationDelegate.registerObject(this.generatedContent);\n\n const payload = this.stateManager.extractPayload();\n this.dataSyncDelegate.pushToBindings(payload);\n\n // Retroactively expand the dialog if the heuristic determines it needs more space\n const optimalWidth = this.calculateOptimalDialogWidth(this.parsedSchema);\n this.dialogDelegate.updateDialogWidthDynamically(optimalWidth);\n\n } catch (error) {\n this.setBusy(false);\n const msg = \"Fatal crash during layout generation: \" + (error as Error).message;\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg, exception: error });\n this.validationDelegate.mountCrashBoundary(error as Error);\n throw error; // Completely eliminate silent error swallowing\n }\n }\n\n /**\n * Helper to heuristically calculate optimal dialog width based on schema content.\n */\n private calculateOptimalDialogWidth(schema: Record<string, any> | null): string {\n if (!schema) return \"auto\";\n let requiresWideDialog = false;\n\n const scanProperties = (props: Record<string, any>) => {\n if (requiresWideDialog) return;\n for (const key in props) {\n const prop = props[key];\n if (prop.type === \"array\") {\n requiresWideDialog = true;\n return;\n }\n if (prop.ui?.fullWidth === true) {\n requiresWideDialog = true;\n return;\n }\n if (prop.ui?.widget === \"codeEditor\" || prop.ui?.widget === \"textArea\" || prop.ui?.widget === \"richText\") {\n requiresWideDialog = true;\n return;\n }\n if (prop.properties) scanProperties(prop.properties);\n if (prop.items && prop.items.properties) scanProperties(prop.items.properties);\n }\n };\n\n if (schema.type === \"array\") return \"80vw\";\n if (schema.properties) {\n scanProperties(schema.properties);\n }\n\n return requiresWideDialog ? \"80vw\" : \"auto\";\n }\n\n /**\n * Programmatic API. Re-parents the generated content into a dialog and opens it.\n */\n public openInDialog(title: string = \"Form\", submitButtonText: string = \"OK\", cancelButtonText: string = \"Cancel\", dialogWidth: string = \"auto\", parentView?: Control): void {\n const isGenerated = !!this.generatedContent;\n \n // If we already have the schema parsed, we can calculate it instantly to prevent flicker\n let finalWidth = dialogWidth;\n if (finalWidth === \"auto\" && this.parsedSchema) {\n finalWidth = this.calculateOptimalDialogWidth(this.parsedSchema);\n }\n \n this.dialogDelegate.openInDialog(title, submitButtonText, isGenerated, cancelButtonText, finalWidth, parentView);\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls/host"}},{"offset":{"line":14,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","SchemaNormalizer","_____core_SchemaNormalizer","DataSyncDelegate","_lastPushedPayloadJson","_lastPushedPayloadObj","_lastReceivedInputObj","constructor","host","this","pushToBindings","payload","payloadStr","JSON","stringify","deepEqual","parse","setProperty","handleInputDataHotSwap","propertyName","value","suppressInvalidate","incomingObj","e","setBaseProperty","getProperty","debug","extend","stateManager","getStateManager","invalidate","getModel","setData","getParsedSchema","newInferredSchema","inferSchemaFromData","parsedSchema","tearDownGeneratedLayout","msg","message","error","Error","injectSchemaDefaults","schema","rootData","depth","type","properties","key","Object","keys","propSchema","undefined","default","tempObj","length","items","Array","isArray","i","__exports","__esModule"],"sources":["DataSyncDelegate.ts"],"sourcesContent":["import deepEqual from \"sap/base/util/deepEqual\";\nimport extend from \"sap/base/util/extend\";\nimport { Logger } from \"../../../utils/Logger\";\nimport { SchemaNormalizer } from \"../../../core/SchemaNormalizer\";\nimport PropertyBinding from \"sap/ui/model/PropertyBinding\";\nimport { StateManager } from \"../../../core/StateManager\";\n\nexport interface IHostDataSync {\n getProperty(name: string): unknown;\n setProperty(name: string, value: unknown, suppressInvalidate?: boolean): this;\n setBaseProperty(name: string, value: unknown, suppressInvalidate?: boolean): this;\n getBinding(name: string): unknown;\n invalidate(): void;\n getStateManager(): StateManager | null;\n getParsedSchema?(): Record<string, unknown> | null;\n tearDownGeneratedLayout(): void;\n}\n\n/**\n * Handles two-way data sync, JSON parsing, loop-breaking, and inference structural diffs.\n */\nexport class DataSyncDelegate {\n private host: IHostDataSync;\n private _lastPushedPayloadJson: string | null = null;\n private _lastPushedPayloadObj: Record<string, unknown> | null = null;\n private _lastReceivedInputObj: Record<string, unknown> | null = null;\n\n /**\n * Initializes a new DataSyncDelegate to handle data payload binding extraction.\n * @param host The parent host interface containing properties.\n */\n constructor(host: IHostDataSync) {\n this.host = host;\n }\n\n /**\n * Natively forces the UI5 framework to push updated properties back up to any bound ViewModels.\n */\n public pushToBindings(payload: Record<string, unknown>): void {\n const payloadStr = JSON.stringify(payload, null, 2);\n\n // Cache exact payload output to catch echoes on the inbound side\n this._lastPushedPayloadJson = payloadStr;\n this._lastPushedPayloadObj = deepEqual({}, payload) ? null : JSON.parse(JSON.stringify(payload)); // Safe clone\n\n this.host.setProperty(\"data\", payload, true);\n this.host.setProperty(\"dataJson\", payloadStr, true);\n }\n\n /**\n * Intercepts and parses live updates to the data payload from two-way Fiori bindings.\n */\n public handleInputDataHotSwap(propertyName: string, value: unknown, suppressInvalidate?: boolean): void {\n let incomingObj: Record<string, unknown> | null = null;\n\n if (typeof value === \"string\") {\n try {\n incomingObj = JSON.parse(value) as Record<string, unknown>;\n } catch (e) {\n this.host.setBaseProperty(propertyName, value, true);\n return;\n }\n } else {\n incomingObj = value as Record<string, unknown>;\n }\n\n if (incomingObj === null) {\n this.host.setBaseProperty(propertyName, value, true);\n return;\n }\n\n // Loop Breaker 1: Stale Data Injection\n if (this._lastReceivedInputObj && deepEqual(incomingObj, this._lastReceivedInputObj)) {\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Dropped stale data injection for ${propertyName}`, \"DataSyncDelegate\");\n }\n this.host.setBaseProperty(propertyName, value, suppressInvalidate);\n return;\n }\n\n // Loop Breaker 2: Two-Way Data Echoes\n if (this._lastPushedPayloadObj && deepEqual(incomingObj, this._lastPushedPayloadObj)) {\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Dropped echo for ${propertyName}`, \"DataSyncDelegate\");\n }\n this.host.setBaseProperty(propertyName, value, suppressInvalidate);\n return;\n }\n\n this._lastReceivedInputObj = extend(true, {}, incomingObj) as Record<string, unknown>;\n\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Accepted external injection for ${propertyName}`, \"DataSyncDelegate\");\n }\n\n this.host.setBaseProperty(propertyName, value, true);\n\n const stateManager = this.host.getStateManager();\n if (!stateManager) {\n this.host.invalidate();\n return;\n }\n\n try {\n stateManager.getModel().setData(incomingObj, false);\n\n if (!this.host.getProperty(\"schemaDefinition\") && typeof this.host.getParsedSchema === \"function\") {\n const newInferredSchema = SchemaNormalizer.inferSchemaFromData(incomingObj);\n const parsedSchema = this.host.getParsedSchema();\n if (!deepEqual(newInferredSchema, parsedSchema)) {\n this.host.tearDownGeneratedLayout();\n this.host.invalidate();\n }\n }\n } catch (e) {\n const msg = `Failed to hot-swap ${propertyName}: ` + (e as Error).message;\n Logger.error(\"[MetaUI]\", msg, \"DataSyncDelegate\");\n throw new Error(msg);\n }\n }\n\n /**\n * Recursively scans an ISchema for `default` properties and injects them into the rootData \n * object if those properties are currently undefined.\n * \n * @param schema The MetaUI ISchema tree.\n * @param rootData The data payload to mutate.\n */\n public injectSchemaDefaults(schema: unknown, rootData: unknown, depth: number = 0): void {\n if (!schema || !rootData || typeof rootData !== \"object\" || depth > 8) return;\n\n if (schema.type === \"object\" && schema.properties) {\n for (const key of Object.keys(schema.properties)) {\n const propSchema = schema.properties[key];\n \n if (rootData[key] === undefined) {\n if (propSchema.default !== undefined) {\n rootData[key] = propSchema.default;\n } else if (propSchema.type === \"object\") {\n const tempObj = {};\n this.injectSchemaDefaults(propSchema, tempObj, depth + 1);\n if (Object.keys(tempObj).length > 0) {\n rootData[key] = tempObj;\n }\n }\n } else if (typeof rootData[key] === \"object\" && rootData[key] !== null) {\n this.injectSchemaDefaults(propSchema, rootData[key], depth + 1);\n }\n }\n } else if (schema.type === \"array\" && schema.items && Array.isArray(rootData)) {\n for (let i = 0; i < rootData.length; i++) {\n if (typeof rootData[i] === \"object\" && rootData[i] !== null) {\n this.injectSchemaDefaults(schema.items, rootData[i], depth + 1);\n }\n }\n }\n }\n}\n"],"mappings":"AAAA,yOAESA,EAAMC,EAAA,gBACNC,EAAgBC,EAAA,oBAkBlB,MAAMC,EAEDC,uBAAwC,KACxCC,sBAAwD,KACxDC,sBAAwD,KAMhEC,YAAYC,GACRC,KAAKD,KAAOA,CAChB,CAKOE,eAAeC,GAClB,MAAMC,EAAaC,KAAKC,UAAUH,EAAS,KAAM,GAGjDF,KAAKL,uBAAyBQ,EAC9BH,KAAKJ,sBAAwBU,EAAU,CAAC,EAAGJ,GAAW,KAAOE,KAAKG,MAAMH,KAAKC,UAAUH,IAEvFF,KAAKD,KAAKS,YAAY,OAAQN,EAAS,MACvCF,KAAKD,KAAKS,YAAY,WAAYL,EAAY,KAClD,CAKOM,uBAAuBC,EAAsBC,EAAgBC,GAChE,IAAIC,EAA8C,KAElD,UAAWF,IAAU,SAAU,CAC3B,IACIE,EAAcT,KAAKG,MAAMI,EAC7B,CAAE,MAAOG,GACLd,KAAKD,KAAKgB,gBAAgBL,EAAcC,EAAO,MAC/C,MACJ,CACJ,KAAO,CACHE,EAAcF,CAClB,CAEA,GAAIE,IAAgB,KAAM,CACtBb,KAAKD,KAAKgB,gBAAgBL,EAAcC,EAAO,MAC/C,MACJ,CAGA,GAAIX,KAAKH,uBAAyBS,EAAUO,EAAab,KAAKH,uBAAwB,CAClF,GAAIG,KAAKD,KAAKiB,YAAY,aAAc,CACpC1B,EAAO2B,MAAM,WAAY,oCAAoCP,IAAgB,mBACjF,CACAV,KAAKD,KAAKgB,gBAAgBL,EAAcC,EAAOC,GAC/C,MACJ,CAGA,GAAIZ,KAAKJ,uBAAyBU,EAAUO,EAAab,KAAKJ,uBAAwB,CAClF,GAAII,KAAKD,KAAKiB,YAAY,aAAc,CACpC1B,EAAO2B,MAAM,WAAY,oBAAoBP,IAAgB,mBACjE,CACAV,KAAKD,KAAKgB,gBAAgBL,EAAcC,EAAOC,GAC/C,MACJ,CAEAZ,KAAKH,sBAAwBqB,EAAO,KAAM,CAAC,EAAGL,GAE9C,GAAIb,KAAKD,KAAKiB,YAAY,aAAc,CACpC1B,EAAO2B,MAAM,WAAY,mCAAmCP,IAAgB,mBAChF,CAEAV,KAAKD,KAAKgB,gBAAgBL,EAAcC,EAAO,MAE/C,MAAMQ,EAAenB,KAAKD,KAAKqB,kBAC/B,IAAKD,EAAc,CACfnB,KAAKD,KAAKsB,aACV,MACJ,CAEA,IACIF,EAAaG,WAAWC,QAAQV,EAAa,OAE7C,IAAKb,KAAKD,KAAKiB,YAAY,4BAA8BhB,KAAKD,KAAKyB,kBAAoB,WAAY,CAC/F,MAAMC,EAAoBjC,EAAiBkC,oBAAoBb,GAC/D,MAAMc,EAAe3B,KAAKD,KAAKyB,kBAC/B,IAAKlB,EAAUmB,EAAmBE,GAAe,CAC7C3B,KAAKD,KAAK6B,0BACV5B,KAAKD,KAAKsB,YACd,CACJ,CACJ,CAAE,MAAOP,GACL,MAAMe,EAAM,sBAAsBnB,MAAoBI,EAAYgB,QAClExC,EAAOyC,MAAM,WAAYF,EAAK,oBAC9B,MAAM,IAAIG,MAAMH,EACpB,CACJ,CASOI,qBAAqBC,EAAiBC,EAAmBC,EAAgB,GAC5E,IAAKF,IAAWC,UAAmBA,IAAa,UAAYC,EAAQ,EAAG,OAEvE,GAAIF,EAAOG,OAAS,UAAYH,EAAOI,WAAY,CAC/C,IAAK,MAAMC,KAAOC,OAAOC,KAAKP,EAAOI,YAAa,CAC9C,MAAMI,EAAaR,EAAOI,WAAWC,GAErC,GAAIJ,EAASI,KAASI,UAAW,CAC7B,GAAID,EAAWE,UAAYD,UAAW,CAClCR,EAASI,GAAOG,EAAWE,OAC/B,MAAO,GAAIF,EAAWL,OAAS,SAAU,CACrC,MAAMQ,EAAU,CAAC,EACjB7C,KAAKiC,qBAAqBS,EAAYG,EAAST,EAAQ,GACvD,GAAII,OAAOC,KAAKI,GAASC,OAAS,EAAG,CACjCX,EAASI,GAAOM,CACpB,CACJ,CACJ,MAAO,UAAWV,EAASI,KAAS,UAAYJ,EAASI,KAAS,KAAM,CACpEvC,KAAKiC,qBAAqBS,EAAYP,EAASI,GAAMH,EAAQ,EACjE,CACJ,CACJ,MAAO,GAAIF,EAAOG,OAAS,SAAWH,EAAOa,OAASC,MAAMC,QAAQd,GAAW,CAC3E,IAAK,IAAIe,EAAI,EAAGA,EAAIf,EAASW,OAAQI,IAAK,CACtC,UAAWf,EAASe,KAAO,UAAYf,EAASe,KAAO,KAAM,CACzDlD,KAAKiC,qBAAqBC,EAAOa,MAAOZ,EAASe,GAAId,EAAQ,EACjE,CACJ,CACJ,CACJ,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAAzD,mBAAA,OAAAyD,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":15,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","DialogDelegate","activeDialog","requestedWidth","calculatedOptimalWidth","constructor","host","this","openInDialog","title","submitButtonText","isGenerated","cancelButtonText","dialogWidth","parentView","busyDialog","BusyDialog","text","open","genResult","generate","Promise","err","close","error","message","finalWidth","dialog","Dialog","contentWidth","content","beginButton","Button","type","press","success","triggerSubmit","fireEvent","fieldPath","endButton","afterClose","destroy","addDependent","updateDialogWidthDynamically","optimalWidth","setContentWidth","__exports","__esModule"],"sources":["DialogDelegate.ts"],"sourcesContent":["import Dialog from \"sap/m/Dialog\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport BusyDialog from \"sap/m/BusyDialog\";\nimport { Logger } from \"../../../utils/Logger\";\n\nexport interface IHostDialog {\n generate(): Promise<void> | void;\n triggerSubmit(): boolean;\n fireEvent(eventName: string, parameters?: Record<string, unknown>): this;\n}\n\n/**\n * Extracts all popup and dialog generation logic from the Host control.\n */\nexport class DialogDelegate {\n private host: IHostDialog & Control;\n private activeDialog: Dialog | null = null;\n private requestedWidth: string = \"auto\";\n private calculatedOptimalWidth: string = \"auto\";\n\n /**\n * Initializes a new DialogDelegate to handle dialog-based rendering.\n * @param host The parent DynamicHost or GeneratorHost control.\n */\n constructor(host: IHostDialog & Control) {\n this.host = host;\n }\n\n /**\n * Dialog Modality: Opens the generated layout inside a sap.m.Dialog.\n * Automatically wires up customizable submit (default: 'OK') and 'Cancel' buttons.\n */\n public async openInDialog(title: string = \"Form\", submitButtonText: string = \"OK\", isGenerated: boolean, cancelButtonText: string = \"Cancel\", dialogWidth: string = \"auto\", parentView?: Control): Promise<void> {\n this.requestedWidth = dialogWidth;\n this.calculatedOptimalWidth = dialogWidth; // Default fallback\n\n // Mask the complex asynchronous rendering to prevent visual snapping\n const busyDialog = new BusyDialog({ text: \"Building Form...\" });\n busyDialog.open();\n\n try {\n // Force manual generation BEFORE mounting the dialog so the optimal width is perfectly calculated first\n const genResult = this.host.generate();\n if (genResult instanceof Promise) {\n await genResult;\n }\n } catch (err) {\n busyDialog.close();\n Logger.error(\"[MetaUI] Catastrophic error during pre-generation of dialog content\", (err as Error).message, \"DialogDelegate\");\n return;\n }\n\n busyDialog.close();\n\n // The Engine heuristically updated `calculatedOptimalWidth` during `generate()`. Apply it on frame 1.\n const finalWidth = this.requestedWidth === \"auto\" && this.calculatedOptimalWidth !== \"auto\" ? this.calculatedOptimalWidth : this.requestedWidth;\n\n const dialog = new Dialog({\n title: title,\n contentWidth: finalWidth,\n content: [this.host], // Mount host inside the dialog\n beginButton: new Button({\n text: submitButtonText,\n type: \"Emphasized\",\n press: () => {\n try {\n const success = this.host.triggerSubmit();\n if (success) {\n dialog.close();\n }\n } catch (err) {\n Logger.error(\"[MetaUI] Catastrophic error during validation/submit pipeline\", (err as Error).message, \"DialogDelegate\");\n this.host.fireEvent(\"validationError\", { fieldPath: \"root\", message: (err as Error).message });\n }\n }\n }),\n endButton: new Button({\n text: cancelButtonText,\n press: () => {\n this.host.fireEvent(\"cancel\");\n dialog.close();\n }\n }),\n afterClose: () => {\n this.activeDialog = null;\n dialog.destroy();\n }\n });\n\n this.activeDialog = dialog;\n\n if (parentView && typeof parentView.addDependent === \"function\") {\n parentView.addDependent(dialog);\n }\n\n dialog.open();\n }\n\n /**\n * Allows the Engine to retroactively expand the dialog once the schema is fully parsed.\n */\n public updateDialogWidthDynamically(optimalWidth: string): void {\n this.calculatedOptimalWidth = optimalWidth;\n // Only dynamically stretch if the dialog is ALREADY open (e.g., hybrid inference late-loading)\n if (this.activeDialog && this.requestedWidth === \"auto\" && optimalWidth !== \"auto\") {\n this.activeDialog.setContentWidth(optimalWidth);\n }\n }\n}\n"],"mappings":"AAAA,sMAISA,EAAMC,EAAA,UAWR,MAAMC,EAEDC,aAA8B,KAC9BC,eAAyB,OACzBC,uBAAiC,OAMzCC,YAAYC,GACRC,KAAKD,KAAOA,CAChB,CAMA,kBAAaE,CAAaC,EAAgB,OAAQC,EAA2B,KAAMC,EAAsBC,EAA2B,SAAUC,EAAsB,OAAQC,GACxKP,KAAKJ,eAAiBU,EACtBN,KAAKH,uBAAyBS,EAG9B,MAAME,EAAa,IAAIC,EAAW,CAAEC,KAAM,qBAC1CF,EAAWG,OAEX,IAEI,MAAMC,EAAYZ,KAAKD,KAAKc,WAC5B,GAAID,aAAqBE,QAAS,OACxBF,CACV,CACJ,CAAE,MAAOG,GACLP,EAAWQ,QACXxB,EAAOyB,MAAM,sEAAwEF,EAAcG,QAAS,kBAC5G,MACJ,CAEAV,EAAWQ,QAGX,MAAMG,EAAanB,KAAKJ,iBAAmB,QAAUI,KAAKH,yBAA2B,OAASG,KAAKH,uBAAyBG,KAAKJ,eAEjI,MAAMwB,EAAS,IAAIC,EAAO,CACtBnB,MAAOA,EACPoB,aAAcH,EACdI,QAAS,CAACvB,KAAKD,MACfyB,YAAa,IAAIC,EAAO,CACpBf,KAAMP,EACNuB,KAAM,aACNC,MAAOA,KACH,IACI,MAAMC,EAAU5B,KAAKD,KAAK8B,gBAC1B,GAAID,EAAS,CACTR,EAAOJ,OACX,CACJ,CAAE,MAAOD,GACLvB,EAAOyB,MAAM,gEAAkEF,EAAcG,QAAS,kBACtGlB,KAAKD,KAAK+B,UAAU,kBAAmB,CAAEC,UAAW,OAAQb,QAAUH,EAAcG,SACxF,KAGRc,UAAW,IAAIP,EAAO,CAClBf,KAAML,EACNsB,MAAOA,KACH3B,KAAKD,KAAK+B,UAAU,UACpBV,EAAOJ,WAGfiB,WAAYA,KACRjC,KAAKL,aAAe,KACpByB,EAAOc,aAIflC,KAAKL,aAAeyB,EAEpB,GAAIb,UAAqBA,EAAW4B,eAAiB,WAAY,CAC7D5B,EAAW4B,aAAaf,EAC5B,CAEAA,EAAOT,MACX,CAKOyB,6BAA6BC,GAChCrC,KAAKH,uBAAyBwC,EAE9B,GAAIrC,KAAKL,cAAgBK,KAAKJ,iBAAmB,QAAUyC,IAAiB,OAAQ,CAChFrC,KAAKL,aAAa2C,gBAAgBD,EACtC,CACJ,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAA7C,iBAAA,OAAA6C,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":16,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","ODataDelegate","odataType","isSyncing","constructor","host","context","this","detectODataType","attachEvent","onFieldChange","oEvent","params","getParameters","fieldPath","value","undefined","handleFieldChange","model","getModel","sClassName","getMetadata","getName","indexOf","syncToEngine","requestObject","then","oData","pushPayload","catch","err","error","message","getObject","cleanData","key","Object","keys","startsWith","setProperty","getProperty","debug","e","__exports","__esModule"],"sources":["ODataDelegate.ts"],"sourcesContent":["import { DynamicHost } from \"../DynamicHost\";\nimport { Logger } from \"../../../utils/Logger\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\nimport Context from \"sap/ui/model/Context\";\n\n/**\n * Universal OData Delegate.\n * Natively detects and manages two-way synchronization for both OData V2 and V4 contexts\n * without requiring controller-level mappings.\n */\nexport class ODataDelegate {\n private host: DynamicHost;\n private context: ODataV4Context | Context;\n private odataType: \"V2\" | \"V4\" | null = null;\n private isSyncing: boolean = false;\n\n /**\n * Initializes a new instance of the ODataDelegate.\n * \n * @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.\n * @param {Context} context The active UI5 Model Context bound to the host.\n */\n constructor(host: DynamicHost, context: ODataV4Context | Context) {\n this.host = host;\n this.context = context;\n this.detectODataType();\n \n // Natively subscribe to the host's field changes to decouple from DynamicHost internals\n this.host.attachEvent(\"fieldChange\", this.onFieldChange, this);\n }\n\n /**\n * Event listener wrapper for field changes emitted by the host.\n */\n private onFieldChange(oEvent: sap.ui.base.Event): void {\n const params = oEvent.getParameters();\n if (params.fieldPath && params.value !== undefined) {\n this.handleFieldChange(params.fieldPath, params.value);\n }\n }\n\n /**\n * Evaluates the underlying UI5 Model bound to the context to determine if it is an\n * OData V2 or OData V4 model. This determination drives the synchronization strategy.\n * \n * @private\n */\n private detectODataType(): void {\n const model = this.context.getModel();\n // sap.ui.model.odata.v4.ODataModel\n // sap.ui.model.odata.v2.ODataModel\n const sClassName = model.getMetadata().getName();\n if (sClassName.indexOf(\"v4\") > -1) {\n this.odataType = \"V4\";\n } else if (sClassName.indexOf(\"v2\") > -1 || sClassName.indexOf(\"ODataModel\") > -1) {\n this.odataType = \"V2\";\n }\n }\n\n /**\n * Extracts the full entity payload from the bound OData context and pushes it to the Engine.\n * V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.\n * \n * @public\n */\n public syncToEngine(): void {\n if (!this.odataType) return;\n\n if (this.odataType === \"V4\") {\n // V4 uses async requestObject()\n if (typeof this.context.requestObject === \"function\") {\n this.context.requestObject().then((oData: unknown) => {\n this.pushPayload(oData);\n }).catch((err: Error) => {\n Logger.error(\"[MetaUI]\", \"Failed to extract V4 Context payload: \" + err.message, \"ODataDelegate\");\n });\n }\n } else if (this.odataType === \"V2\") {\n // V2 uses sync getObject()\n const oData = this.context.getObject();\n if (oData) {\n this.pushPayload(oData);\n }\n }\n }\n\n /**\n * Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')\n * and pushes the sanitized business data into the MetaUI DynamicHost state manager.\n * \n * @param {unknown} oData The raw JSON object extracted from the OData model context.\n * @private\n */\n private pushPayload(oData: unknown): void {\n if (!oData) return;\n \n // Remove OData metadata properties before pushing to MetaUI\n const cleanData = { ...(oData as Record<string, unknown>) };\n for (const key of Object.keys(cleanData)) {\n if (key.startsWith(\"@\") || key.startsWith(\"__\")) {\n delete cleanData[key];\n }\n }\n\n this.isSyncing = true;\n this.host.setProperty(\"data\", cleanData);\n this.isSyncing = false;\n }\n\n /**\n * Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.\n */\n public handleFieldChange(fieldPath: string, value: unknown): void {\n if (this.isSyncing || !this.odataType) return;\n\n try {\n if (this.odataType === \"V4\") {\n // V4 sets property directly on context\n this.context.setProperty(fieldPath, value);\n } else if (this.odataType === \"V2\") {\n // V2 sets property on model, specifying the context path\n const model = this.context.getModel();\n model.setProperty(fieldPath, value, this.context);\n }\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `ODataDelegate Patched ${fieldPath} = ${value} via ${this.odataType}`, \"ODataDelegate\");\n }\n } catch (e) {\n Logger.error(\"[MetaUI]\", `Failed to patch OData context: ${(e as Error).message}`, \"ODataDelegate\");\n }\n }\n}\n"],"mappings":"AAAA,8IACSA,EAAMC,EAAA,UASR,MAAMC,EAGDC,UAAgC,KAChCC,UAAqB,MAQ7BC,YAAYC,EAAmBC,GAC3BC,KAAKF,KAAOA,EACZE,KAAKD,QAAUA,EACfC,KAAKC,kBAGLD,KAAKF,KAAKI,YAAY,cAAeF,KAAKG,cAAeH,KAC7D,CAKQG,cAAcC,GAClB,MAAMC,EAASD,EAAOE,gBACtB,GAAID,EAAOE,WAAaF,EAAOG,QAAUC,UAAW,CAChDT,KAAKU,kBAAkBL,EAAOE,UAAWF,EAAOG,MACpD,CACJ,CAQQP,kBACJ,MAAMU,EAAQX,KAAKD,QAAQa,WAG3B,MAAMC,EAAaF,EAAMG,cAAcC,UACvC,GAAIF,EAAWG,QAAQ,OAAS,EAAG,CAC/BhB,KAAKL,UAAY,IACrB,MAAO,GAAIkB,EAAWG,QAAQ,OAAS,GAAKH,EAAWG,QAAQ,eAAiB,EAAG,CAC/EhB,KAAKL,UAAY,IACrB,CACJ,CAQOsB,eACH,IAAKjB,KAAKL,UAAW,OAErB,GAAIK,KAAKL,YAAc,KAAM,CAEzB,UAAWK,KAAKD,QAAQmB,gBAAkB,WAAY,CAClDlB,KAAKD,QAAQmB,gBAAgBC,KAAMC,IAC/BpB,KAAKqB,YAAYD,KAClBE,MAAOC,IACN/B,EAAOgC,MAAM,WAAY,yCAA2CD,EAAIE,QAAS,kBAEzF,CACJ,MAAO,GAAIzB,KAAKL,YAAc,KAAM,CAEhC,MAAMyB,EAAQpB,KAAKD,QAAQ2B,YAC3B,GAAIN,EAAO,CACPpB,KAAKqB,YAAYD,EACrB,CACJ,CACJ,CASQC,YAAYD,GAChB,IAAKA,EAAO,OAGZ,MAAMO,EAAY,IAAMP,GACxB,IAAK,MAAMQ,KAAOC,OAAOC,KAAKH,GAAY,CACtC,GAAIC,EAAIG,WAAW,MAAQH,EAAIG,WAAW,MAAO,QACtCJ,EAAUC,EACrB,CACJ,CAEA5B,KAAKJ,UAAY,KACjBI,KAAKF,KAAKkC,YAAY,OAAQL,GAC9B3B,KAAKJ,UAAY,KACrB,CAKOc,kBAAkBH,EAAmBC,GACxC,GAAIR,KAAKJ,YAAcI,KAAKL,UAAW,OAEvC,IACI,GAAIK,KAAKL,YAAc,KAAM,CAEzBK,KAAKD,QAAQiC,YAAYzB,EAAWC,EACxC,MAAO,GAAIR,KAAKL,YAAc,KAAM,CAEhC,MAAMgB,EAAQX,KAAKD,QAAQa,WAC3BD,EAAMqB,YAAYzB,EAAWC,EAAOR,KAAKD,QAC7C,CACA,GAAIC,KAAKF,KAAKmC,YAAY,aAAc,CACpCzC,EAAO0C,MAAM,WAAY,yBAAyB3B,OAAeC,SAAaR,KAAKL,YAAa,gBACpG,CACJ,CAAE,MAAOwC,GACL3C,EAAOgC,MAAM,WAAY,kCAAmCW,EAAYV,UAAW,gBACvF,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAA1C,gBAAA,OAAA0C,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":17,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","ValidationDelegate","constructor","host","this","registerObject","control","unregisterObject","removeAllMessages","stateManager","getStateManager","getProperty","messageManager","Messaging","messages","getMessageModel","getData","messagesToRemove","filter","m","getMessageProcessor","getId","getModel","length","removeMessages","pushMessage","path","text","targetPath","replace","displayText","warn","addMessages","Message","message","type","coreLibrary","MessageType","Error","target","processor","addCustomError","fieldPath","code","clearCustomError","processorId","getTarget","getCode","mountCrashBoundary","error","errorPage","IllustratedMessage","title","description","setAggregation","__exports","__esModule"],"sources":["ValidationDelegate.ts"],"sourcesContent":["import IllustratedMessage from \"sap/m/IllustratedMessage\";\nimport Messaging from \"sap/ui/core/Messaging\";\nimport Control from \"sap/ui/core/Control\";\nimport { StateManager } from \"../../../core/StateManager\";\nimport { Logger } from \"../../../utils/Logger\";\nimport Message from \"sap/ui/core/message/Message\";\nimport coreLibrary from \"sap/ui/core/library\";\n\nexport interface IHostValidation {\n getProperty(name: string): unknown;\n setAggregation(aggregationName: string, object: sap.ui.core.Control, suppressInvalidate?: boolean): this;\n getStateManager(): StateManager | null;\n}\n\n/**\n * Handles Fiori MessageManager integration and provides a standardized Error Boundary UI fallback.\n */\nexport class ValidationDelegate {\n private host: IHostValidation;\n\n /**\n * Initializes the ValidationDelegate for registering controls to the global MessageManager.\n * @param host The parent host interface.\n */\n constructor(host: IHostValidation) {\n this.host = host;\n }\n\n /**\n * Registers a control and all its children with the global MessageManager.\n * (Deprecated: Native registration causes UI5 to aggressively clear custom schema validation messages \n * on every keystroke. MetaUI handles valueState manually via plugins).\n */\n public registerObject(control: Control): void {\n // Do nothing to prevent UI5 from hijacking valueState and clearing our manual messages\n }\n\n /**\n * Unregisters a control from the global MessageManager.\n */\n public unregisterObject(control: Control): void {\n // Do nothing\n }\n\n public removeAllMessages(): void {\n const stateManager = this.host.getStateManager();\n if (stateManager && this.host.getProperty(\"useMessageManager\")) {\n const messageManager = Messaging;\n const messages = messageManager.getMessageModel().getData();\n const messagesToRemove = messages.filter((m: sap.ui.core.message.Message) =>\n m.getMessageProcessor() && m.getMessageProcessor().getId() === stateManager.getModel().getId()\n );\n if (messagesToRemove && messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n }\n }\n\n /**\n * Pushes a validation message to the console, and optionally to the MessageManager.\n */\n public pushMessage(path: string, text: string): void {\n const targetPath = path ? `/${path.replace(/^\\//, \"\")}` : \"\";\n const displayText = path ? `Field '${path}': ${text}` : text;\n\n if (path) {\n Logger.warn(`[MetaUI Validation Error] ${displayText}`);\n } else {\n Logger.warn(`[MetaUI Validation Error] Global - ${text}`);\n }\n\n if (this.host.getProperty(\"useMessageManager\") === true) {\n const messageManager = Messaging;\n const stateManager = this.host.getStateManager();\n messageManager.addMessages(new Message({\n message: displayText,\n type: coreLibrary.MessageType.Error,\n target: targetPath,\n processor: stateManager?.getModel()\n }));\n }\n }\n\n /**\n * Imperatively invalidates a field and highlights it with an error message.\n * Uses a specific 'CustomError' code to distinguish it from internal schema validations.\n * \n * @param fieldPath The internal JSON path of the field to highlight.\n * @param message The custom error message to display.\n */\n public addCustomError(fieldPath: string, message: string): void {\n if (this.host.getProperty(\"useMessageManager\") !== true) {\n return;\n }\n\n const stateManager = this.host.getStateManager();\n if (!stateManager) {\n return;\n }\n\n Messaging.addMessages(new Message({\n message: message,\n type: coreLibrary.MessageType.Error,\n target: `/${fieldPath.replace(/^\\//, \"\")}`,\n processor: stateManager.getModel(),\n code: \"CustomError\"\n }));\n }\n\n /**\n * Reverts a custom error state on a field, safely ignoring native schema validations.\n * \n * @param fieldPath The internal JSON path of the field to clear.\n */\n public clearCustomError(fieldPath: string): void {\n if (this.host.getProperty(\"useMessageManager\") !== true) {\n return;\n }\n\n const stateManager = this.host.getStateManager();\n if (!stateManager) {\n return;\n }\n\n const target = `/${fieldPath.replace(/^\\//, \"\")}`;\n const processorId = stateManager.getModel().getId();\n const messages = Messaging.getMessageModel().getData() as sap.ui.core.message.Message[];\n\n const messagesToRemove = messages.filter(m =>\n m.getTarget() === target &&\n m.getCode() === \"CustomError\" &&\n m.getMessageProcessor()?.getId() === processorId\n );\n\n if (messagesToRemove.length > 0) {\n Messaging.removeMessages(messagesToRemove);\n }\n }\n\n /**\n * Triggers a visual Error Page (Crash Boundary) when generation catastrophically fails.\n */\n public mountCrashBoundary(error: Error): void {\n Logger.error(\"[MetaUI] Engine failed to generate layout. Preventing Launchpad crash.\", error.message, \"ValidationDelegate\");\n\n const errorPage = new IllustratedMessage({\n title: \"UI Generation Failed\",\n description: \"The dynamic schema could not be rendered. Please check the Fiori console for diagnostic logs.\"\n });\n\n this.host.setAggregation(\"_content\", errorPage);\n }\n}\n"],"mappings":"AAAA,kQAISA,EAAMC,EAAA,UAaR,MAAMC,EAOTC,YAAYC,GACRC,KAAKD,KAAOA,CAChB,CAOOE,eAAeC,GAClB,CAMGC,iBAAiBD,GACpB,CAGGE,oBACH,MAAMC,EAAeL,KAAKD,KAAKO,kBAC/B,GAAID,GAAgBL,KAAKD,KAAKQ,YAAY,qBAAsB,CAC5D,MAAMC,EAAiBC,EACvB,MAAMC,EAAWF,EAAeG,kBAAkBC,UAClD,MAAMC,EAAmBH,EAASI,OAAQC,GACtCA,EAAEC,uBAAyBD,EAAEC,sBAAsBC,UAAYZ,EAAaa,WAAWD,SAE3F,GAAIJ,GAAoBA,EAAiBM,OAAS,EAAG,CACjDX,EAAeY,eAAeP,EAClC,CACJ,CACJ,CAKOQ,YAAYC,EAAcC,GAC7B,MAAMC,EAAaF,EAAO,IAAIA,EAAKG,QAAQ,MAAO,MAAQ,GAC1D,MAAMC,EAAcJ,EAAO,UAAUA,OAAUC,IAASA,EAExD,GAAID,EAAM,CACN3B,EAAOgC,KAAK,6BAA6BD,IAC7C,KAAO,CACH/B,EAAOgC,KAAK,sCAAsCJ,IACtD,CAEA,GAAIvB,KAAKD,KAAKQ,YAAY,uBAAyB,KAAM,CACrD,MAAMC,EAAiBC,EACvB,MAAMJ,EAAeL,KAAKD,KAAKO,kBAC/BE,EAAeoB,YAAY,IAAIC,EAAQ,CACnCC,QAASJ,EACTK,KAAMC,EAAYC,YAAYC,MAC9BC,OAAQX,EACRY,UAAW/B,GAAca,aAEjC,CACJ,CASOmB,eAAeC,EAAmBR,GACrC,GAAI9B,KAAKD,KAAKQ,YAAY,uBAAyB,KAAM,CACrD,MACJ,CAEA,MAAMF,EAAeL,KAAKD,KAAKO,kBAC/B,IAAKD,EAAc,CACf,MACJ,CAEAI,EAAUmB,YAAY,IAAIC,EAAQ,CAC9BC,QAASA,EACTC,KAAMC,EAAYC,YAAYC,MAC9BC,OAAQ,IAAIG,EAAUb,QAAQ,MAAO,MACrCW,UAAW/B,EAAaa,WACxBqB,KAAM,gBAEd,CAOOC,iBAAiBF,GACpB,GAAItC,KAAKD,KAAKQ,YAAY,uBAAyB,KAAM,CACrD,MACJ,CAEA,MAAMF,EAAeL,KAAKD,KAAKO,kBAC/B,IAAKD,EAAc,CACf,MACJ,CAEA,MAAM8B,EAAS,IAAIG,EAAUb,QAAQ,MAAO,MAC5C,MAAMgB,EAAcpC,EAAaa,WAAWD,QAC5C,MAAMP,EAAWD,EAAUE,kBAAkBC,UAE7C,MAAMC,EAAmBH,EAASI,OAAOC,GACrCA,EAAE2B,cAAgBP,GAClBpB,EAAE4B,YAAc,eAChB5B,EAAEC,uBAAuBC,UAAYwB,GAGzC,GAAI5B,EAAiBM,OAAS,EAAG,CAC7BV,EAAUW,eAAeP,EAC7B,CACJ,CAKO+B,mBAAmBC,GACtBlD,EAAOkD,MAAM,yEAA0EA,EAAMf,QAAS,sBAEtG,MAAMgB,EAAY,IAAIC,EAAmB,CACrCC,MAAO,uBACPC,YAAa,kGAGjBjD,KAAKD,KAAKmD,eAAe,WAAYJ,EACzC,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAAtD,qBAAA,OAAAsD,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":18,"column":0},"map":{"version":3,"names":["Registry","___Registry","OperatorRegistry","register","a","b","ConditionEngine","constructor","schema","this","plugins","Map","handleEvent","fieldKey","isValid","registerPlugin","bindingPath","plugin","set","destroy","clear","__exports","__esModule"],"sources":["ConditionEngine.ts"],"sourcesContent":["/**\n * @file ConditionEngine.ts\n * @description Evaluates dynamic rules to alter the schema in real-time.\n */\n\nimport { IPlugin } from \"../interfaces/IPlugin\";\nimport { ISchema } from \"../interfaces/ISchema\";\nimport { Registry } from \"./Registry\";\n\nexport type ConditionOperator = (a: unknown, b: unknown) => boolean;\n\nexport const OperatorRegistry = new Registry<ConditionOperator>(\"Operators\");\n\n// Register basic default operators\nOperatorRegistry.register(\"==\", (a, b) => a == b);\nOperatorRegistry.register(\"===\", (a, b) => a === b);\nOperatorRegistry.register(\"!=\", (a, b) => a != b);\nOperatorRegistry.register(\"!==\", (a, b) => a !== b);\nOperatorRegistry.register(\">\", (a, b) => a > b);\nOperatorRegistry.register(\"<\", (a, b) => a < b);\nOperatorRegistry.register(\">=\", (a, b) => a >= b);\nOperatorRegistry.register(\"<=\", (a, b) => a <= b);\n\n/**\n * Engine that listens to the EventBus and evaluates cross-field dependencies (e.g. visibleOn, enabledOn).\n * It delegates actual evaluations to the configurable `OperatorRegistry`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class ConditionEngine {\n /** The active form schema being evaluated. */\n private schema: ISchema;\n /**\n * Initializes the ConditionEngine with the active schema.\n * @param schema The current UI layout schema.\n */\n constructor(schema: ISchema) {\n this.schema = schema;\n }\n\n\n\n /** Internal map tracking active plugins against their binding paths for real-time state updates. */\n private plugins: Map<string, IPlugin> = new Map();\n\n /**\n * Internal handler to evaluate business rules when a field is updated.\n * @param fieldKey The key of the field that was changed\n * @param isValid Whether the field is currently valid\n */\n public handleEvent(fieldKey: string, isValid: boolean): void {\n // Evaluate conditions via registered operators if a rule system is added later\n }\n\n /**\n * Registers a rendered plugin so the condition engine can push dynamic state updates to it.\n * \n * @param bindingPath The JSON path representing the field within the payload.\n * @param plugin The instantiated plugin handling the field.\n */\n public registerPlugin(bindingPath: string, plugin: IPlugin): void {\n this.plugins.set(bindingPath, plugin);\n }\n\n /**\n * Cleans up listeners to prevent memory leaks on destruction.\n */\n public destroy(): void {\n this.plugins.clear();\n }\n}\n"],"mappings":"AAAA,4GAAA,MAOSA,EAAQC,EAAA,YAIV,MAAMC,EAAmB,IAAIF,EAA4B,aAGhEE,EAAiBC,SAAS,KAAM,CAACC,EAAGC,IAAMD,GAAKC,GAC/CH,EAAiBC,SAAS,MAAO,CAACC,EAAGC,IAAMD,IAAMC,GACjDH,EAAiBC,SAAS,KAAM,CAACC,EAAGC,IAAMD,GAAKC,GAC/CH,EAAiBC,SAAS,MAAO,CAACC,EAAGC,IAAMD,IAAMC,GACjDH,EAAiBC,SAAS,IAAK,CAACC,EAAGC,IAAMD,EAAIC,GAC7CH,EAAiBC,SAAS,IAAK,CAACC,EAAGC,IAAMD,EAAIC,GAC7CH,EAAiBC,SAAS,KAAM,CAACC,EAAGC,IAAMD,GAAKC,GAC/CH,EAAiBC,SAAS,KAAM,CAACC,EAAGC,IAAMD,GAAKC,GASxC,MAAMC,EAOTC,YAAYC,GACRC,KAAKD,OAASA,CAClB,CAKQE,QAAgC,IAAIC,IAOrCC,YAAYC,EAAkBC,GACjC,CASGC,eAAeC,EAAqBC,GACvCR,KAAKC,QAAQQ,IAAIF,EAAaC,EAClC,CAKOE,UACHV,KAAKC,QAAQU,OACjB,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAnB,mBAAAmB,EAAAf,kBAAA,OAAAe,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":19,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","this","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","scope","error","msg","message","Error","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n /**\n * Recursively traverses property metadata to synthesize generic Group and Control layout definitions.\n * @param props The properties object from the schema.\n * @param basePath The absolute JSON scope path to prefix bindings.\n * @returns An array of generated layout element descriptors.\n */\n private static generateElementsFromProperties(props: Record<string, import(\"../interfaces/ISchema\").IPropertyMetadata>, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n try {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n // We do not recursively inline nested objects as Groups.\n // MetaUI handles nested objects dynamically via the ObjectPlugin drill-down dialog.\n // This prevents duplicate Tables and infinite recursion on circular $refs.\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n } catch (error) {\n // Do not swallow errors. A failure to synthesize a property is a critical failure.\n const msg = `[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}': ${(error as Error).message}`;\n Logger.error(msg);\n throw new Error(msg);\n }\n }\n return elements;\n }\n}\n"],"mappings":"AAAA,wHAAA,MAMSA,EAAMC,EAAA,UAYR,MAAMC,EAMT,mBAAcC,CAAaC,GAEvB,GAAIA,EAAOC,UAAYC,MAAMC,QAAQH,EAAOC,WAAaD,EAAOC,SAASG,OAAS,EAAG,CACjF,OAAO,KACX,CAEA,MAAMD,EAAUH,EAAOK,OAAS,QAChC,MAAMC,EAAQH,EAAUH,EAAOO,OAAOC,WAAaR,EAAOQ,WAE1D,IAAKF,GAASG,OAAOC,KAAKJ,GAAOF,SAAW,EAAG,CAC3C,OAAO,KACX,CAEA,MAAMO,EAAWC,KAAKC,+BAA+BP,EAAO,gBAE5D,GAAIH,EAAS,CAITH,EAAOC,SAAWU,EAASG,OAAOC,GAAKA,EAAEV,OAAS,UACtD,KAAO,CAEHL,EAAOC,SAAW,CACd,CACII,KAAM,QACNW,MAAOhB,EAAOiB,MACdN,SAAUA,GAGtB,CAEA,OAAO,IACX,CAQA,qCAAeE,CAA+BP,EAA0EY,GACpH,MAAMP,EAA6B,GACnC,IAAK,MAAMQ,KAAOV,OAAOC,KAAKJ,GAAQ,CAClC,IACI,MAAMc,EAAOd,EAAMa,GACnB,MAAME,EAAc,GAAGH,KAAYC,IAKnCR,EAASW,KAAK,CACVjB,KAAM,UACNkB,MAAOF,GAEf,CAAE,MAAOG,GAEL,MAAMC,EAAM,kEAAkEN,OAAUK,EAAgBE,UACxG9B,EAAO4B,MAAMC,GACb,MAAM,IAAIE,MAAMF,EACpB,CACJ,CACA,OAAOd,CACX,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAA9B,yBAAA,OAAA8B,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":20,"column":0},"map":{"version":3,"names":["ConditionEngine","___ConditionEngine","PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","Engine","conditionEngine","activePlugins","isEditable","hasPartialRenderingErrors","useMessageManager","constructor","editable","pluginRegistry","this","getInstance","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","handleEvent","ensureLayout","warn","layoutStrategy","type","layoutManager","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","setUseMessageManager","push","path","scopeId","undefined","control","registerPlugin","generateLayout","validateAll","applyVisualState","errors","item","result","validate","setVisualValidationState","replace","name","getPluginByPath","cleanPath","startsWith","match","find","p","destroy","messageManager","Messaging","existingMessages","getMessageModel","getData","messagesToRemove","targetPath","matched","filter","getTarget","getMessageProcessor","getId","length","removeMessages","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\nimport { ConditionEngine } from \"./ConditionEngine\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n /** Handles dynamic conditional logic across the active form. */\n private conditionEngine: ConditionEngine | null = null;\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: sap.ui.model.Model;\n\n /** Reference to the GeneratorHost that instantiated this engine, for retrieving global definitions. */\n public host?: unknown;\n\n /** Callback to notify the host that an internal field changed. */\n public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */\n public hasPartialRenderingErrors: boolean = false;\n\n /** Tracks whether the engine should delegate visual state to the global MessageManager. */\n public readonly useMessageManager: boolean = false;\n\n /** The injected PluginRegistry instance */\n public readonly pluginRegistry: PluginRegistry;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.\n * @param pluginRegistry Optional injected plugin registry. Defaults to singleton.\n */\n constructor(editable: boolean = true, useMessageManager: boolean = false, pluginRegistry?: PluginRegistry) {\n this.isEditable = editable;\n this.useMessageManager = useMessageManager;\n this.pluginRegistry = pluginRegistry || PluginRegistry.getInstance();\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: sap.ui.model.Model, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.conditionEngine = new ConditionEngine(schema);\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (this.conditionEngine && fieldKey) {\n this.conditionEngine.handleEvent(fieldKey, isValid);\n }\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n // Intercept and synthesize a default layout if the developer/backend failed to provide one\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(\"[MetaUI Engine] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = this.pluginRegistry.getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = this.pluginRegistry.getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n if (typeof plugin.setEditable === \"function\") {\n plugin.setEditable(this.isEditable);\n }\n\n if (typeof plugin.setUseMessageManager === \"function\") {\n plugin.setUseMessageManager(this.useMessageManager);\n }\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange, this.activeModel);\n\n if (this.conditionEngine) {\n this.conditionEngine.registerPlugin(bindingPath, plugin);\n }\n\n return control;\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = this.pluginRegistry.getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.\n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(applyVisualState: boolean = false): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (applyVisualState && typeof item.plugin.setVisualValidationState === \"function\") {\n item.plugin.setVisualValidationState(result.isValid, result.errorMessage);\n }\n\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n Logger.error(`[MetaUI Engine] Error validating plugin at ${item.path}`, (error as Error).message);\n }\n }\n return errors;\n }\n\n /**\n * Retrieves an active plugin instance by its absolute binding path.\n * Useful for programmatic field manipulation (e.g., custom error injection).\n * \n * @param path The binding path (e.g. \"/General/CustomerName\").\n * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.\n */\n public getPluginByPath(path: string): import(\"../interfaces/IPlugin\").IPlugin | undefined {\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n const match = this.activePlugins.find(p => p.path === cleanPath || p.path === `/${cleanPath}`);\n return match ? match.plugin : undefined;\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n if (this.conditionEngine) {\n this.conditionEngine.destroy();\n this.conditionEngine = null;\n }\n\n // ------------------------------------------------------------------------\n // Ghost Error Prevention\n // Flush MessageManager for active plugins before destroying their controls\n // ------------------------------------------------------------------------\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove: unknown[] = [];\n\n for (const item of this.activePlugins) {\n if (this.activeModel) {\n const targetPath = `/${item.path.replace(/^\\//, \"\")}`;\n const matched = (existingMessages as { getTarget: () => string, getMessageProcessor: () => { getId: () => string } }[]).filter(msg =>\n msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.activeModel!.getId()\n );\n messagesToRemove.push(...matched);\n }\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.activePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":21,"column":0},"map":{"version":3,"names":["Registry","___Registry","PatternValidatorPlugin","___plugins_validators_PatternValidatorPlugin","MinLengthValidatorPlugin","___plugins_validators_MinLengthValidatorPlugin","RangeValidatorPlugin","___plugins_validators_RangeValidatorPlugin","UrlValidatorPlugin","___plugins_validators_UrlValidatorPlugin","IbanValidatorPlugin","___plugins_validators_IbanValidatorPlugin","EmailValidatorPlugin","___plugins_validators_EmailValidatorPlugin","DateFormatterPlugin","___plugins_formatters_DateFormatterPlugin","PhoneFormatterPlugin","___plugins_formatters_PhoneFormatterPlugin","TextCaseFormatterPlugin","___plugins_formatters_TextCaseFormatterPlugin","Logger","___utils_Logger","RequiredValidator","validate","parsedValue","args","undefined","isValid","errorMessage","MaxLengthValidator","length","PipelineManager","formatters","parsers","validators","constructor","this","register","executeValidation","requestedValidators","argsMap","rule","validator","get","result","error","msg","message","warn","GlobalPipeline","__exports","__esModule"],"sources":["PipelineManager.ts"],"sourcesContent":["/**\n * @file PipelineManager.ts\n * @description Central manager for the data manipulation pipeline. \n * Orchestrates Formatting, Parsing, and Validating data using the generic Registry.\n */\n\nimport { Registry } from \"./Registry\";\nimport { IFormatter, IParser, IValidator, IValidationResult } from \"../interfaces/IPipeline\";\nimport { PatternValidatorPlugin } from \"../plugins/validators/PatternValidatorPlugin\";\nimport { MinLengthValidatorPlugin } from \"../plugins/validators/MinLengthValidatorPlugin\";\nimport { RangeValidatorPlugin } from \"../plugins/validators/RangeValidatorPlugin\";\nimport { UrlValidatorPlugin } from \"../plugins/validators/UrlValidatorPlugin\";\nimport { IbanValidatorPlugin } from \"../plugins/validators/IbanValidatorPlugin\";\nimport { EmailValidatorPlugin } from \"../plugins/validators/EmailValidatorPlugin\";\nimport { DateFormatterPlugin } from \"../plugins/formatters/DateFormatterPlugin\";\nimport { PhoneFormatterPlugin } from \"../plugins/formatters/PhoneFormatterPlugin\";\nimport { TextCaseFormatterPlugin } from \"../plugins/formatters/TextCaseFormatterPlugin\";\nimport { Logger } from \"../utils/Logger\";\n\n// --- Built-in Default Validators ---\n/** Internal rule for required fields. */\nclass RequiredValidator implements IValidator {\n /** Validates that the value is not null, undefined, or empty string. */\n validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (parsedValue === null || parsedValue === undefined || parsedValue === \"\") {\n return { isValid: false, errorMessage: \"This field is required.\" };\n }\n return { isValid: true };\n }\n}\n\n/** Internal rule for string maximum length. */\nclass MaxLengthValidator implements IValidator {\n /** Validates that a string does not exceed the provided argument length. */\n validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (typeof parsedValue === \"string\" && args && typeof args === \"number\") {\n if (parsedValue.length > args) {\n return { isValid: false, errorMessage: `Maximum length is ${args} characters.` };\n }\n }\n return { isValid: true };\n }\n}\n\n\n/**\n * The core engine responsible for marshalling data through the validation, formatting, and parsing phases.\n * Pluggable design allows new validators to be registered dynamically.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class PipelineManager {\n /** Registry of data formatters applied before pushing to the UI. */\n public readonly formatters: Registry<IFormatter> = new Registry<IFormatter>(\"Formatters\");\n /** Registry of data parsers applied when pulling data from the UI. */\n public readonly parsers: Registry<IParser> = new Registry<IParser>(\"Parsers\");\n /** Registry of business logic validators. */\n public readonly validators: Registry<IValidator> = new Registry<IValidator>(\"Validators\");\n\n /**\n * Bootstraps the PipelineManager with default validators (required, maxLength, email).\n */\n constructor() {\n // Register default validators\n this.validators.register(\"required\", new RequiredValidator());\n this.validators.register(\"maxLength\", new MaxLengthValidator());\n this.validators.register(\"pattern\", new PatternValidatorPlugin());\n this.validators.register(\"minLength\", new MinLengthValidatorPlugin());\n this.validators.register(\"range\", new RangeValidatorPlugin());\n this.validators.register(\"url\", new UrlValidatorPlugin());\n this.validators.register(\"iban\", new IbanValidatorPlugin());\n this.validators.register(\"email\", new EmailValidatorPlugin());\n\n // Register default formatters\n this.formatters.register(\"date\", new DateFormatterPlugin());\n this.formatters.register(\"phone\", new PhoneFormatterPlugin());\n this.formatters.register(\"textCase\", new TextCaseFormatterPlugin());\n }\n\n /**\n * Executes the validation pipeline sequentially. Fails fast on the first encountered error.\n * \n * @param parsedValue The raw extracted value from the UI control.\n * @param requestedValidators Array of validation rule keys (e.g. ['required', 'email']).\n * @param argsMap Optional map of parameters required by specific rules (e.g. { maxLength: 50 }).\n * @returns {IValidationResult} The final result state and any associated error message.\n */\n public executeValidation(parsedValue: unknown, requestedValidators: string[], argsMap?: Record<string, unknown>): IValidationResult {\n for (const rule of requestedValidators) {\n const validator = this.validators.get(rule);\n if (validator) {\n const args = argsMap ? argsMap[rule] : undefined;\n try {\n const result = validator.validate(parsedValue, args);\n if (!result.isValid) {\n return result; // Fast fail on first error\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] PipelineManager: Validator '${rule}' crashed during execution.`, msg);\n return { isValid: false, errorMessage: `System validation error: ${msg}` };\n }\n } else {\n Logger.warn(`[MetaUI] PipelineManager: Requested validator '${rule}' not found in registry.`);\n }\n }\n return { isValid: true };\n }\n}\n\n/** \n * Singleton instance for global access to the active validation pipeline. \n * @public \n */\nexport const GlobalPipeline = new PipelineManager();\n"],"mappings":"AAAA,4iBAAA,MAMSA,EAAQC,EAAA,kBAERC,EAAsBC,EAAA,gCACtBC,EAAwBC,EAAA,kCACxBC,EAAoBC,EAAA,8BACpBC,EAAkBC,EAAA,4BAClBC,EAAmBC,EAAA,6BACnBC,EAAoBC,EAAA,8BACpBC,EAAmBC,EAAA,6BACnBC,EAAoBC,EAAA,8BACpBC,EAAuBC,EAAA,iCACvBC,EAAMC,EAAA,UAIf,MAAMC,EAEFC,SAASC,EAAsBC,GAC3B,GAAID,IAAgB,MAAQA,IAAgBE,WAAaF,IAAgB,GAAI,CACzE,MAAO,CAAEG,QAAS,MAAOC,aAAc,0BAC3C,CACA,MAAO,CAAED,QAAS,KACtB,EAIJ,MAAME,EAEFN,SAASC,EAAsBC,GAC3B,UAAWD,IAAgB,UAAYC,UAAeA,IAAS,SAAU,CACrE,GAAID,EAAYM,OAASL,EAAM,CAC3B,MAAO,CAAEE,QAAS,MAAOC,aAAc,qBAAqBH,gBAChE,CACJ,CACA,MAAO,CAAEE,QAAS,KACtB,EAWG,MAAMI,EAEOC,WAAmC,IAAIhC,EAAqB,cAE5DiC,QAA6B,IAAIjC,EAAkB,WAEnDkC,WAAmC,IAAIlC,EAAqB,cAK5EmC,cAEIC,KAAKF,WAAWG,SAAS,WAAY,IAAIf,GACzCc,KAAKF,WAAWG,SAAS,YAAa,IAAIR,GAC1CO,KAAKF,WAAWG,SAAS,UAAW,IAAInC,GACxCkC,KAAKF,WAAWG,SAAS,YAAa,IAAIjC,GAC1CgC,KAAKF,WAAWG,SAAS,QAAS,IAAI/B,GACtC8B,KAAKF,WAAWG,SAAS,MAAO,IAAI7B,GACpC4B,KAAKF,WAAWG,SAAS,OAAQ,IAAI3B,GACrC0B,KAAKF,WAAWG,SAAS,QAAS,IAAIzB,GAGtCwB,KAAKJ,WAAWK,SAAS,OAAQ,IAAIvB,GACrCsB,KAAKJ,WAAWK,SAAS,QAAS,IAAIrB,GACtCoB,KAAKJ,WAAWK,SAAS,WAAY,IAAInB,EAC7C,CAUOoB,kBAAkBd,EAAsBe,EAA+BC,GAC1E,IAAK,MAAMC,KAAQF,EAAqB,CACpC,MAAMG,EAAYN,KAAKF,WAAWS,IAAIF,GACtC,GAAIC,EAAW,CACX,MAAMjB,EAAOe,EAAUA,EAAQC,GAAQf,UACvC,IACI,MAAMkB,EAASF,EAAUnB,SAASC,EAAaC,GAC/C,IAAKmB,EAAOjB,QAAS,CACjB,OAAOiB,CACX,CACJ,CAAE,MAAOC,GACL,MAAMC,EAAOD,EAAgBE,QAC7B3B,EAAOyB,MAAM,wCAAwCJ,+BAAmCK,GACxF,MAAO,CAAEnB,QAAS,MAAOC,aAAc,4BAA4BkB,IACvE,CACJ,KAAO,CACH1B,EAAO4B,KAAK,kDAAkDP,4BAClE,CACJ,CACA,MAAO,CAAEd,QAAS,KACtB,EAOG,MAAMsB,EAAiB,IAAIlB,EAAkB,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAAnB,kBAAAmB,EAAAD,iBAAA,OAAAC,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":22,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","PluginRegistry","fieldIndex","actionIndex","layoutIndex","activePromises","constructor","this","registerPluginPath","undefined","registerLayoutPath","getInstance","instance","type","widgetName","path","key","registerActionPath","actionName","strategy","getFieldPath","Error","getLayoutPath","getPathsToLoad","schema","pathsToLoad","Set","layoutStrategy","add","scanProperties","props","prop","ui","widget","e","msg","message","error","properties","items","preloadDependencies","promises","Array","from","map","Promise","resolve","reject","sap","require","Module","err","all","extractConstructor","default","keys","Object","getPlugin","PluginClass","getLayout","LayoutClass","__exports","__esModule"],"sources":["PluginRegistry.ts"],"sourcesContent":["/**\n * @file PluginRegistry.ts\n * @description Centralized hub for mapping UI5 controls to SAP schema data types.\n * Enforces the Registry Pattern to decouple the core engine from specific UI5 control implementations.\n * NOW WITH UNIVERSAL LAZY LOADING.\n */\n\nimport { IPlugin } from \"../interfaces/IPlugin\";\nimport { FieldType, ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\n\nexport class PluginRegistry {\n private static instance: PluginRegistry;\n \n private fieldIndex: Record<string, string> = {};\n private actionIndex: Record<string, string> = {};\n private layoutIndex: Record<string, string> = {};\n \n private activePromises: Record<string, Promise<unknown>> = {};\n\n private constructor() {\n // Core Mappings\n this.registerPluginPath(\"string\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin\");\n this.registerPluginPath(\"number\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin\");\n this.registerPluginPath(\"integer\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin\");\n this.registerPluginPath(\"date\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin\");\n this.registerPluginPath(\"boolean\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin\");\n this.registerPluginPath(\"array\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin\");\n this.registerPluginPath(\"object\", undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin\");\n this.registerPluginPath(\"string\", \"default\", \"nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin\");\n this.registerPluginPath(\"object\", \"dictionary\", \"nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin\");\n this.registerPluginPath(\"object\", \"reference\", \"nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin\");\n\n // Widget Overrides\n this.registerPluginPath(\"string\", \"time\", \"nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin\");\n this.registerPluginPath(\"string\", \"datetime\", \"nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin\");\n this.registerPluginPath(\"boolean\", \"switch\", \"nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin\");\n this.registerPluginPath(\"number\", \"step\", \"nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin\");\n this.registerPluginPath(\"string\", \"select\", \"nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin\");\n this.registerPluginPath(\"string\", \"textArea\", \"nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin\");\n this.registerPluginPath(\"string\", \"codeEditor\", \"nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin\");\n this.registerPluginPath(\"string\", \"link\", \"nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin\");\n this.registerPluginPath(\"string\", \"password\", \"nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin\");\n this.registerPluginPath(\"string\", \"email\", \"nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin\");\n \n // Phase 1 Mappings\n this.registerPluginPath(\"string\", \"fileUploader\", \"nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin\");\n this.registerPluginPath(\"array\", \"multiSelect\", \"nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin\");\n this.registerPluginPath(\"array\", \"multiInput\", \"nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin\");\n this.registerPluginPath(\"number\", \"slider\", \"nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin\");\n this.registerPluginPath(\"number\", \"rating\", \"nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin\");\n this.registerPluginPath(\"string\", \"messageStrip\", \"nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin\");\n\n // Phase 5 Mappings (Hardware)\n this.registerPluginPath(\"string\", \"camera\", \"nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin\");\n this.registerPluginPath(\"string\", \"signature\", \"nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin\");\n this.registerPluginPath(\"object\", \"location\", \"nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin\");\n this.registerPluginPath(\"string\", \"scanner\", \"nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin\");\n this.registerPluginPath(\"string\", \"voiceInput\", \"nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin\");\n this.registerPluginPath(\"string\", \"richText\", \"nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin\");\n\n // Actions & Datasources\n this.registerPluginPath(\"string\", \"urlButton\", \"nz/co/siliconst/ui5/metaui/plugins/actions/UrlNavigationActionPlugin\");\n this.registerPluginPath(\"string\", \"submitButton\", \"nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin\");\n this.registerPluginPath(\"string\", \"odataSelect\", \"nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin\");\n this.registerPluginPath(\"string\", \"remoteDropdown\", \"nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin\");\n this.registerPluginPath(\"string\", \"liveSearch\", \"nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin\");\n this.registerPluginPath(\"string\", \"remoteValueHelp\", \"nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin\");\n\n // Layouts\n this.registerLayoutPath(\"form\", \"nz/co/siliconst/ui5/metaui/layouts/FormLayout\");\n this.registerLayoutPath(\"table\", \"nz/co/siliconst/ui5/metaui/layouts/TableLayout\");\n this.registerLayoutPath(\"wizard\", \"nz/co/siliconst/ui5/metaui/layouts/WizardLayout\");\n this.registerLayoutPath(\"compact\", \"nz/co/siliconst/ui5/metaui/layouts/CompactLayout\");\n }\n\n public static getInstance(): PluginRegistry {\n if (!PluginRegistry.instance) {\n PluginRegistry.instance = new PluginRegistry();\n }\n return PluginRegistry.instance;\n }\n\n public registerPluginPath(type: FieldType, widgetName: string | undefined, path: string): void {\n const key = widgetName ? `${type}:${widgetName}` : type;\n this.fieldIndex[key] = path;\n }\n\n public registerActionPath(actionName: string, path: string): void {\n this.actionIndex[actionName] = path;\n }\n\n public registerLayoutPath(strategy: string, path: string): void {\n this.layoutIndex[strategy] = path;\n }\n\n private getFieldPath(type: FieldType, widgetName?: string): string {\n let path;\n if (widgetName) {\n path = this.fieldIndex[`${type}:${widgetName}`];\n }\n if (!path) {\n path = this.fieldIndex[type];\n }\n if (!path) {\n throw new Error(`No plugin path mapped for FieldType: ${type} (widget: ${widgetName})`);\n }\n return path;\n }\n\n private getLayoutPath(strategy: string): string {\n const path = this.layoutIndex[strategy];\n if (!path) {\n throw new Error(`No layout path mapped for strategy: ${strategy}`);\n }\n return path;\n }\n\n /**\n * Statically traverses the schema structure to identify all required plugins\n * and layouts without actually instantiating them.\n * \n * @param {ISchema} schema The root JSON schema payload to traverse\n * @returns {Set<string>} A distinct set of UI5 module paths required to render the schema\n */\n public getPathsToLoad(schema: ISchema): Set<string> {\n const pathsToLoad = new Set<string>();\n \n // 1. Gather layout strategy\n const strategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n pathsToLoad.add(this.getLayoutPath(strategy));\n\n // 2. Recursively gather field plugins\n const scanProperties = (props: Record<string, IPropertyMetadata>) => {\n for (const key in props) {\n const prop = props[key];\n try {\n pathsToLoad.add(this.getFieldPath(prop.type || \"string\", prop.ui?.widget));\n } catch (e) {\n const msg = `[MetaUI LazyLoad] Could not find mapped plugin for field ${key}: ${(e as Error).message}`;\n Logger.error(msg);\n throw new Error(msg);\n }\n if (prop.properties) scanProperties(prop.properties);\n if (prop.items && prop.items.properties) scanProperties(prop.items.properties);\n if (prop.items && prop.items.type) {\n try {\n pathsToLoad.add(this.getFieldPath(prop.items.type, prop.items.ui?.widget));\n } catch (e) {\n const msg = `[MetaUI LazyLoad] Could not find mapped plugin for array item type ${prop.items.type}: ${(e as Error).message}`;\n Logger.error(msg);\n throw new Error(msg);\n }\n }\n }\n };\n\n if (schema.properties) {\n scanProperties(schema.properties);\n } else if (schema.items && schema.items.properties) {\n scanProperties(schema.items.properties);\n }\n\n return pathsToLoad;\n }\n\n /**\n * Defers the generation of the UI until all required UI5 modules have been\n * downloaded asynchronously. Maintains a cache of active promises to prevent\n * redundant network requests for the same module.\n * \n * @param {ISchema} schema The root JSON schema payload to parse\n * @returns {Promise<void>} Resolves when all dependencies are securely in the UI5 require cache\n */\n public async preloadDependencies(schema: ISchema): Promise<void> {\n const pathsToLoad = this.getPathsToLoad(schema);\n\n // 3. Batch execute sap.ui.require via Promises\n const promises = Array.from(pathsToLoad).map(path => {\n if (!this.activePromises[path]) {\n this.activePromises[path] = new Promise((resolve, reject) => {\n sap.ui.require([path], \n (Module: unknown) => resolve(Module), \n (err: unknown) => {\n Logger.error(`Failed to lazy load module: ${path}`);\n // CRITICAL: Delete from cache so future attempts can retry the network request\n delete this.activePromises[path];\n reject(err);\n }\n );\n });\n }\n return this.activePromises[path];\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Extracts a valid constructor from a dynamically required module.\n */\n private extractConstructor(Module: unknown): new () => IPlugin | ILayoutManager | null {\n if (!Module) return null;\n if (typeof Module === \"function\") return Module as any;\n if ((Module as any).default && typeof (Module as any).default === \"function\") return (Module as any).default;\n \n // Handle namespace exports (e.g. { FormLayout: class... })\n const keys = Object.keys(Module as object);\n for (const key of keys) {\n if (typeof (Module as any)[key] === \"function\") {\n return (Module as any)[key];\n }\n }\n return null;\n }\n\n /**\n * Instantiates the requested plugin for the given field type.\n */\n public getPlugin(type: FieldType, widgetName?: string): IPlugin {\n const path = this.getFieldPath(type, widgetName);\n const Module = sap.ui.require(path);\n const PluginClass = this.extractConstructor(Module);\n \n if (!PluginClass) {\n throw new Error(`[MetaUI Plugin Instantiation] Plugin ${path} was not preloaded or has no constructor!`);\n }\n \n return new PluginClass();\n }\n\n /**\n * Instantiates the requested layout manager for the given strategy.\n */\n public getLayout(strategy: string): ILayoutManager {\n const path = this.getLayoutPath(strategy);\n const Module = sap.ui.require(path);\n const LayoutClass = this.extractConstructor(Module);\n \n if (!LayoutClass) {\n throw new Error(`[MetaUI Layout Instantiation] Layout ${path} was not preloaded or has no constructor!`);\n }\n \n return new LayoutClass();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":23,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","Registry","items","Map","constructor","registryName","this","register","key","item","has","warn","set","get","getStrict","msg","error","Error","getKeys","Array","from","keys","clear","__exports","__esModule"],"sources":["Registry.ts"],"sourcesContent":["/**\n * @file Registry.ts\n * @description Universal generic registry pattern used across the MetaUI library \n * for registering and resolving decoupled plugins (Layouts, Controls, Validators, etc).\n */\n\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Universal generic registry pattern used across the MetaUI library \n * for registering and resolving decoupled plugins (Layouts, Controls, Validators, etc).\n * \n * @template T The type of item being stored in the registry.\n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Registry<T> {\n /** The internal map storing the registered items. */\n public readonly items = new Map<string, T>();\n\n constructor(public readonly registryName: string = \"Registry\") {}\n\n /**\n * Registers a new item (plugin/layout/validator) into the registry.\n * @param key The unique string identifier.\n * @param item The implementation class or instance.\n */\n public register(key: string, item: T): void {\n if (this.items.has(key)) {\n Logger.warn(`[MetaUI] ${this.registryName}: Overwriting existing key '${key}'.`);\n }\n this.items.set(key, item);\n }\n\n /**\n * Retrieves an item by its key.\n * @param key The unique string identifier.\n * @returns The registered item, or undefined if not found.\n */\n public get(key: string): T | undefined {\n return this.items.get(key);\n }\n\n /**\n * Retrieves an item by its key, throwing an error if it doesn't exist.\n * @param key The unique string identifier.\n * @returns The registered item.\n */\n public getStrict(key: string): T {\n const item = this.get(key);\n if (!item) {\n const msg = `[MetaUI] ${this.registryName}: Key '${key}' not found.`;\n Logger.error(msg);\n throw new Error(msg);\n }\n return item;\n }\n\n /**\n * Returns an array of all registered keys.\n */\n public getKeys(): string[] {\n return Array.from(this.items.keys());\n }\n\n /**\n * Clears the entire registry.\n */\n public clear(): void {\n this.items.clear();\n }\n}\n"],"mappings":"AAAA,0GAAA,MAMSA,EAAMC,EAAA,UAUR,MAAMC,EAEOC,MAAQ,IAAIC,IAE5BC,YAA4BC,EAAuB,YAAYC,KAAnCD,cAAoC,CAOzDE,SAASC,EAAaC,GACzB,GAAIH,KAAKJ,MAAMQ,IAAIF,GAAM,CACrBT,EAAOY,KAAK,YAAYL,KAAKD,2CAA2CG,MAC5E,CACAF,KAAKJ,MAAMU,IAAIJ,EAAKC,EACxB,CAOOI,IAAIL,GACP,OAAOF,KAAKJ,MAAMW,IAAIL,EAC1B,CAOOM,UAAUN,GACb,MAAMC,EAAOH,KAAKO,IAAIL,GACtB,IAAKC,EAAM,CACP,MAAMM,EAAM,YAAYT,KAAKD,sBAAsBG,gBACnDT,EAAOiB,MAAMD,GACb,MAAM,IAAIE,MAAMF,EACpB,CACA,OAAON,CACX,CAKOS,UACH,OAAOC,MAAMC,KAAKd,KAAKJ,MAAMmB,OACjC,CAKOC,QACHhB,KAAKJ,MAAMoB,OACf,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAtB,WAAA,OAAAsB,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":24,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___SchemaNormalizer","OpenApiBuilder","___openapi_OpenApiBuilder","Logger","___utils_Logger","SchemaBuilderRegistry","static","register","plugin","this","_plugins","push","getBuilderFor","rawSchema","canHandle","warn","__exports","__esModule"],"sources":["SchemaBuilderRegistry.ts"],"sourcesContent":["/**\n * @file SchemaBuilderRegistry.ts\n * @description Singleton registry for Schema Builder plugins.\n * Routes unknown JSON payloads to the appropriate parser plugin.\n */\n\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { SchemaNormalizer } from \"./SchemaNormalizer\";\nimport { OpenApiBuilder } from \"../openapi/OpenApiBuilder\";\nimport { Logger } from \"../utils/Logger\";\n\nexport class SchemaBuilderRegistry {\n private static _plugins: ISchemaBuilderPlugin[] = [\n new OpenApiBuilder(),\n new SchemaNormalizer()\n ];\n\n /**\n * Registers a new schema builder plugin into the engine.\n * @param plugin An instance of ISchemaBuilderPlugin\n */\n public static register(plugin: ISchemaBuilderPlugin): void {\n this._plugins.push(plugin);\n }\n\n /**\n * Finds the first registered plugin that claims it can handle the payload.\n * @param rawSchema The raw JSON schema object to inspect.\n * @returns The matching plugin instance, or null if none match.\n */\n public static getBuilderFor(rawSchema: unknown): ISchemaBuilderPlugin | null {\n if (!rawSchema || typeof rawSchema !== \"object\") {\n return null;\n }\n\n for (const plugin of this._plugins) {\n if (plugin.canHandle(rawSchema)) {\n return plugin;\n }\n }\n \n Logger.warn(\"[SchemaBuilderRegistry]\", \"No suitable Schema Builder plugin found for the provided payload.\");\n return null;\n }\n}\n"],"mappings":"AAAA,4KAAA,MAOSA,EAAgBC,EAAA,0BAChBC,EAAcC,EAAA,wBACdC,EAAMC,EAAA,UAER,MAAMC,EACTC,gBAAkD,CAC9C,IAAIL,EACJ,IAAIF,GAOR,eAAcQ,CAASC,GACnBC,KAAKC,SAASC,KAAKH,EACvB,CAOA,oBAAcI,CAAcC,GACxB,IAAKA,UAAoBA,IAAc,SAAU,CAC7C,OAAO,IACX,CAEA,IAAK,MAAML,KAAUC,KAAKC,SAAU,CAChC,GAAIF,EAAOM,UAAUD,GAAY,CAC7B,OAAOL,CACX,CACJ,CAEAL,EAAOY,KAAK,0BAA2B,qEACvC,OAAO,IACX,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAX,wBAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":25,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","SchemaNormalizer","canHandle","rawSchema","build","targetDefinition","normalize","data","schemaObj","trim","JSON","parse","e","msg","message","error","Error","Array","isArray","this","inferSchemaFromData","normalized","title","type","items","layoutStrategy","uiLayout","additionalProperties","targetProperties","properties","inferred","deepMergeProperties","requiredKeys","required","normalizeProperties","normalizePropertyMetadata","base","override","merged","key","Object","keys","overrideVal","baseVal","normalizedProps","isRequired","includes","prop","keyName","$ref","ui","label","generateLabel","isKey","readOnly","widget","valueHelp","enum","undefined","visibleOn","enabledOn","format","validators","formatter","args","rows","fullWidth","dialogButtonText","maxLength","minLength","minimum","maximum","pattern","precision","scale","multipleOf","name","spaced","replace","split","filter","w","length","map","word","charAt","toUpperCase","slice","toLowerCase","join","schema","inferPropertiesFromObject","obj","val","nestedProps","resolveScope","scope","startsWith","meta","bindingPath","propKey","pathSegments","current","debug","stringify","i","segment","__exports","__esModule"],"sources":["SchemaNormalizer.ts"],"sourcesContent":["/**\n * @file SchemaNormalizer.ts\n * @description Transforms and validates incoming JSON payloads into the strict v2 ISchema dictionary matrix.\n */\n\nimport { ISchema, IPropertyMetadata, FieldType } from \"../interfaces/ISchema\";\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { Logger } from \"../utils/Logger\";\n\nexport class SchemaNormalizer implements ISchemaBuilderPlugin {\n\n /**\n * ISchemaBuilderPlugin Contract\n */\n public canHandle(rawSchema: unknown): boolean {\n // Fallback for native ISchemas or data inference.\n // It always returns true because it is the final fallback builder in the registry.\n return true;\n }\n\n /**\n * ISchemaBuilderPlugin Contract\n */\n public build(rawSchema: unknown, targetDefinition?: string): ISchema {\n return SchemaNormalizer.normalize(rawSchema);\n }\n\n /**\n * Validates that the provided raw payload conforms to the required ISchema structures.\n */\n public static normalize(rawSchema?: unknown, data?: unknown): ISchema {\n let schemaObj = rawSchema;\n\n if (typeof schemaObj === \"string\") {\n if (!schemaObj.trim()) {\n schemaObj = null;\n } else {\n try {\n schemaObj = JSON.parse(schemaObj);\n } catch (e) {\n const msg = \"Failed to parse schema string: \" + (e as Error).message;\n Logger.error(\"[MetaUI SchemaNormalizer]\", msg);\n throw new Error(msg);\n }\n }\n }\n\n if (!schemaObj || typeof schemaObj !== 'object' || Array.isArray(schemaObj)) {\n return this.inferSchemaFromData(data);\n }\n\n try {\n // It is an object. Ensure it conforms to v2 structure.\n const normalized: ISchema = {\n title: schemaObj.title,\n type: schemaObj.type || (schemaObj.items ? \"array\" : \"object\"),\n layoutStrategy: schemaObj.layoutStrategy,\n uiLayout: schemaObj.uiLayout,\n additionalProperties: schemaObj.additionalProperties\n };\n\n let targetProperties = schemaObj.properties || {};\n\n if (schemaObj.additionalProperties === true && data) {\n const inferred = this.inferSchemaFromData(data);\n if (inferred.type === \"object\" && inferred.properties) {\n targetProperties = this.deepMergeProperties(inferred.properties, targetProperties);\n } else if (inferred.type === \"array\" && inferred.items && inferred.items.properties) {\n // Array schema merging could be added here if we want full support.\n }\n }\n\n if (normalized.type === \"object\") {\n const requiredKeys = Array.isArray(schemaObj.required) ? schemaObj.required : [];\n normalized.properties = this.normalizeProperties(targetProperties, requiredKeys);\n } else if (normalized.type === \"array\") {\n // Future expansion: array deep merge\n normalized.items = this.normalizePropertyMetadata(schemaObj.items || { type: \"object\", properties: {} }, \"items\", false);\n }\n\n return normalized;\n } catch (error) {\n const msg = \"Critical error normalizing schema object: \" + (error as Error).message;\n Logger.error(\"[MetaUI SchemaNormalizer]\", msg);\n throw new Error(msg);\n }\n }\n\n /**\n * Recursively deep merges an inferred schema over a base schema.\n * @param base The base property dictionary.\n * @param override The overriding inferred dictionary.\n * @returns A new deeply merged property dictionary.\n */\n private static deepMergeProperties(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {\n const merged = { ...base };\n for (const key of Object.keys(override)) {\n const overrideVal = override[key];\n const baseVal = merged[key];\n\n if (baseVal && typeof baseVal === \"object\" && !Array.isArray(baseVal) &&\n overrideVal && typeof overrideVal === \"object\" && !Array.isArray(overrideVal)) {\n merged[key] = this.deepMergeProperties(baseVal, overrideVal);\n } else {\n merged[key] = overrideVal;\n }\n }\n return merged;\n }\n\n /**\n * Normalizes a collection of properties.\n * @param properties The raw properties map.\n * @param requiredKeys An optional array of keys that are required by the parent object.\n * @returns A map of strict IPropertyMetadata objects.\n */\n private static normalizeProperties(properties: Record<string, unknown>, requiredKeys: string[] = []): Record<string, IPropertyMetadata> {\n const normalizedProps: Record<string, IPropertyMetadata> = {};\n for (const key of Object.keys(properties)) {\n const isRequired = requiredKeys.includes(key);\n normalizedProps[key] = this.normalizePropertyMetadata(properties[key], key, isRequired);\n }\n return normalizedProps;\n }\n\n /**\n * Normalizes a single property against the ISchema specification.\n * @param prop The raw property definition.\n * @param keyName The string key name for generating default labels.\n * @param isRequired Indicates if the parent object mandated this property as required.\n * @returns A strict IPropertyMetadata instance.\n */\n private static normalizePropertyMetadata(prop: Record<string, unknown>, keyName: string, isRequired: boolean = false): IPropertyMetadata {\n const normalized: IPropertyMetadata = {\n type: (prop.type as FieldType) || \"string\",\n $ref: prop.$ref as string | undefined,\n ui: {\n label: (prop.ui as any)?.label || this.generateLabel(keyName),\n isKey: !!(prop.ui as any)?.isKey,\n readOnly: !!(prop.ui as any)?.readOnly,\n widget: (prop.ui as any)?.widget || (prop.valueHelp || prop.enum ? \"select\" : undefined),\n visibleOn: prop.ui?.visibleOn,\n enabledOn: prop.ui?.enabledOn,\n format: prop.ui?.format,\n validators: prop.ui?.validators,\n formatter: prop.ui?.formatter,\n args: prop.ui?.args,\n rows: prop.ui?.rows,\n fullWidth: prop.ui?.fullWidth,\n dialogButtonText: prop.ui?.dialogButtonText\n },\n required: isRequired || !!prop.required,\n maxLength: prop.maxLength as number,\n minLength: prop.minLength as number,\n minimum: prop.minimum,\n maximum: prop.maximum,\n pattern: prop.pattern,\n precision: prop.precision,\n scale: prop.scale,\n multipleOf: prop.multipleOf as number,\n valueHelp: prop.valueHelp,\n enum: prop.enum\n };\n\n if (normalized.type === \"object\" && prop.properties) {\n const requiredKeys = Array.isArray(prop.required) ? prop.required : [];\n normalized.properties = this.normalizeProperties(prop.properties as Record<string, unknown>, requiredKeys);\n normalized.uiLayout = prop.uiLayout;\n } else if (normalized.type === \"array\" && prop.items) {\n normalized.items = this.normalizePropertyMetadata(prop.items as Record<string, unknown>, \"items\", false);\n normalized.uiLayout = prop.uiLayout;\n }\n\n return normalized;\n }\n\n /**\n * Generates a Title Case label from camelCase or snake_case technical names.\n */\n private static generateLabel(name: string): string {\n if (!name) return \"\";\n let spaced = name.replace(/([A-Z])/g, \" $1\").replace(/_/g, \" \");\n return spaced.split(' ')\n .filter(w => w.length > 0)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n .trim();\n }\n\n /**\n * Infers a v2 ISchema structure dynamically from a plain data payload.\n */\n public static inferSchemaFromData(data: unknown): ISchema {\n const schema: ISchema = { type: \"object\", properties: {}, layoutStrategy: \"compact\", title: \"\" };\n\n if (!data || typeof data !== \"object\") {\n return schema;\n }\n\n if (Array.isArray(data)) {\n schema.type = \"array\";\n if (data.length > 0 && typeof data[0] !== \"object\") {\n schema.layoutStrategy = \"compact\";\n schema.items = { type: typeof data[0] as FieldType };\n } else {\n schema.layoutStrategy = \"table\";\n schema.items = {\n type: \"object\",\n layoutStrategy: \"compact\",\n properties: data.length > 0 ? this.inferPropertiesFromObject(data[0] as Record<string, unknown>) : {}\n };\n }\n } else {\n schema.type = \"object\";\n schema.properties = this.inferPropertiesFromObject(data);\n }\n\n return schema;\n }\n\n /**\n * Infers field metadata recursively from a raw data object.\n * @param obj The raw JavaScript object.\n * @returns A dictionary of inferred IPropertyMetadata.\n */\n private static inferPropertiesFromObject(obj: Record<string, unknown>): Record<string, IPropertyMetadata> {\n const properties: Record<string, IPropertyMetadata> = {};\n if (!obj || typeof obj !== \"object\") return properties;\n\n for (const key of Object.keys(obj)) {\n const val = obj[key];\n if (val === null || val === undefined) continue;\n\n let type: FieldType = \"string\";\n let items: IPropertyMetadata | undefined;\n let nestedProps: Record<string, IPropertyMetadata> | undefined;\n\n if (typeof val === \"number\") type = \"number\";\n else if (typeof val === \"boolean\") type = \"boolean\";\n else if (Array.isArray(val)) {\n type = \"array\";\n if (val.length > 0 && typeof val[0] !== \"object\") {\n items = {\n type: typeof val[0] as FieldType\n };\n } else {\n items = {\n type: \"object\",\n properties: val.length > 0 ? this.inferPropertiesFromObject(val[0] as Record<string, unknown>) : {}\n };\n }\n } else if (typeof val === \"object\") {\n type = \"object\";\n nestedProps = this.inferPropertiesFromObject(val);\n }\n\n properties[key] = {\n type,\n items,\n properties: nestedProps,\n ui: {\n label: this.generateLabel(key),\n isKey: false,\n readOnly: false,\n widget: type === \"array\" && items?.type !== \"object\" ? \"multiInput\" : undefined\n }\n };\n }\n\n return properties;\n }\n\n /**\n * Resolves a JSON Schema scope (e.g. '#/properties/header/properties/id')\n * against the ISchema, returning the PropertyMetadata and the UI5 binding path.\n */\n public static resolveScope(schema: ISchema, scope: string): { meta: IPropertyMetadata | undefined, bindingPath: string, propKey: string } {\n if (!scope || !scope.startsWith(\"#/properties/\")) {\n return { meta: undefined, bindingPath: scope || \"\", propKey: scope || \"\" };\n }\n \n const pathSegments = scope.replace(\"#/properties/\", \"\").split(\"/properties/\");\n let current: Record<string, IPropertyMetadata> | undefined = schema.properties;\n let meta: IPropertyMetadata | undefined;\n \n Logger.debug(\"[MetaUI SchemaNormalizer]\", `Resolving scope '${scope}' with segments: ${JSON.stringify(pathSegments)}`, \"SchemaNormalizer\");\n Logger.debug(\"[MetaUI SchemaNormalizer]\", `Root schema keys: ${Object.keys(schema.properties || {})}`, \"SchemaNormalizer\");\n\n for (let i = 0; i < pathSegments.length; i++) {\n const segment = pathSegments[i];\n if (!current) {\n Logger.debug(\"[MetaUI SchemaNormalizer]\", `current is undefined at segment '${segment}'`, \"SchemaNormalizer\");\n meta = undefined;\n break;\n }\n meta = current[segment];\n Logger.debug(\"[MetaUI SchemaNormalizer]\", `Segment '${segment}' resolved to meta: ${!!meta}. Available keys in current: ${Object.keys(current)}`, \"SchemaNormalizer\");\n if (i < pathSegments.length - 1) {\n current = meta?.properties;\n }\n }\n \n const bindingPath = pathSegments.join(\"/\");\n const propKey = scope.replace(\"#/properties/\", \"\"); // The original raw string for logging\n \n return {\n meta,\n bindingPath,\n propKey\n };\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":26,"column":0},"map":{"version":3,"names":["SchemaValidator","validateSchemaStructure","schema","errors","s","type","push","properties","key","Object","keys","prop","allowedTypes","includes","join","__exports","__esModule"],"sources":["SchemaValidator.ts"],"sourcesContent":["/**\n * @file SchemaValidator.ts\n * @description Structural validation utility to catch developer errors in the JSON schema itself.\n */\n\nimport { ISchema, FieldType } from \"../interfaces/ISchema\";\n\nexport class SchemaValidator {\n /**\n * Validates a parsed JSON schema object for structural correctness.\n * @param schema The schema object to validate\n * @returns An array of error strings. Empty if no errors.\n */\n public static validateSchemaStructure(schema: unknown): string[] {\n const errors: string[] = [];\n\n if (!schema || typeof schema !== \"object\") {\n return [\"Root schema must be an object.\"];\n }\n\n const s = schema as Record<string, any>;\n if (s.type !== \"object\" && s.type !== \"array\") {\n errors.push(`Root schema must have type 'object' or 'array'. Found: '${s.type}'`);\n }\n\n if (s.type === \"object\" && !s.properties) {\n errors.push(\"Object schema is missing the 'properties' node.\");\n }\n\n if (s.properties) {\n for (const key of Object.keys(s.properties)) {\n const prop = s.properties[key];\n if (!prop || typeof prop !== \"object\") {\n errors.push(`Property '${key}' must be an object.`);\n continue;\n }\n\n if (!prop.type) {\n errors.push(`Property '${key}' is missing 'type'.`);\n } else {\n const allowedTypes: FieldType[] = [\"string\", \"number\", \"integer\", \"boolean\", \"date\", \"object\", \"array\"];\n if (!allowedTypes.includes(prop.type)) {\n errors.push(`Property '${key}' has invalid type '${prop.type}'. Allowed: ${allowedTypes.join(\", \")}`);\n }\n }\n\n // Removed strict check for prop.items on array properties because inference handles empty definitions\n\n }\n }\n\n return errors;\n }\n}\n"],"mappings":"AAAA,+FAOO,MAAMA,EAMT,8BAAcC,CAAwBC,GAClC,MAAMC,EAAmB,GAEzB,IAAKD,UAAiBA,IAAW,SAAU,CACvC,MAAO,CAAC,iCACZ,CAEA,MAAME,EAAIF,EACV,GAAIE,EAAEC,OAAS,UAAYD,EAAEC,OAAS,QAAS,CAC3CF,EAAOG,KAAK,2DAA2DF,EAAEC,QAC7E,CAEA,GAAID,EAAEC,OAAS,WAAaD,EAAEG,WAAY,CACtCJ,EAAOG,KAAK,kDAChB,CAEA,GAAIF,EAAEG,WAAY,CACd,IAAK,MAAMC,KAAOC,OAAOC,KAAKN,EAAEG,YAAa,CACzC,MAAMI,EAAOP,EAAEG,WAAWC,GAC1B,IAAKG,UAAeA,IAAS,SAAU,CACnCR,EAAOG,KAAK,aAAaE,yBACzB,QACJ,CAEA,IAAKG,EAAKN,KAAM,CACZF,EAAOG,KAAK,aAAaE,wBAC7B,KAAO,CACH,MAAMI,EAA4B,CAAC,SAAU,SAAU,UAAW,UAAW,OAAQ,SAAU,SAC/F,IAAKA,EAAaC,SAASF,EAAKN,MAAO,CACnCF,EAAOG,KAAK,aAAaE,wBAA0BG,EAAKN,mBAAmBO,EAAaE,KAAK,QACjG,CACJ,CAIJ,CACJ,CAEA,OAAOX,CACX,EACH,IAAAY,EAAA,CAAAC,WAAA,MAAAD,EAAAf,kBAAA,OAAAe,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":27,"column":0},"map":{"version":3,"names":["GlobalPipeline","___PipelineManager","StateManager","schema","_useMessageManager","constructor","initialData","modelName","this","activeModelName","safeData","JSON","parse","stringify","model","JSONModel","setDefaultBindingMode","originalSetProperty","setProperty","bind","sPath","oValue","oContext","bAsyncUpdate","result","validatePath","setUseMessageManager","use","value","fieldKey","replace","metadata","findMetadataForPath","messageManager","Messaging","targetPath","startsWith","existingMessages","getMessageModel","getData","messagesToRemove","filter","msg","isMatch","getTarget","getMessageProcessor","getId","length","removeMessages","validatorsToRun","argsMap","required","push","type","maxLength","minLength","pattern","minimum","undefined","maximum","min","max","format","ui","validators","v","name","args","validationResult","executeValidation","isValid","newMsg","Message","message","errorMessage","coreLibrary","MessageType","Error","target","processor","addMessages","path","properties","getModel","bindControl","control","property","bindingPath","bindProperty","extractPayload","data","destroy","__exports","__esModule"],"sources":["StateManager.ts"],"sourcesContent":["/**\n * @file StateManager.ts\n * @description Isolated internal state management. Decouples the MetaUI engine from external host models.\n */\n\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport ManagedObject from \"sap/ui/base/ManagedObject\";\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { GlobalPipeline } from \"./PipelineManager\";\nimport Message from \"sap/ui/core/message/Message\";\nimport coreLibrary from \"sap/ui/core/library\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n\n/**\n * Manages the isolated internal data payload for the MetaUI engine.\n */\nexport class StateManager {\n private model: JSONModel;\n private activeModelName: string;\n private schema: ISchema | null = null;\n private _useMessageManager: boolean = false;\n\n /**\n * Initializes the state manager with an authentic SAPUI5 JSONModel.\n * @param initialData The initial JSON payload to populate the fields.\n * @param schema The normalized schema for live validation.\n * @param modelName The UI5 model alias used for isolation.\n */\n constructor(initialData: Record<string, unknown> = {}, schema: ISchema, modelName: string = \"meta\") {\n this.activeModelName = modelName;\n this.schema = schema;\n \n // Deep copy to ensure no reference leakage from the host application\n const safeData = JSON.parse(JSON.stringify(initialData));\n this.model = new JSONModel(safeData);\n this.model.setDefaultBindingMode(\"TwoWay\");\n\n // Centralized Model-Level Validation Interceptor\n const originalSetProperty = this.model.setProperty.bind(this.model);\n this.model.setProperty = (sPath: string, oValue: unknown, oContext?: unknown, bAsyncUpdate?: boolean) => {\n const result = originalSetProperty(sPath, oValue, oContext, bAsyncUpdate);\n this.validatePath(sPath, oValue);\n return result;\n };\n }\n\n /**\n * Updates the flag indicating whether this manager should push validation errors directly to the global MessageManager.\n */\n public setUseMessageManager(use: boolean): void {\n this._useMessageManager = use;\n }\n\n /**\n * Validates a specific path against the schema and updates the MessageManager.\n */\n private validatePath(sPath: string, value: unknown): void {\n const fieldKey = sPath.replace(/^\\//, \"\");\n const metadata = this.findMetadataForPath(fieldKey);\n \n const messageManager = Messaging;\n const targetPath = sPath.startsWith(\"/\") ? sPath : `/${sPath}`; // Pure UI5: target MUST be absolute path\n \n // 1. Remove existing messages (strictly for THIS model instance)\n if (this._useMessageManager) {\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove = existingMessages.filter((msg: sap.ui.core.message.Message) => {\n const isMatch = msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.model.getId();\n return isMatch;\n });\n \n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n }\n\n if (!metadata) return;\n\n // 2. Run GlobalPipeline\n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {};\n\n if (metadata.required) {\n validatorsToRun.push(\"required\");\n }\n if (metadata.type === \"string\" && metadata.maxLength) {\n validatorsToRun.push(\"maxLength\");\n argsMap[\"maxLength\"] = metadata.maxLength;\n }\n if (metadata.minLength) {\n validatorsToRun.push(\"minLength\");\n argsMap[\"minLength\"] = metadata.minLength;\n }\n if (metadata.pattern) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = metadata.pattern;\n }\n if (metadata.minimum !== undefined || metadata.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: metadata.minimum, max: metadata.maximum };\n }\n \n const format = metadata.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n if (metadata.ui?.validators) {\n for (const v of metadata.ui.validators) {\n if (typeof v === \"string\") {\n validatorsToRun.push(v);\n } else if (v && v.name) {\n validatorsToRun.push(v.name);\n if (v.args !== undefined) {\n argsMap[v.name] = v.args;\n }\n }\n }\n }\n\n if (validatorsToRun.length > 0) {\n const validationResult = GlobalPipeline.executeValidation(value, validatorsToRun, argsMap);\n if (!validationResult.isValid && this._useMessageManager) {\n const newMsg = new Message({\n message: validationResult.errorMessage || \"Invalid value.\",\n type: coreLibrary.MessageType.Error,\n target: targetPath,\n processor: this.model\n });\n messageManager.addMessages(newMsg);\n }\n }\n }\n\n /**\n * Resolves the schema metadata for a given internal binding path.\n * @param path The flat binding path representing the field.\n * @returns The associated IPropertyMetadata, or undefined if not mapped.\n */\n private findMetadataForPath(path: string): IPropertyMetadata | undefined {\n if (!this.schema || !this.schema.properties) return undefined;\n // Basic single-level support for now. Nested object resolution would split by '.' or '/'\n return this.schema.properties[path];\n }\n\n\n\n /**\n * Retrieves the isolated JSONModel instance to attach to the root GeneratorHost control.\n * @returns The internal JSONModel.\n */\n public getModel(): JSONModel {\n return this.model;\n }\n\n /**\n * Binds a generated UI control property to a path in the internal model.\n * @param control The target UI5 Control.\n * @param property The UI5 property name (e.g., 'value').\n * @param bindingPath The exact path in the JSON payload.\n */\n public bindControl(control: ManagedObject, property: string, bindingPath: string): void {\n control.bindProperty(property, {\n path: bindingPath,\n model: \"meta\" // Assumes the model is bound to the root container with the name 'meta'\n });\n }\n\n /**\n * Extracts the flat JavaScript object representing the current state of the UI.\n * @returns A serialized record of the data payload, free of UI5 wrappers.\n */\n public extractPayload(): Record<string, unknown> {\n // Create a deep copy to prevent accidental mutations by the host\n const data = this.model.getData();\n return JSON.parse(JSON.stringify(data));\n }\n\n /**\n * Cleans up internal state and natively destroys the UI5 JSONModel to prevent memory leaks.\n */\n public destroy(): void {\n \n if (this.model) {\n this.model.destroy();\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":28,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","CompactLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","addStyleClass","uiLayout","Array","isArray","warn","tableElements","renderElement","element","type","label","title","sap","m","Title","text","level","addItem","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fieldBox","__exports","__esModule"],"sources":["CompactLayout.ts"],"sourcesContent":["/**\n * @file CompactLayout.ts\n * @description Generates a lightweight, dense VBox layout for use inside tight spaces like table cells.\n */\n\nimport VBox from \"sap/m/VBox\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).\n * Ideal for rendering objects dynamically inside table cells or side-panels.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class CompactLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a dense VBox layout.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated compact form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n container.addStyleClass(\"sapUiTinyMargin\");\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.\");\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n const title = new sap.m.Title({ text: element.label, level: \"H5\" });\n title.addStyleClass(\"sapUiTinyMarginTop sapUiTinyMarginBottom\");\n container.addItem(title);\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"CompactLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"CompactLayout\");\n return;\n }\n\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI CompactLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"CompactLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n Logger.debug(\"[MetaUI CompactLayout]\", `Rendering scalar field '${bindingPath}'.`, \"CompactLayout\");\n this._renderScalarField(container, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"CompactLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n // Render array/table sub-layouts full width below the fields\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiTinyMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n /**\n * Synthesizes a primitive field into the layout.\n * @param container The VBox container.\n * @param element The layout element definition.\n * @param propKey The bound property key.\n * @param meta The inferred metadata schema.\n * @param modelName The UI5 data model name.\n * @param engine The core Engine instance.\n */\n private _renderScalarField(container: VBox, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n label.addStyleClass(\"sapUiTinyMarginTop\");\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n control.addStyleClass(\"sapUiTinyMarginBottom\");\n\n // Wrap label and field tightly\n const fieldBox = new VBox({ renderType: \"Bare\", items: [label, control] });\n container.addItem(fieldBox);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":29,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","FormLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","form","SimpleForm","editable","title","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","uiLayout","Array","isArray","warn","addItem","tableElements","hasFormFields","renderElement","element","type","label","addContent","Title","text","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","addStyleClass","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","isNativelyWide","isFullWidth","fullWidth","undefined","sap","require","GridData","setLayoutData","span","__exports","__esModule"],"sources":["FormLayout.ts"],"sourcesContent":["/**\n * @file FormLayout.ts\n * @description Generates a fully responsive SAP Fiori Form layout (SimpleForm).\n */\n\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.\n * It traverses the `uiLayout` tree defined in the schema to build the form groups and fields,\n * completely separating visual orchestration from data modeling.\n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class FormLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a UI5 SimpleForm using the uiLayout definitions.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n const form = new SimpleForm({\n editable: true,\n title: schema.title,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.\");\n container.addItem(form);\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n let hasFormFields = false;\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n form.addContent(new Title({ text: element.label }));\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"FormLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"FormLayout\");\n return;\n }\n\n // Architectural Boundary: Separate Field Controls (Plugins) from Sub-Layouts (LayoutManagers)\n // A property is delegated to a Sub-Layout Manager (Table) ONLY if it represents a collection of complex objects.\n // Collections of primitives, or explicitly assigned widgets (like multiSelect), remain in the Form as Field Plugins.\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI FormLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"FormLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n hasFormFields = true;\n Logger.debug(\"[MetaUI FormLayout]\", `Rendering scalar field '${bindingPath}'.`, \"FormLayout\");\n this._renderScalarField(form, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"FormLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n if (hasFormFields) {\n container.addItem(form);\n }\n\n // Render array/table sub-layouts full width below the form\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout // Pass down sub-layout if available\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiSmallMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n /**\n * Synthesizes a primitive field into the Form.\n * @param form The SimpleForm instance.\n * @param element The layout element definition.\n * @param propKey The bound property key.\n * @param meta The inferred metadata schema.\n * @param modelName The UI5 data model name.\n * @param engine The core Engine instance.\n */\n private _renderScalarField(form: SimpleForm, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n // Override widget if specified in the layout element\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n\n // Automatically apply fullWidth layout data if natively wide or explicitly requested\n const widget = effectiveMeta.ui?.widget;\n const isNativelyWide = widget === \"codeEditor\" || widget === \"textArea\" || widget === \"richText\";\n const isFullWidth = effectiveMeta.ui?.fullWidth !== undefined ? effectiveMeta.ui?.fullWidth : isNativelyWide;\n\n if (isFullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: typeof import(\"sap/ui/layout/GridData\").default) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":30,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","TableLayout","render","schema","modelName","engine","onSubmit","bindingPath","itemsSchema","items","properties","ui","widget","$ref","debug","host","getSchemaDefinition","resolved","Object","keys","error","getMetadata","getName","type","Error","tableTitle","title","actualModelName","actualPath","table","Table","headerToolbar","Toolbar","content","Title","text","ToolbarSpacer","isEditable","Button","icon","press","oEvent","btn","getSource","tbl","getParent","model","getModel","info","getBindingInfo","path","rawData","getProperty","data","Array","isArray","newData","setProperty","onChange","replace","fixedLayout","mode","delete","item","getParameter","getBindingContext","getPath","splitPaths","split","index","parseInt","pop","arrayPath","join","splice","templateCells","props","layoutElements","uiLayout","forEach","element","scope","meta","fieldMeta","propKey","resolveScope","addColumn","Column","header","Text","label","demandPopin","isKey","minScreenWidth","popinDisplay","effectiveMeta","control","generateField","push","warn","key","column","msg","message","showErrorPopup","rowTemplate","ColumnListItem","cells","bindItems","template","templateShareable","__exports","__esModule"],"sources":["TableLayout.ts"],"sourcesContent":["/**\n * @file TableLayout.ts\n * @description Generates a responsive SAP Fiori Table layout for v2 schema.\n */\n\nimport Table from \"sap/m/Table\";\nimport Column from \"sap/m/Column\";\nimport Text from \"sap/m/Text\";\nimport ColumnListItem from \"sap/m/ColumnListItem\";\nimport Toolbar from \"sap/m/Toolbar\";\nimport Title from \"sap/m/Title\";\nimport ToolbarSpacer from \"sap/m/ToolbarSpacer\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Control from \"sap/ui/core/Control\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Layout Manager responsible for generating a responsive SAP Fiori Table.\n * It is automatically utilized by the Engine when the schema root or property is of type 'array'.\n * Includes built-in support for adding and deleting rows via dynamic data binding manipulation.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class TableLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema array properties into a UI5 Table.\n * \n * @param schema The active JSON schema array definition.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @param engine The central orchestrator for delegating column plugin generation.\n * @param onSubmit Optional submit hook.\n * @param bindingPath The JSON path representing the array within the payload.\n * @returns {Control} The generated sap.m.Table control.\n * @throws {Error} If the provided schema is not of type 'array'.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void, bindingPath: string = \"/\"): Control {\n let itemsSchema = schema.items;\n if (itemsSchema && !itemsSchema.properties && itemsSchema.ui?.widget === \"reference\" && itemsSchema.$ref) {\n Logger.debug(`[MetaUI] TableLayout detecting reference widget for ${bindingPath}. Resolving ${itemsSchema.$ref}`, \"\", \"TableLayout\");\n if (engine.host && engine.host.getSchemaDefinition) {\n const resolved = engine.host.getSchemaDefinition(itemsSchema.$ref);\n Logger.debug(`[MetaUI] Resolved schema for ${itemsSchema.$ref}: ${!!resolved} ${resolved ? Object.keys(resolved) : \"\"}`, \"\", \"TableLayout\");\n if (resolved && resolved.properties) {\n itemsSchema = resolved;\n } else {\n Logger.error(`[MetaUI] TableLayout resolved schema but it has no properties!`, \"\", \"TableLayout\");\n }\n } else {\n Logger.error(`[MetaUI] TableLayout cannot resolve ${itemsSchema.$ref} because engine.host.getSchemaDefinition is missing! host: ${engine.host?.getMetadata().getName()}`, \"\", \"TableLayout\");\n }\n }\n\n if (schema.type !== \"array\" || !itemsSchema || !itemsSchema.properties) {\n Logger.error(`[MetaUI] TableLayout fatal error! schema.type: ${schema.type}, itemsSchema: ${!!itemsSchema}, properties: ${itemsSchema ? !!itemsSchema.properties : false}`, \"\", \"TableLayout\");\n throw new Error(\"[MetaUI] TableLayout requires an array schema with items.properties.\");\n }\n\n const tableTitle = schema.title || \"Table\";\n const actualModelName = modelName;\n const actualPath = bindingPath;\n\n const table = new Table({\n headerToolbar: new Toolbar({\n content: [\n new Title({ text: tableTitle }),\n new ToolbarSpacer(),\n ...(!engine.isEditable ? [] : [\n new Button({\n text: \"Add Row\",\n icon: \"sap-icon://add\",\n press: (oEvent: sap.ui.base.Event) => {\n const btn = oEvent.getSource();\n const tbl = btn.getParent().getParent() as Table;\n const model = tbl.getModel(actualModelName) as JSONModel;\n const info = tbl.getBindingInfo(\"items\");\n if (!info || !info.path) return;\n\n const rawData = model.getProperty(info.path);\n const data = Array.isArray(rawData) ? rawData : [];\n const newData = [...data, {}];\n model.setProperty(info.path, newData);\n\n // CRITICAL: Notify the engine so it extracts payload and triggers liveUpdate\n if (engine.onChange) {\n engine.onChange(true, actualPath.replace(/^\\//, \"\"));\n }\n }\n })\n ])\n ]\n }),\n fixedLayout: false,\n mode: !engine.isEditable ? \"None\" : \"Delete\",\n delete: (oEvent: sap.ui.base.Event) => {\n const item = oEvent.getParameter(\"listItem\");\n const path = item.getBindingContext(actualModelName).getPath();\n const model = item.getModel(actualModelName) as JSONModel;\n\n const splitPaths = path.split(\"/\");\n const index = parseInt(splitPaths.pop() || \"0\", 10);\n let arrayPath = splitPaths.join(\"/\");\n if (arrayPath === \"\") arrayPath = \"/\";\n\n const rawData = model.getProperty(arrayPath);\n const data = Array.isArray(rawData) ? rawData : [];\n const newData = [...data];\n newData.splice(index, 1);\n model.setProperty(arrayPath, newData);\n\n // CRITICAL: Notify the engine so it extracts payload and triggers liveUpdate\n if (engine.onChange) {\n engine.onChange(true, actualPath.replace(/^\\//, \"\"));\n }\n }\n });\n\n const templateCells: Control[] = [];\n const props = itemsSchema.properties;\n const layoutElements = schema.uiLayout;\n\n if (layoutElements && Array.isArray(layoutElements)) {\n // Only render columns defined in uiLayout\n layoutElements.forEach((element: ILayoutElement) => {\n if (element.type === \"Control\" && element.scope) {\n const { meta: fieldMeta, bindingPath, propKey } = SchemaNormalizer.resolveScope(\n { type: \"object\", properties: props } as ISchema, \n element.scope\n );\n \n if (!fieldMeta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions for Table.`, \"\", \"TableLayout\");\n } else {\n // The architectural boundary: Table Layout orchestrates the columns and aggregation binding,\n // but delegates the actual cell rendering to the Engine's Field Plugins.\n table.addColumn(new Column({\n header: new Text({ text: element.label || fieldMeta.ui?.label || propKey }),\n demandPopin: !fieldMeta.ui?.isKey,\n minScreenWidth: fieldMeta.ui?.isKey ? \"\" : \"Tablet\",\n popinDisplay: \"Inline\"\n }));\n\n const effectiveMeta = { ...fieldMeta };\n if (element.widget) {\n effectiveMeta.ui = { ...fieldMeta.ui, widget: element.widget };\n }\n\n // We pass the activeModel as actualModelName down. But the path must be relative to the \n // table row binding context, so we just use the bindingPath (e.g. \"id\" or \"header/id\")\n const control = engine.generateField(effectiveMeta, bindingPath, actualModelName || \"meta\", true);\n templateCells.push(control);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}' in Table.`, \"\", \"TableLayout\");\n }\n });\n } else {\n Logger.debug(\"[MetaUI TableLayout]\", \"No uiLayout provided. Falling back to rendering all properties as columns.\", \"TableLayout\");\n // Fallback: If no uiLayout is provided, render all properties as columns\n Object.keys(props).forEach((key) => {\n try {\n const fieldMeta = props[key];\n const isKey = !!fieldMeta.ui?.isKey;\n\n const column = new Column({\n header: new Text({ text: fieldMeta.ui?.label || key }),\n demandPopin: !isKey,\n minScreenWidth: isKey ? \"\" : \"Tablet\",\n popinDisplay: \"Inline\"\n });\n table.addColumn(column);\n\n const control = engine.generateField(fieldMeta, key, actualModelName || \"meta\", true);\n templateCells.push(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render fallback column ${key}`, msg, \"TableLayout\");\n Logger.showErrorPopup(`Failed to render fallback table column '${key}'.\\n\\nDetails: ${msg}`);\n templateCells.push(new Text({ text: \"Error\" }));\n }\n });\n }\n\n\n\n const rowTemplate = new ColumnListItem({\n cells: templateCells\n });\n\n table.bindItems({\n path: actualPath,\n model: actualModelName,\n template: rowTemplate,\n templateShareable: false\n });\n\n return table;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":31,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","WizardLayout","render","schema","modelName","engine","onSubmit","wizard","Wizard","renderMode","showNextButton","complete","uiLayout","Array","isArray","warn","forEach","element","type","step","WizardStep","title","label","validated","form","SimpleForm","editable","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","elements","childElement","this","_renderElementInForm","addContent","addStep","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","labelText","ui","Label","text","required","effectiveMeta","widget","control","generateField","fullWidth","sap","require","GridData","setLayoutData","span","message","__exports","__esModule"],"sources":["WizardLayout.ts"],"sourcesContent":["/**\n * @file WizardLayout.ts\n * @description Generates a fully responsive SAP Fiori Wizard layout.\n */\n\nimport Wizard from \"sap/m/Wizard\";\nimport WizardStep from \"sap/m/WizardStep\";\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a responsive SAP Fiori Wizard.\n * It segments the schema fields into discrete Wizard Steps based on `uiLayout` elements \n * of type `Group` or `WizardStep`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class WizardLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a paginated UI5 Wizard using uiLayout.\n * \n * @param schema The active JSON schema object.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Hook executed when the Wizard's native 'complete' event is fired.\n * @returns {Control} The generated sap.m.Wizard control.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const wizard = new Wizard({\n renderMode: \"Page\",\n showNextButton: true,\n complete: function() {\n if (onSubmit) onSubmit();\n }\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in wizard schema. Wizard will not render any steps.\");\n return wizard;\n }\n\n schema.uiLayout.forEach((element: ILayoutElement) => {\n if (element.type === \"Group\" || element.type === \"WizardStep\") {\n const step = new WizardStep({\n title: element.label || \"Step\",\n validated: true // The PipelineManager handles global validation, wizard step validation can be local later\n });\n\n const form = new SimpleForm({\n editable: true,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(childElement => {\n this._renderElementInForm(form, childElement, schema, modelName, engine);\n });\n }\n\n step.addContent(form);\n wizard.addStep(step);\n } else {\n Logger.warn(`[MetaUI] Top-level element '${element.type}' inside WizardLayout must be 'Group' or 'WizardStep'.`, \"\", \"WizardLayout\");\n }\n });\n\n return wizard;\n }\n\n /**\n * Synthesizes a field into the wizard step form.\n * @param form The SimpleForm belonging to the step.\n * @param element The layout element definition.\n * @param schema The schema reference.\n * @param modelName The UI5 data model name.\n * @param engine The core Engine instance.\n */\n private _renderElementInForm(form: SimpleForm, element: ILayoutElement, schema: ISchema, modelName: string, engine: Engine): void {\n if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"WizardLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"WizardLayout\");\n return;\n }\n\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${bindingPath}`, modelName);\n\n if (effectiveMeta.ui?.fullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: typeof import(\"sap/ui/layout/GridData\").default) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n Logger.error(`[MetaUI] Failed to render Wizard field ${propKey}`, (error as Error).message, \"WizardLayout\");\n form.addContent(new Label({ text: propKey }));\n }\n } else {\n Logger.warn(`[MetaUI] Nested groups within Wizard steps are not fully supported in SimpleForm yet.`, \"\", \"WizardLayout\");\n }\n }\n}\n"],"mappings":"AAAA,4OAaSA,EAAgBC,EAAA,0BAChBC,EAAMC,EAAA,UAWR,MAAMC,EAUFC,OAAOC,EAAiBC,EAAmBC,EAAgBC,GAC9D,MAAMC,EAAS,IAAIC,EAAO,CACtBC,WAAY,OACZC,eAAgB,KAChBC,SAAU,WACN,GAAIL,EAAUA,GAClB,IAGJ,IAAKH,EAAOS,WAAaC,MAAMC,QAAQX,EAAOS,UAAW,CACrDb,EAAOgB,KAAK,yFACZ,OAAOR,CACX,CAEAJ,EAAOS,SAASI,QAASC,IACrB,GAAIA,EAAQC,OAAS,SAAWD,EAAQC,OAAS,aAAc,CAC3D,MAAMC,EAAO,IAAIC,EAAW,CACxBC,MAAOJ,EAAQK,OAAS,OACxBC,UAAW,OAGf,MAAMC,EAAO,IAAIC,EAAW,CACxBC,SAAU,KACVC,OAAQ,uBACRC,YAAa,EAAGC,WAAY,EAAGC,WAAY,EAAGC,WAAY,GAC1DC,gBAAiB,MACjBC,YAAa,EAAGC,WAAY,EAAGC,WAAY,EAAGC,WAAY,EAC1DC,UAAW,EAAGC,SAAU,EAAGC,SAAU,EACrCC,wBAAyB,QAG7B,GAAIvB,EAAQwB,UAAY5B,MAAMC,QAAQG,EAAQwB,UAAW,CACrDxB,EAAQwB,SAASzB,QAAQ0B,IACrBC,KAAKC,qBAAqBpB,EAAMkB,EAAcvC,EAAQC,EAAWC,IAEzE,CAEAc,EAAK0B,WAAWrB,GAChBjB,EAAOuC,QAAQ3B,EACnB,KAAO,CACHpB,EAAOgB,KAAK,+BAA+BE,EAAQC,6DAA8D,GAAI,eACzH,IAGJ,OAAOX,CACX,CAUQqC,qBAAqBpB,EAAkBP,EAAyBd,EAAiBC,EAAmBC,GACxG,GAAIY,EAAQC,OAAS,UAAW,CAC5B,IAAKD,EAAQ8B,QAAU9B,EAAQ8B,MAAMC,WAAW,iBAAkB,CAC9DjD,EAAOkD,MAAM,2BAA2BhC,EAAQ8B,8BAA+B,GAAI,gBACnF,MACJ,CAEA,MAAMG,KAAEA,EAAIC,YAAEA,EAAWC,QAAEA,GAAYvD,EAAiBwD,aAAalD,EAAQc,EAAQ8B,OAErF,IAAKG,EAAM,CACPnD,EAAOkD,MAAM,sBAAsBG,sCAA6C,GAAI,gBACpF,MACJ,CAEA,IACI,MAAME,EAAYrC,EAAQK,OAAS4B,EAAKK,IAAIjC,OAAS8B,EACrD,MAAM9B,EAAQ,IAAIkC,EAAM,CACpBC,KAAMH,EACNI,SAAUR,EAAKQ,WAGnB,MAAMC,EAAgB,IAAKT,GAC3B,GAAIjC,EAAQ2C,OAAQ,CAChBD,EAAcJ,GAAK,IAAKL,EAAKK,GAAIK,OAAQ3C,EAAQ2C,OACrD,CAEA,MAAMC,EAAUxD,EAAOyD,cAAcH,EAAe,IAAIR,IAAe/C,GAEvE,GAAIuD,EAAcJ,IAAIQ,UAAW,CAC7BC,IAAIT,GAAGU,QAAQ,CAAC,0BAA4BC,IACxCL,EAAQM,cAAc,IAAID,EAAS,CAAEE,KAAM,uBAEnD,CAEA5C,EAAKqB,WAAWvB,GAChBE,EAAKqB,WAAWgB,EACpB,CAAE,MAAOZ,GACLlD,EAAOkD,MAAM,0CAA0CG,IAAYH,EAAgBoB,QAAS,gBAC5F7C,EAAKqB,WAAW,IAAIW,EAAM,CAAEC,KAAML,IACtC,CACJ,KAAO,CACHrD,EAAOgB,KAAK,wFAAyF,GAAI,eAC7G,CACJ,EACH,IAAAuD,EAAA,CAAAC,WAAA,MAAAD,EAAArE,eAAA,OAAAqE,CAAA","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":32,"column":0},"map":{"version":3,"names":["Core","initLibrary","name","version","dependencies","controls","elements","interfaces","noLibraryCSS","__exports","window","nz","co","siliconst","ui5","metaui"],"sources":["library.ts"],"sourcesContent":["/**\n * @file library.ts\n * @description Standard SAP UI5 library registration file. Exposes the MetaUI namespace \n * and automatically bootstraps the internal PluginRegistry.\n */\n\nimport Core from \"sap/ui/core/Core\";\n\n// Explicitly import core plugins to bundle them into library-preload.js\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin\";\nimport \"nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator\";\nimport \"nz/co/siliconst/ui5/metaui/utils/ExpressionBuilder\";\n\n// Explicitly import core Layouts\nimport \"nz/co/siliconst/ui5/metaui/layouts/FormLayout\";\nimport \"nz/co/siliconst/ui5/metaui/layouts/TableLayout\";\nimport \"nz/co/siliconst/ui5/metaui/layouts/WizardLayout\";\nimport \"nz/co/siliconst/ui5/metaui/layouts/CompactLayout\";\n\n// AI Inference\nimport \"nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator\";\nimport \"nz/co/siliconst/ui5/metaui/ai/MockLLMProxy\";\nimport \"nz/co/siliconst/ui5/metaui/ai/RestLLMProxy\";\nimport \"nz/co/siliconst/ui5/metaui/ai/AIConfig\";\n\n// Delegate to standard library registration\nCore.initLibrary({\n name: \"nz.co.siliconst.ui5.metaui\",\n version: \"1.0.0\",\n dependencies: [\n \"sap.ui.core\",\n \"sap.m\",\n \"sap.ui.layout\",\n \"sap.ui.table\"\n ],\n controls: [\n \"nz.co.siliconst.ui5.metaui.controls.DynamicHost\",\n \"nz.co.siliconst.ui5.metaui.controls.host.GeneratorHost\",\n \"nz.co.siliconst.ui5.metaui.controls.BaseHardwareControl\",\n \"nz.co.siliconst.ui5.metaui.controls.CameraControl\",\n \"nz.co.siliconst.ui5.metaui.controls.BarcodeScannerControl\",\n \"nz.co.siliconst.ui5.metaui.controls.SignatureControl\",\n \"nz.co.siliconst.ui5.metaui.controls.VoiceInputControl\",\n \"nz.co.siliconst.ui5.metaui.controls.GeolocationControl\",\n \"nz.co.siliconst.ui5.metaui.controls.RichTextControl\"\n ],\n elements: [],\n interfaces: [],\n noLibraryCSS: true\n});\n\n// Exporting window object safely for UI5 compatibility if needed\ndeclare global {\n interface Window {\n nz: {\n co: {\n siliconst: {\n ui5: {\n metaui: Record<string, unknown>;\n };\n };\n };\n };\n }\n}\n\nexport default window.nz.co.siliconst.ui5.metaui;\n"],"mappings":"AAAA,4kCAiCAA,EAAKC,YAAY,CACbC,KAAM,6BACNC,QAAS,QACTC,aAAc,CACV,cACA,QACA,gBACA,gBAEJC,SAAU,CACN,kDACA,yDACA,0DACA,oDACA,4DACA,uDACA,wDACA,yDACA,uDAEJC,SAAU,GACVC,WAAY,GACZC,aAAc,OAGlB,IAAAC,EAeeC,OAAOC,GAAGC,GAAGC,UAAUC,IAAIC,OAAM,OAAAN,CAAA","ignoreList":[],"sourceRoot":""}},{"offset":{"line":33,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","OpenApiParserFactory","___OpenApiParserFactory","OpenApiHeuristicEngine","___heuristics_OpenApiHeuristicEngine","OpenApiBuilder","canHandle","rawSchema","schema","openapi","swagger","build","targetDefinition","fetchAndBuild","url","response","fetch","ok","Error","status","openApiRoot","json","this","error","msg","message","heuristicEngine","run","parser","getParser","parse","__exports","__esModule"],"sources":["OpenApiBuilder.ts"],"sourcesContent":["/**\n * @file OpenApiBuilder.ts\n * @description Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.\n * Strict Single Responsibility architecture delegates mapping logic to dedicated utilities and factories.\n */\n\nimport { ISchema } from \"../interfaces/ISchema\";\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { Logger } from \"../utils/Logger\";\nimport { OpenApiParserFactory } from \"./OpenApiParserFactory\";\nimport { OpenApiHeuristicEngine } from \"./heuristics/OpenApiHeuristicEngine\";\n\n/**\n * Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.\n * Strict Single Responsibility architecture delegates mapping logic to dedicated utilities and factories.\n * \n * @public\n */\nexport class OpenApiBuilder implements ISchemaBuilderPlugin {\n\n /**\n * Determines if the provided JSON payload is a Swagger or OpenAPI document.\n * \n * @param {unknown} rawSchema The raw JSON schema to test.\n * @returns {boolean} True if the document contains 'openapi' or 'swagger' root keys.\n */\n public canHandle(rawSchema: unknown): boolean {\n const schema = rawSchema as Record<string, unknown>;\n return !!(schema && (schema.openapi || schema.swagger));\n }\n\n /**\n * Builds a strict MetaUI ISchema from the provided OpenAPI payload.\n * \n * @param {unknown} rawSchema The OpenAPI root document.\n * @param {string} [targetDefinition] Optional target root definition.\n * @returns {ISchema} The translated MetaUI schema.\n */\n public build(rawSchema: unknown, targetDefinition?: string): ISchema {\n return OpenApiBuilder.build(rawSchema, targetDefinition);\n }\n\n /**\n * Asynchronously fetches a remote OpenAPI document and compiles it into a MetaUI ISchema.\n * \n * @param {string} url The URL to fetch the JSON payload from.\n * @param {string} [targetDefinition] Optional. The specific entity schema to extract.\n * @returns {Promise<ISchema>} A Promise resolving to the compiled ISchema.\n */\n public static async fetchAndBuild(url: string, targetDefinition?: string): Promise<ISchema> {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const openApiRoot = await response.json();\n return this.build(openApiRoot, targetDefinition);\n } catch (error) {\n const msg = \"Failed to fetch Swagger JSON from URL: \" + (error as Error).message;\n Logger.error(\"[MetaUI OpenApiBuilder]\", msg);\n throw new Error(msg);\n }\n }\n\n /**\n * Synchronously builds a MetaUI ISchema from a provided OpenAPI root document.\n * Delegates to HeuristicEngine and OpenApiParserFactory.\n * \n * @public\n * @param {unknown} openApiRoot The raw OpenAPI root JSON document.\n * @param {string} [targetDefinition] Optional target definition key to extract.\n * @returns {ISchema} The synthesized MetaUI schema.\n * @throws {Error} If the root object is invalid.\n */\n public static build(openApiRoot: unknown, targetDefinition?: string): ISchema {\n if (!openApiRoot || typeof openApiRoot !== \"object\") {\n throw new Error(\"[MetaUI OpenApiBuilder] Invalid Swagger root object provided.\");\n }\n\n // 1. Run Heuristics to mutate AST (e.g., simulating oneOf)\n const heuristicEngine = new OpenApiHeuristicEngine();\n heuristicEngine.run(openApiRoot);\n\n // 2. Delegate to correct parser version\n const parser = OpenApiParserFactory.getParser(openApiRoot);\n return parser.parse(openApiRoot, targetDefinition);\n }\n}\n"],"mappings":"AAAA,sLAAA,MAQSA,EAAMC,EAAA,gBACNC,EAAoBC,EAAA,8BACpBC,EAAsBC,EAAA,0BAQxB,MAAMC,EAQFC,UAAUC,GACb,MAAMC,EAASD,EACf,SAAUC,IAAWA,EAAOC,SAAWD,EAAOE,SAClD,CASOC,MAAMJ,EAAoBK,GAC7B,OAAOP,EAAeM,MAAMJ,EAAWK,EAC3C,CASA,0BAAoBC,CAAcC,EAAaF,GAC3C,IACI,MAAMG,QAAiBC,MAAMF,GAC7B,IAAKC,EAASE,GAAI,CACd,MAAM,IAAIC,MAAM,uBAAuBH,EAASI,SACpD,CACA,MAAMC,QAAoBL,EAASM,OACnC,OAAOC,KAAKX,MAAMS,EAAaR,EACnC,CAAE,MAAOW,GACL,MAAMC,EAAM,0CAA6CD,EAAgBE,QACzE1B,EAAOwB,MAAM,0BAA2BC,GACxC,MAAM,IAAIN,MAAMM,EACpB,CACJ,CAYA,YAAcb,CAAMS,EAAsBR,GACtC,IAAKQ,UAAsBA,IAAgB,SAAU,CACjD,MAAM,IAAIF,MAAM,gEACpB,CAGA,MAAMQ,EAAkB,IAAIvB,EAC5BuB,EAAgBC,IAAIP,GAGpB,MAAMQ,EAAS3B,EAAqB4B,UAAUT,GAC9C,OAAOQ,EAAOE,MAAMV,EAAaR,EACrC,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAA1B,iBAAA,OAAA0B,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":34,"column":0},"map":{"version":3,"names":["OpenApi2Parser","___parsers_OpenApi2Parser","OpenApi3Parser","___parsers_OpenApi3Parser","Logger","___utils_Logger","OpenApiParserFactory","getParser","rawSchema","error","swagger","openapi","startsWith","warn","__exports","__esModule"],"sources":["OpenApiParserFactory.ts"],"sourcesContent":["/**\n * @file OpenApiParserFactory.ts\n * @description Factory class to determine and instantiate the correct Swagger parser version.\n */\n\nimport { IOpenApiParserPlugin } from \"./interfaces/IOpenApiParserPlugin\";\nimport { OpenApi2Parser } from \"./parsers/OpenApi2Parser\";\nimport { OpenApi3Parser } from \"./parsers/OpenApi3Parser\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Factory class responsible for analyzing a raw OpenAPI document's metadata to dynamically \n * instantiate the correct, version-specific parser plugin. This isolates structural version \n * differences from the primary Engine orchestration layer.\n * \n * @public\n */\nexport class OpenApiParserFactory {\n /**\n * Inspects the root level structural signatures of an OpenAPI document (e.g., `swagger: \"2.0\"` \n * vs `openapi: \"3.x\"`) to instantiate the appropriate parsing engine.\n * \n * @param {any} rawSchema The raw, unparsed OpenAPI root JSON structure.\n * @returns {IOpenApiParserPlugin} An initialized instance of the correct concrete parser plugin.\n */\n public static getParser(rawSchema: unknown): IOpenApiParserPlugin {\n if (!rawSchema || typeof rawSchema !== \"object\") {\n Logger.error(\"[MetaUI OpenApiParserFactory] Invalid OpenAPI document provided.\");\n return new OpenApi3Parser(); // Fallback\n }\n\n if (rawSchema.swagger === \"2.0\") {\n return new OpenApi2Parser();\n }\n\n if (rawSchema.openapi && typeof rawSchema.openapi === \"string\" && rawSchema.openapi.startsWith(\"3\")) {\n return new OpenApi3Parser();\n }\n\n Logger.warn(\"[MetaUI OpenApiParserFactory] Unable to strictly determine OpenAPI version. Defaulting to OpenAPI 3.0 Parser.\");\n return new OpenApi3Parser();\n }\n}\n"],"mappings":"AAAA,mLAAA,MAMSA,EAAcC,EAAA,wBACdC,EAAcC,EAAA,wBACdC,EAAMC,EAAA,UASR,MAAMC,EAQT,gBAAcC,CAAUC,GACpB,IAAKA,UAAoBA,IAAc,SAAU,CAC7CJ,EAAOK,MAAM,oEACb,OAAO,IAAIP,CACf,CAEA,GAAIM,EAAUE,UAAY,MAAO,CAC7B,OAAO,IAAIV,CACf,CAEA,GAAIQ,EAAUG,gBAAkBH,EAAUG,UAAY,UAAYH,EAAUG,QAAQC,WAAW,KAAM,CACjG,OAAO,IAAIV,CACf,CAEAE,EAAOS,KAAK,iHACZ,OAAO,IAAIX,CACf,EACH,IAAAY,EAAA,CAAAC,WAAA,MAAAD,EAAAR,uBAAA,OAAAQ,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":35,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","OpenApiRefResolver","resolve","refUrl","openApiRoot","depth","startsWith","debug","error","pathSegments","substring","split","current","segment","$ref","this","__exports","__esModule"],"sources":["OpenApiRefResolver.ts"],"sourcesContent":["/**\n * @file OpenApiRefResolver.ts\n * @description Utility class for resolving local $ref pointers within an OpenAPI document.\n */\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Utility class for resolving local $ref pointers within an OpenAPI document.\n * \n * @public\n */\nexport class OpenApiRefResolver {\n /**\n * Recursively traverses a local JSON Pointer $ref path (e.g., '#/components/schemas/Pet')\n * and extracts the target object from the Swagger root document.\n * External URLs or invalid references are safely ignored.\n * \n * @param {string} refUrl The $ref string path.\n * @param {any} openApiRoot The root OpenAPI document to query against.\n * @param {number} depth The current recursive depth count, used to prevent infinite loops.\n * @returns {any} The resolved schema object, or null if unresolvable.\n */\n public static resolve(refUrl: string, openApiRoot: unknown, depth: number = 0): unknown {\n if (!refUrl || !refUrl.startsWith(\"#/\")) {\n Logger.debug(`[MetaUI OpenApiBuilder] Ignoring non-local or empty $ref: ${refUrl}`, \"OpenApiBuilder\");\n return null; // Ignore external URLs per architectural rules\n }\n\n // Circular Reference Limit:\n // A hard limit is enforced to prevent stack overflow exceptions caused by infinitely \n // recursive structures (e.g., a Tree node that references another Tree node).\n if (depth > 10) {\n Logger.error(`[MetaUI OpenApiBuilder] Circular or overly deep $ref detected: ${refUrl}`, null, \"OpenApiBuilder\");\n return null;\n }\n\n // Path Segment Parsing:\n // The '#/' prefix is stripped, and the remaining path is split by '/'.\n // We incrementally descend into the swagger root using these segments.\n const pathSegments = refUrl.substring(2).split(\"/\");\n let current = openApiRoot;\n\n for (const segment of pathSegments) {\n if (current && typeof current === \"object\" && segment in current) {\n current = current[segment];\n } else {\n Logger.error(`[MetaUI OpenApiBuilder] Failed to resolve local $ref: ${refUrl}`, null, \"OpenApiBuilder\");\n return null;\n }\n }\n\n // Deep Resolution Recursion:\n // If the resolved target is itself a reference pointer, recursively resolve again\n // until we reach a terminal structure or hit the recursion depth limit.\n if (current && typeof current === \"object\" && current.$ref) {\n return this.resolve(current.$ref, openApiRoot, depth + 1);\n }\n\n return current;\n }\n}\n"],"mappings":"AAAA,uHAAA,MAISA,EAAMC,EAAA,UAOR,MAAMC,EAWT,cAAcC,CAAQC,EAAgBC,EAAsBC,EAAgB,GACxE,IAAKF,IAAWA,EAAOG,WAAW,MAAO,CACrCP,EAAOQ,MAAM,6DAA6DJ,IAAU,kBACpF,OAAO,IACX,CAKA,GAAIE,EAAQ,GAAI,CACZN,EAAOS,MAAM,kEAAkEL,IAAU,KAAM,kBAC/F,OAAO,IACX,CAKA,MAAMM,EAAeN,EAAOO,UAAU,GAAGC,MAAM,KAC/C,IAAIC,EAAUR,EAEd,IAAK,MAAMS,KAAWJ,EAAc,CAChC,GAAIG,UAAkBA,IAAY,UAAYC,KAAWD,EAAS,CAC9DA,EAAUA,EAAQC,EACtB,KAAO,CACHd,EAAOS,MAAM,yDAAyDL,IAAU,KAAM,kBACtF,OAAO,IACX,CACJ,CAKA,GAAIS,UAAkBA,IAAY,UAAYA,EAAQE,KAAM,CACxD,OAAOC,KAAKb,QAAQU,EAAQE,KAAMV,EAAaC,EAAQ,EAC3D,CAEA,OAAOO,CACX,EACH,IAAAI,EAAA,CAAAC,WAAA,MAAAD,EAAAf,qBAAA,OAAAe,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":36,"column":0},"map":{"version":3,"names":["OpenApiTypeMapper","mapType","openApiType","typeMap","string","number","integer","boolean","array","object","date","__exports","__esModule"],"sources":["OpenApiTypeMapper.ts"],"sourcesContent":["/**\n * @file OpenApiTypeMapper.ts\n * @description Utility class for mapping OpenAPI primitive types to MetaUI FieldTypes.\n */\nimport { FieldType } from \"../interfaces/ISchema\";\n\n/**\n * Acts as the translation boundary between raw OpenAPI types and the internal MetaUI FieldType enumerations.\n * This ensures that the core layout engine never has to parse or understand Swagger-specific semantics.\n * \n * @public\n */\nexport class OpenApiTypeMapper {\n /**\n * Maps an OpenAPI primitive type string to the closest MetaUI FieldType.\n * If the type is omitted (common for objects) or unknown, it defaults to \"object\"\n * to trigger a safe nested-form fallback behavior.\n * \n * @param {string} openApiType The raw OpenAPI type (e.g., 'string', 'integer').\n * @returns {FieldType} The mapped MetaUI FieldType strictly understood by the core engine.\n */\n public static mapType(openApiType: string): FieldType {\n const typeMap: Record<string, FieldType> = {\n \"string\": \"string\",\n \"number\": \"number\",\n \"integer\": \"integer\",\n \"boolean\": \"boolean\",\n \"array\": \"array\",\n \"object\": \"object\",\n \"date\": \"date\"\n };\n \n // Default to \"object\" if the type is unknown or omitted by the API specification.\n return typeMap[openApiType] || \"object\";\n }\n}\n"],"mappings":"AAAA,oGAYO,MAAMA,EAST,cAAcC,CAAQC,GAClB,MAAMC,EAAqC,CACvCC,OAAU,SACVC,OAAU,SACVC,QAAW,UACXC,QAAW,UACXC,MAAS,QACTC,OAAU,SACVC,KAAQ,QAIZ,OAAOP,EAAQD,IAAgB,QACnC,EACH,IAAAS,EAAA,CAAAC,WAAA,MAAAD,EAAAX,oBAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":37,"column":0},"map":{"version":3,"names":["OpenApiUIMapper","build","swaggerProp","keyName","ui","title","label","this","generateLabel","readOnly","format","widget","validators","push","name","spaced","replace","split","filter","w","length","map","word","charAt","toUpperCase","slice","toLowerCase","join","trim","__exports","__esModule"],"sources":["OpenApiUIMapper.ts"],"sourcesContent":["/**\n * @file OpenApiUIMapper.ts\n * @description Utility class for mapping OpenAPI properties and formats into MetaUI IUIDirectives.\n */\nimport { IUIDirective } from \"../interfaces/ISchema\";\n\n/**\n * Utility class responsible for evaluating OpenAPI metadata and generating the corresponding \n * MetaUI UI rendering directives. This isolates all visual layout assumptions from the parsing engine.\n * \n * @public\n */\nexport class OpenApiUIMapper {\n /**\n * Evaluates an OpenAPI property definition and constructs a MetaUI IUIDirective block.\n * Extracts labels from title/description, maps readOnly state, and assigns \n * specific UI5 Fiori widgets based on the OpenAPI 'format' property.\n * \n * @param {any} swaggerProp The raw OpenAPI property schema chunk.\n * @param {string} keyName The technical JSON key of the property.\n * @returns {IUIDirective} The constructed MetaUI UI orchestration directive.\n */\n public static build(swaggerProp: unknown, keyName: string): IUIDirective {\n const ui: IUIDirective = {};\n\n // Label Synthesis\n if (swaggerProp.title) {\n ui.label = swaggerProp.title;\n } else {\n ui.label = this.generateLabel(keyName);\n }\n\n // State Mapping\n if (swaggerProp.readOnly === true) {\n ui.readOnly = true;\n }\n\n // Format to Widget Translation\n if (swaggerProp.format) {\n switch (swaggerProp.format) {\n case \"date-time\":\n ui.widget = \"datetime\";\n break;\n case \"date\":\n ui.widget = \"date\";\n break;\n case \"password\":\n ui.widget = \"password\";\n ui.format = \"password\"; // Kept for schema validation\n break;\n case \"email\":\n ui.widget = \"email\";\n ui.format = \"email\"; // Kept for schema validation\n break;\n case \"uri\":\n ui.widget = \"link\";\n ui.format = \"url\"; // Kept for schema validation\n break;\n case \"binary\":\n case \"byte\":\n ui.widget = \"fileUploader\";\n break;\n case \"uuid\":\n case \"ipv4\":\n case \"ipv6\":\n case \"hostname\":\n if (!ui.validators) ui.validators = [];\n ui.validators.push(swaggerProp.format);\n break;\n }\n }\n\n return ui;\n }\n\n /**\n * Synthesizes a human-readable Title Case label from camelCase or snake_case technical keys.\n * \n * @param {string} name The raw technical property key (e.g., 'creationTimestamp').\n * @returns {string} The formatted human-readable label (e.g., 'Creation Timestamp').\n * @private\n */\n private static generateLabel(name: string): string {\n if (!name) return \"\";\n let spaced = name.replace(/([A-Z])/g, \" $1\").replace(/_/g, \" \");\n return spaced.split(' ')\n .filter(w => w.length > 0)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n .trim();\n }\n}\n"],"mappings":"AAAA,kGAYO,MAAMA,EAUT,YAAcC,CAAMC,EAAsBC,GACtC,MAAMC,EAAmB,CAAC,EAG1B,GAAIF,EAAYG,MAAO,CACnBD,EAAGE,MAAQJ,EAAYG,KAC3B,KAAO,CACHD,EAAGE,MAAQC,KAAKC,cAAcL,EAClC,CAGA,GAAID,EAAYO,WAAa,KAAM,CAC/BL,EAAGK,SAAW,IAClB,CAGA,GAAIP,EAAYQ,OAAQ,CACpB,OAAQR,EAAYQ,QAChB,IAAK,YACDN,EAAGO,OAAS,WACZ,MACJ,IAAK,OACDP,EAAGO,OAAS,OACZ,MACJ,IAAK,WACDP,EAAGO,OAAS,WACZP,EAAGM,OAAS,WACZ,MACJ,IAAK,QACDN,EAAGO,OAAS,QACZP,EAAGM,OAAS,QACZ,MACJ,IAAK,MACDN,EAAGO,OAAS,OACZP,EAAGM,OAAS,MACZ,MACJ,IAAK,SACL,IAAK,OACDN,EAAGO,OAAS,eACZ,MACJ,IAAK,OACL,IAAK,OACL,IAAK,OACL,IAAK,WACD,IAAKP,EAAGQ,WAAYR,EAAGQ,WAAa,GACpCR,EAAGQ,WAAWC,KAAKX,EAAYQ,QAC/B,MAEZ,CAEA,OAAON,CACX,CASA,oBAAeI,CAAcM,GACzB,IAAKA,EAAM,MAAO,GAClB,IAAIC,EAASD,EAAKE,QAAQ,WAAY,OAAOA,QAAQ,KAAM,KAC3D,OAAOD,EAAOE,MAAM,KACfC,OAAOC,GAAKA,EAAEC,OAAS,GACvBC,IAAIC,GAAQA,EAAKC,OAAO,GAAGC,cAAgBF,EAAKG,MAAM,GAAGC,eACzDC,KAAK,KACLC,MACT,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA7B,kBAAA,OAAA6B,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":38,"column":0},"map":{"version":3,"names":["ProtobufVariantHeuristic","___plugins_ProtobufVariantHeuristic","OpenApiHeuristicEngine","plugins","constructor","this","push","run","openApiRoot","plugin","apply","error","Error","message","__exports","__esModule"],"sources":["OpenApiHeuristicEngine.ts"],"sourcesContent":["/**\n * @file OpenApiHeuristicEngine.ts\n * @description Orchestrator that registers and executes all IHeuristicPlugin implementations against the raw schema.\n */\n\nimport { IHeuristicPlugin } from \"./interfaces/IHeuristicPlugin\";\nimport { ProtobufVariantHeuristic } from \"./plugins/ProtobufVariantHeuristic\";\n\n/**\n * Orchestration engine that initializes and executes heuristic plugins sequentially.\n * This pipeline mutates the raw OpenAPI document in-place to normalize non-standard constructs\n * (like Protobuf unions) before the primary parsing phase occurs.\n * \n * @public\n */\nexport class OpenApiHeuristicEngine {\n private plugins: IHeuristicPlugin[] = [];\n\n /**\n * Initializes a new instance of the HeuristicEngine and registers default heuristics.\n */\n constructor() {\n // Register default heuristics\n this.plugins.push(new ProtobufVariantHeuristic());\n }\n\n /**\n * Runs all registered heuristic plugins sequentially against the raw OpenAPI document.\n * Captures and bubbles plugin-specific execution failures to prevent silent pipeline corruption.\n * \n * @param {any} openApiRoot The entire OpenAPI root document, to be mutated in-place.\n * @throws {Error} If any heuristic plugin crashes during execution.\n */\n public run(openApiRoot: unknown): void {\n for (const plugin of this.plugins) {\n try {\n plugin.apply(openApiRoot);\n } catch (error: Error) {\n throw new Error(`[MetaUI HeuristicEngine] Plugin execution failed: ${error.message}`);\n }\n }\n }\n}\n"],"mappings":"AAAA,yJAAA,MAMSA,EAAwBC,EAAA,4BAS1B,MAAMC,EACDC,QAA8B,GAKtCC,cAEIC,KAAKF,QAAQG,KAAK,IAAIN,EAC1B,CASOO,IAAIC,GACP,IAAK,MAAMC,KAAUJ,KAAKF,QAAS,CAC/B,IACIM,EAAOC,MAAMF,EACjB,CAAE,MAAOG,GACL,MAAM,IAAIC,MAAM,qDAAqDD,EAAME,UAC/E,CACJ,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAZ,yBAAA,OAAAY,CAAA","ignoreList":[],"sourceRoot":"openapi/heuristics"}},{"offset":{"line":39,"column":0},"map":{"version":3,"names":["ProtobufVariantHeuristic","apply","openApiRoot","swagger","definitions","this","_scanDefinitions","key","definition","Object","entries","_isProtobufVariant","_mutateToOneOf","type","properties","required","length","propKeys","keys","allEndWithValue","every","k","endsWith","oneOfArray","propKey","variantSchema","syntheticVariant","title","description","push","oneOf","__exports","__esModule"],"sources":["ProtobufVariantHeuristic.ts"],"sourcesContent":["/**\n * @file ProtobufVariantHeuristic.ts\n * @description Scans OpenAPI 2.0 schemas for implicitly polymorphic structures (e.g., objects containing purely optional, mutually exclusive fields) and explicitly mutates them into `oneOf` structures.\n */\n\nimport { IHeuristicPlugin } from \"../interfaces/IHeuristicPlugin\";\n\n/**\n * Heuristic plugin that detects Protobuf-style Variant representations (objects with exclusively optional *_value fields)\n * and mutates the AST to a proper oneOf polymorphic array before it reaches the parsers.\n * \n * @public\n */\nexport class ProtobufVariantHeuristic implements IHeuristicPlugin {\n /**\n * Executes the heuristic logic against the OpenAPI AST.\n * Initiates a scan of the global definitions block if the document matches the OpenAPI 2.0 specification.\n * \n * @param {any} openApiRoot The entire OpenAPI root document.\n */\n public apply(openApiRoot: unknown): void {\n if (!openApiRoot) return;\n\n // In OpenAPI 2.0, scan definitions\n if (openApiRoot.swagger === \"2.0\" && openApiRoot.definitions) {\n this._scanDefinitions(openApiRoot.definitions);\n }\n }\n\n /**\n * Iterates over all root-level definitions to detect and mutate variant structures.\n * \n * @param {Record<string, any>} definitions The raw OpenAPI 2.0 definitions dictionary.\n * @private\n */\n private _scanDefinitions(definitions: Record<string, any>): void {\n for (const [key, definition] of Object.entries(definitions)) {\n // Heuristic 1: If the object name ends with \"Value\" and has multiple optional properties \n // that end with \"_value\" (common Protobuf JSON representation for variants)\n if (this._isProtobufVariant(key, definition)) {\n this._mutateToOneOf(definition);\n }\n }\n }\n\n /**\n * Evaluates a schema block against the heuristic signature of a Protobuf Variant.\n * \n * @param {string} key The schema definition name.\n * @param {any} definition The structural definition block.\n * @returns {boolean} True if the structure matches a Protobuf variant pattern.\n * @private\n */\n private _isProtobufVariant(key: string, definition: unknown): boolean {\n if (definition.type !== \"object\" || !definition.properties) {\n return false;\n }\n\n // Must not have required fields if it's a pure union\n if (definition.required && definition.required.length > 0) {\n return false;\n }\n\n const propKeys = Object.keys(definition.properties);\n if (propKeys.length < 2) {\n return false;\n }\n\n // Check if all properties end with \"_value\" (e.g. bool_value, list_value)\n const allEndWithValue = propKeys.every(k => k.endsWith(\"_value\"));\n if (allEndWithValue && (key.endsWith(\"Value\") || key.endsWith(\"Variant\"))) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Mutates the AST in-place by synthesizing a `oneOf` array from the optional properties\n * and strictly purging the original object layout to force polymorphic evaluation.\n * \n * @param {any} definition The target variant object schema.\n * @private\n */\n private _mutateToOneOf(definition: unknown): void {\n const propKeys = Object.keys(definition.properties);\n const oneOfArray: unknown[] = [];\n\n for (const propKey of propKeys) {\n const variantSchema = definition.properties[propKey];\n \n // Reconstruct a sub-object for each variant, enforcing strict requirement of the single variant property\n const syntheticVariant = {\n type: \"object\",\n properties: {\n [propKey]: variantSchema\n },\n required: [propKey],\n title: variantSchema.description || propKey\n };\n \n oneOfArray.push(syntheticVariant);\n }\n\n // Mutate the original definition to become a oneOf root\n definition.oneOf = oneOfArray;\n \n // CRITICAL DESTRUCTIVE MUTATION:\n // We delete the original properties block. If this is not done, the core engine's layout\n // orchestrator will attempt to render both a standard static form AND the polymorphic switcher simultaneously.\n delete definition.properties;\n }\n}\n"],"mappings":"AAAA,8HAaO,MAAMA,EAOFC,MAAMC,GACT,IAAKA,EAAa,OAGlB,GAAIA,EAAYC,UAAY,OAASD,EAAYE,YAAa,CAC1DC,KAAKC,iBAAiBJ,EAAYE,YACtC,CACJ,CAQQE,iBAAiBF,GACrB,IAAK,MAAOG,EAAKC,KAAeC,OAAOC,QAAQN,GAAc,CAGzD,GAAIC,KAAKM,mBAAmBJ,EAAKC,GAAa,CAC1CH,KAAKO,eAAeJ,EACxB,CACJ,CACJ,CAUQG,mBAAmBJ,EAAaC,GACpC,GAAIA,EAAWK,OAAS,WAAaL,EAAWM,WAAY,CACxD,OAAO,KACX,CAGA,GAAIN,EAAWO,UAAYP,EAAWO,SAASC,OAAS,EAAG,CACvD,OAAO,KACX,CAEA,MAAMC,EAAWR,OAAOS,KAAKV,EAAWM,YACxC,GAAIG,EAASD,OAAS,EAAG,CACrB,OAAO,KACX,CAGA,MAAMG,EAAkBF,EAASG,MAAMC,GAAKA,EAAEC,SAAS,WACvD,GAAIH,IAAoBZ,EAAIe,SAAS,UAAYf,EAAIe,SAAS,YAAa,CACvE,OAAO,IACX,CAEA,OAAO,KACX,CASQV,eAAeJ,GACnB,MAAMS,EAAWR,OAAOS,KAAKV,EAAWM,YACxC,MAAMS,EAAwB,GAE9B,IAAK,MAAMC,KAAWP,EAAU,CAC5B,MAAMQ,EAAgBjB,EAAWM,WAAWU,GAG5C,MAAME,EAAmB,CACrBb,KAAM,SACNC,WAAY,CACRU,CAACA,GAAUC,GAEfV,SAAU,CAACS,GACXG,MAAOF,EAAcG,aAAeJ,GAGxCD,EAAWM,KAAKH,EACpB,CAGAlB,EAAWsB,MAAQP,SAKZf,EAAWM,UACtB,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAA/B,2BAAA,OAAA+B,CAAA","ignoreList":[],"sourceRoot":"openapi/heuristics/plugins"}},{"offset":{"line":40,"column":0},"map":{"version":3,"names":["OpenApiPropertyMapper","___OpenApiPropertyMapper","OpenApiRefResolver","___OpenApiRefResolver","OpenApi2Parser","parse","openApiRoot","targetDefinition","targetObject","definitions","keys","Object","length","replace","Error","$ref","resolved","resolve","Array","isArray","allOf","merged","subSchema","resolvedSub","deepMergeSchemas","schema","title","info","type","layoutStrategy","additionalProperties","mapPropertyMetadata","properties","requiredFields","required","mapProperties","items","key","mappedProp","ui","__exports","__esModule"],"sources":["OpenApi2Parser.ts"],"sourcesContent":["/**\n * @file OpenApi2Parser.ts\n * @description Native parser for OpenAPI 2.0 (Swagger) specifications.\n */\n\nimport { IOpenApiParserPlugin } from \"../interfaces/IOpenApiParserPlugin\";\nimport { ISchema } from \"../../interfaces/ISchema\";\nimport { OpenApiPropertyMapper } from \"./OpenApiPropertyMapper\";\nimport { OpenApiRefResolver } from \"../OpenApiRefResolver\";\n\n/**\n * Parser plugin specifically designed for parsing OpenAPI 2.0 (Swagger) schemas.\n * Responsible for translating OpenAPI 2.0 specific constructs into the MetaUI normalized schema.\n * \n * @public\n */\nexport class OpenApi2Parser implements IOpenApiParserPlugin {\n /**\n * Parses a raw OpenAPI 2.0 document into a normalized MetaUI ISchema tree.\n * Extracts definitions, normalizes properties, and recursively resolves composition (allOf).\n * \n * @param {any} openApiRoot The root JSON document.\n * @param {string} [targetDefinition] Optional specific definition to extract. If omitted, uses the first definition available.\n * @returns {ISchema} The synthesized MetaUI schema structure.\n * @throws {Error} If the target definition cannot be found in the provided Swagger document.\n */\n public parse(openApiRoot: unknown, targetDefinition?: string): ISchema {\n let targetObject = openApiRoot;\n\n if (!targetDefinition) {\n if (openApiRoot.definitions) {\n const keys = Object.keys(openApiRoot.definitions);\n if (keys.length > 0) targetDefinition = keys[0];\n }\n }\n\n if (targetDefinition) {\n targetDefinition = targetDefinition.replace(\"#/components/schemas/\", \"\").replace(\"#/definitions/\", \"\");\n if (openApiRoot.definitions && openApiRoot.definitions[targetDefinition]) {\n targetObject = openApiRoot.definitions[targetDefinition];\n } else {\n throw new Error(`[MetaUI OpenApi2Parser] Could not find target definition '${targetDefinition}' in definitions.`);\n }\n }\n\n if (targetObject.$ref) {\n const resolved = OpenApiRefResolver.resolve(targetObject.$ref, openApiRoot);\n if (resolved) {\n targetObject = { ...resolved, ...targetObject };\n }\n }\n\n if (Array.isArray(targetObject.allOf)) {\n let merged = { ...targetObject };\n delete merged.allOf;\n for (const subSchema of targetObject.allOf) {\n let resolvedSub = subSchema;\n if (subSchema.$ref) {\n resolvedSub = OpenApiRefResolver.resolve(subSchema.$ref, openApiRoot) || {};\n }\n merged = OpenApiPropertyMapper.deepMergeSchemas(merged, resolvedSub);\n }\n targetObject = merged;\n }\n\n const schema: ISchema = {\n title: targetObject.title || openApiRoot.info?.title || targetDefinition,\n type: targetObject.type === \"array\" ? \"array\" : \"object\",\n layoutStrategy: targetObject.type === \"array\" ? \"table\" : \"form\"\n };\n\n if (targetObject.additionalProperties) {\n if (targetObject.additionalProperties === true) {\n schema.additionalProperties = true;\n } else if (typeof targetObject.additionalProperties === \"object\") {\n schema.additionalProperties = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.additionalProperties, \"value\", false, openApiRoot, \"2.0\");\n }\n }\n\n if (targetObject.properties) {\n const requiredFields = Array.isArray(targetObject.required) ? targetObject.required : [];\n schema.properties = OpenApiPropertyMapper.mapProperties(targetObject.properties, requiredFields, openApiRoot, \"2.0\");\n } else if (schema.type === \"array\" && targetObject.items) {\n schema.items = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.items, \"items\", false, openApiRoot, \"2.0\");\n }\n\n if (openApiRoot.definitions) {\n schema.definitions = {};\n for (const key of Object.keys(openApiRoot.definitions)) {\n const mappedProp = OpenApiPropertyMapper.mapPropertyMetadata(openApiRoot.definitions[key], key, false, openApiRoot, \"2.0\");\n schema.definitions[key] = {\n title: key,\n type: mappedProp.type === \"array\" ? \"array\" : \"object\",\n properties: mappedProp.properties,\n items: mappedProp.items,\n ui: mappedProp.ui,\n layoutStrategy: mappedProp.type === \"array\" ? \"table\" : \"form\"\n };\n }\n }\n\n return schema;\n }\n}\n"],"mappings":"AAAA,6JAAA,MAOSA,EAAqBC,EAAA,+BACrBC,EAAkBC,EAAA,sBAQpB,MAAMC,EAUFC,MAAMC,EAAsBC,GAC/B,IAAIC,EAAeF,EAEnB,IAAKC,EAAkB,CACnB,GAAID,EAAYG,YAAa,CACzB,MAAMC,EAAOC,OAAOD,KAAKJ,EAAYG,aACrC,GAAIC,EAAKE,OAAS,EAAGL,EAAmBG,EAAK,EACjD,CACJ,CAEA,GAAIH,EAAkB,CAClBA,EAAmBA,EAAiBM,QAAQ,wBAAyB,IAAIA,QAAQ,iBAAkB,IACnG,GAAIP,EAAYG,aAAeH,EAAYG,YAAYF,GAAmB,CACtEC,EAAeF,EAAYG,YAAYF,EAC3C,KAAO,CACH,MAAM,IAAIO,MAAM,6DAA6DP,qBACjF,CACJ,CAEA,GAAIC,EAAaO,KAAM,CACnB,MAAMC,EAAWd,EAAmBe,QAAQT,EAAaO,KAAMT,GAC/D,GAAIU,EAAU,CACVR,EAAe,IAAKQ,KAAaR,EACrC,CACJ,CAEA,GAAIU,MAAMC,QAAQX,EAAaY,OAAQ,CACnC,IAAIC,EAAS,IAAKb,UACXa,EAAOD,MACd,IAAK,MAAME,KAAad,EAAaY,MAAO,CACxC,IAAIG,EAAcD,EAClB,GAAIA,EAAUP,KAAM,CAChBQ,EAAcrB,EAAmBe,QAAQK,EAAUP,KAAMT,IAAgB,CAAC,CAC9E,CACAe,EAASrB,EAAsBwB,iBAAiBH,EAAQE,EAC5D,CACAf,EAAea,CACnB,CAEA,MAAMI,EAAkB,CACpBC,MAAOlB,EAAakB,OAASpB,EAAYqB,MAAMD,OAASnB,EACxDqB,KAAMpB,EAAaoB,OAAS,QAAU,QAAU,SAChDC,eAAgBrB,EAAaoB,OAAS,QAAU,QAAU,QAG9D,GAAIpB,EAAasB,qBAAsB,CACnC,GAAItB,EAAasB,uBAAyB,KAAM,CAC5CL,EAAOK,qBAAuB,IAClC,MAAO,UAAWtB,EAAasB,uBAAyB,SAAU,CAC9DL,EAAOK,qBAAuB9B,EAAsB+B,oBAAoBvB,EAAasB,qBAAsB,QAAS,MAAOxB,EAAa,MAC5I,CACJ,CAEA,GAAIE,EAAawB,WAAY,CACzB,MAAMC,EAAiBf,MAAMC,QAAQX,EAAa0B,UAAY1B,EAAa0B,SAAW,GACtFT,EAAOO,WAAahC,EAAsBmC,cAAc3B,EAAawB,WAAYC,EAAgB3B,EAAa,MAClH,MAAO,GAAImB,EAAOG,OAAS,SAAWpB,EAAa4B,MAAO,CACtDX,EAAOW,MAAQpC,EAAsB+B,oBAAoBvB,EAAa4B,MAAO,QAAS,MAAO9B,EAAa,MAC9G,CAEA,GAAIA,EAAYG,YAAa,CACzBgB,EAAOhB,YAAc,CAAC,EACtB,IAAK,MAAM4B,KAAO1B,OAAOD,KAAKJ,EAAYG,aAAc,CACpD,MAAM6B,EAAatC,EAAsB+B,oBAAoBzB,EAAYG,YAAY4B,GAAMA,EAAK,MAAO/B,EAAa,OACpHmB,EAAOhB,YAAY4B,GAAO,CACtBX,MAAOW,EACPT,KAAMU,EAAWV,OAAS,QAAU,QAAU,SAC9CI,WAAYM,EAAWN,WACvBI,MAAOE,EAAWF,MAClBG,GAAID,EAAWC,GACfV,eAAgBS,EAAWV,OAAS,QAAU,QAAU,OAEhE,CACJ,CAEA,OAAOH,CACX,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAApC,iBAAA,OAAAoC,CAAA","ignoreList":[],"sourceRoot":"openapi/parsers"}},{"offset":{"line":41,"column":0},"map":{"version":3,"names":["OpenApiPropertyMapper","___OpenApiPropertyMapper","OpenApiRefResolver","___OpenApiRefResolver","OpenApi3Parser","parse","openApiRoot","targetDefinition","targetObject","components","schemas","keys","Object","length","replace","Error","$ref","resolved","resolve","Array","isArray","allOf","merged","subSchema","resolvedSub","deepMergeSchemas","schema","title","info","type","layoutStrategy","additionalProperties","mapPropertyMetadata","properties","requiredFields","required","mapProperties","items","definitions","key","mappedProp","ui","__exports","__esModule"],"sources":["OpenApi3Parser.ts"],"sourcesContent":["/**\n * @file OpenApi3Parser.ts\n * @description Native parser for OpenAPI 3.0.x specifications.\n */\n\nimport { IOpenApiParserPlugin } from \"../interfaces/IOpenApiParserPlugin\";\nimport { ISchema } from \"../../interfaces/ISchema\";\nimport { OpenApiPropertyMapper } from \"./OpenApiPropertyMapper\";\nimport { OpenApiRefResolver } from \"../OpenApiRefResolver\";\n\n/**\n * Parser plugin specifically designed for parsing OpenAPI 3.0.x schemas.\n * Responsible for translating OpenAPI 3.0 specific constructs into the MetaUI normalized schema.\n * \n * @public\n */\nexport class OpenApi3Parser implements IOpenApiParserPlugin {\n /**\n * Parses a raw OpenAPI 3.0 document into a normalized MetaUI ISchema tree.\n * Extracts definitions from components.schemas, normalizes properties, and recursively resolves composition (allOf).\n * \n * @param {any} openApiRoot The root JSON document.\n * @param {string} [targetDefinition] Optional specific schema to extract from components.schemas. If omitted, uses the first schema available.\n * @returns {ISchema} The synthesized MetaUI schema structure.\n * @throws {Error} If the target definition cannot be found in the provided Swagger document.\n */\n public parse(openApiRoot: unknown, targetDefinition?: string): ISchema {\n let targetObject = openApiRoot;\n\n if (!targetDefinition) {\n if (openApiRoot.components && openApiRoot.components.schemas) {\n const keys = Object.keys(openApiRoot.components.schemas);\n if (keys.length > 0) targetDefinition = keys[0];\n }\n }\n\n if (targetDefinition) {\n targetDefinition = targetDefinition.replace(\"#/components/schemas/\", \"\").replace(\"#/definitions/\", \"\");\n if (openApiRoot.components && openApiRoot.components.schemas && openApiRoot.components.schemas[targetDefinition]) {\n targetObject = openApiRoot.components.schemas[targetDefinition];\n } else {\n throw new Error(`[MetaUI OpenApi3Parser] Could not find target definition '${targetDefinition}' in components.schemas.`);\n }\n }\n\n if (targetObject.$ref) {\n const resolved = OpenApiRefResolver.resolve(targetObject.$ref, openApiRoot);\n if (resolved) {\n targetObject = { ...resolved, ...targetObject };\n }\n }\n\n if (Array.isArray(targetObject.allOf)) {\n let merged = { ...targetObject };\n delete merged.allOf;\n for (const subSchema of targetObject.allOf) {\n let resolvedSub = subSchema;\n if (subSchema.$ref) {\n resolvedSub = OpenApiRefResolver.resolve(subSchema.$ref, openApiRoot) || {};\n }\n merged = OpenApiPropertyMapper.deepMergeSchemas(merged, resolvedSub);\n }\n targetObject = merged;\n }\n\n const schema: ISchema = {\n title: targetObject.title || openApiRoot.info?.title || targetDefinition,\n type: targetObject.type === \"array\" ? \"array\" : \"object\",\n layoutStrategy: targetObject.type === \"array\" ? \"table\" : \"form\"\n };\n\n if (targetObject.additionalProperties) {\n if (targetObject.additionalProperties === true) {\n schema.additionalProperties = true;\n } else if (typeof targetObject.additionalProperties === \"object\") {\n schema.additionalProperties = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.additionalProperties, \"value\", false, openApiRoot, \"3.0\");\n }\n }\n\n if (targetObject.properties) {\n const requiredFields = Array.isArray(targetObject.required) ? targetObject.required : [];\n schema.properties = OpenApiPropertyMapper.mapProperties(targetObject.properties, requiredFields, openApiRoot, \"3.0\");\n } else if (schema.type === \"array\" && targetObject.items) {\n schema.items = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.items, \"items\", false, openApiRoot, \"3.0\");\n }\n\n if (openApiRoot.components && openApiRoot.components.schemas) {\n schema.definitions = {};\n const schemas = openApiRoot.components.schemas;\n for (const key of Object.keys(schemas)) {\n const mappedProp = OpenApiPropertyMapper.mapPropertyMetadata(schemas[key], key, false, openApiRoot, \"3.0\");\n schema.definitions[key] = {\n title: key,\n type: mappedProp.type === \"array\" ? \"array\" : \"object\",\n properties: mappedProp.properties,\n items: mappedProp.items,\n ui: mappedProp.ui,\n layoutStrategy: mappedProp.type === \"array\" ? \"table\" : \"form\"\n };\n }\n }\n\n return schema;\n }\n}\n"],"mappings":"AAAA,6JAAA,MAOSA,EAAqBC,EAAA,+BACrBC,EAAkBC,EAAA,sBAQpB,MAAMC,EAUFC,MAAMC,EAAsBC,GAC/B,IAAIC,EAAeF,EAEnB,IAAKC,EAAkB,CACnB,GAAID,EAAYG,YAAcH,EAAYG,WAAWC,QAAS,CAC1D,MAAMC,EAAOC,OAAOD,KAAKL,EAAYG,WAAWC,SAChD,GAAIC,EAAKE,OAAS,EAAGN,EAAmBI,EAAK,EACjD,CACJ,CAEA,GAAIJ,EAAkB,CAClBA,EAAmBA,EAAiBO,QAAQ,wBAAyB,IAAIA,QAAQ,iBAAkB,IACnG,GAAIR,EAAYG,YAAcH,EAAYG,WAAWC,SAAWJ,EAAYG,WAAWC,QAAQH,GAAmB,CAC9GC,EAAeF,EAAYG,WAAWC,QAAQH,EAClD,KAAO,CACH,MAAM,IAAIQ,MAAM,6DAA6DR,4BACjF,CACJ,CAEA,GAAIC,EAAaQ,KAAM,CACnB,MAAMC,EAAWf,EAAmBgB,QAAQV,EAAaQ,KAAMV,GAC/D,GAAIW,EAAU,CACVT,EAAe,IAAKS,KAAaT,EACrC,CACJ,CAEA,GAAIW,MAAMC,QAAQZ,EAAaa,OAAQ,CACnC,IAAIC,EAAS,IAAKd,UACXc,EAAOD,MACd,IAAK,MAAME,KAAaf,EAAaa,MAAO,CACxC,IAAIG,EAAcD,EAClB,GAAIA,EAAUP,KAAM,CAChBQ,EAActB,EAAmBgB,QAAQK,EAAUP,KAAMV,IAAgB,CAAC,CAC9E,CACAgB,EAAStB,EAAsByB,iBAAiBH,EAAQE,EAC5D,CACAhB,EAAec,CACnB,CAEA,MAAMI,EAAkB,CACpBC,MAAOnB,EAAamB,OAASrB,EAAYsB,MAAMD,OAASpB,EACxDsB,KAAMrB,EAAaqB,OAAS,QAAU,QAAU,SAChDC,eAAgBtB,EAAaqB,OAAS,QAAU,QAAU,QAG9D,GAAIrB,EAAauB,qBAAsB,CACnC,GAAIvB,EAAauB,uBAAyB,KAAM,CAC5CL,EAAOK,qBAAuB,IAClC,MAAO,UAAWvB,EAAauB,uBAAyB,SAAU,CAC9DL,EAAOK,qBAAuB/B,EAAsBgC,oBAAoBxB,EAAauB,qBAAsB,QAAS,MAAOzB,EAAa,MAC5I,CACJ,CAEA,GAAIE,EAAayB,WAAY,CACzB,MAAMC,EAAiBf,MAAMC,QAAQZ,EAAa2B,UAAY3B,EAAa2B,SAAW,GACtFT,EAAOO,WAAajC,EAAsBoC,cAAc5B,EAAayB,WAAYC,EAAgB5B,EAAa,MAClH,MAAO,GAAIoB,EAAOG,OAAS,SAAWrB,EAAa6B,MAAO,CACtDX,EAAOW,MAAQrC,EAAsBgC,oBAAoBxB,EAAa6B,MAAO,QAAS,MAAO/B,EAAa,MAC9G,CAEA,GAAIA,EAAYG,YAAcH,EAAYG,WAAWC,QAAS,CAC1DgB,EAAOY,YAAc,CAAC,EACtB,MAAM5B,EAAUJ,EAAYG,WAAWC,QACvC,IAAK,MAAM6B,KAAO3B,OAAOD,KAAKD,GAAU,CACpC,MAAM8B,EAAaxC,EAAsBgC,oBAAoBtB,EAAQ6B,GAAMA,EAAK,MAAOjC,EAAa,OACpGoB,EAAOY,YAAYC,GAAO,CACtBZ,MAAOY,EACPV,KAAMW,EAAWX,OAAS,QAAU,QAAU,SAC9CI,WAAYO,EAAWP,WACvBI,MAAOG,EAAWH,MAClBI,GAAID,EAAWC,GACfX,eAAgBU,EAAWX,OAAS,QAAU,QAAU,OAEhE,CACJ,CAEA,OAAOH,CACX,EACH,IAAAgB,EAAA,CAAAC,WAAA,MAAAD,EAAAtC,iBAAA,OAAAsC,CAAA","ignoreList":[],"sourceRoot":"openapi/parsers"}},{"offset":{"line":42,"column":0},"map":{"version":3,"names":["OpenApiRefResolver","___OpenApiRefResolver","OpenApiTypeMapper","___OpenApiTypeMapper","OpenApiUIMapper","___OpenApiUIMapper","OpenApiPropertyMapper","mapProperties","properties","requiredKeys","openApiRoot","version","depth","normalizedProps","key","Object","keys","isRequired","includes","propDef","$ref","resolved","resolve","this","mapPropertyMetadata","swaggerProp","keyName","currentProp","refResult","_resolveReference","_resolveAllOf","type","mapType","metaProp","required","uiDirective","build","length","ui","_applyConstraints","_applyStateModifiers","default","undefined","Array","isArray","enum","widget","_applyPolymorphism","_applyNestedTypes","resolvedType","inlineProp","allOf","merged","subSchema","resolvedSub","deepMergeSchemas","maxLength","minLength","pattern","maximum","minimum","multipleOf","maxItems","minItems","uniqueItems","maxProperties","minProperties","exclusiveMaximum","exclusiveMinimum","readOnly","writeOnly","nullable","deprecated","discriminator","propertyName","mapping","oneOf","i","push","anyOf","not","childRequired","additionalProperties","items","target","source","output","assign","forEach","from","Set","__exports","__esModule"],"sources":["OpenApiPropertyMapper.ts"],"sourcesContent":["/**\n * @file OpenApiPropertyMapper.ts\n * @description Extracts and maps OpenAPI properties into MetaUI IPropertyMetadata.\n */\n\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport { OpenApiRefResolver } from \"../OpenApiRefResolver\";\nimport { OpenApiTypeMapper } from \"../OpenApiTypeMapper\";\nimport { OpenApiUIMapper } from \"../OpenApiUIMapper\";\n\n/**\n * Utility class responsible for extracting and mapping OpenAPI properties into the native MetaUI IPropertyMetadata schema format.\n * \n * @public\n */\nexport class OpenApiPropertyMapper {\n /**\n * Recursively traverses and translates an OpenAPI properties block into a MetaUI IPropertyMetadata dictionary.\n * \n * @param {Record<string, any>} properties The OpenAPI properties block.\n * @param {string[]} requiredKeys Array of required property keys.\n * @param {any} openApiRoot The OpenAPI root document for resolving references.\n * @param {\"2.0\" | \"3.0\"} version The OpenAPI version.\n * @param {number} [depth=0] Recursion depth limiter to prevent stack overflows on circular refs.\n * @returns {Record<string, IPropertyMetadata>} The normalized MetaUI properties mapping.\n */\n public static mapProperties(\n properties: Record<string, any>, \n requiredKeys: string[], \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number = 0\n ): Record<string, IPropertyMetadata> {\n const normalizedProps: Record<string, IPropertyMetadata> = {};\n \n if (depth > 8) return normalizedProps;\n\n for (const key of Object.keys(properties)) {\n const isRequired = requiredKeys.includes(key);\n let propDef = properties[key];\n\n if (propDef.$ref) {\n const resolved = OpenApiRefResolver.resolve(propDef.$ref, openApiRoot);\n if (resolved) {\n propDef = { ...resolved, ...propDef };\n }\n }\n\n normalizedProps[key] = this.mapPropertyMetadata(propDef, key, isRequired, openApiRoot, version, depth + 1);\n }\n \n return normalizedProps;\n }\n\n /**\n * Translates a single OpenAPI property schema block into a MetaUI IPropertyMetadata block.\n * Delegates specific mapping tasks to focused private methods to adhere to SRP.\n * \n * @param {any} swaggerProp The specific OpenAPI property schema to map.\n * @param {string} keyName The key/name of this property.\n * @param {boolean} isRequired Whether this property is strictly required.\n * @param {any} openApiRoot The OpenAPI root document for resolving references.\n * @param {\"2.0\" | \"3.0\"} version The OpenAPI version.\n * @param {number} [depth=0] Recursion depth limiter.\n * @returns {IPropertyMetadata} The normalized MetaUI property metadata.\n */\n public static mapPropertyMetadata(\n swaggerProp: unknown, \n keyName: string, \n isRequired: boolean, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number = 0\n ): IPropertyMetadata {\n let currentProp = swaggerProp;\n\n // 1. Resolve References\n const refResult = this._resolveReference(currentProp, keyName, isRequired, openApiRoot, version, depth);\n if (refResult) {\n return refResult;\n }\n\n // 2. Resolve Composition (allOf)\n currentProp = this._resolveAllOf(currentProp, openApiRoot);\n\n // 3. Base Initialization\n const type = OpenApiTypeMapper.mapType(currentProp.type);\n const metaProp: IPropertyMetadata = {\n type: type,\n required: isRequired\n };\n\n // 4. UI Directive Binding\n const uiDirective = OpenApiUIMapper.build(currentProp, keyName);\n if (Object.keys(uiDirective).length > 0) {\n metaProp.ui = uiDirective;\n }\n\n // 5. Constraints & State Modifiers\n this._applyConstraints(metaProp, currentProp, version);\n this._applyStateModifiers(metaProp, currentProp);\n\n if (currentProp.default !== undefined) {\n metaProp.default = currentProp.default;\n }\n\n if (Array.isArray(currentProp.enum)) {\n metaProp.enum = currentProp.enum;\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"dropdown\";\n }\n\n // 6. Polymorphism & Nesting\n this._applyPolymorphism(metaProp, currentProp, openApiRoot, version, depth);\n this._applyNestedTypes(metaProp, currentProp, openApiRoot, version, depth, type);\n\n return metaProp;\n }\n\n /**\n * Attempts to resolve a $ref block. If it resolves to a primitive, it inlines it.\n * Otherwise, it returns a reference widget payload.\n * \n * @param {any} currentProp The current schema property definition.\n * @param {string} keyName The structural key name.\n * @param {boolean} isRequired Whether the property is strictly required.\n * @param {any} openApiRoot The root API definition for relative resolution.\n * @param {\"2.0\" | \"3.0\"} version The structural version context.\n * @param {number} depth The recursive resolution depth.\n * @returns {IPropertyMetadata | null} Resolved metadata, or null if no reference exists.\n * @private\n */\n private static _resolveReference(\n currentProp: unknown, \n keyName: string, \n isRequired: boolean, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number\n ): IPropertyMetadata | null {\n if (!currentProp.$ref) {\n return null;\n }\n\n const resolved = OpenApiRefResolver.resolve(currentProp.$ref, openApiRoot);\n const resolvedType = currentProp.type || (resolved && resolved.type);\n \n if (resolvedType && [\"string\", \"number\", \"integer\", \"boolean\"].includes(resolvedType)) {\n const inlineProp = { ...resolved, ...currentProp };\n delete inlineProp.$ref;\n return this.mapPropertyMetadata(inlineProp, keyName, isRequired, openApiRoot, version, depth + 1);\n }\n\n return {\n type: \"object\",\n $ref: currentProp.$ref,\n required: isRequired,\n ui: { widget: \"reference\" }\n };\n }\n\n /**\n * Evaluates and merges 'allOf' arrays into a unified schema definition.\n * \n * @param {any} currentProp The structural property definition containing potential aggregations.\n * @param {any} openApiRoot The base schema for deep resolution.\n * @returns {any} A flattened and merged schema entity.\n * @private\n */\n private static _resolveAllOf(currentProp: unknown, openApiRoot: unknown): unknown {\n if (!Array.isArray(currentProp.allOf)) {\n return currentProp;\n }\n \n let merged = { ...currentProp };\n delete merged.allOf;\n for (const subSchema of currentProp.allOf) {\n let resolvedSub = subSchema;\n if (subSchema.$ref) {\n resolvedSub = OpenApiRefResolver.resolve(subSchema.$ref, openApiRoot) || {};\n }\n merged = this.deepMergeSchemas(merged, resolvedSub);\n }\n return merged;\n }\n\n /**\n * Extracts structural constraints (min/max, regex, etc.) and maps them natively to the output metadata.\n * \n * @param {IPropertyMetadata} metaProp The target metadata definition block.\n * @param {any} currentProp The source OpenAPI schema chunk.\n * @param {\"2.0\" | \"3.0\"} version The version, utilized for nuanced boundary matching.\n * @private\n */\n private static _applyConstraints(metaProp: IPropertyMetadata, currentProp: unknown, version: \"2.0\" | \"3.0\"): void {\n // String Constraints\n if (typeof currentProp.maxLength === \"number\") metaProp.maxLength = currentProp.maxLength;\n if (typeof currentProp.minLength === \"number\") metaProp.minLength = currentProp.minLength;\n if (typeof currentProp.pattern === \"string\") metaProp.pattern = currentProp.pattern;\n\n // Numeric Constraints\n if (typeof currentProp.maximum === \"number\") metaProp.maximum = currentProp.maximum;\n if (typeof currentProp.minimum === \"number\") metaProp.minimum = currentProp.minimum;\n if (typeof currentProp.multipleOf === \"number\") metaProp.multipleOf = currentProp.multipleOf;\n \n // Array Constraints\n if (typeof currentProp.maxItems === \"number\") metaProp.maxItems = currentProp.maxItems;\n if (typeof currentProp.minItems === \"number\") metaProp.minItems = currentProp.minItems;\n if (typeof currentProp.uniqueItems === \"boolean\") metaProp.uniqueItems = currentProp.uniqueItems;\n\n // Object Constraints\n if (typeof currentProp.maxProperties === \"number\") metaProp.maxProperties = currentProp.maxProperties;\n if (typeof currentProp.minProperties === \"number\") metaProp.minProperties = currentProp.minProperties;\n\n // Exclusive Min/Max version-specific logic\n if (version === \"2.0\") {\n if (currentProp.exclusiveMaximum === true && typeof currentProp.maximum === \"number\") {\n metaProp.exclusiveMaximum = true;\n }\n if (currentProp.exclusiveMinimum === true && typeof currentProp.minimum === \"number\") {\n metaProp.exclusiveMinimum = true;\n }\n } else if (version === \"3.0\") {\n if (typeof currentProp.exclusiveMaximum === \"number\" || typeof currentProp.exclusiveMaximum === \"boolean\") {\n metaProp.exclusiveMaximum = currentProp.exclusiveMaximum;\n }\n if (typeof currentProp.exclusiveMinimum === \"number\" || typeof currentProp.exclusiveMinimum === \"boolean\") {\n metaProp.exclusiveMinimum = currentProp.exclusiveMinimum;\n }\n }\n }\n\n /**\n * Extracts operational state flags like readOnly or nullable mapping them onto the internal specification.\n * \n * @param {IPropertyMetadata} metaProp Target native specification.\n * @param {any} currentProp Source raw schema payload.\n * @private\n */\n private static _applyStateModifiers(metaProp: IPropertyMetadata, currentProp: unknown): void {\n if (currentProp.readOnly === true) metaProp.readOnly = true;\n if (currentProp.writeOnly === true) metaProp.writeOnly = true;\n if (currentProp.nullable === true) metaProp.nullable = true;\n if (currentProp.deprecated === true) metaProp.deprecated = true;\n }\n\n /**\n * Extracts and maps polymorphic discriminator and union types (oneOf/anyOf) to MetaUI structural directives.\n * \n * @param {IPropertyMetadata} metaProp Native MetaUI definition tree.\n * @param {any} currentProp Raw schema block.\n * @param {any} openApiRoot Master OpenAPI root.\n * @param {\"2.0\" | \"3.0\"} version Protocol version identifier.\n * @param {number} depth Internal depth tracker.\n * @private\n */\n private static _applyPolymorphism(\n metaProp: IPropertyMetadata, \n currentProp: unknown, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number\n ): void {\n // Discriminator handling\n if (currentProp.discriminator) {\n if (version === \"2.0\" && typeof currentProp.discriminator === \"string\") {\n metaProp.discriminator = { propertyName: currentProp.discriminator };\n } else if (version === \"3.0\" && typeof currentProp.discriminator === \"object\") {\n metaProp.discriminator = {\n propertyName: currentProp.discriminator.propertyName,\n mapping: currentProp.discriminator.mapping\n };\n }\n }\n\n // Handle oneOf polymorphic mapping\n if (Array.isArray(currentProp.oneOf)) {\n metaProp.oneOf = [];\n for (let i = 0; i < currentProp.oneOf.length; i++) {\n metaProp.oneOf.push(this.mapPropertyMetadata(currentProp.oneOf[i], `Variant${i}`, false, openApiRoot, version, depth + 1));\n }\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"polymorphic\";\n }\n \n // Handle anyOf mapping\n if (Array.isArray(currentProp.anyOf)) {\n metaProp.anyOf = [];\n for (let i = 0; i < currentProp.anyOf.length; i++) {\n metaProp.anyOf.push(this.mapPropertyMetadata(currentProp.anyOf[i], `AnyVariant${i}`, false, openApiRoot, version, depth + 1));\n }\n }\n\n // Handle not mapping\n if (currentProp.not) {\n metaProp.not = this.mapPropertyMetadata(currentProp.not, `NotVariant`, false, openApiRoot, version, depth + 1);\n }\n }\n\n /**\n * Recursively traverses into nested objects and arrays constructing the structural node trees.\n * \n * @param {IPropertyMetadata} metaProp The localized destination structure.\n * @param {any} currentProp The source chunk representing a complex element.\n * @param {any} openApiRoot The OpenAPI dictionary context.\n * @param {\"2.0\" | \"3.0\"} version System schema version.\n * @param {number} depth Invocation stack depth.\n * @param {string} type Normalized atomic structure type.\n * @private\n */\n private static _applyNestedTypes(\n metaProp: IPropertyMetadata, \n currentProp: unknown, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number,\n type: string\n ): void {\n if (type === \"object\") {\n if (currentProp.properties) {\n const childRequired = Array.isArray(currentProp.required) ? currentProp.required : [];\n metaProp.properties = this.mapProperties(currentProp.properties, childRequired, openApiRoot, version, depth + 1);\n }\n \n if (currentProp.additionalProperties) {\n if (currentProp.additionalProperties === true) {\n metaProp.additionalProperties = true;\n } else if (typeof currentProp.additionalProperties === \"object\") {\n metaProp.additionalProperties = this.mapPropertyMetadata(currentProp.additionalProperties, \"value\", false, openApiRoot, version, depth + 1);\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"dictionary\";\n }\n }\n \n // Opaque JSON object definition mapping\n if (!currentProp.properties && !currentProp.additionalProperties) {\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"codeEditor\";\n }\n } else if (type === \"array\" && currentProp.items) {\n metaProp.items = this.mapPropertyMetadata(currentProp.items, \"items\", false, openApiRoot, version, depth + 1);\n if (metaProp.items.type !== \"object\") {\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"multiInput\";\n }\n }\n }\n\n /**\n * Recursively deep-merges two OpenAPI objects, ensuring array boundaries and nested structures are preserved.\n * \n * @param {any} target The target base object.\n * @param {any} source The source object providing override details.\n * @returns {any} The synthesized output object.\n */\n public static deepMergeSchemas(target: unknown, source: unknown): unknown {\n const output = Object.assign({}, target);\n if (source === null || typeof source !== \"object\") return output;\n\n Object.keys(source).forEach(key => {\n if (Array.isArray(source[key])) {\n output[key] = Array.isArray(target[key]) \n ? Array.from(new Set([...target[key], ...source[key]])) \n : [...source[key]];\n } else if (typeof source[key] === \"object\" && source[key] !== null) {\n if (target[key] && typeof target[key] === \"object\") {\n output[key] = this.deepMergeSchemas(target[key], source[key]);\n } else {\n output[key] = Object.assign({}, source[key]);\n }\n } else {\n output[key] = source[key];\n }\n });\n return output;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"openapi/parsers"}},{"offset":{"line":43,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","ClearFormActionPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","isEditable","sap","ui","requireSync","TextControl","require","control","visible","Button","text","label","type","icon","press","oEvent","btn","getSource","model","getModel","setProperty","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["ClearFormActionPlugin.ts"],"sourcesContent":["/**\n * @file ClearFormActionPlugin.ts\n * @description A custom action plugin that renders a Button to reset the model data.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\n\n/**\n * A custom action plugin that renders a Button to reset the model data.\n * Demonstrates how to create functional action plugins that interact with the bound model.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.actions\n * @public\n */\nexport class ClearFormActionPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n if (!this.isEditable) {\n sap.ui.requireSync(\"sap/m/Text\");\n const TextControl = sap.ui.require(\"sap/m/Text\");\n this.control = new TextControl({ visible: false });\n return this.control as Control;\n }\n \n this.control = new Button({\n text: fieldMetadata.ui?.label || \"Clear Data\",\n type: \"Reject\",\n icon: \"sap-icon://delete\",\n press: (oEvent: sap.ui.base.Event) => {\n const btn = oEvent.getSource() as Button;\n const model = btn.getModel(modelName) as JSONModel;\n if (model) {\n // Reset the entire model payload to an empty object\n model.setProperty(\"/\", {});\n }\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null; // Actions do not store scalar values\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,0JAAA,MAKSA,EAAUC,EAAA,cAaZ,MAAMC,UAA8BF,EAChCG,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,IAAKG,KAAKE,WAAY,CAClBC,IAAIC,GAAGC,YAAY,cACnB,MAAMC,EAAcH,IAAIC,GAAGG,QAAQ,cACnCP,KAAKQ,QAAU,IAAIF,EAAY,CAAEG,QAAS,QAC1C,OAAOT,KAAKQ,OAChB,CAEAR,KAAKQ,QAAU,IAAIE,EAAO,CACtBC,KAAMd,EAAcO,IAAIQ,OAAS,aACjCC,KAAM,SACNC,KAAM,oBACNC,MAAQC,IACJ,MAAMC,EAAMD,EAAOE,YACnB,MAAMC,EAAQF,EAAIG,SAASrB,GAC3B,GAAIoB,EAAO,CAEPA,EAAME,YAAY,IAAK,CAAC,EAC5B,KAIR,OAAOrB,KAAKQ,OAChB,CAEUc,WACN,OAAO,IACX,CAEUC,aACN,GAAIvB,KAAKQ,SAAWR,KAAKC,SAAU,CAC/B,IAAKD,KAAKE,WAAY,OACrBF,KAAKQ,QAAmBgB,YAAYxB,KAAKC,SAASG,IAAIqB,SAC3D,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA/B,wBAAA,OAAA+B,CAAA","ignoreList":[],"sourceRoot":"plugins/actions"}},{"offset":{"line":44,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","SubmitFormActionPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","isEditable","sap","ui","requireSync","TextControl","require","control","visible","Button","text","label","type","icon","press","Core","getEventBus","publish","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["SubmitFormActionPlugin.ts"],"sourcesContent":["/**\n * @file SubmitFormActionPlugin.ts\n * @description A custom action plugin that triggers form submission.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport Core from \"sap/ui/core/Core\";\n\n/**\n * Renders a Button that requests the host container to execute its submit flow.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.actions\n * @public\n */\nexport class SubmitFormActionPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n if (!this.isEditable) {\n sap.ui.requireSync(\"sap/m/Text\");\n const TextControl = sap.ui.require(\"sap/m/Text\");\n this.control = new TextControl({ visible: false });\n return this.control as Control;\n }\n \n this.control = new Button({\n text: fieldMetadata.ui?.label || \"Submit\",\n type: \"Emphasized\",\n icon: \"sap-icon://save\",\n press: () => {\n // Fire an event that the GeneratorHost or LayoutManager listens to\n Core.getEventBus().publish(\"MetaUI\", \"TriggerSubmit\", {});\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null;\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,gLAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA+BF,EACjCG,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,IAAKG,KAAKE,WAAY,CAClBC,IAAIC,GAAGC,YAAY,cACnB,MAAMC,EAAcH,IAAIC,GAAGG,QAAQ,cACnCP,KAAKQ,QAAU,IAAIF,EAAY,CAAEG,QAAS,QAC1C,OAAOT,KAAKQ,OAChB,CAEAR,KAAKQ,QAAU,IAAIE,EAAO,CACtBC,KAAMd,EAAcO,IAAIQ,OAAS,SACjCC,KAAM,aACNC,KAAM,kBACNC,MAAOA,KAEHC,EAAKC,cAAcC,QAAQ,SAAU,gBAAiB,CAAC,MAI/D,OAAOlB,KAAKQ,OAChB,CAEUW,WACN,OAAO,IACX,CAEUC,aACN,GAAIpB,KAAKQ,SAAWR,KAAKC,SAAU,CAC/B,IAAKD,KAAKE,WAAY,OACrBF,KAAKQ,QAAmBa,YAAYrB,KAAKC,SAASG,IAAIkB,SAC3D,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA5B,yBAAA,OAAA4B,CAAA","ignoreList":[],"sourceRoot":"plugins/actions"}},{"offset":{"line":45,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","URLHelper","library","UrlNavigationActionPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","control","Button","text","ui","label","icon","press","targetUrl","args","redirect","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["UrlNavigationActionPlugin.ts"],"sourcesContent":["/**\n * @file UrlNavigationActionPlugin.ts\n * @description A custom action plugin that navigates to a URL.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport * as library from \"sap/m/library\";\nconst URLHelper = library.URLHelper;\n\n/**\n * Renders a Button that triggers a redirect to an external URL (defined in args).\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.actions\n * @public\n */\nexport class UrlNavigationActionPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n\n this.control = new Button({\n text: fieldMetadata.ui?.label || \"Open Link\",\n icon: \"sap-icon://action\",\n press: () => {\n // In a real scenario, the URL might come from the payload or from schema args\n const targetUrl = fieldMetadata.ui?.args || \"https://sap.com\";\n URLHelper.redirect(targetUrl as string, true); // true = open in new window\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null;\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,gLAAA,MAKSA,EAAUC,EAAA,cAKnB,MAAMC,EAAYC,EAAQD,UAQnB,MAAME,UAAkCJ,EACpCK,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhBG,KAAKE,QAAU,IAAIC,EAAO,CACtBC,KAAMP,EAAcQ,IAAIC,OAAS,YACjCC,KAAM,oBACNC,MAAOA,KAEH,MAAMC,EAAYZ,EAAcQ,IAAIK,MAAQ,kBAC5CjB,EAAUkB,SAASF,EAAqB,SAIhD,OAAOT,KAAKE,OAChB,CAEUU,WACN,OAAO,IACX,CAEUC,aACN,GAAIb,KAAKE,SAAWF,KAAKC,SAAU,CAC9BD,KAAKE,QAAmBY,YAAYd,KAAKC,SAASI,IAAIU,SAC3D,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAArB,4BAAA,OAAAqB,CAAA","ignoreList":[],"sourceRoot":"plugins/actions"}},{"offset":{"line":46,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","ArrayPlugin","render","field","bindingPath","modelName","engineScopeId","onChange","this","metadata","propKey","startsWith","substring","subSchema","type","title","ui","label","items","properties","uiLayout","control","Button","id","generateStableId","text","isEditable","icon","press","oEvent","btn","getSource","parentModel","getModel","bindingContext","getBindingContext","updatePath","ctxPath","getPath","endsWith","nestedData","JSON","parse","stringify","getProperty","parent","getParent","parentHost","getMetadata","getName","schemaDefs","sap","require","DynamicHost","host","schemaDefinition","schemaDefinitions","data","editable","attachSubmit","e","payload","getParameter","setProperty","buttonText","dialogButtonText","openInDialog","getValue","applyState","__exports","__esModule"],"sources":["ArrayPlugin.ts"],"sourcesContent":["/**\n * @file ArrayPlugin.ts\n * @description Renders a button that drills down into a nested table (array) via a recursive Dialog using v2 schema.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\n\nexport class ArrayPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Button` to open a nested array form dialog.\n * \n * @param field The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Button control.\n */\n public render(field: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = field;\n const propKey = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n \n const subSchema: ISchema = {\n type: \"array\",\n title: field.ui?.label || propKey,\n items: field.items || {\n type: \"object\",\n properties: {} // inference will handle it if empty\n }\n };\n\n if (field.uiLayout) {\n subSchema.uiLayout = field.uiLayout;\n }\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? \"View Records\" : \"Edit Records\",\n icon: !this.isEditable ? \"sap-icon://display\" : \"sap-icon://list\",\n press: (oEvent: sap.ui.base.Event) => {\n const btn = oEvent.getSource() as Button;\n const parentModel = btn.getModel(modelName) as JSONModel;\n if (!parentModel) return;\n \n const bindingContext = btn.getBindingContext(modelName);\n let updatePath = bindingPath;\n if (bindingContext && !bindingPath.startsWith(\"/\")) {\n const ctxPath = bindingContext.getPath();\n updatePath = ctxPath.endsWith(\"/\") ? ctxPath + bindingPath : (ctxPath === \"/\" ? \"/\" + bindingPath : ctxPath + \"/\" + bindingPath);\n }\n \n // Deep clone to prevent live-mutations on the parent model before 'Submit' is clicked\n const nestedData = JSON.parse(JSON.stringify(parentModel.getProperty(updatePath) || []));\n\n let parent = btn.getParent();\n let parentHost = null;\n while (parent) {\n if (parent.getMetadata().getName() === \"nz.co.siliconst.ui5.metaui.controls.host.GeneratorHost\" || \n parent.getMetadata().getName() === \"nz.co.siliconst.ui5.metaui.controls.DynamicHost\") {\n parentHost = parent as any;\n break;\n }\n parent = parent.getParent();\n }\n const schemaDefs = parentHost ? parentHost.getProperty(\"schemaDefinitions\") : null;\n\n sap.ui.require([\"nz/co/siliconst/ui5/metaui/controls/DynamicHost\"], (DynamicHost: typeof import(\"../../controls/DynamicHost\").default) => {\n const host = new DynamicHost({\n schemaDefinition: subSchema,\n schemaDefinitions: schemaDefs,\n data: nestedData,\n editable: this.isEditable // Pass the display mode down to the child Engine!\n });\n\n // Only attach submit event if we are not in display mode\n if (!!this.isEditable) {\n host.attachSubmit((e: sap.ui.base.Event) => {\n const payload = e.getParameter(\"payload\");\n parentModel.setProperty(updatePath, payload);\n\n // CRITICAL: Notify the parent Engine that this field mutated\n // so it can trigger LiveUpdate syncs and validate!\n if (this.onChange) {\n this.onChange(true, propKey);\n }\n });\n }\n\n const buttonText = field.ui?.dialogButtonText || (!this.isEditable ? \"Close\" : \"OK\");\n host.openInDialog(`Nested Records: ${field.ui?.label || propKey}`, buttonText);\n });\n }\n });\n \n return this.control as Control;\n }\n\n /**\n * Read-only component for the engine, returns null.\n */\n protected getValue(): unknown {\n return null;\n }\n\n /**\n * Read-only component, no dynamic state handling needed for the button itself.\n */\n protected applyState(): void {\n // dynamic state changes\n }\n}\n"],"mappings":"AAAA,uIAAA,MAKSA,EAAUC,EAAA,cAMZ,MAAMC,UAAoBF,EAWtBG,OAAOC,EAA2BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAC/GC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChB,MAAMO,EAAUN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,MAAMS,EAAqB,CACvBC,KAAM,QACNC,MAAOZ,EAAMa,IAAIC,OAASP,EAC1BQ,MAAOf,EAAMe,OAAS,CAClBJ,KAAM,SACNK,WAAY,CAAC,IAIrB,GAAIhB,EAAMiB,SAAU,CAChBP,EAAUO,SAAWjB,EAAMiB,QAC/B,CAEAZ,KAAKa,QAAU,IAAIC,EAAO,CACtBC,GAAIf,KAAKgB,iBAAiBlB,EAAeF,GACzCqB,MAAOjB,KAAKkB,WAAa,eAAiB,eAC1CC,MAAOnB,KAAKkB,WAAa,qBAAuB,kBAChDE,MAAQC,IACJ,MAAMC,EAAMD,EAAOE,YACnB,MAAMC,EAAcF,EAAIG,SAAS5B,GACjC,IAAK2B,EAAa,OAElB,MAAME,EAAiBJ,EAAIK,kBAAkB9B,GAC7C,IAAI+B,EAAahC,EACjB,GAAI8B,IAAmB9B,EAAYO,WAAW,KAAM,CAChD,MAAM0B,EAAUH,EAAeI,UAC/BF,EAAaC,EAAQE,SAAS,KAAOF,EAAUjC,EAAeiC,IAAY,IAAM,IAAMjC,EAAciC,EAAU,IAAMjC,CACxH,CAGA,MAAMoC,EAAaC,KAAKC,MAAMD,KAAKE,UAAUX,EAAYY,YAAYR,IAAe,KAEpF,IAAIS,EAASf,EAAIgB,YACjB,IAAIC,EAAa,KACjB,MAAOF,EAAQ,CACX,GAAIA,EAAOG,cAAcC,YAAc,0DACnCJ,EAAOG,cAAcC,YAAc,kDAAmD,CACtFF,EAAaF,EACb,KACJ,CACAA,EAASA,EAAOC,WACpB,CACA,MAAMI,EAAaH,EAAaA,EAAWH,YAAY,qBAAuB,KAE9EO,IAAInC,GAAGoC,QAAQ,CAAC,mDAAqDC,IACjE,MAAMC,EAAO,IAAID,EAAY,CACzBE,iBAAkB1C,EAClB2C,kBAAmBN,EACnBO,KAAMjB,EACNkB,SAAUlD,KAAKkB,aAInB,KAAMlB,KAAKkB,WAAY,CACnB4B,EAAKK,aAAcC,IACf,MAAMC,EAAUD,EAAEE,aAAa,WAC/B9B,EAAY+B,YAAY3B,EAAYyB,GAIpC,GAAIrD,KAAKD,SAAU,CACfC,KAAKD,SAAS,KAAMG,EACxB,GAER,CAEA,MAAMsD,EAAa7D,EAAMa,IAAIiD,oBAAsBzD,KAAKkB,WAAa,QAAU,MAC/E4B,EAAKY,aAAa,mBAAmB/D,EAAMa,IAAIC,OAASP,IAAWsD,QAK/E,OAAOxD,KAAKa,OAChB,CAKU8C,WACN,OAAO,IACX,CAKUC,aACN,EAEP,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAApE,cAAA,OAAAoE,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":47,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","BarcodeScannerPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","inputControl","Input","value","editable","ui","readOnly","width","change","result","validateAndApplyVisualState","isValid","scannerBtn","BarcodeScannerButton","scanSuccess","oEvent","getParameter","setValue","HBox","items","addStyleClass","getValue","applyState","setEditable","__exports","__esModule"],"sources":["BarcodeScannerPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport HBox from \"sap/m/HBox\";\nimport Input from \"sap/m/Input\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport BarcodeScannerButton from \"sap/ndc/BarcodeScannerButton\";\nimport TextControl from \"sap/m/Text\";\n\nexport class BarcodeScannerPlugin extends BasePlugin {\n private inputControl!: Input;\n\n /**\n * Renders a `BarcodeScannerButton` alongside an `Input`.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured HBox control.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.inputControl = new Input({\n id: this.generateStableId(engineScopeId, bindingPath + \"-input\"),\n value: this.generateBindingInfo(bindingPath, modelName),\n editable: !metadata.ui?.readOnly,\n width: \"100%\",\n change: () => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n \n const scannerBtn = new BarcodeScannerButton({\n id: this.generateStableId(engineScopeId, bindingPath + \"-btn\"),\n scanSuccess: (oEvent: sap.ui.base.Event) => {\n const text = oEvent.getParameter(\"text\") as string;\n if (text) {\n this.inputControl.setValue(text);\n // UI5's two-way data binding on the input will sync the model automatically\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n }\n });\n\n this.control = new HBox({\n id: this.generateStableId(engineScopeId, bindingPath),\n items: [this.inputControl, scannerBtn],\n width: \"100%\"\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current scanned text.\n * @returns {unknown} The barcode string.\n */\n protected getValue(): unknown {\n return this.inputControl ? this.inputControl.getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.inputControl && this.metadata) {\n if (!this.isEditable) return;\n this.inputControl.setEditable(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,8NAASA,EAAUC,EAAA,cASZ,MAAMC,UAA6BF,EAa/BG,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAY,CAC3BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,KAAMR,KAAKS,oBAAoBb,EAAaC,KAEhDG,KAAKU,sBAAsBV,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKW,aAAe,IAAIC,EAAM,CAC1BN,GAAIN,KAAKO,iBAAiBT,EAAeF,EAAc,UACvDiB,MAAOb,KAAKS,oBAAoBb,EAAaC,GAC7CiB,UAAWnB,EAASoB,IAAIC,SACxBC,MAAO,OACPC,OAAQA,KACJ,MAAMC,EAASnB,KAAKoB,8BACpB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SACvC,KAIR,MAAMqB,EAAa,IAAIC,EAAqB,CACxCjB,GAAIN,KAAKO,iBAAiBT,EAAeF,EAAc,QACvD4B,YAAcC,IACV,MAAMjB,EAAOiB,EAAOC,aAAa,QACjC,GAAIlB,EAAM,CACNR,KAAKW,aAAagB,SAASnB,GAE3B,MAAMW,EAASnB,KAAKoB,8BACpB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SACvC,CACJ,KAIRD,KAAKI,QAAU,IAAIwB,EAAK,CACpBtB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCiC,MAAO,CAAC7B,KAAKW,aAAcW,GAC3BL,MAAO,SACRa,cAAc,0BAEjB9B,KAAKU,sBAAsBV,KAAKI,QAAST,EAAUE,GAEnD,OAAOG,KAAKI,OAChB,CAMU2B,WACN,OAAO/B,KAAKW,aAAeX,KAAKW,aAAaoB,WAAa,IAC9D,CAKUC,aACN,GAAIhC,KAAKW,cAAgBX,KAAKL,SAAU,CACpC,IAAKK,KAAKG,WAAY,OACtBH,KAAKW,aAAasB,aAAajC,KAAKL,SAASoB,IAAIC,SACrD,CACJ,EACH,IAAAkB,EAAA,CAAAC,WAAA,MAAAD,EAAAzC,uBAAA,OAAAyC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":48,"column":0},"map":{"version":3,"names":["GlobalPipeline","____core_PipelineManager","Logger","____utils_Logger","BasePlugin","control","metadata","fieldKey","modelName","isEditable","useMessageManager","setEditable","editable","this","setUseMessageManager","generateStableId","engineScopeId","bindingPath","undefined","safePath","replace","generateBindingInfo","typeInstance","additionalOptions","path","model","type","validate","isValid","getVisible","validatorsToRun","argsMap","maxLength","required","push","minLength","pattern","minimum","maximum","min","max","format","ui","validators","v","name","args","length","errorMessage","val","getValue","result","executeValidation","setVisualValidationState","ctrl","setValueState","coreLibrary","ValueState","None","Error","setValueStateText","error","validateAndApplyVisualState","onStateChange","newMetadata","applyState","applyCommonDirectives","readOnly","visibleOn","ExpressionBuilder","sap","require","expr","build","bindProperty","parts","formatter","enabledOn","setEnabled","destroy","__exports","__esModule"],"sources":["BasePlugin.ts"],"sourcesContent":["/**\n * @file BasePlugin.ts\n * @description Abstract foundation for all MetaUI plugins, enforcing lifecycle hooks for v2 Schema.\n */\n\nimport { IPlugin } from \"../../interfaces/IPlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport { GlobalPipeline } from \"../../core/PipelineManager\";\nimport coreLibrary from \"sap/ui/core/library\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * Abstract class representing a standard MetaUI Plugin.\n * Enforces the required rendering, state extraction, and validation contracts.\n * \n * @abstract\n * @public\n */\nexport abstract class BasePlugin implements IPlugin {\n /** The instantiated UI5 control for this plugin. */\n protected control: Control | null = null;\n\n /** The metadata schema defining the field rules. */\n protected metadata: IPropertyMetadata | null = null;\n\n /** The internal JSON path of the field relative to its parent payload. */\n protected fieldKey: string = \"\";\n\n /** The UI5 JSONModel name used for absolute binding paths. */\n protected modelName: string = \"meta\";\n\n /** Indicates if the engine is enforcing an editable mode. */\n protected isEditable: boolean = true;\n\n /** Indicates if the plugin should delegate visual validation to the MessageManager. */\n protected useMessageManager: boolean = false;\n\n /** Internal callback provided by GeneratorHost to signal validation/data changes upwards */\n protected onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /**\n * Injects the global editable mode context into the plugin before rendering.\n * @param editable True if the plugin should render in editable mode.\n */\n public setEditable(editable: boolean): void {\n this.isEditable = editable;\n }\n\n /**\n * Injects the global MessageManager context into the plugin.\n * @param useMessageManager True if the MessageManager is handling validation visual states.\n */\n public setUseMessageManager(useMessageManager: boolean): void {\n this.useMessageManager = useMessageManager;\n }\n\n /**\n * Instantiates the raw UI5 control and binds it to the model.\n * \n * @param fieldMetadata The JSON Schema for the field.\n * @param bindingPath The JSON path to bind to.\n * @param modelName The UI5 model name.\n * @param engineScopeId The deterministic scope ID provided by the Engine to prevent cloning collisions.\n * @param onChange The callback fired natively when a field value blur/change occurs.\n * @returns {Control} The generated UI5 control.\n */\n public abstract render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName?: string, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void, model?: unknown): Control;\n\n /**\n * Generates a deterministic, globally unique ID for this control.\n * Prefixes the sanitized binding path with the Engine's scoped ID.\n */\n protected generateStableId(engineScopeId: string | undefined, bindingPath: string): string | undefined {\n if (!engineScopeId) return undefined;\n // Strip leading slash and replace internal slashes with hyphens\n const safePath = bindingPath.replace(/^\\//, '').replace(/\\//g, '-');\n return `${engineScopeId}--${safePath}`;\n }\n\n /**\n * Extracts the current raw value from the underlying UI5 control.\n */\n protected abstract getValue(): unknown;\n\n /**\n * Generates a standardized programmatic binding configuration object.\n * Ensures perfect architectural consistency across all plugins instead of relying on string parsing.\n * \n * @param bindingPath The relative or absolute path.\n * @param modelName The target model name.\n * @param typeInstance An optional UI5 Type instance (e.g. Integer, Float).\n * @param additionalOptions Optional extra configurations (e.g. formatOptions, constraints).\n * @returns A configuration object ready to be assigned to 'value', 'text', 'state', etc.\n */\n protected generateBindingInfo(bindingPath: string, modelName: string, typeInstance?: unknown, additionalOptions?: Record<string, unknown>): { path: string, model: string, type?: unknown, [key: string]: unknown } {\n return {\n path: bindingPath,\n model: modelName,\n ...(typeInstance ? { type: typeInstance } : {}),\n ...(additionalOptions || {})\n };\n }\n\n /**\n * Universal pipeline validation.\n */\n public validate(): import(\"../../interfaces/IPlugin\").IPluginValidationResult {\n if (!this.control || !this.metadata) return { isValid: true };\n\n // Skip validation for hidden fields (e.g. hidden by ConditionEngine visibleOn)\n if (typeof (this.control as Control).getVisible === \"function\") {\n if (!(this.control as Control).getVisible()) {\n return { isValid: true };\n }\n }\n\n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {\n \"maxLength\": this.metadata.maxLength\n };\n\n if (this.metadata.required) {\n validatorsToRun.push(\"required\");\n }\n if (this.metadata.maxLength) validatorsToRun.push(\"maxLength\");\n if (this.metadata.minLength) {\n validatorsToRun.push(\"minLength\");\n argsMap[\"minLength\"] = this.metadata.minLength;\n }\n if (this.metadata.pattern) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = this.metadata.pattern;\n }\n if (this.metadata.minimum !== undefined || this.metadata.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: this.metadata.minimum, max: this.metadata.maximum };\n }\n \n const format = this.metadata.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n\n if (this.metadata.ui?.validators) {\n for (const v of this.metadata.ui.validators) {\n if (typeof v === \"string\") {\n validatorsToRun.push(v);\n } else if (v && v.name) {\n validatorsToRun.push(v.name);\n if (v.args !== undefined) {\n argsMap[v.name] = v.args;\n }\n }\n }\n }\n\n if (validatorsToRun.length === 0) {\n return { isValid: true, errorMessage: undefined, fieldKey: this.fieldKey };\n }\n\n const val = this.getValue();\n const result = GlobalPipeline.executeValidation(val, validatorsToRun, argsMap);\n return { isValid: result.isValid, errorMessage: result.errorMessage, fieldKey: this.fieldKey };\n }\n\n /**\n * Natively manipulates the UI5 control's valueState if the control supports it.\n * Uses reflection to safely apply styles without crashing on structural controls.\n */\n public setVisualValidationState(isValid: boolean, errorMessage?: string): void {\n if (!this.control) return;\n\n \n // Use reflection to check if the control supports ValueState (e.g. sap.m.Input does, sap.m.Text does not)\n type StateControl = {\n setValueState?: (state: string) => void;\n setValueStateText?: (text: string) => void;\n };\n const ctrl = this.control as unknown as StateControl;\n if (typeof ctrl.setValueState === \"function\") {\n ctrl.setValueState(isValid ? coreLibrary.ValueState.None : coreLibrary.ValueState.Error);\n \n if (typeof ctrl.setValueStateText === \"function\") {\n ctrl.setValueStateText(isValid ? \"\" : (errorMessage || \"\"));\n }\n } else {\n Logger.error(\"[MetaUI]\", `Plugin ${this.fieldKey} has no setValueState function!`, \"BasePlugin\");\n }\n }\n\n /**\n * Wraps standard validation and immediately applies the visual state.\n * Ideal for 'change' events to instantly turn fields red on blur.\n */\n protected validateAndApplyVisualState(): import(\"../../interfaces/IPlugin\").IPluginValidationResult {\n const result = this.validate();\n this.setVisualValidationState(result.isValid, result.errorMessage);\n return result;\n }\n\n /**\n * Executes when the condition engine pushes new schema metadata to this field (e.g. readOnly changing).\n * @param newMetadata The mutated schema metadata.\n */\n public onStateChange(newMetadata: IPropertyMetadata): void {\n this.metadata = newMetadata;\n this.applyState();\n }\n\n /**\n * Abstract hook for the plugin to apply state changes to its specific UI5 control (e.g. placeholders, labels).\n */\n protected abstract applyState(): void;\n\n /**\n * Helper to apply common UI directives (like readOnly, visibleOn) directly to any control.\n */\n protected applyCommonDirectives(control: Control, metadata: IPropertyMetadata, modelName: string = \"meta\"): void {\n const ctrl = control as unknown as { setEditable?: (b: boolean) => void, setEnabled?: (b: boolean) => void };\n if (metadata.ui?.readOnly !== undefined && typeof ctrl.setEditable === \"function\") {\n ctrl.setEditable(!metadata.ui.readOnly);\n }\n\n if (metadata.ui?.visibleOn) {\n const ExpressionBuilder = sap.ui.require(\"nz/co/siliconst/ui5/metaui/utils/ExpressionBuilder\")?.ExpressionBuilder;\n let expr = \"\";\n if (ExpressionBuilder) {\n expr = ExpressionBuilder.build(metadata.ui.visibleOn, this.fieldKey, modelName);\n } else {\n expr = `{= ${metadata.ui.visibleOn.replace(/\\$root\\./g, `${modelName}>/`).replace(/\\./g, '/')} }`;\n }\n control.bindProperty(\"visible\", { parts: [{ path: \"meta>/\" }], formatter: () => false });\n control.bindProperty(\"visible\", expr);\n }\n\n if (metadata.ui?.enabledOn && typeof ctrl.setEnabled === \"function\") {\n const ExpressionBuilder = sap.ui.require(\"nz/co/siliconst/ui5/metaui/utils/ExpressionBuilder\")?.ExpressionBuilder;\n let expr = \"\";\n if (ExpressionBuilder) {\n expr = ExpressionBuilder.build(metadata.ui.enabledOn, this.fieldKey, modelName);\n } else {\n expr = `{= ${metadata.ui.enabledOn.replace(/\\$root\\./g, `${modelName}>/`).replace(/\\./g, '/')} }`;\n }\n control.bindProperty(\"enabled\", expr);\n }\n }\n\n\n\n /**\n * Natively destroys the instantiated UI5 control to prevent memory leaks.\n * Can be overridden by subclasses if they manage secondary controls or custom models.\n */\n public destroy(): void {\n if (this.control && typeof this.control.destroy === \"function\") {\n this.control.destroy();\n this.control = null;\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":49,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","BooleanPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","applyCommonDirectives","CheckBox","selected","enabled","ui","readOnly","select","oEvent","getParameter","result","validateAndApplyVisualState","isValid","getValue","getSelected","applyState","setEnabled","__exports","__esModule"],"sources":["BooleanPlugin.ts"],"sourcesContent":["/**\n * @file BooleanPlugin.ts\n * @description Renders a sap.m.Switch for boolean states.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport CheckBox from \"sap/m/CheckBox\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for toggleable booleans using `sap.m.CheckBox`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class BooleanPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.CheckBox` component for boolean evaluation.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @returns {Control} The configured CheckBox control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: boolean) => val ? \"Yes\" : \"No\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new CheckBox({\n id: this.generateStableId(engineScopeId, bindingPath),\n selected: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n select: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"selected\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current boolean state.\n * @returns {boolean} The selected state.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as CheckBox).getSelected() : false;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as CheckBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,0JAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAAsBF,EASxBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAWe,UAAW,CAC9DC,UAAYC,GAAiBA,EAAM,MAAQ,SAGnDd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAS,CACxBR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,SAAUjB,KAAKW,oBAAoBf,EAAaC,GAChDqB,SAAUvB,EAAcwB,IAAIC,SAC5BC,OAASC,IACL,MAAMR,EAAMQ,EAAOC,aAAa,YAChC,MAAMC,EAASxB,KAAKyB,8BACpB,GAAIzB,KAAKD,SAAU,CACfC,KAAKD,SAASyB,EAAOE,QAAS1B,KAAKE,SACvC,KAIRF,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUqB,WACN,OAAO3B,KAAKM,QAAWN,KAAKM,QAAqBsB,cAAgB,KACrE,CAKUC,aACN,GAAI7B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAAqBwB,YAAY9B,KAAKC,SAASkB,IAAIC,SAC7D,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAAtC,gBAAA,OAAAsC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":50,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","CameraControl","_interopRequireDefault","__CameraControl","CameraPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","ImageControl","id","generateStableId","src","generateBindingInfo","width","alt","ui","label","applyCommonDirectives","value","schemaMetadata","readOnly","attachCapture","result","validateAndApplyVisualState","isValid","getValue","applyState","setProperty","__exports","__esModule"],"sources":["CameraPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport CameraControl from \"../../controls/CameraControl\";\nimport ImageControl from \"sap/m/Image\";\n\nexport class CameraPlugin extends BasePlugin {\n /**\n * Renders a `CameraControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured CameraControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new ImageControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n src: this.generateBindingInfo(bindingPath, modelName),\n width: \"400px\",\n alt: metadata.ui?.label || \"Image\"\n });\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new CameraControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n });\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n // Validation mapping could be hooked into the 'capture' event if needed, but Two-Way binding updates the model naturally.\n (this.control as CameraControl).attachCapture(() => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current base64 image state.\n * @returns {unknown} The image value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as CameraControl).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,yQAASA,EAAUC,EAAA,oBAGZC,EAAaC,EAAAC,GAGb,MAAMC,UAAqBL,EAWvBM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAa,CAC5BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,IAAKR,KAAKS,oBAAoBb,EAAaC,GAC3Ca,MAAO,QACPC,IAAKhB,EAASiB,IAAIC,OAAS,UAE/Bb,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAc,CAC7BgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCmB,MAAOf,KAAKS,oBAAoBb,EAAaC,GAC7CmB,eAAgBrB,EAChBsB,WAAYtB,EAASiB,IAAIK,WAG7BjB,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GAGlDG,KAAKI,QAA0Bc,cAAc,KAC1C,MAAMC,EAASnB,KAAKoB,8BAChB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SACvC,IAGR,OAAOD,KAAKI,OAChB,CAMUkB,WACN,OAAOtB,KAAKI,QAAWJ,KAAKI,QAA0BkB,WAAa,IACvE,CAKUC,aACN,GAAIvB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCoB,YAAY,aAAcxB,KAAKL,SAASiB,IAAIK,SACtF,CACJ,EACH,IAAAQ,EAAA,CAAAC,WAAA,MAAAD,EAAAhC,eAAA,OAAAgC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":51,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","CodeEditorPlugin","detectLanguage","value","trimmed","trim","startsWith","JSON","parse","e","test","adjustHeight","this","control","val","getValue","lines","split","length","newHeight","Math","max","setHeight","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","metadata","fieldKey","replace","CodeEditor","id","generateStableId","generateBindingInfo","type","ui","args","editable","isEditable","readOnly","height","width","change","result","validateAndApplyVisualState","isValid","currentVal","detectedType","getType","setType","attachEventOnce","oBinding","getBinding","initLogic","applyState","attachChange","applyCommonDirectives","setEditable","__exports","__esModule"],"sources":["CodeEditorPlugin.ts"],"sourcesContent":["/**\n * @file CodeEditorPlugin.ts\n * @description Renders a sap.ui.codeeditor.CodeEditor for editing source code/JSON.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport CodeEditor from \"sap/ui/codeeditor/CodeEditor\";\n\n/**\n * Handles rendering logic for code editing.\n * Requires the `sap.ui.codeeditor` library to be loaded.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class CodeEditorPlugin extends BasePlugin {\n /**\n * Infers the language type from the content.\n * @param value The raw string.\n * @returns The language string.\n */\n private detectLanguage(value: string): string {\n if (!value || typeof value !== \"string\") return \"javascript\";\n \n const trimmed = value.trim();\n if (trimmed === \"\") return \"javascript\";\n\n // 1. JSON\n if (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n try {\n JSON.parse(trimmed);\n return \"json\";\n } catch (e) {\n // Not valid JSON, continue testing\n }\n }\n\n // 2. XML / HTML\n if (/^\\s*<[\\s\\S]*>\\s*$/.test(trimmed)) {\n return \"xml\";\n }\n\n // 3. Fallback to JavaScript\n return \"javascript\";\n }\n\n /**\n * Dynamically adjusts the height of the editor based on content lines.\n */\n private adjustHeight(): void {\n if (!this.control) return;\n const val = (this.control as CodeEditor).getValue() || \"\";\n const lines = val.split(/\\r\\n|\\r|\\n/).length;\n // 18px per line + 20px padding, minimum 100px\n const newHeight = Math.max(100, (lines * 18) + 20);\n (this.control as CodeEditor).setHeight(newHeight + \"px\");\n }\n\n /**\n * Renders a `sap.ui.codeeditor.CodeEditor` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured CodeEditor control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\"); // For EventBus\n \n \n \n this.control = new CodeEditor({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: fieldMetadata.ui?.args || \"javascript\", // will be dynamically overridden if args is missing\n editable: !this.isEditable ? false : !fieldMetadata.ui?.readOnly,\n height: \"100px\", // Initial minimum height\n width: \"100%\",\n change: () => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n \n // If language isn't explicitly defined, try to guess it dynamically\n if (!fieldMetadata.ui?.args) {\n const currentVal = (this.control as CodeEditor).getValue();\n const detectedType = this.detectLanguage(currentVal);\n if ((this.control as CodeEditor).getType() !== detectedType) {\n (this.control as CodeEditor).setType(detectedType);\n }\n }\n \n this.adjustHeight();\n }\n });\n\n // Clean architecture: Wait for the model context, then attach safely to the binding itself.\n // No timeouts, no DOM hacks, pure UI5 Eventing.\n (this.control as CodeEditor).attachEventOnce(\"modelContextChange\", () => {\n const oBinding = (this.control as CodeEditor).getBinding(\"value\");\n \n const initLogic = () => {\n if (this.control) {\n const currentVal = (this.control as CodeEditor).getValue();\n if (!fieldMetadata.ui?.args) {\n (this.control as CodeEditor).setType(this.detectLanguage(currentVal));\n }\n this.adjustHeight();\n // CRITICAL: Ace Editor sometimes loses its constructor `editable` flag \n // when the model asynchronously injects a new value string. \n // We must forcefully re-apply the correct state after binding.\n this.applyState();\n }\n };\n\n if (oBinding) {\n // Attach for future model changes\n oBinding.attachChange(initLogic);\n }\n \n // Execute immediately in case the model is synchronous (JSONModel)\n initLogic();\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current code string.\n * @returns {unknown} The code value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as CodeEditor).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) {\n (this.control as CodeEditor).setEditable(false);\n } else {\n (this.control as CodeEditor).setEditable(!this.metadata.ui?.readOnly);\n }\n }\n }\n}\n"],"mappings":"AAAA,4JAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAAyBF,EAM1BG,eAAeC,GACnB,IAAKA,UAAgBA,IAAU,SAAU,MAAO,aAEhD,MAAMC,EAAUD,EAAME,OACtB,GAAID,IAAY,GAAI,MAAO,aAG3B,GAAIA,EAAQE,WAAW,MAAQF,EAAQE,WAAW,KAAM,CACpD,IACIC,KAAKC,MAAMJ,GACX,MAAO,MACX,CAAE,MAAOK,GACL,CAER,CAGA,GAAI,oBAAoBC,KAAKN,GAAU,CACnC,MAAO,KACX,CAGA,MAAO,YACX,CAKQO,eACJ,IAAKC,KAAKC,QAAS,OACnB,MAAMC,EAAOF,KAAKC,QAAuBE,YAAc,GACvD,MAAMC,EAAQF,EAAIG,MAAM,cAAcC,OAEtC,MAAMC,EAAYC,KAAKC,IAAI,IAAML,EAAQ,GAAM,IAC9CJ,KAAKC,QAAuBS,UAAUH,EAAY,KACvD,CAYOI,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHhB,KAAKgB,SAAWA,EAChBhB,KAAKiB,SAAWL,EAChBZ,KAAKkB,SAAWL,EAAYM,QAAQ,IAAK,IAIzCnB,KAAKC,QAAU,IAAImB,EAAW,CAC1BC,GAAIrB,KAAKsB,iBAAiBP,EAAeF,GACzCtB,MAAOS,KAAKuB,oBAAoBV,EAAaC,GAC7CU,KAAMZ,EAAca,IAAIC,MAAQ,aAChCC,UAAW3B,KAAK4B,WAAa,OAAShB,EAAca,IAAII,SACxDC,OAAQ,QACRC,MAAO,OACPC,OAAQA,KACJ,MAAMC,EAASjC,KAAKkC,8BACpB,GAAIlC,KAAKgB,SAAU,CACfhB,KAAKgB,SAASiB,EAAOE,QAASnC,KAAKkB,SACvC,CAGA,IAAKN,EAAca,IAAIC,KAAM,CACzB,MAAMU,EAAcpC,KAAKC,QAAuBE,WAChD,MAAMkC,EAAerC,KAAKV,eAAe8C,GACzC,GAAKpC,KAAKC,QAAuBqC,YAAcD,EAAc,CACxDrC,KAAKC,QAAuBsC,QAAQF,EACzC,CACJ,CAEArC,KAAKD,kBAMZC,KAAKC,QAAuBuC,gBAAgB,qBAAsB,KAC/D,MAAMC,EAAYzC,KAAKC,QAAuByC,WAAW,SAEzD,MAAMC,EAAYA,KACd,GAAI3C,KAAKC,QAAS,CACd,MAAMmC,EAAcpC,KAAKC,QAAuBE,WAChD,IAAKS,EAAca,IAAIC,KAAM,CACxB1B,KAAKC,QAAuBsC,QAAQvC,KAAKV,eAAe8C,GAC7D,CACApC,KAAKD,eAILC,KAAK4C,YACT,GAGJ,GAAIH,EAAU,CAEVA,EAASI,aAAaF,EAC1B,CAGAA,MAGJ3C,KAAK8C,sBAAsB9C,KAAKC,QAASW,EAAeE,GAExD,OAAOd,KAAKC,OAChB,CAMUE,WACN,OAAOH,KAAKC,QAAWD,KAAKC,QAAuBE,WAAa,IACpE,CAKUyC,aACN,GAAI5C,KAAKC,SAAWD,KAAKiB,SAAU,CAC/B,IAAKjB,KAAK4B,WAAY,CACjB5B,KAAKC,QAAuB8C,YAAY,MAC7C,KAAO,CACF/C,KAAKC,QAAuB8C,aAAa/C,KAAKiB,SAASQ,IAAII,SAChE,CACJ,CACJ,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAA3D,mBAAA,OAAA2D,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":52,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","DatePlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","formatOptions","source","pattern","applyCommonDirectives","DatePicker","value","displayFormat","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","dp","setEditable","setRequired","__exports","__esModule"],"sources":["DatePlugin.ts"],"sourcesContent":["/**\n * @file DatePlugin.ts\n * @description Renders a sap.m.DatePicker natively bound to ISO date strings.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport DatePicker from \"sap/m/DatePicker\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for Date strings.\n */\nexport class DatePlugin extends BasePlugin {\n /**\n * Renders a `sap.m.DatePicker` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured DatePicker control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Date\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd\" },\n pattern: \"yyyy-MM-dd\"\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new DatePicker({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Date\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd\" },\n pattern: \"yyyy-MM-dd\"\n }\n }),\n displayFormat: \"long\",\n editable: !fieldMetadata.ui?.readOnly,\n required: fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current date string.\n * @returns {unknown} The date value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as DatePicker).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const dp = this.control as DatePicker;\n dp.setEditable(!this.metadata.ui?.readOnly);\n dp.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,yJAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAmBF,EAWrBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC7Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,cACnBA,QAAS,kBAIrBd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAW,CAC1BR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC9Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,cACnBA,QAAS,gBAGjBI,cAAe,OACfC,UAAWxB,EAAcyB,IAAIC,SAC7BC,SAAU3B,EAAc2B,SACxBC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,SAChC,MAAMC,EAAS3B,KAAK4B,8BACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SACvC,KAIR,OAAOF,KAAKM,OAChB,CAMUwB,WACN,OAAO9B,KAAKM,QAAWN,KAAKM,QAAuBwB,WAAa,IACpE,CAKUC,aACN,GAAI/B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM2B,EAAKhC,KAAKM,QAChB0B,EAAGC,aAAajC,KAAKC,SAASmB,IAAIC,UAClCW,EAAGE,YAAYlC,KAAKC,SAASqB,SACjC,CACJ,EACH,IAAAa,EAAA,CAAAC,WAAA,MAAAD,EAAA1C,aAAA,OAAA0C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":53,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","DateTimePlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","formatOptions","source","pattern","applyCommonDirectives","DateTimePicker","value","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","input","setEditable","setRequired","__exports","__esModule"],"sources":["DateTimePlugin.ts"],"sourcesContent":["/**\n * @file DateTimePlugin.ts\n * @description Handles rendering logic for DateTime strings (timestamps).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport DateTimePicker from \"sap/m/DateTimePicker\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for timestamps/datetime inputs.\n */\nexport class DateTimePlugin extends BasePlugin {\n /**\n * Renders a `sap.m.DateTimePicker` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured DateTimePicker control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.DateTime\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\" },\n pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\"\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new DateTimePicker({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.DateTime\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\" },\n pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\"\n }\n }),\n editable: !fieldMetadata.ui?.readOnly,\n required: fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current datetime string.\n * @returns {unknown} The datetime value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as DateTimePicker).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as DateTimePicker;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,iKAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAuBF,EAWzBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAW,6BAA8B,CACjFe,cAAe,CACXC,OAAQ,CAAEC,QAAS,4BACnBA,QAAS,gCAIrBd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAe,CAC9BR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,EAAW,6BAA8B,CAClFe,cAAe,CACXC,OAAQ,CAAEC,QAAS,4BACnBA,QAAS,8BAGjBI,UAAWvB,EAAcwB,IAAIC,SAC7BC,SAAU1B,EAAc0B,SACxBC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,SAChC,MAAMC,EAAS1B,KAAK2B,8BACpB,GAAI3B,KAAKD,SAAU,CACfC,KAAKD,SAAS2B,EAAOE,QAAS5B,KAAKE,SACvC,KAIRF,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUuB,WACN,OAAO7B,KAAKM,QAAWN,KAAKM,QAA2BuB,WAAa,IACxE,CAKUC,aACN,GAAI9B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM0B,EAAQ/B,KAAKM,QACnByB,EAAMC,aAAahC,KAAKC,SAASkB,IAAIC,UACrCW,EAAME,YAAYjC,KAAKC,SAASoB,SACpC,CACJ,EACH,IAAAa,EAAA,CAAAC,WAAA,MAAAD,EAAAzC,iBAAA,OAAAyC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":54,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","PluginRegistry","____core_PluginRegistry","DictionaryMapPlugin","_isSyncing","_binding","canHandle","schema","type","additionalProperties","render","bindingPath","modelName","engineScopeId","onChange","model","this","metadata","valueSchema","container","VBox","width","addStyleClass","absolutePath","startsWith","currentData","getProperty","localItems","Object","keys","map","k","key","value","localModel","JSONModel","items","syncToParent","newDict","forEach","item","trim","setProperty","bindProperty","attachChange","initialize","headerItems","Title","text","title","ui","label","level","isEditable","push","Button","icon","press","header","HBox","justifyContent","alignItems","addItem","columns","Column","Label","hAlign","table","Table","mode","noDataText","setModel","bindItems","path","factory","sId","oContext","rowPath","getPath","keyInput","Input","editable","change","plugin","getInstance","getPlugin","widget","effectiveValueSchema","readOnly","valueControl","Date","now","cells","delBtn","matchIndex","parseInt","split","pop","splice","ColumnListItem","control","id","generateStableId","dialog","Dialog","contentWidth","contentHeight","horizontalScrolling","content","buttons","close","afterClose","removeAllContent","destroy","addDependent","open","getValue","validate","isValid","applyState","super"],"sources":["DictionaryMapPlugin.ts"],"sourcesContent":["/**\n * @file DictionaryMapPlugin.ts\n * @description Plugin for rendering open-ended JSON Dictionaries (additionalProperties).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { ISchema, IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport { PluginRegistry } from \"../../core/PluginRegistry\";\nimport VBox from \"sap/m/VBox\";\nimport HBox from \"sap/m/HBox\";\nimport Input from \"sap/m/Input\";\nimport Button from \"sap/m/Button\";\nimport Title from \"sap/m/Title\";\nimport Table from \"sap/m/Table\";\nimport Column from \"sap/m/Column\";\nimport Label from \"sap/m/Label\";\nimport ColumnListItem from \"sap/m/ColumnListItem\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Control from \"sap/ui/core/Control\";\nimport Dialog from \"sap/m/Dialog\";\nimport Toolbar from \"sap/m/Toolbar\";\nimport ToolbarSpacer from \"sap/m/ToolbarSpacer\";\n\n/**\n * Plugin for rendering open-ended JSON Dictionaries (additionalProperties).\n * Uses a local JSONModel and sap.m.Table to provide a stable, zero-hack UI5 two-way binding experience.\n * \n * @public\n */\nexport default class DictionaryMapPlugin extends BasePlugin {\n private _isSyncing: boolean = false;\n private _binding: sap.ui.model.PropertyBinding | null = null;\n\n public canHandle(schema: ISchema | IPropertyMetadata): boolean {\n return schema.type === \"object\" && typeof schema.additionalProperties === \"object\";\n }\n\n public render(\n schema: ISchema | IPropertyMetadata, \n bindingPath: string, \n modelName: string, \n engineScopeId: string, \n onChange?: () => void, \n model?: sap.ui.model.Model\n ): Control {\n this.onChange = onChange;\n this.metadata = schema as IPropertyMetadata;\n\n\n\n const valueSchema = (schema.additionalProperties as IPropertyMetadata) || { type: \"string\" };\n const container = new VBox({ width: \"100%\" }).addStyleClass(\"sapUiSmallMarginTopBottom\");\n \n const absolutePath = bindingPath.startsWith(\"/\") ? bindingPath : `/${bindingPath}`;\n \n // 1. Initialize local flat array model for the Table\n const currentData = model ? model.getProperty(absolutePath) || {} : {};\n\n \n const localItems = Object.keys(currentData).map(k => ({ key: k, value: currentData[k] }));\n const localModel = new JSONModel({ items: localItems });\n \n // Setup listener to flush local model back to parent dictionary model\n const syncToParent = () => {\n if (!model) return;\n this._isSyncing = true;\n const items = localModel.getProperty(\"/items\") as any[];\n const newDict: Record<string, any> = {};\n items.forEach(item => {\n if (item.key && item.key.trim() !== \"\") {\n newDict[item.key] = item.value;\n }\n });\n\n model.setProperty(absolutePath, newDict);\n if (this.onChange) this.onChange();\n this._isSyncing = false;\n };\n\n if (model) {\n this._binding = model.bindProperty(absolutePath);\n this._binding.attachChange(() => {\n if (this._isSyncing) return;\n const currentData = model.getProperty(absolutePath) || {};\n\n const localItems = Object.keys(currentData).map(k => ({ key: k, value: currentData[k] }));\n localModel.setProperty(\"/items\", localItems);\n });\n this._binding.initialize();\n }\n\n const headerItems: Control[] = [\n new Title({ text: schema.title || schema.ui?.label || \"Dictionary Map\", level: \"H5\" })\n ];\n\n if (this.isEditable) {\n headerItems.push(\n new Button({\n text: \"Add Property\",\n icon: \"sap-icon://add\",\n press: () => {\n const items = localModel.getProperty(\"/items\") as any[];\n items.push({ key: \"\", value: null });\n localModel.setProperty(\"/items\", items);\n syncToParent();\n }\n })\n );\n }\n\n const header = new HBox({\n justifyContent: \"SpaceBetween\",\n alignItems: \"Center\",\n items: headerItems\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n container.addItem(header);\n\n // 2. Build the Table\n const columns = [\n new Column({ header: new Label({ text: \"Key\" }) }),\n new Column({ header: new Label({ text: \"Value\" }) })\n ];\n\n if (this.isEditable) {\n columns.push(new Column({ width: \"4rem\", hAlign: \"Center\" }));\n }\n\n const table = new Table({\n mode: \"None\",\n noDataText: \"No metadata properties defined.\",\n columns: columns\n });\n\n table.setModel(localModel, \"localDict\");\n\n table.bindItems({\n path: \"localDict>/items\",\n factory: (sId: string, oContext: sap.ui.model.Context) => {\n const rowPath = oContext.getPath();\n \n // Key Input\n const keyInput = new Input({\n value: \"{localDict>key}\",\n editable: this.isEditable,\n change: () => syncToParent()\n });\n\n // Value Control\n const plugin = PluginRegistry.getInstance().getPlugin(valueSchema.type || \"string\", valueSchema.ui?.widget);\n \n // Temporarily override value schema readOnly state if the dictionary as a whole is readOnly\n const effectiveValueSchema = { ...valueSchema };\n if (!this.isEditable) {\n if (!effectiveValueSchema.ui) effectiveValueSchema.ui = {};\n effectiveValueSchema.ui.readOnly = true;\n }\n\n const valueControl = plugin.render(\n effectiveValueSchema,\n `${rowPath}/value`,\n \"localDict\",\n \"dict_\" + Date.now(),\n () => syncToParent(),\n localModel\n );\n\n const cells: Control[] = [keyInput, valueControl];\n\n if (this.isEditable) {\n const delBtn = new Button({\n icon: \"sap-icon://delete\",\n type: \"Reject\",\n press: () => {\n const items = localModel.getProperty(\"/items\") as any[];\n const matchIndex = parseInt(rowPath.split(\"/\").pop() || \"0\", 10);\n items.splice(matchIndex, 1);\n localModel.setProperty(\"/items\", items);\n syncToParent();\n }\n });\n cells.push(delBtn);\n }\n\n return new ColumnListItem({ cells });\n }\n });\n\n container.addItem(table);\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? \"View Dictionary\" : \"Edit Dictionary\",\n icon: !this.isEditable ? \"sap-icon://display\" : \"sap-icon://form\",\n press: () => {\n\n const dialog = new Dialog({\n title: schema.title || schema.ui?.label || \"Dictionary Map\",\n contentWidth: \"600px\",\n contentHeight: \"400px\",\n horizontalScrolling: false,\n content: [container],\n buttons: [\n new Button({\n text: !this.isEditable ? \"Close\" : \"OK\",\n type: \"Emphasized\",\n press: () => {\n dialog.close();\n }\n })\n ],\n afterClose: () => {\n // Remove container so it isn't destroyed when the dialog is destroyed\n dialog.removeAllContent();\n dialog.destroy();\n }\n });\n \n // Add dependent to ensure models are inherited properly if needed\n if (this.control) {\n this.control.addDependent(dialog);\n }\n \n dialog.open();\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null;\n }\n\n public validate(): import(\"../../interfaces/IPlugin\").IPluginValidationResult {\n return { isValid: true };\n }\n\n protected applyState(): void {\n }\n\n public destroy(): void {\n if (this._binding) {\n this._binding.destroy();\n this._binding = null;\n }\n super.destroy();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":55,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","DropdownPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","valueHelpArray","valueHelp","Array","isArray","enum","map","e","key","String","text","control","TextControl","id","generateStableId","generateBindingInfo","undefined","formatter","match","find","vh","applyCommonDirectives","select","Select","selectedKey","enabled","ui","readOnly","forceSelection","change","oEvent","item","getParameter","val","getKey","result","validateAndApplyVisualState","isValid","length","addItem","Item","forEach","getValue","getSelectedKey","applyState","setEnabled","__exports","__esModule"],"sources":["DropdownPlugin.ts"],"sourcesContent":["/**\n * @file DropdownPlugin.ts\n * @description Renders a sap.m.Select utilizing the schema's valueHelp structure.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Select from \"sap/m/Select\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for dropdown inputs.\n * Maps the static `valueHelp` schema array to `sap.ui.core.Item` elements.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class DropdownPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Select` component populated with schema-defined value help.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Select control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n \n const valueHelpArray = fieldMetadata.valueHelp && Array.isArray(fieldMetadata.valueHelp) \n ? fieldMetadata.valueHelp \n : (fieldMetadata.enum ? fieldMetadata.enum.map(e => ({ key: String(e), text: String(e) })) : []);\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (key: string) => {\n const match = valueHelpArray.find(vh => vh.key === key);\n return match ? match.text : key;\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n const select = new Select({\n id: this.generateStableId(engineScopeId, bindingPath),\n selectedKey: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n forceSelection: false,\n change: (oEvent: sap.ui.base.Event) => {\n const item = oEvent.getParameter(\"selectedItem\");\n const val = item ? item.getKey() : \"\";\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n const valueHelpArray = fieldMetadata.valueHelp && Array.isArray(fieldMetadata.valueHelp) \n ? fieldMetadata.valueHelp \n : (fieldMetadata.enum ? fieldMetadata.enum.map(e => ({ key: String(e), text: String(e) })) : []);\n\n if (valueHelpArray.length > 0) {\n // Always add the empty placeholder so that 'required' checks can actually fire if the user hasn't made a choice\n select.addItem(new Item({ key: \"\", text: \"--- Select ---\" }));\n \n valueHelpArray.forEach(vh => {\n select.addItem(new Item({ key: vh.key, text: vh.text }));\n });\n }\n\n this.control = select;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the currently selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Select).getSelectedKey() : null;\n }\n\n /**\n * Applies dynamic metadata state (e.g. readOnly) when the ConditionEngine fires.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const select = this.control as Select;\n select.setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,8KAAA,MAKSA,EAAUC,EAAA,cAcZ,MAAMC,UAAuBF,EAWzBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAGlB,MAAMC,EAAiBX,EAAcY,WAAaC,MAAMC,QAAQd,EAAcY,WACxEZ,EAAcY,UACbZ,EAAce,KAAOf,EAAce,KAAKC,IAAIC,IAAC,CAAOC,IAAKC,OAAOF,GAAIG,KAAMD,OAAOF,MAAS,GAEjGZ,KAAKgB,QAAU,IAAIC,EAAY,CAC3BC,GAAIlB,KAAKmB,iBAAiBrB,EAAeF,GACzCmB,KAAMf,KAAKoB,oBAAoBxB,EAAaC,EAAWwB,UAAW,CAC9DC,UAAYT,IACR,MAAMU,EAAQjB,EAAekB,KAAKC,GAAMA,EAAGZ,MAAQA,GACnD,OAAOU,EAAQA,EAAMR,KAAOF,OAIxCb,KAAK0B,sBAAsB1B,KAAKgB,QAASrB,EAAeE,GACxD,OAAOG,KAAKgB,OAChB,CAEA,MAAMW,EAAS,IAAIC,EAAO,CACtBV,GAAIlB,KAAKmB,iBAAiBrB,EAAeF,GACzCiC,YAAa7B,KAAKoB,oBAAoBxB,EAAaC,GACnDiC,SAAUnC,EAAcoC,IAAIC,SAC5BC,eAAgB,MAChBC,OAASC,IACL,MAAMC,EAAOD,EAAOE,aAAa,gBACjC,MAAMC,EAAMF,EAAOA,EAAKG,SAAW,GACnC,MAAMC,EAASxC,KAAKyC,8BACpB,GAAIzC,KAAKD,SAAU,CACfC,KAAKD,SAASyC,EAAOE,QAAS1C,KAAKE,SACvC,KAIR,MAAMI,EAAiBX,EAAcY,WAAaC,MAAMC,QAAQd,EAAcY,WACxEZ,EAAcY,UACbZ,EAAce,KAAOf,EAAce,KAAKC,IAAIC,IAAC,CAAOC,IAAKC,OAAOF,GAAIG,KAAMD,OAAOF,MAAS,GAEjG,GAAIN,EAAeqC,OAAS,EAAG,CAE3BhB,EAAOiB,QAAQ,IAAIC,EAAK,CAAEhC,IAAK,GAAIE,KAAM,oBAEzCT,EAAewC,QAAQrB,IACnBE,EAAOiB,QAAQ,IAAIC,EAAK,CAAEhC,IAAKY,EAAGZ,IAAKE,KAAMU,EAAGV,SAExD,CAEAf,KAAKgB,QAAUW,EACf3B,KAAK0B,sBAAsB1B,KAAKgB,QAASrB,EAAeE,GACxD,OAAOG,KAAKgB,OAChB,CAMU+B,WACN,OAAO/C,KAAKgB,QAAWhB,KAAKgB,QAAmBgC,iBAAmB,IACtE,CAKUC,aACN,GAAIjD,KAAKgB,SAAWhB,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAMsB,EAAS3B,KAAKgB,QACpBW,EAAOuB,YAAYlD,KAAKC,SAAS8B,IAAIC,SACzC,CACJ,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAA1D,iBAAA,OAAA0D,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":56,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","EmailPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","Input","value","type","maxLength","required","change","oEvent","result","validateAndApplyVisualState","isValid","getValue","getMetadata","getName","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["EmailPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\nexport class EmailPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\");\n \n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: \"Email\",\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) this.onChange(result.isValid, this.fieldKey);\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return this.control && this.control.getMetadata().getName() === \"sap.m.Input\" ? (this.control as Input).getValue() : null;\n }\n\n protected applyState(): void {\n if (!this.control || !this.metadata || this.control.getMetadata().getName() !== \"sap.m.Input\") return;\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n}\n"],"mappings":"AAAA,2JAASA,EAAUC,EAAA,cAMZ,MAAMC,UAAoBF,EACtBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAClBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,KAEhDG,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIO,EAAM,CACrBL,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCiB,MAAOb,KAAKU,oBAAoBd,EAAaC,GAC7CiB,KAAM,QACNC,UAAWpB,EAAcoB,WAAa,EACtCC,WAAYrB,EAAcqB,SAC1BC,OAASC,IACL,MAAMC,EAASnB,KAAKoB,8BACpB,GAAIpB,KAAKD,SAAUC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKE,aAI9DF,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEUiB,WACN,OAAOtB,KAAKK,SAAWL,KAAKK,QAAQkB,cAAcC,YAAc,cAAiBxB,KAAKK,QAAkBiB,WAAa,IACzH,CAEUG,aACN,IAAKzB,KAAKK,UAAYL,KAAKC,UAAYD,KAAKK,QAAQkB,cAAcC,YAAc,cAAe,OAC/F,MAAME,EAAQ1B,KAAKK,QACnBqB,EAAMC,aAAa3B,KAAKC,SAAS2B,IAAIC,UACrCH,EAAMI,cAAc9B,KAAKC,SAASe,SACtC,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAAtC,cAAA,OAAAsC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":57,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","FileUploaderPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","LinkControl","id","generateStableId","text","generateBindingInfo","href","target","applyCommonDirectives","FileUploader","value","enabled","ui","readOnly","placeholder","label","width","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["FileUploaderPlugin.ts"],"sourcesContent":["/**\n * @file FileUploaderPlugin.ts\n * @description Renders a sap.ui.unified.FileUploader.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport FileUploader from \"sap/ui/unified/FileUploader\";\nimport Control from \"sap/ui/core/Control\";\nimport LinkControl from \"sap/m/Link\";\n\n/**\n * Handles rendering logic for file uploads.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class FileUploaderPlugin extends BasePlugin {\n /**\n * Renders a `sap.ui.unified.FileUploader` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured FileUploader control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new LinkControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName),\n href: this.generateBindingInfo(bindingPath, modelName), // Assuming the value is a URL to the file\n target: \"_blank\"\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new FileUploader({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Choose a file...\",\n width: \"100%\",\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"newValue\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current file path.\n * @returns {unknown} The file value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as FileUploader).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as FileUploader).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,4KAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA2BF,EAW7BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,GAC5Ce,KAAMZ,KAAKW,oBAAoBf,EAAaC,GAC5CgB,OAAQ,WAEZb,KAAKc,sBAAsBd,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIS,EAAa,CAC5BP,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCoB,MAAOhB,KAAKW,oBAAoBf,EAAaC,GAC7CoB,SAAUtB,EAAcuB,IAAIC,SAC5BC,YAAazB,EAAcuB,IAAIG,OAAS,mBACxCC,MAAO,OACPC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,YAChC,MAAMC,EAAS3B,KAAK4B,8BACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SACvC,KAIRF,KAAKc,sBAAsBd,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAMUwB,WACN,OAAO9B,KAAKM,QAAWN,KAAKM,QAAyBwB,WAAa,IACtE,CAKUC,aACN,GAAI/B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAAyB0B,YAAYhC,KAAKC,SAASiB,IAAIC,SACjE,CACJ,EACH,IAAAc,EAAA,CAAAC,WAAA,MAAAD,EAAAxC,qBAAA,OAAAwC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":58,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","GeolocationControl","_interopRequireDefault","__GeolocationControl","GeolocationPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","lat","lng","applyCommonDirectives","value","schemaMetadata","readOnly","ui","attachCapture","result","validateAndApplyVisualState","isValid","getValue","applyState","setProperty","__exports","__esModule"],"sources":["GeolocationPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport GeolocationControl from \"../../controls/GeolocationControl\";\nimport TextControl from \"sap/m/Text\";\n\nexport class GeolocationPlugin extends BasePlugin {\n /**\n * Renders a `GeolocationControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured GeolocationControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: Record<string, unknown>) => val && val.lat !== undefined && val.lng !== undefined ? `Lat: ${val.lat}, Lng: ${val.lng}` : \"\"\n })\n });\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new GeolocationControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n });\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n (this.control as GeolocationControl).attachCapture(() => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current geolocation object.\n * @returns {unknown} The geolocation value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as GeolocationControl).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,kRAASA,EAAUC,EAAA,oBAGZC,EAAkBC,EAAAC,GAGlB,MAAMC,UAA0BL,EAW5BM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAY,CAC3BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,KAAMR,KAAKS,oBAAoBb,EAAaC,EAAWa,UAAW,CAC9DC,UAAYC,GAAiCA,GAAOA,EAAIC,MAAQH,WAAaE,EAAIE,MAAQJ,UAAY,QAAQE,EAAIC,aAAaD,EAAIE,MAAQ,OAGlJd,KAAKe,sBAAsBf,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAmB,CAClCgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCoB,MAAOhB,KAAKS,oBAAoBb,EAAaC,GAC7CoB,eAAgBtB,EAChBuB,WAAYvB,EAASwB,IAAID,WAG7BlB,KAAKe,sBAAsBf,KAAKI,QAAST,EAAUE,GAElDG,KAAKI,QAA+BgB,cAAc,KAC/C,MAAMC,EAASrB,KAAKsB,8BAChB,GAAItB,KAAKD,SAAU,CACfC,KAAKD,SAASsB,EAAOE,QAASvB,KAAKC,SACvC,IAGR,OAAOD,KAAKI,OAChB,CAMUoB,WACN,OAAOxB,KAAKI,QAAWJ,KAAKI,QAA+BoB,WAAa,IAC5E,CAKUC,aACN,GAAIzB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCsB,YAAY,aAAc1B,KAAKL,SAASwB,IAAID,SACtF,CACJ,EACH,IAAAS,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,oBAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":59,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","LinkPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","Link","id","generateStableId","text","generateBindingInfo","href","target","applyCommonDirectives","Input","value","type","maxLength","required","change","oEvent","result","validateAndApplyVisualState","isValid","getValue","getMetadata","getName","getHref","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["LinkPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Link from \"sap/m/Link\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\n\nexport class LinkPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\");\n \n if (!this.isEditable) {\n this.control = new Link({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName),\n href: this.generateBindingInfo(bindingPath, modelName),\n target: \"_blank\"\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n // Editable mode: user needs to type a URL, so we use an Input configured for URLs\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: \"Url\",\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) this.onChange(result.isValid, this.fieldKey);\n }\n });\n \n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n protected getValue(): unknown {\n if (!this.control) return null;\n if (this.control.getMetadata().getName() === \"sap.m.Input\") {\n return (this.control as Input).getValue();\n }\n return (this.control as Link).getHref();\n }\n \n protected applyState(): void {\n if (!this.control || !this.metadata) return;\n if (this.control.getMetadata().getName() === \"sap.m.Input\") {\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,0JAASA,EAAUC,EAAA,cAMZ,MAAMC,UAAmBF,EACrBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAClBJ,KAAKK,QAAU,IAAIC,EAAK,CACpBC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,GAC5Cc,KAAMX,KAAKU,oBAAoBd,EAAaC,GAC5Ce,OAAQ,WAEZZ,KAAKa,sBAAsBb,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAGAL,KAAKK,QAAU,IAAIS,EAAM,CACrBP,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCmB,MAAOf,KAAKU,oBAAoBd,EAAaC,GAC7CmB,KAAM,MACNC,UAAWtB,EAAcsB,WAAa,EACtCC,WAAYvB,EAAcuB,SAC1BC,OAASC,IACL,MAAMC,EAASrB,KAAKsB,8BACpB,GAAItB,KAAKD,SAAUC,KAAKD,SAASsB,EAAOE,QAASvB,KAAKE,aAI9DF,KAAKa,sBAAsBb,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEUmB,WACN,IAAKxB,KAAKK,QAAS,OAAO,KAC1B,GAAIL,KAAKK,QAAQoB,cAAcC,YAAc,cAAe,CACxD,OAAQ1B,KAAKK,QAAkBmB,UACnC,CACA,OAAQxB,KAAKK,QAAiBsB,SAClC,CAEUC,aACN,IAAK5B,KAAKK,UAAYL,KAAKC,SAAU,OACrC,GAAID,KAAKK,QAAQoB,cAAcC,YAAc,cAAe,CACxD,MAAMG,EAAQ7B,KAAKK,QACnBwB,EAAMC,aAAa9B,KAAKC,SAAS8B,IAAIC,UACrCH,EAAMI,cAAcjC,KAAKC,SAASiB,SACtC,CACJ,EACH,IAAAgB,EAAA,CAAAC,WAAA,MAAAD,EAAAzC,aAAA,OAAAyC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":60,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","MessageStripPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","control","MessageStrip","id","generateStableId","text","generateBindingInfo","type","showIcon","showCloseButton","getValue","applyState","__exports","__esModule"],"sources":["MessageStripPlugin.ts"],"sourcesContent":["/**\n * @file MessageStripPlugin.ts\n * @description Renders a sap.m.MessageStrip for informational text.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MessageStrip from \"sap/m/MessageStrip\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Renders read-only informational alerts within the layout.\n * Does not emit values to the payload.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MessageStripPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MessageStrip` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MessageStrip control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n // Use binding to display text if the field has a value, otherwise use the label\n this.control = new MessageStrip({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName),\n type: \"Information\", // Can be driven by schema arguments in the future\n showIcon: true,\n showCloseButton: false\n });\n\n return this.control as Control;\n }\n\n /**\n * Read-only control, returns null.\n */\n protected getValue(): unknown {\n return null; // Read-only component\n }\n\n /**\n * Read-only control, no dynamic state needed.\n */\n protected applyState(): void {\n // Read-only component, no dynamic state needed currently\n }\n}\n"],"mappings":"AAAA,oJAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA2BF,EAW7BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAGzEI,KAAKK,QAAU,IAAIC,EAAa,CAC5BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,GAC5Cc,KAAM,cACNC,SAAU,KACVC,gBAAiB,QAGrB,OAAOb,KAAKK,OAChB,CAKUS,WACN,OAAO,IACX,CAKUC,aACN,EAEP,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAvB,qBAAA,OAAAuB,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":61,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","Logger","____utils_Logger","MultiInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","Array","isArray","join","applyCommonDirectives","plugin","mi","MultiInput","enabled","ui","readOnly","placeholder","label","showValueHelp","tokenUpdate","oEvent","type","getParameter","sourceMi","getSource","removedTokens","removedTexts","map","t","getText","bindingInfo","getNativeBindingContext","model","absPath","currentArray","getProperty","newArray","filter","includes","debug","syncTokensToModel","attachSubmit","getValue","trim","setValue","addValidator","args","bindAggregation","factory","sId","oContext","getObject","Token","key","binding","getBinding","error","getModel","ctx","getContext","getPath","cp","endsWith","setProperty","refresh","result","validateAndApplyVisualState","isValid","tokens","getTokens","applyState","setEnabled","__exports","__esModule"],"sources":["MultiInputPlugin.ts"],"sourcesContent":["/**\n * @file MultiInputPlugin.ts\n * @description Renders a sap.m.MultiInput for primitive arrays (e.g. arrays of strings).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MultiInput from \"sap/m/MultiInput\";\nimport Token from \"sap/m/Token\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Event from \"sap/ui/base/Event\";\nimport ListBinding from \"sap/ui/model/ListBinding\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * Handles rendering logic for arrays of primitive strings.\n * Users can type custom strings and press Enter to add them as tokens.\n * Adheres strictly to native UI5 Model-View-Controller ListBinding principles.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiInput` component natively bound to a JSONModel array.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n this.modelName = modelName;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n const plugin = this;\n\n const mi = new MultiInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Type and press Enter...\",\n showValueHelp: false, // We don't have a list of options for primitive tags\n tokenUpdate: (oEvent: Event) => {\n const type = oEvent.getParameter(\"type\");\n const sourceMi = oEvent.getSource() as MultiInput;\n \n // Native UI5 tokens removed via the 'x' icon. We sync this directly back to the model.\n if (type === \"removed\") {\n const removedTokens = oEvent.getParameter(\"removedTokens\") as Token[];\n const removedTexts = removedTokens.map(t => t.getText());\n \n const bindingInfo = plugin.getNativeBindingContext(sourceMi);\n if (bindingInfo) {\n const { model, absPath } = bindingInfo;\n const currentArray = (model.getProperty(absPath) || []) as string[];\n const newArray = currentArray.filter(text => !removedTexts.includes(text));\n \n Logger.debug(`[MultiInputPlugin] Removing tokens from absolute path: ${absPath}`, removedTexts.join(\", \"), \"MultiInputPlugin\");\n plugin.syncTokensToModel(sourceMi, newArray);\n }\n }\n }\n });\n\n // The native addValidator pipeline is notoriously unreliable when there is no suggestion list bound,\n // often completely dropping the 'Enter' key event. Therefore, we use the standard `submit` event \n // inherited from InputBase to robustly capture when the user presses Enter.\n if (typeof mi.attachSubmit === \"function\") {\n mi.attachSubmit((oEvent: Event) => {\n const sourceMi = oEvent.getSource() as MultiInput;\n const val = (oEvent.getParameter(\"value\") as string || sourceMi.getValue()).trim();\n \n if (val) {\n const bindingInfo = plugin.getNativeBindingContext(sourceMi);\n if (bindingInfo) {\n const { model, absPath } = bindingInfo;\n const currentArray = (model.getProperty(absPath) || []) as string[];\n \n if (!currentArray.includes(val)) { // Prevent exact duplicates in primitive arrays\n const newArray = [...currentArray, val];\n Logger.debug(`[MultiInputPlugin] submit (Enter) fired. Adding token to absolute path: ${absPath}`, val, \"MultiInputPlugin\");\n \n // Natively clear the text input\n sourceMi.setValue(\"\");\n \n // Synchronize natively to the JSON model\n plugin.syncTokensToModel(sourceMi, newArray);\n } else {\n sourceMi.setValue(\"\");\n }\n }\n }\n });\n }\n\n // We must still register an addValidator returning null.\n // If UI5 *does* sporadically trigger the validator pipeline, this prevents the control \n // from attempting to natively mutate the bound ListBinding aggregation, which causes a core crash.\n mi.addValidator(function(args: { text: string }) {\n return null;\n });\n\n // Bind existing strings to tokens using a factory function\n mi.bindAggregation(\"tokens\", this.generateBindingInfo(bindingPath, modelName, undefined, {\n factory: (sId: string, oContext: sap.ui.model.Context) => {\n const text = (oContext.getObject() as string) || \"\";\n return new Token(sId, { key: text, text: text });\n }\n }));\n\n this.control = mi;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Extracts the native UI5 ListBinding, its absolute path, and underlying JSONModel.\n * \n * @param sourceMi The live, cloned MultiInput control instance inside the DOM tree.\n * @returns Object containing model and absolute path, or null if resolution fails.\n */\n private getNativeBindingContext(sourceMi: MultiInput): { model: JSONModel, absPath: string } | null {\n const binding = sourceMi.getBinding(\"tokens\") as ListBinding;\n if (!binding) {\n Logger.error(\"[MultiInputPlugin] token list binding is completely missing on the source clone.\");\n return null;\n }\n\n const model = binding.getModel() as JSONModel;\n if (!model) {\n Logger.error(\"[MultiInputPlugin] Failed to resolve underlying JSONModel from ListBinding.\");\n return null;\n }\n\n let absPath: string;\n const ctx = binding.getContext();\n const bindingPath = binding.getPath();\n\n if (ctx) {\n const cp = ctx.getPath();\n absPath = cp.endsWith(\"/\") ? cp + bindingPath : (cp === \"/\" ? \"/\" + bindingPath : cp + \"/\" + bindingPath);\n } else {\n absPath = bindingPath.startsWith(\"/\") ? bindingPath : \"/\" + bindingPath;\n }\n\n return { model, absPath };\n }\n\n /**\n * Synchronizes the primitive string array derived from the MultiInput tokens directly back into the Model.\n * \n * @param sourceMi The live MultiInput clone.\n * @param newArray The final array of string values to save.\n */\n private syncTokensToModel(sourceMi: MultiInput, newArray: string[]): void {\n const bindingInfo = this.getNativeBindingContext(sourceMi);\n if (!bindingInfo) return;\n\n const { model, absPath } = bindingInfo;\n \n model.setProperty(absPath, newArray);\n model.refresh(true); // Force UI5 to sync bindings down the tree\n\n if (this.onChange) {\n const result = this.validateAndApplyVisualState();\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n\n /**\n * Retrieves the current primitive array from the control.\n * @returns {unknown} The array of string tokens.\n */\n protected getValue(): unknown {\n if (!this.control) return [];\n const tokens = (this.control as MultiInput).getTokens();\n return tokens.map(t => t.getText());\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiInput).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":62,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","MultiSelectPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","Array","isArray","join","applyCommonDirectives","mcb","MultiComboBox","selectedKeys","enabled","ui","readOnly","placeholder","label","selectionChange","oEvent","keys","getSelectedKeys","result","validateAndApplyVisualState","isValid","enum","forEach","addItem","Item","key","toString","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["MultiSelectPlugin.ts"],"sourcesContent":["/**\n * @file MultiSelectPlugin.ts\n * @description Renders a sap.m.MultiComboBox for selecting multiple string values.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MultiComboBox from \"sap/m/MultiComboBox\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for selecting multiple strings from a predefined list.\n * Expects the payload to be an array of strings.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiSelectPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiComboBox` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiComboBox control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n const mcb = new MultiComboBox({\n id: this.generateStableId(engineScopeId, bindingPath),\n selectedKeys: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Select items...\",\n selectionChange: (oEvent: sap.ui.base.Event) => {\n const keys = (this.control as MultiComboBox).getSelectedKeys();\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n if (fieldMetadata.enum) {\n fieldMetadata.enum.forEach((val: string | number) => {\n mcb.addItem(new Item({ key: val.toString(), text: val.toString() }));\n });\n }\n\n this.control = mcb;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current selection keys.\n * @returns {unknown} The selected keys.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as MultiComboBox).getSelectedKeys() : [];\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiComboBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,wLAAA,MAKSA,EAAUC,EAAA,cAcZ,MAAMC,UAA0BF,EAW5BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAWe,UAAW,CAC9DC,UAAYC,GAAmBC,MAAMC,QAAQF,GAAOA,EAAIG,KAAK,MAAQ,OAG7EjB,KAAKkB,sBAAsBlB,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEA,MAAMa,EAAM,IAAIC,EAAc,CAC1BZ,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCyB,aAAcrB,KAAKW,oBAAoBf,EAAaC,GACpDyB,SAAU3B,EAAc4B,IAAIC,SAC5BC,YAAa9B,EAAc4B,IAAIG,OAAS,kBACxCC,gBAAkBC,IACd,MAAMC,EAAQ7B,KAAKM,QAA0BwB,kBAC7C,MAAMC,EAAS/B,KAAKgC,8BACpB,GAAIhC,KAAKD,SAAU,CACfC,KAAKD,SAASgC,EAAOE,QAASjC,KAAKE,SACvC,KAIR,GAAIP,EAAcuC,KAAM,CACpBvC,EAAcuC,KAAKC,QAASrB,IACxBK,EAAIiB,QAAQ,IAAIC,EAAK,CAAEC,IAAKxB,EAAIyB,WAAY7B,KAAMI,EAAIyB,eAE9D,CAEAvC,KAAKM,QAAUa,EACfnB,KAAKkB,sBAAsBlB,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAMUkC,WACN,OAAOxC,KAAKM,QAAWN,KAAKM,QAA0BwB,kBAAoB,EAC9E,CAKUW,aACN,GAAIzC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAA0BoC,YAAY1C,KAAKC,SAASsB,IAAIC,SAClE,CACJ,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAAlD,oBAAA,OAAAkD,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":63,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","NumberPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","typeInstance","type","Integer","groupingEnabled","Float","minFractionDigits","scale","undefined","maxFractionDigits","Input","value","path","model","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","input","binding","getBinding","applyState","setEditable","setRequired","__exports","__esModule"],"sources":["NumberPlugin.ts"],"sourcesContent":["/**\n * @file NumberPlugin.ts\n * @description Renders a sap.m.Input configured for generic dynamic numeric data.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport Float from \"sap/ui/model/type/Float\";\nimport Integer from \"sap/ui/model/type/Integer\";\n\n/**\n * Handles rendering and logic for dynamic numeric inputs.\n */\nexport class NumberPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Input` component for numeric evaluation with dynamic Float type.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Input control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n let typeInstance;\n if (fieldMetadata.type === \"integer\") {\n typeInstance = new Integer({ groupingEnabled: false });\n } else {\n typeInstance = new Float({\n groupingEnabled: false,\n minFractionDigits: fieldMetadata.scale !== undefined ? fieldMetadata.scale : 0,\n maxFractionDigits: fieldMetadata.scale !== undefined ? fieldMetadata.scale : 9\n });\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: {\n path: bindingPath,\n model: modelName,\n type: typeInstance\n },\n type: \"Number\",\n editable: !fieldMetadata.ui?.readOnly,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current numeric state.\n * @returns {unknown} The numeric value.\n */\n protected getValue(): unknown {\n if (!this.control) return null;\n // In UI5, Input.getValue() returns a string. We must parse it if it's bound.\n // However, we can also extract it directly from the binding.\n const input = this.control as Input;\n const binding = input.getBinding(\"value\");\n if (binding) {\n return binding.getValue();\n }\n return input.getValue();\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,gNAAA,MAKSA,EAAUC,EAAA,cAWZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAClBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEA,IAAIO,EACJ,GAAIlB,EAAcmB,OAAS,UAAW,CAClCD,EAAe,IAAIE,EAAQ,CAAEC,gBAAiB,OAClD,KAAO,CACHH,EAAe,IAAII,EAAM,CACrBD,gBAAiB,MACjBE,kBAAmBvB,EAAcwB,QAAUC,UAAYzB,EAAcwB,MAAQ,EAC7EE,kBAAmB1B,EAAcwB,QAAUC,UAAYzB,EAAcwB,MAAQ,GAErF,CAEAnB,KAAKM,QAAU,IAAIgB,EAAM,CACrBd,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzC2B,MAAO,CACHC,KAAM5B,EACN6B,MAAO5B,EACPiB,KAAMD,GAEVC,KAAM,SACNY,UAAW/B,EAAcgC,IAAIC,SAC7BC,WAAYlC,EAAckC,SAC1BC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,SAChC,MAAMC,EAASlC,KAAKmC,8BACpB,GAAInC,KAAKD,SAAU,CACfC,KAAKD,SAASmC,EAAOE,QAASpC,KAAKE,SACvC,KAIRF,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMU+B,WACN,IAAKrC,KAAKM,QAAS,OAAO,KAG1B,MAAMgC,EAAQtC,KAAKM,QACnB,MAAMiC,EAAUD,EAAME,WAAW,SACjC,GAAID,EAAS,CACT,OAAOA,EAAQF,UACnB,CACA,OAAOC,EAAMD,UACjB,CAKUI,aACN,GAAIzC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAMiC,EAAQtC,KAAKM,QACnBgC,EAAMI,aAAa1C,KAAKC,SAAS0B,IAAIC,UACrCU,EAAMK,cAAc3C,KAAKC,SAAS4B,SACtC,CACJ,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAAnD,eAAA,OAAAmD,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":64,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","ObjectPlugin","render","field","bindingPath","modelName","engineScopeId","onChange","this","metadata","propKey","startsWith","substring","subSchema","type","title","ui","label","properties","uiLayout","control","Button","id","generateStableId","text","isEditable","icon","press","oEvent","btn","getSource","parentModel","getModel","bindingContext","getBindingContext","updatePath","ctxPath","getPath","endsWith","nestedData","JSON","parse","stringify","getProperty","sap","require","DynamicHost","host","schemaDefinition","data","editable","attachSubmit","e","payload","getParameter","setProperty","buttonText","dialogButtonText","openInDialog","validate","isValid","getValue","applyState","__exports","__esModule"],"sources":["ObjectPlugin.ts"],"sourcesContent":["/**\n * @file ObjectPlugin.ts\n * @description Renders a button that opens a dialog to edit a nested object structure.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPluginValidationResult } from \"../../interfaces/IPlugin\";\nimport { ISchema, IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport Event from \"sap/ui/base/Event\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\n\nexport class ObjectPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Button` to open a nested Object form dialog.\n * \n * @param field The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Button control.\n */\n public render(field: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = field;\n const propKey = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n \n const subSchema: ISchema = {\n type: \"object\",\n title: field.ui?.label || propKey,\n properties: field.properties || {}\n };\n \n if (field.uiLayout) {\n subSchema.uiLayout = field.uiLayout;\n }\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? \"View Details\" : \"Edit Details\",\n icon: !this.isEditable ? \"sap-icon://display\" : \"sap-icon://form\",\n press: (oEvent: Event) => {\n const btn = oEvent.getSource() as Button;\n const parentModel = btn.getModel(modelName) as JSONModel;\n if (!parentModel) return;\n \n const bindingContext = btn.getBindingContext(modelName);\n let updatePath = bindingPath;\n if (bindingContext && !bindingPath.startsWith(\"/\")) {\n const ctxPath = bindingContext.getPath();\n updatePath = ctxPath.endsWith(\"/\") ? ctxPath + bindingPath : (ctxPath === \"/\" ? \"/\" + bindingPath : ctxPath + \"/\" + bindingPath);\n }\n \n // Deep clone to prevent live-mutations on the parent model before 'Submit' is clicked\n const nestedData = JSON.parse(JSON.stringify(parentModel.getProperty(updatePath) || {}));\n\n sap.ui.require([\"nz/co/siliconst/ui5/metaui/controls/DynamicHost\"], (DynamicHost: typeof import(\"../../controls/DynamicHost\").default) => {\n const host = new DynamicHost({\n schemaDefinition: subSchema,\n data: nestedData,\n editable: this.isEditable\n });\n\n if (!!this.isEditable) {\n host.attachSubmit((e: Event) => {\n const payload = (e.getParameter(\"payload\") as unknown);\n parentModel.setProperty(updatePath, payload);\n \n // CRITICAL: Notify the parent Engine that this field mutated\n // so it can trigger LiveUpdate syncs and validate!\n if (this.onChange) {\n this.onChange(true, propKey);\n }\n });\n }\n\n const buttonText = field.ui?.dialogButtonText || (!this.isEditable ? \"Close\" : \"OK\");\n host.openInDialog(`Nested Details: ${field.ui?.label || propKey}`, buttonText);\n });\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Validates the object plugin (always true as validation is deferred to the dialog host).\n * @returns {IPluginValidationResult} The validation result.\n */\n public validate(): IPluginValidationResult {\n return { isValid: true };\n }\n\n /**\n * Read-only component for the engine, returns null.\n */\n protected getValue(): null {\n return null;\n }\n\n /**\n * Read-only component, no dynamic state handling needed for the button itself.\n */\n protected applyState(): void {\n // No dynamic state handling needed for the button\n }\n}\n"],"mappings":"AAAA,wIAAA,MAKSA,EAAUC,EAAA,cAQZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAA2BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAC/GC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChB,MAAMO,EAAUN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,MAAMS,EAAqB,CACvBC,KAAM,SACNC,MAAOZ,EAAMa,IAAIC,OAASP,EAC1BQ,WAAYf,EAAMe,YAAc,CAAC,GAGrC,GAAIf,EAAMgB,SAAU,CAChBN,EAAUM,SAAWhB,EAAMgB,QAC/B,CAEAX,KAAKY,QAAU,IAAIC,EAAO,CACtBC,GAAId,KAAKe,iBAAiBjB,EAAeF,GACzCoB,MAAOhB,KAAKiB,WAAa,eAAiB,eAC1CC,MAAOlB,KAAKiB,WAAa,qBAAuB,kBAChDE,MAAQC,IACJ,MAAMC,EAAMD,EAAOE,YACnB,MAAMC,EAAcF,EAAIG,SAAS3B,GACjC,IAAK0B,EAAa,OAElB,MAAME,EAAiBJ,EAAIK,kBAAkB7B,GAC7C,IAAI8B,EAAa/B,EACjB,GAAI6B,IAAmB7B,EAAYO,WAAW,KAAM,CAChD,MAAMyB,EAAUH,EAAeI,UAC/BF,EAAaC,EAAQE,SAAS,KAAOF,EAAUhC,EAAegC,IAAY,IAAM,IAAMhC,EAAcgC,EAAU,IAAMhC,CACxH,CAGA,MAAMmC,EAAaC,KAAKC,MAAMD,KAAKE,UAAUX,EAAYY,YAAYR,IAAe,CAAC,IAErFS,IAAI5B,GAAG6B,QAAQ,CAAC,mDAAqDC,IACjE,MAAMC,EAAO,IAAID,EAAY,CACzBE,iBAAkBnC,EAClBoC,KAAMV,EACNW,SAAU1C,KAAKiB,aAGnB,KAAMjB,KAAKiB,WAAY,CACnBsB,EAAKI,aAAcC,IACf,MAAMC,EAAWD,EAAEE,aAAa,WAChCvB,EAAYwB,YAAYpB,EAAYkB,GAIpC,GAAI7C,KAAKD,SAAU,CACfC,KAAKD,SAAS,KAAMG,EACxB,GAER,CAEA,MAAM8C,EAAarD,EAAMa,IAAIyC,oBAAsBjD,KAAKiB,WAAa,QAAU,MAC/EsB,EAAKW,aAAa,mBAAmBvD,EAAMa,IAAIC,OAASP,IAAW8C,QAK/E,OAAOhD,KAAKY,OAChB,CAMOuC,WACH,MAAO,CAAEC,QAAS,KACtB,CAKUC,WACN,OAAO,IACX,CAKUC,aACN,EAEP,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA9D,eAAA,OAAA8D,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":65,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","PasswordPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","applyCommonDirectives","Input","value","generateBindingInfo","type","maxLength","required","change","oEvent","result","validateAndApplyVisualState","isValid","getValue","getMetadata","getName","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["PasswordPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\nexport class PasswordPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\");\n \n if (!this.isEditable) {\n // Password in read-only should be masked natively\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: \"********\" \n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: \"Password\",\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) this.onChange(result.isValid, this.fieldKey);\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return this.control && this.control.getMetadata().getName() === \"sap.m.Input\" ? (this.control as Input).getValue() : null;\n }\n\n protected applyState(): void {\n if (!this.control || !this.metadata || this.control.getMetadata().getName() !== \"sap.m.Input\") return;\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n}\n"],"mappings":"AAAA,8JAASA,EAAUC,EAAA,cAMZ,MAAMC,UAAuBF,EACzBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAElBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAM,aAEVT,KAAKU,sBAAsBV,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIM,EAAM,CACrBJ,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCgB,MAAOZ,KAAKa,oBAAoBjB,EAAaC,GAC7CiB,KAAM,WACNC,UAAWpB,EAAcoB,WAAa,EACtCC,WAAYrB,EAAcqB,SAC1BC,OAASC,IACL,MAAMC,EAASnB,KAAKoB,8BACpB,GAAIpB,KAAKD,SAAUC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKE,aAI9DF,KAAKU,sBAAsBV,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEUiB,WACN,OAAOtB,KAAKK,SAAWL,KAAKK,QAAQkB,cAAcC,YAAc,cAAiBxB,KAAKK,QAAkBiB,WAAa,IACzH,CAEUG,aACN,IAAKzB,KAAKK,UAAYL,KAAKC,UAAYD,KAAKK,QAAQkB,cAAcC,YAAc,cAAe,OAC/F,MAAME,EAAQ1B,KAAKK,QACnBqB,EAAMC,aAAa3B,KAAKC,SAAS2B,IAAIC,UACrCH,EAAMI,cAAc9B,KAAKC,SAASe,SACtC,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAAtC,iBAAA,OAAAsC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":66,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","RatingIndicatorPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","RatingIndicator","value","enabled","ui","readOnly","maxValue","maximum","undefined","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["RatingIndicatorPlugin.ts"],"sourcesContent":["/**\n * @file RatingIndicatorPlugin.ts\n * @description Renders a sap.m.RatingIndicator for 1-5 numeric feedback.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport RatingIndicator from \"sap/m/RatingIndicator\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for rating feedback.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class RatingIndicatorPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.RatingIndicator` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured RatingIndicator control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n this.control = new RatingIndicator({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n maxValue: fieldMetadata.maximum !== undefined ? fieldMetadata.maximum : 5,\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current rating value.\n * @returns {unknown} The rating value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as RatingIndicator).getValue() : 0;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as RatingIndicator).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,yKAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA8BF,EAWhCG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIO,EAAgB,CAC/BL,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCkB,MAAOd,KAAKW,oBAAoBf,EAAaC,GAC7CkB,SAAUpB,EAAcqB,IAAIC,SAC5BC,SAAUvB,EAAcwB,UAAYC,UAAYzB,EAAcwB,QAAU,EACxEE,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,SAChC,MAAMC,EAASzB,KAAK0B,8BACpB,GAAI1B,KAAKD,SAAU,CACfC,KAAKD,SAAS0B,EAAOE,QAAS3B,KAAKE,SACvC,KAIRF,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUsB,WACN,OAAO5B,KAAKM,QAAWN,KAAKM,QAA4BsB,WAAa,CACzE,CAKUC,aACN,GAAI7B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAA4BwB,YAAY9B,KAAKC,SAASe,IAAIC,SACpE,CACJ,EACH,IAAAc,EAAA,CAAAC,WAAA,MAAAD,EAAAtC,wBAAA,OAAAsC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":67,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","GlobalPipeline","____core_PipelineManager","ReferencePlugin","findParentHost","control","parent","getParent","getSchemaDefinition","render","field","bindingPath","modelName","engineScopeId","onChange","this","metadata","propKey","startsWith","substring","label","ui","Button","id","generateStableId","text","isEditable","icon","press","oEvent","btn","getSource","$ref","Logger","error","parentHost","subSchema","getProperty","parentModel","getModel","bindingContext","getBindingContext","updatePath","ctxPath","getPath","endsWith","rawData","nestedData","JSON","parse","stringify","sap","require","DynamicHostModule","DynamicHostClass","default","host","schemaDefinition","schemaDefinitions","data","editable","useMessageManager","attachEvent","e","fireEvent","getParameters","attachSubmit","payload","getParameter","setProperty","buttonText","dialogButtonText","openInDialog","undefined","message","validate","isValid","properties","getAbsoluteBindingPath","key","Object","keys","propMeta","val","required","errMsg","setVisualValidationState","errorMessage","validatorsToRun","argsMap","minLength","maxLength","push","min","max","pattern","regex","minimum","maximum","format","length","res","executeValidation","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["ReferencePlugin.ts"],"sourcesContent":["/**\n * @file ReferencePlugin.ts\n * @description Renders a button that lazily loads a referenced schema definition from the global dictionary\n * and opens it in a nested dialog. Implements headless validation for the deferred schema.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPluginValidationResult } from \"../../interfaces/IPlugin\";\nimport { ISchema, IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport Event from \"sap/ui/base/Event\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport { GlobalPipeline } from \"../../core/PipelineManager\";\n\nexport class ReferencePlugin extends BasePlugin {\n /**\n * Finds the closest GeneratorHost in the control hierarchy.\n */\n private findParentHost(control: Control): unknown {\n let parent = control.getParent();\n while (parent) {\n if (typeof (parent as any).getSchemaDefinition === \"function\") {\n return parent;\n }\n parent = parent.getParent();\n }\n return null;\n }\n\n public render(field: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = field;\n const propKey = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n const label = field.ui?.label || propKey;\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? `View Link: ${label}` : `Edit Link: ${label}`,\n icon: \"sap-icon://chain-link\",\n press: (oEvent: Event) => {\n const btn = oEvent.getSource() as Button;\n if (!this.metadata?.$ref) {\n Logger.error(`[ReferencePlugin] FATAL: this.metadata.$ref is MISSING or UNDEFINED! Cannot resolve child schema.`);\n return;\n }\n \n const parentHost = this.findParentHost(btn);\n if (!parentHost) {\n Logger.error(\"[ReferencePlugin] FATAL: Could not locate parent GeneratorHost via duck typing `getSchemaDefinition`.\");\n return;\n }\n\n const subSchema = parentHost.getSchemaDefinition(this.metadata.$ref);\n if (!subSchema) {\n Logger.error(`[ReferencePlugin] FATAL: Schema definition not found for reference: ${this.metadata.$ref}. Dumping parent schemaDefinitions:`, parentHost.getProperty(\"schemaDefinitions\"));\n return;\n }\n\n const parentModel = btn.getModel(modelName) as JSONModel;\n if (!parentModel) {\n Logger.error(`[ReferencePlugin] FATAL: Could not get JSONModel named '${modelName}' from the button.`);\n return;\n }\n \n const bindingContext = btn.getBindingContext(modelName);\n let updatePath = bindingPath;\n if (bindingContext && !bindingPath.startsWith(\"/\")) {\n const ctxPath = bindingContext.getPath();\n updatePath = ctxPath.endsWith(\"/\") ? ctxPath + bindingPath : (ctxPath === \"/\" ? \"/\" + bindingPath : ctxPath + \"/\" + bindingPath);\n }\n \n const rawData = parentModel.getProperty(updatePath);\n const nestedData = rawData ? JSON.parse(JSON.stringify(rawData)) : {};\n\n sap.ui.require([\"nz/co/siliconst/ui5/metaui/controls/DynamicHost\"], (DynamicHostModule: unknown) => {\n const DynamicHostClass = DynamicHostModule.default || DynamicHostModule;\n const host = new DynamicHostClass({\n schemaDefinition: subSchema,\n schemaDefinitions: parentHost.getProperty(\"schemaDefinitions\"), // Pass the dictionary down\n data: nestedData,\n editable: this.isEditable,\n useMessageManager: this.useMessageManager\n });\n\n // Event Piping: Bubble validation events up to the parent host\n host.attachEvent(\"validationError\", (e: Event) => {\n parentHost.fireEvent(\"validationError\", e.getParameters());\n });\n host.attachEvent(\"validationSuccess\", (e: Event) => {\n parentHost.fireEvent(\"validationSuccess\", e.getParameters());\n });\n\n if (!!this.isEditable) {\n host.attachSubmit((e: Event) => {\n const payload = (e.getParameter(\"payload\") as unknown);\n parentModel.setProperty(updatePath, payload);\n \n if (this.onChange) {\n this.onChange(true, propKey);\n }\n });\n }\n\n const buttonText = field.ui?.dialogButtonText || (!this.isEditable ? \"Close\" : \"OK\");\n try {\n host.openInDialog(`Nested Link: ${label}`, buttonText, undefined, undefined, btn);\n } catch (e) {\n Logger.error(`[ReferencePlugin] FATAL ERROR CALLING openInDialog:`, (e as Error).message);\n }\n });\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Headless validation: since child controls are not rendered, we manually validate the nested payload against the lazily resolved schema.\n */\n public validate(): IPluginValidationResult {\n if (!this.metadata?.$ref || !this.control) return { isValid: true };\n \n const parentHost = this.findParentHost(this.control);\n if (!parentHost) return { isValid: true };\n \n const subSchema = parentHost.getSchemaDefinition(this.metadata.$ref);\n if (!subSchema || !subSchema.properties) return { isValid: true };\n \n const parentModel = this.control.getModel(this.modelName) as JSONModel;\n if (!parentModel) return { isValid: true };\n \n let updatePath = this.getAbsoluteBindingPath();\n \n const nestedData = parentModel.getProperty(updatePath) || {};\n \n // Basic headless validation over the subSchema properties\n for (const key of Object.keys(subSchema.properties)) {\n const propMeta = subSchema.properties[key] as IPropertyMetadata;\n const val = nestedData[key];\n \n if (propMeta.required && (val === undefined || val === null || val === \"\")) {\n const errMsg = `Field '${key}' is required in referenced object.`;\n this.setVisualValidationState(false, errMsg);\n return { isValid: false, errorMessage: errMsg };\n }\n \n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {};\n\n if (propMeta.minLength !== undefined || propMeta.maxLength !== undefined) {\n validatorsToRun.push(\"length\");\n argsMap[\"length\"] = { min: propMeta.minLength, max: propMeta.maxLength };\n }\n if (propMeta.pattern !== undefined) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = { regex: propMeta.pattern };\n }\n if (propMeta.minimum !== undefined || propMeta.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: propMeta.minimum, max: propMeta.maximum };\n }\n \n const format = propMeta.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n \n if (validatorsToRun.length > 0) {\n const res = GlobalPipeline.executeValidation(val, validatorsToRun, argsMap);\n if (!res.isValid) {\n const errMsg = `Field '${key}' in reference: ${res.errorMessage}`;\n this.setVisualValidationState(false, errMsg);\n return { isValid: false, errorMessage: errMsg };\n }\n }\n }\n \n this.setVisualValidationState(true);\n return { isValid: true };\n }\n\n protected getValue(): null {\n return null;\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":68,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","RichTextControl","_interopRequireDefault","__RichTextControl","isValueAccessor","control","getValue","RichTextPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","FormattedTextControl","id","generateStableId","htmlText","generateBindingInfo","applyCommonDirectives","value","schemaMetadata","readOnly","ui","attachCapture","result","validateAndApplyVisualState","isValid","applyState","setProperty","__exports","__esModule"],"sources":["RichTextPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport RichTextControl from \"../../controls/RichTextControl\";\nimport FormattedTextControl from \"sap/m/FormattedText\";\n\ninterface IValueAccessor {\n getValue(): unknown;\n attachCapture?(fn: Function): void;\n}\n\nfunction isValueAccessor(control: unknown): control is IValueAccessor {\n return control !== null && typeof (control as IValueAccessor).getValue === 'function';\n}\n\nexport class RichTextPlugin extends BasePlugin {\n /**\n * Renders a `RichTextControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured RichTextControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new FormattedTextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n htmlText: this.generateBindingInfo(bindingPath, modelName)\n }) as Control;\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new RichTextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n }) as Control;\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n if (isValueAccessor(this.control) && this.control.attachCapture) {\n this.control.attachCapture(() => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n });\n }\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current HTML string value.\n * @returns {unknown} The string value.\n */\n protected getValue(): unknown {\n if (isValueAccessor(this.control)) {\n return this.control.getValue();\n }\n return null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,qRAASA,EAAUC,EAAA,oBAGZC,EAAeC,EAAAC,GAQtB,SAASC,EAAgBC,GACrB,OAAOA,IAAY,aAAgBA,EAA2BC,WAAa,UAC/E,CAEO,MAAMC,UAAuBR,EAWzBS,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKT,QAAU,IAAIa,EAAqB,CACpCC,GAAIL,KAAKM,iBAAiBR,EAAeF,GACzCW,SAAUP,KAAKQ,oBAAoBZ,EAAaC,KAEpDG,KAAKS,sBAAsBT,KAAKT,QAASI,EAAUE,GACnD,OAAOG,KAAKT,OAChB,CAEAS,KAAKT,QAAU,IAAIJ,EAAgB,CAC/BkB,GAAIL,KAAKM,iBAAiBR,EAAeF,GACzCc,MAAOV,KAAKQ,oBAAoBZ,EAAaC,GAC7Cc,eAAgBhB,EAChBiB,WAAYjB,EAASkB,IAAID,WAG7BZ,KAAKS,sBAAsBT,KAAKT,QAASI,EAAUE,GAEnD,GAAIP,EAAgBU,KAAKT,UAAYS,KAAKT,QAAQuB,cAAe,CAC7Dd,KAAKT,QAAQuB,cAAc,KACvB,MAAMC,EAASf,KAAKgB,8BACpB,GAAIhB,KAAKD,SAAU,CACfC,KAAKD,SAASgB,EAAOE,QAASjB,KAAKC,SACvC,GAER,CAEA,OAAOD,KAAKT,OAChB,CAMUC,WACN,GAAIF,EAAgBU,KAAKT,SAAU,CAC/B,OAAOS,KAAKT,QAAQC,UACxB,CACA,OAAO,IACX,CAKU0B,aACN,GAAIlB,KAAKT,SAAWS,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKT,QAAgC4B,YAAY,aAAcnB,KAAKL,SAASkB,IAAID,SACtF,CACJ,EACH,IAAAQ,EAAA,CAAAC,WAAA,MAAAD,EAAA3B,iBAAA,OAAA2B,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":69,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","SignatureControl","_interopRequireDefault","__SignatureControl","SignaturePlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","ImageControl","id","generateStableId","src","generateBindingInfo","width","alt","ui","label","applyCommonDirectives","value","schemaMetadata","readOnly","attachCapture","result","validateAndApplyVisualState","isValid","getValue","applyState","setProperty","__exports","__esModule"],"sources":["SignaturePlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport SignatureControl from \"../../controls/SignatureControl\";\nimport ImageControl from \"sap/m/Image\";\n\nexport class SignaturePlugin extends BasePlugin {\n /**\n * Renders a `SignatureControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured SignatureControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new ImageControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n src: this.generateBindingInfo(bindingPath, modelName),\n width: \"400px\",\n alt: metadata.ui?.label || \"Signature\"\n }) as Control;\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new SignatureControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n }) as Control;\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n (this.control as SignatureControl).attachCapture(() => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current base64 signature image state.\n * @returns {unknown} The signature image value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as SignatureControl).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,+QAASA,EAAUC,EAAA,oBAGZC,EAAgBC,EAAAC,GAGhB,MAAMC,UAAwBL,EAW1BM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAa,CAC5BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,IAAKR,KAAKS,oBAAoBb,EAAaC,GAC3Ca,MAAO,QACPC,IAAKhB,EAASiB,IAAIC,OAAS,cAE/Bb,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAiB,CAChCgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCmB,MAAOf,KAAKS,oBAAoBb,EAAaC,GAC7CmB,eAAgBrB,EAChBsB,WAAYtB,EAASiB,IAAIK,WAG7BjB,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GAElDG,KAAKI,QAA6Bc,cAAc,KAC7C,MAAMC,EAASnB,KAAKoB,8BAChB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SACvC,IAGR,OAAOD,KAAKI,OAChB,CAMUkB,WACN,OAAOtB,KAAKI,QAAWJ,KAAKI,QAA6BkB,WAAa,IAC1E,CAKUC,aACN,GAAIvB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCoB,YAAY,aAAcxB,KAAKL,SAASiB,IAAIK,SACtF,CACJ,EACH,IAAAQ,EAAA,CAAAC,WAAA,MAAAD,EAAAhC,kBAAA,OAAAgC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":70,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","SliderPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","Slider","value","enabled","ui","readOnly","min","minimum","undefined","max","maximum","step","multipleOf","enableTickmarks","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["SliderPlugin.ts"],"sourcesContent":["/**\n * @file SliderPlugin.ts\n * @description Renders a sap.m.Slider for picking numbers in a range.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Slider from \"sap/m/Slider\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for numeric sliders.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class SliderPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Slider` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Slider control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Slider({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n min: fieldMetadata.minimum !== undefined ? fieldMetadata.minimum : 0,\n max: fieldMetadata.maximum !== undefined ? fieldMetadata.maximum : 100,\n step: fieldMetadata.multipleOf !== undefined ? fieldMetadata.multipleOf : 1,\n enableTickmarks: true,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current slider value.\n * @returns {unknown} The numeric value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Slider).getValue() : 0;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as Slider).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,uJAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIO,EAAO,CACtBL,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCkB,MAAOd,KAAKW,oBAAoBf,EAAaC,GAC7CkB,SAAUpB,EAAcqB,IAAIC,SAC5BC,IAAKvB,EAAcwB,UAAYC,UAAYzB,EAAcwB,QAAU,EACnEE,IAAK1B,EAAc2B,UAAYF,UAAYzB,EAAc2B,QAAU,IACnEC,KAAM5B,EAAc6B,aAAeJ,UAAYzB,EAAc6B,WAAa,EAC1EC,gBAAiB,KACjBC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,SACvD,MAAMC,EAAS9B,KAAK+B,8BACpB,GAAI/B,KAAKD,SAAU,CACfC,KAAKD,SAAS+B,EAAOE,QAAShC,KAAKE,SACvC,KAIRF,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMU2B,WACN,OAAOjC,KAAKM,QAAWN,KAAKM,QAAmB2B,WAAa,CAChE,CAKUC,aACN,GAAIlC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAAmB6B,YAAYnC,KAAKC,SAASe,IAAIC,SAC3D,CACJ,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAA3C,eAAA,OAAA2C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":71,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","StepInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","StepInput","value","displayValuePrecision","scale","undefined","type","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","input","setEditable","setRequired","__exports","__esModule"],"sources":["StepInputPlugin.ts"],"sourcesContent":["/**\n * @file StepInputPlugin.ts\n * @description Renders a sap.m.StepInput for numeric data requiring step increments.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport StepInput from \"sap/m/StepInput\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for step-based numeric inputs.\n */\nexport class StepInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.StepInput` component for numeric evaluation.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured StepInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new StepInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n displayValuePrecision: fieldMetadata.scale !== undefined ? fieldMetadata.scale : (fieldMetadata.type === \"integer\" ? 0 : 3),\n editable: !fieldMetadata.ui?.readOnly,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = oEvent.getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current numeric state.\n * @returns {unknown} The numeric value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as StepInput).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as StepInput;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,6JAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAwBF,EAW1BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIO,EAAU,CACzBL,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCkB,MAAOd,KAAKW,oBAAoBf,EAAaC,GAC7CkB,sBAAuBpB,EAAcqB,QAAUC,UAAYtB,EAAcqB,MAASrB,EAAcuB,OAAS,UAAY,EAAI,EACzHC,UAAWxB,EAAcyB,IAAIC,SAC7BC,WAAY3B,EAAc2B,SAC1BC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,SAChC,MAAMC,EAAS3B,KAAK4B,8BACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SACvC,KAIRF,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUwB,WACN,OAAO9B,KAAKM,QAAWN,KAAKM,QAAsBwB,WAAa,IACnE,CAKUC,aACN,GAAI/B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM2B,EAAQhC,KAAKM,QACnB0B,EAAMC,aAAajC,KAAKC,SAASmB,IAAIC,UACrCW,EAAME,cAAclC,KAAKC,SAASqB,SACtC,CACJ,EACH,IAAAa,EAAA,CAAAC,WAAA,MAAAD,EAAA1C,kBAAA,OAAA0C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":72,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","StringPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","Input","value","maxLength","required","showValueHelp","ui","widget","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","input","setEditable","readOnly","setRequired","__exports","__esModule"],"sources":["StringPlugin.ts"],"sourcesContent":["/**\n * @file StringPlugin.ts\n * @description Renders a sap.m.Input for string data and validates lengths.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for basic text inputs.\n * Maps schema properties like `maxLength` and `required` natively to `sap.m.Input`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class StringPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Input` control configured via the provided schema metadata.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Input control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\"); // For EventBus\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n showValueHelp: fieldMetadata.ui?.widget === \"searchHelp\",\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current string value from the input.\n * @returns {unknown} The string value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Input).getValue() : null;\n }\n\n /**\n * Adjusts dynamic state properties (editable/required) based on ConditionEngine mutations.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) {\n // Text doesn't have editable/required state\n return;\n }\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,sJAAA,MAKSA,EAAUC,EAAA,cAaZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAElBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,KAEhDG,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIO,EAAM,CACrBL,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCiB,MAAOb,KAAKU,oBAAoBd,EAAaC,GAC7CiB,UAAWnB,EAAcmB,WAAa,EACtCC,WAAYpB,EAAcoB,SAC1BC,cAAerB,EAAcsB,IAAIC,SAAW,aAC5CC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,SACvD,MAAMC,EAASvB,KAAKwB,8BACpB,GAAIxB,KAAKD,SAAU,CACfC,KAAKD,SAASwB,EAAOE,QAASzB,KAAKE,SACvC,KAIRF,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GAExD,OAAOG,KAAKK,OAChB,CAMUqB,WACN,OAAO1B,KAAKK,QAAWL,KAAKK,QAAkBqB,WAAa,IAC/D,CAKUC,aACN,GAAI3B,KAAKK,SAAWL,KAAKC,SAAU,CAC/B,IAAKD,KAAKI,WAAY,CAElB,MACJ,CACA,MAAMwB,EAAQ5B,KAAKK,QACnBuB,EAAMC,aAAa7B,KAAKC,SAASgB,IAAIa,UACrCF,EAAMG,YAAY/B,KAAKC,SAASc,SACpC,CACJ,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAAvC,eAAA,OAAAuC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":73,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","SwitchPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","applyCommonDirectives","Switch","state","enabled","ui","readOnly","change","oEvent","getParameter","result","validateAndApplyVisualState","isValid","getValue","getState","applyState","sw","setEnabled","__exports","__esModule"],"sources":["SwitchPlugin.ts"],"sourcesContent":["/**\n * @file SwitchPlugin.ts\n * @description Renders a sap.m.Switch for boolean data specifically marked with the switch widget.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Switch from \"sap/m/Switch\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for toggleable boolean switches.\n */\nexport class SwitchPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Switch` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Switch control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: boolean) => val ? \"Yes\" : \"No\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Switch({\n id: this.generateStableId(engineScopeId, bindingPath),\n state: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"state\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current switch state.\n * @returns {unknown} The boolean state.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Switch).getState() : false;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const sw = this.control as Switch;\n sw.setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,uJAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAWe,UAAW,CAC9DC,UAAYC,GAAiBA,EAAM,MAAQ,SAGnDd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAO,CACtBR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,GAC7CqB,SAAUvB,EAAcwB,IAAIC,SAC5BC,OAASC,IACL,MAAMR,EAAOQ,EAA6BC,aAAa,SACvD,MAAMC,EAASxB,KAAKyB,8BACpB,GAAIzB,KAAKD,SAAU,CACfC,KAAKD,SAASyB,EAAOE,QAAS1B,KAAKE,SACvC,KAIRF,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUqB,WACN,OAAO3B,KAAKM,QAAWN,KAAKM,QAAmBsB,WAAa,KAChE,CAKUC,aACN,GAAI7B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAMyB,EAAK9B,KAAKM,QAChBwB,EAAGC,YAAY/B,KAAKC,SAASkB,IAAIC,SACrC,CACJ,EACH,IAAAY,EAAA,CAAAC,WAAA,MAAAD,EAAAvC,eAAA,OAAAuC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":74,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","TextAreaPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","TextArea","value","maxLength","required","rows","growing","change","oEvent","updateHeight","getSource","result","validateAndApplyVisualState","isValid","liveChange","attachEventOnce","oBinding","getBinding","initLogic","attachChange","oTextArea","val","getValue","numLines","split","length","wrappedLines","Math","ceil","totalLines","max","setRows","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["TextAreaPlugin.ts"],"sourcesContent":["/**\n * @file TextAreaPlugin.ts\n * @description Renders a sap.m.TextArea for string data specifically marked with the textArea widget.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport TextArea from \"sap/m/TextArea\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for multi-line text areas.\n */\nexport class TextAreaPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.TextArea` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured TextArea control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\"); // For EventBus\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new TextArea({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n rows: 3, // Start with at least 3 lines\n growing: false, // We manage height manually to maintain the +2 lines requirement\n change: (oEvent: sap.ui.base.Event) => {\n this.updateHeight(oEvent.getSource() as TextArea);\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n },\n liveChange: (oEvent: sap.ui.base.Event) => {\n this.updateHeight(oEvent.getSource() as TextArea);\n }\n });\n\n // Clean architecture: Wait for the model context, then calculate initial height\n (this.control as TextArea).attachEventOnce(\"modelContextChange\", () => {\n const oBinding = (this.control as TextArea).getBinding(\"value\");\n \n const initLogic = () => {\n if (this.control) {\n this.updateHeight(this.control as TextArea);\n }\n };\n\n if (oBinding) {\n oBinding.attachChange(initLogic);\n }\n // Execute immediately in case the model is synchronous (JSONModel)\n initLogic();\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Dynamically sets the rows to the content length + 2\n */\n private updateHeight(oTextArea: TextArea): void {\n const val = oTextArea.getValue() || \"\";\n // Count actual newlines in the string\n const numLines = val.split(/\\r\\n|\\r|\\n/).length;\n // Also estimate word wrapping if they type a really long single line without pressing enter\n // A standard character width approximation, assuming ~80 chars per line for full width\n const wrappedLines = Math.ceil(val.length / 80);\n \n const totalLines = Math.max(numLines, wrappedLines);\n \n // Ensure there is always 2 lines of extra breathing room\n oTextArea.setRows(Math.max(3, totalLines + 2));\n }\n\n /**\n * Retrieves the current text string.\n * @returns {unknown} The text string.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as TextArea).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as TextArea;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,2JAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAuBF,EAWzBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAElBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,KAEhDG,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIO,EAAS,CACxBL,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCiB,MAAOb,KAAKU,oBAAoBd,EAAaC,GAC7CiB,UAAWnB,EAAcmB,WAAa,EACtCC,WAAYpB,EAAcoB,SAC1BC,KAAM,EACNC,QAAS,MACTC,OAASC,IACLnB,KAAKoB,aAAaD,EAAOE,aACzB,MAAMC,EAAStB,KAAKuB,8BACpB,GAAIvB,KAAKD,SAAU,CACfC,KAAKD,SAASuB,EAAOE,QAASxB,KAAKE,SACvC,GAEJuB,WAAaN,IACTnB,KAAKoB,aAAaD,EAAOE,gBAKhCrB,KAAKK,QAAqBqB,gBAAgB,qBAAsB,KAC7D,MAAMC,EAAY3B,KAAKK,QAAqBuB,WAAW,SAEvD,MAAMC,EAAYA,KACd,GAAI7B,KAAKK,QAAS,CACdL,KAAKoB,aAAapB,KAAKK,QAC3B,GAGJ,GAAIsB,EAAU,CACVA,EAASG,aAAaD,EAC1B,CAEAA,MAGJ7B,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GAExD,OAAOG,KAAKK,OAChB,CAKQe,aAAaW,GACjB,MAAMC,EAAMD,EAAUE,YAAc,GAEpC,MAAMC,EAAWF,EAAIG,MAAM,cAAcC,OAGzC,MAAMC,EAAeC,KAAKC,KAAKP,EAAII,OAAS,IAE5C,MAAMI,EAAaF,KAAKG,IAAIP,EAAUG,GAGtCN,EAAUW,QAAQJ,KAAKG,IAAI,EAAGD,EAAa,GAC/C,CAMUP,WACN,OAAOjC,KAAKK,QAAWL,KAAKK,QAAqB4B,WAAa,IAClE,CAKUU,aACN,GAAI3C,KAAKK,SAAWL,KAAKC,SAAU,CAC/B,IAAKD,KAAKI,WAAY,OACtB,MAAMwC,EAAQ5C,KAAKK,QACnBuC,EAAMC,aAAa7C,KAAKC,SAAS6C,IAAIC,UACrCH,EAAMI,YAAYhD,KAAKC,SAASc,SACpC,CACJ,EACH,IAAAkC,EAAA,CAAAC,WAAA,MAAAD,EAAAxD,iBAAA,OAAAwD,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":75,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","TimePlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","formatOptions","source","pattern","applyCommonDirectives","TimePicker","value","displayFormat","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validateAndApplyVisualState","isValid","getValue","applyState","input","setEditable","setRequired","__exports","__esModule"],"sources":["TimePlugin.ts"],"sourcesContent":["/**\n * @file TimePlugin.ts\n * @description Handles rendering logic for Time strings.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport TimePicker from \"sap/m/TimePicker\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for time inputs.\n */\nexport class TimePlugin extends BasePlugin {\n /**\n * Renders a `sap.m.TimePicker` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured TimePicker control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Time\", {\n formatOptions: {\n source: { pattern: \"HH:mm:ss\" },\n pattern: \"HH:mm:ss\"\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new TimePicker({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Time\", {\n formatOptions: {\n source: { pattern: \"HH:mm:ss\" },\n pattern: \"HH:mm:ss\"\n }\n }),\n displayFormat: \"HH:mm:ss\",\n editable: !fieldMetadata.ui?.readOnly,\n required: fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"value\");\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current time string.\n * @returns {unknown} The time string.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as TimePicker).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as TimePicker;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,yJAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAmBF,EAWrBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC7Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,YACnBA,QAAS,gBAIrBd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAW,CAC1BR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC9Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,YACnBA,QAAS,cAGjBI,cAAe,WACfC,UAAWxB,EAAcyB,IAAIC,SAC7BC,SAAU3B,EAAc2B,SACxBC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,SACvD,MAAMC,EAAS3B,KAAK4B,8BACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SACvC,KAIRF,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUwB,WACN,OAAO9B,KAAKM,QAAWN,KAAKM,QAAuBwB,WAAa,IACpE,CAKUC,aACN,GAAI/B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM2B,EAAQhC,KAAKM,QACnB0B,EAAMC,aAAajC,KAAKC,SAASmB,IAAIC,UACrCW,EAAME,YAAYlC,KAAKC,SAASqB,SACpC,CACJ,EACH,IAAAa,EAAA,CAAAC,WAAA,MAAAD,EAAA1C,aAAA,OAAA0C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":76,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","VoiceInputControl","_interopRequireDefault","__VoiceInputControl","VoiceInputPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","applyCommonDirectives","value","schemaMetadata","readOnly","ui","attachCapture","result","validateAndApplyVisualState","isValid","getValue","applyState","setProperty","__exports","__esModule"],"sources":["VoiceInputPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport VoiceInputControl from \"../../controls/VoiceInputControl\";\nimport TextControl from \"sap/m/Text\";\n\nexport class VoiceInputPlugin extends BasePlugin {\n /**\n * Renders a `VoiceInputControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured VoiceInputControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: unknown) => {\n if (!val || val === \"undefined\" || val === \"null\") return \"\";\n return val;\n }\n })\n }) as Control;\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new VoiceInputControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n }) as Control;\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n (this.control as VoiceInputControl).attachCapture(() => {\n const result = this.validateAndApplyVisualState();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current voice transcription text.\n * @returns {unknown} The text string.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as VoiceInputControl).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,gRAASA,EAAUC,EAAA,oBAGZC,EAAiBC,EAAAC,GAGjB,MAAMC,UAAyBL,EAW3BM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAY,CAC3BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,KAAMR,KAAKS,oBAAoBb,EAAaC,EAAWa,UAAW,CAC9DC,UAAYC,IACR,IAAKA,GAAOA,IAAQ,aAAeA,IAAQ,OAAQ,MAAO,GAC1D,OAAOA,OAInBZ,KAAKa,sBAAsBb,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAkB,CACjCgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCkB,MAAOd,KAAKS,oBAAoBb,EAAaC,GAC7CkB,eAAgBpB,EAChBqB,WAAYrB,EAASsB,IAAID,WAG7BhB,KAAKa,sBAAsBb,KAAKI,QAAST,EAAUE,GAElDG,KAAKI,QAA8Bc,cAAc,KAC9C,MAAMC,EAASnB,KAAKoB,8BAChB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SACvC,IAGR,OAAOD,KAAKI,OAChB,CAMUkB,WACN,OAAOtB,KAAKI,QAAWJ,KAAKI,QAA8BkB,WAAa,IAC3E,CAKUC,aACN,GAAIvB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCoB,YAAY,aAAcxB,KAAKL,SAASsB,IAAID,SACtF,CACJ,EACH,IAAAS,EAAA,CAAAC,WAAA,MAAAD,EAAAhC,mBAAA,OAAAgC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":77,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","Logger","____utils_Logger","LiveSearchPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","input","Input","value","enabled","ui","readOnly","placeholder","showSuggestion","suggest","oEvent","query","getParameter","fetchSuggestions","change","validate","control","vhConfig","valueHelp","url","error","removeAllSuggestionItems","setBusy","fetch","then","res","json","data","keyPath","textPath","lowerQuery","toLowerCase","filteredData","filter","item","textValue","String","includes","forEach","itemData","addSuggestionItem","Item","key","text","catch","err","message","finally","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["LiveSearchPlugin.ts"],"sourcesContent":["/**\n * @file LiveSearchPlugin.ts\n * @description A custom datasource plugin that provides asynchronous live search (autocomplete) functionality.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata, IRemoteValueHelpConfig } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * A custom datasource plugin that provides asynchronous live search (autocomplete) functionality.\n * As the user types, it fetches suggestions from a remote endpoint.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class LiveSearchPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n const input = new Input({\n value: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: \"Type to search...\",\n showSuggestion: true,\n suggest: (oEvent: sap.ui.base.Event) => {\n const query = (oEvent as sap.ui.base.Event).getParameter(\"suggestValue\");\n this.fetchSuggestions(input, query);\n },\n change: (oEvent: sap.ui.base.Event) => {\n this.validate();\n }\n });\n\n this.control = input;\n return this.control as Control;\n }\n\n /**\n * Executes the REST fetch for suggestions based on a query. Can be overridden by mock subclasses.\n * @param input The UI5 Input to populate with suggestions.\n * @param query The text typed by the user.\n */\n protected fetchSuggestions(input: Input, query: string): void {\n const vhConfig = this.metadata?.valueHelp as IRemoteValueHelpConfig;\n if (!vhConfig || !vhConfig.url) {\n Logger.error(\"LiveSearchPlugin requires a valid valueHelp configuration with a URL.\", \"\", \"LiveSearchPlugin\");\n return;\n }\n\n if (!query) {\n input.removeAllSuggestionItems();\n return;\n }\n \n input.setBusy(true);\n \n // In a real application, the query parameter would be passed to the backend (e.g. ?q=query)\n // Here, we simulate fetching and filter locally, but subclasses can override this entirely.\n fetch(vhConfig.url)\n .then(res => res.json())\n .then((data: Record<string, unknown>[]) => {\n const keyPath = vhConfig.keyPath || \"key\";\n const textPath = vhConfig.textPath || \"text\";\n \n input.removeAllSuggestionItems();\n\n // Simple client-side filter for demonstration\n const lowerQuery = query.toLowerCase();\n const filteredData = data.filter(item => {\n const textValue = String(item[textPath] || item[keyPath]).toLowerCase();\n return textValue.includes(lowerQuery);\n });\n \n filteredData.forEach(itemData => {\n input.addSuggestionItem(new Item({ \n key: String(itemData[keyPath]), \n text: String(itemData[textPath] || itemData[keyPath])\n }));\n });\n })\n .catch(err => {\n Logger.error(\"Failed to load value help from \" + vhConfig.url, err.message, \"LiveSearchPlugin\");\n })\n .finally(() => {\n input.setBusy(false);\n });\n }\n\n /**\n * Retrieves the current input value.\n * @returns {unknown} The input text.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Input).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as Input).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,oMAAA,MAKSA,EAAUC,EAAA,oBAKVC,EAAMC,EAAA,UASR,MAAMC,UAAyBJ,EAC3BK,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,MAAMK,EAAQ,IAAIC,EAAM,CACpBC,MAAO,IAAIL,KAAaD,KACxBO,SAAUR,EAAcS,IAAIC,SAC5BC,YAAa,oBACbC,eAAgB,KAChBC,QAAUC,IACN,MAAMC,EAASD,EAA6BE,aAAa,gBACzDb,KAAKc,iBAAiBZ,EAAOU,IAEjCG,OAASJ,IACLX,KAAKgB,cAIbhB,KAAKiB,QAAUf,EACf,OAAOF,KAAKiB,OAChB,CAOUH,iBAAiBZ,EAAcU,GACrC,MAAMM,EAAWlB,KAAKC,UAAUkB,UAChC,IAAKD,IAAaA,EAASE,IAAK,CAC5B3B,EAAO4B,MAAM,wEAAyE,GAAI,oBAC1F,MACJ,CAEA,IAAKT,EAAO,CACRV,EAAMoB,2BACN,MACJ,CAEApB,EAAMqB,QAAQ,MAIdC,MAAMN,EAASE,KACVK,KAAKC,GAAOA,EAAIC,QAChBF,KAAMG,IACH,MAAMC,EAAUX,EAASW,SAAW,MACpC,MAAMC,EAAWZ,EAASY,UAAY,OAEtC5B,EAAMoB,2BAGN,MAAMS,EAAanB,EAAMoB,cACzB,MAAMC,EAAeL,EAAKM,OAAOC,IAC7B,MAAMC,EAAYC,OAAOF,EAAKL,IAAaK,EAAKN,IAAUG,cAC1D,OAAOI,EAAUE,SAASP,KAG9BE,EAAaM,QAAQC,IACjBtC,EAAMuC,kBAAkB,IAAIC,EAAK,CAC7BC,IAAKN,OAAOG,EAASX,IACrBe,KAAMP,OAAOG,EAASV,IAAaU,EAASX,WAIvDgB,MAAMC,IACHrD,EAAO4B,MAAM,kCAAoCH,EAASE,IAAK0B,EAAIC,QAAS,sBAE/EC,QAAQ,KACL9C,EAAMqB,QAAQ,QAE1B,CAMU0B,WACN,OAAOjD,KAAKiB,QAAWjB,KAAKiB,QAAkBgC,WAAa,IAC/D,CAKUC,aACN,GAAIlD,KAAKiB,SAAWjB,KAAKC,SAAU,CAC9BD,KAAKiB,QAAkBkC,YAAYnD,KAAKC,SAASK,IAAIC,SAC1D,CACJ,EACH,IAAA6C,EAAA,CAAAC,WAAA,MAAAD,EAAAzD,mBAAA,OAAAyD,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":78,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","ODataListBindingPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","args","ui","path","key","text","control","ComboBox","selectedKey","enabled","readOnly","placeholder","label","change","oEvent","val","getParameter","getKey","validate","bindAggregation","template","Item","templateShareable","getValue","getSelectedKey","applyState","setEnabled","__exports","__esModule"],"sources":["ODataListBindingPlugin.ts"],"sourcesContent":["/**\n * @file ODataListBindingPlugin.ts\n * @description A custom datasource plugin that binds a ComboBox to an OData EntitySet.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport ComboBox from \"sap/m/ComboBox\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Renders a ComboBox natively bound to an OData Model entity set.\n * Expects args: { path: \"/Categories\", key: \"ID\", text: \"Name\" }\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class ODataListBindingPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n const args = fieldMetadata.ui?.args || { path: \"/\", key: \"ID\", text: \"Name\" };\n \n this.control = new ComboBox({\n selectedKey: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Select...\",\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"selectedItem\")?.getKey();\n this.validate();\n }\n });\n\n // Natively bind aggregation to the default model (OData)\n (this.control as ComboBox).bindAggregation(\"items\", {\n path: args.path,\n template: new Item({\n key: `{${args.key}}`,\n text: `{${args.text}}`\n }),\n templateShareable: false\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as ComboBox).getSelectedKey() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as ComboBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,sLAAA,MAKSA,EAAUC,EAAA,cAaZ,MAAMC,UAA+BF,EACjCG,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,MAAMK,EAAOL,EAAcM,IAAID,MAAQ,CAAEE,KAAM,IAAKC,IAAK,KAAMC,KAAM,QAErEN,KAAKO,QAAU,IAAIC,EAAS,CACxBC,YAAa,IAAIV,KAAaD,KAC9BY,SAAUb,EAAcM,IAAIQ,SAC5BC,YAAaf,EAAcM,IAAIU,OAAS,YACxCC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,iBAAiBC,SACxElB,KAAKmB,cAKZnB,KAAKO,QAAqBa,gBAAgB,QAAS,CAChDhB,KAAMF,EAAKE,KACXiB,SAAU,IAAIC,EAAK,CACfjB,IAAK,IAAIH,EAAKG,OACdC,KAAM,IAAIJ,EAAKI,UAEnBiB,kBAAmB,QAGvB,OAAOvB,KAAKO,OAChB,CAMUiB,WACN,OAAOxB,KAAKO,QAAWP,KAAKO,QAAqBkB,iBAAmB,IACxE,CAKUC,aACN,GAAI1B,KAAKO,SAAWP,KAAKC,SAAU,CAC9BD,KAAKO,QAAqBoB,YAAY3B,KAAKC,SAASE,IAAIQ,SAC7D,CACJ,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAAjC,yBAAA,OAAAiC,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":79,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","Logger","____utils_Logger","RemoteDropdownPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","config","valueHelp","url","warn","sap","m","Text","text","isEditable","ui","requireSync","TextControl","require","control","id","generateStableId","applyCommonDirectives","select","Select","selectedKey","enabled","readOnly","forceSelection","busy","change","oEvent","result","validate","isValid","fieldKey","addItem","Item","key","fetch","then","res","ok","Error","status","json","data","arr","Array","isArray","value","forEach","item","k","keyPath","t","textPath","String","setBusy","catch","err","error","message","getValue","getSelectedKey","applyState","setEnabled","__exports","__esModule"],"sources":["RemoteDropdownPlugin.ts"],"sourcesContent":["/**\n * @file RemoteDropdownPlugin.ts\n * @description Renders a sap.m.Select that fetches valueHelp remotely via a JSON URL.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata, IRemoteValueHelpConfig } from \"../../interfaces/ISchema\";\nimport Select from \"sap/m/Select\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * Handles rendering logic for dropdown inputs fetching data remotely.\n * Maps a URL response array to `sap.ui.core.Item` elements.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class RemoteDropdownPlugin extends BasePlugin {\n \n /**\n * Renders a `Select` dropdown that fetches data remotely.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Select control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n\n const config = fieldMetadata.valueHelp as IRemoteValueHelpConfig;\n if (!config || !config.url) {\n Logger.warn(\"[MetaUI RemoteDropdownPlugin] No valid URL provided for remoteDropdown.\");\n return new sap.m.Text({ text: \"Error: No URL provided\" }) as Control;\n }\n \n if (!this.isEditable) {\n sap.ui.requireSync(\"sap/m/Text\");\n const TextControl = sap.ui.require(\"sap/m/Text\");\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: `{${modelName}>${bindingPath}}` // We might not have the text mapping synchronously\n });\n \n // Optionally, we could fetch data and update the text formatter here\n \n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n const select = new Select({\n id: this.generateStableId(engineScopeId, bindingPath),\n selectedKey: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n forceSelection: false,\n busy: true, // Show busy indicator while fetching\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey);\n }\n }\n });\n\n // Add empty placeholder\n select.addItem(new Item({ key: \"\", text: \"--- Select ---\" }));\n\n // Fetch data remotely\n fetch(config.url)\n .then(res => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n return res.json();\n })\n .then(data => {\n const arr = Array.isArray(data) ? data : (data.value || []);\n arr.forEach((item: Record<string, unknown>) => {\n const k = config.keyPath ? item[config.keyPath] : item;\n const t = config.textPath ? item[config.textPath] : item;\n select.addItem(new Item({ key: String(k), text: String(t) }));\n });\n select.setBusy(false);\n })\n .catch(err => {\n Logger.error(`[MetaUI RemoteDropdownPlugin] Failed to fetch remote data from ${config.url}`, err.message);\n select.addItem(new Item({ key: \"\", text: \"Error loading data\" }));\n select.setBusy(false);\n });\n\n this.control = select;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Select).getSelectedKey() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const select = this.control as Select;\n select.setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,yMAAA,MAKSA,EAAUC,EAAA,oBAKVC,EAAMC,EAAA,UASR,MAAMC,UAA6BJ,EAY/BK,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAEhB,MAAMO,EAASP,EAAcQ,UAC7B,IAAKD,IAAWA,EAAOE,IAAK,CACxBb,EAAOc,KAAK,2EACZ,OAAO,IAAIC,IAAIC,EAAEC,KAAK,CAAEC,KAAM,0BAClC,CAEA,IAAKT,KAAKU,WAAY,CAClBJ,IAAIK,GAAGC,YAAY,cACnB,MAAMC,EAAcP,IAAIK,GAAGG,QAAQ,cAEnCd,KAAKe,QAAU,IAAIF,EAAY,CAC3BG,GAAIhB,KAAKiB,iBAAiBnB,EAAeF,GACzCa,KAAM,IAAIZ,KAAaD,OAK3BI,KAAKkB,sBAAsBlB,KAAKe,QAASpB,EAAeE,GACxD,OAAOG,KAAKe,OAChB,CAEA,MAAMI,EAAS,IAAIC,EAAO,CACtBJ,GAAIhB,KAAKiB,iBAAiBnB,EAAeF,GACzCyB,YAAa,IAAIxB,KAAaD,KAC9B0B,SAAU3B,EAAcgB,IAAIY,SAC5BC,eAAgB,MAChBC,KAAM,KACNC,OAASC,IACL,MAAMC,EAAS5B,KAAK6B,WACpB,GAAI7B,KAAKD,SAAU,CACfC,KAAKD,SAAS6B,EAAOE,QAAS9B,KAAK+B,SACvC,KAKRZ,EAAOa,QAAQ,IAAIC,EAAK,CAAEC,IAAK,GAAIzB,KAAM,oBAGzC0B,MAAMjC,EAAOE,KACRgC,KAAKC,IACF,IAAKA,EAAIC,GAAI,MAAM,IAAIC,MAAM,QAAQF,EAAIG,UACzC,OAAOH,EAAII,SAEdL,KAAKM,IACF,MAAMC,EAAMC,MAAMC,QAAQH,GAAQA,EAAQA,EAAKI,OAAS,GACxDH,EAAII,QAASC,IACT,MAAMC,EAAI/C,EAAOgD,QAAUF,EAAK9C,EAAOgD,SAAWF,EAClD,MAAMG,EAAIjD,EAAOkD,SAAWJ,EAAK9C,EAAOkD,UAAYJ,EACpD7B,EAAOa,QAAQ,IAAIC,EAAK,CAAEC,IAAKmB,OAAOJ,GAAIxC,KAAM4C,OAAOF,QAE3DhC,EAAOmC,QAAQ,SAElBC,MAAMC,IACHjE,EAAOkE,MAAM,kEAAkEvD,EAAOE,MAAOoD,EAAIE,SACjGvC,EAAOa,QAAQ,IAAIC,EAAK,CAAEC,IAAK,GAAIzB,KAAM,wBACzCU,EAAOmC,QAAQ,SAGvBtD,KAAKe,QAAUI,EACfnB,KAAKkB,sBAAsBlB,KAAKe,QAASpB,EAAeE,GACxD,OAAOG,KAAKe,OAChB,CAMU4C,WACN,OAAO3D,KAAKe,QAAWf,KAAKe,QAAmB6C,iBAAmB,IACtE,CAKUC,aACN,GAAI7D,KAAKe,SAAWf,KAAKC,SAAU,CAC/B,IAAKD,KAAKU,WAAY,OACtB,MAAMS,EAASnB,KAAKe,QACpBI,EAAO2C,YAAY9D,KAAKC,SAASU,IAAIY,SACzC,CACJ,EACH,IAAAwC,EAAA,CAAAC,WAAA,MAAAD,EAAAtE,uBAAA,OAAAsE,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":80,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","Logger","____utils_Logger","RemoteValueHelpPlugin","isLoaded","render","fieldMetadata","bindingPath","modelName","this","metadata","comboBox","ComboBox","selectedKey","enabled","ui","readOnly","placeholder","change","oEvent","item","getParameter","val","getKey","validate","attachEventOnce","fetchData","control","vhConfig","valueHelp","url","error","setBusy","fetch","then","res","json","data","keyPath","textPath","forEach","itemData","addItem","Item","key","String","text","catch","err","message","finally","getValue","getSelectedKey","applyState","setEnabled","__exports","__esModule"],"sources":["RemoteValueHelpPlugin.ts"],"sourcesContent":["/**\n * @file RemoteValueHelpPlugin.ts\n * @description A custom datasource plugin that simulates fetching data from a remote server.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata, IRemoteValueHelpConfig } from \"../../interfaces/ISchema\";\nimport ComboBox from \"sap/m/ComboBox\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * A custom datasource plugin that simulates fetching data from a remote server.\n * Proves out custom data sources that dynamically load value help.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class RemoteValueHelpPlugin extends BasePlugin {\n private isLoaded = false;\n\n /**\n * Renders a `ComboBox` that simulates fetching data from a remote server.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @returns {Control} The configured ComboBox control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n const comboBox = new ComboBox({\n selectedKey: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: \"Select a country...\",\n change: (oEvent: sap.ui.base.Event) => {\n const item = (oEvent as sap.ui.base.Event).getParameter(\"selectedItem\");\n const val = item ? item.getKey() : (oEvent as sap.ui.base.Event).getParameter(\"value\"); // Allow free text as well\n this.validate();\n }\n });\n\n // Perform an async load against the REST endpoint\n comboBox.attachEventOnce(\"loadItems\", () => {\n this.fetchData(comboBox);\n });\n\n this.control = comboBox;\n return this.control as Control;\n }\n\n /**\n * Executes the REST fetch for data.\n * @param comboBox The UI5 ComboBox to populate.\n */\n protected fetchData(comboBox: ComboBox): void {\n const vhConfig = this.metadata?.valueHelp as IRemoteValueHelpConfig;\n if (!vhConfig || !vhConfig.url) {\n Logger.error(\"RemoteValueHelpPlugin requires a valid valueHelp configuration with a URL.\", \"\", \"RemoteValueHelpPlugin\");\n return;\n }\n \n comboBox.setBusy(true);\n \n fetch(vhConfig.url)\n .then(res => res.json())\n .then((data: Record<string, unknown>[]) => {\n const keyPath = vhConfig.keyPath || \"key\";\n const textPath = vhConfig.textPath || \"text\";\n \n data.forEach(itemData => {\n comboBox.addItem(new Item({ \n key: String(itemData[keyPath]), \n text: String(itemData[textPath] || itemData[keyPath])\n }));\n });\n })\n .catch(err => {\n Logger.error(\"Failed to load value help from \" + vhConfig.url, err.message, \"RemoteValueHelpPlugin\");\n })\n .finally(() => {\n comboBox.setBusy(false);\n this.isLoaded = true;\n });\n }\n\n /**\n * Retrieves the current selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as ComboBox).getSelectedKey() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as ComboBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,4MAAA,MAKSA,EAAUC,EAAA,oBAKVC,EAAMC,EAAA,UASR,MAAMC,UAA8BJ,EAC/BK,SAAW,MAUZC,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,MAAMK,EAAW,IAAIC,EAAS,CAC1BC,YAAa,IAAIL,KAAaD,KAC9BO,SAAUR,EAAcS,IAAIC,SAC5BC,YAAa,sBACbC,OAASC,IACL,MAAMC,EAAQD,EAA6BE,aAAa,gBACxD,MAAMC,EAAMF,EAAOA,EAAKG,SAAYJ,EAA6BE,aAAa,SAC9EZ,KAAKe,cAKbb,EAASc,gBAAgB,YAAa,KAClChB,KAAKiB,UAAUf,KAGnBF,KAAKkB,QAAUhB,EACf,OAAOF,KAAKkB,OAChB,CAMUD,UAAUf,GAChB,MAAMiB,EAAWnB,KAAKC,UAAUmB,UAChC,IAAKD,IAAaA,EAASE,IAAK,CAC5B7B,EAAO8B,MAAM,6EAA8E,GAAI,yBAC/F,MACJ,CAEApB,EAASqB,QAAQ,MAEjBC,MAAML,EAASE,KACVI,KAAKC,GAAOA,EAAIC,QAChBF,KAAMG,IACH,MAAMC,EAAUV,EAASU,SAAW,MACpC,MAAMC,EAAWX,EAASW,UAAY,OAEtCF,EAAKG,QAAQC,IACT9B,EAAS+B,QAAQ,IAAIC,EAAK,CACtBC,IAAKC,OAAOJ,EAASH,IACrBQ,KAAMD,OAAOJ,EAASF,IAAaE,EAASH,WAIvDS,MAAMC,IACH/C,EAAO8B,MAAM,kCAAoCH,EAASE,IAAKkB,EAAIC,QAAS,2BAE/EC,QAAQ,KACLvC,EAASqB,QAAQ,OACjBvB,KAAKL,SAAW,MAE5B,CAMU+C,WACN,OAAO1C,KAAKkB,QAAWlB,KAAKkB,QAAqByB,iBAAmB,IACxE,CAKUC,aACN,GAAI5C,KAAKkB,SAAWlB,KAAKC,SAAU,CAC9BD,KAAKkB,QAAqB2B,YAAY7C,KAAKC,SAASK,IAAIC,SAC7D,CACJ,EACH,IAAAuC,EAAA,CAAAC,WAAA,MAAAD,EAAApD,wBAAA,OAAAoD,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":81,"column":0},"map":{"version":3,"names":["CurrencyFormatterPlugin","constructor","this","currencyFormat","NumberFormat","getCurrencyInstance","showMeasure","format","rawValue","args","undefined","__exports","__esModule"],"sources":["CurrencyFormatterPlugin.ts"],"sourcesContent":["/**\n * @file CurrencyFormatterPlugin.ts\n * @description Standard data formatter for currency values.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\nimport NumberFormat from \"sap/ui/core/format/NumberFormat\";\n\n/**\n * Standard data formatter for currency values.\n * Uses sap.ui.core.format.NumberFormat to format raw numbers into localized currency strings.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class CurrencyFormatterPlugin implements IFormatter {\n private currencyFormat: NumberFormat;\n\n constructor() {\n this.currencyFormat = NumberFormat.getCurrencyInstance({\n showMeasure: false\n });\n }\n\n /**\n * Formats raw JSON model data into a UI-friendly currency string.\n * @param rawValue The raw numeric value from the JSON payload.\n * @returns The formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (rawValue === null || rawValue === undefined) {\n return \"\";\n }\n return \"$\" + this.currencyFormat.format(rawValue as number);\n }\n}\n"],"mappings":"AAAA,uJAeO,MAAMA,EAGTC,cACIC,KAAKC,eAAiBC,EAAaC,oBAAoB,CACnDC,YAAa,OAErB,CAOOC,OAAOC,EAAmBC,GAC7B,GAAID,IAAa,MAAQA,IAAaE,UAAW,CAC7C,MAAO,EACX,CACA,MAAO,IAAMR,KAAKC,eAAeI,OAAOC,EAC5C,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAX,0BAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":82,"column":0},"map":{"version":3,"names":["DateFormatterPlugin","constructor","this","dateFormat","DateFormat","getDateInstance","style","format","rawValue","args","dateObj","Date","e","__exports","__esModule"],"sources":["DateFormatterPlugin.ts"],"sourcesContent":["/**\n * @file DateFormatterPlugin.ts\n * @description Standard data formatter for dates.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\nimport DateFormat from \"sap/ui/core/format/DateFormat\";\n\n/**\n * Formats ISO date strings to localized Medium formats (e.g., \"Oct 15, 2026\").\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class DateFormatterPlugin implements IFormatter {\n private dateFormat: DateFormat;\n\n constructor() {\n this.dateFormat = DateFormat.getDateInstance({ style: \"medium\" });\n }\n\n /**\n * Formats raw JSON model data into a medium-style date string.\n * @param rawValue The raw date string.\n * @returns The formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (!rawValue) return \"\";\n try {\n const dateObj = new Date(rawValue as string);\n return this.dateFormat.format(dateObj);\n } catch (e) {\n return rawValue as string; // Fallback to raw string if invalid date\n }\n }\n}\n"],"mappings":"AAAA,iJAcO,MAAMA,EAGTC,cACIC,KAAKC,WAAaC,EAAWC,gBAAgB,CAAEC,MAAO,UAC1D,CAOOC,OAAOC,EAAmBC,GAC7B,IAAKD,EAAU,MAAO,GACtB,IACI,MAAME,EAAU,IAAIC,KAAKH,GACzB,OAAON,KAAKC,WAAWI,OAAOG,EAClC,CAAE,MAAOE,GACL,OAAOJ,CACX,CACJ,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAAb,sBAAA,OAAAa,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":83,"column":0},"map":{"version":3,"names":["PhoneFormatterPlugin","format","rawValue","args","String","cleaned","replace","match","__exports","__esModule"],"sources":["PhoneFormatterPlugin.ts"],"sourcesContent":["/**\n * @file PhoneFormatterPlugin.ts\n * @description Standard data formatter for phone numbers.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\n\n/**\n * Simple mask for 10-digit phone numbers (e.g. 5551234567 -> (555) 123-4567).\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class PhoneFormatterPlugin implements IFormatter {\n /**\n * Formats raw JSON model data into a masked phone number.\n * @param rawValue The raw phone string.\n * @returns The formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (!rawValue || typeof rawValue !== \"string\") return String(rawValue || \"\");\n \n const cleaned = ('' + rawValue).replace(/\\D/g, '');\n const match = cleaned.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n \n if (match) {\n return '(' + match[1] + ') ' + match[2] + '-' + match[3];\n }\n \n return rawValue as string;\n }\n}\n"],"mappings":"AAAA,kHAaO,MAAMA,EAMFC,OAAOC,EAAmBC,GAC7B,IAAKD,UAAmBA,IAAa,SAAU,OAAOE,OAAOF,GAAY,IAEzE,MAAMG,GAAW,GAAKH,GAAUI,QAAQ,MAAO,IAC/C,MAAMC,EAAQF,EAAQE,MAAM,2BAE5B,GAAIA,EAAO,CACP,MAAO,IAAMA,EAAM,GAAK,KAAOA,EAAM,GAAK,IAAMA,EAAM,EAC1D,CAEA,OAAOL,CACX,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAR,uBAAA,OAAAQ,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":84,"column":0},"map":{"version":3,"names":["TextCaseFormatterPlugin","format","rawValue","args","String","toUpperCase","__exports","__esModule"],"sources":["TextCaseFormatterPlugin.ts"],"sourcesContent":["/**\n * @file TextCaseFormatterPlugin.ts\n * @description Standard data formatter for text casing.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\n\n/**\n * Transforms text to UPPERCASE, lowercase, or Title Case.\n * Defaults to uppercase.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class TextCaseFormatterPlugin implements IFormatter {\n /**\n * Formats raw JSON model data into uppercase.\n * @param rawValue The raw string.\n * @returns The uppercase formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (typeof rawValue !== \"string\") return String(rawValue || \"\");\n \n // Default to uppercase if no specific arg could be easily parsed by simple formatter \n // (could be enhanced to support schema args if formatters allowed args).\n return rawValue.toUpperCase();\n }\n}\n"],"mappings":"AAAA,qHAcO,MAAMA,EAMFC,OAAOC,EAAmBC,GAC7B,UAAWD,IAAa,SAAU,OAAOE,OAAOF,GAAY,IAI5D,OAAOA,EAASG,aACpB,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAN,0BAAA,OAAAM,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":85,"column":0},"map":{"version":3,"names":["EmailValidatorPlugin","validate","parsedValue","args","isValid","emailRegex","test","errorMessage","__exports","__esModule"],"sources":["EmailValidatorPlugin.ts"],"sourcesContent":["/**\n * @file EmailValidatorPlugin.ts\n * @description Standard business logic validator for email addresses.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Standard business logic validator for email addresses.\n * Extracts the email regex validation logic into a standalone, modular plugin.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class EmailValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (typeof parsedValue !== \"string\" || !emailRegex.test(parsedValue)) {\n return { isValid: false, errorMessage: \"Please enter a valid email address.\" };\n }\n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,kHAcO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,MAAMC,EAAa,6BACnB,UAAWH,IAAgB,WAAaG,EAAWC,KAAKJ,GAAc,CAClE,MAAO,CAAEE,QAAS,MAAOG,aAAc,sCAC3C,CACA,MAAO,CAAEH,QAAS,KACtB,EACH,IAAAI,EAAA,CAAAC,WAAA,MAAAD,EAAAR,uBAAA,OAAAQ,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":86,"column":0},"map":{"version":3,"names":["IbanValidatorPlugin","validate","parsedValue","args","isValid","ibanRegex","test","replace","toUpperCase","errorMessage","__exports","__esModule"],"sources":["IbanValidatorPlugin.ts"],"sourcesContent":["/**\n * @file IbanValidatorPlugin.ts\n * @description Standard business logic validator for International Bank Account Numbers.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Validates a standard IBAN string.\n * This provides a simplified check for demonstration (starts with 2 chars, followed by digits/chars).\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class IbanValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n \n // Very basic IBAN structure regex (e.g. DE89370400440532013000)\n // A true IBAN check requires modulo 97 arithmetic which is out of scope for a basic mock.\n const ibanRegex = /^[A-Z]{2}\\d{2}[A-Z0-9]{1,30}$/;\n \n if (typeof parsedValue !== \"string\" || !ibanRegex.test(parsedValue.replace(/\\s+/g, '').toUpperCase())) {\n return { isValid: false, errorMessage: \"Please enter a valid IBAN.\" };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,iHAcO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MAIpC,MAAMC,EAAY,gCAElB,UAAWH,IAAgB,WAAaG,EAAUC,KAAKJ,EAAYK,QAAQ,OAAQ,IAAIC,eAAgB,CACnG,MAAO,CAAEJ,QAAS,MAAOK,aAAc,6BAC3C,CAEA,MAAO,CAAEL,QAAS,KACtB,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAV,sBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":87,"column":0},"map":{"version":3,"names":["MinLengthValidatorPlugin","validate","parsedValue","args","isValid","length","errorMessage","__exports","__esModule"],"sources":["MinLengthValidatorPlugin.ts"],"sourcesContent":["/**\n * @file MinLengthValidatorPlugin.ts\n * @description Standard business logic validator for string minimum lengths.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Ensures string length meets a minimum threshold.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class MinLengthValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n if (typeof args !== \"number\") return { isValid: true }; // Invalid config\n\n if (typeof parsedValue === \"string\" && parsedValue.length < args) {\n return { isValid: false, errorMessage: `Minimum length is ${args} characters.` };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,sHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,UAAWD,IAAS,SAAU,MAAO,CAAEC,QAAS,MAEhD,UAAWF,IAAgB,UAAYA,EAAYG,OAASF,EAAM,CAC9D,MAAO,CAAEC,QAAS,MAAOE,aAAc,qBAAqBH,gBAChE,CAEA,MAAO,CAAEC,QAAS,KACtB,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAP,2BAAA,OAAAO,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":88,"column":0},"map":{"version":3,"names":["PatternValidatorPlugin","validate","parsedValue","args","isValid","regex","RegExp","test","errorMessage","e","__exports","__esModule"],"sources":["PatternValidatorPlugin.ts"],"sourcesContent":["/**\n * @file PatternValidatorPlugin.ts\n * @description Standard business logic validator for Regex patterns.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Validates a string against a regular expression pattern provided in the schema args.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class PatternValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n if (typeof args !== \"string\") {\n return { isValid: true }; // Invalid config, skip\n }\n\n try {\n const regex = new RegExp(args);\n if (typeof parsedValue !== \"string\" || !regex.test(parsedValue)) {\n return { isValid: false, errorMessage: `Input does not match the required pattern.` };\n }\n } catch (e) {\n // Invalid regex string provided\n return { isValid: false, errorMessage: `Schema configuration error: Invalid regex pattern.` };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,oHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,UAAWD,IAAS,SAAU,CAC1B,MAAO,CAAEC,QAAS,KACtB,CAEA,IACI,MAAMC,EAAQ,IAAIC,OAAOH,GACzB,UAAWD,IAAgB,WAAaG,EAAME,KAAKL,GAAc,CAC7D,MAAO,CAAEE,QAAS,MAAOI,aAAc,6CAC3C,CACJ,CAAE,MAAOC,GAEL,MAAO,CAAEL,QAAS,MAAOI,aAAc,qDAC3C,CAEA,MAAO,CAAEJ,QAAS,KACtB,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAV,yBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":89,"column":0},"map":{"version":3,"names":["RangeValidatorPlugin","validate","parsedValue","args","undefined","isValid","rangeArgs","min","max","errorMessage","__exports","__esModule"],"sources":["RangeValidatorPlugin.ts"],"sourcesContent":["/**\n * @file RangeValidatorPlugin.ts\n * @description Standard business logic validator for numeric ranges.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Ensures a numeric value falls within an optionally provided min and max range.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class RangeValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (parsedValue === null || parsedValue === undefined) return { isValid: true }; \n if (typeof parsedValue !== \"number\") return { isValid: true };\n\n const rangeArgs = args as { min?: number, max?: number } | undefined;\n const min = rangeArgs?.min;\n const max = rangeArgs?.max;\n\n if (min !== undefined && typeof min === \"number\" && parsedValue < min) {\n return { isValid: false, errorMessage: `Value must be greater than or equal to ${min}.` };\n }\n\n if (max !== undefined && typeof max === \"number\" && parsedValue > max) {\n return { isValid: false, errorMessage: `Value must be less than or equal to ${max}.` };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,kHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,GAAID,IAAgB,MAAQA,IAAgBE,UAAW,MAAO,CAAEC,QAAS,MACzE,UAAWH,IAAgB,SAAU,MAAO,CAAEG,QAAS,MAEvD,MAAMC,EAAYH,EAClB,MAAMI,EAAMD,GAAWC,IACvB,MAAMC,EAAMF,GAAWE,IAEvB,GAAID,IAAQH,kBAAoBG,IAAQ,UAAYL,EAAcK,EAAK,CACnE,MAAO,CAAEF,QAAS,MAAOI,aAAc,0CAA0CF,KACrF,CAEA,GAAIC,IAAQJ,kBAAoBI,IAAQ,UAAYN,EAAcM,EAAK,CACnE,MAAO,CAAEH,QAAS,MAAOI,aAAc,uCAAuCD,KAClF,CAEA,MAAO,CAAEH,QAAS,KACtB,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAAV,uBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":90,"column":0},"map":{"version":3,"names":["UrlValidatorPlugin","validate","parsedValue","args","isValid","url","URL","protocol","errorMessage","e","__exports","__esModule"],"sources":["UrlValidatorPlugin.ts"],"sourcesContent":["/**\n * @file UrlValidatorPlugin.ts\n * @description Standard business logic validator for URL formats.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Ensures a string is a valid HTTP/HTTPS URL.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class UrlValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n if (typeof parsedValue !== \"string\") return { isValid: true };\n \n try {\n const url = new URL(parsedValue);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return { isValid: false, errorMessage: \"URL must use http or https protocol.\" };\n }\n } catch (e) {\n return { isValid: false, errorMessage: \"Please enter a valid URL.\" };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,gHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,UAAWF,IAAgB,SAAU,MAAO,CAAEE,QAAS,MAEvD,IACI,MAAMC,EAAM,IAAIC,IAAIJ,GACpB,GAAIG,EAAIE,WAAa,SAAWF,EAAIE,WAAa,SAAU,CACvD,MAAO,CAAEH,QAAS,MAAOI,aAAc,uCAC3C,CACJ,CAAE,MAAOC,GACL,MAAO,CAAEL,QAAS,MAAOI,aAAc,4BAC3C,CAEA,MAAO,CAAEJ,QAAS,KACtB,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAV,qBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":91,"column":0},"map":{"version":3,"names":["OpenApiExtractor","UI5Object","extend","extractTargets","rawSchema","aTargets","oSchema","openapi","startsWith","components","schemas","Object","keys","forEach","sKey","push","key","text","swagger","definitions","paths","sPath","methods","sMethod","escapedPath","replace","toUpperCase","length","bestScore","bestIndex","info","title","toLowerCase","titleWords","split","target","index","score","includes","name","pop","nameLower","nameClean","word","genericRoots","some","r","schemaDef","scoreSchemaNode","node","nodeObj","properties","values","prop","propObj","$ref","items","required","Array","isArray","allOf","anyOf","oneOf","primary","splice","unshift"],"sources":["OpenApiExtractor.ts"],"sourcesContent":["import UI5Object from \"sap/ui/base/Object\";\n\nexport interface OpenApiTarget {\n key: string;\n text: string;\n}\n\n/**\n * @class\n * OpenApiExtractor utility.\n * Dynamically crawls OpenAPI/Swagger JSON specifications to find all valid \n * root endpoints and schema definitions that can be used as a schemaTarget.\n * \n * @extends sap.ui.base.Object\n * @alias nz.co.siliconst.ui5.metaui.swagger.OpenApiExtractor\n */\nexport default class OpenApiExtractor extends UI5Object {\n\n /**\n * Parses an OpenAPI document and extracts an array of valid targets.\n * \n * @public\n * @param oSchema The parsed JSON schema object.\n * @returns Array of target bindings.\n */\n public static extractTargets(rawSchema: unknown): OpenApiTarget[] {\n const aTargets: OpenApiTarget[] = [];\n if (!rawSchema || typeof rawSchema !== \"object\") {\n return aTargets;\n }\n\n const oSchema = rawSchema as Record<string, unknown>;\n\n // OpenAPI 3.0 (components/schemas)\n if (typeof oSchema.openapi === \"string\" && oSchema.openapi.startsWith(\"3.\") && oSchema.components && typeof (oSchema.components as Record<string,unknown>).schemas === \"object\") {\n Object.keys((oSchema.components as Record<string,unknown>).schemas as Record<string,unknown>).forEach((sKey) => {\n aTargets.push({\n key: \"#/components/schemas/\" + sKey,\n text: \"Schema: \" + sKey\n });\n });\n }\n \n // Swagger 2.0 (definitions)\n if (typeof oSchema.swagger === \"string\" && oSchema.swagger.startsWith(\"2.\") && typeof oSchema.definitions === \"object\" && oSchema.definitions !== null) {\n Object.keys(oSchema.definitions as Record<string,unknown>).forEach((sKey) => {\n aTargets.push({\n key: \"#/definitions/\" + sKey,\n text: \"Definition: \" + sKey\n });\n });\n }\n\n // Extract endpoints\n if (typeof oSchema.paths === \"object\" && oSchema.paths !== null) {\n Object.keys(oSchema.paths as Record<string,unknown>).forEach((sPath) => {\n const methods = (oSchema.paths as Record<string,unknown>)[sPath];\n if (methods && typeof methods === \"object\") {\n Object.keys(methods).forEach((sMethod) => {\n const escapedPath = sPath.replace(/\\//g, \"~1\");\n aTargets.push({\n key: \"#/paths/\" + escapedPath + \"/\" + sMethod,\n text: \"Operation: \" + sMethod.toUpperCase() + \" \" + sPath\n });\n });\n }\n });\n }\n\n // Primary Schema Detection\n if (aTargets.length > 1) {\n let bestScore = -1;\n let bestIndex = -1;\n \n const info = oSchema.info as Record<string, unknown> | undefined;\n const title = (info && typeof info.title === \"string\") ? info.title.toLowerCase().replace(/[^a-z0-9]/g, \"\") : \"\";\n const titleWords = (info && typeof info.title === \"string\") ? info.title.toLowerCase().split(/[\\s_-]+/) : [];\n \n aTargets.forEach((target, index) => {\n let score = 0;\n \n // Only score Schemas/Definitions, not operations for the primary node heuristic\n if (target.key.includes(\"/schemas/\") || target.key.includes(\"/definitions/\")) {\n const name = target.key.split(\"/\").pop() || \"\";\n const nameLower = name.toLowerCase();\n const nameClean = nameLower.replace(/[^a-z0-9]/g, \"\");\n \n if (title && nameClean === title) score += 30; // Reduced from 100\n else if (title && title.includes(nameClean)) score += 15; // Reduced from 50\n else if (title && nameClean.includes(title)) score += 15; // Reduced from 50\n \n titleWords.forEach((word: string) => {\n if (word.length > 3 && nameLower.includes(word)) score += 5; // Reduced from 10\n });\n \n const genericRoots = [\"root\", \"main\", \"app\", \"application\", \"payload\", \"document\"];\n if (genericRoots.some(r => nameLower.includes(r))) score += 5;\n\n // Complexity Fallback\n let schemaDef: Record<string, unknown> | null = null;\n if (target.key.startsWith(\"#/components/schemas/\") && typeof oSchema.components === \"object\" && oSchema.components !== null) {\n const components = oSchema.components as Record<string, unknown>;\n if (typeof components.schemas === \"object\" && components.schemas !== null) {\n schemaDef = (components.schemas as Record<string, Record<string, unknown>>)[name] || null;\n }\n } else if (target.key.startsWith(\"#/definitions/\") && typeof oSchema.definitions === \"object\" && oSchema.definitions !== null) {\n schemaDef = (oSchema.definitions as Record<string, Record<string, unknown>>)[name] || null;\n }\n\n if (schemaDef && typeof schemaDef === \"object\") {\n const scoreSchemaNode = (node: unknown) => {\n if (!node || typeof node !== \"object\") return;\n const nodeObj = node as Record<string, unknown>;\n if (nodeObj.properties && typeof nodeObj.properties === \"object\") {\n score += Object.keys(nodeObj.properties).length * 2; // +2 per property\n Object.values(nodeObj.properties).forEach((prop: unknown) => {\n if (prop && typeof prop === \"object\") {\n const propObj = prop as Record<string, unknown>;\n if (propObj.$ref) score += 20; // +20 for referencing sub-schemas (aggregate root)\n if (propObj.items && typeof propObj.items === \"object\" && (propObj.items as Record<string, unknown>).$ref) score += 20;\n }\n });\n }\n \n if (nodeObj.required && Array.isArray(nodeObj.required)) {\n score += nodeObj.required.length * 5; // +5 per required constraint\n }\n };\n\n scoreSchemaNode(schemaDef);\n\n // Handle OpenAPI composition structures\n if (schemaDef.allOf && Array.isArray(schemaDef.allOf)) {\n schemaDef.allOf.forEach(scoreSchemaNode);\n }\n if (schemaDef.anyOf && Array.isArray(schemaDef.anyOf)) {\n schemaDef.anyOf.forEach(scoreSchemaNode);\n }\n if (schemaDef.oneOf && Array.isArray(schemaDef.oneOf)) {\n schemaDef.oneOf.forEach(scoreSchemaNode);\n }\n }\n }\n \n if (score > bestScore) {\n bestScore = score;\n bestIndex = index;\n }\n });\n\n if (bestIndex !== -1 && bestScore > 0) {\n const primary = aTargets.splice(bestIndex, 1)[0];\n primary.text = `(Recommended) ${primary.text}`;\n aTargets.unshift(primary);\n }\n }\n\n return aTargets;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"swagger"}},{"offset":{"line":92,"column":0},"map":{"version":3,"names":["ExpressionBuilder","build","rule","bindingPath","modelName","parsedRule","replace","match","path","reserved","includes","basePath","startsWith","substring","parts","split","pop","contextPrefix","length","join","__exports","__esModule"],"sources":["ExpressionBuilder.ts"],"sourcesContent":["/**\n * @file ExpressionBuilder.ts\n * @description Safely parses and builds UI5 expression bindings from JSON Schema condition rules.\n */\n\nexport class ExpressionBuilder {\n /**\n * Safely converts a raw condition rule (e.g. \"$root.Status === 'NEW'\") into a valid UI5 \n * expression binding string, preserving relative vs absolute paths.\n * \n * @param rule The raw schema condition rule (e.g., \"$root.Category === 'A' || SubCategory === 'B'\").\n * @param bindingPath The absolute binding path of the current field (e.g., \"/Items/0/Category\").\n * @param modelName The UI5 JSONModel name (default \"meta\").\n * @returns {string} The fully formed UI5 expression binding (e.g., \"{= ${meta>/Status} === 'NEW' }\").\n */\n public static build(rule: string, bindingPath: string, modelName: string = \"meta\"): string {\n if (!rule) return \"{= true }\";\n\n let parsedRule = rule;\n\n // 1. Replace absolute $root paths\n // $root.Status -> ${meta>/Status}\n parsedRule = parsedRule.replace(/\\$root\\.([a-zA-Z0-9_.]+)/g, (match, path) => {\n return `\\${${modelName}>/${path.replace(/\\./g, '/')}}`;\n });\n\n // 2. Replace relative paths\n parsedRule = parsedRule.replace(/(?<!['\"\\${a-zA-Z0-9_.>/-])([a-zA-Z_][a-zA-Z0-9_.]+)(?!['\"a-zA-Z0-9_.(])/g, (match, path) => {\n const reserved = [\"true\", \"false\", \"null\", \"undefined\", \"Math\", \"String\", \"Number\", \"Array\", \"Object\"];\n if (reserved.includes(path)) return path;\n\n // Resolve relative to the current binding path context\n let basePath = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n const parts = basePath.split('/');\n parts.pop(); \n const contextPrefix = parts.length > 0 ? parts.join('/') + '/' : '';\n \n return `\\${${modelName}>/${contextPrefix}${path.replace(/\\./g, '/')}}`;\n });\n\n return `{= ${parsedRule} }`;\n }\n}\n"],"mappings":"AAAA,kGAKO,MAAMA,EAUT,YAAcC,CAAMC,EAAcC,EAAqBC,EAAoB,QACvE,IAAKF,EAAM,MAAO,YAElB,IAAIG,EAAaH,EAIjBG,EAAaA,EAAWC,QAAQ,4BAA6B,CAACC,EAAOC,IAC1D,MAAMJ,MAAcI,EAAKF,QAAQ,MAAO,SAInDD,EAAaA,EAAWC,QAAQ,2EAA4E,CAACC,EAAOC,KAChH,MAAMC,EAAW,CAAC,OAAQ,QAAS,OAAQ,YAAa,OAAQ,SAAU,SAAU,QAAS,UAC7F,GAAIA,EAASC,SAASF,GAAO,OAAOA,EAGpC,IAAIG,EAAWR,EAAYS,WAAW,KAAOT,EAAYU,UAAU,GAAKV,EACxE,MAAMW,EAAQH,EAASI,MAAM,KAC7BD,EAAME,MACN,MAAMC,EAAgBH,EAAMI,OAAS,EAAIJ,EAAMK,KAAK,KAAO,IAAM,GAEjE,MAAO,MAAMf,MAAca,IAAgBT,EAAKF,QAAQ,MAAO,UAGnE,MAAO,MAAMD,KACjB,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAApB,oBAAA,OAAAoB,CAAA","ignoreList":[],"sourceRoot":"utils"}},{"offset":{"line":93,"column":0},"map":{"version":3,"names":["Logger","static","setDebugMode","enabled","this","debugMode","logInstance","sap","ui","require","Log","isDebugMode","debug","message","details","component","console","info","warn","warning","error","showErrorPopup","title","MessageBox","__exports","__esModule"],"sources":["Logger.ts"],"sourcesContent":["/**\n * @file Logger.ts\n * @description Centralized logging utility for MetaUI.\n * Wraps sap/base/Log and provides a global toggle for debug mode.\n */\n\nexport class Logger {\n private static debugMode: boolean = false;\n private static logInstance: unknown = null;\n\n /**\n * Toggles the global debug mode for MetaUI.\n * @param enabled Set to true to enable logging.\n */\n public static setDebugMode(enabled: boolean): void {\n this.debugMode = enabled;\n if (enabled && !this.logInstance) {\n sap.ui.require([\"sap/base/Log\"], (Log: Record<string, Function>) => {\n this.logInstance = Log;\n });\n }\n }\n\n /**\n * Checks if debug mode is currently active.\n */\n public static isDebugMode(): boolean {\n return this.debugMode;\n }\n\n public static debug(message: string, details?: string, component?: string): void {\n if (!this.debugMode) return;\n if (this.logInstance) {\n this.logInstance.debug(message, details, component || \"MetaUI\");\n } else {\n console.debug(`[MetaUI] ${message}`, details || \"\");\n }\n }\n\n public static info(message: string, details?: string, component?: string): void {\n if (!this.debugMode) return;\n if (this.logInstance) {\n this.logInstance.info(message, details, component || \"MetaUI\");\n } else {\n console.info(`[MetaUI] ${message}`, details || \"\");\n }\n }\n\n public static warn(message: string, details?: string, component?: string): void {\n if (!this.debugMode) return;\n if (this.logInstance) {\n this.logInstance.warning(message, details, component || \"MetaUI\");\n } else {\n console.warn(`[MetaUI] ${message}`, details || \"\");\n }\n }\n\n public static error(message: string, details?: string, component?: string): void {\n if (this.logInstance) {\n this.logInstance.error(message, details, component || \"MetaUI\");\n } else {\n console.error(`[MetaUI Error] ${message}`, details || \"\");\n }\n }\n\n /**\n * Pops up a MessageBox UI alert if debug mode is active.\n */\n public static showErrorPopup(message: string, title?: string): void {\n if (!this.debugMode) return;\n sap.ui.require([\"sap/m/MessageBox\"], (MessageBox: Record<string, Function>) => {\n (MessageBox as Record<string, Function>).error(message, { title: title || \"MetaUI Error\" });\n });\n }\n}\n"],"mappings":"AAAA,uFAMO,MAAMA,EACTC,iBAAoC,MACpCA,mBAAsC,KAMtC,mBAAcC,CAAaC,GACvBC,KAAKC,UAAYF,EACjB,GAAIA,IAAYC,KAAKE,YAAa,CAC9BC,IAAIC,GAAGC,QAAQ,CAAC,gBAAkBC,IAC9BN,KAAKE,YAAcI,GAE3B,CACJ,CAKA,kBAAcC,GACV,OAAOP,KAAKC,SAChB,CAEA,YAAcO,CAAMC,EAAiBC,EAAkBC,GACnD,IAAKX,KAAKC,UAAW,OACrB,GAAID,KAAKE,YAAa,CAClBF,KAAKE,YAAYM,MAAMC,EAASC,EAASC,GAAa,SAC1D,KAAO,CACHC,QAAQJ,MAAM,YAAYC,IAAWC,GAAW,GACpD,CACJ,CAEA,WAAcG,CAAKJ,EAAiBC,EAAkBC,GAClD,IAAKX,KAAKC,UAAW,OACrB,GAAID,KAAKE,YAAa,CAClBF,KAAKE,YAAYW,KAAKJ,EAASC,EAASC,GAAa,SACzD,KAAO,CACHC,QAAQC,KAAK,YAAYJ,IAAWC,GAAW,GACnD,CACJ,CAEA,WAAcI,CAAKL,EAAiBC,EAAkBC,GAClD,IAAKX,KAAKC,UAAW,OACrB,GAAID,KAAKE,YAAa,CAClBF,KAAKE,YAAYa,QAAQN,EAASC,EAASC,GAAa,SAC5D,KAAO,CACHC,QAAQE,KAAK,YAAYL,IAAWC,GAAW,GACnD,CACJ,CAEA,YAAcM,CAAMP,EAAiBC,EAAkBC,GACnD,GAAIX,KAAKE,YAAa,CAClBF,KAAKE,YAAYc,MAAMP,EAASC,EAASC,GAAa,SAC1D,KAAO,CACHC,QAAQI,MAAM,kBAAkBP,IAAWC,GAAW,GAC1D,CACJ,CAKA,qBAAcO,CAAeR,EAAiBS,GAC1C,IAAKlB,KAAKC,UAAW,OACrBE,IAAIC,GAAGC,QAAQ,CAAC,oBAAsBc,IACjCA,EAAwCH,MAAMP,EAAS,CAAES,MAAOA,GAAS,kBAElF,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAxB,SAAA,OAAAwB,CAAA","ignoreList":[],"sourceRoot":"utils"}},{"offset":{"line":94,"column":0},"map":{"version":3,"names":[],"sources":["library-preload.js?bundle-code-0"],"mappings":"AAAA;AACA","sourcesContent":["sap.ui.require.preload({\n"],"sourceRoot":""}},{"offset":{"line":96,"column":0},"map":{"version":3,"file":"ILayoutManager.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":99,"column":0},"map":{"version":3,"file":"IPipeline.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":102,"column":0},"map":{"version":3,"file":"IPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":105,"column":0},"map":{"version":3,"file":"ISchema.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":108,"column":0},"map":{"version":3,"file":"ISchemaBuilderPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":112,"column":0},"map":{"version":3,"file":"IHeuristicPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"openapi/heuristics/interfaces"}},{"offset":{"line":115,"column":0},"map":{"version":3,"file":"IOpenApiParserPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"openapi/interfaces"}}]}
1
+ {"version":3,"file":"library-preload.js","sections":[{"offset":{"line":1,"column":0},"map":{"version":3,"names":["MockLLMProxy","___MockLLMProxy","AIConfig","static","setProxy","proxy","this","activeProxy","getProxy","setEndpointUrl","url","endpointUrl","getEndpointUrl","__exports","__esModule"],"sources":["AIConfig.ts"],"sourcesContent":["/**\n * @file AIConfig.ts\n * @description Global configuration singleton for AI Inference integrations.\n */\nimport { BaseAIGenerator } from \"./BaseAIGenerator\";\nimport { MockLLMProxy } from \"./MockLLMProxy\";\n\nexport class AIConfig {\n private static activeProxy: BaseAIGenerator = new MockLLMProxy();\n private static endpointUrl: string = \"/api/mock/ai\";\n\n /**\n * Sets the active proxy instance (e.g. Mock vs Rest).\n */\n public static setProxy(proxy: BaseAIGenerator): void {\n this.activeProxy = proxy;\n }\n\n /**\n * Gets the current active proxy.\n */\n public static getProxy(): BaseAIGenerator {\n return this.activeProxy;\n }\n\n /**\n * Configures the remote URL for the REST LLM Proxy to hit.\n */\n public static setEndpointUrl(url: string): void {\n this.endpointUrl = url;\n }\n\n /**\n * Gets the configured remote URL.\n */\n public static getEndpointUrl(): string {\n return this.endpointUrl;\n }\n}\n"],"mappings":"AAAA,uGAAA,MAKSA,EAAYC,EAAA,gBAEd,MAAMC,EACTC,mBAA8C,IAAIH,EAClDG,mBAAqC,eAKrC,eAAcC,CAASC,GACnBC,KAAKC,YAAcF,CACvB,CAKA,eAAcG,GACV,OAAOF,KAAKC,WAChB,CAKA,qBAAcE,CAAeC,GACzBJ,KAAKK,YAAcD,CACvB,CAKA,qBAAcE,GACV,OAAON,KAAKK,WAChB,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAX,WAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":2,"column":0},"map":{"version":3,"names":["BaseAIGenerator","generateSchema","data","partialSchema","dataSkeleton","this","buildDataSkeleton","Object","keys","length","type","properties","llmGeneratedSchema","callLLM","deepMergeSchemas","skeleton","definedKeys","dataObj","key","includes","base","override","outTarget","output","assign","srcObj","forEach","Array","isArray","from","Set","__exports","__esModule"],"sources":["BaseAIGenerator.ts"],"sourcesContent":["/**\n * @file BaseAIGenerator.ts\n * @description Abstract base class defining the contract for AI Schema Generation Proxies.\n */\nimport { ISchema } from \"../interfaces/ISchema\";\n\nexport abstract class BaseAIGenerator {\n\n /**\n * Generates a schema dynamically for the provided data payload.\n * @param data The raw data to infer from.\n * @param partialSchema The manual overrides provided by the developer.\n * @returns A promise resolving to the final merged schema.\n */\n public async generateSchema(data: object, partialSchema?: ISchema): Promise<ISchema> {\n // 1. Build a structural skeleton of the data (no real values).\n const dataSkeleton = this.buildDataSkeleton(data, partialSchema);\n\n if (Object.keys(dataSkeleton).length === 0) {\n // Nothing to infer, the partial schema covered everything.\n return partialSchema || { type: \"object\", properties: {} };\n }\n\n // 2. Delegate to the subclass to get the schema from the LLM.\n const llmGeneratedSchema = await this.callLLM(dataSkeleton);\n\n // 3. Deep merge the partial schema over the LLM schema.\n return this.deepMergeSchemas(llmGeneratedSchema, partialSchema) as ISchema;\n }\n\n /**\n * Abstract method implemented by proxies to handle network/mock calls.\n * @param dataSkeleton The structure of unknown fields.\n */\n protected abstract callLLM(dataSkeleton: Record<string, string>): Promise<ISchema>;\n\n /**\n * Strips actual values and ignores fields already defined in the partial schema.\n */\n private buildDataSkeleton(data: unknown, partialSchema?: ISchema): Record<string, string> {\n const skeleton: Record<string, string> = {};\n if (!data || typeof data !== \"object\") return skeleton;\n\n const definedKeys = partialSchema?.properties ? Object.keys(partialSchema.properties) : [];\n const dataObj = data as Record<string, unknown>;\n\n for (const key of Object.keys(dataObj)) {\n if (!definedKeys.includes(key)) {\n skeleton[key] = `type: ${typeof dataObj[key]}`;\n }\n }\n return skeleton;\n }\n\n /**\n * Merges a manual partial schema over the LLM generated schema.\n */\n private deepMergeSchemas(base: unknown, override?: unknown): unknown {\n const outTarget = (base || {}) as Record<string, unknown>;\n const output: Record<string, unknown> = Object.assign({}, outTarget);\n if (override === null || typeof override !== \"object\") return output;\n \n const srcObj = override as Record<string, unknown>;\n\n Object.keys(srcObj).forEach(key => {\n if (Array.isArray(srcObj[key])) {\n output[key] = Array.isArray(outTarget[key]) \n ? Array.from(new Set([...(outTarget[key] as unknown[]), ...(srcObj[key] as unknown[])])) \n : [...(srcObj[key] as unknown[])];\n } else if (typeof srcObj[key] === \"object\" && srcObj[key] !== null) {\n if (outTarget[key] && typeof outTarget[key] === \"object\") {\n output[key] = this.deepMergeSchemas(outTarget[key], srcObj[key]);\n } else {\n output[key] = Object.assign({}, srcObj[key]);\n }\n } else {\n output[key] = srcObj[key];\n }\n });\n return output;\n }\n}\n"],"mappings":"AAAA,6FAMO,MAAeA,EAQlB,oBAAaC,CAAeC,EAAcC,GAEtC,MAAMC,EAAeC,KAAKC,kBAAkBJ,EAAMC,GAElD,GAAII,OAAOC,KAAKJ,GAAcK,SAAW,EAAG,CAExC,OAAON,GAAiB,CAAEO,KAAM,SAAUC,WAAY,CAAC,EAC3D,CAGA,MAAMC,QAA2BP,KAAKQ,QAAQT,GAG9C,OAAOC,KAAKS,iBAAiBF,EAAoBT,EACrD,CAWQG,kBAAkBJ,EAAeC,GACrC,MAAMY,EAAmC,CAAC,EAC1C,IAAKb,UAAeA,IAAS,SAAU,OAAOa,EAE9C,MAAMC,EAAcb,GAAeQ,WAAaJ,OAAOC,KAAKL,EAAcQ,YAAc,GACxF,MAAMM,EAAUf,EAEhB,IAAK,MAAMgB,KAAOX,OAAOC,KAAKS,GAAU,CACpC,IAAKD,EAAYG,SAASD,GAAM,CAC5BH,EAASG,GAAO,gBAAgBD,EAAQC,IAC5C,CACJ,CACA,OAAOH,CACX,CAKQD,iBAAiBM,EAAeC,GACpC,MAAMC,EAAaF,GAAQ,CAAC,EAC5B,MAAMG,EAAkChB,OAAOiB,OAAO,CAAC,EAAGF,GAC1D,GAAID,IAAa,aAAeA,IAAa,SAAU,OAAOE,EAE9D,MAAME,EAASJ,EAEfd,OAAOC,KAAKiB,GAAQC,QAAQR,IACxB,GAAIS,MAAMC,QAAQH,EAAOP,IAAO,CAC5BK,EAAOL,GAAOS,MAAMC,QAAQN,EAAUJ,IAChCS,MAAME,KAAK,IAAIC,IAAI,IAAKR,EAAUJ,MAAwBO,EAAOP,MACjE,IAAKO,EAAOP,GACtB,MAAO,UAAWO,EAAOP,KAAS,UAAYO,EAAOP,KAAS,KAAM,CAChE,GAAII,EAAUJ,WAAeI,EAAUJ,KAAS,SAAU,CACtDK,EAAOL,GAAOb,KAAKS,iBAAiBQ,EAAUJ,GAAMO,EAAOP,GAC/D,KAAO,CACHK,EAAOL,GAAOX,OAAOiB,OAAO,CAAC,EAAGC,EAAOP,GAC3C,CACJ,KAAO,CACHK,EAAOL,GAAOO,EAAOP,EACzB,IAEJ,OAAOK,CACX,EACH,IAAAQ,EAAA,CAAAC,WAAA,MAAAD,EAAA/B,kBAAA,OAAA+B,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":3,"column":0},"map":{"version":3,"names":["BaseAIGenerator","___BaseAIGenerator","Logger","___utils_Logger","MockLLMProxy","callLLM","dataSkeleton","Promise","resolve","info","Object","keys","setTimeout","schema","type","properties","key","metadata","includes","ui","label","this","camelCaseToTitle","toLowerCase","widget","format","str","replace","s","toUpperCase","__exports","__esModule"],"sources":["MockLLMProxy.ts"],"sourcesContent":["/**\n * @file MockLLMProxy.ts\n * @description Simulates an LLM backend call with a timeout.\n */\nimport { BaseAIGenerator } from \"./BaseAIGenerator\";\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { Logger } from \"../utils/Logger\";\n\nexport class MockLLMProxy extends BaseAIGenerator {\n \n protected callLLM(dataSkeleton: Record<string, string>): Promise<ISchema> {\n return new Promise((resolve) => {\n Logger.info(\"[MockLLMProxy]\", \"Simulating AI Schema generation for keys:\", Object.keys(dataSkeleton));\n \n setTimeout(() => {\n const schema: ISchema = {\n type: \"object\",\n properties: {}\n };\n\n // Naive mocked mapping for demo purposes.\n // In reality, the LLM provides this enriched schema.\n for (const key of Object.keys(dataSkeleton)) {\n const metadata: IPropertyMetadata = {\n type: dataSkeleton[key].includes(\"number\") ? \"number\" : \"string\",\n ui: {\n label: this.camelCaseToTitle(key)\n }\n };\n\n if (key.toLowerCase().includes(\"email\")) {\n metadata.ui!.widget = \"email\";\n metadata.ui!.format = \"email\";\n } else if (key.toLowerCase().includes(\"phone\")) {\n metadata.ui!.widget = \"phone\";\n metadata.ui!.format = \"phone\";\n } else if (key.toLowerCase().includes(\"date\")) {\n metadata.ui!.widget = \"date\";\n } else if (key.toLowerCase().includes(\"active\") || key.toLowerCase().includes(\"is\")) {\n metadata.type = \"boolean\";\n metadata.ui!.widget = \"switch\";\n } else if (key.toLowerCase().includes(\"limit\") || key.toLowerCase().includes(\"amount\") || key.toLowerCase().includes(\"salary\")) {\n metadata.type = \"number\";\n metadata.ui!.widget = \"currency\";\n }\n\n schema.properties![key] = metadata;\n }\n\n Logger.info(\"[MockLLMProxy]\", \"Schema generation complete.\");\n resolve(schema);\n }, 1500); // Emulate 1.5s network/LLM latency\n });\n }\n\n private camelCaseToTitle(str: string): string {\n return str.replace(/([A-Z])/g, ' $1').replace(/^./, (s) => s.toUpperCase());\n }\n}\n"],"mappings":"AAAA,kIAAA,MAISA,EAAeC,EAAA,yBAEfC,EAAMC,EAAA,UAER,MAAMC,UAAqBJ,EAEpBK,QAAQC,GACd,OAAO,IAAIC,QAASC,IAChBN,EAAOO,KAAK,iBAAkB,4CAA6CC,OAAOC,KAAKL,IAEvFM,WAAW,KACP,MAAMC,EAAkB,CACpBC,KAAM,SACNC,WAAY,CAAC,GAKjB,IAAK,MAAMC,KAAON,OAAOC,KAAKL,GAAe,CACzC,MAAMW,EAA8B,CAChCH,KAAMR,EAAaU,GAAKE,SAAS,UAAY,SAAW,SACxDC,GAAI,CACAC,MAAOC,KAAKC,iBAAiBN,KAIrC,GAAIA,EAAIO,cAAcL,SAAS,SAAU,CACrCD,EAASE,GAAIK,OAAS,QACtBP,EAASE,GAAIM,OAAS,OAC1B,MAAO,GAAIT,EAAIO,cAAcL,SAAS,SAAU,CAC5CD,EAASE,GAAIK,OAAS,QACtBP,EAASE,GAAIM,OAAS,OAC1B,MAAO,GAAIT,EAAIO,cAAcL,SAAS,QAAS,CAC3CD,EAASE,GAAIK,OAAS,MAC1B,MAAO,GAAIR,EAAIO,cAAcL,SAAS,WAAaF,EAAIO,cAAcL,SAAS,MAAO,CACjFD,EAASH,KAAO,UAChBG,EAASE,GAAIK,OAAS,QAC1B,MAAO,GAAIR,EAAIO,cAAcL,SAAS,UAAYF,EAAIO,cAAcL,SAAS,WAAaF,EAAIO,cAAcL,SAAS,UAAW,CAC5HD,EAASH,KAAO,SAChBG,EAASE,GAAIK,OAAS,UAC1B,CAEAX,EAAOE,WAAYC,GAAOC,CAC9B,CAEAf,EAAOO,KAAK,iBAAkB,+BAC9BD,EAAQK,IACT,OAEX,CAEQS,iBAAiBI,GACrB,OAAOA,EAAIC,QAAQ,WAAY,OAAOA,QAAQ,KAAOC,GAAMA,EAAEC,cACjE,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA1B,eAAA,OAAA0B,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":4,"column":0},"map":{"version":3,"names":["BaseAIGenerator","___BaseAIGenerator","Logger","___utils_Logger","AIConfig","___AIConfig","RestLLMProxy","callLLM","dataSkeleton","endpoint","getEndpointUrl","Error","info","response","fetch","method","headers","body","JSON","stringify","skeleton","ok","status","schema","json","e","error","message","type","properties","__exports","__esModule"],"sources":["RestLLMProxy.ts"],"sourcesContent":["/**\n * @file RestLLMProxy.ts\n * @description Real HTTP REST client for communicating with an external LLM generation endpoint.\n */\nimport { BaseAIGenerator } from \"./BaseAIGenerator\";\nimport { ISchema } from \"../interfaces/ISchema\";\nimport { Logger } from \"../utils/Logger\";\nimport { AIConfig } from \"./AIConfig\";\n\nexport class RestLLMProxy extends BaseAIGenerator {\n\n protected async callLLM(dataSkeleton: Record<string, string>): Promise<ISchema> {\n const endpoint = AIConfig.getEndpointUrl();\n if (!endpoint) {\n throw new Error(\"[RestLLMProxy] No AI Endpoint configured in AIConfig.\");\n }\n\n Logger.info(\"[RestLLMProxy]\", `Sending skeleton to ${endpoint}...`);\n\n try {\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\"\n },\n body: JSON.stringify({\n skeleton: dataSkeleton\n })\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const schema: ISchema = await response.json();\n Logger.info(\"[RestLLMProxy]\", \"Successfully received schema from backend.\");\n return schema;\n } catch (e: unknown) {\n Logger.error(\"[RestLLMProxy]\", `Failed to fetch LLM schema: ${(e as Error).message}`);\n // Fallback to empty schema on error so the app doesn't crash completely\n return { type: \"object\", properties: {} };\n }\n }\n}\n"],"mappings":"AAAA,iJAAA,MAISA,EAAeC,EAAA,yBAEfC,EAAMC,EAAA,gBACNC,EAAQC,EAAA,YAEV,MAAMC,UAAqBN,EAE9B,aAAgBO,CAAQC,GACpB,MAAMC,EAAWL,EAASM,iBAC1B,IAAKD,EAAU,CACX,MAAM,IAAIE,MAAM,wDACpB,CAEAT,EAAOU,KAAK,iBAAkB,uBAAuBH,QAErD,IACI,MAAMI,QAAiBC,MAAML,EAAU,CACnCM,OAAQ,OACRC,QAAS,CACL,eAAgB,oBAEpBC,KAAMC,KAAKC,UAAU,CACjBC,SAAUZ,MAIlB,IAAKK,EAASQ,GAAI,CACd,MAAM,IAAIV,MAAM,uBAAuBE,EAASS,SACpD,CAEA,MAAMC,QAAwBV,EAASW,OACvCtB,EAAOU,KAAK,iBAAkB,8CAC9B,OAAOW,CACX,CAAE,MAAOE,GACLvB,EAAOwB,MAAM,iBAAkB,+BAAgCD,EAAYE,WAE3E,MAAO,CAAEC,KAAM,SAAUC,WAAY,CAAC,EAC1C,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAxB,eAAA,OAAAwB,CAAA","ignoreList":[],"sourceRoot":"ai"}},{"offset":{"line":5,"column":0},"map":{"version":3,"names":["RENDER_MODE","INLINE","DIALOG","SCHEMA_TYPE","OBJECT","ARRAY","STRING","NUMBER","INTEGER","BOOLEAN","DATE","WIDGET_TYPE","REFERENCE","DICTIONARY_MAP","TIME","DATETIME","SWITCH","STEP","SELECT","TEXT_AREA","CODE_EDITOR","LINK","PASSWORD","EMAIL","FILE_UPLOADER","MULTI_SELECT","MULTI_INPUT","SLIDER","RATING","MESSAGE_STRIP","CAMERA","SIGNATURE","LOCATION","SCANNER","VOICE_INPUT","RICH_TEXT","URL_BUTTON","SUBMIT_BUTTON","ODATA_SELECT","REMOTE_DROPDOWN","LIVE_SEARCH","REMOTE_VALUE_HELP","LAYOUT_STRATEGY","FORM","TABLE","WIZARD","COMPACT","UI5_EVENT","SUBMIT","CHANGE","PRESS","LIVE_CHANGE","UI5_AGGREGATION","TOKENS","ITEMS","OPENAPI_PREFIX","DEFINITIONS","COMPONENTS_SCHEMAS","__exports","__esModule"],"sources":["MetaUIConstants.ts"],"sourcesContent":["/**\n * @file MetaUIConstants.ts\n * @description Centralized registry of all core architectural string constants to prevent magic strings.\n */\n\n/**\n * Defines the physical layout rendering mode of a schema node.\n */\nexport const RENDER_MODE = {\n INLINE: \"inline\",\n DIALOG: \"dialog\"\n} as const;\n\nexport type RenderModeType = typeof RENDER_MODE[keyof typeof RENDER_MODE];\n\n/**\n * Standard JSON schema and MetaUI extended types.\n */\nexport const SCHEMA_TYPE = {\n OBJECT: \"object\",\n ARRAY: \"array\",\n STRING: \"string\",\n NUMBER: \"number\",\n INTEGER: \"integer\",\n BOOLEAN: \"boolean\",\n DATE: \"date\"\n} as const;\n\nexport type SchemaTypeType = typeof SCHEMA_TYPE[keyof typeof SCHEMA_TYPE];\n\n/**\n * Common widget types injected into schema metadata.\n */\nexport const WIDGET_TYPE = {\n REFERENCE: \"reference\",\n DICTIONARY_MAP: \"dictionaryMap\",\n TIME: \"time\",\n DATETIME: \"datetime\",\n SWITCH: \"switch\",\n STEP: \"step\",\n SELECT: \"select\",\n TEXT_AREA: \"textArea\",\n CODE_EDITOR: \"codeEditor\",\n LINK: \"link\",\n PASSWORD: \"password\",\n EMAIL: \"email\",\n FILE_UPLOADER: \"fileUploader\",\n MULTI_SELECT: \"multiSelect\",\n MULTI_INPUT: \"multiInput\",\n SLIDER: \"slider\",\n RATING: \"rating\",\n MESSAGE_STRIP: \"messageStrip\",\n CAMERA: \"camera\",\n SIGNATURE: \"signature\",\n LOCATION: \"location\",\n SCANNER: \"scanner\",\n VOICE_INPUT: \"voiceInput\",\n RICH_TEXT: \"richText\",\n URL_BUTTON: \"urlButton\",\n SUBMIT_BUTTON: \"submitButton\",\n ODATA_SELECT: \"odataSelect\",\n REMOTE_DROPDOWN: \"remoteDropdown\",\n LIVE_SEARCH: \"liveSearch\",\n REMOTE_VALUE_HELP: \"remoteValueHelp\"\n} as const;\n\n/**\n * Layout strategies for the core engine.\n */\nexport const LAYOUT_STRATEGY = {\n FORM: \"form\",\n TABLE: \"table\",\n WIZARD: \"wizard\",\n COMPACT: \"compact\"\n} as const;\n\n/**\n * Standard UI5 Event names used by the framework.\n */\nexport const UI5_EVENT = {\n SUBMIT: \"submit\",\n CHANGE: \"change\",\n PRESS: \"press\",\n LIVE_CHANGE: \"liveChange\"\n} as const;\n\n/**\n * Standard UI5 Aggregation names used by the framework.\n */\nexport const UI5_AGGREGATION = {\n TOKENS: \"tokens\",\n ITEMS: \"items\"\n} as const;\n\n/**\n * Prefix strings for OpenAPI schema references.\n */\nexport const OPENAPI_PREFIX = {\n DEFINITIONS: \"#/definitions/\",\n COMPONENTS_SCHEMAS: \"#/components/schemas/\"\n} as const;\n"],"mappings":"AAAA,oGAQO,MAAMA,EAAc,CACvBC,OAAQ,SACRC,OAAQ,UAQL,MAAMC,EAAc,CACvBC,OAAQ,SACRC,MAAO,QACPC,OAAQ,SACRC,OAAQ,SACRC,QAAS,UACTC,QAAS,UACTC,KAAM,QAQH,MAAMC,EAAc,CACvBC,UAAW,YACXC,eAAgB,gBAChBC,KAAM,OACNC,SAAU,WACVC,OAAQ,SACRC,KAAM,OACNC,OAAQ,SACRC,UAAW,WACXC,YAAa,aACbC,KAAM,OACNC,SAAU,WACVC,MAAO,QACPC,cAAe,eACfC,aAAc,cACdC,YAAa,aACbC,OAAQ,SACRC,OAAQ,SACRC,cAAe,eACfC,OAAQ,SACRC,UAAW,YACXC,SAAU,WACVC,QAAS,UACTC,YAAa,aACbC,UAAW,WACXC,WAAY,YACZC,cAAe,eACfC,aAAc,cACdC,gBAAiB,iBACjBC,YAAa,aACbC,kBAAmB,mBAMhB,MAAMC,EAAkB,CAC3BC,KAAM,OACNC,MAAO,QACPC,OAAQ,SACRC,QAAS,WAMN,MAAMC,EAAY,CACrBC,OAAQ,SACRC,OAAQ,SACRC,MAAO,QACPC,YAAa,cAMV,MAAMC,EAAkB,CAC3BC,OAAQ,SACRC,MAAO,SAMJ,MAAMC,EAAiB,CAC1BC,YAAa,iBACbC,mBAAoB,yBACb,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA1D,cAAA0D,EAAAvD,cAAAuD,EAAA/C,cAAA+C,EAAAhB,kBAAAgB,EAAAX,YAAAW,EAAAN,kBAAAM,EAAAH,iBAAA,OAAAG,CAAA","ignoreList":[],"sourceRoot":"constants"}},{"offset":{"line":6,"column":0},"map":{"version":3,"names":["BaseHardwareControlRenderer","_interopRequireDefault","__BaseHardwareControlRenderer","BaseHardwareControl","Control","extend","renderer","metadata","properties","value","type","defaultValue","schemaMetadata","readOnly","aggregations","_content","multiple","visibility","events","capture","parameters","setValueAndFire","_setValueAndFire","val","this","setProperty","fireEvent","renderContent","_renderContent","rm","control"],"sources":["BaseHardwareControl.ts"],"sourcesContent":["/**\n * @file BaseHardwareControl.ts\n * @description Foundational UI5 Custom Control for hardware plugins.\n * Exposes a standard 'value' property for pure two-way data binding.\n * \n */\n\nimport Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport { IPropertyMetadata } from \"../interfaces/ISchema\";\nimport BaseHardwareControlRenderer from \"./BaseHardwareControlRenderer\";\n\n/**\n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class BaseHardwareControl extends Control {\n static readonly metadata = {\n properties: {\n /** The raw data value. Two-way bound to the model. */\n value: { type: \"any\", defaultValue: null },\n /** The schema metadata for rendering dynamic hints (like labels/readOnly) */\n schemaMetadata: { type: \"object\", defaultValue: null },\n /** Indicates if the control should be in a read-only state */\n readOnly: { type: \"boolean\", defaultValue: false }\n },\n aggregations: {\n _content: { type: \"sap.m.VBox\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n /** Fired when the hardware successfully captures a value */\n capture: {\n parameters: {\n value: { type: \"any\" }\n }\n }\n }\n };\n\n /**\n * Updates the bound value and fires the capture event.\n */\n public setValueAndFire(val: unknown): void {\n this.setProperty(\"value\", val, true); // true to suppress re-rendering if desired, but we want the binding to update\n this.fireEvent(\"capture\", { value: val });\n }\n\n /**\n * Common renderer for all hardware controls\n */\n static readonly renderer = BaseHardwareControlRenderer;\n\n /**\n * Abstract hook for subclasses to render their specific DOM/Controls.\n */\n public renderContent(rm: RenderManager, control: BaseHardwareControl): void {\n // To be overridden by hardware implementations\n }\n}\n"],"mappings":"AAAA,sPAUOA,EAA2BC,EAAAC,GAElC,MAGqBC,EAA4BC,EAAOC,OAAA,2DAkCpCC,SAAWN,EAjCXO,SAAW,CACvBC,WAAY,CAERC,MAAO,CAAEC,KAAM,MAAOC,aAAc,MAEpCC,eAAgB,CAAEF,KAAM,SAAUC,aAAc,MAEhDE,SAAU,CAAEH,KAAM,UAAWC,aAAc,QAE/CG,aAAc,CACVC,SAAU,CAAEL,KAAM,aAAcM,SAAU,MAAOC,WAAY,WAEjEC,OAAQ,CAEJC,QAAS,CACLC,WAAY,CACRX,MAAO,CAAEC,KAAM,WASxBW,gBAAe,SAAAC,EAACC,GACnBC,KAAKC,YAAY,QAASF,EAAK,MAC/BC,KAAKE,UAAU,UAAW,CAAEjB,MAAOc,GACvC,EAUOI,cAAa,SAAAC,EAACC,EAAmBC,GACpC,IACH,OAzCgB3B,CAAmB","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":7,"column":0},"map":{"version":3,"names":["__exports","apiVersion","render","rm","control","openStart","class","openEnd","content","getAggregation","renderControl","renderContent","close"],"sources":["BaseHardwareControlRenderer.ts"],"sourcesContent":["/**\n * @file BaseHardwareControlRenderer.ts\n * @description Standard renderer for all MetaUI hardware controls.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport BaseHardwareControl from \"./BaseHardwareControl\";\n\nimport Control from \"sap/ui/core/Control\";\nexport default {\n apiVersion: 2,\n render: function (rm: RenderManager, control: BaseHardwareControl) {\n rm.openStart(\"div\", control);\n rm.class(\"sapUiSmallMarginBottom\");\n rm.openEnd();\n \n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n \n if (typeof control.renderContent === \"function\") {\n control.renderContent(rm, control);\n }\n \n rm.close(\"div\");\n }\n};\n"],"mappings":"AAAA,+GAAA,IAAAA,EAUe,CACXC,WAAY,EACZC,OAAQ,SAAUC,EAAmBC,GACjCD,EAAGE,UAAU,MAAOD,GACpBD,EAAGG,MAAM,0BACTH,EAAGI,UAEH,MAAMC,EAAUJ,EAAQK,eAAe,YACvC,GAAID,EAAS,CACTL,EAAGO,cAAcF,EACrB,CAEA,UAAWJ,EAAQO,gBAAkB,WAAY,CAC7CP,EAAQO,cAAcR,EAAIC,EAC9B,CAEAD,EAAGS,MAAM,MACb,GACH,OAAAZ,CAAA","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":8,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","Logger","___utils_Logger","CameraControl","static","properties","events","videoEl","mediaStream","init","super","this","videoHtml","HTML","content","afterRendering","onVideoRendered","bind","addStyleClass","previewImage","Image","width","visible","startBtn","Button","icon","text","press","handleStartCameraPress","captureBtn","captureImage","retakeBtn","retakeImage","vBox","VBox","items","setAggregation","domRef","getDomRef","val","getProperty","startsWith","showPreview","getVisible","startCamera","setVisible","style","display","navigator","mediaDevices","getUserMedia","video","facingMode","srcObject","err","error","message","MessageToast","show","stopCamera","getTracks","forEach","track","stop","canvas","document","createElement","videoWidth","height","videoHeight","ctx","getContext","drawImage","dataUrl","toDataURL","setValueAndFire","setSrc","setValue","value","setProperty","exit"],"sources":["CameraControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport Button from \"sap/m/Button\";\nimport VBox from \"sap/m/VBox\";\nimport HTML from \"sap/ui/core/HTML\";\nimport MessageToast from \"sap/m/MessageToast\";\nimport Image from \"sap/m/Image\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * CameraControl\n * Provides a live video feed to capture photos.\n */\nexport default class CameraControl extends BaseHardwareControl {\n static readonly renderer = \"nz.co.siliconst.ui5.metaui.controls.BaseHardwareControlRenderer\";\n static readonly metadata = {\n properties: {},\n events: {}\n };\n\n private startBtn!: Button;\n private vBox!: VBox;\n private captureBtn!: Button;\n private retakeBtn!: Button;\n private videoHtml!: HTML;\n private previewImage!: Image;\n \n private videoEl: HTMLVideoElement | null = null;\n private mediaStream: MediaStream | null = null;\n\n /**\n * Initializes the control and builds the internal camera UI.\n */\n public init(): void {\n super.init();\n\n this.videoHtml = new HTML({\n content: \"<video width='400' height='300' autoplay playsinline style='background-color: #000; display: none;'></video>\",\n afterRendering: this.onVideoRendered.bind(this)\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.previewImage = new Image({\n width: \"400px\",\n visible: false\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.startBtn = new Button({\n icon: \"sap-icon://video\",\n text: \"Start Camera\",\n press: this.handleStartCameraPress.bind(this)\n });\n\n this.captureBtn = new Button({\n icon: \"sap-icon://camera\",\n text: \"Capture\",\n visible: false,\n press: this.captureImage.bind(this)\n });\n\n this.retakeBtn = new Button({\n icon: \"sap-icon://undo\",\n text: \"Retake\",\n visible: false,\n press: this.retakeImage.bind(this)\n });\n\n this.vBox = new VBox({\n items: [this.videoHtml, this.previewImage, this.startBtn, this.captureBtn, this.retakeBtn]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n }\n\n private async onVideoRendered(): Promise<void> {\n const domRef = this.videoHtml.getDomRef() as HTMLElement;\n if (!domRef) return;\n \n this.videoEl = domRef as HTMLVideoElement;\n \n const val = this.getProperty(\"value\");\n if (val && typeof val === \"string\" && val.startsWith(\"data:image\")) {\n this.showPreview(val);\n } else if (this.captureBtn.getVisible() && this.videoHtml.getVisible()) {\n this.startCamera();\n }\n }\n\n private handleStartCameraPress(): void {\n this.startCamera();\n this.startBtn.setVisible(false);\n this.captureBtn.setVisible(true);\n if (this.videoEl) {\n this.videoEl.style.display = \"block\";\n }\n }\n\n private async startCamera(): Promise<void> {\n try {\n this.mediaStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: \"environment\" } });\n if (this.videoEl) {\n this.videoEl.srcObject = this.mediaStream;\n }\n } catch (err) {\n Logger.error(\"Camera access denied or unavailable\", (err as Error).message, \"CameraControl\");\n MessageToast.show(\"Camera access denied or unavailable.\");\n }\n }\n\n private stopCamera(): void {\n if (this.mediaStream) {\n this.mediaStream.getTracks().forEach(track => track.stop());\n this.mediaStream = null;\n }\n }\n\n private captureImage(): void {\n if (!this.videoEl) return;\n \n const canvas = document.createElement(\"canvas\");\n canvas.width = this.videoEl.videoWidth || 400;\n canvas.height = this.videoEl.videoHeight || 300;\n \n const ctx = canvas.getContext(\"2d\");\n if (ctx) {\n ctx.drawImage(this.videoEl, 0, 0, canvas.width, canvas.height);\n const dataUrl = canvas.toDataURL(\"image/jpeg\", 0.8);\n this.setValueAndFire(dataUrl);\n this.showPreview(dataUrl);\n MessageToast.show(\"Image captured successfully.\");\n }\n }\n\n private retakeImage(): void {\n this.setValueAndFire(null);\n this.previewImage.setVisible(false);\n this.videoHtml.setVisible(true);\n this.captureBtn.setVisible(true);\n this.retakeBtn.setVisible(false);\n \n // startCamera is now handled safely by onVideoRendered hook\n }\n\n private showPreview(dataUrl: string): void {\n this.stopCamera();\n this.videoHtml.setVisible(false);\n this.previewImage.setSrc(dataUrl);\n this.previewImage.setVisible(true);\n this.captureBtn.setVisible(false);\n this.retakeBtn.setVisible(true);\n }\n\n /**\n * Sets the value of the control programmatically.\n * @param value The base64 data URL string representing the image.\n */\n public setValue(value: unknown): this {\n super.setProperty(\"value\", value);\n if (value && typeof value === \"string\" && value.startsWith(\"data:image\")) {\n this.showPreview(value);\n } else if (!value) {\n // Only retake if we were showing a preview\n if (this.previewImage.getVisible()) {\n this.retakeImage();\n }\n }\n return this;\n }\n\n /**\n * Cleans up the hardware streams when the control is destroyed.\n */\n public exit(): void {\n this.stopCamera();\n super.exit();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":9,"column":0},"map":{"version":3,"names":["GeneratorHost","_interopRequireDefault","__GeneratorHost","Logger","___utils_Logger","ODataDelegate","___host_delegates_ODataDelegate","SchemaBuilderRegistry","___core_SchemaBuilderRegistry","SchemaProvider","___services_SchemaProvider","AIConfig","___ai_AIConfig","DynamicHost","Control","extend","constructor","prototype","apply","this","arguments","odataDelegate","_innerHost","_initializedInner","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","schemaDefinitions","schemaTarget","pluginRegistry","schemaBuilderRegistry","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","layoutBudget","inferenceStrategy","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","error","exception","initODataDelegate","_initODataDelegate","getBindingInfo","dataBinding","path","oContext","getBindingContext","debug","getPath","requestObject","syncToEngine","Object","keys","setBindingContext","_setBindingContext","sModelName","Control.prototype.setBindingContext.call","bindElement","_bindElement","vPath","mParameters","Control.prototype.bindElement.call","model","undefined","oBinding","getElementBinding","attachChange","onBeforeRendering","_onBeforeRendering","schemaRaw","getProperty","startsWith","self","_fetchingSchema","BusyIndicator","show","resolve","then","json","plugin","getBuilderFor","finalSchema","build","Control.prototype.setProperty.call","definitions","hide","invalidate","catch","err","MessageToast","schema","trim","JSON","parse","e","hasSchema","length","hasData","rawDataObj","msg","MessageBox","title","proxy","getProxy","generateSchema","generatedSchema","warn","props","getMetadata","getProperties","propName","val","Control.prototype.getProperty.call","setProperty","setAggregation","getEvents","eventName","attachEvent","oEvent","params","getParameters","isLive","str","stringify","fireEvent","_setProperty","propertyName","suppressInvalidate","openInDialog","_openInDialog","submitButtonText","cancelButtonText","dialogWidth","parentView","triggerSubmit","_triggerSubmit","addCustomError","_addCustomError","inner","clearCustomError","_clearCustomError","_getProperty"],"sources":["DynamicHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport GeneratorHost from \"./host/GeneratorHost\";\nimport { Logger } from \"../utils/Logger\";\nimport { ODataDelegate } from \"./host/delegates/ODataDelegate\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\nimport { SchemaBuilderRegistry } from \"../core/SchemaBuilderRegistry\";\nimport BusyIndicator from \"sap/ui/core/BusyIndicator\";\nimport MessageToast from \"sap/m/MessageToast\";\nimport MessageBox from \"sap/m/MessageBox\";\nimport { SchemaProvider } from \"../services/SchemaProvider\";\nimport { AIConfig } from \"../ai/AIConfig\";\n\n/**\n * A transparent wrapper control (Facade) that automatically chooses between Explicit Schema Mode \n * and Inference Mode based on the presence of a 'schemaDefinition'.\n * \n * This maintains total architectural separation of the modes without forcing developers to \n * use different XML tags.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class DynamicHost extends Control {\n private odataDelegate: ODataDelegate | null = null;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n schemaDefinitions: { type: \"object\", defaultValue: null },\n schemaTarget: { type: \"string\", defaultValue: null },\n pluginRegistry: { type: \"object\", defaultValue: null },\n schemaBuilderRegistry: { type: \"object\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true },\n layoutBudget: { type: \"int\", defaultValue: 0 },\n inferenceStrategy: { type: \"string\", defaultValue: \"RuleBased\" }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } },\n error: { parameters: { message: { type: \"string\" }, exception: { type: \"object\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: DynamicHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Internal reference to the generated inner host instance.\n * @private\n */\n private _innerHost: GeneratorHost | null = null;\n\n /**\n * Flag indicating if the inner host has been initialized.\n * @private\n */\n private _initializedInner: boolean = false;\n\n /**\n * Initializes the OData Delegate if an OData context is detected.\n * This allows DynamicHost to seamlessly synchronize metadata and properties from an OData model.\n * @private\n */\n private initODataDelegate(): void {\n if (!this.odataDelegate) {\n // Guard: If the user explicitly bound dataJson, do not steal the context.\n if (this.getBindingInfo(\"dataJson\")) {\n return;\n }\n\n // Guard: If the user explicitly bound 'data' to a specific property path, do not steal the context.\n const dataBinding = this.getBindingInfo(\"data\") as Record<string, unknown> | undefined;\n if (dataBinding && dataBinding.path && dataBinding.path !== \"\") {\n return;\n }\n\n const oContext = this.getBindingContext(\"odata\") || this.getBindingContext();\n if (oContext) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context found for delegate initialization: ${oContext.getPath()}`, \"DynamicHost\");\n if (oContext && (oContext as ODataV4Context).requestObject && typeof (oContext as ODataV4Context).requestObject === \"function\") {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context supports requestObject/getObject. Instantiating ODataDelegate.`, \"DynamicHost\");\n this.odataDelegate = new ODataDelegate(this, oContext as ODataV4Context);\n this.odataDelegate.syncToEngine();\n } else {\n Logger.debug(\"[MetaUI DynamicHost]\", `Context does NOT support requestObject/getObject! Keys: ${Object.keys(oContext)}`, \"DynamicHost\");\n }\n }\n }\n }\n\n /**\n * Standard UI5 method override.\n * Sets the binding context for the control and attempts to initialize the OData delegate\n * if the context points to an OData model.\n * \n * @param {sap.ui.model.Context | null | undefined} oContext The binding context object\n * @param {string} [sModelName] Optional model name\n * @returns {this} The control instance for chaining\n */\n public setBindingContext(oContext: unknown, sModelName?: string): this {\n super.setBindingContext(oContext as sap.ui.model.Context, sModelName);\n this.initODataDelegate();\n return this;\n }\n\n /**\n * Standard UI5 method override.\n * Binds the element to the given path and attaches a change listener to re-evaluate\n * the OData delegate when the element binding resolves.\n * \n * @param {string | Record<string, unknown>} vPath The binding path or configuration object\n * @param {object} [mParameters] Optional mapping parameters\n * @returns {this} Reference to this instance for chaining\n */\n public bindElement(vPath: unknown, mParameters?: object): this {\n super.bindElement(vPath as string | { path: string }, mParameters);\n const sModelName = typeof vPath === \"object\" ? vPath.model : undefined;\n const oBinding = this.getElementBinding(sModelName);\n if (oBinding) {\n oBinding.attachChange(() => {\n this.initODataDelegate();\n });\n }\n return this;\n }\n\n /**\n * Standard UI5 Lifecycle Hook.\n * Evaluates the initial properties and spawns the GeneratorHost.\n * It handles the complex lifecycle task of copying all bindings, raw properties, and event listeners \n * down to the inner host perfectly transparently.\n */\n public onBeforeRendering(): void {\n Logger.debug(\"[MetaUI DynamicHost]\", `onBeforeRendering called. _initializedInner: ${this._initializedInner}`, \"DynamicHost\");\n\n this.initODataDelegate();\n\n if (!this._initializedInner) {\n let schemaRaw = this.getProperty(\"schemaDefinition\");\n\n if (typeof schemaRaw === \"string\" && (schemaRaw.startsWith(\"http://\") || schemaRaw.startsWith(\"https://\"))) {\n const self = this as unknown as { _fetchingSchema?: boolean };\n if (self._fetchingSchema) return; // Prevent re-entry\n self._fetchingSchema = true;\n \n BusyIndicator.show(0);\n SchemaProvider.resolve(schemaRaw)\n .then(json => {\n const plugin = SchemaBuilderRegistry.getBuilderFor(json);\n const finalSchema = plugin ? plugin.build(json, this.getProperty(\"schemaTarget\") as string | undefined) : json;\n super.setProperty(\"schemaDefinition\", finalSchema, true);\n if (finalSchema.definitions) {\n super.setProperty(\"schemaDefinitions\", finalSchema.definitions, true);\n }\n const self = this as unknown as { _fetchingSchema?: boolean };\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate(); // Force re-render with resolved schema\n })\n .catch(err => {\n const self = this as unknown as { _fetchingSchema?: boolean };\n MessageToast.show(\"Failed to fetch remote schema\");\n super.setProperty(\"schemaDefinition\", null, true); // Fallback to full inference\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate();\n });\n return; // Abort this render cycle until fetch completes\n }\n\n // 2. Local Plugin Detection (Stringified JSON or Raw Object)\n let schema = schemaRaw;\n if (schema && typeof schema === \"string\" && (schema as string).trim().startsWith(\"{\")) {\n try {\n schema = JSON.parse(schema);\n } catch (e) {\n // Ignore, let standard validation catch it\n }\n }\n\n if (schema && typeof schema === \"object\") {\n const plugin = SchemaBuilderRegistry.getBuilderFor(schema);\n if (plugin) {\n schema = plugin.build(schema, this.getProperty(\"schemaTarget\") as string | undefined);\n // Silently update the wrapper property so the inner host gets the final parsed MetaUI format\n super.setProperty(\"schemaDefinition\", schema, true);\n if ((schema as Record<string, unknown>).definitions) {\n super.setProperty(\"schemaDefinitions\", (schema as Record<string, unknown>).definitions, true);\n }\n }\n }\n\n const dataJson = this.getProperty(\"dataJson\");\n const data = this.getProperty(\"data\");\n\n let hasSchema = !!schema;\n if (hasSchema && typeof schema === \"object\" && Object.keys(schema as Record<string, unknown>).length === 0) {\n hasSchema = false; // Treat empty object as no schema\n }\n\n const hasData = !!dataJson || !!data;\n\n // 3. AI Schema Inference Detection\n if (hasData && this.getProperty(\"inferenceStrategy\") === \"AI\") {\n const self = this as unknown as { _fetchingSchema?: boolean };\n if (self._fetchingSchema) return; // Prevent re-entry\n self._fetchingSchema = true;\n\n let rawDataObj = data;\n if (!rawDataObj && dataJson) {\n try { rawDataObj = JSON.parse(dataJson as string); } catch(e: unknown) { \n const msg = \"Ignored invalid dataJson parse: \" + (e as Error).message;\n Logger.error(\"[DynamicHost]\", msg, \"DynamicHost\"); \n MessageBox.error(msg, { title: \"Invalid JSON Data\" });\n }\n }\n\n if (rawDataObj) {\n BusyIndicator.show(0);\n const proxy = AIConfig.getProxy();\n \n proxy.generateSchema(rawDataObj, schema || undefined)\n .then((generatedSchema: unknown) => {\n const self = this as unknown as { _fetchingSchema?: boolean };\n super.setProperty(\"schemaDefinition\", generatedSchema, true);\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate(); // Force re-render with the new schema\n })\n .catch((err: Error) => {\n const self = this as unknown as { _fetchingSchema?: boolean };\n Logger.warn(\"[MetaUI DynamicHost]\", \"AI inference failed, falling back to RuleBased. Error: \" + err.message, \"DynamicHost\");\n MessageToast.show(\"AI Inference failed, using fallback.\");\n super.setProperty(\"inferenceStrategy\", \"RuleBased\", true); // Fallback to normal inference\n self._fetchingSchema = false;\n BusyIndicator.hide();\n this.invalidate(); \n });\n return; // Abort render cycle until AI is done\n }\n }\n\n Logger.debug(\"[MetaUI DynamicHost]\", `Evaluating boot. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n\n // Only boot if we have either a schema or some data to infer from\n if (hasSchema || hasData) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Booting inner host. hasSchema: ${hasSchema}, hasData: ${hasData}`, \"DynamicHost\");\n }\n // The architectural Facade router logic:\n // We've simplified this! We no longer use HostFactory or separate subclasses.\n // GeneratorHost is fully capable of inferring the schema if none is provided.\n this._innerHost = new GeneratorHost();\n\n // 1. Forward all static values to the spawned host BEFORE mounting.\n // Since we no longer use bindProperty, it's perfectly safe to set raw properties before mounting.\n const props = this.getMetadata().getProperties();\n for (const propName in props) {\n if (propName === \"inferenceStrategy\") continue;\n const val = super.getProperty(propName);\n if (val !== null && val !== undefined) {\n if (propName === \"schemaDefinitions\") {\n Logger.debug(`[MetaUI DynamicHost] Proxying schemaDefinitions: ${Object.keys(val)}`, \"\", \"DynamicHost\");\n }\n this._innerHost.setProperty(propName, val);\n } else if (propName === \"schemaDefinitions\") {\n Logger.warn(`[MetaUI DynamicHost] Warning: schemaDefinitions is null/undefined in Wrapper. Defaulting to empty object in GeneratorHost.`, \"\", \"DynamicHost\");\n }\n }\n\n // 2. Mount so it inherits models and triggers lifecycle.\n this.setAggregation(\"_content\", this._innerHost);\n\n // 3. Forward all event subscriptions.\n // By proxying the events upwards, the developer can subscribe to `<meta:DynamicHost submit=\"...\">` \n // and perfectly receive the inner host's submission event.\n const events = this.getMetadata().getEvents();\n for (const eventName in events) {\n this._innerHost.attachEvent(eventName, (oEvent: sap.ui.base.Event) => {\n // Natively push updated payload out to any bound Fiori Element properties.\n // Using super.setProperty prevents an infinite loop back down to _innerHost.\n if (eventName === \"submit\" || eventName === \"fieldChange\") {\n const params = oEvent.getParameters();\n if (params.payload) {\n const isLive = this.getProperty(\"liveUpdate\") === true;\n if (eventName === \"submit\" || isLive) {\n super.setProperty(\"data\", params.payload, true);\n\n const str = params.payloadJson || JSON.stringify(params.payload, null, 2);\n super.setProperty(\"dataJson\", str, true);\n }\n }\n }\n this.fireEvent(eventName, oEvent.getParameters());\n });\n }\n\n this._initializedInner = true;\n }\n }\n }\n\n /**\n * Overrides standard UI5 setProperty to act as a transparent proxy.\n * When a property is updated on the wrapper (either programmatically or via a binding update),\n * it instantly mirrors that value down to the inner instantiated host.\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\" || propertyName === \"schemaDefinitions\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `Wrapper received setProperty: ${propertyName}`, \"DynamicHost\");\n }\n }\n super.setProperty(propertyName, value, suppressInvalidate);\n if (this._innerHost && propertyName !== \"inferenceStrategy\") {\n this._innerHost.setProperty(propertyName, value, suppressInvalidate);\n } else if (propertyName === \"data\" || propertyName === \"dataJson\" || propertyName === \"schemaDefinition\" || propertyName === \"schemaDefinitions\") {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI DynamicHost]\", `_innerHost not yet initialized when ${propertyName} was set. Booting will happen on next render.`, \"DynamicHost\");\n }\n }\n return this;\n }\n\n\n\n\n\n /**\n * Programmatic API support. Routes dialog commands down to the spawned inner host.\n * If the inner host has not booted yet, it forces initialization immediately.\n * \n * @param {string} [title=\"Form\"] The title of the dialog\n * @param {string} [submitButtonText=\"OK\"] The text for the primary action button\n * @param {string} [cancelButtonText=\"Cancel\"] The text for the cancel button\n * @param {string} [dialogWidth=\"auto\"] The width of the dialog\n * @param {sap.ui.core.Control} [parentView] The parent view to attach the dialog to for model inheritance.\n */\n public openInDialog(title?: string, submitButtonText?: string, cancelButtonText?: string, dialogWidth?: string, parentView?: Control): void {\n if (!this._innerHost) {\n this.onBeforeRendering(); // Force init if they bypassed UI5 rendering\n }\n this._innerHost?.openInDialog(title, submitButtonText, cancelButtonText, dialogWidth, parentView);\n }\n\n /**\n * Proxies submission triggering down to the instantiated generator host.\n * Evaluates the internal Engine validation suite and returns true if structurally sound.\n * \n * @returns {boolean} True if the internal payload passes schema validation, false otherwise.\n */\n public triggerSubmit(): boolean {\n if (!this._innerHost) {\n return false;\n }\n return this._innerHost.triggerSubmit();\n }\n\n /**\n * Injects a custom error message onto a specific field.\n * Useful for injecting custom backend validation errors.\n * \n * @param {string} fieldPath The schema key path to target.\n * @param {string} message The custom error message to display.\n */\n public addCustomError(fieldPath: string, message: string): void {\n const inner = this._innerHost as unknown as { addCustomError?: (p: string, m: string) => void };\n if (inner && typeof inner.addCustomError === \"function\") {\n inner.addCustomError(fieldPath, message);\n }\n }\n\n /**\n * Clears a custom error message from a specific field.\n * \n * @param {string} fieldPath The schema key path to target.\n */\n public clearCustomError(fieldPath: string): void {\n const inner = this._innerHost as unknown as { clearCustomError?: (p: string) => void };\n if (inner && typeof inner.clearCustomError === \"function\") {\n inner.clearCustomError(fieldPath);\n }\n }\n\n /**\n * Overrides standard UI5 getProperty to transparently pull extracted data from the inner host.\n * Ensures that querying the DynamicHost facade for `data` always yields the freshest payload.\n * \n * @param {string} propertyName The name of the property to retrieve\n * @returns {unknown} The property value\n */\n public getProperty(propertyName: string): unknown {\n if (propertyName === \"outputData\") {\n propertyName = \"data\"; // Forward deprecated outputData to data\n }\n if (this._innerHost && (propertyName === \"data\" || propertyName === \"dataJson\")) {\n return this._innerHost.getProperty(propertyName);\n }\n return super.getProperty(propertyName);\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":10,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","BaseHardwareControlRenderer","__BaseHardwareControlRenderer","GeolocationControl","static","init","super","this","locationBtn","Button","icon","text","press","getLocation","bind","resultInput","Input","editable","visible","vBox","VBox","items","setAggregation","onBeforeRendering","metadata","getProperty","ui","label","setText","readOnly","setEnabled","currentVal","setValue","setVisible","navigator","geolocation","MessageToast","show","getCurrentPosition","position","locStr","coords","latitude","longitude","setValueAndFire","error","__ui5_require_async","then","Logger","message"],"sources":["GeolocationControl.ts"],"sourcesContent":["/**\n * @file GeolocationControl.ts\n * @description Native UI5 Control for GPS capture.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nimport BaseHardwareControl from \"./BaseHardwareControl\";\nimport BaseHardwareControlRenderer from \"./BaseHardwareControlRenderer\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport Button from \"sap/m/Button\";\nimport Input from \"sap/m/Input\";\nimport VBox from \"sap/m/VBox\";\nimport MessageToast from \"sap/m/MessageToast\";\n\nexport default class GeolocationControl extends BaseHardwareControl {\n private vBox!: VBox;\n private locationBtn!: Button;\n private resultInput!: Input;\n\n static readonly renderer = BaseHardwareControlRenderer;\n\n /**\n * Initializes the control and builds the internal UI components.\n */\n public init(): void {\n super.init();\n\n this.locationBtn = new Button({\n icon: \"sap-icon://map\",\n text: \"Get Location\",\n press: this.getLocation.bind(this)\n });\n\n this.resultInput = new Input({\n editable: false,\n visible: false\n });\n\n this.vBox = new VBox({\n items: [this.locationBtn, this.resultInput]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n }\n\n /**\n * Lifecycle hook called before the control is rendered to the DOM.\n * Updates button state and sets any existing values.\n */\n public onBeforeRendering(): void {\n const metadata = this.getProperty(\"schemaMetadata\");\n if (metadata && metadata.ui && metadata.ui.label) {\n this.locationBtn.setText(metadata.ui.label);\n }\n\n const readOnly = this.getProperty(\"readOnly\");\n this.locationBtn.setEnabled(!readOnly);\n\n const currentVal = this.getProperty(\"value\");\n if (currentVal) {\n this.resultInput.setValue(currentVal as string);\n this.resultInput.setVisible(true);\n }\n }\n\n private getLocation(): void {\n if (!navigator.geolocation) {\n MessageToast.show(\"Geolocation is not supported by your browser\");\n return;\n }\n\n navigator.geolocation.getCurrentPosition(\n (position) => {\n const locStr = `${position.coords.latitude}, ${position.coords.longitude}`;\n this.resultInput.setValue(locStr);\n this.resultInput.setVisible(true);\n this.setValueAndFire(locStr);\n MessageToast.show(\"Location acquired.\");\n },\n (error) => {\n import(\"../utils/Logger\").then(({ Logger }) => {\n Logger.error(\"[MetaUI] Geolocation failed or denied\", error.message, \"GeolocationControl\");\n });\n MessageToast.show(\"Unable to retrieve your location\");\n }\n );\n }\n\n\n}\n"],"mappings":"AAAA,ojBAAA,MAMOA,EAAmBC,EAAAC,GAAA,MACnBC,EAA2BF,EAAAG,GAOnB,MAAMC,UAA2BL,EAK5CM,gBAA2BH,EAKpBI,OACHC,MAAMD,OAENE,KAAKC,YAAc,IAAIC,EAAO,CAC1BC,KAAM,iBACNC,KAAM,eACNC,MAAOL,KAAKM,YAAYC,KAAKP,QAGjCA,KAAKQ,YAAc,IAAIC,EAAM,CACzBC,SAAU,MACVC,QAAS,QAGbX,KAAKY,KAAO,IAAIC,EAAK,CACjBC,MAAO,CAACd,KAAKC,YAAaD,KAAKQ,eAGnCR,KAAKe,eAAe,WAAYf,KAAKY,KACzC,CAMOI,oBACH,MAAMC,EAAWjB,KAAKkB,YAAY,kBAClC,GAAID,GAAYA,EAASE,IAAMF,EAASE,GAAGC,MAAO,CAC9CpB,KAAKC,YAAYoB,QAAQJ,EAASE,GAAGC,MACzC,CAEA,MAAME,EAAWtB,KAAKkB,YAAY,YAClClB,KAAKC,YAAYsB,YAAYD,GAE7B,MAAME,EAAaxB,KAAKkB,YAAY,SACpC,GAAIM,EAAY,CACZxB,KAAKQ,YAAYiB,SAASD,GAC1BxB,KAAKQ,YAAYkB,WAAW,KAChC,CACJ,CAEQpB,cACJ,IAAKqB,UAAUC,YAAa,CACxBC,EAAaC,KAAK,gDAClB,MACJ,CAEAH,UAAUC,YAAYG,mBACjBC,IACG,MAAMC,EAAS,GAAGD,EAASE,OAAOC,aAAaH,EAASE,OAAOE,YAC/DpC,KAAKQ,YAAYiB,SAASQ,GAC1BjC,KAAKQ,YAAYkB,WAAW,MAC5B1B,KAAKqC,gBAAgBJ,GACrBJ,EAAaC,KAAK,uBAErBQ,IACGC,EAAO,mBAAmBC,KAAK,EAAGC,aAC9BA,EAAOH,MAAM,wCAAyCA,EAAMI,QAAS,wBAEzEb,EAAaC,KAAK,qCAG9B,EAGH,OAAAlC,CAAA","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":11,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","BaseHardwareControlRenderer","__BaseHardwareControlRenderer","RichTextControl","extend","renderer","init","_init","BaseHardwareControl.prototype.init.call","this","richTextEditor","RichTextEditor","width","height","showGroupFont","showGroupInsert","tooltip","change","oEvent","val","getParameter","setValueAndFire","vBox","VBox","items","setAggregation","onBeforeRendering","_onBeforeRendering","readOnly","getProperty","setEditable","currentVal","undefined","getValue","setValue","_setValue","setProperty"],"sources":["RichTextControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport BaseHardwareControlRenderer from \"./BaseHardwareControlRenderer\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport VBox from \"sap/m/VBox\";\nimport RichTextEditor from \"sap/ui/richtexteditor/RichTextEditor\";\n\nimport Event from \"sap/ui/base/Event\";\n/**\n * @file RichTextControl.ts\n * @description Native UI5 Control for rich text input.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls\n */\nexport default class RichTextControl extends BaseHardwareControl {\n private vBox!: VBox;\n private richTextEditor!: RichTextEditor;\n\n static readonly renderer = BaseHardwareControlRenderer;\n\n public init(): void {\n super.init();\n\n this.richTextEditor = new RichTextEditor({\n width: \"100%\",\n height: \"300px\",\n showGroupFont: true,\n showGroupInsert: true,\n tooltip: \"Rich Text Editor\",\n change: (oEvent: Event) => {\n const val = oEvent.getParameter(\"newValue\");\n this.setValueAndFire(val);\n }\n });\n\n this.vBox = new VBox({\n items: [this.richTextEditor]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n }\n\n public onBeforeRendering(): void {\n const readOnly = this.getProperty(\"readOnly\");\n this.richTextEditor.setEditable(!readOnly);\n\n const currentVal = this.getProperty(\"value\");\n if (currentVal !== undefined && currentVal !== null) {\n // Prevent recursive update if the value matches the editor's current value\n if (this.richTextEditor.getValue() !== currentVal) {\n this.richTextEditor.setValue(currentVal as string);\n }\n }\n }\n\n /**\n * Overrides the default property setter to prevent full DOM invalidation.\n * When dataJson pushes updates down to the UI5 models, UI5 typically destroys \n * and recreates the custom control if the property changes. \n * By suppressing re-rendering (true flag) and manually passing the value \n * to the inner RichTextEditor, we prevent TinyMCE from tearing down its iframe\n * and triggering expensive, redundant plugin boot sequences.\n *\n * @param {unknown} val The new string value to bind\n * @returns {this} The control instance for chaining\n */\n public setValue(val: unknown): this {\n this.setProperty(\"value\", val, true); // suppress re-rendering\n if (this.richTextEditor && val !== undefined && val !== null) {\n if (this.richTextEditor.getValue() !== val) {\n this.richTextEditor.setValue(val as string);\n }\n }\n return this;\n }\n}\n"],"mappings":"AAAA,4SAAOA,EAAmBC,EAAAC,GAAA,MACnBC,EAA2BF,EAAAG,GAMlC,MAMqBC,EAAwBL,EAAmBM,OAAA,uDAI5CC,SAAWJ,EAEpBK,KAAI,SAAAC,IACPC,sBAAAC,MAEAA,KAAKC,eAAiB,IAAIC,EAAe,CACrCC,MAAO,OACPC,OAAQ,QACRC,cAAe,KACfC,gBAAiB,KACjBC,QAAS,mBACTC,OAASC,IACL,MAAMC,EAAMD,EAAOE,aAAa,YAChCX,KAAKY,gBAAgBF,MAI7BV,KAAKa,KAAO,IAAIC,EAAK,CACjBC,MAAO,CAACf,KAAKC,kBAGjBD,KAAKgB,eAAe,WAAYhB,KAAKa,KACzC,EAEOI,kBAAiB,SAAAC,IACpB,MAAMC,EAAWnB,KAAKoB,YAAY,YAClCpB,KAAKC,eAAeoB,aAAaF,GAEjC,MAAMG,EAAatB,KAAKoB,YAAY,SACpC,GAAIE,IAAeC,WAAaD,IAAe,KAAM,CAEjD,GAAItB,KAAKC,eAAeuB,aAAeF,EAAY,CAC/CtB,KAAKC,eAAewB,SAASH,EACjC,CACJ,CACJ,EAaOG,SAAQ,SAAAC,EAAChB,GACZV,KAAK2B,YAAY,QAASjB,EAAK,MAC/B,GAAIV,KAAKC,gBAAkBS,IAAQa,WAAab,IAAQ,KAAM,CAC1D,GAAIV,KAAKC,eAAeuB,aAAed,EAAK,CACxCV,KAAKC,eAAewB,SAASf,EACjC,CACJ,CACA,OAAOV,IACX,IAAC,OA5DgBN,CAAe","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":12,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","SignatureControl","isDrawing","canvasCtx","canvasEl","init","super","this","canvasHtml","HTML","content","afterRendering","onCanvasRendered","bind","addStyleClass","clearBtn","Button","icon","text","press","clearSignature","vBox","VBox","items","setAggregation","boundStartDrawing","startDrawing","boundDraw","draw","boundStopDrawing","stopDrawing","boundStartDrawingTouch","startDrawingTouch","boundDrawTouch","drawTouch","domRef","getDomRef","getContext","lineWidth","lineCap","strokeStyle","addEventListener","passive","val","getProperty","startsWith","loadImageOntoCanvas","dataUrl","img","window","Image","onload","clearRect","width","height","drawImage","src","getCoordinates","e","x","y","rect","getBoundingClientRect","clientX","clientY","type","touches","left","top","preventDefault","pos","lineTo","stroke","beginPath","moveTo","saveSignature","setValueAndFire","MessageToast","show","toDataURL","setValue","value","setProperty","exit","removeEventListener"],"sources":["SignatureControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport Button from \"sap/m/Button\";\nimport VBox from \"sap/m/VBox\";\nimport HTML from \"sap/ui/core/HTML\";\nimport MessageToast from \"sap/m/MessageToast\";\n\n/**\n * SignatureControl\n * Provides an HTML5 Canvas for capturing signatures.\n */\nexport default class SignatureControl extends BaseHardwareControl {\n\n\n private vBox!: VBox;\n private clearBtn!: Button;\n private canvasHtml!: HTML;\n private isDrawing = false;\n private canvasCtx: CanvasRenderingContext2D | null = null;\n private canvasEl: HTMLCanvasElement | null = null;\n\n private boundStartDrawing!: (e: MouseEvent) => void;\n private boundDraw!: (e: MouseEvent) => void;\n private boundStopDrawing!: (e: MouseEvent | TouchEvent) => void;\n private boundStartDrawingTouch!: (e: TouchEvent) => void;\n private boundDrawTouch!: (e: TouchEvent) => void;\n\n /**\n * Initializes the control and builds the canvas drawing surface.\n */\n public init(): void {\n super.init();\n\n this.canvasHtml = new HTML({\n content: \"<canvas width='400' height='200' style='border: 1px solid #ccc; background-color: #fff; touch-action: none; cursor: crosshair;'></canvas>\",\n afterRendering: this.onCanvasRendered.bind(this)\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.clearBtn = new Button({\n icon: \"sap-icon://sys-cancel\",\n text: \"Clear Signature\",\n press: this.clearSignature.bind(this)\n });\n\n this.vBox = new VBox({\n items: [this.canvasHtml, this.clearBtn]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n\n this.boundStartDrawing = this.startDrawing.bind(this);\n this.boundDraw = this.draw.bind(this);\n this.boundStopDrawing = this.stopDrawing.bind(this);\n this.boundStartDrawingTouch = this.startDrawingTouch.bind(this);\n this.boundDrawTouch = this.drawTouch.bind(this);\n }\n\n private onCanvasRendered(): void {\n const domRef = this.canvasHtml.getDomRef() as HTMLElement;\n if (!domRef) return;\n \n this.canvasEl = domRef as HTMLCanvasElement;\n this.canvasCtx = this.canvasEl.getContext(\"2d\");\n if (this.canvasCtx) {\n this.canvasCtx.lineWidth = 2;\n this.canvasCtx.lineCap = \"round\";\n this.canvasCtx.strokeStyle = \"#000\";\n }\n\n // Mouse events\n this.canvasEl.addEventListener(\"mousedown\", this.boundStartDrawing);\n this.canvasEl.addEventListener(\"mousemove\", this.boundDraw);\n this.canvasEl.addEventListener(\"mouseup\", this.boundStopDrawing);\n this.canvasEl.addEventListener(\"mouseout\", this.boundStopDrawing);\n \n // Touch events\n this.canvasEl.addEventListener(\"touchstart\", this.boundStartDrawingTouch, { passive: false });\n this.canvasEl.addEventListener(\"touchmove\", this.boundDrawTouch, { passive: false });\n this.canvasEl.addEventListener(\"touchend\", this.boundStopDrawing);\n\n // Restore existing signature if any\n const val = this.getProperty(\"value\");\n if (val && typeof val === \"string\" && val.startsWith(\"data:image\")) {\n this.loadImageOntoCanvas(val);\n }\n }\n\n private loadImageOntoCanvas(dataUrl: string): void {\n const img = new window.Image();\n img.onload = () => {\n if (this.canvasCtx && this.canvasEl) {\n this.canvasCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);\n this.canvasCtx.drawImage(img, 0, 0, this.canvasEl.width, this.canvasEl.height);\n }\n };\n img.src = dataUrl;\n }\n\n private getCoordinates(e: MouseEvent | TouchEvent): { x: number, y: number } {\n if (!this.canvasEl) return { x: 0, y: 0 };\n const rect = this.canvasEl.getBoundingClientRect();\n \n let clientX, clientY;\n if (e.type.startsWith(\"touch\")) {\n clientX = (e as TouchEvent).touches[0].clientX;\n clientY = (e as TouchEvent).touches[0].clientY;\n } else {\n clientX = (e as MouseEvent).clientX;\n clientY = (e as MouseEvent).clientY;\n }\n \n return {\n x: clientX - rect.left,\n y: clientY - rect.top\n };\n }\n\n private startDrawing(e: MouseEvent): void {\n this.isDrawing = true;\n this.draw(e);\n }\n\n private startDrawingTouch(e: TouchEvent): void {\n e.preventDefault(); // Prevent scrolling\n this.isDrawing = true;\n this.drawTouch(e);\n }\n\n private draw(e: MouseEvent): void {\n if (!this.isDrawing || !this.canvasCtx) return;\n const pos = this.getCoordinates(e);\n this.canvasCtx.lineTo(pos.x, pos.y);\n this.canvasCtx.stroke();\n this.canvasCtx.beginPath();\n this.canvasCtx.moveTo(pos.x, pos.y);\n }\n\n private drawTouch(e: TouchEvent): void {\n if (!this.isDrawing || !this.canvasCtx) return;\n e.preventDefault(); // Prevent scrolling\n const pos = this.getCoordinates(e);\n this.canvasCtx.lineTo(pos.x, pos.y);\n this.canvasCtx.stroke();\n this.canvasCtx.beginPath();\n this.canvasCtx.moveTo(pos.x, pos.y);\n }\n\n private stopDrawing(): void {\n if (!this.isDrawing) return;\n this.isDrawing = false;\n if (this.canvasCtx) {\n this.canvasCtx.beginPath(); // Reset path\n this.saveSignature();\n }\n }\n\n private clearSignature(): void {\n if (this.canvasCtx && this.canvasEl) {\n this.canvasCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);\n }\n this.setValueAndFire(null);\n MessageToast.show(\"Signature cleared.\");\n }\n\n private saveSignature(): void {\n if (this.canvasEl) {\n const dataUrl = this.canvasEl.toDataURL(\"image/png\");\n this.setValueAndFire(dataUrl);\n }\n }\n\n /**\n * Sets the value of the control programmatically and re-draws the canvas.\n * @param value The base64 data URL string representing the signature image.\n */\n public setValue(value: unknown): this {\n super.setProperty(\"value\", value);\n if (value && typeof value === \"string\" && value.startsWith(\"data:image\")) {\n this.loadImageOntoCanvas(value);\n } else if (!value && this.canvasCtx && this.canvasEl) {\n this.canvasCtx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height);\n }\n return this;\n }\n\n /**\n * Cleans up event listeners to prevent memory leaks when the control is destroyed.\n */\n public exit(): void {\n if (this.canvasEl) {\n this.canvasEl.removeEventListener(\"mousedown\", this.boundStartDrawing as EventListener);\n this.canvasEl.removeEventListener(\"mousemove\", this.boundDraw as EventListener);\n this.canvasEl.removeEventListener(\"mouseup\", this.boundStopDrawing as EventListener);\n this.canvasEl.removeEventListener(\"mouseout\", this.boundStopDrawing as EventListener);\n \n this.canvasEl.removeEventListener(\"touchstart\", this.boundStartDrawingTouch as EventListener);\n this.canvasEl.removeEventListener(\"touchmove\", this.boundDrawTouch as EventListener);\n this.canvasEl.removeEventListener(\"touchend\", this.boundStopDrawing as EventListener);\n }\n this.canvasEl = null;\n this.canvasCtx = null;\n super.exit();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":13,"column":0},"map":{"version":3,"names":["BaseHardwareControl","_interopRequireDefault","__BaseHardwareControl","Logger","___utils_Logger","VoiceInputControl","recognition","isRecording","init","super","this","textArea","TextArea","rows","width","placeholder","liveChange","oEvent","setValueAndFire","getParameter","startBtn","Button","icon","text","type","press","toggleDictation","bind","hBox","HBox","items","addStyleClass","vBox","VBox","setAggregation","initSpeechRecognition","stopDictation","startDictation","SpeechRecognitionClass","window","SpeechRecognition","webkitSpeechRecognition","continuous","interimResults","onresult","event","finalTranscript","interimTranscript","i","resultIndex","results","length","isFinal","transcript","currentVal","getProperty","newVal","setValue","onstart","setIcon","setText","setType","MessageToast","show","onerror","error","sap","ui","require","MessageBox","onend","warn","setEnabled","setTooltip","start","err","message","String","stop","e","onBeforeRendering","readOnly","setEditable","undefined","exit"],"sources":["VoiceInputControl.ts"],"sourcesContent":["import BaseHardwareControl from \"./BaseHardwareControl\";\nimport Button from \"sap/m/Button\";\nimport VBox from \"sap/m/VBox\";\nimport TextArea from \"sap/m/TextArea\";\nimport MessageToast from \"sap/m/MessageToast\";\nimport HBox from \"sap/m/HBox\";\nimport { Logger } from \"../utils/Logger\";\n\nimport Event from \"sap/ui/base/Event\";\ndeclare global {\n interface Window {\n SpeechRecognition: new () => SpeechRecognition;\n webkitSpeechRecognition: new () => SpeechRecognition;\n }\n interface SpeechRecognition {\n continuous: boolean;\n interimResults: boolean;\n onresult: (event: SpeechRecognitionEvent) => void;\n onstart: () => void;\n onerror: (event: SpeechRecognitionErrorEvent) => void;\n onend: () => void;\n start(): void;\n stop(): void;\n }\n interface SpeechRecognitionEvent {\n resultIndex: number;\n results: {\n length: number;\n [index: number]: {\n isFinal: boolean;\n [index: number]: {\n transcript: string;\n };\n };\n };\n }\n interface SpeechRecognitionErrorEvent {\n error: string;\n }\n}\n\n/**\n * VoiceInputControl\n * Provides a UI to dictate text using the browser's native Web Speech API.\n */\nexport default class VoiceInputControl extends BaseHardwareControl {\n\n\n private vBox!: VBox;\n private textArea!: TextArea;\n private startBtn!: Button;\n private stopBtn!: Button;\n \n private recognition: SpeechRecognition | null = null;\n private isRecording: boolean = false;\n\n /**\n * Initializes the dictation interface and requests Web Speech API setup.\n */\n public init(): void {\n super.init();\n\n this.textArea = new TextArea({\n rows: 3,\n width: \"100%\",\n placeholder: \"Dictated text will appear here...\",\n liveChange: (oEvent: Event) => {\n this.setValueAndFire((oEvent.getParameter(\"value\") as any));\n }\n });\n\n this.startBtn = new Button({\n icon: \"sap-icon://microphone\",\n text: \"Start Dictation\",\n type: \"Emphasized\",\n press: this.toggleDictation.bind(this)\n });\n\n const hBox = new HBox({\n items: [this.startBtn]\n }).addStyleClass(\"sapUiSmallMarginTop\");\n\n this.vBox = new VBox({\n items: [this.textArea, hBox]\n });\n\n this.setAggregation(\"_content\", this.vBox);\n this.initSpeechRecognition();\n }\n\n private toggleDictation(): void {\n if (this.isRecording) {\n this.stopDictation();\n } else {\n this.startDictation();\n }\n }\n\n private initSpeechRecognition(): void {\n const SpeechRecognitionClass = window.SpeechRecognition || window.webkitSpeechRecognition;\n if (SpeechRecognitionClass) {\n this.recognition = new SpeechRecognitionClass();\n this.recognition.continuous = true;\n this.recognition.interimResults = true;\n\n this.recognition.onresult = (event: SpeechRecognitionEvent) => {\n let finalTranscript = \"\";\n let interimTranscript = \"\";\n\n for (let i = event.resultIndex; i < event.results.length; ++i) {\n if (event.results[i].isFinal) {\n finalTranscript += event.results[i][0].transcript;\n } else {\n interimTranscript += event.results[i][0].transcript;\n }\n }\n\n // Append the new final transcript to whatever was already in the textarea\n const currentVal = this.getProperty(\"value\") as string || \"\";\n const newVal = currentVal ? currentVal + \" \" + finalTranscript : finalTranscript;\n \n if (finalTranscript) {\n this.textArea.setValue(newVal);\n this.setValueAndFire(newVal);\n } else if (interimTranscript) {\n // Just show interim temporarily in textarea without saving to model\n this.textArea.setValue(currentVal ? currentVal + \" \" + interimTranscript : interimTranscript);\n }\n };\n\n this.recognition.onstart = () => {\n this.isRecording = true;\n this.startBtn.setIcon(\"sap-icon://stop\");\n this.startBtn.setText(\"Stop Recording\");\n this.startBtn.setType(\"Reject\");\n MessageToast.show(\"Listening... Please speak now.\");\n };\n\n this.recognition.onerror = (event: SpeechRecognitionErrorEvent) => {\n Logger.error(\"Speech recognition error\", event.error, \"VoiceInputControl\");\n sap.ui.require([\"sap/m/MessageBox\"], (MessageBox: typeof import(\"sap/m/MessageBox\").default) => {\n MessageBox.error(\"Microphone Error: \" + event.error + \"\\n\\nPlease ensure you have a working microphone attached and have not blocked access in your browser settings.\");\n });\n this.stopDictation();\n };\n \n this.recognition.onend = () => {\n // If it ends natively (e.g. timeout), update UI\n this.stopDictation();\n };\n } else {\n Logger.warn(\"Web Speech API not supported in this browser.\", \"\", \"VoiceInputControl\");\n this.startBtn.setEnabled(false);\n this.startBtn.setTooltip(\"Speech Recognition is not supported in this browser.\");\n }\n }\n\n private startDictation(): void {\n if (!this.recognition) return;\n \n try {\n this.recognition.start();\n MessageToast.show(\"Requesting microphone access...\");\n // Provide immediate UI feedback in case browser delays the onstart event\n this.startBtn.setIcon(\"sap-icon://stop\");\n this.startBtn.setText(\"Requesting mic...\");\n this.startBtn.setType(\"Reject\");\n } catch (err) {\n const error = err as Error;\n Logger.error(\"Failed to start speech recognition\", error.message || String(error), \"VoiceInputControl\");\n sap.ui.require([\"sap/m/MessageBox\"], (MessageBox: typeof import(\"sap/m/MessageBox\").default) => {\n MessageBox.error(\"Failed to start dictation. Please ensure you have a working microphone and have granted browser permissions.\\n\\nDetails: \" + (error.message || String(error)));\n });\n this.stopDictation();\n }\n }\n\n private stopDictation(): void {\n if (!this.recognition) return;\n \n try {\n this.recognition.stop();\n } catch(e) {\n Logger.warn(\"Failed to gracefully stop speech recognition.\", String(e), \"VoiceInputControl\");\n }\n \n this.isRecording = false;\n this.startBtn.setIcon(\"sap-icon://microphone\");\n this.startBtn.setText(\"Start Dictation\");\n this.startBtn.setType(\"Emphasized\");\n }\n\n /**\n * Lifecycle hook called before the control is rendered to the DOM.\n * Handles browser support visual state.\n */\n public onBeforeRendering(): void {\n const readOnly = this.getProperty(\"readOnly\");\n this.textArea.setEditable(!readOnly);\n \n // Only enable if it's not readonly AND the browser supports speech recognition\n this.startBtn.setEnabled(!readOnly && !!this.recognition);\n\n const currentVal = this.getProperty(\"value\");\n if (currentVal !== undefined && currentVal !== null) {\n // Only update text area if we aren't currently dictating interim results\n if (!this.isRecording) {\n this.textArea.setValue(currentVal as string);\n }\n }\n }\n\n /**\n * Cleans up hardware event listeners when the control is destroyed.\n */\n public exit(): void {\n this.stopDictation();\n if (this.recognition) {\n (this.recognition as any).onstart = null;\n (this.recognition as any).onresult = null;\n (this.recognition as any).onerror = null;\n (this.recognition as any).onend = null;\n this.recognition = null;\n }\n super.exit();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls"}},{"offset":{"line":14,"column":0},"map":{"version":3,"names":["Logger","____utils_Logger","SchemaNormalizer","____core_SchemaNormalizer","SchemaValidator","____core_SchemaValidator","Engine","____core_Engine","StateManager","____core_StateManager","PolicyEngine","____core_PolicyEngine","DataSyncDelegate","___delegates_DataSyncDelegate","ValidationDelegate","___delegates_ValidationDelegate","DialogDelegate","___delegates_DialogDelegate","PluginRegistry","____core_PluginRegistry","LayoutScorer","____core_LayoutScorer","LayoutMutator","____core_LayoutMutator","DefaultLayoutGenerator","____core_DefaultLayoutGenerator","GeneratorHost","Control","extend","renderer","apiVersion","render","rm","control","openStart","style","openEnd","content","getAggregation","renderControl","close","metadata","properties","schemaDefinition","type","defaultValue","schemaDefinitions","schemaTarget","pluginRegistry","schemaBuilderRegistry","data","bindable","dataJson","liveUpdate","isValid","useMessageManager","modelName","debugMode","editable","layoutBudget","engineScopeId","aggregations","_content","multiple","visibility","events","beforeSubmit","parameters","payload","addError","preventDefault","submit","payloadJson","cancel","fieldChange","fieldPath","value","validationStateChanged","validationError","message","validationSuccess","error","exception","constructor","_constructor","idOrSettings","settings","Control.prototype.constructor.call","this","stateManager","generatedContent","engine","policyEngine","policyDebounceTimer","activeModelName","parsedSchema","_generatePromise","init","_init","Control.prototype.init.call","dataSyncDelegate","validationDelegate","dialogDelegate","onInternalFieldChange","bind","setDebugMode","_setDebugMode","enabled","setProperty","getStateManager","_getStateManager","getSchemaDefinition","_getSchemaDefinition","refPath","defs","getProperty","undefined","key","startsWith","substring","tearDownGeneratedLayout","_tearDownGeneratedLayout","unregisterObject","destroy","_onInternalFieldChange","fieldKey","errorMessage","controlId","extractPayload","debug","pushToBindings","currentValidity","fireEvent","clearTimeout","setTimeout","evaluatePolicies","_evaluatePolicies","deltas","evaluate","delta","plugin","getPluginByPath","target","property","applyVisibility","reportPolicyError","applyRequired","applyEditable","exit","_exit","getModel","getParsedSchema","_getParsedSchema","onBeforeRendering","_onBeforeRendering","hasSchema","hasData","generate","msg","Error","triggerSubmit","_triggerSubmit","isPrevented","removeAllMessages","errors","validateAll","length","pushMessage","err","fieldLabel","JSON","stringify","propertyPath","setVisualValidationState","addCustomError","_addCustomError","clearCustomError","_clearCustomError","schemaValid","validate","setBusy","_setBusy","isBusy","Control.prototype.setBusy.call","_setProperty","propertyName","suppressInvalidate","setUseMessageManager","handleInputDataHotSwap","currentVal","Control.prototype.setProperty.call","setBaseProperty","_setBaseProperty","async","_generate","Promise","resolve","then","_doGenerate","e","internalPayload","rawSchema","parse","isSchemaEmpty","Object","keys","inputData","inputDataJson","dataParseError","finalData","schemaToNormalize","normalizedSchema","normalize","uiPolicies","schemaErrors","validateSchemaStructure","errorMsg","join","MessageBox","title","rawDefinitions","parsedRawSchema","trim","definitions","assign","normalizedDefinitions","warn","budget","ensureLayout","apply","activePluginRegistry","getInstance","pathsToLoad","getPathsToLoad","needsNetworkLoad","Array","from","some","path","sap","ui","require","preloadDependencies","injectSchemaDefaults","getId","setModel","isEditable","host","build","contentContainer","hasProperties","strip","MessageStrip","text","showIcon","showCloseButton","addStyleClass","VBox","items","insertItem","insertContent","hasPartialRenderingErrors","setAggregation","registerObject","calculateAndApplyOptimalWidth","mountCrashBoundary","openInDialog","_openInDialog","submitButtonText","cancelButtonText","dialogWidth","parentView","isGenerated"],"sources":["GeneratorHost.ts"],"sourcesContent":["import Control from \"sap/ui/core/Control\";\nimport RenderManager from \"sap/ui/core/RenderManager\";\nimport { Logger } from \"../../utils/Logger\";\nimport { SchemaNormalizer } from \"../../core/SchemaNormalizer\";\nimport { SchemaValidator } from \"../../core/SchemaValidator\";\nimport { Engine } from \"../../core/Engine\";\nimport { StateManager } from \"../../core/StateManager\";\nimport { PolicyEngine } from \"../../core/PolicyEngine\";\nimport { DataSyncDelegate } from \"./delegates/DataSyncDelegate\";\nimport { ValidationDelegate } from \"./delegates/ValidationDelegate\";\nimport { DialogDelegate } from \"./delegates/DialogDelegate\";\nimport MessageBox from \"sap/m/MessageBox\";\nimport MessageStrip from \"sap/m/MessageStrip\";\nimport VBox from \"sap/m/VBox\";\nimport { PluginRegistry } from \"../../core/PluginRegistry\";\nimport { LayoutScorer } from \"../../core/LayoutScorer\";\nimport { LayoutMutator } from \"../../core/LayoutMutator\";\nimport { DefaultLayoutGenerator } from \"../../core/DefaultLayoutGenerator\";\nimport type { ISchema } from \"../../interfaces/ISchema\";\n\n/**\n * Base wrapper element for embedding the dynamic form natively via Explicit Schemas.\n * \n * This class serves as the core rendering engine for standard MetaUI implementations.\n * It manages the lifecycle of the Engine, StateManager, and the delegation of \n * data synchronization, validation, and dialog interactions.\n * \n * @namespace nz.co.siliconst.ui5.metaui.controls.host\n */\nexport default class GeneratorHost extends Control {\n\n protected stateManager: StateManager | null = null;\n protected generatedContent: Control | null = null;\n /** The embedded engine responsible for rendering the UI controls */\n protected engine: Engine | null = null;\n \n /** \n * The Policy-Based Rules Engine.\n * Continuously evaluates declarative cross-field rules and pushes visual/structural mutations down into the plugins.\n */\n protected policyEngine: PolicyEngine | null = null;\n \n private policyDebounceTimer: any = null;\n protected activeModelName: string = \"\";\n\n protected dataSyncDelegate!: DataSyncDelegate;\n protected validationDelegate!: ValidationDelegate;\n protected dialogDelegate!: DialogDelegate;\n\n static readonly metadata = {\n properties: {\n schemaDefinition: { type: \"any\", defaultValue: null },\n schemaDefinitions: { type: \"object\", defaultValue: {} },\n schemaTarget: { type: \"string\", defaultValue: null },\n pluginRegistry: { type: \"object\", defaultValue: null },\n schemaBuilderRegistry: { type: \"object\", defaultValue: null },\n data: { type: \"object\", defaultValue: null, bindable: \"bindable\" },\n dataJson: { type: \"string\", defaultValue: null, bindable: \"bindable\" },\n liveUpdate: { type: \"boolean\", defaultValue: false },\n isValid: { type: \"boolean\", defaultValue: true },\n useMessageManager: { type: \"boolean\", defaultValue: false },\n modelName: { type: \"string\", defaultValue: \"meta\" },\n debugMode: { type: \"boolean\", defaultValue: false },\n editable: { type: \"boolean\", defaultValue: true },\n layoutBudget: { type: \"int\", defaultValue: 0 },\n engineScopeId: { type: \"string\", defaultValue: null }\n },\n aggregations: {\n _content: { type: \"sap.ui.core.Control\", multiple: false, visibility: \"hidden\" }\n },\n events: {\n beforeSubmit: {\n parameters: {\n payload: { type: \"object\" },\n addError: { type: \"function\" },\n preventDefault: { type: \"function\" }\n }\n },\n submit: {\n parameters: {\n payload: { type: \"object\" },\n payloadJson: { type: \"string\" }\n }\n },\n cancel: {},\n fieldChange: {\n parameters: {\n fieldPath: { type: \"string\" },\n value: { type: \"any\" },\n payload: { type: \"object\" },\n isValid: { type: \"boolean\" }\n }\n },\n validationStateChanged: { parameters: { isValid: { type: \"boolean\" } } },\n validationError: { parameters: { fieldPath: { type: \"string\" }, message: { type: \"string\" } } },\n validationSuccess: { parameters: { fieldPath: { type: \"string\" } } },\n error: { parameters: { message: { type: \"string\" }, exception: { type: \"object\" } } }\n }\n };\n\n static renderer = {\n apiVersion: 2,\n render(rm: RenderManager, control: GeneratorHost) {\n rm.openStart(\"div\", control);\n rm.style(\"width\", \"100%\");\n rm.style(\"height\", \"100%\");\n rm.openEnd();\n\n const content = control.getAggregation(\"_content\") as Control;\n if (content) {\n rm.renderControl(content);\n }\n\n rm.close(\"div\");\n }\n };\n\n /**\n * Standard UI5 Constructor.\n */\n constructor(idOrSettings?: string | object, settings?: object) {\n super(idOrSettings as string, settings);\n }\n\n /**\n * Initializes the control and instantiates the composition delegates.\n * Delegates must be initialized here rather than in the constructor so they are \n * available before `applySettings` runs during UI5's control lifecycle.\n */\n public init(): void {\n super.init();\n\n // Initialize Composition Delegates\n this.dataSyncDelegate = new DataSyncDelegate(this);\n this.validationDelegate = new ValidationDelegate(this);\n this.dialogDelegate = new DialogDelegate(this as any);\n\n this.onInternalFieldChange = this.onInternalFieldChange.bind(this);\n }\n\n /**\n * Enables or disables debug mode.\n */\n public setDebugMode(enabled: boolean): this {\n this.setProperty(\"debugMode\", enabled, true);\n Logger.setDebugMode(enabled);\n return this;\n }\n\n\n /**\n * Returns the active state manager instance managing the JSON payload.\n */\n public getStateManager(): StateManager | null {\n return this.stateManager;\n }\n\n /**\n * Resolves a reference pointer against the global schema definitions dictionary.\n * @param refPath The string reference path (e.g., \"#/definitions/User\")\n * @returns The resolved ISchema or undefined\n */\n public getSchemaDefinition(refPath: string): ISchema | undefined {\n const defs = this.getProperty(\"schemaDefinitions\") as Record<string, ISchema>;\n if (!defs || !refPath) return undefined;\n let key = refPath;\n if (key.startsWith(\"#/definitions/\")) {\n key = key.substring(14);\n } else if (key.startsWith(\"#/components/schemas/\")) {\n key = key.substring(21);\n }\n return defs[key];\n }\n\n /**\n * Safely destroys the currently generated UI tree and cleans up references.\n * This is called before every regeneration to prevent memory leaks.\n */\n public tearDownGeneratedLayout(): void {\n if (this.generatedContent) {\n this.validationDelegate.unregisterObject(this.generatedContent);\n this.generatedContent.destroy();\n this.generatedContent = null;\n }\n }\n\n /**\n * Internal event handler triggered by the Engine when a field value changes.\n * Coordinates LiveUpdate syncs, validation state tracking, and bubbling the change upwards.\n */\n protected onInternalFieldChange(isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string): void {\n const payload = this.stateManager ? this.stateManager.extractPayload() : {};\n\n if (this.getProperty(\"liveUpdate\") === true) {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", \"liveUpdate is enabled, pushing outbound payload.\", \"GeneratorHost\");\n }\n this.dataSyncDelegate.pushToBindings(payload);\n }\n\n const currentValidity = this.getProperty(\"isValid\") as boolean;\n if (isValid !== currentValidity) {\n this.setProperty(\"isValid\", isValid, true);\n this.fireEvent(\"validationStateChanged\", { isValid });\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Validation state shifted to: ${isValid}`, \"GeneratorHost\");\n }\n }\n\n this.fireEvent(\"fieldChange\", {\n fieldPath: fieldKey || \"\",\n value: undefined,\n payload: payload,\n isValid: isValid\n });\n\n // Trigger PBRE Live Evaluation\n if (this.policyEngine && fieldKey) {\n if (this.policyDebounceTimer) clearTimeout(this.policyDebounceTimer);\n this.policyDebounceTimer = setTimeout(() => {\n this.evaluatePolicies();\n }, 200);\n }\n }\n\n /**\n * Executes the PBRE policy evaluations and orchestrates the delta updates to the UI plugins.\n * Acts as the bridge between the headless PolicyEngine calculations and the physical UI5 plugins.\n * \n * @param changedPath The specific JSON path that triggered the evaluation (used for incremental sweeps).\n * If undefined, a full engine sweep is performed (e.g. during initial render or manual submit).\n */\n private evaluatePolicies(): void {\n if (!this.policyEngine || !this.stateManager || !this.engine) return;\n const payload = this.stateManager.extractPayload();\n const deltas = this.policyEngine.evaluate(payload);\n for (const delta of deltas) {\n const plugin = this.engine.getPluginByPath(delta.target);\n if (plugin) {\n // Systemic Failsafe: State Pruning on Hide/Disable\n if ((delta.property === \"visibility\" || delta.property === \"editable\") && delta.value === false) {\n this.stateManager.setProperty(delta.target, undefined); \n }\n\n switch (delta.property) {\n case \"visibility\": \n if (plugin.applyVisibility) plugin.applyVisibility(delta.value);\n break;\n case \"validity\":\n if (delta.value) {\n this.engine.reportPolicyError(delta.target, null);\n } else {\n this.engine.reportPolicyError(delta.target, delta.errorMessage || \"Validation failed by policy\");\n }\n break;\n case \"required\":\n if (plugin.applyRequired) plugin.applyRequired(delta.value);\n break;\n case \"editable\":\n if (plugin.applyEditable) plugin.applyEditable(delta.value);\n break;\n }\n }\n }\n }\n\n /**\n * Standard UI5 Exit Hook. Ensures complete teardown of the engine and state manager.\n */\n public exit(): void {\n if (this.engine) {\n this.engine.destroy();\n this.engine = null;\n }\n\n if (this.stateManager) {\n this.stateManager.getModel().destroy();\n this.stateManager = null;\n }\n\n if (this.generatedContent) {\n this.generatedContent.destroy();\n this.generatedContent = null;\n }\n }\n\n /** Cached schema for intelligent diffing during inference mode hot-swaps */\n protected parsedSchema: Record<string, unknown> | null = null;\n\n /**\n * Exposes the parsed schema to the DataSyncDelegate for diffing.\n */\n public getParsedSchema(): Record<string, unknown> | null {\n return this.parsedSchema;\n }\n\n /**\n * Standard UI5 Rendering Hook.\n * Evaluates whether it possesses a schema or data. If so, triggers the internal engine generation.\n */\n public onBeforeRendering(): void {\n if (this.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI GeneratorHost]\", `onBeforeRendering called. Engine boot state: schemaDefinition exists = ${!!this.getProperty(\"schemaDefinition\")}, data exists = ${!!this.getProperty(\"data\")}, dataJson exists = ${!!this.getProperty(\"dataJson\")}`, \"GeneratorHost\");\n }\n\n if (!this.generatedContent) {\n const hasSchema = !!this.getProperty(\"schemaDefinition\");\n const hasData = !!this.getProperty(\"dataJson\") || !!this.getProperty(\"data\");\n\n if (hasSchema || hasData) {\n this.generate();\n } else {\n const msg = \"GeneratorHost skipped rendering. Neither 'schemaDefinition' nor 'data' was provided.\";\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg });\n throw new Error(msg); // Eradicate silent errors\n }\n }\n }\n\n /**\n * Public API method to manually trigger form submission.\n * Executes all structural validations, clears old messages, and pushes payload to bindings.\n * @returns boolean True if submission succeeded, false if validation failed.\n */\n public triggerSubmit(): boolean {\n if (this.stateManager && this.engine) {\n let isPrevented = false;\n\n this.validationDelegate.removeAllMessages();\n\n // Run PBRE Full Sweep before validation to ensure visibility states are perfect\n if (this.policyEngine) {\n this.evaluatePolicies();\n }\n\n // PBRE Architecture Rule 12: Controls are deliberately isolated from UI5's native \n // MessageManager auto-sync. We must explicitly instruct plugins to paint their \n // visual red borders (ValueState) manually during a full form submission sweep.\n const errors = this.engine.validateAll(true);\n if (errors.length > 0) {\n if (this.getProperty(\"useMessageManager\") === true) {\n this.validationDelegate.pushMessage(\"\", \"One or more fields failed schema validation. Please review the highlighted fields.\");\n }\n for (const err of errors) {\n if (err.fieldKey && err.errorMessage) {\n this.validationDelegate.pushMessage(err.fieldKey, err.errorMessage, err.fieldLabel);\n }\n }\n return false;\n }\n\n const payload = this.stateManager.extractPayload();\n const payloadJson = JSON.stringify(payload);\n\n this.fireEvent(\"beforeSubmit\", {\n payload,\n preventDefault: () => { isPrevented = true; },\n addError: (propertyPath: string, errorMessage: string) => {\n isPrevented = true;\n if (this.getProperty(\"useMessageManager\") === true) {\n this.validationDelegate.pushMessage(propertyPath, errorMessage);\n }\n if (this.engine) {\n const plugin = this.engine.getPluginByPath(propertyPath);\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n plugin.setVisualValidationState(false, errorMessage);\n }\n }\n }\n });\n\n if (isPrevented) {\n return false;\n }\n\n this.dataSyncDelegate.pushToBindings(payload);\n this.fireEvent(\"submit\", { payload, payloadJson });\n return true;\n }\n return false;\n }\n\n /**\n * Injects a custom error message onto a specific field.\n */\n public addCustomError(fieldPath: string, message: string): void {\n this.validationDelegate.addCustomError(fieldPath, message);\n if (this.getProperty(\"useMessageManager\") !== true && this.engine) {\n const plugin = this.engine.getPluginByPath(fieldPath);\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n plugin.setVisualValidationState(false, message);\n }\n }\n }\n\n /**\n * Clears a custom error message from a specific field.\n */\n public clearCustomError(fieldPath: string): void {\n this.validationDelegate.clearCustomError(fieldPath);\n if (this.getProperty(\"useMessageManager\") !== true && this.engine) {\n const plugin = this.engine.getPluginByPath(fieldPath);\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n const schemaValid = plugin.validate();\n plugin.setVisualValidationState(schemaValid.isValid, schemaValid.errorMessage);\n }\n }\n }\n\n /**\n * Toggles busy state on the host control.\n */\n public setBusy(isBusy: boolean): this {\n super.setBusy(isBusy);\n return this;\n }\n\n /**\n * Intercepts property changes. Hot-swaps data gracefully if it's an inputData change,\n * or forces a full UI teardown if it's a structural property change (like schemaDefinition).\n */\n public setProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n if (propertyName === \"useMessageManager\" && this.stateManager) {\n this.stateManager.setUseMessageManager(value === true);\n }\n\n if (propertyName === \"dataJson\" || propertyName === \"data\") {\n this.dataSyncDelegate.handleInputDataHotSwap(propertyName, value, suppressInvalidate);\n return this;\n }\n\n if (propertyName === \"editable\" || propertyName === \"debugMode\" || propertyName === \"schemaDefinition\" || propertyName === \"schemaTarget\") {\n const currentVal = this.getProperty(propertyName);\n if (currentVal !== value) {\n super.setProperty(propertyName, value, suppressInvalidate);\n this.tearDownGeneratedLayout();\n }\n return this;\n }\n\n return super.setProperty(propertyName, value, suppressInvalidate);\n }\n\n /**\n * Bypasses the interceptor to write directly to the base UI5 control.\n */\n public setBaseProperty(propertyName: string, value: unknown, suppressInvalidate?: boolean): this {\n return super.setProperty(propertyName, value, suppressInvalidate);\n }\n\n /**\n * Internal reference to the active generate promise.\n * Prevents concurrent redundant layouts from being generated when properties are set rapidly or DialogDelegate triggers it.\n */\n private _generatePromise: Promise<void> | null = null;\n\n /**\n * The core rendering pipeline entry point.\n * Uses Promise resolution to debounce concurrent or rapid consecutive calls natively without arbitrary timeouts.\n * @returns Promise that resolves when the layout is successfully built and mounted.\n */\n public async generate(): Promise<void> {\n if (this._generatePromise) {\n return this._generatePromise;\n }\n this._generatePromise = Promise.resolve().then(async () => {\n try {\n await this._doGenerate();\n } catch (e) {\n Logger.error(\"[MetaUI]\", \"Error in deferred generate: \" + e, \"GeneratorHost\");\n throw e; // Ensure it bubbles up to awaiters\n } finally {\n this._generatePromise = null;\n }\n });\n return this._generatePromise;\n }\n\n /**\n * The underlying synchronous generator orchestration method.\n * Normalizes the schema, sets up the state manager, loads missing plugins over the network,\n * orchestrates the Engine build, and mounts the generated UI components into the internal tree.\n */\n private async _doGenerate(): Promise<void> {\n try {\n this.tearDownGeneratedLayout();\n\n // CRITICAL FIX: Extract the unsaved internal payload BEFORE destroying the state manager\n // Otherwise, toggling editable (or other structural properties) will wipe user inputs!\n let internalPayload = null;\n if (this.stateManager) {\n internalPayload = this.stateManager.extractPayload();\n }\n\n if (this.engine) {\n this.engine.destroy();\n this.engine = null;\n }\n if (this.stateManager) {\n this.stateManager.getModel().destroy();\n this.stateManager = null;\n }\n\n let rawSchema = this.getProperty(\"schemaDefinition\");\n if (rawSchema && typeof rawSchema === \"object\") {\n rawSchema = JSON.parse(JSON.stringify(rawSchema));\n }\n const isSchemaEmpty = !rawSchema || (typeof rawSchema === \"object\" && Object.keys(rawSchema).length === 0);\n\n let inputData = this.getProperty(\"data\");\n const inputDataJson = this.getProperty(\"dataJson\");\n\n let dataParseError = \"\";\n\n if (inputDataJson) {\n try {\n inputData = JSON.parse(inputDataJson as string);\n } catch (e) {\n dataParseError = \"Failed to parse inputDataJson string: \" + (e as Error).message;\n Logger.error(\"[MetaUI]\", dataParseError, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: dataParseError, exception: e });\n inputData = {}; // Fallback to empty object to allow schema to render\n }\n } else if (typeof inputData === \"string\") {\n try {\n inputData = JSON.parse(inputData);\n } catch (e) {\n dataParseError = \"Failed to parse inputData string: \" + (e as Error).message;\n Logger.error(\"[MetaUI]\", dataParseError, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: dataParseError, exception: e });\n inputData = {}; // Fallback to empty object to allow schema to render\n }\n }\n\n // The internal payload represents the user's latest un-extracted edits. It must take priority, unless an external data-swap failed.\n const finalData = dataParseError ? inputData : (internalPayload || inputData);\n\n if (!finalData || Object.keys(finalData).length === 0) {\n if (isSchemaEmpty) {\n const msg = \"No payload provided and no explicit schema defined. Cannot infer UI.\";\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg });\n throw new Error(msg);\n }\n }\n\n const schemaToNormalize = isSchemaEmpty ? null : rawSchema;\n const normalizedSchema = SchemaNormalizer.normalize(schemaToNormalize, finalData);\n\n // Cache the parsed/inferred schema so DataSyncDelegate can diff against it later\n this.parsedSchema = normalizedSchema as Record<string, unknown>;\n\n if (normalizedSchema) {\n if (normalizedSchema.uiPolicies && normalizedSchema.uiPolicies.length > 0) {\n this.policyEngine = new PolicyEngine(normalizedSchema.uiPolicies);\n } else {\n this.policyEngine = null;\n }\n\n const schemaErrors = SchemaValidator.validateSchemaStructure(normalizedSchema);\n if (schemaErrors.length > 0) {\n const errorMsg = \"Schema Structural Errors Found:\\n- \" + schemaErrors.join(\"\\n- \");\n // Let's log it out loudly regardless of debug mode, so developers can see why it didn't render\n Logger.error(\"[MetaUI]\", errorMsg, \"GeneratorHost\");\n if (this.getProperty(\"debugMode\")) {\n MessageBox.error(errorMsg, { title: \"MetaUI Schema Error\" });\n return;\n }\n }\n }\n\n const rawDefinitions = this.getProperty(\"schemaDefinitions\") as Record<string, any> || {};\n \n // Extract any definitions embedded inside the root schema definition\n let parsedRawSchema = rawSchema;\n if (typeof rawSchema === \"string\" && rawSchema.trim() !== \"\") {\n try {\n parsedRawSchema = JSON.parse(rawSchema);\n } catch (e) {\n // Ignore parse errors here; SchemaNormalizer will throw loudly later if invalid.\n }\n }\n\n if (parsedRawSchema && typeof parsedRawSchema === \"object\" && (parsedRawSchema as any).definitions) {\n Object.assign(rawDefinitions, (parsedRawSchema as any).definitions);\n this.setProperty(\"schemaDefinitions\", rawDefinitions, true);\n }\n\n let normalizedDefinitions: Record<string, ISchema> | undefined;\n if (Object.keys(rawDefinitions).length > 0) {\n normalizedDefinitions = {};\n for (const key in rawDefinitions) {\n try {\n normalizedDefinitions[key] = SchemaNormalizer.normalize(rawDefinitions[key]) as ISchema;\n } catch (e) {\n Logger.warn(`[MetaUI] Failed to normalize schema definition '${key}'`, \"\", \"GeneratorHost\");\n }\n }\n }\n\n const budget = this.getProperty(\"layoutBudget\") as number;\n\n // Ensure we have a uiLayout synthesized before applying scoring and mutation \n // (crucial for inferred/swagger schemas)\n if (DefaultLayoutGenerator.ensureLayout(normalizedSchema as ISchema)) {\n Logger.warn(\"[MetaUI GeneratorHost] Missing 'uiLayout' array in schema. Synthesized a default layout mapping to prevent a blank render.\");\n }\n\n LayoutScorer.apply(normalizedSchema as ISchema, budget, normalizedDefinitions);\n LayoutMutator.apply(normalizedSchema as ISchema);\n\n const activePluginRegistry = this.getProperty(\"pluginRegistry\") || PluginRegistry.getInstance();\n \n const pathsToLoad = activePluginRegistry.getPathsToLoad(normalizedSchema as ISchema);\n const needsNetworkLoad = Array.from(pathsToLoad).some((path: any) => !sap.ui.require(path));\n\n if (needsNetworkLoad) {\n this.setBusy(true);\n await activePluginRegistry.preloadDependencies(normalizedSchema as ISchema);\n this.setBusy(false);\n }\n\n // Inject defaults into empty payload values\n if (normalizedSchema && finalData) {\n this.dataSyncDelegate.injectSchemaDefaults(normalizedSchema, finalData);\n }\n\n this.activeModelName = \"metaUI_\" + this.getId();\n this.stateManager = new StateManager(finalData, normalizedSchema, this.activeModelName);\n this.stateManager.setUseMessageManager(this.getProperty(\"useMessageManager\") === true);\n this.setModel(this.stateManager.getModel(), this.activeModelName);\n\n if (!this.engine) {\n const isEditable = this.getProperty(\"editable\") !== false;\n const useMessageManager = this.getProperty(\"useMessageManager\") === true;\n const activePluginRegistry = this.getProperty(\"pluginRegistry\") || PluginRegistry.getInstance();\n this.engine = new Engine(isEditable, useMessageManager, activePluginRegistry);\n this.engine.host = this;\n }\n\n this.generatedContent = this.engine.build(\n normalizedSchema,\n this.stateManager.getModel(),\n this.activeModelName,\n this.triggerSubmit.bind(this),\n this.getId(),\n this.onInternalFieldChange.bind(this)\n );\n\n // Defect #15: PBRE Initialization Blackout - Force headless evaluation of initial visibility state\n if (this.policyEngine) {\n this.evaluatePolicies();\n }\n\n let contentContainer = this.generatedContent;\n\n const hasProperties = normalizedSchema && Object.keys(normalizedSchema).length > 0;\n\n if (!hasProperties) {\n const strip = new MessageStrip({\n text: \"Warning: The generated UI is blank. Reason: The schema (or inferred schema) contains no valid properties to render.\",\n type: \"Warning\",\n showIcon: true,\n showCloseButton: true\n });\n strip.addStyleClass(\"sapUiSmallMargin\");\n contentContainer = new VBox({\n items: [strip]\n });\n } else if (dataParseError) {\n const strip = new MessageStrip({\n text: \"Data Error: \" + dataParseError + \". The form has been rendered with a blank dataset.\",\n type: \"Error\",\n showIcon: true,\n showCloseButton: true\n });\n strip.addStyleClass(\"sapUiSmallMargin\");\n \n if (typeof (contentContainer as any).insertItem === \"function\") {\n (contentContainer as any).insertItem(strip, 0);\n } else if (typeof (contentContainer as any).insertContent === \"function\") {\n (contentContainer as any).insertContent(strip, 0);\n } else {\n contentContainer = new VBox({\n items: [strip, this.generatedContent!]\n });\n }\n } else if (this.engine.hasPartialRenderingErrors) {\n const strip = new MessageStrip({\n text: \"Layout partially rendered. Some fields failed to generate due to configuration errors.\",\n type: \"Warning\",\n showIcon: true,\n showCloseButton: true\n });\n strip.addStyleClass(\"sapUiSmallMarginBottom\");\n contentContainer = new VBox({\n items: [strip, this.generatedContent]\n });\n }\n\n this.setAggregation(\"_content\", contentContainer);\n this.validationDelegate.registerObject(this.generatedContent);\n\n const payload = this.stateManager.extractPayload();\n this.dataSyncDelegate.pushToBindings(payload);\n\n // Retroactively expand the dialog if the heuristic determines it needs more space\n this.dialogDelegate.calculateAndApplyOptimalWidth(this.parsedSchema);\n\n } catch (error) {\n this.setBusy(false);\n const msg = \"Fatal crash during layout generation: \" + (error as Error).message;\n Logger.error(\"[MetaUI]\", msg, \"GeneratorHost\");\n this.fireEvent(\"error\", { message: msg, exception: error });\n this.validationDelegate.mountCrashBoundary(error as Error);\n throw error; // Completely eliminate silent error swallowing\n }\n }\n\n\n\n /**\n * Programmatic API. Re-parents the generated content into a dialog and opens it.\n */\n public openInDialog(title: string = \"Form\", submitButtonText: string = \"OK\", cancelButtonText: string = \"Cancel\", dialogWidth: string = \"auto\", parentView?: Control): void {\n const isGenerated = !!this.generatedContent;\n this.dialogDelegate.openInDialog(title, submitButtonText, isGenerated, cancelButtonText, dialogWidth, parentView);\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls/host"}},{"offset":{"line":15,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","SchemaNormalizer","_____core_SchemaNormalizer","DataSyncDelegate","_isSyncing","constructor","host","this","pushToBindings","payload","payloadStr","JSON","stringify","setProperty","handleInputDataHotSwap","propertyName","value","suppressInvalidate","incomingObj","parse","e","setBaseProperty","getProperty","debug","stateManager","getStateManager","invalidate","getModel","setData","getParsedSchema","parsedSchema","newInferredSchema","inferSchemaFromData","deepEquals","tearDownGeneratedLayout","msg","message","error","Error","a","b","Array","isArray","keysA","Object","keys","keysB","length","key","includes","injectSchemaDefaults","schema","rootData","depth","typedSchema","typedRootData","type","properties","propSchema","undefined","default","tempObj","items","i","__exports","__esModule"],"sources":["DataSyncDelegate.ts"],"sourcesContent":["\nimport { Logger } from \"../../../utils/Logger\";\nimport { SchemaNormalizer } from \"../../../core/SchemaNormalizer\";\nimport PropertyBinding from \"sap/ui/model/PropertyBinding\";\nimport { StateManager } from \"../../../core/StateManager\";\n\nexport interface IHostDataSync {\n getProperty(name: string): unknown;\n setProperty(name: string, value: unknown, suppressInvalidate?: boolean): this;\n setBaseProperty(name: string, value: unknown, suppressInvalidate?: boolean): this;\n getBinding(name: string): unknown;\n invalidate(): void;\n getStateManager(): StateManager | null;\n getParsedSchema?(): Record<string, unknown> | null;\n tearDownGeneratedLayout(): void;\n}\n\n/**\n * Handles two-way data sync, JSON parsing, loop-breaking, and inference structural diffs.\n */\nexport class DataSyncDelegate {\n private host: IHostDataSync;\n private _isSyncing: boolean = false;\n\n /**\n * Initializes a new DataSyncDelegate to handle data payload binding extraction.\n * @param host The parent host interface containing properties.\n */\n constructor(host: IHostDataSync) {\n this.host = host;\n }\n\n /**\n * Natively forces the UI5 framework to push updated properties back up to any bound ViewModels.\n */\n public pushToBindings(payload: Record<string, unknown>): void {\n this._isSyncing = true;\n const payloadStr = JSON.stringify(payload, null, 2);\n\n this.host.setProperty(\"data\", payload, true);\n this.host.setProperty(\"dataJson\", payloadStr, true);\n \n this._isSyncing = false;\n }\n\n /**\n * Intercepts and parses live updates to the data payload from two-way Fiori bindings.\n */\n public handleInputDataHotSwap(propertyName: string, value: unknown, suppressInvalidate?: boolean): void {\n let incomingObj: Record<string, unknown> | null = null;\n\n if (typeof value === \"string\") {\n try {\n incomingObj = JSON.parse(value) as Record<string, unknown>;\n } catch (e) {\n this.host.setBaseProperty(propertyName, value, false); // Invalidate to force rendering engine to display the error strip\n return;\n }\n } else {\n incomingObj = value as Record<string, unknown>;\n }\n\n if (incomingObj === null) {\n this.host.setBaseProperty(propertyName, value, true);\n return;\n }\n\n if (this._isSyncing) {\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Dropped echo for ${propertyName} due to active sync lock`, \"DataSyncDelegate\");\n }\n this.host.setBaseProperty(propertyName, value, suppressInvalidate);\n return;\n }\n\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `Accepted external injection for ${propertyName}`, \"DataSyncDelegate\");\n }\n\n this.host.setBaseProperty(propertyName, value, true);\n\n const stateManager = this.host.getStateManager();\n if (!stateManager) {\n this.host.invalidate();\n return;\n }\n\n try {\n stateManager.getModel().setData(incomingObj, false);\n\n if (!this.host.getProperty(\"schemaDefinition\") && typeof this.host.getParsedSchema === \"function\") {\n const parsedSchema = this.host.getParsedSchema();\n const newInferredSchema = SchemaNormalizer.inferSchemaFromData(incomingObj);\n if (!this.deepEquals(newInferredSchema, parsedSchema)) {\n this.host.tearDownGeneratedLayout();\n this.host.invalidate();\n }\n }\n } catch (e) {\n const msg = `Failed to hot-swap ${propertyName}: ` + (e as Error).message;\n Logger.error(\"[MetaUI]\", msg, \"DataSyncDelegate\");\n throw new Error(msg);\n }\n }\n\n /**\n * Recursively compares two objects for equality, ignoring key order.\n */\n private deepEquals(a: any, b: any): boolean {\n if (a === b) return true;\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (!keysB.includes(key)) return false;\n if (!this.deepEquals(a[key], b[key])) return false;\n }\n\n return true;\n }\n\n /**\n * Recursively scans an ISchema for `default` properties and injects them into the rootData \n * object if those properties are currently undefined.\n * \n * @param schema The MetaUI ISchema tree.\n * @param rootData The data payload to mutate.\n */\n public injectSchemaDefaults(schema: unknown, rootData: unknown, depth: number = 0): void {\n if (!schema || !rootData || typeof rootData !== \"object\" || depth > 8) return;\n\n const typedSchema = schema as Record<string, unknown>;\n const typedRootData = rootData as Record<string, unknown>;\n\n if (typedSchema.type === \"object\" && typedSchema.properties) {\n const properties = typedSchema.properties as Record<string, unknown>;\n for (const key of Object.keys(properties)) {\n const propSchema = properties[key] as Record<string, unknown>;\n \n if (typedRootData[key] === undefined) {\n if (propSchema.default !== undefined) {\n typedRootData[key] = propSchema.default;\n } else if (propSchema.type === \"object\") {\n const tempObj = {};\n this.injectSchemaDefaults(propSchema, tempObj, depth + 1);\n if (Object.keys(tempObj).length > 0) {\n typedRootData[key] = tempObj;\n }\n }\n } else if (typeof typedRootData[key] === \"object\" && typedRootData[key] !== null) {\n this.injectSchemaDefaults(propSchema, typedRootData[key], depth + 1);\n }\n }\n } else if (typedSchema.type === \"array\" && typedSchema.items && Array.isArray(typedRootData)) {\n for (let i = 0; i < typedRootData.length; i++) {\n if (typeof typedRootData[i] === \"object\" && typedRootData[i] !== null) {\n this.injectSchemaDefaults(typedSchema.items, typedRootData[i], depth + 1);\n }\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":16,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","DialogDelegate","activeDialog","requestedWidth","calculatedOptimalWidth","constructor","host","this","openInDialog","title","submitButtonText","isGenerated","cancelButtonText","dialogWidth","parentView","busyDialog","BusyDialog","text","open","genResult","generate","Promise","err","close","error","message","finalWidth","dialog","Dialog","contentWidth","content","beginButton","Button","type","press","success","triggerSubmit","fireEvent","fieldPath","endButton","afterClose","destroy","addDependent","calculateAndApplyOptimalWidth","schema","optimalWidth","calculateOptimalDialogWidth","setContentWidth","requiresWideDialog","visited","WeakSet","scanProperties","props","has","add","key","prop","ui","fullWidth","widget","properties","items","delete","__exports","__esModule"],"sources":["DialogDelegate.ts"],"sourcesContent":["import Dialog from \"sap/m/Dialog\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport BusyDialog from \"sap/m/BusyDialog\";\nimport { Logger } from \"../../../utils/Logger\";\n\nexport interface IHostDialog {\n generate(): Promise<void> | void;\n triggerSubmit(): boolean;\n fireEvent(eventName: string, parameters?: Record<string, unknown>): this;\n}\n\n/**\n * Extracts all popup and dialog generation logic from the Host control.\n */\nexport class DialogDelegate {\n private host: IHostDialog & Control;\n private activeDialog: Dialog | null = null;\n private requestedWidth: string = \"auto\";\n private calculatedOptimalWidth: string = \"auto\";\n\n /**\n * Initializes a new DialogDelegate to handle dialog-based rendering.\n * @param host The parent DynamicHost or GeneratorHost control.\n */\n constructor(host: IHostDialog & Control) {\n this.host = host;\n }\n\n /**\n * Dialog Modality: Opens the generated layout inside a sap.m.Dialog.\n * Automatically wires up customizable submit (default: 'OK') and 'Cancel' buttons.\n */\n public async openInDialog(title: string = \"Form\", submitButtonText: string = \"OK\", isGenerated: boolean, cancelButtonText: string = \"Cancel\", dialogWidth: string = \"auto\", parentView?: Control): Promise<void> {\n this.requestedWidth = dialogWidth;\n this.calculatedOptimalWidth = dialogWidth; // Default fallback\n\n // Mask the complex asynchronous rendering to prevent visual snapping\n const busyDialog = new BusyDialog({ text: \"Building Form...\" });\n busyDialog.open();\n\n try {\n // Force manual generation BEFORE mounting the dialog so the optimal width is perfectly calculated first\n const genResult = this.host.generate();\n if (genResult instanceof Promise) {\n await genResult;\n }\n } catch (err) {\n busyDialog.close();\n Logger.error(\"[MetaUI] Catastrophic error during pre-generation of dialog content\", (err as Error).message, \"DialogDelegate\");\n return;\n }\n\n busyDialog.close();\n\n // The Engine heuristically updated `calculatedOptimalWidth` during `generate()`. Apply it on frame 1.\n const finalWidth = this.requestedWidth === \"auto\" && this.calculatedOptimalWidth !== \"auto\" ? this.calculatedOptimalWidth : this.requestedWidth;\n\n const dialog = new Dialog({\n title: title,\n contentWidth: finalWidth,\n content: [this.host], // Mount host inside the dialog\n beginButton: new Button({\n text: submitButtonText,\n type: \"Emphasized\",\n press: () => {\n try {\n const success = this.host.triggerSubmit();\n if (success) {\n dialog.close();\n }\n } catch (err) {\n Logger.error(\"[MetaUI] Catastrophic error during validation/submit pipeline\", (err as Error).message, \"DialogDelegate\");\n this.host.fireEvent(\"validationError\", { fieldPath: \"root\", message: (err as Error).message });\n }\n }\n }),\n endButton: new Button({\n text: cancelButtonText,\n press: () => {\n this.host.fireEvent(\"cancel\");\n dialog.close();\n }\n }),\n afterClose: () => {\n this.activeDialog = null;\n dialog.destroy();\n }\n });\n\n this.activeDialog = dialog;\n\n if (parentView && typeof parentView.addDependent === \"function\") {\n parentView.addDependent(dialog);\n }\n\n dialog.open();\n }\n\n /**\n * Allows the Engine to retroactively calculate and expand the dialog once the schema is fully parsed.\n */\n public calculateAndApplyOptimalWidth(schema: Record<string, unknown> | null): void {\n const optimalWidth = this.calculateOptimalDialogWidth(schema);\n this.calculatedOptimalWidth = optimalWidth;\n // Only dynamically stretch if the dialog is ALREADY open (e.g., hybrid inference late-loading)\n if (this.activeDialog && this.requestedWidth === \"auto\" && optimalWidth !== \"auto\") {\n this.activeDialog.setContentWidth(optimalWidth);\n }\n }\n\n /**\n * Heuristically calculates optimal dialog width based on schema content.\n */\n private calculateOptimalDialogWidth(schema: Record<string, any> | null): string {\n if (!schema) return \"auto\";\n let requiresWideDialog = false;\n const visited = new WeakSet<object>();\n\n const scanProperties = (props: Record<string, any>) => {\n if (requiresWideDialog) return;\n if (visited.has(props)) return;\n visited.add(props);\n\n for (const key in props) {\n const prop = props[key];\n if (!prop || typeof prop !== \"object\") continue;\n \n if (prop.type === \"array\") {\n requiresWideDialog = true;\n return;\n }\n if (prop.ui?.fullWidth === true) {\n requiresWideDialog = true;\n return;\n }\n if (prop.ui?.widget === \"codeEditor\" || prop.ui?.widget === \"textArea\" || prop.ui?.widget === \"richText\") {\n requiresWideDialog = true;\n return;\n }\n if (prop.properties) scanProperties(prop.properties);\n if (prop.items && prop.items.properties) scanProperties(prop.items.properties);\n }\n \n visited.delete(props);\n };\n\n if (schema.type === \"array\") return \"80vw\";\n if (schema.properties) {\n scanProperties(schema.properties);\n }\n\n return requiresWideDialog ? \"80vw\" : \"auto\";\n }\n}\n"],"mappings":"AAAA,sMAISA,EAAMC,EAAA,UAWR,MAAMC,EAEDC,aAA8B,KAC9BC,eAAyB,OACzBC,uBAAiC,OAMzCC,YAAYC,GACRC,KAAKD,KAAOA,CAChB,CAMA,kBAAaE,CAAaC,EAAgB,OAAQC,EAA2B,KAAMC,EAAsBC,EAA2B,SAAUC,EAAsB,OAAQC,GACxKP,KAAKJ,eAAiBU,EACtBN,KAAKH,uBAAyBS,EAG9B,MAAME,EAAa,IAAIC,EAAW,CAAEC,KAAM,qBAC1CF,EAAWG,OAEX,IAEI,MAAMC,EAAYZ,KAAKD,KAAKc,WAC5B,GAAID,aAAqBE,QAAS,OACxBF,CACV,CACJ,CAAE,MAAOG,GACLP,EAAWQ,QACXxB,EAAOyB,MAAM,sEAAwEF,EAAcG,QAAS,kBAC5G,MACJ,CAEAV,EAAWQ,QAGX,MAAMG,EAAanB,KAAKJ,iBAAmB,QAAUI,KAAKH,yBAA2B,OAASG,KAAKH,uBAAyBG,KAAKJ,eAEjI,MAAMwB,EAAS,IAAIC,EAAO,CACtBnB,MAAOA,EACPoB,aAAcH,EACdI,QAAS,CAACvB,KAAKD,MACfyB,YAAa,IAAIC,EAAO,CACpBf,KAAMP,EACNuB,KAAM,aACNC,MAAOA,KACH,IACI,MAAMC,EAAU5B,KAAKD,KAAK8B,gBAC1B,GAAID,EAAS,CACTR,EAAOJ,OACX,CACJ,CAAE,MAAOD,GACLvB,EAAOyB,MAAM,gEAAkEF,EAAcG,QAAS,kBACtGlB,KAAKD,KAAK+B,UAAU,kBAAmB,CAAEC,UAAW,OAAQb,QAAUH,EAAcG,SACxF,KAGRc,UAAW,IAAIP,EAAO,CAClBf,KAAML,EACNsB,MAAOA,KACH3B,KAAKD,KAAK+B,UAAU,UACpBV,EAAOJ,WAGfiB,WAAYA,KACRjC,KAAKL,aAAe,KACpByB,EAAOc,aAIflC,KAAKL,aAAeyB,EAEpB,GAAIb,UAAqBA,EAAW4B,eAAiB,WAAY,CAC7D5B,EAAW4B,aAAaf,EAC5B,CAEAA,EAAOT,MACX,CAKOyB,8BAA8BC,GACjC,MAAMC,EAAetC,KAAKuC,4BAA4BF,GACtDrC,KAAKH,uBAAyByC,EAE9B,GAAItC,KAAKL,cAAgBK,KAAKJ,iBAAmB,QAAU0C,IAAiB,OAAQ,CAChFtC,KAAKL,aAAa6C,gBAAgBF,EACtC,CACJ,CAKQC,4BAA4BF,GAChC,IAAKA,EAAQ,MAAO,OACpB,IAAII,EAAqB,MACzB,MAAMC,EAAU,IAAIC,QAEpB,MAAMC,EAAkBC,IACpB,GAAIJ,EAAoB,OACxB,GAAIC,EAAQI,IAAID,GAAQ,OACxBH,EAAQK,IAAIF,GAEZ,IAAK,MAAMG,KAAOH,EAAO,CACrB,MAAMI,EAAOJ,EAAMG,GACnB,IAAKC,UAAeA,IAAS,SAAU,SAEvC,GAAIA,EAAKvB,OAAS,QAAS,CACvBe,EAAqB,KACrB,MACJ,CACA,GAAIQ,EAAKC,IAAIC,YAAc,KAAM,CAC7BV,EAAqB,KACrB,MACJ,CACA,GAAIQ,EAAKC,IAAIE,SAAW,cAAgBH,EAAKC,IAAIE,SAAW,YAAcH,EAAKC,IAAIE,SAAW,WAAY,CACtGX,EAAqB,KACrB,MACJ,CACA,GAAIQ,EAAKI,WAAYT,EAAeK,EAAKI,YACzC,GAAIJ,EAAKK,OAASL,EAAKK,MAAMD,WAAYT,EAAeK,EAAKK,MAAMD,WACvE,CAEAX,EAAQa,OAAOV,IAGnB,GAAIR,EAAOX,OAAS,QAAS,MAAO,OACpC,GAAIW,EAAOgB,WAAY,CACnBT,EAAeP,EAAOgB,WAC1B,CAEA,OAAOZ,EAAqB,OAAS,MACzC,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAA9D,iBAAA,OAAA8D,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":17,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","ODataDelegate","odataType","isSyncing","constructor","host","context","this","detectODataType","attachEvent","onFieldChange","oEvent","params","getParameters","fieldPath","value","undefined","handleFieldChange","model","getModel","sClassName","getMetadata","getName","indexOf","syncToEngine","requestObject","then","oData","pushPayload","catch","err","error","message","getObject","cleanData","key","Object","keys","startsWith","setProperty","getProperty","debug","e","__exports","__esModule"],"sources":["ODataDelegate.ts"],"sourcesContent":["import DynamicHost from \"../../DynamicHost\";\nimport { Logger } from \"../../../utils/Logger\";\nimport ODataV4Context from \"sap/ui/model/odata/v4/Context\";\nimport Context from \"sap/ui/model/Context\";\n\nimport Event from \"sap/ui/base/Event\";\n/**\n * Universal OData Delegate.\n * Natively detects and manages two-way synchronization for both OData V2 and V4 contexts\n * without requiring controller-level mappings.\n */\nexport class ODataDelegate {\n private host: DynamicHost;\n private context: ODataV4Context | Context;\n private odataType: \"V2\" | \"V4\" | null = null;\n private isSyncing: boolean = false;\n\n /**\n * Initializes a new instance of the ODataDelegate.\n * \n * @param {DynamicHost} host The parent MetaUI DynamicHost instance managing the UI generation.\n * @param {Context} context The active UI5 Model Context bound to the host.\n */\n constructor(host: DynamicHost, context: ODataV4Context | Context) {\n this.host = host;\n this.context = context;\n this.detectODataType();\n \n // Natively subscribe to the host's field changes to decouple from DynamicHost internals\n this.host.attachEvent(\"fieldChange\", this.onFieldChange, this);\n }\n\n /**\n * Event listener wrapper for field changes emitted by the host.\n */\n private onFieldChange(oEvent: Event): void {\n const params = oEvent.getParameters() as any;\n if (params.fieldPath && params.value !== undefined) {\n this.handleFieldChange(params.fieldPath, params.value);\n }\n }\n\n /**\n * Evaluates the underlying UI5 Model bound to the context to determine if it is an\n * OData V2 or OData V4 model. This determination drives the synchronization strategy.\n * \n * @private\n */\n private detectODataType(): void {\n const model = this.context.getModel();\n // sap.ui.model.odata.v4.ODataModel\n // sap.ui.model.odata.v2.ODataModel\n const sClassName = model.getMetadata().getName();\n if (sClassName.indexOf(\"v4\") > -1) {\n this.odataType = \"V4\";\n } else if (sClassName.indexOf(\"v2\") > -1 || sClassName.indexOf(\"ODataModel\") > -1) {\n this.odataType = \"V2\";\n }\n }\n\n /**\n * Extracts the full entity payload from the bound OData context and pushes it to the Engine.\n * V4 uses an asynchronous requestObject(), while V2 retrieves it synchronously.\n * \n * @public\n */\n public syncToEngine(): void {\n if (!this.odataType) return;\n\n if (this.odataType === \"V4\") {\n // V4 uses async requestObject()\n if (typeof (this.context as any).requestObject === \"function\") {\n (this.context as any).requestObject().then((oData: unknown) => {\n this.pushPayload(oData);\n }).catch((err: Error) => {\n Logger.error(\"[MetaUI]\", \"Failed to extract V4 Context payload: \" + err.message, \"ODataDelegate\");\n });\n }\n } else if (this.odataType === \"V2\") {\n // V2 uses sync getObject()\n const oData = this.context.getObject();\n if (oData) {\n this.pushPayload(oData);\n }\n }\n }\n\n /**\n * Cleans the raw OData payload by stripping framework metadata properties (keys starting with '@' or '__')\n * and pushes the sanitized business data into the MetaUI DynamicHost state manager.\n * \n * @param {unknown} oData The raw JSON object extracted from the OData model context.\n * @private\n */\n private pushPayload(oData: unknown): void {\n if (!oData) return;\n \n // Remove OData metadata properties before pushing to MetaUI\n const cleanData = { ...(oData as Record<string, unknown>) };\n for (const key of Object.keys(cleanData)) {\n if (key.startsWith(\"@\") || key.startsWith(\"__\")) {\n delete cleanData[key];\n }\n }\n\n this.isSyncing = true;\n this.host.setProperty(\"data\", cleanData);\n this.isSyncing = false;\n }\n\n /**\n * Intercepts a field change from the MetaUI Engine and translates it into an OData PATCH.\n */\n public handleFieldChange(fieldPath: string, value: unknown): void {\n if (this.isSyncing || !this.odataType) return;\n\n try {\n if (this.odataType === \"V4\") {\n // V4 sets property directly on context\n (this.context as any).setProperty(fieldPath, value);\n } else if (this.odataType === \"V2\") {\n // V2 sets property on model, specifying the context path\n const model = this.context.getModel();\n (model as any).setProperty(fieldPath, value, this.context);\n }\n if (this.host.getProperty(\"debugMode\")) {\n Logger.debug(\"[MetaUI]\", `ODataDelegate Patched ${fieldPath} = ${value} via ${this.odataType}`, \"ODataDelegate\");\n }\n } catch (e) {\n Logger.error(\"[MetaUI]\", `Failed to patch OData context: ${(e as Error).message}`, \"ODataDelegate\");\n }\n }\n}\n"],"mappings":"AAAA,8IACSA,EAAMC,EAAA,UAUR,MAAMC,EAGDC,UAAgC,KAChCC,UAAqB,MAQ7BC,YAAYC,EAAmBC,GAC3BC,KAAKF,KAAOA,EACZE,KAAKD,QAAUA,EACfC,KAAKC,kBAGLD,KAAKF,KAAKI,YAAY,cAAeF,KAAKG,cAAeH,KAC7D,CAKQG,cAAcC,GAClB,MAAMC,EAASD,EAAOE,gBACtB,GAAID,EAAOE,WAAaF,EAAOG,QAAUC,UAAW,CAChDT,KAAKU,kBAAkBL,EAAOE,UAAWF,EAAOG,MACpD,CACJ,CAQQP,kBACJ,MAAMU,EAAQX,KAAKD,QAAQa,WAG3B,MAAMC,EAAaF,EAAMG,cAAcC,UACvC,GAAIF,EAAWG,QAAQ,OAAS,EAAG,CAC/BhB,KAAKL,UAAY,IACrB,MAAO,GAAIkB,EAAWG,QAAQ,OAAS,GAAKH,EAAWG,QAAQ,eAAiB,EAAG,CAC/EhB,KAAKL,UAAY,IACrB,CACJ,CAQOsB,eACH,IAAKjB,KAAKL,UAAW,OAErB,GAAIK,KAAKL,YAAc,KAAM,CAEzB,UAAYK,KAAKD,QAAgBmB,gBAAkB,WAAY,CAC1DlB,KAAKD,QAAgBmB,gBAAgBC,KAAMC,IACxCpB,KAAKqB,YAAYD,KAClBE,MAAOC,IACN/B,EAAOgC,MAAM,WAAY,yCAA2CD,EAAIE,QAAS,kBAEzF,CACJ,MAAO,GAAIzB,KAAKL,YAAc,KAAM,CAEhC,MAAMyB,EAAQpB,KAAKD,QAAQ2B,YAC3B,GAAIN,EAAO,CACPpB,KAAKqB,YAAYD,EACrB,CACJ,CACJ,CASQC,YAAYD,GAChB,IAAKA,EAAO,OAGZ,MAAMO,EAAY,IAAMP,GACxB,IAAK,MAAMQ,KAAOC,OAAOC,KAAKH,GAAY,CACtC,GAAIC,EAAIG,WAAW,MAAQH,EAAIG,WAAW,MAAO,QACtCJ,EAAUC,EACrB,CACJ,CAEA5B,KAAKJ,UAAY,KACjBI,KAAKF,KAAKkC,YAAY,OAAQL,GAC9B3B,KAAKJ,UAAY,KACrB,CAKOc,kBAAkBH,EAAmBC,GACxC,GAAIR,KAAKJ,YAAcI,KAAKL,UAAW,OAEvC,IACI,GAAIK,KAAKL,YAAc,KAAM,CAExBK,KAAKD,QAAgBiC,YAAYzB,EAAWC,EACjD,MAAO,GAAIR,KAAKL,YAAc,KAAM,CAEhC,MAAMgB,EAAQX,KAAKD,QAAQa,WAC1BD,EAAcqB,YAAYzB,EAAWC,EAAOR,KAAKD,QACtD,CACA,GAAIC,KAAKF,KAAKmC,YAAY,aAAc,CACpCzC,EAAO0C,MAAM,WAAY,yBAAyB3B,OAAeC,SAAaR,KAAKL,YAAa,gBACpG,CACJ,CAAE,MAAOwC,GACL3C,EAAOgC,MAAM,WAAY,kCAAmCW,EAAYV,UAAW,gBACvF,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAA1C,gBAAA,OAAA0C,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":18,"column":0},"map":{"version":3,"names":["Logger","_____utils_Logger","ValidationDelegate","constructor","host","this","registerObject","control","unregisterObject","removeAllMessages","stateManager","getStateManager","getProperty","messageManager","Messaging","messages","getMessageModel","getData","messagesToRemove","filter","m","getMessageProcessor","getId","getModel","length","removeMessages","pushMessage","path","text","label","targetPath","replace","displayLabel","displayText","warn","addMessages","Message","message","additionalText","undefined","type","coreLibrary","MessageType","Error","target","processor","addCustomError","fieldPath","code","clearCustomError","processorId","getTarget","getCode","mountCrashBoundary","error","errorPage","IllustratedMessage","title","description","setAggregation","__exports","__esModule"],"sources":["ValidationDelegate.ts"],"sourcesContent":["import IllustratedMessage from \"sap/m/IllustratedMessage\";\nimport Messaging from \"sap/ui/core/Messaging\";\nimport Control from \"sap/ui/core/Control\";\nimport { StateManager } from \"../../../core/StateManager\";\nimport { Logger } from \"../../../utils/Logger\";\nimport Message from \"sap/ui/core/message/Message\";\nimport coreLibrary from \"sap/ui/core/library\";\n\nexport interface IHostValidation {\n getProperty(name: string): unknown;\n setAggregation(aggregationName: string, object: Control, suppressInvalidate?: boolean): this;\n getStateManager(): StateManager | null;\n}\n\n/**\n * Handles Fiori MessageManager integration and provides a standardized Error Boundary UI fallback.\n */\nexport class ValidationDelegate {\n private host: IHostValidation;\n\n /**\n * Initializes the ValidationDelegate for registering controls to the global MessageManager.\n * @param host The parent host interface.\n */\n constructor(host: IHostValidation) {\n this.host = host;\n }\n\n /**\n * Registers a control and all its children with the global MessageManager.\n * (Deprecated: Native registration causes UI5 to aggressively clear custom schema validation messages \n * on every keystroke. MetaUI handles valueState manually via plugins).\n */\n public registerObject(control: Control): void {\n // Do nothing to prevent UI5 from hijacking valueState and clearing our manual messages\n }\n\n /**\n * Unregisters a control from the global MessageManager.\n */\n public unregisterObject(control: Control): void {\n // Do nothing\n }\n\n public removeAllMessages(): void {\n const stateManager = this.host.getStateManager();\n if (stateManager && this.host.getProperty(\"useMessageManager\")) {\n const messageManager = Messaging;\n const messages = messageManager.getMessageModel().getData();\n const messagesToRemove = messages.filter((m: Message) =>\n m.getMessageProcessor() && m.getMessageProcessor().getId() === stateManager.getModel().getId()\n );\n if (messagesToRemove && messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n }\n }\n\n /**\n * Pushes a validation message to the console, and optionally to the MessageManager.\n * @param path The JSON pointer path of the field.\n * @param text The error message.\n * @param label The human-readable label of the field (optional).\n */\n public pushMessage(path: string, text: string, label?: string): void {\n const targetPath = path ? `/${path.replace(/^\\//, \"\")}` : \"\";\n const displayLabel = label || path;\n const displayText = path ? `Field '${displayLabel}': ${text}` : text;\n\n if (path) {\n Logger.warn(`[MetaUI Validation Error] ${displayText}`);\n } else {\n Logger.warn(`[MetaUI Validation Error] Global - ${text}`);\n }\n\n if (this.host.getProperty(\"useMessageManager\") === true) {\n const messageManager = Messaging;\n const stateManager = this.host.getStateManager();\n messageManager.addMessages(new Message({\n message: displayText,\n additionalText: displayLabel !== targetPath ? displayLabel : undefined,\n type: coreLibrary.MessageType.Error,\n target: targetPath,\n processor: stateManager?.getModel()\n }));\n }\n }\n\n /**\n * Imperatively invalidates a field and highlights it with an error message.\n * Uses a specific 'CustomError' code to distinguish it from internal schema validations.\n * \n * @param fieldPath The internal JSON path of the field to highlight.\n * @param message The custom error message to display.\n */\n public addCustomError(fieldPath: string, message: string): void {\n if (this.host.getProperty(\"useMessageManager\") !== true) {\n return;\n }\n\n const stateManager = this.host.getStateManager();\n if (!stateManager) {\n return;\n }\n\n Messaging.addMessages(new Message({\n message: message,\n type: coreLibrary.MessageType.Error,\n target: `/${fieldPath.replace(/^\\//, \"\")}`,\n processor: stateManager.getModel(),\n code: \"CustomError\"\n }));\n }\n\n /**\n * Reverts a custom error state on a field, safely ignoring native schema validations.\n * \n * @param fieldPath The internal JSON path of the field to clear.\n */\n public clearCustomError(fieldPath: string): void {\n if (this.host.getProperty(\"useMessageManager\") !== true) {\n return;\n }\n\n const stateManager = this.host.getStateManager();\n if (!stateManager) {\n return;\n }\n\n const target = `/${fieldPath.replace(/^\\//, \"\")}`;\n const processorId = stateManager.getModel().getId();\n const messages = Messaging.getMessageModel().getData() as Message[];\n\n const messagesToRemove = messages.filter(m =>\n m.getTarget() === target &&\n m.getCode() === \"CustomError\" &&\n m.getMessageProcessor()?.getId() === processorId\n );\n\n if (messagesToRemove.length > 0) {\n Messaging.removeMessages(messagesToRemove);\n }\n }\n\n /**\n * Triggers a visual Error Page (Crash Boundary) when generation catastrophically fails.\n */\n public mountCrashBoundary(error: Error): void {\n Logger.error(\"[MetaUI] Engine failed to generate layout. Preventing Launchpad crash.\", error.message, \"ValidationDelegate\");\n\n const errorPage = new IllustratedMessage({\n title: \"UI Generation Failed\",\n description: \"The dynamic schema could not be rendered. Please check the Fiori console for diagnostic logs.\"\n });\n\n this.host.setAggregation(\"_content\", errorPage);\n }\n}\n"],"mappings":"AAAA,kQAISA,EAAMC,EAAA,UAaR,MAAMC,EAOTC,YAAYC,GACRC,KAAKD,KAAOA,CAChB,CAOOE,eAAeC,GAClB,CAMGC,iBAAiBD,GACpB,CAGGE,oBACH,MAAMC,EAAeL,KAAKD,KAAKO,kBAC/B,GAAID,GAAgBL,KAAKD,KAAKQ,YAAY,qBAAsB,CAC5D,MAAMC,EAAiBC,EACvB,MAAMC,EAAWF,EAAeG,kBAAkBC,UAClD,MAAMC,EAAmBH,EAASI,OAAQC,GACtCA,EAAEC,uBAAyBD,EAAEC,sBAAsBC,UAAYZ,EAAaa,WAAWD,SAE3F,GAAIJ,GAAoBA,EAAiBM,OAAS,EAAG,CACjDX,EAAeY,eAAeP,EAClC,CACJ,CACJ,CAQOQ,YAAYC,EAAcC,EAAcC,GAC3C,MAAMC,EAAaH,EAAO,IAAIA,EAAKI,QAAQ,MAAO,MAAQ,GAC1D,MAAMC,EAAeH,GAASF,EAC9B,MAAMM,EAAcN,EAAO,UAAUK,OAAkBJ,IAASA,EAEhE,GAAID,EAAM,CACN3B,EAAOkC,KAAK,6BAA6BD,IAC7C,KAAO,CACHjC,EAAOkC,KAAK,sCAAsCN,IACtD,CAEA,GAAIvB,KAAKD,KAAKQ,YAAY,uBAAyB,KAAM,CACrD,MAAMC,EAAiBC,EACvB,MAAMJ,EAAeL,KAAKD,KAAKO,kBAC/BE,EAAesB,YAAY,IAAIC,EAAQ,CACnCC,QAASJ,EACTK,eAAgBN,IAAiBF,EAAaE,EAAeO,UAC7DC,KAAMC,EAAYC,YAAYC,MAC9BC,OAAQd,EACRe,UAAWnC,GAAca,aAEjC,CACJ,CASOuB,eAAeC,EAAmBV,GACrC,GAAIhC,KAAKD,KAAKQ,YAAY,uBAAyB,KAAM,CACrD,MACJ,CAEA,MAAMF,EAAeL,KAAKD,KAAKO,kBAC/B,IAAKD,EAAc,CACf,MACJ,CAEAI,EAAUqB,YAAY,IAAIC,EAAQ,CAC9BC,QAASA,EACTG,KAAMC,EAAYC,YAAYC,MAC9BC,OAAQ,IAAIG,EAAUhB,QAAQ,MAAO,MACrCc,UAAWnC,EAAaa,WACxByB,KAAM,gBAEd,CAOOC,iBAAiBF,GACpB,GAAI1C,KAAKD,KAAKQ,YAAY,uBAAyB,KAAM,CACrD,MACJ,CAEA,MAAMF,EAAeL,KAAKD,KAAKO,kBAC/B,IAAKD,EAAc,CACf,MACJ,CAEA,MAAMkC,EAAS,IAAIG,EAAUhB,QAAQ,MAAO,MAC5C,MAAMmB,EAAcxC,EAAaa,WAAWD,QAC5C,MAAMP,EAAWD,EAAUE,kBAAkBC,UAE7C,MAAMC,EAAmBH,EAASI,OAAOC,GACrCA,EAAE+B,cAAgBP,GAClBxB,EAAEgC,YAAc,eAChBhC,EAAEC,uBAAuBC,UAAY4B,GAGzC,GAAIhC,EAAiBM,OAAS,EAAG,CAC7BV,EAAUW,eAAeP,EAC7B,CACJ,CAKOmC,mBAAmBC,GACtBtD,EAAOsD,MAAM,yEAA0EA,EAAMjB,QAAS,sBAEtG,MAAMkB,EAAY,IAAIC,EAAmB,CACrCC,MAAO,uBACPC,YAAa,kGAGjBrD,KAAKD,KAAKuD,eAAe,WAAYJ,EACzC,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAA1D,qBAAA,OAAA0D,CAAA","ignoreList":[],"sourceRoot":"controls/host/delegates"}},{"offset":{"line":19,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","DefaultLayoutGenerator","ensureLayout","schema","uiLayout","Array","isArray","length","type","props","items","properties","Object","keys","elements","this","generateElementsFromProperties","filter","e","label","title","basePath","key","prop","currentPath","push","scope","error","msg","message","Error","__exports","__esModule"],"sources":["DefaultLayoutGenerator.ts"],"sourcesContent":["/**\n * @file DefaultLayoutGenerator.ts\n * @description Automatically synthesizes a default UI layout for schemas that lack an explicit mapping.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Encapsulates the logic to dynamically build a safe, default layout orchestration\n * when the developer or backend fails to provide an explicit `uiLayout`.\n * \n * By elevating this into a dedicated utility, we avoid polluting layout engines\n * (like FormLayout or TableLayout) with structural inference responsibilities.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class DefaultLayoutGenerator {\n /**\n * Inspects a schema. If it has properties but no `uiLayout`, it synthesizes a default.\n * @param schema The ISchema dictionary.\n * @returns boolean True if a layout was synthesized, false if it already existed or was empty.\n */\n public static ensureLayout(schema: ISchema): boolean {\n // If it already has a valid array, do nothing\n if (schema.uiLayout && Array.isArray(schema.uiLayout) && schema.uiLayout.length > 0) {\n return false;\n }\n\n const isArray = schema.type === \"array\";\n const props = isArray ? schema.items?.properties : schema.properties;\n\n if (!props || Object.keys(props).length === 0) {\n return false; // Nothing to map\n }\n\n const elements = this.generateElementsFromProperties(props, \"#/properties\");\n\n if (isArray) {\n // Table layouts expect an array of flat Controls at the root uiLayout\n // For tables, we flatten the deep elements or just render the root level\n // To keep it safe, we'll just use the flat elements for tables\n schema.uiLayout = elements.filter(e => e.type === \"Control\");\n } else {\n // Form layouts expect a grouped structure\n schema.uiLayout = [\n {\n type: \"Group\",\n label: schema.title,\n elements: elements\n }\n ];\n }\n\n return true;\n }\n\n /**\n * Recursively traverses property metadata to synthesize generic Group and Control layout definitions.\n * @param props The properties object from the schema.\n * @param basePath The absolute JSON scope path to prefix bindings.\n * @returns An array of generated layout element descriptors.\n */\n private static generateElementsFromProperties(props: Record<string, import(\"../interfaces/ISchema\").IPropertyMetadata>, basePath: string): ILayoutElement[] {\n const elements: ILayoutElement[] = [];\n for (const key of Object.keys(props)) {\n try {\n const prop = props[key];\n const currentPath = `${basePath}/${key}`;\n\n // We do not recursively inline nested objects as Groups.\n // MetaUI handles nested objects dynamically via the ObjectPlugin drill-down dialog.\n // This prevents duplicate Tables and infinite recursion on circular $refs.\n elements.push({\n type: \"Control\",\n scope: currentPath\n });\n } catch (error) {\n // Do not swallow errors. A failure to synthesize a property is a critical failure.\n const msg = `[MetaUI] DefaultLayoutGenerator failed to synthesize property '${key}': ${(error as Error).message}`;\n Logger.error(msg);\n throw new Error(msg);\n }\n }\n return elements;\n }\n}\n"],"mappings":"AAAA,wHAAA,MAMSA,EAAMC,EAAA,UAYR,MAAMC,EAMT,mBAAcC,CAAaC,GAEvB,GAAIA,EAAOC,UAAYC,MAAMC,QAAQH,EAAOC,WAAaD,EAAOC,SAASG,OAAS,EAAG,CACjF,OAAO,KACX,CAEA,MAAMD,EAAUH,EAAOK,OAAS,QAChC,MAAMC,EAAQH,EAAUH,EAAOO,OAAOC,WAAaR,EAAOQ,WAE1D,IAAKF,GAASG,OAAOC,KAAKJ,GAAOF,SAAW,EAAG,CAC3C,OAAO,KACX,CAEA,MAAMO,EAAWC,KAAKC,+BAA+BP,EAAO,gBAE5D,GAAIH,EAAS,CAITH,EAAOC,SAAWU,EAASG,OAAOC,GAAKA,EAAEV,OAAS,UACtD,KAAO,CAEHL,EAAOC,SAAW,CACd,CACII,KAAM,QACNW,MAAOhB,EAAOiB,MACdN,SAAUA,GAGtB,CAEA,OAAO,IACX,CAQA,qCAAeE,CAA+BP,EAA0EY,GACpH,MAAMP,EAA6B,GACnC,IAAK,MAAMQ,KAAOV,OAAOC,KAAKJ,GAAQ,CAClC,IACI,MAAMc,EAAOd,EAAMa,GACnB,MAAME,EAAc,GAAGH,KAAYC,IAKnCR,EAASW,KAAK,CACVjB,KAAM,UACNkB,MAAOF,GAEf,CAAE,MAAOG,GAEL,MAAMC,EAAM,kEAAkEN,OAAUK,EAAgBE,UACxG9B,EAAO4B,MAAMC,GACb,MAAM,IAAIE,MAAMF,EACpB,CACJ,CACA,OAAOd,CACX,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAA9B,yBAAA,OAAA8B,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":20,"column":0},"map":{"version":3,"names":["PluginRegistry","___PluginRegistry","Logger","___utils_Logger","DefaultLayoutGenerator","___DefaultLayoutGenerator","GlobalPipeline","___PipelineManager","Engine","activePlugins","templatePlugins","validationLedger","Map","isEditable","hasPartialRenderingErrors","useMessageManager","constructor","editable","pluginRegistry","this","getInstance","build","schema","model","modelName","onSubmit","engineScopeId","onChange","activeModel","isValid","fieldKey","errorMessage","controlId","reportSchemaError","layoutStrategy","type","layoutManager","getLayout","render","error","msg","message","showErrorPopup","Text","text","generateField","fieldMeta","bindingPath","isTemplate","plugin","getPlugin","ui","widget","setEditable","setUseMessageManager","push","path","scopeId","undefined","control","generateLayout","ensureLayout","warn","validateAll","applyVisualState","errors","item","result","validate","replace","name","host","getStateManager","stateManager","payload","extractPayload","getSchema","getParsedSchema","arrayErrors","validatePayloadArrays","forEach","err","filter","e","onArrayMutated","arrayPath","clearArrayMessages","currentPath","properties","key","Object","keys","propSchema","childPath","items","Array","isArray","index","itemPath","propMeta","propPath","val","validatorsToRun","argsMap","required","maxLength","minLength","pattern","regex","minimum","maximum","min","max","format","length","res","executeValidation","fieldLabel","label","getPluginByPath","cleanPath","match","find","p","fieldPath","has","set","schemaError","policyError","get","resolveVisualState","reportPolicyError","ledgerEntry","isError","setVisualValidationState","setNativeControlError","targetPath","generatedContent","rootControl","traverseAndSetError","bindingInfos","getBindingInfo","info","parts","boundPath","endsWith","context","getBindingContext","activeModelName","fullPath","getPath","cleanedFullPath","setValueState","setValueStateText","getAggregation","getMetadata","aggs","getAggregations","aggName","child","c","destroy","clear","__exports","__esModule"],"sources":["Engine.ts"],"sourcesContent":["/**\n * @file Engine.ts\n * @description The central orchestrator that routes data between the Layout Factory and Plugin Registry (v2).\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPlugin, IPluginValidationResult } from \"../interfaces/IPlugin\";\n\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport Control from \"sap/ui/core/Control\";\nimport VBox from \"sap/m/VBox\";\nimport Text from \"sap/m/Text\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\nimport { GlobalPipeline } from \"./PipelineManager\";\n\n/**\n * The Engine is responsible for translating a normalized schema into a physical UI5 layout.\n * It delegates layout generation to the configured `LayoutManager` and field generation to the `PluginRegistry`.\n * It strictly routes execution flow and tracks active plugins for validation.\n * It embodies the \"Plugin-First Philosophy\" by routing all complex field and layout rendering\n * through discrete, decoupled plugins rather than handling native overrides.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Engine {\n\n\n /** Array of all instantiated plugins generated during the current build. */\n private activePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Array of template plugins generated for table rows to prevent memory leaks during destruction. */\n private templatePlugins: { plugin: IPlugin, path: string }[] = [];\n\n /** Deterministic scope ID injected by the host control to prevent clone collisions. */\n public engineScopeId?: string;\n\n private activeModel?: unknown;\n\n /** Ledger tracking local vs cross-field errors to prevent visual race conditions. */\n private validationLedger: Map<string, { schemaError: string | null, policyError: string | null }> = new Map();\n\n /** Reference to the GeneratorHost that instantiated this engine, for retrieving global definitions. */\n public host?: unknown;\n\n /** Callback to notify the host that an internal field changed. */\n public onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** Tracks whether the entire engine is running in Editable mode. */\n public readonly isEditable: boolean = true;\n\n /** Tracks if any fields or sub-layouts failed to render, requiring a warning strip. */\n public hasPartialRenderingErrors: boolean = false;\n\n /** Tracks whether the engine should delegate visual state to the global MessageManager. */\n public readonly useMessageManager: boolean = false;\n\n /** The injected PluginRegistry instance */\n public readonly pluginRegistry: PluginRegistry;\n\n /**\n * Initializes a new Engine instance.\n * @param editable Whether the engine should render form fields as editable or read-only.\n * @param useMessageManager Whether to delegate visual state to UI5 MessageManager.\n * @param pluginRegistry Optional injected plugin registry. Defaults to singleton.\n */\n constructor(editable: boolean = true, useMessageManager: boolean = false, pluginRegistry?: PluginRegistry) {\n this.isEditable = editable;\n this.useMessageManager = useMessageManager;\n this.pluginRegistry = pluginRegistry || PluginRegistry.getInstance();\n }\n\n /**\n * Bootstraps the layout generation process by resolving the correct layout strategy.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param model The active StateManager JSONModel instance.\n * @param modelName The UI5 model alias used for isolation.\n * @param onSubmit Callback fired when form is submitted.\n * @param engineScopeId Deterministic scope ID for this engine instance.\n * @param onChange Callback fired when field values change.\n * @returns The generated root UI5 Control container.\n */\n public build(schema: ISchema, model: unknown, modelName: string = \"meta\", onSubmit?: () => void, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n\n this.activePlugins = [];\n this.activeModel = model;\n this.engineScopeId = engineScopeId;\n this.onChange = (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => {\n if (fieldKey) {\n this.reportSchemaError(fieldKey, isValid ? null : errorMessage || \"Invalid input\");\n }\n\n if (onChange) {\n onChange(isValid, fieldKey, errorMessage, controlId);\n }\n };\n\n try {\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = this.pluginRegistry.getLayout(layoutStrategy);\n\n return layoutManager.render(schema, modelName, this, onSubmit);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(\"[MetaUI Engine] Critical error during layout generation\", msg);\n Logger.showErrorPopup(`Engine failed to generate the layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Layout Error\" });\n }\n }\n\n /**\n * Instantiates the correct plugin for a specific field based on type and widget hints,\n * and tracks the plugin for global validation.\n * \n * @param fieldMeta The metadata schema specific to the field.\n * @param bindingPath The JSON path representing the field within the payload.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @returns The generated UI5 Control for the field.\n */\n public generateField(fieldMeta: IPropertyMetadata, bindingPath: string, modelName: string, isTemplate: boolean = false): Control {\n try {\n const plugin = this.pluginRegistry.getPlugin(fieldMeta.type || \"string\", fieldMeta.ui?.widget);\n if (typeof plugin.setEditable === \"function\") {\n plugin.setEditable(this.isEditable);\n }\n\n if (typeof plugin.setUseMessageManager === \"function\") {\n plugin.setUseMessageManager(this.useMessageManager);\n }\n\n if (!isTemplate) {\n this.activePlugins.push({ plugin, path: bindingPath });\n } else {\n this.templatePlugins.push({ plugin, path: bindingPath });\n }\n const scopeId = isTemplate ? undefined : this.engineScopeId;\n const control = plugin.render(fieldMeta, bindingPath, modelName, scopeId, this.onChange, this.activeModel);\n\n\n\n return control;\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Failed to generate field at ${bindingPath}`, msg);\n Logger.showErrorPopup(`Failed to generate field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n return new Text({ text: `[Error generating field ${bindingPath}]` });\n }\n }\n\n /**\n * Generates a sub-layout (like an embedded table or nested form) without \n * destroying the current Engine state or Condition tracking.\n * \n * @param schema The normalized JSON schema representing the view.\n * @param modelName The UI5 JSONModel name used for data binding (defaults to \"meta\").\n * @param bindingPath Optional path to bind the sub-layout to a specific array/object property.\n * @returns The generated root UI5 Control container.\n */\n public generateLayout(schema: ISchema, modelName: string, bindingPath?: string): Control {\n try {\n if (DefaultLayoutGenerator.ensureLayout(schema)) {\n Logger.warn(`[MetaUI Engine] Missing 'uiLayout' array in sub-schema for ${bindingPath}. Synthesized a default layout mapping.`);\n }\n\n const layoutStrategy = schema.layoutStrategy || (schema.type === \"array\" ? \"table\" : \"form\");\n const layoutManager = this.pluginRegistry.getLayout(layoutStrategy);\n return layoutManager.render(schema, modelName, this, undefined, bindingPath);\n } catch (error) {\n this.hasPartialRenderingErrors = true;\n const msg = (error as Error).message;\n Logger.error(`[MetaUI Engine] Critical error generating sub-layout for ${bindingPath}`, msg);\n Logger.showErrorPopup(`Engine failed to generate a sub-layout.\\n\\nDetails: ${msg}`);\n return new Text({ text: \"Critical Sub-Layout Error\" });\n }\n }\n\n /**\n * Iterates through all active plugins and triggers their internal validation pipelines.\n * \n * @param applyVisualState If true, explicitly instructs the plugin to natively paint its own ValueState.\n * @returns {IPluginValidationResult[]} Array of validation error objects. Empty array if valid.\n */\n public validateAll(applyVisualState: boolean = false): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n for (const item of this.activePlugins) {\n try {\n const result = item.plugin.validate();\n if (applyVisualState) {\n this.reportSchemaError(item.path, result.isValid ? null : result.errorMessage || \"Invalid input\");\n }\n\n if (!result.isValid) {\n // Ensure the path is bound to the error so GeneratorHost knows where to target it\n result.fieldKey = result.fieldKey || item.path.replace(/^\\//, \"\");\n errors.push(result);\n // Add console log to find which plugin fails silently\n Logger.error(\"[MetaUI Validation] Plugin failed validation silently:\", item.path || item.plugin.constructor.name);\n }\n } catch (error) {\n Logger.error(`[MetaUI Engine] Error validating plugin at ${item.path}`, (error as Error).message);\n }\n }\n\n // 2. Recursively validate arrays via StateManager payload traversing for Table layout rows\n if (this.host && typeof (this.host as any).getStateManager === \"function\") {\n const stateManager = (this.host as any).getStateManager();\n if (stateManager) {\n const payload = stateManager.extractPayload();\n const schema = stateManager.getSchema ? stateManager.getSchema() : (this.host as any).getParsedSchema?.();\n if (payload && schema) {\n const arrayErrors = this.validatePayloadArrays(schema, payload, \"\");\n if (applyVisualState) {\n arrayErrors.forEach(err => {\n if (err.fieldKey) {\n this.reportSchemaError(err.fieldKey, err.isValid ? null : err.errorMessage || \"Invalid input\");\n }\n });\n }\n errors.push(...arrayErrors.filter(e => !e.isValid));\n }\n }\n }\n\n return errors;\n }\n\n public onArrayMutated(arrayPath: string): void {\n if (this.host && typeof (this.host as any).getStateManager === \"function\") {\n const stateManager = (this.host as any).getStateManager();\n if (stateManager && typeof stateManager.clearArrayMessages === \"function\") {\n stateManager.clearArrayMessages(arrayPath);\n }\n }\n }\n\n private validatePayloadArrays(schema: any, payload: any, currentPath: string): IPluginValidationResult[] {\n const errors: IPluginValidationResult[] = [];\n if (!schema || !payload || typeof payload !== \"object\") return errors;\n\n if (schema.type === \"object\" && schema.properties) {\n for (const key of Object.keys(schema.properties)) {\n const propSchema = schema.properties[key];\n if (payload[key] !== undefined) {\n const childPath = currentPath ? `${currentPath}/${key}` : key;\n errors.push(...this.validatePayloadArrays(propSchema, payload[key], childPath));\n }\n }\n } else if (schema.type === \"array\" && schema.items && Array.isArray(payload)) {\n payload.forEach((item, index) => {\n const itemPath = currentPath ? `${currentPath}/${index}` : `${index}`;\n if (schema.items.type === \"object\" && schema.items.properties) {\n for (const key of Object.keys(schema.items.properties)) {\n const propMeta = schema.items.properties[key];\n const propPath = `${itemPath}/${key}`;\n const val = item ? item[key] : undefined;\n \n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {};\n\n if (propMeta.required) validatorsToRun.push(\"required\");\n if (propMeta.maxLength !== undefined) {\n validatorsToRun.push(\"maxLength\");\n argsMap[\"maxLength\"] = propMeta.maxLength;\n }\n if (propMeta.minLength !== undefined) {\n validatorsToRun.push(\"minLength\");\n argsMap[\"minLength\"] = propMeta.minLength;\n }\n if (propMeta.pattern !== undefined) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = { regex: propMeta.pattern };\n }\n if (propMeta.minimum !== undefined || propMeta.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: propMeta.minimum, max: propMeta.maximum };\n }\n const format = propMeta.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n \n if (validatorsToRun.length > 0) {\n const res = GlobalPipeline.executeValidation(val, validatorsToRun, argsMap);\n if (!res.isValid) {\n errors.push({\n isValid: false,\n errorMessage: res.errorMessage,\n fieldKey: propPath,\n fieldLabel: propMeta.ui?.label || key\n });\n } else {\n errors.push({ isValid: true, fieldKey: propPath }); // Push successful state to clear old errors\n }\n }\n }\n }\n });\n }\n return errors;\n }\n\n /**\n * Retrieves an active plugin instance by its absolute binding path.\n * Useful for programmatic field manipulation (e.g., custom error injection).\n * \n * @param path The binding path (e.g. \"/General/CustomerName\").\n * @returns {IPlugin | undefined} The plugin instance, or undefined if not found.\n */\n public getPluginByPath(path: string): import(\"../interfaces/IPlugin\").IPlugin | undefined {\n const cleanPath = path.replace(/^\\//, \"\");\n const match = this.activePlugins.find(p => p.path.replace(/^\\//, \"\") === cleanPath);\n return match ? match.plugin : undefined;\n }\n\n /**\n * Reports a localized schema validation error to the coordinator ledger.\n */\n public reportSchemaError(fieldPath: string, errorMessage: string | null): void {\n const cleanPath = fieldPath.replace(/^\\//, \"\");\n if (!this.validationLedger.has(cleanPath)) {\n this.validationLedger.set(cleanPath, { schemaError: null, policyError: null });\n }\n this.validationLedger.get(cleanPath)!.schemaError = errorMessage;\n this.resolveVisualState(cleanPath);\n }\n\n /**\n * Reports a cross-field policy error to the coordinator ledger.\n */\n public reportPolicyError(fieldPath: string, errorMessage: string | null): void {\n const cleanPath = fieldPath.replace(/^\\//, \"\");\n if (!this.validationLedger.has(cleanPath)) {\n this.validationLedger.set(cleanPath, { schemaError: null, policyError: null });\n }\n this.validationLedger.get(cleanPath)!.policyError = errorMessage;\n this.resolveVisualState(cleanPath);\n }\n\n /**\n * Computes the final visual state by checking both engines and applies it to the plugin.\n */\n private resolveVisualState(cleanPath: string): void {\n const plugin = this.getPluginByPath(cleanPath);\n const ledgerEntry = this.validationLedger.get(cleanPath);\n if (!ledgerEntry) return;\n\n const isError = ledgerEntry.policyError !== null || ledgerEntry.schemaError !== null;\n const errorMessage = ledgerEntry.policyError || ledgerEntry.schemaError;\n\n if (plugin && typeof plugin.setVisualValidationState === \"function\") {\n plugin.setVisualValidationState(!isError, isError ? errorMessage || undefined : undefined);\n } else {\n // Un-tracked template clones (Table Layout rows)\n this.setNativeControlError(cleanPath, isError ? errorMessage || undefined : undefined);\n }\n }\n\n private setNativeControlError(targetPath: string, errorMessage?: string): void {\n if (this.host && (this.host as any).generatedContent) {\n const rootControl = (this.host as any).generatedContent;\n this.traverseAndSetError(rootControl, targetPath, errorMessage);\n }\n }\n\n private traverseAndSetError(control: any, targetPath: string, errorMessage?: string): void {\n if (!control) return;\n \n const bindingInfos = [control.getBindingInfo(\"value\"), control.getBindingInfo(\"selectedKey\"), control.getBindingInfo(\"dateValue\"), control.getBindingInfo(\"selected\")];\n for (const info of bindingInfos) {\n if (info && info.parts && info.parts.length > 0) {\n const boundPath = info.parts[0].path;\n // UI5 relative bindings drop the leading slash in the context, but retain it in the path\n if (boundPath === targetPath || targetPath.endsWith(boundPath)) {\n // Ensure we match the exact row context path\n const context = control.getBindingContext((this.host as any).activeModelName);\n if (context) {\n const fullPath = context.getPath() + \"/\" + boundPath;\n const cleanedFullPath = fullPath.replace(/^\\//, \"\");\n if (cleanedFullPath === targetPath) {\n if (typeof control.setValueState === \"function\") {\n control.setValueState(errorMessage ? \"Error\" : \"None\");\n if (typeof control.setValueStateText === \"function\") {\n control.setValueStateText(errorMessage || \"\");\n }\n }\n }\n }\n }\n }\n }\n \n if (typeof control.getAggregation === \"function\" && typeof control.getMetadata === \"function\") {\n const aggs = control.getMetadata().getAggregations();\n for (const aggName in aggs) {\n const child = control.getAggregation(aggName);\n if (Array.isArray(child)) {\n child.forEach(c => this.traverseAndSetError(c, targetPath, errorMessage));\n } else if (child) {\n this.traverseAndSetError(child, targetPath, errorMessage);\n }\n }\n }\n }\n\n /**\n * Cleans up internal state and destroys the condition engine to prevent memory leaks.\n */\n public destroy(): void {\n\n\n for (const item of this.activePlugins) {\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n for (const item of this.templatePlugins) {\n if (typeof item.plugin.destroy === \"function\") {\n item.plugin.destroy();\n }\n }\n\n this.validationLedger.clear();\n this.activePlugins = [];\n this.templatePlugins = [];\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":21,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___SchemaNormalizer","RENDER_MODE","___constants_MetaUIConstants","SCHEMA_TYPE","LayoutMutator","apply","schema","uiLayout","Array","isArray","this","expandElements","elements","rootSchema","expanded","element","type","push","scope","meta","bindingPath","resolveScope","hasExplicitWidget","ui","widget","isInlineObject","OBJECT","renderMode","INLINE","properties","newGroup","label","split","pop","childKey","Object","keys","e","__exports","__esModule"],"sources":["LayoutMutator.ts"],"sourcesContent":["/**\n * @file LayoutMutator.ts\n * @description Intercepts the generated schema before rendering to dynamically mutate the UI layout based on inline rendering rules.\n */\n\nimport { ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { SchemaNormalizer } from \"./SchemaNormalizer\";\nimport { RENDER_MODE, SCHEMA_TYPE } from \"../constants/MetaUIConstants\";\n\nexport class LayoutMutator {\n /**\n * Mutates the `uiLayout` array to expand nested inline objects into native Groups.\n * @param schema The normalized root schema.\n */\n public static apply(schema: ISchema): void {\n if (!schema || !schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n return; // No layout to mutate\n }\n\n schema.uiLayout = this.expandElements(schema.uiLayout, schema);\n }\n\n private static expandElements(elements: ILayoutElement[], rootSchema: ISchema): ILayoutElement[] {\n const expanded: ILayoutElement[] = [];\n\n for (const element of elements) {\n if (element.type === \"Group\") {\n // Recursively expand group elements\n if (element.elements) {\n element.elements = this.expandElements(element.elements, rootSchema);\n }\n expanded.push(element);\n } else if (element.type === \"Control\") {\n if (!element.scope) {\n expanded.push(element);\n continue;\n }\n // Resolve the schema to see if this control points to an inline object\n try {\n const { meta, bindingPath } = SchemaNormalizer.resolveScope(rootSchema, element.scope);\n \n const hasExplicitWidget = !!meta?.ui?.widget;\n const isInlineObject = meta?.type === SCHEMA_TYPE.OBJECT && meta.ui?.renderMode === RENDER_MODE.INLINE && !hasExplicitWidget;\n\n if (isInlineObject && meta.properties) {\n // Transform this Control into a Group containing its properties\n const newGroup: ILayoutElement = {\n ...element,\n type: \"Group\",\n label: element.label || meta.ui?.label || bindingPath.split(\"/\").pop(),\n elements: []\n };\n delete newGroup.scope;\n\n // Add all child properties as controls\n for (const childKey of Object.keys(meta.properties)) {\n newGroup.elements!.push({\n type: \"Control\",\n scope: `${element.scope}/properties/${childKey}`\n });\n }\n\n // Recursively expand this new group in case it contains further inline objects\n newGroup.elements = this.expandElements(newGroup.elements!, rootSchema);\n \n expanded.push(newGroup);\n } else {\n // Scalar control, keep as is\n expanded.push(element);\n }\n } catch (e) {\n // Scope not found, keep element to let normal error handling report it\n expanded.push(element);\n }\n } else {\n expanded.push(element);\n }\n }\n\n return expanded;\n }\n}\n"],"mappings":"AAAA,mJAAA,MAMSA,EAAgBC,EAAA,0BAChBC,EAAWC,EAAA,qBAAEC,EAAWD,EAAA,eAE1B,MAAME,EAKT,YAAcC,CAAMC,GAChB,IAAKA,IAAWA,EAAOC,WAAaC,MAAMC,QAAQH,EAAOC,UAAW,CAChE,MACJ,CAEAD,EAAOC,SAAWG,KAAKC,eAAeL,EAAOC,SAAUD,EAC3D,CAEA,qBAAeK,CAAeC,EAA4BC,GACtD,MAAMC,EAA6B,GAEnC,IAAK,MAAMC,KAAWH,EAAU,CAC5B,GAAIG,EAAQC,OAAS,QAAS,CAE1B,GAAID,EAAQH,SAAU,CAClBG,EAAQH,SAAWF,KAAKC,eAAeI,EAAQH,SAAUC,EAC7D,CACAC,EAASG,KAAKF,EAClB,MAAO,GAAIA,EAAQC,OAAS,UAAW,CACnC,IAAKD,EAAQG,MAAO,CAChBJ,EAASG,KAAKF,GACd,QACJ,CAEA,IACI,MAAMI,KAAEA,EAAIC,YAAEA,GAAgBrB,EAAiBsB,aAAaR,EAAYE,EAAQG,OAEhF,MAAMI,IAAsBH,GAAMI,IAAIC,OACtC,MAAMC,EAAiBN,GAAMH,OAASb,EAAYuB,QAAUP,EAAKI,IAAII,aAAe1B,EAAY2B,SAAWN,EAE3G,GAAIG,GAAkBN,EAAKU,WAAY,CAEnC,MAAMC,EAA2B,IAC1Bf,EACHC,KAAM,QACNe,MAAOhB,EAAQgB,OAASZ,EAAKI,IAAIQ,OAASX,EAAYY,MAAM,KAAKC,MACjErB,SAAU,WAEPkB,EAASZ,MAGhB,IAAK,MAAMgB,KAAYC,OAAOC,KAAKjB,EAAKU,YAAa,CACjDC,EAASlB,SAAUK,KAAK,CACpBD,KAAM,UACNE,MAAO,GAAGH,EAAQG,oBAAoBgB,KAE9C,CAGAJ,EAASlB,SAAWF,KAAKC,eAAemB,EAASlB,SAAWC,GAE5DC,EAASG,KAAKa,EAClB,KAAO,CAEHhB,EAASG,KAAKF,EAClB,CACJ,CAAE,MAAOsB,GAELvB,EAASG,KAAKF,EAClB,CACJ,KAAO,CACHD,EAASG,KAAKF,EAClB,CACJ,CAEA,OAAOD,CACX,EACH,IAAAwB,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,gBAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":22,"column":0},"map":{"version":3,"names":["PluginRegistry","___PluginRegistry","Logger","___utils_Logger","RENDER_MODE","___constants_MetaUIConstants","SCHEMA_TYPE","OPENAPI_PREFIX","WIDGET_TYPE","LayoutScorer","apply","schema","budget","schemaDefinitions","visited","WeakSet","activeRefs","Set","properties","key","prop","type","OBJECT","ARRAY","$ref","this","_scoreNode","node","path","has","warn","ui","renderMode","DIALOG","layoutBudget","add","startsWith","DEFINITIONS","substring","length","COMPONENTS_SCHEMAS","resolvedOriginal","resolved","JSON","parse","stringify","resolvedScore","delete","Object","assign","widget","REFERENCE","INLINE","arrayScore","getInstance","getPluginScore","items","itemsSchema","totalScore","child","STRING","__exports","__esModule"],"sources":["LayoutScorer.ts"],"sourcesContent":["/**\n * @file LayoutScorer.ts\n * @description Core utility that calculates the nested footprint score of schemas \n * to determine if they should be rendered inline or overflowed into a dialog button.\n */\n\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport { Logger } from \"../utils/Logger\";\nimport { RENDER_MODE, SCHEMA_TYPE, OPENAPI_PREFIX, WIDGET_TYPE } from \"../constants/MetaUIConstants\";\n\nexport class LayoutScorer {\n /**\n * Recursively computes scores and annotates the schema with `renderMode`.\n * \n * @param schema The normalized schema root.\n * @param budget The remaining layout budget (e.g., 50).\n */\n public static apply(schema: ISchema | null, budget: number, schemaDefinitions?: Record<string, ISchema>): void {\n if (!schema || budget <= 0) return; // 0 budget means default fallback (no inline budget logic).\n\n const visited = new WeakSet<object>();\n const activeRefs = new Set<string>();\n\n // We only score the root properties (not the root object itself).\n if (schema.properties) {\n for (const key in schema.properties) {\n const prop = schema.properties[key];\n if (prop.type === SCHEMA_TYPE.OBJECT || prop.type === SCHEMA_TYPE.ARRAY || prop.$ref) {\n this._scoreNode(prop, budget, visited, activeRefs, key, schemaDefinitions);\n }\n }\n }\n }\n\n /**\n * Traverses a node, computing its total footprint.\n * If the score > budget, forces `renderMode = \"dialog\"`.\n * If the score <= budget, forces `renderMode = \"inline\"`.\n */\n private static _scoreNode(node: IPropertyMetadata, budget: number, visited: WeakSet<object>, activeRefs: Set<string>, path: string, schemaDefinitions?: Record<string, ISchema>): number {\n if (!node || typeof node !== SCHEMA_TYPE.OBJECT) return 0;\n\n if (visited.has(node)) {\n Logger.warn(`[MetaUI LayoutScorer] Circular reference detected at '${path}'. Forcing dialog mode to prevent crash.`, \"\", \"LayoutScorer\");\n node.ui = node.ui || {};\n node.ui.renderMode = RENDER_MODE.DIALOG;\n node.ui.layoutBudget = budget;\n return 1; // A dialog button is just 1 unit\n }\n visited.add(node);\n\n if (node.$ref && schemaDefinitions) {\n let key = node.$ref;\n if (key.startsWith(OPENAPI_PREFIX.DEFINITIONS)) key = key.substring(OPENAPI_PREFIX.DEFINITIONS.length);\n else if (key.startsWith(OPENAPI_PREFIX.COMPONENTS_SCHEMAS)) key = key.substring(OPENAPI_PREFIX.COMPONENTS_SCHEMAS.length);\n\n if (activeRefs.has(key)) {\n Logger.warn(`[MetaUI LayoutScorer] Circular OpenAPI $ref detected at '${path}' for '${key}'. Forcing dialog mode to prevent crash.`, \"\", \"LayoutScorer\");\n node.ui = node.ui || {};\n node.ui.renderMode = RENDER_MODE.DIALOG;\n return 1;\n }\n\n const resolvedOriginal = schemaDefinitions[key];\n if (resolvedOriginal) {\n activeRefs.add(key);\n \n // Deep clone it BEFORE scoring so we don't mutate the global dictionary\n const resolved = JSON.parse(JSON.stringify(resolvedOriginal));\n \n const resolvedScore = this._scoreNode(resolved, budget, visited, activeRefs, path, schemaDefinitions);\n activeRefs.delete(key);\n \n node.ui = node.ui || {};\n node.ui.layoutBudget = budget;\n if (resolvedScore <= budget) {\n // Merge it permanently in the layout!\n Object.assign(node, resolved);\n delete node.$ref;\n if (node.ui?.widget === WIDGET_TYPE.REFERENCE) delete node.ui.widget;\n \n node.ui.renderMode = RENDER_MODE.INLINE;\n visited.delete(node);\n return resolvedScore;\n } else {\n node.ui.renderMode = RENDER_MODE.DIALOG;\n visited.delete(node);\n return 1;\n }\n }\n }\n\n if (node.type === SCHEMA_TYPE.ARRAY) {\n let arrayScore = PluginRegistry.getInstance().getPluginScore(SCHEMA_TYPE.ARRAY, node.ui?.widget);\n \n // Traverse array items!\n if (node.items) {\n const itemsSchema = node.items as ISchema;\n if (itemsSchema.type === SCHEMA_TYPE.OBJECT || itemsSchema.type === SCHEMA_TYPE.ARRAY || itemsSchema.$ref) {\n arrayScore += this._scoreNode(itemsSchema, budget, visited, activeRefs, `${path}/items`, schemaDefinitions);\n }\n }\n\n node.ui = node.ui || {};\n node.ui.layoutBudget = budget;\n if (arrayScore <= budget) {\n node.ui.renderMode = RENDER_MODE.INLINE;\n visited.delete(node);\n return arrayScore;\n } else {\n node.ui.renderMode = RENDER_MODE.DIALOG;\n visited.delete(node);\n return 1;\n }\n }\n\n let totalScore = 0;\n\n if (node.properties) {\n for (const key in node.properties) {\n const child = node.properties[key] as IPropertyMetadata;\n if (child.type === SCHEMA_TYPE.OBJECT || child.type === SCHEMA_TYPE.ARRAY || child.$ref) {\n totalScore += this._scoreNode(child, budget, visited, activeRefs, `${path}/${key}`, schemaDefinitions);\n } else {\n totalScore += PluginRegistry.getInstance().getPluginScore(child.type || SCHEMA_TYPE.STRING, child.ui?.widget);\n }\n }\n } else {\n // An open dictionary (additionalProperties) is scored as a single table\n totalScore += PluginRegistry.getInstance().getPluginScore(SCHEMA_TYPE.OBJECT, node.ui?.widget); // e.g. dictionaryMap\n }\n\n node.ui = node.ui || {};\n node.ui.layoutBudget = budget;\n \n visited.delete(node);\n\n if (totalScore <= budget) {\n node.ui.renderMode = RENDER_MODE.INLINE;\n return totalScore;\n } else {\n node.ui.renderMode = RENDER_MODE.DIALOG;\n return 1; // It collapsed into an \"Edit Details\" button\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":23,"column":0},"map":{"version":3,"names":["Registry","___Registry","PatternValidatorPlugin","___plugins_validators_PatternValidatorPlugin","MinLengthValidatorPlugin","___plugins_validators_MinLengthValidatorPlugin","RangeValidatorPlugin","___plugins_validators_RangeValidatorPlugin","UrlValidatorPlugin","___plugins_validators_UrlValidatorPlugin","IbanValidatorPlugin","___plugins_validators_IbanValidatorPlugin","EmailValidatorPlugin","___plugins_validators_EmailValidatorPlugin","DateFormatterPlugin","___plugins_formatters_DateFormatterPlugin","PhoneFormatterPlugin","___plugins_formatters_PhoneFormatterPlugin","TextCaseFormatterPlugin","___plugins_formatters_TextCaseFormatterPlugin","Logger","___utils_Logger","RequiredValidator","validate","parsedValue","args","undefined","isValid","errorMessage","MaxLengthValidator","length","PipelineManager","formatters","parsers","validators","constructor","this","register","executeValidation","requestedValidators","argsMap","isEmpty","isRequired","includes","rule","validator","get","result","error","msg","message","warn","GlobalPipeline","__exports","__esModule"],"sources":["PipelineManager.ts"],"sourcesContent":["/**\n * @file PipelineManager.ts\n * @description Central manager for the data manipulation pipeline. \n * Orchestrates Formatting, Parsing, and Validating data using the generic Registry.\n */\n\nimport { Registry } from \"./Registry\";\nimport { IFormatter, IParser, IValidator, IValidationResult } from \"../interfaces/IPipeline\";\nimport { PatternValidatorPlugin } from \"../plugins/validators/PatternValidatorPlugin\";\nimport { MinLengthValidatorPlugin } from \"../plugins/validators/MinLengthValidatorPlugin\";\nimport { RangeValidatorPlugin } from \"../plugins/validators/RangeValidatorPlugin\";\nimport { UrlValidatorPlugin } from \"../plugins/validators/UrlValidatorPlugin\";\nimport { IbanValidatorPlugin } from \"../plugins/validators/IbanValidatorPlugin\";\nimport { EmailValidatorPlugin } from \"../plugins/validators/EmailValidatorPlugin\";\nimport { DateFormatterPlugin } from \"../plugins/formatters/DateFormatterPlugin\";\nimport { PhoneFormatterPlugin } from \"../plugins/formatters/PhoneFormatterPlugin\";\nimport { TextCaseFormatterPlugin } from \"../plugins/formatters/TextCaseFormatterPlugin\";\nimport { Logger } from \"../utils/Logger\";\n\n// --- Built-in Default Validators ---\n/** Internal rule for required fields. */\nclass RequiredValidator implements IValidator {\n /** Validates that the value is not null, undefined, or empty string. */\n validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (parsedValue === null || parsedValue === undefined || parsedValue === \"\") {\n return { isValid: false, errorMessage: \"This field is required.\" };\n }\n return { isValid: true };\n }\n}\n\n/** Internal rule for string maximum length. */\nclass MaxLengthValidator implements IValidator {\n /** Validates that a string does not exceed the provided argument length. */\n validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (typeof parsedValue === \"string\" && args && typeof args === \"number\") {\n if (parsedValue.length > args) {\n return { isValid: false, errorMessage: `Maximum length is ${args} characters.` };\n }\n }\n return { isValid: true };\n }\n}\n\n\n/**\n * The core engine responsible for marshalling data through the validation, formatting, and parsing phases.\n * Pluggable design allows new validators to be registered dynamically.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class PipelineManager {\n /** Registry of data formatters applied before pushing to the UI. */\n public readonly formatters: Registry<IFormatter> = new Registry<IFormatter>(\"Formatters\");\n /** Registry of data parsers applied when pulling data from the UI. */\n public readonly parsers: Registry<IParser> = new Registry<IParser>(\"Parsers\");\n /** Registry of business logic validators. */\n public readonly validators: Registry<IValidator> = new Registry<IValidator>(\"Validators\");\n\n /**\n * Bootstraps the PipelineManager with default validators (required, maxLength, email).\n */\n constructor() {\n // Register default validators\n this.validators.register(\"required\", new RequiredValidator());\n this.validators.register(\"maxLength\", new MaxLengthValidator());\n this.validators.register(\"pattern\", new PatternValidatorPlugin());\n this.validators.register(\"minLength\", new MinLengthValidatorPlugin());\n this.validators.register(\"range\", new RangeValidatorPlugin());\n this.validators.register(\"url\", new UrlValidatorPlugin());\n this.validators.register(\"iban\", new IbanValidatorPlugin());\n this.validators.register(\"email\", new EmailValidatorPlugin());\n\n // Register default formatters\n this.formatters.register(\"date\", new DateFormatterPlugin());\n this.formatters.register(\"phone\", new PhoneFormatterPlugin());\n this.formatters.register(\"textCase\", new TextCaseFormatterPlugin());\n }\n\n /**\n * Executes the validation pipeline sequentially. Fails fast on the first encountered error.\n * \n * @param parsedValue The raw extracted value from the UI control.\n * @param requestedValidators Array of validation rule keys (e.g. ['required', 'email']).\n * @param argsMap Optional map of parameters required by specific rules (e.g. { maxLength: 50 }).\n * @returns {IValidationResult} The final result state and any associated error message.\n */\n public executeValidation(parsedValue: unknown, requestedValidators: string[], argsMap?: Record<string, unknown>): IValidationResult {\n // Global short-circuit: if the field is completely empty and NOT required, skip all downstream string constraint checks.\n const isEmpty = parsedValue === null || parsedValue === undefined || parsedValue === \"\";\n const isRequired = requestedValidators.includes(\"required\");\n if (isEmpty && !isRequired) {\n return { isValid: true };\n }\n\n for (const rule of requestedValidators) {\n const validator = this.validators.get(rule);\n if (validator) {\n const args = argsMap ? argsMap[rule] : undefined;\n try {\n const result = validator.validate(parsedValue, args);\n if (!result.isValid) {\n return result; // Fast fail on first error\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] PipelineManager: Validator '${rule}' crashed during execution.`, msg);\n return { isValid: false, errorMessage: `System validation error: ${msg}` };\n }\n } else {\n Logger.warn(`[MetaUI] PipelineManager: Requested validator '${rule}' not found in registry.`);\n }\n }\n return { isValid: true };\n }\n}\n\n/** \n * Singleton instance for global access to the active validation pipeline. \n * @public \n */\nexport const GlobalPipeline = new PipelineManager();\n"],"mappings":"AAAA,4iBAAA,MAMSA,EAAQC,EAAA,kBAERC,EAAsBC,EAAA,gCACtBC,EAAwBC,EAAA,kCACxBC,EAAoBC,EAAA,8BACpBC,EAAkBC,EAAA,4BAClBC,EAAmBC,EAAA,6BACnBC,EAAoBC,EAAA,8BACpBC,EAAmBC,EAAA,6BACnBC,EAAoBC,EAAA,8BACpBC,EAAuBC,EAAA,iCACvBC,EAAMC,EAAA,UAIf,MAAMC,EAEFC,SAASC,EAAsBC,GAC3B,GAAID,IAAgB,MAAQA,IAAgBE,WAAaF,IAAgB,GAAI,CACzE,MAAO,CAAEG,QAAS,MAAOC,aAAc,0BAC3C,CACA,MAAO,CAAED,QAAS,KACtB,EAIJ,MAAME,EAEFN,SAASC,EAAsBC,GAC3B,UAAWD,IAAgB,UAAYC,UAAeA,IAAS,SAAU,CACrE,GAAID,EAAYM,OAASL,EAAM,CAC3B,MAAO,CAAEE,QAAS,MAAOC,aAAc,qBAAqBH,gBAChE,CACJ,CACA,MAAO,CAAEE,QAAS,KACtB,EAWG,MAAMI,EAEOC,WAAmC,IAAIhC,EAAqB,cAE5DiC,QAA6B,IAAIjC,EAAkB,WAEnDkC,WAAmC,IAAIlC,EAAqB,cAK5EmC,cAEIC,KAAKF,WAAWG,SAAS,WAAY,IAAIf,GACzCc,KAAKF,WAAWG,SAAS,YAAa,IAAIR,GAC1CO,KAAKF,WAAWG,SAAS,UAAW,IAAInC,GACxCkC,KAAKF,WAAWG,SAAS,YAAa,IAAIjC,GAC1CgC,KAAKF,WAAWG,SAAS,QAAS,IAAI/B,GACtC8B,KAAKF,WAAWG,SAAS,MAAO,IAAI7B,GACpC4B,KAAKF,WAAWG,SAAS,OAAQ,IAAI3B,GACrC0B,KAAKF,WAAWG,SAAS,QAAS,IAAIzB,GAGtCwB,KAAKJ,WAAWK,SAAS,OAAQ,IAAIvB,GACrCsB,KAAKJ,WAAWK,SAAS,QAAS,IAAIrB,GACtCoB,KAAKJ,WAAWK,SAAS,WAAY,IAAInB,EAC7C,CAUOoB,kBAAkBd,EAAsBe,EAA+BC,GAE1E,MAAMC,EAAUjB,IAAgB,MAAQA,IAAgBE,WAAaF,IAAgB,GACrF,MAAMkB,EAAaH,EAAoBI,SAAS,YAChD,GAAIF,IAAYC,EAAY,CACxB,MAAO,CAAEf,QAAS,KACtB,CAEA,IAAK,MAAMiB,KAAQL,EAAqB,CACpC,MAAMM,EAAYT,KAAKF,WAAWY,IAAIF,GACtC,GAAIC,EAAW,CACX,MAAMpB,EAAOe,EAAUA,EAAQI,GAAQlB,UACvC,IACI,MAAMqB,EAASF,EAAUtB,SAASC,EAAaC,GAC/C,IAAKsB,EAAOpB,QAAS,CACjB,OAAOoB,CACX,CACJ,CAAE,MAAOC,GACL,MAAMC,EAAOD,EAAgBE,QAC7B9B,EAAO4B,MAAM,wCAAwCJ,+BAAmCK,GACxF,MAAO,CAAEtB,QAAS,MAAOC,aAAc,4BAA4BqB,IACvE,CACJ,KAAO,CACH7B,EAAO+B,KAAK,kDAAkDP,4BAClE,CACJ,CACA,MAAO,CAAEjB,QAAS,KACtB,EAOG,MAAMyB,EAAiB,IAAIrB,EAAkB,IAAAsB,EAAA,CAAAC,WAAA,MAAAD,EAAAtB,kBAAAsB,EAAAD,iBAAA,OAAAC,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":24,"column":0},"map":{"version":3,"names":["SCHEMA_TYPE","___constants_MetaUIConstants","WIDGET_TYPE","LAYOUT_STRATEGY","Logger","___utils_Logger","PluginRegistry","fieldIndex","actionIndex","layoutIndex","policyConditionIndex","policyEffectIndex","activePromises","constructor","this","registerPluginPath","STRING","undefined","NUMBER","INTEGER","DATE","BOOLEAN","ARRAY","OBJECT","DICTIONARY_MAP","REFERENCE","TIME","DATETIME","SWITCH","STEP","SELECT","TEXT_AREA","CODE_EDITOR","LINK","PASSWORD","EMAIL","FILE_UPLOADER","MULTI_SELECT","MULTI_INPUT","SLIDER","RATING","MESSAGE_STRIP","CAMERA","SIGNATURE","LOCATION","SCANNER","VOICE_INPUT","RICH_TEXT","URL_BUTTON","SUBMIT_BUTTON","ODATA_SELECT","REMOTE_DROPDOWN","LIVE_SEARCH","REMOTE_VALUE_HELP","registerLayoutPath","FORM","TABLE","WIZARD","COMPACT","registerPolicyConditionPath","registerPolicyEffectPath","getInstance","instance","type","widgetName","path","key","registerActionPath","actionName","strategy","conditionKey","effectName","getFieldPath","Error","getLayoutPath","getPathsToLoad","schema","pathsToLoad","Set","layoutStrategy","add","scanProperties","props","prop","ui","widget","e","msg","message","error","properties","items","uiPolicies","policy","condition","Object","keys","effect","preloadDependencies","promises","Array","from","map","Promise","resolve","reject","sap","require","Module","extractConstructor","err","all","mod","default","getPluginScore","Constructor","layoutScore","isPluginNativelyWide","isNativelyWide","getPlugin","PluginClass","getLayout","LayoutClass","getPolicyConditionPlugin","getPolicyEffectPlugin","__exports","__esModule"],"sources":["PluginRegistry.ts"],"sourcesContent":["/**\n * @file PluginRegistry.ts\n * @description Centralized hub for mapping UI5 controls to SAP schema data types.\n * Enforces the Registry Pattern to decouple the core engine from specific UI5 control implementations.\n * NOW WITH UNIVERSAL LAZY LOADING.\n */\n\nimport { IPlugin } from \"../interfaces/IPlugin\";\nimport { FieldType, ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { SCHEMA_TYPE, WIDGET_TYPE, LAYOUT_STRATEGY } from \"../constants/MetaUIConstants\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { IPolicyConditionPlugin, IPolicyEffectPlugin } from \"../interfaces/IPolicyPlugin\";\nimport { Logger } from \"../utils/Logger\";\nimport { DefaultLayoutGenerator } from \"./DefaultLayoutGenerator\";\n\nexport class PluginRegistry {\n private static instance: PluginRegistry;\n \n private fieldIndex: Record<string, string> = {};\n private actionIndex: Record<string, string> = {};\n private layoutIndex: Record<string, string> = {};\n \n private policyConditionIndex: Record<string, string> = {};\n private policyEffectIndex: Record<string, string> = {};\n\n private activePromises: Record<string, Promise<unknown>> = {};\n\n private constructor() {\n // Core Mappings\n this.registerPluginPath(SCHEMA_TYPE.STRING, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.NUMBER, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.INTEGER, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.DATE, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin\");\n this.registerPluginPath(SCHEMA_TYPE.BOOLEAN, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.ARRAY, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.OBJECT, undefined, \"nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, \"default\", \"nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.OBJECT, WIDGET_TYPE.DICTIONARY_MAP, \"nz/co/siliconst/ui5/metaui/plugins/controls/DictionaryMapPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.OBJECT, WIDGET_TYPE.REFERENCE, \"nz/co/siliconst/ui5/metaui/plugins/controls/ReferencePlugin\");\n\n // Widget Overrides\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.TIME, \"nz/co/siliconst/ui5/metaui/plugins/controls/TimePlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.DATETIME, \"nz/co/siliconst/ui5/metaui/plugins/controls/DateTimePlugin\");\n this.registerPluginPath(SCHEMA_TYPE.BOOLEAN, WIDGET_TYPE.SWITCH, \"nz/co/siliconst/ui5/metaui/plugins/controls/SwitchPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.NUMBER, WIDGET_TYPE.STEP, \"nz/co/siliconst/ui5/metaui/plugins/controls/StepInputPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.SELECT, \"nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.TEXT_AREA, \"nz/co/siliconst/ui5/metaui/plugins/controls/TextAreaPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.CODE_EDITOR, \"nz/co/siliconst/ui5/metaui/plugins/controls/CodeEditorPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.LINK, \"nz/co/siliconst/ui5/metaui/plugins/controls/LinkPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.PASSWORD, \"nz/co/siliconst/ui5/metaui/plugins/controls/PasswordPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.EMAIL, \"nz/co/siliconst/ui5/metaui/plugins/controls/EmailPlugin\");\n \n // Phase 1 Mappings\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.FILE_UPLOADER, \"nz/co/siliconst/ui5/metaui/plugins/controls/FileUploaderPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.ARRAY, WIDGET_TYPE.MULTI_SELECT, \"nz/co/siliconst/ui5/metaui/plugins/controls/MultiSelectPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.ARRAY, WIDGET_TYPE.MULTI_INPUT, \"nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.NUMBER, WIDGET_TYPE.SLIDER, \"nz/co/siliconst/ui5/metaui/plugins/controls/SliderPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.NUMBER, WIDGET_TYPE.RATING, \"nz/co/siliconst/ui5/metaui/plugins/controls/RatingIndicatorPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.MESSAGE_STRIP, \"nz/co/siliconst/ui5/metaui/plugins/controls/MessageStripPlugin\");\n\n // Phase 5 Mappings (Hardware)\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.CAMERA, \"nz/co/siliconst/ui5/metaui/plugins/controls/CameraPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.SIGNATURE, \"nz/co/siliconst/ui5/metaui/plugins/controls/SignaturePlugin\");\n this.registerPluginPath(SCHEMA_TYPE.OBJECT, WIDGET_TYPE.LOCATION, \"nz/co/siliconst/ui5/metaui/plugins/controls/GeolocationPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.SCANNER, \"nz/co/siliconst/ui5/metaui/plugins/controls/BarcodeScannerPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.VOICE_INPUT, \"nz/co/siliconst/ui5/metaui/plugins/controls/VoiceInputPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.RICH_TEXT, \"nz/co/siliconst/ui5/metaui/plugins/controls/RichTextPlugin\");\n\n // Actions & Datasources\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.URL_BUTTON, \"nz/co/siliconst/ui5/metaui/plugins/actions/UrlNavigationActionPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.SUBMIT_BUTTON, \"nz/co/siliconst/ui5/metaui/plugins/actions/SubmitFormActionPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.ODATA_SELECT, \"nz/co/siliconst/ui5/metaui/plugins/datasources/ODataListBindingPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.REMOTE_DROPDOWN, \"nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteDropdownPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.LIVE_SEARCH, \"nz/co/siliconst/ui5/metaui/plugins/datasources/LiveSearchPlugin\");\n this.registerPluginPath(SCHEMA_TYPE.STRING, WIDGET_TYPE.REMOTE_VALUE_HELP, \"nz/co/siliconst/ui5/metaui/plugins/datasources/RemoteValueHelpPlugin\");\n\n // Layouts\n this.registerLayoutPath(LAYOUT_STRATEGY.FORM, \"nz/co/siliconst/ui5/metaui/layouts/FormLayout\");\n this.registerLayoutPath(LAYOUT_STRATEGY.TABLE, \"nz/co/siliconst/ui5/metaui/layouts/TableLayout\");\n this.registerLayoutPath(LAYOUT_STRATEGY.WIZARD, \"nz/co/siliconst/ui5/metaui/layouts/WizardLayout\");\n this.registerLayoutPath(LAYOUT_STRATEGY.COMPACT, \"nz/co/siliconst/ui5/metaui/layouts/CompactLayout\");\n\n // Policy Condition Plugins\n this.registerPolicyConditionPath(\"NumericGreaterThan\", \"nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericGreaterThanConditionPlugin\");\n this.registerPolicyConditionPath(\"NumericLessThan\", \"nz/co/siliconst/ui5/metaui/plugins/policies/conditions/NumericLessThanConditionPlugin\");\n this.registerPolicyConditionPath(\"StringEquals\", \"nz/co/siliconst/ui5/metaui/plugins/policies/conditions/StringEqualsConditionPlugin\");\n this.registerPolicyConditionPath(\"IsNull\", \"nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNullConditionPlugin\");\n this.registerPolicyConditionPath(\"IsNotNull\", \"nz/co/siliconst/ui5/metaui/plugins/policies/conditions/IsNotNullConditionPlugin\");\n\n // Policy Effect Plugins\n this.registerPolicyEffectPath(\"Show\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin\");\n this.registerPolicyEffectPath(\"Hide\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/VisibilityEffectPlugin\");\n this.registerPolicyEffectPath(\"Validate\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin\");\n this.registerPolicyEffectPath(\"Invalidate\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/ValidityEffectPlugin\");\n this.registerPolicyEffectPath(\"Require\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin\");\n this.registerPolicyEffectPath(\"Optional\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/RequirementEffectPlugin\");\n this.registerPolicyEffectPath(\"Enable\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin\");\n this.registerPolicyEffectPath(\"Disable\", \"nz/co/siliconst/ui5/metaui/plugins/policies/effects/EditableEffectPlugin\");\n }\n\n public static getInstance(): PluginRegistry {\n if (!PluginRegistry.instance) {\n PluginRegistry.instance = new PluginRegistry();\n }\n return PluginRegistry.instance;\n }\n\n public registerPluginPath(type: FieldType, widgetName: string | undefined, path: string): void {\n const key = widgetName ? `${type}:${widgetName}` : type;\n this.fieldIndex[key] = path;\n }\n\n public registerActionPath(actionName: string, path: string): void {\n this.actionIndex[actionName] = path;\n }\n\n public registerLayoutPath(strategy: string, path: string): void {\n this.layoutIndex[strategy] = path;\n }\n\n public registerPolicyConditionPath(conditionKey: string, path: string): void {\n this.policyConditionIndex[conditionKey] = path;\n }\n\n public registerPolicyEffectPath(effectName: string, path: string): void {\n this.policyEffectIndex[effectName] = path;\n }\n\n private getFieldPath(type: FieldType, widgetName?: string): string {\n let path;\n if (widgetName) {\n path = this.fieldIndex[`${type}:${widgetName}`];\n }\n if (!path) {\n path = this.fieldIndex[type];\n }\n if (!path) {\n throw new Error(`No plugin path mapped for FieldType: ${type} (widget: ${widgetName})`);\n }\n return path;\n }\n\n private getLayoutPath(strategy: string): string {\n const path = this.layoutIndex[strategy];\n if (!path) {\n throw new Error(`No layout path mapped for strategy: ${strategy}`);\n }\n return path;\n }\n\n /**\n * Statically traverses the schema structure to identify all required plugins\n * and layouts without actually instantiating them.\n * \n * @param {ISchema} schema The root JSON schema payload to traverse\n * @returns {Set<string>} A distinct set of UI5 module paths required to render the schema\n */\n public getPathsToLoad(schema: ISchema): Set<string> {\n const pathsToLoad = new Set<string>();\n \n // 1. Gather layout strategy\n const strategy = schema.layoutStrategy || (schema.type === SCHEMA_TYPE.ARRAY ? LAYOUT_STRATEGY.TABLE : LAYOUT_STRATEGY.FORM);\n pathsToLoad.add(this.getLayoutPath(strategy));\n\n // 2. Recursively gather field plugins\n const scanProperties = (props: Record<string, IPropertyMetadata>) => {\n for (const key in props) {\n const prop = props[key];\n try {\n pathsToLoad.add(this.getFieldPath(prop.type || SCHEMA_TYPE.STRING, prop.ui?.widget));\n } catch (e) {\n const msg = `[MetaUI LazyLoad] Could not find mapped plugin for field ${key}: ${(e as Error).message}`;\n Logger.error(msg);\n throw new Error(msg);\n }\n if (prop.properties) scanProperties(prop.properties);\n if (prop.items && prop.items.properties) scanProperties(prop.items.properties);\n if (prop.items && prop.items.type) {\n try {\n pathsToLoad.add(this.getFieldPath(prop.items.type, prop.items.ui?.widget));\n } catch (e) {\n const msg = `[MetaUI LazyLoad] Could not find mapped plugin for array item type ${prop.items.type}: ${(e as Error).message}`;\n Logger.error(msg);\n throw new Error(msg);\n }\n }\n }\n };\n\n if (schema.properties) {\n scanProperties(schema.properties);\n } else if (schema.items && schema.items.properties) {\n scanProperties(schema.items.properties);\n }\n\n // 3. Gather Policy Plugins\n if (schema.uiPolicies) {\n for (const policy of schema.uiPolicies) {\n if (policy.condition) {\n for (const key of Object.keys(policy.condition)) {\n if (this.policyConditionIndex[key]) {\n pathsToLoad.add(this.policyConditionIndex[key]);\n }\n }\n }\n if (policy.effect && this.policyEffectIndex[policy.effect]) {\n pathsToLoad.add(this.policyEffectIndex[policy.effect]);\n }\n }\n }\n\n return pathsToLoad;\n }\n\n /**\n * Defers the generation of the UI until all required UI5 modules have been\n * downloaded asynchronously. Maintains a cache of active promises to prevent\n * redundant network requests for the same module.\n * \n * @param {ISchema} schema The root JSON schema payload to parse\n * @returns {Promise<void>} Resolves when all dependencies are securely in the UI5 require cache\n */\n public async preloadDependencies(schema: ISchema): Promise<void> {\n const pathsToLoad = this.getPathsToLoad(schema);\n\n // 3. Batch execute sap.ui.require via Promises\n const promises = Array.from(pathsToLoad).map(path => {\n if (!this.activePromises[path]) {\n this.activePromises[path] = new Promise((resolve, reject) => {\n sap.ui.require([path], \n (Module: unknown) => {\n if (!this.extractConstructor(Module)) {\n Logger.error(`[MetaUI PluginRegistry] Module ${path} loaded successfully but exported no valid constructor.`);\n delete this.activePromises[path];\n reject(new Error(`Invalid module export: ${path}`));\n } else {\n resolve(Module);\n }\n }, \n (err: unknown) => {\n Logger.error(`Failed to lazy load module: ${path}`);\n // CRITICAL: Delete from cache so future attempts can retry the network request\n delete this.activePromises[path];\n reject(err);\n }\n );\n });\n }\n return this.activePromises[path];\n });\n\n await Promise.all(promises);\n }\n\n /**\n * Extracts a valid constructor from a dynamically required module.\n */\n private extractConstructor(Module: unknown): unknown {\n if (!Module) return null;\n if (typeof Module === \"function\") return Module;\n const mod = Module as Record<string, unknown>;\n if (mod.default && typeof mod.default === \"function\") return mod.default;\n \n // Handle namespace exports (e.g. { FormLayout: class... })\n const keys = Object.keys(mod);\n for (const key of keys) {\n if (typeof mod[key] === \"function\") {\n return mod[key];\n }\n }\n return null;\n }\n\n public getPluginScore(type: FieldType, widgetName?: string): number {\n try {\n const path = this.getFieldPath(type, widgetName);\n const Module = sap.ui.require(path);\n const Constructor = this.extractConstructor(Module) as Record<string, unknown>;\n if (Constructor && typeof Constructor.layoutScore === \"number\") {\n return Constructor.layoutScore as number;\n }\n } catch (e) {\n // Ignore if module not loaded or mapping missing, fallback to 1\n }\n return 1;\n }\n\n public isPluginNativelyWide(type: FieldType, widgetName?: string): boolean {\n try {\n const path = this.getFieldPath(type, widgetName);\n const Module = sap.ui.require(path);\n const Constructor = this.extractConstructor(Module) as Record<string, unknown>;\n if (Constructor && typeof Constructor.isNativelyWide === \"boolean\") {\n return Constructor.isNativelyWide as boolean;\n }\n } catch (e) {\n // Ignore errors, default false\n }\n return false;\n }\n\n /**\n * Instantiates the requested plugin for the given field type.\n */\n public getPlugin(type: FieldType, widgetName?: string): IPlugin {\n const path = this.getFieldPath(type, widgetName);\n const Module = sap.ui.require(path);\n const PluginClass = this.extractConstructor(Module) as new () => IPlugin;\n \n if (!PluginClass) {\n throw new Error(`[MetaUI Plugin Instantiation] Plugin ${path} was not preloaded or has no constructor!`);\n }\n \n return new PluginClass();\n }\n\n /**\n * Instantiates the requested layout manager for the given strategy.\n */\n public getLayout(strategy: string): ILayoutManager {\n const path = this.getLayoutPath(strategy);\n const Module = sap.ui.require(path);\n const LayoutClass = this.extractConstructor(Module) as new () => ILayoutManager;\n \n if (!LayoutClass) {\n throw new Error(`[MetaUI Layout Instantiation] Layout ${path} was not preloaded or has no constructor!`);\n }\n \n return new LayoutClass();\n }\n\n /**\n * Gets a specific condition plugin.\n */\n public getPolicyConditionPlugin(conditionKey: string): IPolicyConditionPlugin | undefined {\n const path = this.policyConditionIndex[conditionKey];\n if (!path) return undefined;\n \n const Module = sap.ui.require(path);\n const PluginClass = this.extractConstructor(Module) as new () => IPolicyConditionPlugin;\n if (!PluginClass) return undefined;\n \n return new PluginClass();\n }\n\n /**\n * Gets a specific effect plugin.\n */\n public getPolicyEffectPlugin(effectName: string): IPolicyEffectPlugin | undefined {\n const path = this.policyEffectIndex[effectName];\n if (!path) return undefined;\n \n const Module = sap.ui.require(path);\n const PluginClass = this.extractConstructor(Module) as new () => IPolicyEffectPlugin;\n if (!PluginClass) return undefined;\n \n return new PluginClass();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":25,"column":0},"map":{"version":3,"names":["PluginRegistry","___PluginRegistry","Logger","___utils_Logger","PolicyEngine","constructor","policies","this","lastStateMatrix","Map","detectCycles","graph","policy","sources","Set","condition","addPaths","obj","Object","keys","forEach","k","add","split","NumericGreaterThan","NumericLessThan","StringEquals","IsNull","p","IsNotNull","target","targets","cleanTarget","has","set","s","get","visited","recursionStack","isCyclic","node","neighbors","neighbor","delete","Error","resolvePointer","data","pointer","undefined","cleanPointer","replace","parts","current","part","evaluateCondition","result","registry","getInstance","key","payload","entries","plugin","getPolicyConditionPlugin","evaluate","bind","warn","expandRowPolicies","expanded","hasRow","arrayPath","includes","checkPaths","arrayData","Array","isArray","i","length","cloneStr","JSON","stringify","String","push","parse","expandedPolicies","ledger","initTargetInLedger","visibility","forcedFalse","forcedTrue","validity","required","editable","isConditionMet","currentLedger","effectPlugin","getPolicyEffectPlugin","effect","error","mapped","resolveState","value","property","message","lastMessage","newStateMatrix","stateMap","errorMessage","deltas","newState","lastState","__exports","__esModule"],"sources":["PolicyEngine.ts"],"sourcesContent":["import { IPolicy, IPolicyCondition, PolicyEffectType } from \"../interfaces/ISchema\";\nimport { PluginRegistry } from \"./PluginRegistry\";\nimport { Logger } from \"../utils/Logger\";\n\nexport type PropertyName = \"visibility\" | \"validity\" | \"required\" | \"editable\";\n\nexport interface IDeltaState {\n /** The absolute JSON pointer path of the target property (e.g., \"/VisitorInfo/PassportNumber\") */\n target: string;\n /** The UI5 visual or structural state to mutate */\n property: PropertyName;\n /** The boolean value to apply to the state */\n value: boolean;\n /** An optional custom error message to paint onto the field if validity is false */\n errorMessage?: string;\n}\n\ninterface ITargetState {\n visibility?: boolean;\n validity?: boolean;\n required?: boolean;\n editable?: boolean;\n errorMessage?: string;\n}\n\n/**\n * The PolicyEngine is responsible for evaluating complex, cross-field conditional logic defined in the schema's `uiPolicies` array.\n * It operates strictly on the JSON payload structure and returns an array of `IDeltaState` mutations which the GeneratorHost\n * then applies to the individual active plugins.\n * \n * It ensures the orchestration of conditional rendering, requiring, and invalidating of fields without the plugins\n * needing to be aware of each other.\n * \n * @namespace nz.co.siliconst.ui5.metaui.core\n */\nexport class PolicyEngine {\n private policies: IPolicy[];\n \n /** Caches the last computed state matrix for differential delta emission */\n private lastStateMatrix: Map<string, ITargetState>;\n\n /**\n * Instantiates the PolicyEngine with an array of policies.\n * @param policies Array of uiPolicies defined in the root schema.\n */\n constructor(policies: IPolicy[]) {\n this.policies = policies || [];\n this.lastStateMatrix = new Map();\n this.detectCycles();\n }\n\n /**\n * Builds a directed dependency graph and detects cycles to prevent infinite event loops.\n */\n private detectCycles(): void {\n const graph = new Map<string, Set<string>>();\n\n for (const policy of this.policies) {\n const sources = new Set<string>();\n if (policy.condition) {\n const addPaths = (obj: Record<string, unknown> | undefined) => {\n if (obj) Object.keys(obj).forEach(k => sources.add(k.split(\"/$row\")[0]));\n };\n addPaths(policy.condition.NumericGreaterThan);\n addPaths(policy.condition.NumericLessThan);\n addPaths(policy.condition.StringEquals);\n if (policy.condition.IsNull) policy.condition.IsNull.forEach(p => sources.add(p.split(\"/$row\")[0]));\n if (policy.condition.IsNotNull) policy.condition.IsNotNull.forEach(p => sources.add(p.split(\"/$row\")[0]));\n }\n\n for (const target of policy.targets) {\n const cleanTarget = target.split(\"/$row\")[0];\n if (!graph.has(cleanTarget)) {\n graph.set(cleanTarget, new Set());\n }\n sources.forEach(s => graph.get(cleanTarget)!.add(s));\n }\n }\n\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n\n const isCyclic = (node: string): boolean => {\n if (!visited.has(node)) {\n visited.add(node);\n recursionStack.add(node);\n\n const neighbors = graph.get(node);\n if (neighbors) {\n for (const neighbor of neighbors) {\n if (!visited.has(neighbor) && isCyclic(neighbor)) {\n return true;\n } else if (recursionStack.has(neighbor)) {\n return true;\n }\n }\n }\n }\n recursionStack.delete(node);\n return false;\n };\n\n for (const node of graph.keys()) {\n if (isCyclic(node)) {\n throw new Error(`[MetaUI PolicyEngine] FATAL: Cyclic dependency detected involving policy target '${node}'. This will cause an infinite rendering loop.`);\n }\n }\n }\n\n /**\n * Safely traverses a JSON payload using a JSON pointer.\n * Handles UI5 model prefixes (like metaui>) seamlessly.\n * \n * @param data The root JSON object representing the form payload.\n * @param pointer The JSON pointer to traverse (e.g., \"/Customer/Age\").\n * @returns The resolved value, or undefined if the path does not exist.\n */\n private resolvePointer(data: unknown, pointer: string): unknown {\n if (!data || !pointer) return undefined;\n // Strip leading slash and any UI5 prefixes\n const cleanPointer = pointer.replace(/^\\//, \"\").replace(/^metaui>\\/?/, \"\");\n if (!cleanPointer) return data;\n \n const parts = cleanPointer.split(\"/\");\n let current = data as Record<string, unknown>;\n for (const part of parts) {\n if (current === undefined || current === null) return undefined;\n current = current[part] as Record<string, unknown>;\n }\n return current;\n }\n\n /**\n * Evaluates a complex condition tree against the live JSON payload.\n * \n * @param condition The condition block to evaluate.\n * @param data The live JSON payload from the StateManager.\n * @returns True if all condition parameters are met, otherwise false.\n */\n private evaluateCondition(condition: IPolicyCondition, data: unknown): boolean {\n // If there are multiple operators, we treat them as AND for now\n let result = true;\n const registry = PluginRegistry.getInstance();\n\n for (const [key, payload] of Object.entries(condition)) {\n const plugin = registry.getPolicyConditionPlugin(key);\n if (plugin) {\n if (!plugin.evaluate(payload, data, this.resolvePointer.bind(this))) {\n result = false;\n }\n } else {\n Logger.warn(`[MetaUI PolicyEngine] Unrecognized condition operator: ${key}`);\n }\n }\n\n return result;\n }\n\n /**\n * Expands relative $row policies into absolute index policies for each physical row.\n */\n private expandRowPolicies(data: unknown, policies: IPolicy[]): IPolicy[] {\n const expanded: IPolicy[] = [];\n for (const policy of policies) {\n let hasRow = false;\n let arrayPath = \"\";\n \n for (const target of policy.targets) {\n if (target.includes(\"$row\")) {\n hasRow = true;\n arrayPath = target.split(\"/$row\")[0];\n break;\n }\n }\n if (!hasRow && policy.condition) {\n const checkPaths = (obj: any) => {\n if (!obj) return;\n for (const key of Object.keys(obj)) {\n if (key.includes(\"$row\")) {\n hasRow = true;\n arrayPath = key.split(\"/$row\")[0];\n break;\n }\n }\n };\n checkPaths(policy.condition.NumericGreaterThan);\n checkPaths(policy.condition.NumericLessThan);\n checkPaths(policy.condition.StringEquals);\n \n if (policy.condition.IsNull) policy.condition.IsNull.forEach(p => { if (p.includes(\"$row\")) { hasRow = true; arrayPath = p.split(\"/$row\")[0]; } });\n if (policy.condition.IsNotNull) policy.condition.IsNotNull.forEach(p => { if (p.includes(\"$row\")) { hasRow = true; arrayPath = p.split(\"/$row\")[0]; } });\n }\n\n if (hasRow && arrayPath) {\n const arrayData = this.resolvePointer(data, arrayPath);\n if (Array.isArray(arrayData)) {\n for (let i = 0; i < arrayData.length; i++) {\n const cloneStr = JSON.stringify(policy).replace(/\\$row/g, String(i));\n expanded.push(JSON.parse(cloneStr));\n }\n }\n } else {\n expanded.push(policy);\n }\n }\n return expanded;\n }\n\n /**\n * Evaluates policies against the given data payload using a State Resolution Matrix.\n * @param data The JSON data payload.\n * @returns Array of delta states to apply to the UI.\n */\n public evaluate(data: unknown): IDeltaState[] {\n if (!this.policies || this.policies.length === 0) {\n return [];\n }\n\n const expandedPolicies = this.expandRowPolicies(data, this.policies);\n\n // Ledger: target -> property -> { forcedFalse: number, forcedTrue: number, lastMessage?: string }\n const ledger = new Map<string, Record<PropertyName, { forcedFalse: number, forcedTrue: number, lastMessage?: string }>>();\n\n const initTargetInLedger = (target: string) => {\n if (!ledger.has(target)) {\n ledger.set(target, {\n visibility: { forcedFalse: 0, forcedTrue: 0 },\n validity: { forcedFalse: 0, forcedTrue: 0 },\n required: { forcedFalse: 0, forcedTrue: 0 },\n editable: { forcedFalse: 0, forcedTrue: 0 }\n });\n }\n };\n\n // 1. Build the Composite State Ledger Matrix\n for (const policy of expandedPolicies) {\n const isConditionMet = this.evaluateCondition(policy.condition, data);\n \n for (const target of policy.targets) {\n initTargetInLedger(target);\n const currentLedger = ledger.get(target)!;\n \n const effectPlugin = PluginRegistry.getInstance().getPolicyEffectPlugin(policy.effect);\n if (!effectPlugin) {\n Logger.error(`[MetaUI PolicyEngine] Unrecognized policy effect: ${policy.effect}`);\n continue;\n }\n const mapped = effectPlugin.resolveState(isConditionMet, policy.effect);\n \n // Track forces. For restrictable properties (visibility, validity, editable), forcedFalse acts as a lock.\n // For required, forcedTrue acts as a lock.\n if (mapped.value) {\n currentLedger[mapped.property].forcedTrue++;\n } else {\n currentLedger[mapped.property].forcedFalse++;\n if (mapped.property === \"validity\" && isConditionMet && policy.message) {\n currentLedger.validity.lastMessage = policy.message;\n }\n }\n }\n }\n\n const newStateMatrix = new Map<string, ITargetState>();\n\n // 2. Resolve the Ledger into a concrete State Matrix\n for (const [target, stateMap] of ledger.entries()) {\n newStateMatrix.set(target, {\n // False (Hidden) wins if ANY policy forced it false\n visibility: stateMap.visibility.forcedFalse > 0 ? false : true,\n // False (Invalid) wins if ANY policy forced it false\n validity: stateMap.validity.forcedFalse > 0 ? false : true,\n // True (Required) wins if ANY policy forced it true\n required: stateMap.required.forcedTrue > 0 ? true : false,\n // False (Disabled) wins if ANY policy forced it false\n editable: stateMap.editable.forcedFalse > 0 ? false : true,\n errorMessage: stateMap.validity.lastMessage\n });\n }\n\n const deltas: IDeltaState[] = [];\n\n // 3. Differential Emission\n for (const [target, newState] of newStateMatrix.entries()) {\n const lastState = this.lastStateMatrix.get(target) || {};\n\n if (newState.visibility !== undefined && newState.visibility !== lastState.visibility) {\n deltas.push({ target, property: \"visibility\", value: newState.visibility });\n }\n if (newState.validity !== undefined && newState.validity !== lastState.validity) {\n if (newState.validity !== lastState.validity || newState.errorMessage !== lastState.errorMessage) {\n deltas.push({ target, property: \"validity\", value: newState.validity, errorMessage: newState.errorMessage });\n }\n }\n if (newState.required !== undefined && newState.required !== lastState.required) {\n deltas.push({ target, property: \"required\", value: newState.required });\n }\n if (newState.editable !== undefined && newState.editable !== lastState.editable) {\n deltas.push({ target, property: \"editable\", value: newState.editable });\n }\n }\n\n // Cache for next evaluation sweep\n this.lastStateMatrix = newStateMatrix;\n\n return deltas;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":26,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","Registry","items","Map","constructor","registryName","this","register","key","item","has","warn","set","get","getStrict","msg","error","Error","getKeys","Array","from","keys","clear","__exports","__esModule"],"sources":["Registry.ts"],"sourcesContent":["/**\n * @file Registry.ts\n * @description Universal generic registry pattern used across the MetaUI library \n * for registering and resolving decoupled plugins (Layouts, Controls, Validators, etc).\n */\n\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Universal generic registry pattern used across the MetaUI library \n * for registering and resolving decoupled plugins (Layouts, Controls, Validators, etc).\n * \n * @template T The type of item being stored in the registry.\n * @namespace nz.co.siliconst.ui5.metaui.core\n * @public\n */\nexport class Registry<T> {\n /** The internal map storing the registered items. */\n public readonly items = new Map<string, T>();\n\n constructor(public readonly registryName: string = \"Registry\") {}\n\n /**\n * Registers a new item (plugin/layout/validator) into the registry.\n * @param key The unique string identifier.\n * @param item The implementation class or instance.\n */\n public register(key: string, item: T): void {\n if (this.items.has(key)) {\n Logger.warn(`[MetaUI] ${this.registryName}: Overwriting existing key '${key}'.`);\n }\n this.items.set(key, item);\n }\n\n /**\n * Retrieves an item by its key.\n * @param key The unique string identifier.\n * @returns The registered item, or undefined if not found.\n */\n public get(key: string): T | undefined {\n return this.items.get(key);\n }\n\n /**\n * Retrieves an item by its key, throwing an error if it doesn't exist.\n * @param key The unique string identifier.\n * @returns The registered item.\n */\n public getStrict(key: string): T {\n const item = this.get(key);\n if (!item) {\n const msg = `[MetaUI] ${this.registryName}: Key '${key}' not found.`;\n Logger.error(msg);\n throw new Error(msg);\n }\n return item;\n }\n\n /**\n * Returns an array of all registered keys.\n */\n public getKeys(): string[] {\n return Array.from(this.items.keys());\n }\n\n /**\n * Clears the entire registry.\n */\n public clear(): void {\n this.items.clear();\n }\n}\n"],"mappings":"AAAA,0GAAA,MAMSA,EAAMC,EAAA,UAUR,MAAMC,EAEOC,MAAQ,IAAIC,IAE5BC,YAA4BC,EAAuB,YAAYC,KAAnCD,cAAoC,CAOzDE,SAASC,EAAaC,GACzB,GAAIH,KAAKJ,MAAMQ,IAAIF,GAAM,CACrBT,EAAOY,KAAK,YAAYL,KAAKD,2CAA2CG,MAC5E,CACAF,KAAKJ,MAAMU,IAAIJ,EAAKC,EACxB,CAOOI,IAAIL,GACP,OAAOF,KAAKJ,MAAMW,IAAIL,EAC1B,CAOOM,UAAUN,GACb,MAAMC,EAAOH,KAAKO,IAAIL,GACtB,IAAKC,EAAM,CACP,MAAMM,EAAM,YAAYT,KAAKD,sBAAsBG,gBACnDT,EAAOiB,MAAMD,GACb,MAAM,IAAIE,MAAMF,EACpB,CACA,OAAON,CACX,CAKOS,UACH,OAAOC,MAAMC,KAAKd,KAAKJ,MAAMmB,OACjC,CAKOC,QACHhB,KAAKJ,MAAMoB,OACf,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAtB,WAAA,OAAAsB,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":27,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___SchemaNormalizer","OpenApiBuilder","___openapi_OpenApiBuilder","Logger","___utils_Logger","SchemaBuilderRegistry","static","register","plugin","this","_plugins","push","getBuilderFor","rawSchema","canHandle","warn","__exports","__esModule"],"sources":["SchemaBuilderRegistry.ts"],"sourcesContent":["/**\n * @file SchemaBuilderRegistry.ts\n * @description Singleton registry for Schema Builder plugins.\n * Routes unknown JSON payloads to the appropriate parser plugin.\n */\n\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { SchemaNormalizer } from \"./SchemaNormalizer\";\nimport { OpenApiBuilder } from \"../openapi/OpenApiBuilder\";\nimport { Logger } from \"../utils/Logger\";\n\nexport class SchemaBuilderRegistry {\n private static _plugins: ISchemaBuilderPlugin[] = [\n new OpenApiBuilder(),\n new SchemaNormalizer()\n ];\n\n /**\n * Registers a new schema builder plugin into the engine.\n * @param plugin An instance of ISchemaBuilderPlugin\n */\n public static register(plugin: ISchemaBuilderPlugin): void {\n this._plugins.push(plugin);\n }\n\n /**\n * Finds the first registered plugin that claims it can handle the payload.\n * @param rawSchema The raw JSON schema object to inspect.\n * @returns The matching plugin instance, or null if none match.\n */\n public static getBuilderFor(rawSchema: unknown): ISchemaBuilderPlugin | null {\n if (!rawSchema || typeof rawSchema !== \"object\") {\n return null;\n }\n\n for (const plugin of this._plugins) {\n if (plugin.canHandle(rawSchema)) {\n return plugin;\n }\n }\n \n Logger.warn(\"[SchemaBuilderRegistry]\", \"No suitable Schema Builder plugin found for the provided payload.\");\n return null;\n }\n}\n"],"mappings":"AAAA,4KAAA,MAOSA,EAAgBC,EAAA,0BAChBC,EAAcC,EAAA,wBACdC,EAAMC,EAAA,UAER,MAAMC,EACTC,gBAAkD,CAC9C,IAAIL,EACJ,IAAIF,GAOR,eAAcQ,CAASC,GACnBC,KAAKC,SAASC,KAAKH,EACvB,CAOA,oBAAcI,CAAcC,GACxB,IAAKA,UAAoBA,IAAc,SAAU,CAC7C,OAAO,IACX,CAEA,IAAK,MAAML,KAAUC,KAAKC,SAAU,CAChC,GAAIF,EAAOM,UAAUD,GAAY,CAC7B,OAAOL,CACX,CACJ,CAEAL,EAAOY,KAAK,0BAA2B,qEACvC,OAAO,IACX,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAX,wBAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":28,"column":0},"map":{"version":3,"names":["SCHEMA_TYPE","___constants_MetaUIConstants","Logger","___utils_Logger","SchemaNormalizer","canHandle","rawSchema","build","targetDefinition","normalize","data","schemaObj","STRING","trim","JSON","parse","e","msg","message","error","Error","Array","isArray","this","inferSchemaFromData","normalized","title","type","items","layoutStrategy","uiLayout","stringify","undefined","additionalProperties","uiPolicies","targetProperties","properties","inferred","deepMergeProperties","requiredKeys","required","normalizeProperties","normalizePropertyMetadata","base","override","merged","key","Object","keys","overrideVal","baseVal","normalizedProps","isRequired","includes","rawProp","keyName","prop","ui","$ref","label","generateLabel","isKey","readOnly","widget","valueHelp","enum","visibleOn","enabledOn","format","validators","formatter","args","rows","fullWidth","dialogButtonText","controlProps","maxLength","minLength","minimum","maximum","pattern","precision","scale","multipleOf","name","spaced","replace","split","filter","w","length","map","word","charAt","toUpperCase","slice","toLowerCase","join","schema","mergedProperties","limit","Math","min","i","inferPropertiesFromObject","obj","val","nestedProps","resolveScope","scope","startsWith","meta","bindingPath","propKey","pathSegments","current","debug","segment","__exports","__esModule"],"sources":["SchemaNormalizer.ts"],"sourcesContent":["/**\n * @file SchemaNormalizer.ts\n * @description Transforms and validates incoming JSON payloads into the strict v2 ISchema dictionary matrix.\n */\n\nimport { ISchema, IPropertyMetadata, FieldType } from \"../interfaces/ISchema\";\nimport { SCHEMA_TYPE } from \"../constants/MetaUIConstants\";\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { Logger } from \"../utils/Logger\";\n\nexport class SchemaNormalizer implements ISchemaBuilderPlugin {\n\n /**\n * ISchemaBuilderPlugin Contract\n */\n public canHandle(rawSchema: unknown): boolean {\n // Fallback for native ISchemas or data inference.\n // It always returns true because it is the final fallback builder in the registry.\n return true;\n }\n\n /**\n * ISchemaBuilderPlugin Contract\n */\n public build(rawSchema: unknown, targetDefinition?: string): ISchema {\n return SchemaNormalizer.normalize(rawSchema);\n }\n\n /**\n * Validates that the provided raw payload conforms to the required ISchema structures.\n */\n public static normalize(rawSchema?: unknown, data?: unknown): ISchema {\n let schemaObj = rawSchema;\n\n if (typeof schemaObj === SCHEMA_TYPE.STRING) {\n if (!schemaObj.trim()) {\n schemaObj = null;\n } else {\n try {\n schemaObj = JSON.parse(schemaObj);\n } catch (e) {\n const msg = \"Failed to parse schema string: \" + (e as Error).message;\n Logger.error(\"[MetaUI SchemaNormalizer]\", msg);\n throw new Error(msg);\n }\n }\n }\n\n if (!schemaObj || typeof schemaObj !== 'object' || Array.isArray(schemaObj)) {\n return this.inferSchemaFromData(data);\n }\n\n try {\n // It is an object. Ensure it conforms to v2 structure.\n const normalized: ISchema = {\n title: schemaObj.title,\n type: schemaObj.type || (schemaObj.items ? \"array\" : \"object\"),\n layoutStrategy: schemaObj.layoutStrategy,\n uiLayout: schemaObj.uiLayout ? JSON.parse(JSON.stringify(schemaObj.uiLayout)) : undefined,\n additionalProperties: schemaObj.additionalProperties,\n uiPolicies: schemaObj.uiPolicies ? JSON.parse(JSON.stringify(schemaObj.uiPolicies)) : undefined\n };\n\n let targetProperties = schemaObj.properties || {};\n\n if (schemaObj.additionalProperties === true && data) {\n const inferred = this.inferSchemaFromData(data);\n if (inferred.type === \"object\" && inferred.properties) {\n targetProperties = this.deepMergeProperties(inferred.properties, targetProperties);\n } else if (inferred.type === \"array\" && inferred.items && inferred.items.properties) {\n // Array schema merging could be added here if we want full support.\n }\n }\n\n if (normalized.type === \"object\") {\n const requiredKeys = Array.isArray(schemaObj.required) ? schemaObj.required : [];\n normalized.properties = this.normalizeProperties(targetProperties, requiredKeys);\n } else if (normalized.type === \"array\") {\n // Future expansion: array deep merge\n normalized.items = this.normalizePropertyMetadata(schemaObj.items || { type: \"object\", properties: {} }, \"items\", false);\n }\n\n return normalized;\n } catch (error) {\n const msg = \"Critical error normalizing schema object: \" + (error as Error).message;\n Logger.error(\"[MetaUI SchemaNormalizer]\", msg);\n throw new Error(msg);\n }\n }\n\n /**\n * Recursively deep merges an inferred schema over a base schema.\n * @param base The base property dictionary.\n * @param override The overriding inferred dictionary.\n * @returns A new deeply merged property dictionary.\n */\n private static deepMergeProperties(base: Record<string, unknown>, override: Record<string, unknown>): Record<string, unknown> {\n const merged = { ...base };\n for (const key of Object.keys(override)) {\n const overrideVal = override[key];\n const baseVal = merged[key];\n\n if (baseVal && typeof baseVal === \"object\" && !Array.isArray(baseVal) &&\n overrideVal && typeof overrideVal === \"object\" && !Array.isArray(overrideVal)) {\n merged[key] = this.deepMergeProperties(baseVal, overrideVal);\n } else {\n merged[key] = overrideVal;\n }\n }\n return merged;\n }\n\n /**\n * Normalizes a collection of properties.\n * @param properties The raw properties map.\n * @param requiredKeys An optional array of keys that are required by the parent object.\n * @returns A map of strict IPropertyMetadata objects.\n */\n private static normalizeProperties(properties: Record<string, unknown>, requiredKeys: string[] = []): Record<string, IPropertyMetadata> {\n const normalizedProps: Record<string, IPropertyMetadata> = {};\n for (const key of Object.keys(properties)) {\n const isRequired = requiredKeys.includes(key);\n normalizedProps[key] = this.normalizePropertyMetadata(properties[key], key, isRequired);\n }\n return normalizedProps;\n }\n\n /**\n * Normalizes a single property against the ISchema specification.\n * @param prop The raw property definition.\n * @param keyName The string key name for generating default labels.\n * @param isRequired Indicates if the parent object mandated this property as required.\n * @returns A strict IPropertyMetadata instance.\n */\n private static normalizePropertyMetadata(rawProp: unknown, keyName: string, isRequired: boolean = false): IPropertyMetadata {\n const prop = (rawProp || {}) as Record<string, unknown>;\n const ui = (prop.ui || {}) as Record<string, unknown>;\n \n const normalized: IPropertyMetadata = {\n type: (prop.type as FieldType) || \"string\",\n $ref: prop.$ref as string | undefined,\n ui: {\n label: ui.label as string || this.generateLabel(keyName),\n isKey: !!ui.isKey,\n readOnly: !!ui.readOnly,\n widget: ui.widget as string || (prop.valueHelp || prop.enum ? \"select\" : undefined),\n visibleOn: prop.ui?.visibleOn,\n enabledOn: prop.ui?.enabledOn,\n format: prop.ui?.format,\n validators: prop.ui?.validators,\n formatter: prop.ui?.formatter,\n args: prop.ui?.args,\n rows: prop.ui?.rows,\n fullWidth: prop.ui?.fullWidth,\n dialogButtonText: prop.ui?.dialogButtonText,\n controlProps: prop.ui?.controlProps\n },\n required: isRequired || !!prop.required,\n maxLength: prop.maxLength as number,\n minLength: prop.minLength as number,\n minimum: prop.minimum,\n maximum: prop.maximum,\n pattern: prop.pattern,\n precision: prop.precision,\n scale: prop.scale,\n multipleOf: prop.multipleOf as number,\n valueHelp: prop.valueHelp,\n enum: prop.enum\n };\n\n if (normalized.type === \"object\" && prop.properties) {\n const requiredKeys = Array.isArray(prop.required) ? prop.required : [];\n normalized.properties = this.normalizeProperties(prop.properties as Record<string, unknown>, requiredKeys);\n normalized.uiLayout = prop.uiLayout;\n } else if (normalized.type === \"array\") {\n // Auto-correct arrays that were mistakenly flattened with 'properties' instead of 'items.properties'\n if (prop.properties && !prop.items) {\n prop.items = {\n type: \"object\",\n properties: prop.properties\n };\n delete prop.properties;\n }\n\n if (prop.items) {\n normalized.items = this.normalizePropertyMetadata(prop.items as Record<string, unknown>, \"items\", false);\n }\n normalized.uiLayout = prop.uiLayout;\n }\n\n return normalized;\n }\n\n /**\n * Generates a Title Case label from camelCase or snake_case technical names.\n */\n private static generateLabel(name: string): string {\n if (!name) return \"\";\n let spaced = name.replace(/([A-Z])/g, \" $1\").replace(/_/g, \" \");\n return spaced.split(' ')\n .filter(w => w.length > 0)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n .trim();\n }\n\n /**\n * Infers a v2 ISchema structure dynamically from a plain data payload.\n */\n public static inferSchemaFromData(data: unknown): ISchema {\n const schema: ISchema = { type: \"object\", properties: {}, layoutStrategy: \"compact\", title: \"\" };\n\n if (!data || typeof data !== \"object\") {\n return schema;\n }\n\n if (Array.isArray(data)) {\n schema.type = \"array\";\n if (data.length > 0 && typeof data[0] !== \"object\") {\n schema.layoutStrategy = \"compact\";\n schema.items = { type: typeof data[0] as FieldType };\n } else {\n schema.layoutStrategy = \"table\";\n \n let mergedProperties: Record<string, unknown> = {};\n const limit = Math.min(data.length, 50);\n for (let i = 0; i < limit; i++) {\n const inferred = this.inferPropertiesFromObject(data[i] as Record<string, any>);\n mergedProperties = this.deepMergeProperties(mergedProperties, inferred as unknown as Record<string, unknown>);\n }\n\n schema.items = {\n type: \"object\",\n layoutStrategy: \"compact\",\n properties: mergedProperties as Record<string, IPropertyMetadata>\n } as any;\n }\n } else {\n schema.type = \"object\";\n schema.properties = this.inferPropertiesFromObject(data);\n }\n\n return schema;\n }\n\n /**\n * Infers field metadata recursively from a raw data object.\n * @param obj The raw JavaScript object.\n * @returns A dictionary of inferred IPropertyMetadata.\n */\n private static inferPropertiesFromObject(obj: Record<string, unknown>): Record<string, IPropertyMetadata> {\n const properties: Record<string, IPropertyMetadata> = {};\n if (!obj || typeof obj !== \"object\") return properties;\n\n for (const key of Object.keys(obj)) {\n const val = obj[key];\n if (val === null || val === undefined) continue;\n\n let type: FieldType = SCHEMA_TYPE.STRING;\n let items: IPropertyMetadata | undefined;\n let nestedProps: Record<string, IPropertyMetadata> | undefined;\n\n if (typeof val === \"number\") type = \"number\";\n else if (typeof val === \"boolean\") type = \"boolean\";\n else if (Array.isArray(val)) {\n type = \"array\";\n if (val.length > 0 && typeof val[0] !== \"object\") {\n items = {\n type: typeof val[0] as FieldType\n };\n } else {\n items = {\n type: \"object\",\n properties: val.length > 0 ? this.inferPropertiesFromObject(val[0] as Record<string, unknown>) : {}\n };\n }\n } else if (typeof val === \"object\") {\n type = \"object\";\n nestedProps = this.inferPropertiesFromObject(val as Record<string, unknown>);\n }\n\n properties[key] = {\n type,\n items,\n properties: nestedProps,\n ui: {\n label: this.generateLabel(key),\n isKey: false,\n readOnly: false,\n widget: type === \"array\" && items?.type !== \"object\" ? \"multiInput\" : undefined\n }\n };\n }\n\n return properties;\n }\n\n /**\n * Resolves a JSON Schema scope (e.g. '#/properties/header/properties/id')\n * against the ISchema, returning the PropertyMetadata and the UI5 binding path.\n */\n public static resolveScope(schema: ISchema, scope: string): { meta: IPropertyMetadata | undefined, bindingPath: string, propKey: string } {\n if (!scope || !scope.startsWith(\"#/properties/\")) {\n return { meta: undefined, bindingPath: scope || \"\", propKey: scope || \"\" };\n }\n \n const pathSegments = scope.replace(\"#/properties/\", \"\").split(\"/properties/\");\n let current: Record<string, IPropertyMetadata> | undefined = schema.properties;\n let meta: IPropertyMetadata | undefined;\n \n Logger.debug(\"[MetaUI SchemaNormalizer]\", `Resolving scope '${scope}' with segments: ${JSON.stringify(pathSegments)}`, \"SchemaNormalizer\");\n Logger.debug(\"[MetaUI SchemaNormalizer]\", `Root schema keys: ${Object.keys(schema.properties || {})}`, \"SchemaNormalizer\");\n\n for (let i = 0; i < pathSegments.length; i++) {\n const segment = pathSegments[i];\n if (!current) {\n Logger.debug(\"[MetaUI SchemaNormalizer]\", `current is undefined at segment '${segment}'`, \"SchemaNormalizer\");\n meta = undefined;\n break;\n }\n meta = current[segment];\n Logger.debug(\"[MetaUI SchemaNormalizer]\", `Segment '${segment}' resolved to meta: ${!!meta}. Available keys in current: ${Object.keys(current)}`, \"SchemaNormalizer\");\n if (i < pathSegments.length - 1) {\n current = meta?.properties;\n }\n }\n \n const bindingPath = pathSegments.join(\"/\");\n const propKey = scope.replace(\"#/properties/\", \"\"); // The original raw string for logging\n \n return {\n meta,\n bindingPath,\n propKey\n };\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":29,"column":0},"map":{"version":3,"names":["SCHEMA_TYPE","___constants_MetaUIConstants","SchemaValidator","validateSchemaStructure","schema","errors","s","type","push","properties","items","itemErrors","key","Object","keys","prop","allowedTypes","STRING","NUMBER","INTEGER","BOOLEAN","DATE","OBJECT","ARRAY","includes","join","__exports","__esModule"],"sources":["SchemaValidator.ts"],"sourcesContent":["/**\n * @file SchemaValidator.ts\n * @description Structural validation utility to catch developer errors in the JSON schema itself.\n */\n\nimport { ISchema, FieldType } from \"../interfaces/ISchema\";\nimport { SCHEMA_TYPE } from \"../constants/MetaUIConstants\";\n\nexport class SchemaValidator {\n /**\n * Validates a parsed JSON schema object for structural correctness.\n * @param schema The schema object to validate\n * @returns An array of error strings. Empty if no errors.\n */\n public static validateSchemaStructure(schema: unknown): string[] {\n const errors: string[] = [];\n\n if (!schema || typeof schema !== \"object\") {\n return [\"Root schema must be an object.\"];\n }\n\n const s = schema as Record<string, any>;\n if (s.type !== \"object\" && s.type !== \"array\") {\n errors.push(`Root schema must have type 'object' or 'array'. Found: '${s.type}'`);\n }\n\n if (s.type === \"object\" && !s.properties) {\n errors.push(\"Object schema is missing the 'properties' node.\");\n }\n\n if (s.type === \"array\") {\n if (!s.items) {\n // Warning rather than error for inference support, but we should check it\n // Actually inference creates { items: { type: 'string' } } for primitives\n // Wait, the instruction says \"completely skipping the validation of the array's items configuration\"\n // I will recursively call validateSchemaStructure if items exist\n }\n if (s.items && typeof s.items === \"object\") {\n const itemErrors = SchemaValidator.validateSchemaStructure(s.items);\n errors.push(...itemErrors);\n }\n }\n\n if (s.properties) {\n for (const key of Object.keys(s.properties)) {\n const prop = s.properties[key];\n if (!prop || typeof prop !== \"object\") {\n errors.push(`Property '${key}' must be an object.`);\n continue;\n }\n\n if (!prop.type) {\n errors.push(`Property '${key}' is missing 'type'.`);\n } else {\n const allowedTypes: FieldType[] = [SCHEMA_TYPE.STRING, SCHEMA_TYPE.NUMBER, SCHEMA_TYPE.INTEGER, SCHEMA_TYPE.BOOLEAN, SCHEMA_TYPE.DATE, SCHEMA_TYPE.OBJECT, SCHEMA_TYPE.ARRAY];\n if (!allowedTypes.includes(prop.type)) {\n errors.push(`Property '${key}' has invalid type '${prop.type}'. Allowed: ${allowedTypes.join(\", \")}`);\n }\n }\n\n // Removed strict check for prop.items on array properties because inference handles empty definitions\n\n }\n }\n\n return errors;\n }\n}\n"],"mappings":"AAAA,8HAAA,MAMSA,EAAWC,EAAA,eAEb,MAAMC,EAMT,8BAAcC,CAAwBC,GAClC,MAAMC,EAAmB,GAEzB,IAAKD,UAAiBA,IAAW,SAAU,CACvC,MAAO,CAAC,iCACZ,CAEA,MAAME,EAAIF,EACV,GAAIE,EAAEC,OAAS,UAAYD,EAAEC,OAAS,QAAS,CAC3CF,EAAOG,KAAK,2DAA2DF,EAAEC,QAC7E,CAEA,GAAID,EAAEC,OAAS,WAAaD,EAAEG,WAAY,CACtCJ,EAAOG,KAAK,kDAChB,CAEA,GAAIF,EAAEC,OAAS,QAAS,CACpB,IAAKD,EAAEI,MAAO,CAIV,CAEJ,GAAIJ,EAAEI,cAAgBJ,EAAEI,QAAU,SAAU,CACxC,MAAMC,EAAaT,EAAgBC,wBAAwBG,EAAEI,OAC7DL,EAAOG,QAAQG,EACnB,CACJ,CAEA,GAAIL,EAAEG,WAAY,CACd,IAAK,MAAMG,KAAOC,OAAOC,KAAKR,EAAEG,YAAa,CACzC,MAAMM,EAAOT,EAAEG,WAAWG,GAC1B,IAAKG,UAAeA,IAAS,SAAU,CACnCV,EAAOG,KAAK,aAAaI,yBACzB,QACJ,CAEA,IAAKG,EAAKR,KAAM,CACZF,EAAOG,KAAK,aAAaI,wBAC7B,KAAO,CACH,MAAMI,EAA4B,CAAChB,EAAYiB,OAAQjB,EAAYkB,OAAQlB,EAAYmB,QAASnB,EAAYoB,QAASpB,EAAYqB,KAAMrB,EAAYsB,OAAQtB,EAAYuB,OACvK,IAAKP,EAAaQ,SAAST,EAAKR,MAAO,CACnCF,EAAOG,KAAK,aAAaI,wBAA0BG,EAAKR,mBAAmBS,EAAaS,KAAK,QACjG,CACJ,CAIJ,CACJ,CAEA,OAAOpB,CACX,EACH,IAAAqB,EAAA,CAAAC,WAAA,MAAAD,EAAAxB,kBAAA,OAAAwB,CAAA","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":30,"column":0},"map":{"version":3,"names":["SCHEMA_TYPE","___constants_MetaUIConstants","GlobalPipeline","___PipelineManager","SchemaNormalizer","___SchemaNormalizer","StateManager","schema","_useMessageManager","constructor","initialData","modelName","this","activeModelName","safeData","JSON","parse","stringify","model","JSONModel","setDefaultBindingMode","originalSetProperty","setProperty","bind","sPath","oValue","oContext","bAsyncUpdate","result","validatePath","setUseMessageManager","use","value","fieldKey","replace","metadata","findMetadataForPath","messageManager","Messaging","targetPath","startsWith","existingMessages","getMessageModel","getData","messagesToRemove","filter","msg","isMatch","getTarget","getMessageProcessor","getId","length","removeMessages","validatorsToRun","argsMap","required","push","type","STRING","maxLength","minLength","pattern","minimum","undefined","maximum","min","max","format","ui","validators","v","name","args","validationResult","executeValidation","isValid","newMsg","Message","message","errorMessage","coreLibrary","MessageType","Error","target","processor","addMessages","clearArrayMessages","arrayPath","currentMessages","pathPrefix","getProcessor","path","properties","absoluteScope","meta","resolveScope","getModel","bindControl","control","property","bindingPath","bindProperty","extractPayload","data","deepClone","obj","Date","getTime","Array","isArray","arrCopy","item","objCopy","key","Object","prototype","hasOwnProperty","call","absolutePath","destroy","__exports","__esModule"],"sources":["StateManager.ts"],"sourcesContent":["/**\n * @file StateManager.ts\n * @description Isolated internal state management. Decouples the MetaUI engine from external host models.\n */\n\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport ManagedObject from \"sap/ui/base/ManagedObject\";\nimport { ISchema, IPropertyMetadata } from \"../interfaces/ISchema\";\nimport { SCHEMA_TYPE } from \"../constants/MetaUIConstants\";\nimport { GlobalPipeline } from \"./PipelineManager\";\nimport { SchemaNormalizer } from \"./SchemaNormalizer\";\nimport Message from \"sap/ui/core/message/Message\";\nimport coreLibrary from \"sap/ui/core/library\";\nimport Core from \"sap/ui/core/Core\";\nimport Messaging from \"sap/ui/core/Messaging\";\n\n\n/**\n * Manages the isolated internal data payload for the MetaUI engine.\n */\nexport class StateManager {\n private model: JSONModel;\n private activeModelName: string;\n private schema: ISchema | null = null;\n private _useMessageManager: boolean = false;\n\n /**\n * Initializes the state manager with an authentic SAPUI5 JSONModel.\n * @param initialData The initial JSON payload to populate the fields.\n * @param schema The normalized schema for live validation.\n * @param modelName The UI5 model alias used for isolation.\n */\n constructor(initialData: Record<string, unknown> = {}, schema: ISchema, modelName: string = \"meta\") {\n this.activeModelName = modelName;\n this.schema = schema;\n \n // Deep copy to ensure no reference leakage from the host application\n const safeData = JSON.parse(JSON.stringify(initialData));\n this.model = new JSONModel(safeData);\n this.model.setDefaultBindingMode(\"TwoWay\");\n\n // Centralized Model-Level Validation Interceptor\n const originalSetProperty = this.model.setProperty.bind(this.model);\n this.model.setProperty = (sPath: string, oValue: unknown, oContext?: unknown, bAsyncUpdate?: boolean) => {\n const result = originalSetProperty(sPath, oValue, oContext, bAsyncUpdate);\n this.validatePath(sPath, oValue);\n return result;\n };\n }\n\n /**\n * Updates the flag indicating whether this manager should push validation errors directly to the global MessageManager.\n */\n public setUseMessageManager(use: boolean): void {\n this._useMessageManager = use;\n }\n\n /**\n * Validates a specific path against the schema and updates the MessageManager.\n */\n private validatePath(sPath: string, value: unknown): void {\n const fieldKey = sPath.replace(/^\\//, \"\");\n const metadata = this.findMetadataForPath(fieldKey);\n \n const messageManager = Messaging;\n const targetPath = sPath.startsWith(\"/\") ? sPath : `/${sPath}`; // Pure UI5: target MUST be absolute path\n \n // 1. Remove existing messages (strictly for THIS model instance) unconditionally\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove = existingMessages.filter((msg: Message) => {\n const isMatch = msg.getTarget() === targetPath && msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.model.getId();\n return isMatch;\n });\n \n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n if (!metadata) return;\n\n // 2. Run GlobalPipeline\n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {};\n\n if (metadata.required) {\n validatorsToRun.push(\"required\");\n }\n if (metadata.type === SCHEMA_TYPE.STRING && metadata.maxLength) {\n validatorsToRun.push(\"maxLength\");\n argsMap[\"maxLength\"] = metadata.maxLength;\n }\n if (metadata.minLength) {\n validatorsToRun.push(\"minLength\");\n argsMap[\"minLength\"] = metadata.minLength;\n }\n if (metadata.pattern) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = metadata.pattern;\n }\n if (metadata.minimum !== undefined || metadata.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: metadata.minimum, max: metadata.maximum };\n }\n \n const format = metadata.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n if (metadata.ui?.validators) {\n for (const v of metadata.ui.validators) {\n if (typeof v === SCHEMA_TYPE.STRING) {\n validatorsToRun.push(v);\n } else if (v && v.name) {\n validatorsToRun.push(v.name);\n if (v.args !== undefined) {\n argsMap[v.name] = v.args;\n }\n }\n }\n }\n\n if (validatorsToRun.length > 0) {\n const validationResult = GlobalPipeline.executeValidation(value, validatorsToRun, argsMap);\n if (!validationResult.isValid && this._useMessageManager) {\n const newMsg = new Message({\n message: validationResult.errorMessage || \"Invalid value.\",\n type: coreLibrary.MessageType.Error,\n target: targetPath,\n processor: this.model\n });\n messageManager.addMessages(newMsg);\n }\n }\n }\n\n /**\n * Purges all MessageManager errors that start with a specific array path.\n * Used to clean up \"ghost errors\" when array structural shifts (deletion) occur.\n * @param arrayPath The root array path (e.g. /Items)\n */\n public clearArrayMessages(arrayPath: string): void {\n const messageManager = Messaging;\n const currentMessages = messageManager.getMessageModel().getData() as Message[];\n \n const pathPrefix = arrayPath.startsWith(\"/\") ? arrayPath : `/${arrayPath}`;\n \n const messagesToRemove = currentMessages.filter(msg => {\n return msg.getProcessor() === this.model && typeof msg.getTarget() === \"string\" && msg.getTarget().startsWith(pathPrefix);\n });\n\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n }\n\n /**\n * Resolves the schema metadata for a given internal binding path.\n * @param path The flat binding path representing the field.\n * @returns The associated IPropertyMetadata, or undefined if not mapped.\n */\n private findMetadataForPath(path: string): IPropertyMetadata | undefined {\n if (!this.schema || !this.schema.properties) return undefined;\n \n // Deeply resolve the metadata using the SchemaNormalizer\n const absoluteScope = \"#/properties/\" + path.replace(/\\//g, \"/properties/\");\n const { meta } = SchemaNormalizer.resolveScope(this.schema, absoluteScope);\n return meta;\n }\n\n\n\n /**\n * Retrieves the isolated JSONModel instance to attach to the root GeneratorHost control.\n * @returns The internal JSONModel.\n */\n public getModel(): JSONModel {\n return this.model;\n }\n\n /**\n * Binds a generated UI control property to a path in the internal model.\n * @param control The target UI5 Control.\n * @param property The UI5 property name (e.g., 'value').\n * @param bindingPath The exact path in the JSON payload.\n */\n public bindControl(control: ManagedObject, property: string, bindingPath: string): void {\n control.bindProperty(property, {\n path: bindingPath,\n model: \"meta\" // Assumes the model is bound to the root container with the name 'meta'\n });\n }\n\n /**\n * Extracts the flat JavaScript object representing the current state of the UI.\n * @returns A serialized record of the data payload, free of UI5 wrappers.\n */\n public extractPayload(): Record<string, unknown> {\n // Create a deep copy to prevent accidental mutations by the host\n // Uses a robust deep clone to avoid destructively coercing native objects (like Dates) to strings\n const data = this.model.getData();\n return this.deepClone(data) as Record<string, unknown>;\n }\n\n /**\n * Recursively clones an object while preserving native Date instances and arrays.\n */\n private deepClone(obj: any): any {\n if (obj === null || typeof obj !== \"object\") {\n return obj;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime());\n }\n\n if (Array.isArray(obj)) {\n const arrCopy = [];\n for (const item of obj) {\n arrCopy.push(this.deepClone(item));\n }\n return arrCopy;\n }\n\n const objCopy: any = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n objCopy[key] = this.deepClone(obj[key]);\n }\n }\n return objCopy;\n }\n\n /**\n * Programmatically mutates the internal JSONModel property (e.g. for PBRE state pruning).\n * @param path The path to the property.\n * @param value The value to set.\n */\n public setProperty(path: string, value: unknown): void {\n const absolutePath = path.startsWith(\"/\") ? path : `/${path}`;\n this.model.setProperty(absolutePath, value);\n }\n\n /**\n * Cleans up internal state and natively destroys the UI5 JSONModel to prevent memory leaks.\n */\n public destroy(): void {\n if (this.model) {\n // Fix Leaky Abstractions: Clean up any ghost errors in the global MessageManager bound to this model\n const messageManager = Messaging;\n const existingMessages = messageManager.getMessageModel().getData();\n const messagesToRemove = existingMessages.filter((msg: Message) => \n msg.getMessageProcessor() && msg.getMessageProcessor().getId() === this.model.getId()\n );\n if (messagesToRemove.length > 0) {\n messageManager.removeMessages(messagesToRemove);\n }\n\n this.model.destroy();\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"core"}},{"offset":{"line":31,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","CompactLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","addStyleClass","uiLayout","Array","isArray","warn","tableElements","renderElement","element","type","label","title","sap","m","Title","text","level","addItem","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isSubLayout","debug","push","this","_renderScalarField","field","subSchema","control","generateLayout","msg","message","showErrorPopup","labelText","Label","required","effectiveMeta","generateField","fieldBox","__exports","__esModule"],"sources":["CompactLayout.ts"],"sourcesContent":["/**\n * @file CompactLayout.ts\n * @description Generates a lightweight, dense VBox layout for use inside tight spaces like table cells.\n */\n\nimport VBox from \"sap/m/VBox\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a dense, lightweight layout (no SimpleForm padding).\n * Ideal for rendering objects dynamically inside table cells or side-panels.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class CompactLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a dense VBox layout.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated compact form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n container.addStyleClass(\"sapUiTinyMargin\");\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. CompactLayout will not render any fields.\");\n return container;\n }\n\n const tableElements: { scope: string, meta: IPropertyMetadata, label?: string }[] = [];\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n const title = new sap.m.Title({ text: element.label, level: \"H5\" });\n title.addStyleClass(\"sapUiTinyMarginTop sapUiTinyMarginBottom\");\n container.addItem(title);\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"CompactLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"CompactLayout\");\n return;\n }\n\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isSubLayout) {\n Logger.debug(\"[MetaUI CompactLayout]\", `Routing property '${propKey}' to Table Sub-Layout.`, \"CompactLayout\");\n tableElements.push({ scope: bindingPath, meta, label: element.label });\n } else {\n Logger.debug(\"[MetaUI CompactLayout]\", `Rendering scalar field '${bindingPath}'.`, \"CompactLayout\");\n this._renderScalarField(container, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"CompactLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n // Render array/table sub-layouts full width below the fields\n tableElements.forEach(field => {\n try {\n const subSchema = {\n type: \"array\",\n title: field.label || field.meta.ui?.label || field.scope,\n items: field.meta.items || { type: \"object\", properties: {} },\n uiLayout: field.meta.items?.uiLayout\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${field.scope}`);\n if (control) {\n control.addStyleClass(\"sapUiTinyMarginTop\");\n container.addItem(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render array field ${field.scope}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render array field '${field.scope}'.\\n\\nDetails: ${msg}`);\n }\n });\n\n return container;\n }\n\n /**\n * Synthesizes a primitive field into the layout.\n * @param container The VBox container.\n * @param element The layout element definition.\n * @param propKey The bound property key.\n * @param meta The inferred metadata schema.\n * @param modelName The UI5 data model name.\n * @param engine The core Engine instance.\n */\n private _renderScalarField(container: VBox, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n label.addStyleClass(\"sapUiTinyMarginTop\");\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n control.addStyleClass(\"sapUiTinyMarginBottom\");\n\n // Wrap label and field tightly\n const fieldBox = new VBox({ renderType: \"Bare\", items: [label, control] });\n container.addItem(fieldBox);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"CompactLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"AAAA,oLAWSA,EAAgBC,EAAA,0BAChBC,EAAMC,EAAA,UAUR,MAAMC,EAUFC,OAAOC,EAAiBC,EAAmBC,EAAgBC,GAC9D,MAAMC,EAAY,IAAIC,EAAK,CAAEC,WAAY,SACzCF,EAAUG,cAAc,mBAExB,IAAKP,EAAOQ,WAAaC,MAAMC,QAAQV,EAAOQ,UAAW,CACrDZ,EAAOe,KAAK,0FACZ,OAAOP,CACX,CAEA,MAAMQ,EAA8E,GAGpF,MAAMC,EAAiBC,IACnB,GAAIA,EAAQC,OAAS,QAAS,CAC1B,GAAID,EAAQE,MAAO,CACf,MAAMC,EAAQ,IAAIC,IAAIC,EAAEC,MAAM,CAAEC,KAAMP,EAAQE,MAAOM,MAAO,OAC5DL,EAAMV,cAAc,4CACpBH,EAAUmB,QAAQN,EACtB,CAEA,GAAIH,EAAQU,UAAYf,MAAMC,QAAQI,EAAQU,UAAW,CACrDV,EAAQU,SAASC,QAAQZ,EAC7B,CACJ,MAAO,GAAIC,EAAQC,OAAS,UAAW,CACnC,IAAKD,EAAQY,QAAUZ,EAAQY,MAAMC,WAAW,iBAAkB,CAC9D/B,EAAOgC,MAAM,2BAA2Bd,EAAQY,8BAA+B,GAAI,iBACnF,MACJ,CAEA,MAAMG,KAAEA,EAAIC,YAAEA,EAAWC,QAAEA,GAAYrC,EAAiBsC,aAAahC,EAAQc,EAAQY,OAErF,IAAKG,EAAM,CACPjC,EAAOgC,MAAM,sBAAsBG,sCAA6C,GAAI,iBACpF,MACJ,CAEA,MAAME,EAAwBJ,EAAKK,OAAOnB,OAAS,UAAYc,EAAKK,OAAOC,WAC3E,MAAMC,IAAsBP,EAAKQ,IAAIC,OACrC,MAAMC,EAAcV,EAAKd,OAAS,SAAWkB,IAA0BG,EAEvE,GAAIG,EAAa,CACb3C,EAAO4C,MAAM,yBAA0B,qBAAqBT,0BAAiC,iBAC7FnB,EAAc6B,KAAK,CAAEf,MAAOI,EAAaD,OAAMb,MAAOF,EAAQE,OAClE,KAAO,CACHpB,EAAO4C,MAAM,yBAA0B,2BAA2BV,MAAiB,iBACnFY,KAAKC,mBAAmBvC,EAAWU,EAASgB,EAAaD,EAAM5B,EAAWC,EAC9E,CACJ,KAAO,CACHN,EAAOe,KAAK,6CAA6CG,EAAQC,SAAU,GAAI,gBACnF,GAIJf,EAAOQ,SAASiB,QAAQZ,GAGxBD,EAAca,QAAQmB,IAClB,IACI,MAAMC,EAAY,CACd9B,KAAM,QACNE,MAAO2B,EAAM5B,OAAS4B,EAAMf,KAAKQ,IAAIrB,OAAS4B,EAAMlB,MACpDQ,MAAOU,EAAMf,KAAKK,OAAS,CAAEnB,KAAM,SAAUoB,WAAY,CAAC,GAC1D3B,SAAUoC,EAAMf,KAAKK,OAAO1B,UAGhC,MAAMsC,EAAU5C,EAAO6C,eAAeF,EAAsB5C,EAAW,IAAI2C,EAAMlB,SACjF,GAAIoB,EAAS,CACTA,EAAQvC,cAAc,sBACtBH,EAAUmB,QAAQuB,EACtB,CACJ,CAAE,MAAOlB,GACL,MAAMoB,EAAOpB,EAAgBqB,QAC7BrD,EAAOgC,MAAM,yCAAyCgB,EAAMlB,QAASsB,EAAK,iBAC1EpD,EAAOsD,eAAe,iCAAiCN,EAAMlB,uBAAuBsB,IACxF,IAGJ,OAAO5C,CACX,CAWQuC,mBAAmBvC,EAAiBU,EAAyBiB,EAAiBF,EAAyB5B,EAAmBC,GAC9H,IACI,MAAMiD,EAAYrC,EAAQE,OAASa,EAAKQ,IAAIrB,OAASe,EACrD,MAAMf,EAAQ,IAAIoC,EAAM,CACpB/B,KAAM8B,EACNE,SAAUxB,EAAKwB,WAEnBrC,EAAMT,cAAc,sBAEpB,MAAM+C,EAAgB,IAAKzB,GAC3B,GAAIf,EAAQwB,OAAQ,CAChBgB,EAAcjB,GAAK,IAAKR,EAAKQ,GAAIC,OAAQxB,EAAQwB,OACrD,CAEA,MAAMQ,EAAU5C,EAAOqD,cAAcD,EAAe,IAAIvB,IAAW9B,GACnE6C,EAAQvC,cAAc,yBAGtB,MAAMiD,EAAW,IAAInD,EAAK,CAAEC,WAAY,OAAQ4B,MAAO,CAAClB,EAAO8B,KAC/D1C,EAAUmB,QAAQiC,EACtB,CAAE,MAAO5B,GACL,MAAMoB,EAAOpB,EAAgBqB,QAC7BrD,EAAOgC,MAAM,mCAAmCG,IAAWiB,EAAK,iBAChEpD,EAAOsD,eAAe,2BAA2BnB,mBAAyBiB,IAC9E,CACJ,EACH,IAAAS,EAAA,CAAAC,WAAA,MAAAD,EAAA3D,gBAAA,OAAA2D,CAAA","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":32,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","PluginRegistry","___core_PluginRegistry","FormLayout","render","schema","modelName","engine","onSubmit","container","VBox","renderType","form","SimpleForm","editable","title","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","uiLayout","Array","isArray","warn","addItem","hasFormFields","renderElement","element","type","label","addContent","Title","text","elements","forEach","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","isCollectionOfRecords","items","properties","hasExplicitWidget","ui","widget","isTableSubLayout","debug","subSchema","control","generateLayout","sap","require","GridData","setLayoutData","span","msg","message","showErrorPopup","this","_renderScalarField","labelText","Label","required","effectiveMeta","generateField","isNativelyWide","getInstance","isPluginNativelyWide","isFullWidth","fullWidth","undefined","__exports","__esModule"],"sources":["FormLayout.ts"],"sourcesContent":["/**\n * @file FormLayout.ts\n * @description Generates a fully responsive SAP Fiori Form layout (SimpleForm).\n */\n\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport Title from \"sap/ui/core/Title\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\nimport { PluginRegistry } from \"../core/PluginRegistry\";\n\n/**\n * Layout Manager responsible for generating a fully responsive SAP Fiori SimpleForm.\n * It traverses the `uiLayout` tree defined in the schema to build the form groups and fields,\n * completely separating visual orchestration from data modeling.\n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class FormLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a UI5 SimpleForm using the uiLayout definitions.\n * \n * @param schema The active JSON schema subset.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Optional submit hook.\n * @returns {Control} The VBox wrapper containing the generated form.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const container = new VBox({ renderType: \"Bare\" });\n const form = new SimpleForm({\n editable: true,\n title: schema.title,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in schema. Form will not render any fields.\");\n container.addItem(form);\n return container;\n }\n\n let hasFormFields = false;\n\n // Recursively render layout elements\n const renderElement = (element: ILayoutElement) => {\n if (element.type === \"Group\") {\n if (element.label) {\n form.addContent(new Title({ text: element.label }));\n }\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(renderElement);\n }\n } else if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"FormLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"FormLayout\");\n return;\n }\n\n // Architectural Boundary: Separate Field Controls (Plugins) from Sub-Layouts (LayoutManagers)\n // A property is delegated to a Sub-Layout Manager (Table) ONLY if it represents a collection of complex objects.\n // Collections of primitives, or explicitly assigned widgets (like multiSelect), remain in the Form as Field Plugins.\n const isCollectionOfRecords = meta.items?.type === \"object\" || meta.items?.properties;\n const hasExplicitWidget = !!meta.ui?.widget;\n const isTableSubLayout = meta.type === \"array\" && isCollectionOfRecords && !hasExplicitWidget;\n\n if (isTableSubLayout) {\n Logger.debug(\"[MetaUI FormLayout]\", `Routing property '${propKey}' to Table Sub-Layout inline.`, \"FormLayout\");\n hasFormFields = true;\n try {\n const subSchema = {\n type: \"array\",\n title: element.label || meta.ui?.label || propKey,\n items: meta.items || { type: \"object\", properties: {} },\n uiLayout: meta.items?.uiLayout // Pass down sub-layout if available\n };\n \n const control = engine.generateLayout(subSchema as ISchema, modelName, `/${bindingPath}`);\n if (control) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: typeof import(\"sap/ui/layout/GridData\").default) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n form.addContent(control);\n }\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render inline array field ${bindingPath}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render array field '${bindingPath}'.\\n\\nDetails: ${msg}`);\n }\n } else {\n hasFormFields = true;\n Logger.debug(\"[MetaUI FormLayout]\", `Rendering scalar field '${bindingPath}'.`, \"FormLayout\");\n this._renderScalarField(form, element, bindingPath, meta, modelName, engine);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}'.`, \"\", \"FormLayout\");\n }\n };\n\n // Render everything defined in the layout\n schema.uiLayout.forEach(renderElement);\n\n if (hasFormFields) {\n container.addItem(form);\n }\n\n return container;\n }\n\n /**\n * Synthesizes a primitive field into the Form.\n * @param form The SimpleForm instance.\n * @param element The layout element definition.\n * @param propKey The bound property key.\n * @param meta The inferred metadata schema.\n * @param modelName The UI5 data model name.\n * @param engine The core Engine instance.\n */\n private _renderScalarField(form: SimpleForm, element: ILayoutElement, propKey: string, meta: IPropertyMetadata, modelName: string, engine: Engine): void {\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n // Override widget if specified in the layout element\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${propKey}`, modelName);\n\n // Automatically apply fullWidth layout data if natively wide or explicitly requested\n const isNativelyWide = PluginRegistry.getInstance().isPluginNativelyWide(effectiveMeta.type || \"string\", effectiveMeta.ui?.widget);\n const isFullWidth = effectiveMeta.ui?.fullWidth !== undefined ? effectiveMeta.ui?.fullWidth : isNativelyWide;\n\n if (isFullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: typeof import(\"sap/ui/layout/GridData\").default) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render field ${propKey}`, msg, \"FormLayout\");\n Logger.showErrorPopup(`Failed to render field '${propKey}'.\\n\\nDetails: ${msg}`);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":33,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","WIDGET_TYPE","___constants_MetaUIConstants","SCHEMA_TYPE","TableLayout","render","schema","modelName","engine","onSubmit","bindingPath","itemsSchema","items","properties","ui","widget","REFERENCE","$ref","debug","host","getSchemaDefinition","resolved","Object","keys","error","getMetadata","getName","isPrimitive","includes","type","ARRAY","Error","createSkeleton","meta","obj","key","default","undefined","enum","tableTitle","title","actualModelName","actualPath","table","Table","headerToolbar","Toolbar","content","Title","text","ToolbarSpacer","isEditable","Button","icon","press","oEvent","btn","getSource","tbl","getParent","model","getModel","info","getBindingInfo","path","rawData","getProperty","data","Array","isArray","newData","setProperty","onChange","replace","fixedLayout","mode","delete","item","getParameter","getBindingContext","getPath","splitPaths","split","index","parseInt","pop","arrayPath","join","splice","onArrayMutated","templateCells","props","layoutElements","uiLayout","addColumn","Column","header","Text","control","generateField","push","forEach","element","scope","fieldMeta","propKey","resolveScope","label","demandPopin","isKey","minScreenWidth","popinDisplay","effectiveMeta","warn","column","msg","message","showErrorPopup","rowTemplate","ColumnListItem","cells","bindItems","template","templateShareable","__exports","__esModule"],"sources":["TableLayout.ts"],"sourcesContent":["/**\n * @file TableLayout.ts\n * @description Generates a responsive SAP Fiori Table layout for v2 schema.\n */\n\nimport Table from \"sap/m/Table\";\nimport Column from \"sap/m/Column\";\nimport Text from \"sap/m/Text\";\nimport ColumnListItem from \"sap/m/ColumnListItem\";\nimport Toolbar from \"sap/m/Toolbar\";\nimport Title from \"sap/m/Title\";\nimport ToolbarSpacer from \"sap/m/ToolbarSpacer\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Control from \"sap/ui/core/Control\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport GeneratorHost from \"../controls/host/GeneratorHost\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport { WIDGET_TYPE, SCHEMA_TYPE } from \"../constants/MetaUIConstants\";\n\n/**\n * Layout Manager responsible for generating a responsive SAP Fiori Table.\n * It is automatically utilized by the Engine when the schema root or property is of type 'array'.\n * Includes built-in support for adding and deleting rows via dynamic data binding manipulation.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class TableLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema array properties into a UI5 Table.\n * \n * @param schema The active JSON schema array definition.\n * @param modelName The UI5 JSONModel name used for data binding.\n * @param engine The central orchestrator for delegating column plugin generation.\n * @param onSubmit Optional submit hook.\n * @param bindingPath The JSON path representing the array within the payload.\n * @returns {Control} The generated sap.m.Table control.\n * @throws {Error} If the provided schema is not of type 'array'.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void, bindingPath: string = \"/\"): Control {\n let itemsSchema = schema.items;\n if (itemsSchema && !itemsSchema.properties && itemsSchema.ui?.widget === WIDGET_TYPE.REFERENCE && itemsSchema.$ref) {\n Logger.debug(`[MetaUI] TableLayout detecting reference widget for ${bindingPath}. Resolving ${itemsSchema.$ref}`, \"\", \"TableLayout\");\n \n const host = engine.host as unknown as GeneratorHost;\n if (host && typeof host.getSchemaDefinition === \"function\") {\n const resolved = host.getSchemaDefinition(itemsSchema.$ref);\n Logger.debug(`[MetaUI] Resolved schema for ${itemsSchema.$ref}: ${!!resolved} ${resolved ? Object.keys(resolved) : \"\"}`, \"\", \"TableLayout\");\n if (resolved && resolved.properties) {\n itemsSchema = resolved;\n } else {\n Logger.error(`[MetaUI] TableLayout resolved schema but it has no properties!`, \"\", \"TableLayout\");\n }\n } else {\n Logger.error(`[MetaUI] TableLayout cannot resolve ${itemsSchema.$ref} because engine.host.getSchemaDefinition is missing! host: ${host?.getMetadata().getName()}`, \"\", \"TableLayout\");\n }\n }\n\n const isPrimitive = itemsSchema && !itemsSchema.properties && [\"string\", \"number\", \"boolean\"].includes(itemsSchema.type as string);\n if (schema.type !== SCHEMA_TYPE.ARRAY || !itemsSchema || (!itemsSchema.properties && !isPrimitive)) {\n Logger.error(`[MetaUI] TableLayout fatal error! schema.type: ${schema.type}, itemsSchema: ${!!itemsSchema}, properties: ${itemsSchema ? !!itemsSchema.properties : false}`, \"\", \"TableLayout\");\n throw new Error(\"[MetaUI] TableLayout requires an array schema with items.properties or primitive items.\");\n }\n\n const createSkeleton = (meta: ISchema | IPropertyMetadata): any => {\n if (meta.type === \"object\" && meta.properties) {\n const obj: any = {};\n for (const key of Object.keys(meta.properties)) {\n obj[key] = createSkeleton(meta.properties[key] as ISchema | IPropertyMetadata);\n }\n return obj;\n } else if (meta.type === \"array\") {\n return [];\n } else if (meta.type === \"string\") {\n return (meta as any).default !== undefined ? (meta as any).default : ((meta as any).enum ? (meta as any).enum[0] : \"\");\n } else if (meta.type === \"number\") {\n return (meta as any).default !== undefined ? (meta as any).default : 0;\n } else if (meta.type === \"boolean\") {\n return (meta as any).default !== undefined ? (meta as any).default : false;\n }\n return \"\";\n };\n\n const tableTitle = schema.title || \"Table\";\n const actualModelName = modelName;\n const actualPath = bindingPath;\n\n const table = new Table({\n headerToolbar: new Toolbar({\n content: [\n new Title({ text: tableTitle }),\n new ToolbarSpacer(),\n ...(!engine.isEditable ? [] : [\n new Button({\n text: \"Add Row\",\n icon: \"sap-icon://add\",\n press: (oEvent: sap.ui.base.Event) => {\n const btn = oEvent.getSource() as Button;\n const tbl = btn.getParent()?.getParent() as Table;\n const model = tbl.getModel(actualModelName) as JSONModel;\n const info = tbl.getBindingInfo(\"items\");\n if (!info || !info.path) return;\n\n const rawData = model.getProperty(info.path);\n const data = Array.isArray(rawData) ? rawData : [];\n const newData = [...data, createSkeleton(itemsSchema)];\n model.setProperty(info.path, newData);\n\n // CRITICAL: Notify the engine so it extracts payload and triggers liveUpdate\n if (engine.onChange) {\n engine.onChange(true, actualPath.replace(/^\\//, \"\"));\n }\n }\n })\n ])\n ]\n }),\n fixedLayout: false,\n mode: !engine.isEditable ? \"None\" : \"Delete\",\n delete: (oEvent: sap.ui.base.Event) => {\n const item = oEvent.getParameter(\"listItem\") as ColumnListItem;\n const path = item.getBindingContext(actualModelName)?.getPath();\n if (!path) return;\n const model = item.getModel(actualModelName) as JSONModel;\n\n const splitPaths = path.split(\"/\");\n const index = parseInt(splitPaths.pop() || \"0\", 10);\n let arrayPath = splitPaths.join(\"/\");\n if (arrayPath === \"\") arrayPath = \"/\";\n\n const rawData = model.getProperty(arrayPath);\n const data = Array.isArray(rawData) ? rawData : [];\n const newData = [...data];\n newData.splice(index, 1);\n model.setProperty(arrayPath, newData);\n\n // CRITICAL: Notify the engine so it extracts payload and triggers liveUpdate\n if (engine.onChange) {\n engine.onChange(true, actualPath.replace(/^\\//, \"\"));\n }\n\n // CRITICAL: Clear ghost errors that shifted due to array mutation\n if (typeof (engine as any).onArrayMutated === \"function\") {\n (engine as any).onArrayMutated(arrayPath);\n }\n }\n });\n\n const templateCells: Control[] = [];\n const props = itemsSchema.properties;\n const layoutElements = schema.uiLayout;\n\n if (isPrimitive) {\n table.addColumn(new Column({\n header: new Text({ text: \"Value\" })\n }));\n const control = engine.generateField(itemsSchema as IPropertyMetadata, \"\", actualModelName || \"meta\", true);\n templateCells.push(control);\n } else if (layoutElements && Array.isArray(layoutElements)) {\n // Only render columns defined in uiLayout\n layoutElements.forEach((element: ILayoutElement) => {\n if (element.type === \"Control\" && element.scope) {\n const { meta: fieldMeta, bindingPath, propKey } = SchemaNormalizer.resolveScope(\n { type: \"object\", properties: props } as ISchema, \n element.scope\n );\n \n if (!fieldMeta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions for Table.`, \"\", \"TableLayout\");\n } else {\n // The architectural boundary: Table Layout orchestrates the columns and aggregation binding,\n // but delegates the actual cell rendering to the Engine's Field Plugins.\n table.addColumn(new Column({\n header: new Text({ text: element.label || fieldMeta.ui?.label || propKey }),\n demandPopin: !fieldMeta.ui?.isKey,\n minScreenWidth: fieldMeta.ui?.isKey ? \"\" : \"Tablet\",\n popinDisplay: \"Inline\"\n }));\n\n const effectiveMeta = { ...fieldMeta };\n if (element.widget) {\n effectiveMeta.ui = { ...fieldMeta.ui, widget: element.widget };\n }\n\n // We pass the activeModel as actualModelName down. But the path must be relative to the \n // table row binding context, so we just use the bindingPath (e.g. \"id\" or \"header/id\")\n const control = engine.generateField(effectiveMeta, bindingPath, actualModelName || \"meta\", true);\n templateCells.push(control);\n }\n } else {\n Logger.warn(`[MetaUI] Unsupported layout element type '${element.type}' in Table.`, \"\", \"TableLayout\");\n }\n });\n } else {\n Logger.debug(\"[MetaUI TableLayout]\", \"No uiLayout provided. Falling back to rendering all properties as columns.\", \"TableLayout\");\n // Fallback: If no uiLayout is provided, render all properties as columns\n Object.keys(props).forEach((key) => {\n try {\n const fieldMeta = props[key];\n const isKey = !!fieldMeta.ui?.isKey;\n\n const column = new Column({\n header: new Text({ text: fieldMeta.ui?.label || key }),\n demandPopin: !isKey,\n minScreenWidth: isKey ? \"\" : \"Tablet\",\n popinDisplay: \"Inline\"\n });\n table.addColumn(column);\n\n const control = engine.generateField(fieldMeta, key, actualModelName || \"meta\", true);\n templateCells.push(control);\n } catch (error) {\n const msg = (error as Error).message;\n Logger.error(`[MetaUI] Failed to render fallback column ${key}`, msg, \"TableLayout\");\n Logger.showErrorPopup(`Failed to render fallback table column '${key}'.\\n\\nDetails: ${msg}`);\n templateCells.push(new Text({ text: \"Error\" }));\n }\n });\n }\n\n\n\n const rowTemplate = new ColumnListItem({\n cells: templateCells\n });\n\n table.bindItems({\n path: actualPath,\n model: actualModelName,\n template: rowTemplate,\n templateShareable: false\n });\n\n return table;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":34,"column":0},"map":{"version":3,"names":["SchemaNormalizer","___core_SchemaNormalizer","Logger","___utils_Logger","WizardLayout","render","schema","modelName","engine","onSubmit","wizard","Wizard","renderMode","showNextButton","complete","uiLayout","Array","isArray","warn","forEach","element","type","step","WizardStep","title","label","validated","form","SimpleForm","editable","layout","labelSpanXL","labelSpanL","labelSpanM","labelSpanS","adjustLabelSpan","emptySpanXL","emptySpanL","emptySpanM","emptySpanS","columnsXL","columnsL","columnsM","singleContainerFullSize","elements","childElement","this","_renderElementInForm","addContent","addStep","scope","startsWith","error","meta","bindingPath","propKey","resolveScope","labelText","ui","Label","text","required","effectiveMeta","widget","control","generateField","fullWidth","sap","require","GridData","setLayoutData","span","message","__exports","__esModule"],"sources":["WizardLayout.ts"],"sourcesContent":["/**\n * @file WizardLayout.ts\n * @description Generates a fully responsive SAP Fiori Wizard layout.\n */\n\nimport Wizard from \"sap/m/Wizard\";\nimport WizardStep from \"sap/m/WizardStep\";\nimport SimpleForm from \"sap/ui/layout/form/SimpleForm\";\nimport Label from \"sap/m/Label\";\nimport VBox from \"sap/m/VBox\";\nimport { IPropertyMetadata, ISchema, ILayoutElement } from \"../interfaces/ISchema\";\nimport { ILayoutManager } from \"../interfaces/ILayoutManager\";\nimport { Engine } from \"../core/Engine\";\nimport { SchemaNormalizer } from \"../core/SchemaNormalizer\";\nimport { Logger } from \"../utils/Logger\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Layout Manager responsible for generating a responsive SAP Fiori Wizard.\n * It segments the schema fields into discrete Wizard Steps based on `uiLayout` elements \n * of type `Group` or `WizardStep`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.layouts\n * @public\n */\nexport class WizardLayout implements ILayoutManager {\n /**\n * Renders the JSON Schema properties into a paginated UI5 Wizard using uiLayout.\n * \n * @param schema The active JSON schema object.\n * @param modelName The bound UI5 model name.\n * @param engine The central orchestrator for delegating plugin generation.\n * @param onSubmit Hook executed when the Wizard's native 'complete' event is fired.\n * @returns {Control} The generated sap.m.Wizard control.\n */\n public render(schema: ISchema, modelName: string, engine: Engine, onSubmit?: () => void): Control {\n const wizard = new Wizard({\n renderMode: \"Page\",\n showNextButton: true,\n complete: function() {\n if (onSubmit) onSubmit();\n }\n });\n\n if (!schema.uiLayout || !Array.isArray(schema.uiLayout)) {\n Logger.warn(\"[MetaUI] Missing 'uiLayout' array in wizard schema. Wizard will not render any steps.\");\n return wizard;\n }\n\n schema.uiLayout.forEach((element: ILayoutElement) => {\n if (element.type === \"Group\" || element.type === \"WizardStep\") {\n const step = new WizardStep({\n title: element.label || \"Step\",\n validated: true // The PipelineManager handles global validation, wizard step validation can be local later\n });\n\n const form = new SimpleForm({\n editable: true,\n layout: \"ResponsiveGridLayout\",\n labelSpanXL: 4, labelSpanL: 4, labelSpanM: 4, labelSpanS: 12,\n adjustLabelSpan: false,\n emptySpanXL: 0, emptySpanL: 0, emptySpanM: 0, emptySpanS: 0,\n columnsXL: 1, columnsL: 1, columnsM: 1,\n singleContainerFullSize: false\n });\n \n if (element.elements && Array.isArray(element.elements)) {\n element.elements.forEach(childElement => {\n this._renderElementInForm(form, childElement, schema, modelName, engine);\n });\n }\n\n step.addContent(form);\n wizard.addStep(step);\n } else {\n Logger.warn(`[MetaUI] Top-level element '${element.type}' inside WizardLayout must be 'Group' or 'WizardStep'.`, \"\", \"WizardLayout\");\n }\n });\n\n return wizard;\n }\n\n /**\n * Synthesizes a field into the wizard step form.\n * @param form The SimpleForm belonging to the step.\n * @param element The layout element definition.\n * @param schema The schema reference.\n * @param modelName The UI5 data model name.\n * @param engine The core Engine instance.\n */\n private _renderElementInForm(form: SimpleForm, element: ILayoutElement, schema: ISchema, modelName: string, engine: Engine): void {\n if (element.type === \"Control\") {\n if (!element.scope || !element.scope.startsWith(\"#/properties/\")) {\n Logger.error(`[MetaUI] Invalid scope '${element.scope}' in uiLayout Control.`, \"\", \"WizardLayout\");\n return;\n }\n \n const { meta, bindingPath, propKey } = SchemaNormalizer.resolveScope(schema, element.scope);\n \n if (!meta) {\n Logger.error(`[MetaUI] Property '${propKey}' not found in schema definitions.`, \"\", \"WizardLayout\");\n return;\n }\n\n try {\n const labelText = element.label || meta.ui?.label || propKey;\n const label = new Label({\n text: labelText,\n required: meta.required\n });\n\n const effectiveMeta = { ...meta };\n if (element.widget) {\n effectiveMeta.ui = { ...meta.ui, widget: element.widget };\n }\n\n const control = engine.generateField(effectiveMeta, `/${bindingPath}`, modelName);\n\n if (effectiveMeta.ui?.fullWidth) {\n sap.ui.require([\"sap/ui/layout/GridData\"], (GridData: typeof import(\"sap/ui/layout/GridData\").default) => {\n control.setLayoutData(new GridData({ span: \"XL12 L12 M12 S12\" }));\n });\n }\n\n form.addContent(label);\n form.addContent(control);\n } catch (error) {\n Logger.error(`[MetaUI] Failed to render Wizard field ${propKey}`, (error as Error).message, \"WizardLayout\");\n form.addContent(new Label({ text: propKey }));\n }\n } else {\n Logger.warn(`[MetaUI] Nested groups within Wizard steps are not fully supported in SimpleForm yet.`, \"\", \"WizardLayout\");\n }\n }\n}\n"],"mappings":"AAAA,4OAaSA,EAAgBC,EAAA,0BAChBC,EAAMC,EAAA,UAWR,MAAMC,EAUFC,OAAOC,EAAiBC,EAAmBC,EAAgBC,GAC9D,MAAMC,EAAS,IAAIC,EAAO,CACtBC,WAAY,OACZC,eAAgB,KAChBC,SAAU,WACN,GAAIL,EAAUA,GAClB,IAGJ,IAAKH,EAAOS,WAAaC,MAAMC,QAAQX,EAAOS,UAAW,CACrDb,EAAOgB,KAAK,yFACZ,OAAOR,CACX,CAEAJ,EAAOS,SAASI,QAASC,IACrB,GAAIA,EAAQC,OAAS,SAAWD,EAAQC,OAAS,aAAc,CAC3D,MAAMC,EAAO,IAAIC,EAAW,CACxBC,MAAOJ,EAAQK,OAAS,OACxBC,UAAW,OAGf,MAAMC,EAAO,IAAIC,EAAW,CACxBC,SAAU,KACVC,OAAQ,uBACRC,YAAa,EAAGC,WAAY,EAAGC,WAAY,EAAGC,WAAY,GAC1DC,gBAAiB,MACjBC,YAAa,EAAGC,WAAY,EAAGC,WAAY,EAAGC,WAAY,EAC1DC,UAAW,EAAGC,SAAU,EAAGC,SAAU,EACrCC,wBAAyB,QAG7B,GAAIvB,EAAQwB,UAAY5B,MAAMC,QAAQG,EAAQwB,UAAW,CACrDxB,EAAQwB,SAASzB,QAAQ0B,IACrBC,KAAKC,qBAAqBpB,EAAMkB,EAAcvC,EAAQC,EAAWC,IAEzE,CAEAc,EAAK0B,WAAWrB,GAChBjB,EAAOuC,QAAQ3B,EACnB,KAAO,CACHpB,EAAOgB,KAAK,+BAA+BE,EAAQC,6DAA8D,GAAI,eACzH,IAGJ,OAAOX,CACX,CAUQqC,qBAAqBpB,EAAkBP,EAAyBd,EAAiBC,EAAmBC,GACxG,GAAIY,EAAQC,OAAS,UAAW,CAC5B,IAAKD,EAAQ8B,QAAU9B,EAAQ8B,MAAMC,WAAW,iBAAkB,CAC9DjD,EAAOkD,MAAM,2BAA2BhC,EAAQ8B,8BAA+B,GAAI,gBACnF,MACJ,CAEA,MAAMG,KAAEA,EAAIC,YAAEA,EAAWC,QAAEA,GAAYvD,EAAiBwD,aAAalD,EAAQc,EAAQ8B,OAErF,IAAKG,EAAM,CACPnD,EAAOkD,MAAM,sBAAsBG,sCAA6C,GAAI,gBACpF,MACJ,CAEA,IACI,MAAME,EAAYrC,EAAQK,OAAS4B,EAAKK,IAAIjC,OAAS8B,EACrD,MAAM9B,EAAQ,IAAIkC,EAAM,CACpBC,KAAMH,EACNI,SAAUR,EAAKQ,WAGnB,MAAMC,EAAgB,IAAKT,GAC3B,GAAIjC,EAAQ2C,OAAQ,CAChBD,EAAcJ,GAAK,IAAKL,EAAKK,GAAIK,OAAQ3C,EAAQ2C,OACrD,CAEA,MAAMC,EAAUxD,EAAOyD,cAAcH,EAAe,IAAIR,IAAe/C,GAEvE,GAAIuD,EAAcJ,IAAIQ,UAAW,CAC7BC,IAAIT,GAAGU,QAAQ,CAAC,0BAA4BC,IACxCL,EAAQM,cAAc,IAAID,EAAS,CAAEE,KAAM,uBAEnD,CAEA5C,EAAKqB,WAAWvB,GAChBE,EAAKqB,WAAWgB,EACpB,CAAE,MAAOZ,GACLlD,EAAOkD,MAAM,0CAA0CG,IAAYH,EAAgBoB,QAAS,gBAC5F7C,EAAKqB,WAAW,IAAIW,EAAM,CAAEC,KAAML,IACtC,CACJ,KAAO,CACHrD,EAAOgB,KAAK,wFAAyF,GAAI,eAC7G,CACJ,EACH,IAAAuD,EAAA,CAAAC,WAAA,MAAAD,EAAArE,eAAA,OAAAqE,CAAA","ignoreList":[],"sourceRoot":"layouts"}},{"offset":{"line":35,"column":0},"map":{"version":3,"names":["Core","initLibrary","name","version","dependencies","controls","elements","interfaces","noLibraryCSS","__exports","window","nz","co","siliconst","ui5","metaui"],"sources":["library.ts"],"sourcesContent":["/**\n * @file library.ts\n * @description Standard SAP UI5 library registration file. Exposes the MetaUI namespace \n * and automatically bootstraps the internal PluginRegistry.\n */\n\nimport Core from \"sap/ui/core/Core\";\n\n// Explicitly import core plugins to bundle them into library-preload.js\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/StringPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/NumberPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/BooleanPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/ObjectPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/ArrayPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/DropdownPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/MultiInputPlugin\";\nimport \"nz/co/siliconst/ui5/metaui/plugins/controls/DatePlugin\";\nimport \"nz/co/siliconst/ui5/metaui/core/DefaultLayoutGenerator\";\nimport \"nz/co/siliconst/ui5/metaui/utils/ExpressionBuilder\";\n\n// Explicitly import core Layouts\nimport \"nz/co/siliconst/ui5/metaui/layouts/FormLayout\";\nimport \"nz/co/siliconst/ui5/metaui/layouts/TableLayout\";\nimport \"nz/co/siliconst/ui5/metaui/layouts/WizardLayout\";\nimport \"nz/co/siliconst/ui5/metaui/layouts/CompactLayout\";\n\n// AI Inference\nimport \"nz/co/siliconst/ui5/metaui/ai/BaseAIGenerator\";\nimport \"nz/co/siliconst/ui5/metaui/ai/MockLLMProxy\";\nimport \"nz/co/siliconst/ui5/metaui/ai/RestLLMProxy\";\nimport \"nz/co/siliconst/ui5/metaui/ai/AIConfig\";\n\n// Delegate to standard library registration\nCore.initLibrary({\n name: \"nz.co.siliconst.ui5.metaui\",\n version: \"1.0.0\",\n dependencies: [\n \"sap.ui.core\",\n \"sap.m\",\n \"sap.ui.layout\",\n \"sap.ui.table\"\n ],\n controls: [\n \"nz.co.siliconst.ui5.metaui.controls.DynamicHost\",\n \"nz.co.siliconst.ui5.metaui.controls.host.GeneratorHost\",\n \"nz.co.siliconst.ui5.metaui.controls.BaseHardwareControl\",\n \"nz.co.siliconst.ui5.metaui.controls.CameraControl\",\n \"nz.co.siliconst.ui5.metaui.controls.BarcodeScannerControl\",\n \"nz.co.siliconst.ui5.metaui.controls.SignatureControl\",\n \"nz.co.siliconst.ui5.metaui.controls.VoiceInputControl\",\n \"nz.co.siliconst.ui5.metaui.controls.GeolocationControl\",\n \"nz.co.siliconst.ui5.metaui.controls.RichTextControl\"\n ],\n elements: [],\n interfaces: [],\n noLibraryCSS: true\n});\n\n// Exporting window object safely for UI5 compatibility if needed\ndeclare global {\n interface Window {\n nz: {\n co: {\n siliconst: {\n ui5: {\n metaui: Record<string, unknown>;\n };\n };\n };\n };\n }\n}\n\nexport default window.nz.co.siliconst.ui5.metaui;\n"],"mappings":"AAAA,4kCAiCAA,EAAKC,YAAY,CACbC,KAAM,6BACNC,QAAS,QACTC,aAAc,CACV,cACA,QACA,gBACA,gBAEJC,SAAU,CACN,kDACA,yDACA,0DACA,oDACA,4DACA,uDACA,wDACA,yDACA,uDAEJC,SAAU,GACVC,WAAY,GACZC,aAAc,OAGlB,IAAAC,EAeeC,OAAOC,GAAGC,GAAGC,UAAUC,IAAIC,OAAM,OAAAN,CAAA","ignoreList":[],"sourceRoot":""}},{"offset":{"line":36,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","OpenApiParserFactory","___OpenApiParserFactory","OpenApiHeuristicEngine","___heuristics_OpenApiHeuristicEngine","OpenApiBuilder","canHandle","rawSchema","schema","openapi","swagger","build","targetDefinition","fetchAndBuild","url","response","fetch","ok","Error","status","openApiRoot","json","this","error","msg","message","heuristicEngine","run","parser","getParser","parse","__exports","__esModule"],"sources":["OpenApiBuilder.ts"],"sourcesContent":["/**\n * @file OpenApiBuilder.ts\n * @description Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.\n * Strict Single Responsibility architecture delegates mapping logic to dedicated utilities and factories.\n */\n\nimport { ISchema } from \"../interfaces/ISchema\";\nimport { ISchemaBuilderPlugin } from \"../interfaces/ISchemaBuilderPlugin\";\nimport { Logger } from \"../utils/Logger\";\nimport { OpenApiParserFactory } from \"./OpenApiParserFactory\";\nimport { OpenApiHeuristicEngine } from \"./heuristics/OpenApiHeuristicEngine\";\n\n/**\n * Facade orchestration for translating Swagger/OpenAPI JSON into native MetaUI ISchema.\n * Strict Single Responsibility architecture delegates mapping logic to dedicated utilities and factories.\n * \n * @public\n */\nexport class OpenApiBuilder implements ISchemaBuilderPlugin {\n\n /**\n * Determines if the provided JSON payload is a Swagger or OpenAPI document.\n * \n * @param {unknown} rawSchema The raw JSON schema to test.\n * @returns {boolean} True if the document contains 'openapi' or 'swagger' root keys.\n */\n public canHandle(rawSchema: unknown): boolean {\n const schema = rawSchema as Record<string, unknown>;\n return !!(schema && (schema.openapi || schema.swagger));\n }\n\n /**\n * Builds a strict MetaUI ISchema from the provided OpenAPI payload.\n * \n * @param {unknown} rawSchema The OpenAPI root document.\n * @param {string} [targetDefinition] Optional target root definition.\n * @returns {ISchema} The translated MetaUI schema.\n */\n public build(rawSchema: unknown, targetDefinition?: string): ISchema {\n return OpenApiBuilder.build(rawSchema, targetDefinition);\n }\n\n /**\n * Asynchronously fetches a remote OpenAPI document and compiles it into a MetaUI ISchema.\n * \n * @param {string} url The URL to fetch the JSON payload from.\n * @param {string} [targetDefinition] Optional. The specific entity schema to extract.\n * @returns {Promise<ISchema>} A Promise resolving to the compiled ISchema.\n */\n public static async fetchAndBuild(url: string, targetDefinition?: string): Promise<ISchema> {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const openApiRoot = await response.json();\n return this.build(openApiRoot, targetDefinition);\n } catch (error) {\n const msg = \"Failed to fetch Swagger JSON from URL: \" + (error as Error).message;\n Logger.error(\"[MetaUI OpenApiBuilder]\", msg);\n throw new Error(msg);\n }\n }\n\n /**\n * Synchronously builds a MetaUI ISchema from a provided OpenAPI root document.\n * Delegates to HeuristicEngine and OpenApiParserFactory.\n * \n * @public\n * @param {unknown} openApiRoot The raw OpenAPI root JSON document.\n * @param {string} [targetDefinition] Optional target definition key to extract.\n * @returns {ISchema} The synthesized MetaUI schema.\n * @throws {Error} If the root object is invalid.\n */\n public static build(openApiRoot: unknown, targetDefinition?: string): ISchema {\n if (!openApiRoot || typeof openApiRoot !== \"object\") {\n throw new Error(\"[MetaUI OpenApiBuilder] Invalid Swagger root object provided.\");\n }\n\n // 1. Run Heuristics to mutate AST (e.g., simulating oneOf)\n const heuristicEngine = new OpenApiHeuristicEngine();\n heuristicEngine.run(openApiRoot);\n\n // 2. Delegate to correct parser version\n const parser = OpenApiParserFactory.getParser(openApiRoot);\n return parser.parse(openApiRoot, targetDefinition);\n }\n}\n"],"mappings":"AAAA,sLAAA,MAQSA,EAAMC,EAAA,gBACNC,EAAoBC,EAAA,8BACpBC,EAAsBC,EAAA,0BAQxB,MAAMC,EAQFC,UAAUC,GACb,MAAMC,EAASD,EACf,SAAUC,IAAWA,EAAOC,SAAWD,EAAOE,SAClD,CASOC,MAAMJ,EAAoBK,GAC7B,OAAOP,EAAeM,MAAMJ,EAAWK,EAC3C,CASA,0BAAoBC,CAAcC,EAAaF,GAC3C,IACI,MAAMG,QAAiBC,MAAMF,GAC7B,IAAKC,EAASE,GAAI,CACd,MAAM,IAAIC,MAAM,uBAAuBH,EAASI,SACpD,CACA,MAAMC,QAAoBL,EAASM,OACnC,OAAOC,KAAKX,MAAMS,EAAaR,EACnC,CAAE,MAAOW,GACL,MAAMC,EAAM,0CAA6CD,EAAgBE,QACzE1B,EAAOwB,MAAM,0BAA2BC,GACxC,MAAM,IAAIN,MAAMM,EACpB,CACJ,CAYA,YAAcb,CAAMS,EAAsBR,GACtC,IAAKQ,UAAsBA,IAAgB,SAAU,CACjD,MAAM,IAAIF,MAAM,gEACpB,CAGA,MAAMQ,EAAkB,IAAIvB,EAC5BuB,EAAgBC,IAAIP,GAGpB,MAAMQ,EAAS3B,EAAqB4B,UAAUT,GAC9C,OAAOQ,EAAOE,MAAMV,EAAaR,EACrC,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAA1B,iBAAA,OAAA0B,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":37,"column":0},"map":{"version":3,"names":["OpenApi2Parser","___parsers_OpenApi2Parser","OpenApi3Parser","___parsers_OpenApi3Parser","Logger","___utils_Logger","OpenApiParserFactory","getParser","rawSchema","error","schema","swagger","openapi","startsWith","warn","__exports","__esModule"],"sources":["OpenApiParserFactory.ts"],"sourcesContent":["/**\n * @file OpenApiParserFactory.ts\n * @description Factory class to determine and instantiate the correct Swagger parser version.\n */\n\nimport { IOpenApiParserPlugin } from \"./interfaces/IOpenApiParserPlugin\";\nimport { OpenApi2Parser } from \"./parsers/OpenApi2Parser\";\nimport { OpenApi3Parser } from \"./parsers/OpenApi3Parser\";\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Factory class responsible for analyzing a raw OpenAPI document's metadata to dynamically \n * instantiate the correct, version-specific parser plugin. This isolates structural version \n * differences from the primary Engine orchestration layer.\n * \n * @public\n */\nexport class OpenApiParserFactory {\n /**\n * Inspects the root level structural signatures of an OpenAPI document (e.g., `swagger: \"2.0\"` \n * vs `openapi: \"3.x\"`) to instantiate the appropriate parsing engine.\n * \n * @param {any} rawSchema The raw, unparsed OpenAPI root JSON structure.\n * @returns {IOpenApiParserPlugin} An initialized instance of the correct concrete parser plugin.\n */\n public static getParser(rawSchema: unknown): IOpenApiParserPlugin {\n if (!rawSchema || typeof rawSchema !== \"object\") {\n Logger.error(\"[MetaUI OpenApiParserFactory] Invalid OpenAPI document provided.\");\n return new OpenApi3Parser(); // Fallback\n }\n\n const schema = rawSchema as Record<string, unknown>;\n if (schema.swagger === \"2.0\") {\n return new OpenApi2Parser();\n }\n\n if (schema.openapi && typeof schema.openapi === \"string\" && schema.openapi.startsWith(\"3\")) {\n return new OpenApi3Parser();\n }\n\n Logger.warn(\"[MetaUI OpenApiParserFactory] Unable to strictly determine OpenAPI version. Defaulting to OpenAPI 3.0 Parser.\");\n return new OpenApi3Parser();\n }\n}\n"],"mappings":"AAAA,mLAAA,MAMSA,EAAcC,EAAA,wBACdC,EAAcC,EAAA,wBACdC,EAAMC,EAAA,UASR,MAAMC,EAQT,gBAAcC,CAAUC,GACpB,IAAKA,UAAoBA,IAAc,SAAU,CAC7CJ,EAAOK,MAAM,oEACb,OAAO,IAAIP,CACf,CAEA,MAAMQ,EAASF,EACf,GAAIE,EAAOC,UAAY,MAAO,CAC1B,OAAO,IAAIX,CACf,CAEA,GAAIU,EAAOE,gBAAkBF,EAAOE,UAAY,UAAYF,EAAOE,QAAQC,WAAW,KAAM,CACxF,OAAO,IAAIX,CACf,CAEAE,EAAOU,KAAK,iHACZ,OAAO,IAAIZ,CACf,EACH,IAAAa,EAAA,CAAAC,WAAA,MAAAD,EAAAT,uBAAA,OAAAS,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":38,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","OpenApiRefResolver","resolve","refUrl","openApiRoot","depth","startsWith","debug","error","pathSegments","substring","split","current","segment","$ref","this","__exports","__esModule"],"sources":["OpenApiRefResolver.ts"],"sourcesContent":["/**\n * @file OpenApiRefResolver.ts\n * @description Utility class for resolving local $ref pointers within an OpenAPI document.\n */\nimport { Logger } from \"../utils/Logger\";\n\n/**\n * Utility class for resolving local $ref pointers within an OpenAPI document.\n * \n * @public\n */\nexport class OpenApiRefResolver {\n /**\n * Recursively traverses a local JSON Pointer $ref path (e.g., '#/components/schemas/Pet')\n * and extracts the target object from the Swagger root document.\n * External URLs or invalid references are safely ignored.\n * \n * @param {string} refUrl The $ref string path.\n * @param {any} openApiRoot The root OpenAPI document to query against.\n * @param {number} depth The current recursive depth count, used to prevent infinite loops.\n * @returns {any} The resolved schema object, or null if unresolvable.\n */\n public static resolve(refUrl: string, openApiRoot: unknown, depth: number = 0): unknown {\n if (!refUrl || !refUrl.startsWith(\"#/\")) {\n Logger.debug(`[MetaUI OpenApiBuilder] Ignoring non-local or empty $ref: ${refUrl}`, \"OpenApiBuilder\");\n return null; // Ignore external URLs per architectural rules\n }\n\n // Circular Reference Limit:\n // A hard limit is enforced to prevent stack overflow exceptions caused by infinitely \n // recursive structures (e.g., a Tree node that references another Tree node).\n if (depth > 10) {\n Logger.error(`[MetaUI OpenApiBuilder] Circular or overly deep $ref detected: ${refUrl}`, null, \"OpenApiBuilder\");\n return null;\n }\n\n // Path Segment Parsing:\n // The '#/' prefix is stripped, and the remaining path is split by '/'.\n // We incrementally descend into the swagger root using these segments.\n const pathSegments = refUrl.substring(2).split(\"/\");\n let current = openApiRoot;\n\n for (const segment of pathSegments) {\n if (current && typeof current === \"object\" && segment in current) {\n current = (current as Record<string, unknown>)[segment];\n } else {\n Logger.error(`[MetaUI OpenApiBuilder] Failed to resolve local $ref: ${refUrl}`, null, \"OpenApiBuilder\");\n return null;\n }\n }\n\n // Deep Resolution Recursion:\n // If the resolved target is itself a reference pointer, recursively resolve again\n // until we reach a terminal structure or hit the recursion depth limit.\n if (current && typeof current === \"object\" && (current as Record<string, unknown>).$ref) {\n return this.resolve((current as Record<string, unknown>).$ref as string, openApiRoot, depth + 1);\n }\n\n return current;\n }\n}\n"],"mappings":"AAAA,uHAAA,MAISA,EAAMC,EAAA,UAOR,MAAMC,EAWT,cAAcC,CAAQC,EAAgBC,EAAsBC,EAAgB,GACxE,IAAKF,IAAWA,EAAOG,WAAW,MAAO,CACrCP,EAAOQ,MAAM,6DAA6DJ,IAAU,kBACpF,OAAO,IACX,CAKA,GAAIE,EAAQ,GAAI,CACZN,EAAOS,MAAM,kEAAkEL,IAAU,KAAM,kBAC/F,OAAO,IACX,CAKA,MAAMM,EAAeN,EAAOO,UAAU,GAAGC,MAAM,KAC/C,IAAIC,EAAUR,EAEd,IAAK,MAAMS,KAAWJ,EAAc,CAChC,GAAIG,UAAkBA,IAAY,UAAYC,KAAWD,EAAS,CAC9DA,EAAWA,EAAoCC,EACnD,KAAO,CACHd,EAAOS,MAAM,yDAAyDL,IAAU,KAAM,kBACtF,OAAO,IACX,CACJ,CAKA,GAAIS,UAAkBA,IAAY,UAAaA,EAAoCE,KAAM,CACrF,OAAOC,KAAKb,QAASU,EAAoCE,KAAgBV,EAAaC,EAAQ,EAClG,CAEA,OAAOO,CACX,EACH,IAAAI,EAAA,CAAAC,WAAA,MAAAD,EAAAf,qBAAA,OAAAe,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":39,"column":0},"map":{"version":3,"names":["OpenApiTypeMapper","mapType","openApiType","typeMap","string","number","integer","boolean","array","object","date","__exports","__esModule"],"sources":["OpenApiTypeMapper.ts"],"sourcesContent":["/**\n * @file OpenApiTypeMapper.ts\n * @description Utility class for mapping OpenAPI primitive types to MetaUI FieldTypes.\n */\nimport { FieldType } from \"../interfaces/ISchema\";\n\n/**\n * Acts as the translation boundary between raw OpenAPI types and the internal MetaUI FieldType enumerations.\n * This ensures that the core layout engine never has to parse or understand Swagger-specific semantics.\n * \n * @public\n */\nexport class OpenApiTypeMapper {\n /**\n * Maps an OpenAPI primitive type string to the closest MetaUI FieldType.\n * If the type is omitted (common for objects) or unknown, it defaults to \"object\"\n * to trigger a safe nested-form fallback behavior.\n * \n * @param {string} openApiType The raw OpenAPI type (e.g., 'string', 'integer').\n * @returns {FieldType} The mapped MetaUI FieldType strictly understood by the core engine.\n */\n public static mapType(openApiType: string): FieldType {\n const typeMap: Record<string, FieldType> = {\n \"string\": \"string\",\n \"number\": \"number\",\n \"integer\": \"integer\",\n \"boolean\": \"boolean\",\n \"array\": \"array\",\n \"object\": \"object\",\n \"date\": \"date\"\n };\n \n // Default to \"object\" if the type is unknown or omitted by the API specification.\n return typeMap[openApiType] || \"object\";\n }\n}\n"],"mappings":"AAAA,oGAYO,MAAMA,EAST,cAAcC,CAAQC,GAClB,MAAMC,EAAqC,CACvCC,OAAU,SACVC,OAAU,SACVC,QAAW,UACXC,QAAW,UACXC,MAAS,QACTC,OAAU,SACVC,KAAQ,QAIZ,OAAOP,EAAQD,IAAgB,QACnC,EACH,IAAAS,EAAA,CAAAC,WAAA,MAAAD,EAAAX,oBAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":40,"column":0},"map":{"version":3,"names":["OpenApiUIMapper","build","rawProp","keyName","swaggerProp","ui","title","label","this","generateLabel","readOnly","format","widget","validators","push","name","spaced","replace","split","filter","w","length","map","word","charAt","toUpperCase","slice","toLowerCase","join","trim","__exports","__esModule"],"sources":["OpenApiUIMapper.ts"],"sourcesContent":["/**\n * @file OpenApiUIMapper.ts\n * @description Utility class for mapping OpenAPI properties and formats into MetaUI IUIDirectives.\n */\nimport { IUIDirective } from \"../interfaces/ISchema\";\n\n/**\n * Utility class responsible for evaluating OpenAPI metadata and generating the corresponding \n * MetaUI UI rendering directives. This isolates all visual layout assumptions from the parsing engine.\n * \n * @public\n */\nexport class OpenApiUIMapper {\n /**\n * Evaluates an OpenAPI property definition and constructs a MetaUI IUIDirective block.\n * Extracts labels from title/description, maps readOnly state, and assigns \n * specific UI5 Fiori widgets based on the OpenAPI 'format' property.\n * \n * @param {any} swaggerProp The raw OpenAPI property schema chunk.\n * @param {string} keyName The technical JSON key of the property.\n * @returns {IUIDirective} The constructed MetaUI UI orchestration directive.\n */\n public static build(rawProp: unknown, keyName: string): IUIDirective {\n const swaggerProp = (rawProp || {}) as Record<string, unknown>;\n const ui: IUIDirective = {};\n\n // Label Synthesis\n if (swaggerProp.title) {\n ui.label = swaggerProp.title as string;\n } else {\n ui.label = this.generateLabel(keyName);\n }\n\n // State Mapping\n if (swaggerProp.readOnly === true) {\n ui.readOnly = true;\n }\n\n // Format to Widget Translation\n if (swaggerProp.format) {\n switch (swaggerProp.format) {\n case \"date-time\":\n ui.widget = \"datetime\";\n break;\n case \"date\":\n ui.widget = \"date\";\n break;\n case \"password\":\n ui.widget = \"password\";\n ui.format = \"password\"; // Kept for schema validation\n break;\n case \"email\":\n ui.widget = \"email\";\n ui.format = \"email\"; // Kept for schema validation\n break;\n case \"uri\":\n ui.widget = \"link\";\n ui.format = \"url\"; // Kept for schema validation\n break;\n case \"binary\":\n case \"byte\":\n ui.widget = \"fileUploader\";\n break;\n case \"uuid\":\n case \"ipv4\":\n case \"ipv6\":\n case \"hostname\":\n if (!ui.validators) ui.validators = [];\n ui.validators.push(swaggerProp.format as string);\n break;\n }\n }\n\n return ui;\n }\n\n /**\n * Synthesizes a human-readable Title Case label from camelCase or snake_case technical keys.\n * \n * @param {string} name The raw technical property key (e.g., 'creationTimestamp').\n * @returns {string} The formatted human-readable label (e.g., 'Creation Timestamp').\n * @private\n */\n private static generateLabel(name: string): string {\n if (!name) return \"\";\n let spaced = name.replace(/([A-Z])/g, \" $1\").replace(/_/g, \" \");\n return spaced.split(' ')\n .filter(w => w.length > 0)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ')\n .trim();\n }\n}\n"],"mappings":"AAAA,kGAYO,MAAMA,EAUT,YAAcC,CAAMC,EAAkBC,GAClC,MAAMC,EAAeF,GAAW,CAAC,EACjC,MAAMG,EAAmB,CAAC,EAG1B,GAAID,EAAYE,MAAO,CACnBD,EAAGE,MAAQH,EAAYE,KAC3B,KAAO,CACHD,EAAGE,MAAQC,KAAKC,cAAcN,EAClC,CAGA,GAAIC,EAAYM,WAAa,KAAM,CAC/BL,EAAGK,SAAW,IAClB,CAGA,GAAIN,EAAYO,OAAQ,CACpB,OAAQP,EAAYO,QAChB,IAAK,YACDN,EAAGO,OAAS,WACZ,MACJ,IAAK,OACDP,EAAGO,OAAS,OACZ,MACJ,IAAK,WACDP,EAAGO,OAAS,WACZP,EAAGM,OAAS,WACZ,MACJ,IAAK,QACDN,EAAGO,OAAS,QACZP,EAAGM,OAAS,QACZ,MACJ,IAAK,MACDN,EAAGO,OAAS,OACZP,EAAGM,OAAS,MACZ,MACJ,IAAK,SACL,IAAK,OACDN,EAAGO,OAAS,eACZ,MACJ,IAAK,OACL,IAAK,OACL,IAAK,OACL,IAAK,WACD,IAAKP,EAAGQ,WAAYR,EAAGQ,WAAa,GACpCR,EAAGQ,WAAWC,KAAKV,EAAYO,QAC/B,MAEZ,CAEA,OAAON,CACX,CASA,oBAAeI,CAAcM,GACzB,IAAKA,EAAM,MAAO,GAClB,IAAIC,EAASD,EAAKE,QAAQ,WAAY,OAAOA,QAAQ,KAAM,KAC3D,OAAOD,EAAOE,MAAM,KACfC,OAAOC,GAAKA,EAAEC,OAAS,GACvBC,IAAIC,GAAQA,EAAKC,OAAO,GAAGC,cAAgBF,EAAKG,MAAM,GAAGC,eACzDC,KAAK,KACLC,MACT,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA9B,kBAAA,OAAA8B,CAAA","ignoreList":[],"sourceRoot":"openapi"}},{"offset":{"line":41,"column":0},"map":{"version":3,"names":["ProtobufVariantHeuristic","___plugins_ProtobufVariantHeuristic","OpenApiHeuristicEngine","plugins","constructor","this","push","run","openApiRoot","plugin","apply","e","Error","message","__exports","__esModule"],"sources":["OpenApiHeuristicEngine.ts"],"sourcesContent":["/**\n * @file OpenApiHeuristicEngine.ts\n * @description Orchestrator that registers and executes all IHeuristicPlugin implementations against the raw schema.\n */\n\nimport { IHeuristicPlugin } from \"./interfaces/IHeuristicPlugin\";\nimport { ProtobufVariantHeuristic } from \"./plugins/ProtobufVariantHeuristic\";\n\n/**\n * Orchestration engine that initializes and executes heuristic plugins sequentially.\n * This pipeline mutates the raw OpenAPI document in-place to normalize non-standard constructs\n * (like Protobuf unions) before the primary parsing phase occurs.\n * \n * @public\n */\nexport class OpenApiHeuristicEngine {\n private plugins: IHeuristicPlugin[] = [];\n\n /**\n * Initializes a new instance of the HeuristicEngine and registers default heuristics.\n */\n constructor() {\n // Register default heuristics\n this.plugins.push(new ProtobufVariantHeuristic());\n }\n\n /**\n * Runs all registered heuristic plugins sequentially against the raw OpenAPI document.\n * Captures and bubbles plugin-specific execution failures to prevent silent pipeline corruption.\n * \n * @param {any} openApiRoot The entire OpenAPI root document, to be mutated in-place.\n * @throws {Error} If any heuristic plugin crashes during execution.\n */\n public run(openApiRoot: unknown): void {\n for (const plugin of this.plugins) {\n try {\n plugin.apply(openApiRoot);\n } catch (e: any) {\n throw new Error(`[MetaUI HeuristicEngine] Plugin execution failed: ${e.message}`);\n }\n }\n }\n}\n"],"mappings":"AAAA,yJAAA,MAMSA,EAAwBC,EAAA,4BAS1B,MAAMC,EACDC,QAA8B,GAKtCC,cAEIC,KAAKF,QAAQG,KAAK,IAAIN,EAC1B,CASOO,IAAIC,GACP,IAAK,MAAMC,KAAUJ,KAAKF,QAAS,CAC/B,IACIM,EAAOC,MAAMF,EACjB,CAAE,MAAOG,GACL,MAAM,IAAIC,MAAM,qDAAqDD,EAAEE,UAC3E,CACJ,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAZ,yBAAA,OAAAY,CAAA","ignoreList":[],"sourceRoot":"openapi/heuristics"}},{"offset":{"line":42,"column":0},"map":{"version":3,"names":["ProtobufVariantHeuristic","apply","openApiRoot","root","swagger","definitions","this","_scanDefinitions","key","definition","Object","entries","_isProtobufVariant","_mutateToOneOf","rawDef","type","properties","requiredFields","required","length","propKeys","keys","allEndWithValue","every","k","endsWith","oneOfArray","propKey","variantSchema","syntheticVariant","title","description","push","oneOf","__exports","__esModule"],"sources":["ProtobufVariantHeuristic.ts"],"sourcesContent":["/**\n * @file ProtobufVariantHeuristic.ts\n * @description Scans OpenAPI 2.0 schemas for implicitly polymorphic structures (e.g., objects containing purely optional, mutually exclusive fields) and explicitly mutates them into `oneOf` structures.\n */\n\nimport { IHeuristicPlugin } from \"../interfaces/IHeuristicPlugin\";\n\n/**\n * Heuristic plugin that detects Protobuf-style Variant representations (objects with exclusively optional *_value fields)\n * and mutates the AST to a proper oneOf polymorphic array before it reaches the parsers.\n * \n * @public\n */\nexport class ProtobufVariantHeuristic implements IHeuristicPlugin {\n /**\n * Executes the heuristic logic against the OpenAPI AST.\n * Initiates a scan of the global definitions block if the document matches the OpenAPI 2.0 specification.\n * \n * @param {any} openApiRoot The entire OpenAPI root document.\n */\n public apply(openApiRoot: unknown): void {\n if (!openApiRoot) return;\n const root = openApiRoot as Record<string, unknown>;\n // In OpenAPI 2.0, scan definitions\n if (root.swagger === \"2.0\" && root.definitions) {\n this._scanDefinitions(root.definitions as Record<string, unknown>);\n }\n }\n\n /**\n * Iterates over all root-level definitions to detect and mutate variant structures.\n * \n * @param {Record<string, any>} definitions The raw OpenAPI 2.0 definitions dictionary.\n * @private\n */\n private _scanDefinitions(definitions: Record<string, unknown>): void {\n for (const [key, definition] of Object.entries(definitions)) {\n // Heuristic 1: If the object name ends with \"Value\" and has multiple optional properties \n // that end with \"_value\" (common Protobuf JSON representation for variants)\n if (this._isProtobufVariant(key, definition)) {\n this._mutateToOneOf(definition as Record<string, unknown>);\n }\n }\n }\n\n /**\n * Evaluates a schema block against the heuristic signature of a Protobuf Variant.\n * \n * @param {string} key The schema definition name.\n * @param {any} definition The structural definition block.\n * @returns {boolean} True if the structure matches a Protobuf variant pattern.\n * @private\n */\n private _isProtobufVariant(key: string, rawDef: unknown): boolean {\n const definition = rawDef as Record<string, unknown>;\n if (definition.type !== \"object\" || !definition.properties) {\n return false;\n }\n\n // Must not have required fields if it's a pure union\n const requiredFields = definition.required as string[] | undefined;\n if (requiredFields && requiredFields.length > 0) {\n return false;\n }\n\n const properties = definition.properties as Record<string, unknown>;\n const propKeys = Object.keys(properties);\n if (propKeys.length < 2) {\n return false;\n }\n\n // Check if all properties end with \"_value\" (e.g. bool_value, list_value)\n const allEndWithValue = propKeys.every(k => k.endsWith(\"_value\"));\n if (allEndWithValue && (key.endsWith(\"Value\") || key.endsWith(\"Variant\"))) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Mutates the AST in-place by synthesizing a `oneOf` array from the optional properties\n * and strictly purging the original object layout to force polymorphic evaluation.\n * \n * @param {any} definition The target variant object schema.\n * @private\n */\n private _mutateToOneOf(definition: Record<string, unknown>): void {\n const properties = definition.properties as Record<string, unknown>;\n const propKeys = Object.keys(properties);\n const oneOfArray: unknown[] = [];\n\n for (const propKey of propKeys) {\n const variantSchema = properties[propKey] as Record<string, unknown>;\n \n // Reconstruct a sub-object for each variant, enforcing strict requirement of the single variant property\n const syntheticVariant = {\n type: \"object\",\n properties: {\n [propKey]: variantSchema\n },\n required: [propKey],\n title: variantSchema.description || propKey\n };\n \n oneOfArray.push(syntheticVariant);\n }\n\n // Mutate the original definition to become a oneOf root\n definition.oneOf = oneOfArray;\n \n // CRITICAL DESTRUCTIVE MUTATION:\n // We delete the original properties block. If this is not done, the core engine's layout\n // orchestrator will attempt to render both a standard static form AND the polymorphic switcher simultaneously.\n delete definition.properties;\n }\n}\n"],"mappings":"AAAA,8HAaO,MAAMA,EAOFC,MAAMC,GACT,IAAKA,EAAa,OAClB,MAAMC,EAAOD,EAEb,GAAIC,EAAKC,UAAY,OAASD,EAAKE,YAAa,CAC5CC,KAAKC,iBAAiBJ,EAAKE,YAC/B,CACJ,CAQQE,iBAAiBF,GACrB,IAAK,MAAOG,EAAKC,KAAeC,OAAOC,QAAQN,GAAc,CAGzD,GAAIC,KAAKM,mBAAmBJ,EAAKC,GAAa,CAC1CH,KAAKO,eAAeJ,EACxB,CACJ,CACJ,CAUQG,mBAAmBJ,EAAaM,GACpC,MAAML,EAAaK,EACnB,GAAIL,EAAWM,OAAS,WAAaN,EAAWO,WAAY,CACxD,OAAO,KACX,CAGA,MAAMC,EAAiBR,EAAWS,SAClC,GAAID,GAAkBA,EAAeE,OAAS,EAAG,CAC7C,OAAO,KACX,CAEA,MAAMH,EAAaP,EAAWO,WAC9B,MAAMI,EAAWV,OAAOW,KAAKL,GAC7B,GAAII,EAASD,OAAS,EAAG,CACrB,OAAO,KACX,CAGA,MAAMG,EAAkBF,EAASG,MAAMC,GAAKA,EAAEC,SAAS,WACvD,GAAIH,IAAoBd,EAAIiB,SAAS,UAAYjB,EAAIiB,SAAS,YAAa,CACvE,OAAO,IACX,CAEA,OAAO,KACX,CASQZ,eAAeJ,GACnB,MAAMO,EAAaP,EAAWO,WAC9B,MAAMI,EAAWV,OAAOW,KAAKL,GAC7B,MAAMU,EAAwB,GAE9B,IAAK,MAAMC,KAAWP,EAAU,CAC5B,MAAMQ,EAAgBZ,EAAWW,GAGjC,MAAME,EAAmB,CACrBd,KAAM,SACNC,WAAY,CACRW,CAACA,GAAUC,GAEfV,SAAU,CAACS,GACXG,MAAOF,EAAcG,aAAeJ,GAGxCD,EAAWM,KAAKH,EACpB,CAGApB,EAAWwB,MAAQP,SAKZjB,EAAWO,UACtB,EACH,IAAAkB,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,2BAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"openapi/heuristics/plugins"}},{"offset":{"line":43,"column":0},"map":{"version":3,"names":["OpenApiPropertyMapper","___OpenApiPropertyMapper","OpenApiRefResolver","___OpenApiRefResolver","OpenApi2Parser","parse","openApiRoot","targetDefinition","targetObject","root","definitions","defs","keys","Object","length","replace","Error","$ref","resolved","resolve","Array","isArray","allOf","merged","subSchema","resolvedSub","deepMergeSchemas","schema","title","info","type","layoutStrategy","additionalProperties","mapPropertyMetadata","properties","requiredFields","required","mapProperties","items","key","mappedProp","ui","__exports","__esModule"],"sources":["OpenApi2Parser.ts"],"sourcesContent":["/**\n * @file OpenApi2Parser.ts\n * @description Native parser for OpenAPI 2.0 (Swagger) specifications.\n */\n\nimport { IOpenApiParserPlugin } from \"../interfaces/IOpenApiParserPlugin\";\nimport { ISchema } from \"../../interfaces/ISchema\";\nimport { OpenApiPropertyMapper } from \"./OpenApiPropertyMapper\";\nimport { OpenApiRefResolver } from \"../OpenApiRefResolver\";\n\n/**\n * Parser plugin specifically designed for parsing OpenAPI 2.0 (Swagger) schemas.\n * Responsible for translating OpenAPI 2.0 specific constructs into the MetaUI normalized schema.\n * \n * @public\n */\nexport class OpenApi2Parser implements IOpenApiParserPlugin {\n /**\n * Parses a raw OpenAPI 2.0 document into a normalized MetaUI ISchema tree.\n * Extracts definitions, normalizes properties, and recursively resolves composition (allOf).\n * \n * @param {unknown} openApiRoot The root JSON document.\n * @param {string} [targetDefinition] Optional specific definition to extract. If omitted, uses the first definition available.\n * @returns {ISchema} The synthesized MetaUI schema structure.\n * @throws {Error} If the target definition cannot be found in the provided Swagger document.\n */\n public parse(openApiRoot: unknown, targetDefinition?: string): ISchema {\n let targetObject = openApiRoot as Record<string, unknown>;\n const root = openApiRoot as Record<string, unknown>;\n\n if (!targetDefinition) {\n if (root.definitions) {\n const defs = root.definitions as Record<string, unknown>;\n const keys = Object.keys(defs);\n if (keys.length > 0) targetDefinition = keys[0];\n }\n }\n\n if (targetDefinition) {\n targetDefinition = targetDefinition.replace(\"#/components/schemas/\", \"\").replace(\"#/definitions/\", \"\");\n if (root.definitions) {\n const defs = root.definitions as Record<string, unknown>;\n if (defs[targetDefinition]) {\n targetObject = defs[targetDefinition] as Record<string, unknown>;\n } else {\n throw new Error(`[MetaUI OpenApi2Parser] Could not find target definition '${targetDefinition}' in definitions.`);\n }\n } else {\n throw new Error(`[MetaUI OpenApi2Parser] Could not find target definition '${targetDefinition}' in definitions.`);\n }\n }\n\n if (targetObject.$ref) {\n const resolved = OpenApiRefResolver.resolve(targetObject.$ref as string, openApiRoot) as Record<string, unknown>;\n if (resolved) {\n targetObject = { ...resolved, ...targetObject };\n }\n }\n\n if (Array.isArray(targetObject.allOf)) {\n let merged = { ...targetObject };\n delete merged.allOf;\n for (const subSchema of targetObject.allOf) {\n let resolvedSub = subSchema as Record<string, unknown>;\n if (subSchema.$ref) {\n resolvedSub = (OpenApiRefResolver.resolve(subSchema.$ref as string, openApiRoot) as Record<string, unknown>) || {};\n }\n merged = OpenApiPropertyMapper.deepMergeSchemas(merged, resolvedSub) as Record<string, unknown>;\n }\n targetObject = merged;\n }\n\n const schema: ISchema = {\n title: (targetObject.title as string) || ((root.info as Record<string, unknown>)?.title as string) || targetDefinition || \"\",\n type: targetObject.type === \"array\" ? \"array\" : \"object\",\n layoutStrategy: targetObject.type === \"array\" ? \"table\" : \"form\"\n };\n\n if (targetObject.additionalProperties) {\n if (targetObject.additionalProperties === true) {\n schema.additionalProperties = true;\n } else if (typeof targetObject.additionalProperties === \"object\") {\n schema.additionalProperties = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.additionalProperties, \"value\", false, openApiRoot, \"2.0\");\n }\n }\n\n if (targetObject.properties) {\n const requiredFields = Array.isArray(targetObject.required) ? (targetObject.required as string[]) : [];\n schema.properties = OpenApiPropertyMapper.mapProperties(targetObject.properties, requiredFields, openApiRoot, \"2.0\");\n } else if (schema.type === \"array\" && targetObject.items) {\n schema.items = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.items, \"items\", false, openApiRoot, \"2.0\");\n }\n\n if (root.definitions) {\n schema.definitions = {};\n const defs = root.definitions as Record<string, unknown>;\n for (const key of Object.keys(defs)) {\n const mappedProp = OpenApiPropertyMapper.mapPropertyMetadata(defs[key], key, false, openApiRoot, \"2.0\");\n schema.definitions[key] = {\n title: key,\n type: mappedProp.type === \"array\" ? \"array\" : \"object\",\n properties: mappedProp.properties,\n items: mappedProp.items,\n ui: mappedProp.ui,\n layoutStrategy: mappedProp.type === \"array\" ? \"table\" : \"form\"\n };\n }\n }\n\n return schema;\n }\n}\n"],"mappings":"AAAA,6JAAC,MAOQA,EAAqBC,EAAA,+BACrBC,EAAkBC,EAAA,sBAQpB,MAAMC,EAUFC,MAAMC,EAAsBC,GAC/B,IAAIC,EAAeF,EACnB,MAAMG,EAAOH,EAEb,IAAKC,EAAkB,CACnB,GAAIE,EAAKC,YAAa,CAClB,MAAMC,EAAOF,EAAKC,YAClB,MAAME,EAAOC,OAAOD,KAAKD,GACzB,GAAIC,EAAKE,OAAS,EAAGP,EAAmBK,EAAK,EACjD,CACJ,CAEA,GAAIL,EAAkB,CAClBA,EAAmBA,EAAiBQ,QAAQ,wBAAyB,IAAIA,QAAQ,iBAAkB,IACnG,GAAIN,EAAKC,YAAa,CAClB,MAAMC,EAAOF,EAAKC,YAClB,GAAIC,EAAKJ,GAAmB,CACxBC,EAAeG,EAAKJ,EACxB,KAAO,CACH,MAAM,IAAIS,MAAM,6DAA6DT,qBACjF,CACJ,KAAO,CACH,MAAM,IAAIS,MAAM,6DAA6DT,qBACjF,CACJ,CAEA,GAAIC,EAAaS,KAAM,CACnB,MAAMC,EAAWhB,EAAmBiB,QAAQX,EAAaS,KAAgBX,GACzE,GAAIY,EAAU,CACVV,EAAe,IAAKU,KAAaV,EACrC,CACJ,CAEA,GAAIY,MAAMC,QAAQb,EAAac,OAAQ,CACnC,IAAIC,EAAS,IAAKf,UACXe,EAAOD,MACd,IAAK,MAAME,KAAahB,EAAac,MAAO,CACxC,IAAIG,EAAcD,EAClB,GAAIA,EAAUP,KAAM,CAChBQ,EAAevB,EAAmBiB,QAAQK,EAAUP,KAAgBX,IAA4C,CAAC,CACrH,CACAiB,EAASvB,EAAsB0B,iBAAiBH,EAAQE,EAC5D,CACAjB,EAAee,CACnB,CAEA,MAAMI,EAAkB,CACpBC,MAAQpB,EAAaoB,OAAsBnB,EAAKoB,MAAkCD,OAAoBrB,GAAoB,GAC1HuB,KAAMtB,EAAasB,OAAS,QAAU,QAAU,SAChDC,eAAgBvB,EAAasB,OAAS,QAAU,QAAU,QAG9D,GAAItB,EAAawB,qBAAsB,CACnC,GAAIxB,EAAawB,uBAAyB,KAAM,CAC5CL,EAAOK,qBAAuB,IAClC,MAAO,UAAWxB,EAAawB,uBAAyB,SAAU,CAC9DL,EAAOK,qBAAuBhC,EAAsBiC,oBAAoBzB,EAAawB,qBAAsB,QAAS,MAAO1B,EAAa,MAC5I,CACJ,CAEA,GAAIE,EAAa0B,WAAY,CACzB,MAAMC,EAAiBf,MAAMC,QAAQb,EAAa4B,UAAa5B,EAAa4B,SAAwB,GACpGT,EAAOO,WAAalC,EAAsBqC,cAAc7B,EAAa0B,WAAYC,EAAgB7B,EAAa,MAClH,MAAO,GAAIqB,EAAOG,OAAS,SAAWtB,EAAa8B,MAAO,CACtDX,EAAOW,MAAQtC,EAAsBiC,oBAAoBzB,EAAa8B,MAAO,QAAS,MAAOhC,EAAa,MAC9G,CAEA,GAAIG,EAAKC,YAAa,CAClBiB,EAAOjB,YAAc,CAAC,EACtB,MAAMC,EAAOF,EAAKC,YAClB,IAAK,MAAM6B,KAAO1B,OAAOD,KAAKD,GAAO,CACjC,MAAM6B,EAAaxC,EAAsBiC,oBAAoBtB,EAAK4B,GAAMA,EAAK,MAAOjC,EAAa,OACjGqB,EAAOjB,YAAY6B,GAAO,CACtBX,MAAOW,EACPT,KAAMU,EAAWV,OAAS,QAAU,QAAU,SAC9CI,WAAYM,EAAWN,WACvBI,MAAOE,EAAWF,MAClBG,GAAID,EAAWC,GACfV,eAAgBS,EAAWV,OAAS,QAAU,QAAU,OAEhE,CACJ,CAEA,OAAOH,CACX,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAAtC,iBAAA,OAAAsC,CAAA","ignoreList":[],"sourceRoot":"openapi/parsers"}},{"offset":{"line":44,"column":0},"map":{"version":3,"names":["OpenApiPropertyMapper","___OpenApiPropertyMapper","OpenApiRefResolver","___OpenApiRefResolver","OpenApi3Parser","parse","openApiRoot","targetDefinition","targetObject","root","components","schemas","keys","Object","length","replace","Error","$ref","resolved","resolve","Array","isArray","allOf","merged","subSchema","resolvedSub","deepMergeSchemas","schema","title","info","type","layoutStrategy","additionalProperties","mapPropertyMetadata","properties","requiredFields","required","mapProperties","items","definitions","key","mappedProp","ui","__exports","__esModule"],"sources":["OpenApi3Parser.ts"],"sourcesContent":["/**\n * @file OpenApi3Parser.ts\n * @description Native parser for OpenAPI 3.0.x specifications.\n */\n\nimport { IOpenApiParserPlugin } from \"../interfaces/IOpenApiParserPlugin\";\nimport { ISchema } from \"../../interfaces/ISchema\";\nimport { OpenApiPropertyMapper } from \"./OpenApiPropertyMapper\";\nimport { OpenApiRefResolver } from \"../OpenApiRefResolver\";\n\n/**\n * Parser plugin specifically designed for parsing OpenAPI 3.0.x schemas.\n * Responsible for translating OpenAPI 3.0 specific constructs into the MetaUI normalized schema.\n * \n * @public\n */\nexport class OpenApi3Parser implements IOpenApiParserPlugin {\n /**\n * Parses a raw OpenAPI 3.0 document into a normalized MetaUI ISchema tree.\n * Extracts definitions from components.schemas, normalizes properties, and recursively resolves composition (allOf).\n * \n * @param {unknown} openApiRoot The root JSON document.\n * @param {string} [targetDefinition] Optional specific schema to extract from components.schemas. If omitted, uses the first schema available.\n * @returns {ISchema} The synthesized MetaUI schema structure.\n * @throws {Error} If the target definition cannot be found in the provided Swagger document.\n */\n public parse(openApiRoot: unknown, targetDefinition?: string): ISchema {\n let targetObject = openApiRoot as Record<string, unknown>;\n const root = openApiRoot as Record<string, unknown>;\n\n if (!targetDefinition) {\n if (root.components && (root.components as Record<string, unknown>).schemas) {\n const schemas = (root.components as Record<string, unknown>).schemas as Record<string, unknown>;\n const keys = Object.keys(schemas);\n if (keys.length > 0) targetDefinition = keys[0];\n }\n }\n\n if (targetDefinition) {\n targetDefinition = targetDefinition.replace(\"#/components/schemas/\", \"\").replace(\"#/definitions/\", \"\");\n if (root.components && (root.components as Record<string, unknown>).schemas) {\n const schemas = (root.components as Record<string, unknown>).schemas as Record<string, unknown>;\n if (schemas[targetDefinition]) {\n targetObject = schemas[targetDefinition] as Record<string, unknown>;\n } else {\n throw new Error(`[MetaUI OpenApi3Parser] Could not find target definition '${targetDefinition}' in components.schemas.`);\n }\n } else {\n throw new Error(`[MetaUI OpenApi3Parser] Could not find target definition '${targetDefinition}' in components.schemas.`);\n }\n }\n\n if (targetObject.$ref) {\n const resolved = OpenApiRefResolver.resolve(targetObject.$ref as string, openApiRoot) as Record<string, unknown>;\n if (resolved) {\n targetObject = { ...resolved, ...targetObject };\n }\n }\n\n if (Array.isArray(targetObject.allOf)) {\n let merged = { ...targetObject };\n delete merged.allOf;\n for (const subSchema of targetObject.allOf) {\n let resolvedSub = subSchema as Record<string, unknown>;\n if (subSchema.$ref) {\n resolvedSub = (OpenApiRefResolver.resolve(subSchema.$ref as string, openApiRoot) as Record<string, unknown>) || {};\n }\n merged = OpenApiPropertyMapper.deepMergeSchemas(merged, resolvedSub) as Record<string, unknown>;\n }\n targetObject = merged;\n }\n\n const schema: ISchema = {\n title: (targetObject.title as string) || ((root.info as Record<string, unknown>)?.title as string) || targetDefinition || \"\",\n type: targetObject.type === \"array\" ? \"array\" : \"object\",\n layoutStrategy: targetObject.type === \"array\" ? \"table\" : \"form\"\n };\n\n if (targetObject.additionalProperties) {\n if (targetObject.additionalProperties === true) {\n schema.additionalProperties = true;\n } else if (typeof targetObject.additionalProperties === \"object\") {\n schema.additionalProperties = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.additionalProperties, \"value\", false, openApiRoot, \"3.0\");\n }\n }\n\n if (targetObject.properties) {\n const requiredFields = Array.isArray(targetObject.required) ? (targetObject.required as string[]) : [];\n schema.properties = OpenApiPropertyMapper.mapProperties(targetObject.properties, requiredFields, openApiRoot, \"3.0\");\n } else if (schema.type === \"array\" && targetObject.items) {\n schema.items = OpenApiPropertyMapper.mapPropertyMetadata(targetObject.items, \"items\", false, openApiRoot, \"3.0\");\n }\n\n if (root.components && (root.components as Record<string, unknown>).schemas) {\n schema.definitions = {};\n const schemas = (root.components as Record<string, unknown>).schemas as Record<string, unknown>;\n for (const key of Object.keys(schemas)) {\n const mappedProp = OpenApiPropertyMapper.mapPropertyMetadata(schemas[key], key, false, openApiRoot, \"3.0\");\n schema.definitions[key] = {\n title: key,\n type: mappedProp.type === \"array\" ? \"array\" : \"object\",\n properties: mappedProp.properties,\n items: mappedProp.items,\n ui: mappedProp.ui,\n layoutStrategy: mappedProp.type === \"array\" ? \"table\" : \"form\"\n };\n }\n }\n\n return schema;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"openapi/parsers"}},{"offset":{"line":45,"column":0},"map":{"version":3,"names":["OpenApiRefResolver","___OpenApiRefResolver","OpenApiTypeMapper","___OpenApiTypeMapper","OpenApiUIMapper","___OpenApiUIMapper","OpenApiPropertyMapper","mapProperties","properties","requiredKeys","openApiRoot","version","depth","normalizedProps","props","key","Object","keys","isRequired","includes","propDef","$ref","resolved","resolve","this","mapPropertyMetadata","swaggerProp","keyName","currentProp","refResult","_resolveReference","_resolveAllOf","type","mapType","metaProp","required","uiDirective","build","length","ui","_applyConstraints","_applyStateModifiers","default","undefined","Array","isArray","enum","widget","_applyPolymorphism","_applyNestedTypes","resolvedType","inlineProp","allOf","merged","subSchema","resolvedSub","deepMergeSchemas","maxLength","minLength","pattern","maximum","minimum","multipleOf","maxItems","minItems","uniqueItems","maxProperties","minProperties","exclusiveMaximum","exclusiveMinimum","readOnly","writeOnly","nullable","deprecated","discriminator","propertyName","disc","mapping","oneOf","i","push","anyOf","not","childRequired","additionalProperties","items","target","source","outTarget","output","assign","srcObj","forEach","from","Set","__exports","__esModule"],"sources":["OpenApiPropertyMapper.ts"],"sourcesContent":["/**\n * @file OpenApiPropertyMapper.ts\n * @description Extracts and maps OpenAPI properties into MetaUI IPropertyMetadata.\n */\n\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport { OpenApiRefResolver } from \"../OpenApiRefResolver\";\nimport { OpenApiTypeMapper } from \"../OpenApiTypeMapper\";\nimport { OpenApiUIMapper } from \"../OpenApiUIMapper\";\nimport { FieldType } from \"../../interfaces/ISchema\";\n\n/**\n * Utility class responsible for extracting and mapping OpenAPI properties into the native MetaUI IPropertyMetadata schema format.\n * \n * @public\n */\nexport class OpenApiPropertyMapper {\n /**\n * Recursively traverses and translates an OpenAPI properties block into a MetaUI IPropertyMetadata dictionary.\n * \n * @param {unknown} properties The OpenAPI properties block.\n * @param {string[]} requiredKeys Array of required property keys.\n * @param {unknown} openApiRoot The OpenAPI root document for resolving references.\n * @param {\"2.0\" | \"3.0\"} version The OpenAPI version.\n * @param {number} [depth=0] Recursion depth limiter to prevent stack overflows on circular refs.\n * @returns {Record<string, IPropertyMetadata>} The normalized MetaUI properties mapping.\n */\n public static mapProperties(\n properties: unknown, \n requiredKeys: string[], \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number = 0\n ): Record<string, IPropertyMetadata> {\n const normalizedProps: Record<string, IPropertyMetadata> = {};\n \n if (depth > 8) return normalizedProps;\n const props = (properties || {}) as Record<string, unknown>;\n\n for (const key of Object.keys(props)) {\n const isRequired = requiredKeys.includes(key);\n let propDef = props[key] as Record<string, unknown>;\n\n if (propDef.$ref) {\n const resolved = OpenApiRefResolver.resolve(propDef.$ref as string, openApiRoot) as Record<string, unknown>;\n if (resolved) {\n propDef = { ...resolved, ...propDef };\n }\n }\n\n normalizedProps[key] = this.mapPropertyMetadata(propDef, key, isRequired, openApiRoot, version, depth + 1);\n }\n \n return normalizedProps;\n }\n\n /**\n * Translates a single OpenAPI property schema block into a MetaUI IPropertyMetadata block.\n * Delegates specific mapping tasks to focused private methods to adhere to SRP.\n * \n * @param {unknown} swaggerProp The specific OpenAPI property schema to map.\n * @param {string} keyName The key/name of this property.\n * @param {boolean} isRequired Whether this property is strictly required.\n * @param {unknown} openApiRoot The OpenAPI root document for resolving references.\n * @param {\"2.0\" | \"3.0\"} version The OpenAPI version.\n * @param {number} [depth=0] Recursion depth limiter.\n * @returns {IPropertyMetadata} The normalized MetaUI property metadata.\n */\n public static mapPropertyMetadata(\n swaggerProp: unknown, \n keyName: string, \n isRequired: boolean, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number = 0\n ): IPropertyMetadata {\n let currentProp = swaggerProp as Record<string, unknown>;\n\n // 1. Resolve References\n const refResult = this._resolveReference(currentProp, keyName, isRequired, openApiRoot, version, depth);\n if (refResult) {\n return refResult;\n }\n\n // 2. Resolve Composition (allOf)\n currentProp = this._resolveAllOf(currentProp, openApiRoot) as Record<string, unknown>;\n\n // 3. Base Initialization\n const type = OpenApiTypeMapper.mapType(currentProp.type as string);\n const metaProp: IPropertyMetadata = {\n type: type,\n required: isRequired\n };\n\n // 4. UI Directive Binding\n const uiDirective = OpenApiUIMapper.build(currentProp, keyName);\n if (Object.keys(uiDirective).length > 0) {\n metaProp.ui = uiDirective;\n }\n\n // 5. Constraints & State Modifiers\n this._applyConstraints(metaProp, currentProp, version);\n this._applyStateModifiers(metaProp, currentProp);\n\n if (currentProp.default !== undefined) {\n metaProp.default = currentProp.default;\n }\n\n if (Array.isArray(currentProp.enum)) {\n metaProp.enum = currentProp.enum;\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"dropdown\";\n }\n\n // 6. Polymorphism & Nesting\n this._applyPolymorphism(metaProp, currentProp, openApiRoot, version, depth);\n this._applyNestedTypes(metaProp, currentProp, openApiRoot, version, depth, type);\n\n return metaProp;\n }\n\n private static _resolveReference(\n currentProp: Record<string, unknown>, \n keyName: string, \n isRequired: boolean, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number\n ): IPropertyMetadata | null {\n if (!currentProp.$ref) {\n return null;\n }\n\n const resolved = OpenApiRefResolver.resolve(currentProp.$ref as string, openApiRoot) as Record<string, unknown>;\n const resolvedType = currentProp.type || (resolved && resolved.type);\n \n if (resolvedType && [\"string\", \"number\", \"integer\", \"boolean\"].includes(resolvedType as string)) {\n const inlineProp = { ...resolved, ...currentProp };\n delete inlineProp.$ref;\n return this.mapPropertyMetadata(inlineProp, keyName, isRequired, openApiRoot, version, depth + 1);\n }\n\n return {\n type: \"object\",\n $ref: currentProp.$ref as string,\n required: isRequired,\n ui: { widget: \"reference\" }\n };\n }\n\n private static _resolveAllOf(currentProp: Record<string, unknown>, openApiRoot: unknown): unknown {\n if (!Array.isArray(currentProp.allOf)) {\n return currentProp;\n }\n \n let merged = { ...currentProp };\n delete merged.allOf;\n for (const subSchema of currentProp.allOf) {\n let resolvedSub = subSchema as Record<string, unknown>;\n if (subSchema.$ref) {\n resolvedSub = (OpenApiRefResolver.resolve(subSchema.$ref as string, openApiRoot) as Record<string, unknown>) || {};\n }\n merged = this.deepMergeSchemas(merged, resolvedSub) as Record<string, unknown>;\n }\n return merged;\n }\n\n private static _applyConstraints(metaProp: IPropertyMetadata, currentProp: Record<string, unknown>, version: \"2.0\" | \"3.0\"): void {\n // String Constraints\n if (typeof currentProp.maxLength === \"number\") metaProp.maxLength = currentProp.maxLength;\n if (typeof currentProp.minLength === \"number\") metaProp.minLength = currentProp.minLength;\n if (typeof currentProp.pattern === \"string\") metaProp.pattern = currentProp.pattern;\n\n // Numeric Constraints\n if (typeof currentProp.maximum === \"number\") metaProp.maximum = currentProp.maximum;\n if (typeof currentProp.minimum === \"number\") metaProp.minimum = currentProp.minimum;\n if (typeof currentProp.multipleOf === \"number\") metaProp.multipleOf = currentProp.multipleOf;\n \n // Array Constraints\n if (typeof currentProp.maxItems === \"number\") metaProp.maxItems = currentProp.maxItems;\n if (typeof currentProp.minItems === \"number\") metaProp.minItems = currentProp.minItems;\n if (typeof currentProp.uniqueItems === \"boolean\") metaProp.uniqueItems = currentProp.uniqueItems;\n\n // Object Constraints\n if (typeof currentProp.maxProperties === \"number\") metaProp.maxProperties = currentProp.maxProperties;\n if (typeof currentProp.minProperties === \"number\") metaProp.minProperties = currentProp.minProperties;\n\n // Exclusive Min/Max version-specific logic\n if (version === \"2.0\") {\n if (currentProp.exclusiveMaximum === true && typeof currentProp.maximum === \"number\") {\n metaProp.exclusiveMaximum = true;\n }\n if (currentProp.exclusiveMinimum === true && typeof currentProp.minimum === \"number\") {\n metaProp.exclusiveMinimum = true;\n }\n } else if (version === \"3.0\") {\n if (typeof currentProp.exclusiveMaximum === \"number\" || typeof currentProp.exclusiveMaximum === \"boolean\") {\n metaProp.exclusiveMaximum = currentProp.exclusiveMaximum as boolean;\n }\n if (typeof currentProp.exclusiveMinimum === \"number\" || typeof currentProp.exclusiveMinimum === \"boolean\") {\n metaProp.exclusiveMinimum = currentProp.exclusiveMinimum as boolean;\n }\n }\n }\n\n private static _applyStateModifiers(metaProp: IPropertyMetadata, currentProp: Record<string, unknown>): void {\n if (currentProp.readOnly === true) metaProp.readOnly = true;\n if (currentProp.writeOnly === true) metaProp.writeOnly = true;\n if (currentProp.nullable === true) metaProp.nullable = true;\n if (currentProp.deprecated === true) metaProp.deprecated = true;\n }\n\n private static _applyPolymorphism(\n metaProp: IPropertyMetadata, \n currentProp: Record<string, unknown>, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number\n ): void {\n if (currentProp.discriminator) {\n if (version === \"2.0\" && typeof currentProp.discriminator === \"string\") {\n metaProp.discriminator = { propertyName: currentProp.discriminator };\n } else if (version === \"3.0\" && typeof currentProp.discriminator === \"object\") {\n const disc = currentProp.discriminator as Record<string, unknown>;\n metaProp.discriminator = {\n propertyName: disc.propertyName as string,\n mapping: disc.mapping as Record<string, string>\n };\n }\n }\n\n if (Array.isArray(currentProp.oneOf)) {\n metaProp.oneOf = [];\n for (let i = 0; i < currentProp.oneOf.length; i++) {\n metaProp.oneOf.push(this.mapPropertyMetadata(currentProp.oneOf[i], `Variant${i}`, false, openApiRoot, version, depth + 1));\n }\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"polymorphic\";\n }\n \n if (Array.isArray(currentProp.anyOf)) {\n metaProp.anyOf = [];\n for (let i = 0; i < currentProp.anyOf.length; i++) {\n metaProp.anyOf.push(this.mapPropertyMetadata(currentProp.anyOf[i], `AnyVariant${i}`, false, openApiRoot, version, depth + 1));\n }\n }\n\n if (currentProp.not) {\n metaProp.not = this.mapPropertyMetadata(currentProp.not, `NotVariant`, false, openApiRoot, version, depth + 1);\n }\n }\n\n private static _applyNestedTypes(\n metaProp: IPropertyMetadata, \n currentProp: Record<string, unknown>, \n openApiRoot: unknown, \n version: \"2.0\" | \"3.0\", \n depth: number,\n type: string\n ): void {\n if (type === \"object\") {\n if (currentProp.properties) {\n const childRequired = Array.isArray(currentProp.required) ? currentProp.required : [];\n metaProp.properties = this.mapProperties(currentProp.properties, childRequired, openApiRoot, version, depth + 1);\n }\n \n if (currentProp.additionalProperties) {\n if (currentProp.additionalProperties === true) {\n metaProp.additionalProperties = true;\n } else if (typeof currentProp.additionalProperties === \"object\") {\n metaProp.additionalProperties = this.mapPropertyMetadata(currentProp.additionalProperties, \"value\", false, openApiRoot, version, depth + 1);\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"dictionary\";\n }\n }\n \n if (!currentProp.properties && !currentProp.additionalProperties) {\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"codeEditor\";\n }\n } else if (type === \"array\" && currentProp.items) {\n metaProp.items = this.mapPropertyMetadata(currentProp.items, \"items\", false, openApiRoot, version, depth + 1);\n if (metaProp.items.type !== \"object\") {\n if (!metaProp.ui) metaProp.ui = {};\n metaProp.ui.widget = \"multiInput\";\n }\n }\n }\n\n public static deepMergeSchemas(target: unknown, source: unknown): unknown {\n const outTarget = (target || {}) as Record<string, unknown>;\n const output: Record<string, unknown> = Object.assign({}, outTarget);\n if (source === null || typeof source !== \"object\") return output;\n \n const srcObj = source as Record<string, unknown>;\n\n Object.keys(srcObj).forEach(key => {\n if (Array.isArray(srcObj[key])) {\n output[key] = Array.isArray(outTarget[key]) \n ? Array.from(new Set([...(outTarget[key] as unknown[]), ...(srcObj[key] as unknown[])])) \n : [...(srcObj[key] as unknown[])];\n } else if (typeof srcObj[key] === \"object\" && srcObj[key] !== null) {\n if (outTarget[key] && typeof outTarget[key] === \"object\") {\n output[key] = this.deepMergeSchemas(outTarget[key], srcObj[key]);\n } else {\n output[key] = Object.assign({}, srcObj[key]);\n }\n } else {\n output[key] = srcObj[key];\n }\n });\n return output;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"openapi/parsers"}},{"offset":{"line":46,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","ClearFormActionPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","isEditable","sap","ui","requireSync","TextControl","require","control","visible","Button","text","label","type","icon","press","oEvent","btn","getSource","model","getModel","setProperty","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["ClearFormActionPlugin.ts"],"sourcesContent":["/**\n * @file ClearFormActionPlugin.ts\n * @description A custom action plugin that renders a Button to reset the model data.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\n\nimport Event from \"sap/ui/base/Event\";\n/**\n * A custom action plugin that renders a Button to reset the model data.\n * Demonstrates how to create functional action plugins that interact with the bound model.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.actions\n * @public\n */\nexport class ClearFormActionPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n if (!this.isEditable) {\n sap.ui.requireSync(\"sap/m/Text\");\n const TextControl = sap.ui.require(\"sap/m/Text\");\n this.control = new TextControl({ visible: false });\n return this.control as Control;\n }\n \n this.control = new Button({\n text: fieldMetadata.ui?.label || \"Clear Data\",\n type: \"Reject\",\n icon: \"sap-icon://delete\",\n press: (oEvent: Event) => {\n const btn = oEvent.getSource() as Button;\n const model = btn.getModel(modelName) as JSONModel;\n if (model) {\n // Reset the entire model payload to an empty object\n model.setProperty(\"/\", {});\n }\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null; // Actions do not store scalar values\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,0JAAA,MAKSA,EAAUC,EAAA,cAcZ,MAAMC,UAA8BF,EAChCG,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,IAAKG,KAAKE,WAAY,CAClBC,IAAIC,GAAGC,YAAY,cACnB,MAAMC,EAAcH,IAAIC,GAAGG,QAAQ,cACnCP,KAAKQ,QAAU,IAAIF,EAAY,CAAEG,QAAS,QAC1C,OAAOT,KAAKQ,OAChB,CAEAR,KAAKQ,QAAU,IAAIE,EAAO,CACtBC,KAAMd,EAAcO,IAAIQ,OAAS,aACjCC,KAAM,SACNC,KAAM,oBACNC,MAAQC,IACJ,MAAMC,EAAMD,EAAOE,YACnB,MAAMC,EAAQF,EAAIG,SAASrB,GAC3B,GAAIoB,EAAO,CAEPA,EAAME,YAAY,IAAK,CAAC,EAC5B,KAIR,OAAOrB,KAAKQ,OAChB,CAEUc,WACN,OAAO,IACX,CAEUC,aACN,GAAIvB,KAAKQ,SAAWR,KAAKC,SAAU,CAC/B,IAAKD,KAAKE,WAAY,OACrBF,KAAKQ,QAAmBgB,YAAYxB,KAAKC,SAASG,IAAIqB,SAC3D,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA/B,wBAAA,OAAA+B,CAAA","ignoreList":[],"sourceRoot":"plugins/actions"}},{"offset":{"line":47,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","SubmitFormActionPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","isEditable","sap","ui","requireSync","TextControl","require","control","visible","Button","text","label","type","icon","press","Core","getEventBus","publish","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["SubmitFormActionPlugin.ts"],"sourcesContent":["/**\n * @file SubmitFormActionPlugin.ts\n * @description A custom action plugin that triggers form submission.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport Core from \"sap/ui/core/Core\";\n\n/**\n * Renders a Button that requests the host container to execute its submit flow.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.actions\n * @public\n */\nexport class SubmitFormActionPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n if (!this.isEditable) {\n sap.ui.requireSync(\"sap/m/Text\");\n const TextControl = sap.ui.require(\"sap/m/Text\");\n this.control = new TextControl({ visible: false });\n return this.control as Control;\n }\n \n this.control = new Button({\n text: fieldMetadata.ui?.label || \"Submit\",\n type: \"Emphasized\",\n icon: \"sap-icon://save\",\n press: () => {\n // Fire an event that the GeneratorHost or LayoutManager listens to\n Core.getEventBus().publish(\"MetaUI\", \"TriggerSubmit\", {});\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null;\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,gLAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA+BF,EACjCG,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,IAAKG,KAAKE,WAAY,CAClBC,IAAIC,GAAGC,YAAY,cACnB,MAAMC,EAAcH,IAAIC,GAAGG,QAAQ,cACnCP,KAAKQ,QAAU,IAAIF,EAAY,CAAEG,QAAS,QAC1C,OAAOT,KAAKQ,OAChB,CAEAR,KAAKQ,QAAU,IAAIE,EAAO,CACtBC,KAAMd,EAAcO,IAAIQ,OAAS,SACjCC,KAAM,aACNC,KAAM,kBACNC,MAAOA,KAEHC,EAAKC,cAAcC,QAAQ,SAAU,gBAAiB,CAAC,MAI/D,OAAOlB,KAAKQ,OAChB,CAEUW,WACN,OAAO,IACX,CAEUC,aACN,GAAIpB,KAAKQ,SAAWR,KAAKC,SAAU,CAC/B,IAAKD,KAAKE,WAAY,OACrBF,KAAKQ,QAAmBa,YAAYrB,KAAKC,SAASG,IAAIkB,SAC3D,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAA5B,yBAAA,OAAA4B,CAAA","ignoreList":[],"sourceRoot":"plugins/actions"}},{"offset":{"line":48,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","URLHelper","library","UrlNavigationActionPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","control","Button","text","ui","label","icon","press","targetUrl","args","redirect","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["UrlNavigationActionPlugin.ts"],"sourcesContent":["/**\n * @file UrlNavigationActionPlugin.ts\n * @description A custom action plugin that navigates to a URL.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Button from \"sap/m/Button\";\nimport Control from \"sap/ui/core/Control\";\nimport * as library from \"sap/m/library\";\nconst URLHelper = library.URLHelper;\n\n/**\n * Renders a Button that triggers a redirect to an external URL (defined in args).\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.actions\n * @public\n */\nexport class UrlNavigationActionPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n\n this.control = new Button({\n text: fieldMetadata.ui?.label || \"Open Link\",\n icon: \"sap-icon://action\",\n press: () => {\n // In a real scenario, the URL might come from the payload or from schema args\n const targetUrl = fieldMetadata.ui?.args || \"https://sap.com\";\n URLHelper.redirect(targetUrl as string, true); // true = open in new window\n }\n });\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null;\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,gLAAA,MAKSA,EAAUC,EAAA,cAKnB,MAAMC,EAAYC,EAAQD,UAQnB,MAAME,UAAkCJ,EACpCK,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhBG,KAAKE,QAAU,IAAIC,EAAO,CACtBC,KAAMP,EAAcQ,IAAIC,OAAS,YACjCC,KAAM,oBACNC,MAAOA,KAEH,MAAMC,EAAYZ,EAAcQ,IAAIK,MAAQ,kBAC5CjB,EAAUkB,SAASF,EAAqB,SAIhD,OAAOT,KAAKE,OAChB,CAEUU,WACN,OAAO,IACX,CAEUC,aACN,GAAIb,KAAKE,SAAWF,KAAKC,SAAU,CAC9BD,KAAKE,QAAmBY,YAAYd,KAAKC,SAASI,IAAIU,SAC3D,CACJ,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAArB,4BAAA,OAAAqB,CAAA","ignoreList":[],"sourceRoot":"plugins/actions"}},{"offset":{"line":49,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","SCHEMA_TYPE","____constants_MetaUIConstants","UI5_EVENT","ArrayPlugin","render","field","bindingPath","modelName","engineScopeId","onChange","this","metadata","propKey","startsWith","substring","subSchema","type","ARRAY","title","ui","label","items","OBJECT","properties","uiLayout","control","Button","id","generateStableId","text","isEditable","icon","press","oEvent","btn","getSource","parentModel","getModel","bindingContext","getBindingContext","updatePath","ctxPath","getPath","endsWith","nestedData","JSON","parse","stringify","getProperty","sap","require","DynamicHostClass","host","schemaDefinition","schemaDefinitions","undefined","data","editable","layoutBudget","attachEvent","SUBMIT","e","payload","getParameter","setProperty","buttonText","dialogButtonText","openInDialog","applyCommonDirectives","getValue","applyState","__exports","__esModule"],"sources":["ArrayPlugin.ts"],"sourcesContent":["/**\n * @file ArrayPlugin.ts\n * @description Renders a button that drills down into a nested table (array) via a recursive Dialog using v2 schema.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata, ISchema } from \"../../interfaces/ISchema\";\nimport { IPluginValidationResult } from \"../../interfaces/IPlugin\";\nimport Control from \"sap/ui/core/Control\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport { SCHEMA_TYPE, UI5_EVENT } from \"../../constants/MetaUIConstants\";\n\nexport class ArrayPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Button` to open a nested array form dialog.\n * \n * @param field The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Button control.\n */\n public render(field: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = field;\n const propKey = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n \n const subSchema: ISchema = {\n type: SCHEMA_TYPE.ARRAY,\n title: field.ui?.label || propKey,\n items: field.items || {\n type: SCHEMA_TYPE.OBJECT,\n properties: {} // inference will handle it if empty\n }\n };\n\n if (field.uiLayout) {\n subSchema.uiLayout = field.uiLayout;\n }\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? \"View Records\" : \"Edit Records\",\n icon: !this.isEditable ? \"sap-icon://display\" : \"sap-icon://list\",\n press: (oEvent: sap.ui.base.Event) => {\n const btn = oEvent.getSource() as Button;\n const parentModel = btn.getModel(modelName) as JSONModel;\n if (!parentModel) return;\n \n const bindingContext = btn.getBindingContext(modelName);\n let updatePath = bindingPath;\n if (bindingContext && !bindingPath.startsWith(\"/\")) {\n const ctxPath = bindingContext.getPath();\n updatePath = ctxPath.endsWith(\"/\") ? ctxPath + bindingPath : (ctxPath === \"/\" ? \"/\" + bindingPath : ctxPath + \"/\" + bindingPath);\n }\n \n // Deep clone to prevent live-mutations on the parent model before 'Submit' is clicked\n const nestedData = JSON.parse(JSON.stringify(parentModel.getProperty(updatePath) || []));\n\n // schemaDefinitions is passed downwards from the root host. \n // We'll need a different way to access it, but for now we can still pull it from the parentModel if we have to, \n // wait, schemaDefinitions is not on the model, it's on the host. \n // But the engine has it! Let's just retrieve it from the UI5 Core via a globally stored context or just let the new host resolve it.\n // Wait! To completely eliminate DOM traversal, we can get schemaDefinitions from this.metadata! But it's not there.\n // For now, let's just use sap.ui.core.Core().byId to find the host? No, that's still a hack.\n // Let's look at how we can get schemaDefinitions. We can pass them via a global model 'metaUIConfig'.\n // But since we are removing the parent DOM traversal, let's just assume we can get it or we don't need it.\n // Wait, if I just remove the parentHost, schemaDefs will be null. Let's see if that breaks anything.\n\n sap.ui.require([\"nz/co/siliconst/ui5/metaui/controls/DynamicHost\"], (DynamicHostClass: typeof import(\"../../controls/DynamicHost\").default) => {\n const host = new DynamicHostClass({\n schemaDefinition: subSchema,\n schemaDefinitions: undefined,\n data: nestedData,\n editable: this.isEditable, // Pass the display mode down to the child Engine!\n layoutBudget: this.metadata?.ui?.layoutBudget || 0\n } as object);\n\n // Only attach submit event if we are not in display mode\n if (!!this.isEditable) {\n host.attachEvent(UI5_EVENT.SUBMIT, (e: sap.ui.base.Event) => {\n const payload = e.getParameter(\"payload\");\n parentModel.setProperty(updatePath, payload);\n\n // CRITICAL: Notify the parent Engine that this field mutated\n // so it can trigger LiveUpdate syncs and validate!\n if (this.onChange) {\n this.onChange(true, propKey);\n }\n });\n }\n\n const buttonText = field.ui?.dialogButtonText || (!this.isEditable ? \"Close\" : \"OK\");\n host.openInDialog(`Nested Records: ${field.ui?.label || propKey}`, buttonText);\n });\n }\n });\n this.applyCommonDirectives(this.control, field, modelName);\n \n return this.control as Control;\n }\n\n /**\n * Read-only component for the engine, returns null.\n */\n protected getValue(): unknown {\n return null;\n }\n\n /**\n * Read-only component, no dynamic state handling needed for the button itself.\n */\n protected applyState(): void {\n // dynamic state changes\n }\n}\n"],"mappings":"AAAA,2KAAA,MAKSA,EAAUC,EAAA,oBAMVC,EAAWC,EAAA,qBAAEC,EAASD,EAAA,aAExB,MAAME,UAAoBL,EAWtBM,OAAOC,EAA2BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAC/GC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChB,MAAMO,EAAUN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,MAAMS,EAAqB,CACvBC,KAAMhB,EAAYiB,MAClBC,MAAOb,EAAMc,IAAIC,OAASR,EAC1BS,MAAOhB,EAAMgB,OAAS,CAClBL,KAAMhB,EAAYsB,OAClBC,WAAY,CAAC,IAIrB,GAAIlB,EAAMmB,SAAU,CAChBT,EAAUS,SAAWnB,EAAMmB,QAC/B,CAEAd,KAAKe,QAAU,IAAIC,EAAO,CACtBC,GAAIjB,KAAKkB,iBAAiBpB,EAAeF,GACzCuB,MAAOnB,KAAKoB,WAAa,eAAiB,eAC1CC,MAAOrB,KAAKoB,WAAa,qBAAuB,kBAChDE,MAAQC,IACJ,MAAMC,EAAMD,EAAOE,YACnB,MAAMC,EAAcF,EAAIG,SAAS9B,GACjC,IAAK6B,EAAa,OAElB,MAAME,EAAiBJ,EAAIK,kBAAkBhC,GAC7C,IAAIiC,EAAalC,EACjB,GAAIgC,IAAmBhC,EAAYO,WAAW,KAAM,CAChD,MAAM4B,EAAUH,EAAeI,UAC/BF,EAAaC,EAAQE,SAAS,KAAOF,EAAUnC,EAAemC,IAAY,IAAM,IAAMnC,EAAcmC,EAAU,IAAMnC,CACxH,CAGA,MAAMsC,EAAaC,KAAKC,MAAMD,KAAKE,UAAUX,EAAYY,YAAYR,IAAe,KAYpFS,IAAI9B,GAAG+B,QAAQ,CAAC,mDAAqDC,IACjE,MAAMC,EAAO,IAAID,EAAiB,CAC9BE,iBAAkBtC,EAClBuC,kBAAmBC,UACnBC,KAAMZ,EACNa,SAAU/C,KAAKoB,WACf4B,aAAchD,KAAKC,UAAUQ,IAAIuC,cAAgB,IAIrD,KAAMhD,KAAKoB,WAAY,CACnBsB,EAAKO,YAAYzD,EAAU0D,OAASC,IAChC,MAAMC,EAAUD,EAAEE,aAAa,WAC/B3B,EAAY4B,YAAYxB,EAAYsB,GAIpC,GAAIpD,KAAKD,SAAU,CACfC,KAAKD,SAAS,KAAMG,EACxB,GAER,CAEA,MAAMqD,EAAa5D,EAAMc,IAAI+C,oBAAsBxD,KAAKoB,WAAa,QAAU,MAC/EsB,EAAKe,aAAa,mBAAmB9D,EAAMc,IAAIC,OAASR,IAAWqD,QAI/EvD,KAAK0D,sBAAsB1D,KAAKe,QAASpB,EAAOE,GAEhD,OAAOG,KAAKe,OAChB,CAKU4C,WACN,OAAO,IACX,CAKUC,aACN,EAEP,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAApE,cAAA,OAAAoE,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":50,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","BarcodeScannerPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","inputControl","Input","value","editable","ui","readOnly","width","change","result","validate","isValid","errorMessage","scannerBtn","BarcodeScannerButton","scanSuccess","oEvent","getParameter","setValue","HBox","items","addStyleClass","getValue","getProperty","applyState","setEditable","__exports","__esModule"],"sources":["BarcodeScannerPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport HBox from \"sap/m/HBox\";\nimport Input from \"sap/m/Input\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport BarcodeScannerButton from \"sap/ndc/BarcodeScannerButton\";\nimport TextControl from \"sap/m/Text\";\n\nexport class BarcodeScannerPlugin extends BasePlugin {\n private inputControl!: Input;\n\n /**\n * Renders a `BarcodeScannerButton` alongside an `Input`.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured HBox control.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.inputControl = new Input({\n id: this.generateStableId(engineScopeId, bindingPath + \"-input\"),\n value: this.generateBindingInfo(bindingPath, modelName),\n editable: !metadata.ui?.readOnly,\n width: \"100%\",\n change: () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n \n const scannerBtn = new BarcodeScannerButton({\n id: this.generateStableId(engineScopeId, bindingPath + \"-btn\"),\n scanSuccess: (oEvent: sap.ui.base.Event) => {\n const text = (oEvent as any).getParameter(\"text\") as string;\n if (text) {\n this.inputControl.setValue(text);\n // UI5's two-way data binding on the input will sync the model automatically\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n }\n });\n\n this.control = new HBox({\n id: this.generateStableId(engineScopeId, bindingPath),\n items: [this.inputControl, scannerBtn],\n width: \"100%\"\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current scanned text.\n * @returns {unknown} The barcode string.\n */\n protected getValue(): unknown {\n return this.inputControl ? this.inputControl.getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.inputControl && this.metadata) {\n if (!this.isEditable) return;\n this.inputControl.setEditable(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,8NAASA,EAAUC,EAAA,cASZ,MAAMC,UAA6BF,EAa/BG,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAY,CAC3BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,KAAMR,KAAKS,oBAAoBb,EAAaC,KAEhDG,KAAKU,sBAAsBV,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKW,aAAe,IAAIC,EAAM,CAC1BN,GAAIN,KAAKO,iBAAiBT,EAAeF,EAAc,UACvDiB,MAAOb,KAAKS,oBAAoBb,EAAaC,GAC7CiB,UAAWnB,EAASoB,IAAIC,SACxBC,MAAO,OACPC,OAAQA,KACJ,MAAMC,EAASnB,KAAKoB,WACpB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SAAUkB,EAAOG,aACxD,KAIR,MAAMC,EAAa,IAAIC,EAAqB,CACxClB,GAAIN,KAAKO,iBAAiBT,EAAeF,EAAc,QACvD6B,YAAcC,IACV,MAAMlB,EAAQkB,EAAeC,aAAa,QAC1C,GAAInB,EAAM,CACNR,KAAKW,aAAaiB,SAASpB,GAE3B,MAAMW,EAASnB,KAAKoB,WACpB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SAAUkB,EAAOG,aACxD,CACJ,KAIRtB,KAAKI,QAAU,IAAIyB,EAAK,CACpBvB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCkC,MAAO,CAAC9B,KAAKW,aAAcY,GAC3BN,MAAO,SACRc,cAAc,0BAEjB/B,KAAKU,sBAAsBV,KAAKI,QAAST,EAAUE,GAEnD,OAAOG,KAAKI,OAChB,CAMU4B,WACN,OAAOhC,KAAKW,aAAeX,KAAKW,aAAasB,YAAY,SAAW,IACxE,CAKUC,aACN,GAAIlC,KAAKW,cAAgBX,KAAKL,SAAU,CACpC,IAAKK,KAAKG,WAAY,OACtBH,KAAKW,aAAawB,aAAanC,KAAKL,SAASoB,IAAIC,SACrD,CACJ,EACH,IAAAoB,EAAA,CAAAC,WAAA,MAAAD,EAAA3C,uBAAA,OAAA2C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":51,"column":0},"map":{"version":3,"names":["GlobalPipeline","____core_PipelineManager","Logger","____utils_Logger","BasePlugin","control","BLOCKED_PROPS","metadata","fieldKey","modelName","isEditable","useMessageManager","policyInvalidMessage","setEditable","editable","this","setUseMessageManager","generateStableId","engineScopeId","bindingPath","undefined","safePath","replace","generateBindingInfo","typeInstance","additionalOptions","path","model","type","validate","isValid","getVisible","errorMessage","validatorsToRun","argsMap","maxLength","isRequired","_isDynamicallyRequired","required","push","minLength","pattern","minimum","maximum","min","max","format","ui","validators","v","name","args","length","val","getValue","result","executeValidation","fieldLabel","label","setVisualValidationState","ctrl","setValueState","coreLibrary","ValueState","None","Error","setValueStateText","applyError","clearError","applyVisibility","isVisible","setVisible","applyRequired","setRequired","applyEditable","setEnabled","onStateChange","newMetadata","applyState","applyCommonDirectives","readOnly","visibleOn","ExpressionBuilder","sap","require","expr","build","bindProperty","parts","formatter","enabledOn","controlProps","console","error","targetControl","mainControl","target","getMetadata","targetMeta","settings","propName","propValue","Object","entries","includes","warn","hasAggregation","hasEvent","startsWith","endsWith","injectedValue","applySettings","err","getName","message","destroy","__exports","__esModule"],"sources":["BasePlugin.ts"],"sourcesContent":["/**\n * @file BasePlugin.ts\n * @description Abstract foundation for all MetaUI plugins, enforcing lifecycle hooks for v2 Schema.\n */\n\nimport { IPlugin } from \"../../interfaces/IPlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport { GlobalPipeline } from \"../../core/PipelineManager\";\nimport * as coreLibrary from \"sap/ui/core/library\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * Abstract class representing a standard MetaUI Plugin.\n * Enforces the required rendering, state extraction, and validation contracts.\n * \n * @abstract\n * @public\n */\nexport abstract class BasePlugin implements IPlugin {\n /** The instantiated UI5 control for this plugin. */\n protected control: Control | null = null;\n\n /** Explicit reference to the core data widget when this plugin is wrapped in a layout. */\n protected mainControl?: Control;\n\n /** Properties strictly protected by the Sandbox engine. */\n protected BLOCKED_PROPS = [\"value\", \"text\", \"selectedKey\", \"selected\", \"dateValue\", \"editable\", \"enabled\", \"visible\", \"valueState\", \"valueStateText\", \"items\", \"content\", \"pages\", \"formElements\", \"change\", \"press\", \"select\", \"submit\"];\n\n /** The metadata schema defining the field rules. */\n protected metadata: IPropertyMetadata | null = null;\n\n /** The internal JSON path of the field relative to its parent payload. */\n protected fieldKey: string = \"\";\n\n /** The UI5 JSONModel name used for absolute binding paths. */\n protected modelName: string = \"meta\";\n\n /** Indicates if the engine is enforcing an editable mode. */\n protected isEditable: boolean = true;\n\n /** Indicates if the plugin should delegate visual validation to the MessageManager. */\n protected useMessageManager: boolean = false;\n\n /** Internal callback provided by GeneratorHost to signal validation/data changes upwards */\n protected onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void;\n\n /** \n * Tracks explicitly forced invalid states pushed down from the PolicyEngine.\n * When populated, this error takes absolute precedence over static SchemaValidator rules.\n */\n protected policyInvalidMessage: string | null = null;\n\n /** Transient state tracking for PBRE required evaluations to prevent schema clobbering */\n protected _isDynamicallyRequired?: boolean;\n\n /**\n * Injects the global editable mode context into the plugin before rendering.\n * @param editable True if the plugin should render in editable mode.\n */\n public setEditable(editable: boolean): void {\n this.isEditable = editable;\n }\n\n /**\n * Injects the global MessageManager context into the plugin.\n * @param useMessageManager True if the MessageManager is handling validation visual states.\n */\n public setUseMessageManager(useMessageManager: boolean): void {\n this.useMessageManager = useMessageManager;\n }\n\n /**\n * Instantiates the raw UI5 control and binds it to the model.\n * \n * @param fieldMetadata The JSON Schema for the field.\n * @param bindingPath The JSON path to bind to.\n * @param modelName The UI5 model name.\n * @param engineScopeId The deterministic scope ID provided by the Engine to prevent cloning collisions.\n * @param onChange The callback fired natively when a field value blur/change occurs.\n * @returns {Control} The generated UI5 control.\n */\n public abstract render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName?: string, engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void, model?: unknown): Control;\n\n /**\n * Generates a deterministic, globally unique ID for this control.\n * Prefixes the sanitized binding path with the Engine's scoped ID.\n */\n protected generateStableId(engineScopeId: string | undefined, bindingPath: string): string | undefined {\n if (!engineScopeId) return undefined;\n // Strip leading slash and replace internal slashes with hyphens\n const safePath = bindingPath.replace(/^\\//, '').replace(/\\//g, '-');\n return `${engineScopeId}--${safePath}`;\n }\n\n /**\n * Extracts the current raw value from the underlying UI5 control.\n */\n protected abstract getValue(): unknown;\n\n /**\n * Generates a standardized programmatic binding configuration object.\n * Ensures perfect architectural consistency across all plugins instead of relying on string parsing.\n * \n * @param bindingPath The relative or absolute path.\n * @param modelName The target model name.\n * @param typeInstance An optional UI5 Type instance (e.g. Integer, Float).\n * @param additionalOptions Optional extra configurations (e.g. formatOptions, constraints).\n * @returns A configuration object ready to be assigned to 'value', 'text', 'state', etc.\n */\n protected generateBindingInfo(bindingPath: string, modelName: string, typeInstance?: unknown, additionalOptions?: Record<string, unknown>): any {\n return {\n path: bindingPath,\n model: modelName,\n ...(typeInstance ? { type: typeInstance } : {}),\n ...(additionalOptions || {})\n };\n }\n\n /**\n * Universal pipeline validation.\n */\n public validate(): import(\"../../interfaces/IPlugin\").IPluginValidationResult {\n if (!this.control || !this.metadata) return { isValid: true };\n\n // Skip validation for hidden fields (e.g. hidden by ConditionEngine visibleOn)\n if (typeof (this.control as Control).getVisible === \"function\") {\n if (!(this.control as Control).getVisible()) {\n return { isValid: true };\n }\n }\n\n if (this.policyInvalidMessage) {\n return { isValid: false, errorMessage: this.policyInvalidMessage, fieldKey: this.fieldKey };\n }\n\n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {\n \"maxLength\": this.metadata.maxLength\n };\n\n const isRequired = this._isDynamicallyRequired !== undefined ? this._isDynamicallyRequired : this.metadata.required;\n if (isRequired) {\n validatorsToRun.push(\"required\");\n }\n if (this.metadata.maxLength) validatorsToRun.push(\"maxLength\");\n if (this.metadata.minLength) {\n validatorsToRun.push(\"minLength\");\n argsMap[\"minLength\"] = this.metadata.minLength;\n }\n if (this.metadata.pattern) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = this.metadata.pattern;\n }\n if (this.metadata.minimum !== undefined || this.metadata.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: this.metadata.minimum, max: this.metadata.maximum };\n }\n\n const format = this.metadata.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n\n if (this.metadata.ui?.validators) {\n for (const v of this.metadata.ui.validators) {\n if (typeof v === \"string\") {\n validatorsToRun.push(v);\n } else if (v && v.name) {\n validatorsToRun.push(v.name);\n if (v.args !== undefined) {\n argsMap[v.name] = v.args;\n }\n }\n }\n }\n\n if (validatorsToRun.length === 0) {\n return { isValid: true, errorMessage: undefined, fieldKey: this.fieldKey };\n }\n\n const val = this.getValue();\n const result = GlobalPipeline.executeValidation(val, validatorsToRun, argsMap);\n return { isValid: result.isValid, errorMessage: result.errorMessage, fieldKey: this.fieldKey, fieldLabel: this.metadata?.ui?.label };\n }\n\n /**\n * Natively manipulates the UI5 control's valueState if the control supports it.\n * Uses reflection to safely apply styles without crashing on structural controls.\n */\n public setVisualValidationState(isValid: boolean, errorMessage?: string): void {\n if (!this.control) return;\n\n\n // Use reflection to check if the control supports ValueState (e.g. sap.m.Input does, sap.m.Text does not)\n type StateControl = {\n setValueState?: (state: string) => void;\n setValueStateText?: (text: string) => void;\n };\n const ctrl = this.control as unknown as StateControl;\n if (typeof ctrl.setValueState === \"function\") {\n ctrl.setValueState(isValid ? coreLibrary.ValueState.None : coreLibrary.ValueState.Error);\n\n if (typeof ctrl.setValueStateText === \"function\") {\n ctrl.setValueStateText(isValid ? \"\" : (errorMessage || \"\"));\n }\n } else {\n // Quietly ignore. Controls like sap.m.Text natively do not support value states, which is completely valid.\n }\n }\n\n\n\n // --- IPluginStateReceiver Implementation for PBRE ---\n\n /**\n * Natively applies a forced error state from the PolicyEngine.\n * Per MetaUI Architecture Rule 12, this explicitly forces the visual state red \n * independently of the MessageManager auto-sync.\n * \n * @param errorMessage The custom error message to display.\n */\n public applyError(errorMessage: string): void {\n this.policyInvalidMessage = errorMessage;\n this.setVisualValidationState(false, errorMessage);\n }\n\n /**\n * Clears a previously forced error state.\n * Restores the visual boundary to standard (non-error) formatting.\n */\n public clearError(): void {\n this.policyInvalidMessage = null;\n this.setVisualValidationState(true);\n }\n\n /**\n * Dynamically manipulates the visibility state of the control based on PolicyEngine directives.\n * \n * @param isVisible True to display the control, false to hide it.\n */\n public applyVisibility(isVisible: boolean): void {\n const ctrl = this.control as unknown as { setVisible?: (b: boolean) => void };\n if (ctrl && typeof ctrl.setVisible === \"function\") {\n ctrl.setVisible(isVisible);\n }\n }\n\n /**\n * Dynamically alters the mandatory status of the field.\n * Updates internal transient state to ensure the `validate()` pipeline enforces the change,\n * and natively triggers the UI5 required indicator (asterisk) if supported,\n * without permanently corrupting the shared global schema definition.\n * \n * @param isRequired True to make the field mandatory, false to make it optional.\n */\n public applyRequired(isRequired: boolean): void {\n this._isDynamicallyRequired = isRequired;\n const ctrl = this.control as unknown as { setRequired?: (b: boolean) => void };\n if (ctrl && typeof ctrl.setRequired === \"function\") {\n ctrl.setRequired(isRequired);\n }\n }\n\n /**\n * Dynamically alters the editability of the field.\n * Falls back to `setEnabled` if the control is structural rather than purely input-driven.\n * \n * @param isEditable True to allow user input, false to lock it.\n */\n public applyEditable(isEditable: boolean): void {\n const ctrl = this.control as unknown as { setEditable?: (b: boolean) => void, setEnabled?: (b: boolean) => void };\n if (ctrl && typeof ctrl.setEditable === \"function\") {\n ctrl.setEditable(isEditable);\n } else if (ctrl && typeof ctrl.setEnabled === \"function\") {\n ctrl.setEnabled(isEditable);\n }\n }\n\n /**\n * Executes when the condition engine pushes new schema metadata to this field (e.g. readOnly changing).\n * @param newMetadata The mutated schema metadata.\n */\n public onStateChange(newMetadata: IPropertyMetadata): void {\n this.metadata = newMetadata;\n this.applyState();\n }\n\n /**\n * Abstract hook for the plugin to apply state changes to its specific UI5 control (e.g. placeholders, labels).\n */\n protected abstract applyState(): void;\n\n /**\n * Helper to apply common UI directives (like readOnly, visibleOn) directly to any control.\n */\n protected applyCommonDirectives(control: Control, metadata: IPropertyMetadata, modelName: string = \"meta\"): void {\n const ctrl = control as unknown as { setEditable?: (b: boolean) => void, setEnabled?: (b: boolean) => void };\n if (metadata.ui?.readOnly !== undefined && typeof ctrl.setEditable === \"function\") {\n ctrl.setEditable(!metadata.ui.readOnly);\n }\n\n if (metadata.ui?.visibleOn) {\n const ExpressionBuilder = sap.ui.require(\"nz/co/siliconst/ui5/metaui/utils/ExpressionBuilder\")?.ExpressionBuilder;\n let expr = \"\";\n if (ExpressionBuilder) {\n expr = ExpressionBuilder.build(metadata.ui.visibleOn, this.fieldKey, modelName);\n } else {\n expr = `{= ${metadata.ui.visibleOn.replace(/\\$root\\./g, `${modelName}>/`).replace(/\\./g, '/')} }`;\n }\n control.bindProperty(\"visible\", { parts: [{ path: \"meta>/\" }], formatter: () => false });\n control.bindProperty(\"visible\", expr);\n }\n\n if (metadata.ui?.enabledOn && typeof ctrl.setEnabled === \"function\") {\n const ExpressionBuilder = sap.ui.require(\"nz/co/siliconst/ui5/metaui/utils/ExpressionBuilder\")?.ExpressionBuilder;\n let expr = \"\";\n if (ExpressionBuilder) {\n expr = ExpressionBuilder.build(metadata.ui.enabledOn, this.fieldKey, modelName);\n } else {\n expr = `{= ${metadata.ui.enabledOn.replace(/\\$root\\./g, `${modelName}>/`).replace(/\\./g, '/')} }`;\n }\n control.bindProperty(\"enabled\", expr);\n }\n\n if (metadata.ui?.controlProps) {\n console.error(`[DEBUG MetaUI] controlProps found for ${this.fieldKey}`, metadata.ui.controlProps);\n const targetControl = this.mainControl || control;\n const target = targetControl as unknown as {\n getMetadata?: () => { getName(): string },\n applySettings?: (settings: Record<string, any>) => void,\n setProperty?: (p: string, v: unknown) => void,\n bindProperty?: (p: string, v: string) => void\n };\n\n if (typeof target.getMetadata === \"function\") {\n const targetMeta = target.getMetadata();\n const settings: Record<string, any> = {};\n for (const [propName, propValue] of Object.entries(metadata.ui.controlProps)) {\n if (this.BLOCKED_PROPS.includes(propName)) {\n Logger.warn(`[BasePlugin] Cannot apply controlProps '${propName}' for field '${this.fieldKey}' - ILLEGAL OVERRIDE (Property is protected by sandbox)`);\n continue;\n }\n \n // Natively block any aggregations or events to prevent sandbox escapes\n if (typeof (targetMeta as any).hasAggregation === \"function\" && (targetMeta as any).hasAggregation(propName)) {\n Logger.warn(`[BasePlugin] Cannot apply controlProps '${propName}' for field '${this.fieldKey}' - ILLEGAL OVERRIDE (Cannot hijack aggregations)`);\n continue;\n }\n \n if (typeof (targetMeta as any).hasEvent === \"function\" && (targetMeta as any).hasEvent(propName)) {\n Logger.warn(`[BasePlugin] Cannot apply controlProps '${propName}' for field '${this.fieldKey}' - ILLEGAL OVERRIDE (Cannot hijack events)`);\n continue;\n }\n\n if (typeof propValue === \"string\" && propValue.startsWith(\"{\") && propValue.endsWith(\"}\")) {\n // The JSON payloads often hardcode 'metaui>' in raw expression bindings, \n // but the Engine dynamically generates model names like 'metaUI_Host1'. \n // We must inject the actual modelName dynamically into the expression string.\n const injectedValue = propValue.replace(/metaui>/g, `${modelName}>`);\n settings[propName] = injectedValue;\n } else {\n settings[propName] = propValue;\n }\n }\n\n try {\n const target = targetControl as unknown as { applySettings?: (s: Record<string, any>) => void };\n if (typeof target.applySettings === \"function\") {\n target.applySettings(settings);\n }\n } catch (err: unknown) {\n Logger.warn(`[BasePlugin] Failed to apply controlProps for field '${this.fieldKey}' on control ${targetMeta.getName()}: ${(err as Error).message}`);\n }\n }\n }\n }\n\n\n\n /**\n * Natively destroys the instantiated UI5 control to prevent memory leaks.\n * Can be overridden by subclasses if they manage secondary controls or custom models.\n */\n public destroy(): void {\n if (this.control && typeof this.control.destroy === \"function\") {\n this.control.destroy();\n this.control = null;\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":52,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","BooleanPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","BLOCKED_PROPS","filter","p","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","applyCommonDirectives","onChangeFn","oEvent","getParameter","result","validate","isValid","errorMessage","ui","widget","Switch","state","enabled","readOnly","change","CheckBox","width","selected","select","getValue","getState","getSelected","applyState","setEnabled","__exports","__esModule"],"sources":["BooleanPlugin.ts"],"sourcesContent":["/**\n * @file BooleanPlugin.ts\n * @description Renders a sap.m.Switch for boolean states.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport CheckBox from \"sap/m/CheckBox\";\nimport Switch from \"sap/m/Switch\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for toggleable booleans using `sap.m.CheckBox`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class BooleanPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.CheckBox` component for boolean evaluation.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @returns {Control} The configured CheckBox control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n // text is safe for Boolean controls\n this.BLOCKED_PROPS = this.BLOCKED_PROPS.filter(p => p !== \"text\");\n\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: boolean) => val ? \"Yes\" : \"No\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n const onChangeFn = (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as any).getParameter(\"state\") ?? (oEvent as any).getParameter(\"selected\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n };\n\n if (fieldMetadata.ui?.widget === \"switch\") {\n this.control = new Switch({\n id: this.generateStableId(engineScopeId, bindingPath),\n state: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n change: onChangeFn\n });\n } else {\n this.control = new CheckBox({\n id: this.generateStableId(engineScopeId, bindingPath),\n width: \"100%\",\n selected: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n select: onChangeFn\n });\n }\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current boolean state.\n * @returns {boolean} The selected state.\n */\n protected getValue(): unknown {\n if (!this.control) return false;\n if (this.control instanceof Switch) {\n return (this.control as Switch).getState();\n }\n return (this.control as CheckBox).getSelected();\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n if (this.control instanceof Switch) {\n (this.control as Switch).setEnabled(!this.metadata.ui?.readOnly);\n } else {\n (this.control as CheckBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n }\n}\n"],"mappings":"AAAA,2KAAA,MAKSA,EAAUC,EAAA,cAaZ,MAAMC,UAAsBF,EASxBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAEvHC,KAAKC,cAAgBD,KAAKC,cAAcC,OAAOC,GAAKA,IAAM,QAE1DH,KAAKD,SAAWA,EAChBC,KAAKI,SAAWT,EAChBK,KAAKK,SAAWT,EAAYU,WAAW,KAAOV,EAAYW,UAAU,GAAKX,EAEzE,IAAKI,KAAKQ,WAAY,CAElBR,KAAKS,QAAU,IAAIC,EAAY,CAC3BC,GAAIX,KAAKY,iBAAiBd,EAAeF,GACzCiB,KAAMb,KAAKc,oBAAoBlB,EAAaC,EAAWkB,UAAW,CAC9DC,UAAYC,GAAiBA,EAAM,MAAQ,SAGnDjB,KAAKkB,sBAAsBlB,KAAKS,QAASd,EAAeE,GACxD,OAAOG,KAAKS,OAChB,CAEA,MAAMU,EAAcC,IAChB,MAAMH,EAAOG,EAAeC,aAAa,UAAaD,EAAeC,aAAa,YAClF,MAAMC,EAAStB,KAAKuB,WACpB,GAAIvB,KAAKD,SAAU,CACfC,KAAKD,SAASuB,EAAOE,QAASxB,KAAKK,SAAUiB,EAAOG,aACxD,GAGJ,GAAI9B,EAAc+B,IAAIC,SAAW,SAAU,CACvC3B,KAAKS,QAAU,IAAImB,EAAO,CACtBjB,GAAIX,KAAKY,iBAAiBd,EAAeF,GACzCiC,MAAO7B,KAAKc,oBAAoBlB,EAAaC,GAC7CiC,SAAUnC,EAAc+B,IAAIK,SAC5BC,OAAQb,GAEhB,KAAO,CACHnB,KAAKS,QAAU,IAAIwB,EAAS,CACxBtB,GAAIX,KAAKY,iBAAiBd,EAAeF,GACzCsC,MAAO,OACPC,SAAUnC,KAAKc,oBAAoBlB,EAAaC,GAChDiC,SAAUnC,EAAc+B,IAAIK,SAC5BK,OAAQjB,GAEhB,CAEAnB,KAAKkB,sBAAsBlB,KAAKS,QAASd,EAAeE,GAExD,OAAOG,KAAKS,OAChB,CAMU4B,WACN,IAAKrC,KAAKS,QAAS,OAAO,MAC1B,GAAIT,KAAKS,mBAAmBmB,EAAQ,CAChC,OAAQ5B,KAAKS,QAAmB6B,UACpC,CACA,OAAQtC,KAAKS,QAAqB8B,aACtC,CAKUC,aACN,GAAIxC,KAAKS,SAAWT,KAAKI,SAAU,CAC/B,IAAKJ,KAAKQ,WAAY,OACtB,GAAIR,KAAKS,mBAAmBmB,EAAQ,CAC/B5B,KAAKS,QAAmBgC,YAAYzC,KAAKI,SAASsB,IAAIK,SAC3D,KAAO,CACF/B,KAAKS,QAAqBgC,YAAYzC,KAAKI,SAASsB,IAAIK,SAC7D,CACJ,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAAjD,gBAAA,OAAAiD,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":53,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","CameraControl","_interopRequireDefault","__CameraControl","CameraPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","ImageControl","id","generateStableId","src","generateBindingInfo","width","alt","ui","label","applyCommonDirectives","value","schemaMetadata","readOnly","attachEvent","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setProperty","__exports","__esModule"],"sources":["CameraPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport CameraControl from \"../../controls/CameraControl\";\nimport ImageControl from \"sap/m/Image\";\n\nexport class CameraPlugin extends BasePlugin {\n /**\n * Renders a `CameraControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured CameraControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new ImageControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n src: this.generateBindingInfo(bindingPath, modelName),\n width: \"400px\",\n alt: metadata.ui?.label || \"Image\"\n });\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new CameraControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n });\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n // Validation mapping could be hooked into the 'capture' event if needed, but Two-Way binding updates the model naturally.\n (this.control as CameraControl).attachEvent('capture', () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current base64 image state.\n * @returns {unknown} The image value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as CameraControl).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,yQAASA,EAAUC,EAAA,oBAGZC,EAAaC,EAAAC,GAGb,MAAMC,UAAqBL,EAWvBM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAa,CAC5BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,IAAKR,KAAKS,oBAAoBb,EAAaC,GAC3Ca,MAAO,QACPC,IAAKhB,EAASiB,IAAIC,OAAS,UAE/Bb,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAc,CAC7BgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCmB,MAAOf,KAAKS,oBAAoBb,EAAaC,GAC7CmB,eAAgBrB,EAChBsB,WAAYtB,EAASiB,IAAIK,WAG7BjB,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GAGlDG,KAAKI,QAA0Bc,YAAY,UAAW,KACnD,MAAMC,EAASnB,KAAKoB,WAChB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SAAUkB,EAAOG,aACxD,IAGR,OAAOtB,KAAKI,OAChB,CAMUmB,WACN,OAAOvB,KAAKI,QAAWJ,KAAKI,QAA0BoB,YAAY,SAAW,IACjF,CAKUC,aACN,GAAIzB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCsB,YAAY,aAAc1B,KAAKL,SAASiB,IAAIK,SACtF,CACJ,EACH,IAAAU,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,eAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":54,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","CodeEditorPlugin","detectLanguage","value","trimmed","trim","startsWith","JSON","parse","e","test","adjustHeight","this","codeEditorRef","metadata","ui","rows","val","getProperty","lines","split","length","newHeight","Math","max","setHeight","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","fieldKey","replace","schemaRows","useDialog","expandable","baseHeight","codeEditor","CodeEditor","id","generateStableId","generateBindingInfo","type","args","editable","isEditable","readOnly","height","width","change","result","validate","isValid","errorMessage","currentVal","detectedType","getType","setType","mainControl","expandBtn","Button","icon","tooltip","press","dlg","Dialog","title","label","contentWidth","contentHeight","verticalScrolling","resizable","content","beginButton","text","close","afterClose","destroy","control","addDependent","open","setLayoutData","FlexItemData","growFactor","HBox","alignItems","items","attachEventOnce","oBinding","getBinding","initLogic","applyState","attachChange","applyCommonDirectives","getValue","setEditable","__exports","__esModule"],"sources":["CodeEditorPlugin.ts"],"sourcesContent":["/**\n * @file CodeEditorPlugin.ts\n * @description Renders a sap.ui.codeeditor.CodeEditor for editing source code/JSON.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport CodeEditor from \"sap/ui/codeeditor/CodeEditor\";\nimport HBox from \"sap/m/HBox\";\nimport Button from \"sap/m/Button\";\nimport Dialog from \"sap/m/Dialog\";\nimport FlexItemData from \"sap/m/FlexItemData\";\n\n/**\n * Handles rendering logic for code editing.\n * Requires the `sap.ui.codeeditor` library to be loaded.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class CodeEditorPlugin extends BasePlugin {\n private codeEditorRef?: CodeEditor;\n\n /**\n * Infers the language type from the content.\n * @param value The raw string.\n * @returns The language string.\n */\n private detectLanguage(value: string): string {\n if (!value || typeof value !== \"string\") return \"javascript\";\n \n const trimmed = value.trim();\n if (trimmed === \"\") return \"javascript\";\n\n // 1. JSON\n if (trimmed.startsWith(\"{\") || trimmed.startsWith(\"[\")) {\n try {\n JSON.parse(trimmed);\n return \"json\";\n } catch (e) {\n // Not valid JSON, continue testing\n }\n }\n\n // 2. XML / HTML\n if (/^\\s*<[\\s\\S]*>\\s*$/.test(trimmed)) {\n return \"xml\";\n }\n\n // 3. Fallback to JavaScript\n return \"javascript\";\n }\n\n /**\n * Dynamically adjusts the height of the editor based on content lines.\n */\n private adjustHeight(): void {\n if (!this.codeEditorRef) return;\n \n // If a static height was requested via ui.rows, do not auto-adjust\n if (this.metadata?.ui?.rows) return;\n \n const val = this.codeEditorRef.getProperty('value') || \"\";\n const lines = val.split(/\\r\\n|\\r|\\n/).length;\n // 18px per line + 20px padding, minimum 100px\n const newHeight = Math.max(100, (lines * 18) + 20);\n this.codeEditorRef.setHeight(newHeight + \"px\");\n }\n\n /**\n * Renders a `sap.ui.codeeditor.CodeEditor` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured CodeEditor control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\"); // For EventBus\n \n const schemaRows = fieldMetadata.ui?.rows;\n const useDialog = fieldMetadata.ui?.expandable !== false;\n const baseHeight = schemaRows ? (schemaRows * 18 + 20) + \"px\" : \"200px\"; // 200px is ~10 rows\n \n const codeEditor = new CodeEditor({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: fieldMetadata.ui?.args || \"javascript\", // will be dynamically overridden if args is missing\n editable: !this.isEditable ? false : !fieldMetadata.ui?.readOnly,\n height: baseHeight, // Initial minimum height\n width: \"100%\",\n change: () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n \n // If language isn't explicitly defined, try to guess it dynamically\n if (!fieldMetadata.ui?.args) {\n const currentVal = this.codeEditorRef!.getProperty('value');\n const detectedType = this.detectLanguage(currentVal);\n if (this.codeEditorRef!.getType() !== detectedType) {\n this.codeEditorRef!.setType(detectedType);\n }\n }\n \n this.adjustHeight();\n }\n });\n \n this.codeEditorRef = codeEditor;\n this.mainControl = codeEditor;\n\n if (useDialog) {\n const expandBtn = new Button({\n icon: \"sap-icon://full-screen\",\n type: \"Transparent\",\n tooltip: \"Expand Code Editor\",\n press: () => {\n const dlg = new Dialog({\n title: fieldMetadata.title || fieldMetadata.ui?.label || \"Edit Code\",\n contentWidth: \"80%\",\n contentHeight: \"80%\",\n verticalScrolling: false,\n resizable: true,\n content: new CodeEditor({\n value: this.generateBindingInfo(bindingPath, modelName),\n type: this.codeEditorRef!.getType(),\n width: \"100%\",\n height: \"100%\",\n editable: !this.isEditable ? false : !fieldMetadata.ui?.readOnly\n }),\n beginButton: new Button({\n text: \"Close\",\n press: () => dlg.close()\n }),\n afterClose: () => dlg.destroy()\n });\n this.control?.addDependent(dlg);\n dlg.open();\n }\n });\n\n codeEditor.setLayoutData(new FlexItemData({ growFactor: 1 }));\n\n this.control = new HBox({\n width: \"100%\",\n alignItems: \"Start\",\n items: [codeEditor, expandBtn]\n });\n } else {\n this.control = codeEditor;\n }\n\n // Clean architecture: Wait for the model context, then attach safely to the binding itself.\n // No timeouts, no DOM hacks, pure UI5 Eventing.\n this.codeEditorRef.attachEventOnce(\"modelContextChange\", () => {\n const oBinding = this.codeEditorRef!.getBinding(\"value\");\n \n const initLogic = () => {\n if (this.codeEditorRef) {\n const currentVal = this.codeEditorRef.getProperty('value');\n if (!fieldMetadata.ui?.args) {\n this.codeEditorRef.setType(this.detectLanguage(currentVal));\n }\n this.adjustHeight();\n // CRITICAL: Ace Editor sometimes loses its constructor `editable` flag \n // when the model asynchronously injects a new value string. \n // We must forcefully re-apply the correct state after binding.\n this.applyState();\n }\n };\n\n if (oBinding) {\n // Attach for future model changes\n oBinding.attachChange(initLogic);\n }\n \n // Execute immediately in case the model is synchronous (JSONModel)\n initLogic();\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current code string.\n * @returns {unknown} The code value.\n */\n protected getValue(): unknown {\n return this.codeEditorRef ? this.codeEditorRef.getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.codeEditorRef && this.metadata) {\n if (!this.isEditable) {\n this.codeEditorRef.setEditable(false);\n } else {\n this.codeEditorRef.setEditable(!this.metadata.ui?.readOnly);\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":55,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","DatePlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","formatOptions","source","pattern","applyCommonDirectives","DatePicker","value","displayFormat","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","dp","setEditable","setRequired","__exports","__esModule"],"sources":["DatePlugin.ts"],"sourcesContent":["/**\n * @file DatePlugin.ts\n * @description Renders a sap.m.DatePicker natively bound to ISO date strings.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport DatePicker from \"sap/m/DatePicker\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for Date strings.\n */\nexport class DatePlugin extends BasePlugin {\n /**\n * Renders a `sap.m.DatePicker` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured DatePicker control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Date\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd\" },\n pattern: \"yyyy-MM-dd\"\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new DatePicker({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Date\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd\" },\n pattern: \"yyyy-MM-dd\"\n }\n }),\n displayFormat: \"long\",\n editable: !fieldMetadata.ui?.readOnly,\n required: fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as any).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current date string.\n * @returns {unknown} The date value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as DatePicker).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const dp = this.control as DatePicker;\n dp.setEditable(!this.metadata.ui?.readOnly);\n dp.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,yJAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAmBF,EAWrBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC7Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,cACnBA,QAAS,kBAIrBd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAW,CAC1BR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC9Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,cACnBA,QAAS,gBAGjBI,cAAe,OACfC,UAAWxB,EAAcyB,IAAIC,SAC7BC,SAAU3B,EAAc2B,SACxBC,OAASC,IACL,MAAMC,EAAOD,EAAeE,aAAa,SACzC,MAAMC,EAAS3B,KAAK4B,WACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SAAUyB,EAAOG,aACxD,KAIR,OAAO9B,KAAKM,OAChB,CAMUyB,WACN,OAAO/B,KAAKM,QAAWN,KAAKM,QAAuB0B,YAAY,SAAW,IAC9E,CAKUC,aACN,GAAIjC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM6B,EAAKlC,KAAKM,QAChB4B,EAAGC,aAAanC,KAAKC,SAASmB,IAAIC,UAClCa,EAAGE,YAAYpC,KAAKC,SAASqB,SACjC,CACJ,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAA5C,aAAA,OAAA4C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":56,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","DateTimePlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","formatOptions","source","pattern","applyCommonDirectives","DateTimePicker","value","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","input","setEditable","setRequired","__exports","__esModule"],"sources":["DateTimePlugin.ts"],"sourcesContent":["/**\n * @file DateTimePlugin.ts\n * @description Handles rendering logic for DateTime strings (timestamps).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport DateTimePicker from \"sap/m/DateTimePicker\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for timestamps/datetime inputs.\n */\nexport class DateTimePlugin extends BasePlugin {\n /**\n * Renders a `sap.m.DateTimePicker` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured DateTimePicker control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.DateTime\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\" },\n pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\"\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new DateTimePicker({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.DateTime\", {\n formatOptions: {\n source: { pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\" },\n pattern: \"yyyy-MM-dd'T'HH:mm:ss'Z'\"\n }\n }),\n editable: !fieldMetadata.ui?.readOnly,\n required: fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as any).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current datetime string.\n * @returns {unknown} The datetime value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as DateTimePicker).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as DateTimePicker;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,iKAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAuBF,EAWzBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAW,6BAA8B,CACjFe,cAAe,CACXC,OAAQ,CAAEC,QAAS,4BACnBA,QAAS,gCAIrBd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAe,CAC9BR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,EAAW,6BAA8B,CAClFe,cAAe,CACXC,OAAQ,CAAEC,QAAS,4BACnBA,QAAS,8BAGjBI,UAAWvB,EAAcwB,IAAIC,SAC7BC,SAAU1B,EAAc0B,SACxBC,OAASC,IACL,MAAMC,EAAOD,EAAeE,aAAa,SACzC,MAAMC,EAAS1B,KAAK2B,WACpB,GAAI3B,KAAKD,SAAU,CACfC,KAAKD,SAAS2B,EAAOE,QAAS5B,KAAKE,SAAUwB,EAAOG,aACxD,KAIR7B,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUwB,WACN,OAAO9B,KAAKM,QAAWN,KAAKM,QAA2ByB,YAAY,SAAW,IAClF,CAKUC,aACN,GAAIhC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM4B,EAAQjC,KAAKM,QACnB2B,EAAMC,aAAalC,KAAKC,SAASkB,IAAIC,UACrCa,EAAME,YAAYnC,KAAKC,SAASoB,SACpC,CACJ,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAA3C,iBAAA,OAAA2C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":57,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","PluginRegistry","____core_PluginRegistry","DictionaryMapPlugin","_isSyncing","_binding","canHandle","schema","type","additionalProperties","render","bindingPath","modelName","engineScopeId","onChange","model","this","metadata","valueSchema","container","VBox","width","addStyleClass","absolutePath","startsWith","currentData","getProperty","localItems","Object","keys","map","k","key","value","localModel","JSONModel","items","syncToParent","newDict","forEach","item","trim","setProperty","bindProperty","attachChange","initialize","headerItems","Title","text","title","ui","label","level","isEditable","push","Button","icon","press","header","HBox","justifyContent","alignItems","addItem","columns","Column","Label","hAlign","table","Table","mode","noDataText","setModel","bindItems","path","factory","sId","oContext","rowPath","getPath","keyInput","Input","editable","change","plugin","getInstance","getPlugin","widget","effectiveValueSchema","readOnly","valueControl","Date","now","cells","delBtn","matchIndex","parseInt","split","pop","splice","ColumnListItem","control","id","generateStableId","dialog","Dialog","contentWidth","contentHeight","horizontalScrolling","content","buttons","close","afterClose","removeAllContent","destroy","addDependent","open","applyCommonDirectives","getValue","validate","isValid","applyState","super"],"sources":["DictionaryMapPlugin.ts"],"sourcesContent":["/**\n * @file DictionaryMapPlugin.ts\n * @description Plugin for rendering open-ended JSON Dictionaries (additionalProperties).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { ISchema, IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport { PluginRegistry } from \"../../core/PluginRegistry\";\nimport VBox from \"sap/m/VBox\";\nimport HBox from \"sap/m/HBox\";\nimport Input from \"sap/m/Input\";\nimport Button from \"sap/m/Button\";\nimport Title from \"sap/m/Title\";\nimport Table from \"sap/m/Table\";\nimport Column from \"sap/m/Column\";\nimport Label from \"sap/m/Label\";\nimport ColumnListItem from \"sap/m/ColumnListItem\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Control from \"sap/ui/core/Control\";\nimport Dialog from \"sap/m/Dialog\";\nimport Toolbar from \"sap/m/Toolbar\";\nimport ToolbarSpacer from \"sap/m/ToolbarSpacer\";\n\n/**\n * Plugin for rendering open-ended JSON Dictionaries (additionalProperties).\n * Uses a local JSONModel and sap.m.Table to provide a stable, zero-hack UI5 two-way binding experience.\n * \n * @public\n */\nexport default class DictionaryMapPlugin extends BasePlugin {\n private _isSyncing: boolean = false;\n private _binding: sap.ui.model.PropertyBinding | null = null;\n\n public canHandle(schema: ISchema | IPropertyMetadata): boolean {\n return schema.type === \"object\" && typeof schema.additionalProperties === \"object\";\n }\n\n public render(\n schema: ISchema | IPropertyMetadata, \n bindingPath: string, \n modelName: string, \n engineScopeId: string, \n onChange?: () => void, \n model?: sap.ui.model.Model\n ): Control {\n this.onChange = onChange;\n this.metadata = schema as IPropertyMetadata;\n\n\n\n const valueSchema = (schema.additionalProperties as IPropertyMetadata) || { type: \"string\" };\n const container = new VBox({ width: \"100%\" }).addStyleClass(\"sapUiSmallMarginTopBottom\");\n \n const absolutePath = bindingPath.startsWith(\"/\") ? bindingPath : `/${bindingPath}`;\n \n // 1. Initialize local flat array model for the Table\n const currentData = model ? model.getProperty(absolutePath) || {} : {};\n\n \n const localItems = Object.keys(currentData).map(k => ({ key: k, value: currentData[k] }));\n const localModel = new JSONModel({ items: localItems });\n \n // Setup listener to flush local model back to parent dictionary model\n const syncToParent = () => {\n if (!model) return;\n this._isSyncing = true;\n const items = localModel.getProperty(\"/items\") as Record<string, unknown>[];\n const newDict: Record<string, unknown> = {};\n items.forEach(item => {\n if (item.key && item.key.trim() !== \"\") {\n newDict[item.key] = item.value;\n }\n });\n\n model.setProperty(absolutePath, newDict);\n if (this.onChange) this.onChange();\n this._isSyncing = false;\n };\n\n if (model) {\n this._binding = model.bindProperty(absolutePath);\n this._binding.attachChange(() => {\n if (this._isSyncing) return;\n const currentData = model.getProperty(absolutePath) || {};\n\n const localItems = Object.keys(currentData).map(k => ({ key: k, value: currentData[k] }));\n localModel.setProperty(\"/items\", localItems);\n });\n this._binding.initialize();\n }\n\n const headerItems: Control[] = [\n new Title({ text: schema.title || schema.ui?.label || \"Dictionary Map\", level: \"H5\" })\n ];\n\n if (this.isEditable) {\n headerItems.push(\n new Button({\n text: \"Add Property\",\n icon: \"sap-icon://add\",\n press: () => {\n const items = localModel.getProperty(\"/items\") as Record<string, unknown>[];\n items.push({ key: \"\", value: null });\n localModel.setProperty(\"/items\", items);\n syncToParent();\n }\n })\n );\n }\n\n const header = new HBox({\n justifyContent: \"SpaceBetween\",\n alignItems: \"Center\",\n items: headerItems\n }).addStyleClass(\"sapUiSmallMarginBottom\");\n\n container.addItem(header);\n\n // 2. Build the Table\n const columns = [\n new Column({ header: new Label({ text: \"Key\" }) }),\n new Column({ header: new Label({ text: \"Value\" }) })\n ];\n\n if (this.isEditable) {\n columns.push(new Column({ width: \"4rem\", hAlign: \"Center\" }));\n }\n\n const table = new Table({\n mode: \"None\",\n noDataText: \"No metadata properties defined.\",\n columns: columns\n });\n\n table.setModel(localModel, \"localDict\");\n\n table.bindItems({\n path: \"localDict>/items\",\n factory: (sId: string, oContext: sap.ui.model.Context) => {\n const rowPath = oContext.getPath();\n \n // Key Input\n const keyInput = new Input({\n value: \"{localDict>key}\",\n editable: this.isEditable,\n change: () => syncToParent()\n });\n\n // Value Control\n const plugin = PluginRegistry.getInstance().getPlugin(valueSchema.type || \"string\", valueSchema.ui?.widget);\n \n // Temporarily override value schema readOnly state if the dictionary as a whole is readOnly\n const effectiveValueSchema = { ...valueSchema };\n if (!this.isEditable) {\n if (!effectiveValueSchema.ui) effectiveValueSchema.ui = {};\n effectiveValueSchema.ui.readOnly = true;\n }\n\n const valueControl = plugin.render(\n effectiveValueSchema,\n `${rowPath}/value`,\n \"localDict\",\n \"dict_\" + Date.now(),\n () => syncToParent(),\n localModel\n );\n\n const cells: Control[] = [keyInput, valueControl];\n\n if (this.isEditable) {\n const delBtn = new Button({\n icon: \"sap-icon://delete\",\n type: \"Reject\",\n press: () => {\n const items = localModel.getProperty(\"/items\") as Record<string, unknown>[];\n const matchIndex = parseInt(rowPath.split(\"/\").pop() || \"0\", 10);\n items.splice(matchIndex, 1);\n localModel.setProperty(\"/items\", items);\n syncToParent();\n }\n });\n cells.push(delBtn);\n }\n\n return new ColumnListItem({ cells });\n }\n });\n\n container.addItem(table);\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? \"View Dictionary\" : \"Edit Dictionary\",\n icon: !this.isEditable ? \"sap-icon://display\" : \"sap-icon://form\",\n press: () => {\n\n const dialog = new Dialog({\n title: schema.title || schema.ui?.label || \"Dictionary Map\",\n contentWidth: \"600px\",\n contentHeight: \"400px\",\n horizontalScrolling: false,\n content: [container],\n buttons: [\n new Button({\n text: !this.isEditable ? \"Close\" : \"OK\",\n type: \"Emphasized\",\n press: () => {\n dialog.close();\n }\n })\n ],\n afterClose: () => {\n // Remove container so it isn't destroyed when the dialog is destroyed\n dialog.removeAllContent();\n dialog.destroy();\n }\n });\n \n // Add dependent to ensure models are inherited properly if needed\n if (this.control) {\n this.control.addDependent(dialog);\n }\n dialog.open();\n }\n });\n\n this.applyCommonDirectives(this.control, schema, modelName);\n\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return null;\n }\n\n public validate(): import(\"../../interfaces/IPlugin\").IPluginValidationResult {\n return { isValid: true };\n }\n\n protected applyState(): void {\n }\n\n public destroy(): void {\n if (this._binding) {\n this._binding.destroy();\n this._binding = null;\n }\n super.destroy();\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":58,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","DropdownPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","valueHelpArray","valueHelp","Array","isArray","enum","map","e","key","String","text","control","TextControl","id","generateStableId","generateBindingInfo","undefined","formatter","match","find","vh","applyCommonDirectives","select","Select","selectedKey","enabled","ui","readOnly","forceSelection","change","oEvent","item","getParameter","val","getKey","result","validate","isValid","errorMessage","length","addItem","Item","forEach","getValue","getSelectedKey","type","parsed","parseFloat","isNaN","applyState","setEnabled","__exports","__esModule"],"sources":["DropdownPlugin.ts"],"sourcesContent":["/**\n * @file DropdownPlugin.ts\n * @description Renders a sap.m.Select utilizing the schema's valueHelp structure.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Select from \"sap/m/Select\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for dropdown inputs.\n * Maps the static `valueHelp` schema array to `sap.ui.core.Item` elements.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class DropdownPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Select` component populated with schema-defined value help.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Select control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n \n const valueHelpArray = fieldMetadata.valueHelp && Array.isArray(fieldMetadata.valueHelp) \n ? fieldMetadata.valueHelp \n : (fieldMetadata.enum ? fieldMetadata.enum.map(e => ({ key: String(e), text: String(e) })) : []);\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (key: string) => {\n const match = valueHelpArray.find(vh => vh.key === key);\n return match ? match.text : key;\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n const select = new Select({\n id: this.generateStableId(engineScopeId, bindingPath),\n selectedKey: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n forceSelection: false,\n change: (oEvent: sap.ui.base.Event) => {\n const item = (oEvent as any).getParameter(\"selectedItem\");\n const val = item ? item.getKey() : \"\";\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n const valueHelpArray = fieldMetadata.valueHelp && Array.isArray(fieldMetadata.valueHelp) \n ? fieldMetadata.valueHelp \n : (fieldMetadata.enum ? fieldMetadata.enum.map(e => ({ key: String(e), text: String(e) })) : []);\n\n if (valueHelpArray.length > 0) {\n // Always add the empty placeholder so that 'required' checks can actually fire if the user hasn't made a choice\n select.addItem(new Item({ key: \"\", text: \"--- Select ---\" }));\n \n valueHelpArray.forEach(vh => {\n select.addItem(new Item({ key: vh.key, text: vh.text }));\n });\n }\n\n this.control = select;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the currently selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n const val = this.control ? (this.control as Select).getSelectedKey() : null;\n if (val && this.metadata && (this.metadata.type === \"number\" || this.metadata.type === \"integer\")) {\n const parsed = parseFloat(val);\n return isNaN(parsed) ? val : parsed;\n }\n return val;\n }\n\n /**\n * Applies dynamic metadata state (e.g. readOnly) when the ConditionEngine fires.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const select = this.control as Select;\n select.setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,8KAAA,MAKSA,EAAUC,EAAA,cAcZ,MAAMC,UAAuBF,EAWzBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAGlB,MAAMC,EAAiBX,EAAcY,WAAaC,MAAMC,QAAQd,EAAcY,WACxEZ,EAAcY,UACbZ,EAAce,KAAOf,EAAce,KAAKC,IAAIC,IAAC,CAAOC,IAAKC,OAAOF,GAAIG,KAAMD,OAAOF,MAAS,GAEjGZ,KAAKgB,QAAU,IAAIC,EAAY,CAC3BC,GAAIlB,KAAKmB,iBAAiBrB,EAAeF,GACzCmB,KAAMf,KAAKoB,oBAAoBxB,EAAaC,EAAWwB,UAAW,CAC9DC,UAAYT,IACR,MAAMU,EAAQjB,EAAekB,KAAKC,GAAMA,EAAGZ,MAAQA,GACnD,OAAOU,EAAQA,EAAMR,KAAOF,OAIxCb,KAAK0B,sBAAsB1B,KAAKgB,QAASrB,EAAeE,GACxD,OAAOG,KAAKgB,OAChB,CAEA,MAAMW,EAAS,IAAIC,EAAO,CACtBV,GAAIlB,KAAKmB,iBAAiBrB,EAAeF,GACzCiC,YAAa7B,KAAKoB,oBAAoBxB,EAAaC,GACnDiC,SAAUnC,EAAcoC,IAAIC,SAC5BC,eAAgB,MAChBC,OAASC,IACL,MAAMC,EAAQD,EAAeE,aAAa,gBAC1C,MAAMC,EAAMF,EAAOA,EAAKG,SAAW,GACnC,MAAMC,EAASxC,KAAKyC,WACpB,GAAIzC,KAAKD,SAAU,CACfC,KAAKD,SAASyC,EAAOE,QAAS1C,KAAKE,SAAUsC,EAAOG,aACxD,KAIR,MAAMrC,EAAiBX,EAAcY,WAAaC,MAAMC,QAAQd,EAAcY,WACxEZ,EAAcY,UACbZ,EAAce,KAAOf,EAAce,KAAKC,IAAIC,IAAC,CAAOC,IAAKC,OAAOF,GAAIG,KAAMD,OAAOF,MAAS,GAEjG,GAAIN,EAAesC,OAAS,EAAG,CAE3BjB,EAAOkB,QAAQ,IAAIC,EAAK,CAAEjC,IAAK,GAAIE,KAAM,oBAEzCT,EAAeyC,QAAQtB,IACnBE,EAAOkB,QAAQ,IAAIC,EAAK,CAAEjC,IAAKY,EAAGZ,IAAKE,KAAMU,EAAGV,SAExD,CAEAf,KAAKgB,QAAUW,EACf3B,KAAK0B,sBAAsB1B,KAAKgB,QAASrB,EAAeE,GACxD,OAAOG,KAAKgB,OAChB,CAMUgC,WACN,MAAMV,EAAMtC,KAAKgB,QAAWhB,KAAKgB,QAAmBiC,iBAAmB,KACvE,GAAIX,GAAOtC,KAAKC,WAAaD,KAAKC,SAASiD,OAAS,UAAYlD,KAAKC,SAASiD,OAAS,WAAY,CAC/F,MAAMC,EAASC,WAAWd,GAC1B,OAAOe,MAAMF,GAAUb,EAAMa,CACjC,CACA,OAAOb,CACX,CAKUgB,aACN,GAAItD,KAAKgB,SAAWhB,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAMsB,EAAS3B,KAAKgB,QACpBW,EAAO4B,YAAYvD,KAAKC,SAAS8B,IAAIC,SACzC,CACJ,EACH,IAAAwB,EAAA,CAAAC,WAAA,MAAAD,EAAA/D,iBAAA,OAAA+D,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":59,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","EmailPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","Input","value","type","maxLength","required","change","oEvent","result","validate","isValid","errorMessage","getValue","getMetadata","getName","getProperty","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["EmailPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\nexport class EmailPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\");\n \n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: \"Email\",\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validate();\n if (this.onChange) this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return this.control && this.control.getMetadata().getName() === \"sap.m.Input\" ? (this.control as Input).getProperty('value') : null;\n }\n\n protected applyState(): void {\n if (!this.control || !this.metadata || this.control.getMetadata().getName() !== \"sap.m.Input\") return;\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n}\n"],"mappings":"AAAA,2JAASA,EAAUC,EAAA,cAMZ,MAAMC,UAAoBF,EACtBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAClBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,KAEhDG,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIO,EAAM,CACrBL,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCiB,MAAOb,KAAKU,oBAAoBd,EAAaC,GAC7CiB,KAAM,QACNC,UAAWpB,EAAcoB,WAAa,EACtCC,WAAYrB,EAAcqB,SAC1BC,OAASC,IACL,MAAMC,EAASnB,KAAKoB,WACpB,GAAIpB,KAAKD,SAAUC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKE,SAAUiB,EAAOG,iBAI/EtB,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEUkB,WACN,OAAOvB,KAAKK,SAAWL,KAAKK,QAAQmB,cAAcC,YAAc,cAAiBzB,KAAKK,QAAkBqB,YAAY,SAAW,IACnI,CAEUC,aACN,IAAK3B,KAAKK,UAAYL,KAAKC,UAAYD,KAAKK,QAAQmB,cAAcC,YAAc,cAAe,OAC/F,MAAMG,EAAQ5B,KAAKK,QACnBuB,EAAMC,aAAa7B,KAAKC,SAAS6B,IAAIC,UACrCH,EAAMI,cAAchC,KAAKC,SAASe,SACtC,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAAxC,cAAA,OAAAwC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":60,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","FileUploaderPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","LinkControl","id","generateStableId","text","generateBindingInfo","href","target","applyCommonDirectives","FileUploader","value","enabled","ui","readOnly","placeholder","label","width","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setEnabled","__exports","__esModule"],"sources":["FileUploaderPlugin.ts"],"sourcesContent":["/**\n * @file FileUploaderPlugin.ts\n * @description Renders a sap.ui.unified.FileUploader.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport FileUploader from \"sap/ui/unified/FileUploader\";\nimport Control from \"sap/ui/core/Control\";\nimport LinkControl from \"sap/m/Link\";\n\n/**\n * Handles rendering logic for file uploads.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class FileUploaderPlugin extends BasePlugin {\n /**\n * Renders a `sap.ui.unified.FileUploader` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured FileUploader control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new LinkControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName),\n href: this.generateBindingInfo(bindingPath, modelName), // Assuming the value is a URL to the file\n target: \"_blank\"\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new FileUploader({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Choose a file...\",\n width: \"100%\",\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as any).getParameter(\"newValue\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current file path.\n * @returns {unknown} The file value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as FileUploader).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as FileUploader).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,4KAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA2BF,EAW7BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,GAC5Ce,KAAMZ,KAAKW,oBAAoBf,EAAaC,GAC5CgB,OAAQ,WAEZb,KAAKc,sBAAsBd,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIS,EAAa,CAC5BP,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCoB,MAAOhB,KAAKW,oBAAoBf,EAAaC,GAC7CoB,SAAUtB,EAAcuB,IAAIC,SAC5BC,YAAazB,EAAcuB,IAAIG,OAAS,mBACxCC,MAAO,OACPC,OAASC,IACL,MAAMC,EAAOD,EAAeE,aAAa,YACzC,MAAMC,EAAS3B,KAAK4B,WACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SAAUyB,EAAOG,aACxD,KAIR9B,KAAKc,sBAAsBd,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAMUyB,WACN,OAAO/B,KAAKM,QAAWN,KAAKM,QAAyB0B,YAAY,SAAW,IAChF,CAKUC,aACN,GAAIjC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAAyB4B,YAAYlC,KAAKC,SAASiB,IAAIC,SACjE,CACJ,EACH,IAAAgB,EAAA,CAAAC,WAAA,MAAAD,EAAA1C,qBAAA,OAAA0C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":61,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","GeolocationControl","_interopRequireDefault","__GeolocationControl","GeolocationPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","lat","lng","applyCommonDirectives","value","schemaMetadata","readOnly","ui","attachEvent","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setProperty","__exports","__esModule"],"sources":["GeolocationPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport GeolocationControl from \"../../controls/GeolocationControl\";\nimport TextControl from \"sap/m/Text\";\n\nexport class GeolocationPlugin extends BasePlugin {\n /**\n * Renders a `GeolocationControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured GeolocationControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: Record<string, unknown>) => val && val.lat !== undefined && val.lng !== undefined ? `Lat: ${val.lat}, Lng: ${val.lng}` : \"\"\n })\n });\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new GeolocationControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n });\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n (this.control as GeolocationControl).attachEvent('capture', () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current geolocation object.\n * @returns {unknown} The geolocation value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as GeolocationControl).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,kRAASA,EAAUC,EAAA,oBAGZC,EAAkBC,EAAAC,GAGlB,MAAMC,UAA0BL,EAW5BM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAY,CAC3BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,KAAMR,KAAKS,oBAAoBb,EAAaC,EAAWa,UAAW,CAC9DC,UAAYC,GAAiCA,GAAOA,EAAIC,MAAQH,WAAaE,EAAIE,MAAQJ,UAAY,QAAQE,EAAIC,aAAaD,EAAIE,MAAQ,OAGlJd,KAAKe,sBAAsBf,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAmB,CAClCgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCoB,MAAOhB,KAAKS,oBAAoBb,EAAaC,GAC7CoB,eAAgBtB,EAChBuB,WAAYvB,EAASwB,IAAID,WAG7BlB,KAAKe,sBAAsBf,KAAKI,QAAST,EAAUE,GAElDG,KAAKI,QAA+BgB,YAAY,UAAW,KACxD,MAAMC,EAASrB,KAAKsB,WAChB,GAAItB,KAAKD,SAAU,CACfC,KAAKD,SAASsB,EAAOE,QAASvB,KAAKC,SAAUoB,EAAOG,aACxD,IAGR,OAAOxB,KAAKI,OAChB,CAMUqB,WACN,OAAOzB,KAAKI,QAAWJ,KAAKI,QAA+BsB,YAAY,SAAW,IACtF,CAKUC,aACN,GAAI3B,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCwB,YAAY,aAAc5B,KAAKL,SAASwB,IAAID,SACtF,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAApC,oBAAA,OAAAoC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":62,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","LinkPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","Link","id","generateStableId","text","generateBindingInfo","href","target","applyCommonDirectives","Input","value","type","maxLength","required","change","oEvent","result","validate","isValid","errorMessage","getValue","getMetadata","getName","getProperty","getHref","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["LinkPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Link from \"sap/m/Link\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\n\nexport class LinkPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\");\n \n if (!this.isEditable) {\n this.control = new Link({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName),\n href: this.generateBindingInfo(bindingPath, modelName),\n target: \"_blank\"\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n // Editable mode: user needs to type a URL, so we use an Input configured for URLs\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: \"Url\",\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validate();\n if (this.onChange) this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n \n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n protected getValue(): unknown {\n if (!this.control) return null;\n if (this.control.getMetadata().getName() === \"sap.m.Input\") {\n return (this.control as Input).getProperty('value');\n }\n return (this.control as Link).getHref();\n }\n \n protected applyState(): void {\n if (!this.control || !this.metadata) return;\n if (this.control.getMetadata().getName() === \"sap.m.Input\") {\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,0JAASA,EAAUC,EAAA,cAMZ,MAAMC,UAAmBF,EACrBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAClBJ,KAAKK,QAAU,IAAIC,EAAK,CACpBC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,GAC5Cc,KAAMX,KAAKU,oBAAoBd,EAAaC,GAC5Ce,OAAQ,WAEZZ,KAAKa,sBAAsBb,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAGAL,KAAKK,QAAU,IAAIS,EAAM,CACrBP,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCmB,MAAOf,KAAKU,oBAAoBd,EAAaC,GAC7CmB,KAAM,MACNC,UAAWtB,EAAcsB,WAAa,EACtCC,WAAYvB,EAAcuB,SAC1BC,OAASC,IACL,MAAMC,EAASrB,KAAKsB,WACpB,GAAItB,KAAKD,SAAUC,KAAKD,SAASsB,EAAOE,QAASvB,KAAKE,SAAUmB,EAAOG,iBAI/ExB,KAAKa,sBAAsBb,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEUoB,WACN,IAAKzB,KAAKK,QAAS,OAAO,KAC1B,GAAIL,KAAKK,QAAQqB,cAAcC,YAAc,cAAe,CACxD,OAAQ3B,KAAKK,QAAkBuB,YAAY,QAC/C,CACA,OAAQ5B,KAAKK,QAAiBwB,SAClC,CAEUC,aACN,IAAK9B,KAAKK,UAAYL,KAAKC,SAAU,OACrC,GAAID,KAAKK,QAAQqB,cAAcC,YAAc,cAAe,CACxD,MAAMI,EAAQ/B,KAAKK,QACnB0B,EAAMC,aAAahC,KAAKC,SAASgC,IAAIC,UACrCH,EAAMI,cAAcnC,KAAKC,SAASiB,SACtC,CACJ,EACH,IAAAkB,EAAA,CAAAC,WAAA,MAAAD,EAAA3C,aAAA,OAAA2C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":63,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","MessageStripPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","control","MessageStrip","id","generateStableId","text","generateBindingInfo","type","showIcon","showCloseButton","getValue","applyState","__exports","__esModule"],"sources":["MessageStripPlugin.ts"],"sourcesContent":["/**\n * @file MessageStripPlugin.ts\n * @description Renders a sap.m.MessageStrip for informational text.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MessageStrip from \"sap/m/MessageStrip\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Renders read-only informational alerts within the layout.\n * Does not emit values to the payload.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MessageStripPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MessageStrip` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MessageStrip control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n // Use binding to display text if the field has a value, otherwise use the label\n this.control = new MessageStrip({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName),\n type: \"Information\", // Can be driven by schema arguments in the future\n showIcon: true,\n showCloseButton: false\n });\n\n return this.control as Control;\n }\n\n /**\n * Read-only control, returns null.\n */\n protected getValue(): unknown {\n return null; // Read-only component\n }\n\n /**\n * Read-only control, no dynamic state needed.\n */\n protected applyState(): void {\n // Read-only component, no dynamic state needed currently\n }\n}\n"],"mappings":"AAAA,oJAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA2BF,EAW7BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAGzEI,KAAKK,QAAU,IAAIC,EAAa,CAC5BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,GAC5Cc,KAAM,cACNC,SAAU,KACVC,gBAAiB,QAGrB,OAAOb,KAAKK,OAChB,CAKUS,WACN,OAAO,IACX,CAKUC,aACN,EAEP,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAvB,qBAAA,OAAAuB,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":64,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","UI5_AGGREGATION","____constants_MetaUIConstants","Logger","____utils_Logger","MultiInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","Array","isArray","join","applyCommonDirectives","plugin","mi","MultiInput","enabled","ui","readOnly","placeholder","label","showValueHelp","tokenUpdate","oEvent","type","getParameter","sourceMi","getSource","removedTokens","removedTexts","map","t","getText","bindingInfo","getNativeBindingContext","model","absPath","currentArray","getProperty","newArray","filter","includes","debug","syncTokensToModel","attachSubmit","trim","setValue","addValidator","args","bindAggregation","TOKENS","factory","sId","oContext","getObject","Token","key","binding","getBinding","error","getModel","ctx","getContext","getPath","cp","endsWith","setProperty","refresh","result","validate","isValid","errorMessage","getValue","tokens","getTokens","applyState","setEnabled","__exports","__esModule"],"sources":["MultiInputPlugin.ts"],"sourcesContent":["/**\n * @file MultiInputPlugin.ts\n * @description Renders a sap.m.MultiInput for primitive arrays (e.g. arrays of strings).\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport { UI5_EVENT, UI5_AGGREGATION } from \"../../constants/MetaUIConstants\";\nimport MultiInput from \"sap/m/MultiInput\";\nimport Token from \"sap/m/Token\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport Event from \"sap/ui/base/Event\";\nimport ListBinding from \"sap/ui/model/ListBinding\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * Handles rendering logic for arrays of primitive strings.\n * Users can type custom strings and press Enter to add them as tokens.\n * Adheres strictly to native UI5 Model-View-Controller ListBinding principles.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiInput` component natively bound to a JSONModel array.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n this.modelName = modelName;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n const plugin = this;\n\n const mi = new MultiInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Type and press Enter...\",\n showValueHelp: false, // We don't have a list of options for primitive tags\n tokenUpdate: (oEvent: Event) => {\n const type = (oEvent.getParameter(\"type\") as unknown) as string;\n const sourceMi = oEvent.getSource() as MultiInput;\n \n // Native UI5 tokens removed via the 'x' icon. We sync this directly back to the model.\n if (type === \"removed\") {\n const removedTokens = (oEvent.getParameter(\"removedTokens\") as unknown) as Token[];\n const removedTexts = removedTokens.map(t => t.getText());\n \n const bindingInfo = plugin.getNativeBindingContext(sourceMi);\n if (bindingInfo) {\n const { model, absPath } = bindingInfo;\n const currentArray = (model.getProperty(absPath) || []) as string[];\n const newArray = currentArray.filter(text => !removedTexts.includes(text));\n \n Logger.debug(`[MultiInputPlugin] Removing tokens from absolute path: ${absPath}`, removedTexts.join(\", \"), \"MultiInputPlugin\");\n plugin.syncTokensToModel(sourceMi, newArray);\n }\n }\n }\n });\n\n // The native addValidator pipeline is notoriously unreliable when there is no suggestion list bound,\n // often completely dropping the 'Enter' key event. Therefore, we use the standard `submit` event \n // inherited from InputBase to robustly capture when the user presses Enter.\n if (typeof mi.attachSubmit === \"function\") {\n mi.attachSubmit((oEvent: Event) => {\n const sourceMi = oEvent.getSource() as MultiInput;\n const val = ((oEvent.getParameter(\"value\") as unknown) as string || sourceMi.getProperty('value')).trim();\n \n if (val) {\n const bindingInfo = plugin.getNativeBindingContext(sourceMi);\n if (bindingInfo) {\n const { model, absPath } = bindingInfo;\n const currentArray = (model.getProperty(absPath) || []) as string[];\n \n if (!currentArray.includes(val)) { // Prevent exact duplicates in primitive arrays\n const newArray = [...currentArray, val];\n Logger.debug(`[MultiInputPlugin] submit (Enter) fired. Adding token to absolute path: ${absPath}`, val, \"MultiInputPlugin\");\n \n // Natively clear the text input\n sourceMi.setValue(\"\");\n \n // Synchronize natively to the JSON model\n plugin.syncTokensToModel(sourceMi, newArray);\n } else {\n sourceMi.setValue(\"\");\n }\n }\n }\n });\n }\n\n // We must still register an addValidator returning null.\n // If UI5 *does* sporadically trigger the validator pipeline, this prevents the control \n // from attempting to natively mutate the bound ListBinding aggregation, which causes a core crash.\n mi.addValidator(function(args: { text: string }) {\n return null;\n });\n\n // Bind existing strings to tokens using a factory function\n mi.bindAggregation(UI5_AGGREGATION.TOKENS, this.generateBindingInfo(bindingPath, modelName, undefined, {\n factory: (sId: string, oContext: sap.ui.model.Context) => {\n const text = (oContext.getObject() as string) || \"\";\n return new Token(sId, { key: text, text: text });\n }\n }));\n\n this.control = mi;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Extracts the native UI5 ListBinding, its absolute path, and underlying JSONModel.\n * \n * @param sourceMi The live, cloned MultiInput control instance inside the DOM tree.\n * @returns Object containing model and absolute path, or null if resolution fails.\n */\n private getNativeBindingContext(sourceMi: MultiInput): { model: JSONModel, absPath: string } | null {\n const binding = sourceMi.getBinding(UI5_AGGREGATION.TOKENS) as ListBinding;\n if (!binding) {\n Logger.error(\"[MultiInputPlugin] token list binding is completely missing on the source clone.\");\n return null;\n }\n\n const model = binding.getModel() as JSONModel;\n if (!model) {\n Logger.error(\"[MultiInputPlugin] Failed to resolve underlying JSONModel from ListBinding.\");\n return null;\n }\n\n let absPath: string;\n const ctx = binding.getContext();\n const bindingPath = binding.getPath();\n\n if (ctx) {\n const cp = ctx.getPath();\n absPath = cp.endsWith(\"/\") ? cp + bindingPath : (cp === \"/\" ? \"/\" + bindingPath : cp + \"/\" + bindingPath);\n } else {\n absPath = bindingPath.startsWith(\"/\") ? bindingPath : \"/\" + bindingPath;\n }\n\n return { model, absPath };\n }\n\n /**\n * Synchronizes the primitive string array derived from the MultiInput tokens directly back into the Model.\n * \n * @param sourceMi The live MultiInput clone.\n * @param newArray The final array of string values to save.\n */\n private syncTokensToModel(sourceMi: MultiInput, newArray: string[]): void {\n const bindingInfo = this.getNativeBindingContext(sourceMi);\n if (!bindingInfo) return;\n\n const { model, absPath } = bindingInfo;\n \n model.setProperty(absPath, newArray);\n model.refresh(true); // Force UI5 to sync bindings down the tree\n\n if (this.onChange) {\n const result = this.validate();\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n\n /**\n * Retrieves the current primitive array from the control.\n * @returns {unknown} The array of string tokens.\n */\n protected getValue(): unknown {\n if (!this.control) return [];\n const tokens = (this.control as MultiInput).getTokens();\n return tokens.map(t => t.getText());\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiInput).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":65,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","MultiSelectPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","Array","isArray","join","applyCommonDirectives","mcb","MultiComboBox","selectedKeys","enabled","ui","readOnly","placeholder","label","selectionChange","oEvent","keys","getSelectedKeys","result","validate","isValid","errorMessage","enum","forEach","addItem","Item","key","toString","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["MultiSelectPlugin.ts"],"sourcesContent":["/**\n * @file MultiSelectPlugin.ts\n * @description Renders a sap.m.MultiComboBox for selecting multiple string values.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport MultiComboBox from \"sap/m/MultiComboBox\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for selecting multiple strings from a predefined list.\n * Expects the payload to be an array of strings.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class MultiSelectPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.MultiComboBox` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured MultiComboBox control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: unknown[]) => Array.isArray(val) ? val.join(\", \") : \"\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n const mcb = new MultiComboBox({\n id: this.generateStableId(engineScopeId, bindingPath),\n selectedKeys: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Select items...\",\n selectionChange: (oEvent: sap.ui.base.Event) => {\n const keys = (this.control as MultiComboBox).getSelectedKeys();\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n if (fieldMetadata.enum) {\n fieldMetadata.enum.forEach((val: string | number) => {\n mcb.addItem(new Item({ key: val.toString(), text: val.toString() }));\n });\n }\n\n this.control = mcb;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current selection keys.\n * @returns {unknown} The selected keys.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as MultiComboBox).getSelectedKeys() : [];\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as MultiComboBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,wLAAA,MAKSA,EAAUC,EAAA,cAcZ,MAAMC,UAA0BF,EAW5BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAWe,UAAW,CAC9DC,UAAYC,GAAmBC,MAAMC,QAAQF,GAAOA,EAAIG,KAAK,MAAQ,OAG7EjB,KAAKkB,sBAAsBlB,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEA,MAAMa,EAAM,IAAIC,EAAc,CAC1BZ,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCyB,aAAcrB,KAAKW,oBAAoBf,EAAaC,GACpDyB,SAAU3B,EAAc4B,IAAIC,SAC5BC,YAAa9B,EAAc4B,IAAIG,OAAS,kBACxCC,gBAAkBC,IACd,MAAMC,EAAQ7B,KAAKM,QAA0BwB,kBAC7C,MAAMC,EAAS/B,KAAKgC,WACpB,GAAIhC,KAAKD,SAAU,CACfC,KAAKD,SAASgC,EAAOE,QAASjC,KAAKE,SAAU6B,EAAOG,aACxD,KAIR,GAAIvC,EAAcwC,KAAM,CACpBxC,EAAcwC,KAAKC,QAAStB,IACxBK,EAAIkB,QAAQ,IAAIC,EAAK,CAAEC,IAAKzB,EAAI0B,WAAY9B,KAAMI,EAAI0B,eAE9D,CAEAxC,KAAKM,QAAUa,EACfnB,KAAKkB,sBAAsBlB,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAMUmC,WACN,OAAOzC,KAAKM,QAAWN,KAAKM,QAA0BwB,kBAAoB,EAC9E,CAKUY,aACN,GAAI1C,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAA0BqC,YAAY3C,KAAKC,SAASsB,IAAIC,SAClE,CACJ,EACH,IAAAoB,EAAA,CAAAC,WAAA,MAAAD,EAAAnD,oBAAA,OAAAmD,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":66,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","NumberPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","typeInstance","type","Integer","groupingEnabled","Float","minFractionDigits","scale","undefined","maxFractionDigits","onChangeFn","oEvent","val","getParameter","result","validate","isValid","errorMessage","ui","widget","StepInput","value","path","model","editable","readOnly","required","change","Input","getValue","input","binding","getBinding","getProperty","applyState","setEditable","setRequired","__exports","__esModule"],"sources":["NumberPlugin.ts"],"sourcesContent":["/**\n * @file NumberPlugin.ts\n * @description Renders a sap.m.Input configured for generic dynamic numeric data.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport Float from \"sap/ui/model/type/Float\";\nimport Integer from \"sap/ui/model/type/Integer\";\nimport StepInput from \"sap/m/StepInput\";\n\n/**\n * Handles rendering and logic for dynamic numeric inputs.\n */\nexport class NumberPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Input` component for numeric evaluation with dynamic Float type.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Input control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n let typeInstance;\n if (fieldMetadata.type === \"integer\") {\n typeInstance = new Integer({ groupingEnabled: false });\n } else {\n typeInstance = new Float({\n groupingEnabled: false,\n minFractionDigits: fieldMetadata.scale !== undefined ? fieldMetadata.scale : 0,\n maxFractionDigits: fieldMetadata.scale !== undefined ? fieldMetadata.scale : 9\n });\n }\n\n const onChangeFn = (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as any).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n };\n\n if (fieldMetadata.ui?.widget === \"stepInput\") {\n this.control = new StepInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: {\n path: bindingPath,\n model: modelName,\n type: typeInstance\n },\n editable: !fieldMetadata.ui?.readOnly,\n required: !!fieldMetadata.required,\n change: onChangeFn\n });\n } else {\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: {\n path: bindingPath,\n model: modelName,\n type: typeInstance\n },\n type: \"Number\",\n editable: !fieldMetadata.ui?.readOnly,\n required: !!fieldMetadata.required,\n change: onChangeFn\n });\n }\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current numeric state.\n * @returns {unknown} The numeric value.\n */\n protected getValue(): unknown {\n if (!this.control) return null;\n // In UI5, Input.getProperty('value') returns a string. We must parse it if it's bound.\n // However, we can also extract it directly from the binding.\n const input = this.control as any;\n const binding = input.getBinding(\"value\");\n if (binding && typeof binding.getValue === \"function\") {\n return binding.getValue();\n }\n return input.getProperty('value');\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as any;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,oOAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAClBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEA,IAAIO,EACJ,GAAIlB,EAAcmB,OAAS,UAAW,CAClCD,EAAe,IAAIE,EAAQ,CAAEC,gBAAiB,OAClD,KAAO,CACHH,EAAe,IAAII,EAAM,CACrBD,gBAAiB,MACjBE,kBAAmBvB,EAAcwB,QAAUC,UAAYzB,EAAcwB,MAAQ,EAC7EE,kBAAmB1B,EAAcwB,QAAUC,UAAYzB,EAAcwB,MAAQ,GAErF,CAEA,MAAMG,EAAcC,IAChB,MAAMC,EAAOD,EAAeE,aAAa,SACzC,MAAMC,EAAS1B,KAAK2B,WACpB,GAAI3B,KAAKD,SAAU,CACfC,KAAKD,SAAS2B,EAAOE,QAAS5B,KAAKE,SAAUwB,EAAOG,aACxD,GAGJ,GAAIlC,EAAcmC,IAAIC,SAAW,YAAa,CAC1C/B,KAAKM,QAAU,IAAI0B,EAAU,CACzBxB,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqC,MAAO,CACHC,KAAMtC,EACNuC,MAAOtC,EACPiB,KAAMD,GAEVuB,UAAWzC,EAAcmC,IAAIO,SAC7BC,WAAY3C,EAAc2C,SAC1BC,OAAQjB,GAEhB,KAAO,CACHtB,KAAKM,QAAU,IAAIkC,EAAM,CACrBhC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqC,MAAO,CACHC,KAAMtC,EACNuC,MAAOtC,EACPiB,KAAMD,GAEVC,KAAM,SACNsB,UAAWzC,EAAcmC,IAAIO,SAC7BC,WAAY3C,EAAc2C,SAC1BC,OAAQjB,GAEhB,CAEAtB,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUmC,WACN,IAAKzC,KAAKM,QAAS,OAAO,KAG1B,MAAMoC,EAAQ1C,KAAKM,QACnB,MAAMqC,EAAUD,EAAME,WAAW,SACjC,GAAID,UAAkBA,EAAQF,WAAa,WAAY,CACnD,OAAOE,EAAQF,UACnB,CACA,OAAOC,EAAMG,YAAY,QAC7B,CAKUC,aACN,GAAI9C,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAMqC,EAAQ1C,KAAKM,QACnBoC,EAAMK,aAAa/C,KAAKC,SAAS6B,IAAIO,UACrCK,EAAMM,cAAchD,KAAKC,SAASqC,SACtC,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAAxD,eAAA,OAAAwD,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":67,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","SCHEMA_TYPE","____constants_MetaUIConstants","UI5_EVENT","ObjectPlugin","render","field","bindingPath","modelName","engineScopeId","onChange","this","metadata","propKey","startsWith","substring","subSchema","type","OBJECT","title","ui","label","properties","uiLayout","control","Button","id","generateStableId","text","isEditable","icon","press","oEvent","btn","getSource","parentModel","getModel","bindingContext","getBindingContext","updatePath","ctxPath","getPath","endsWith","nestedData","JSON","parse","stringify","getProperty","sap","require","DynamicHostClass","host","schemaDefinition","data","editable","layoutBudget","attachEvent","SUBMIT","e","payload","getParameter","setProperty","buttonText","dialogButtonText","openInDialog","validate","isValid","getValue","applyState","__exports","__esModule"],"sources":["ObjectPlugin.ts"],"sourcesContent":["/**\n * @file ObjectPlugin.ts\n * @description Renders a button that opens a dialog to edit a nested object structure.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPluginValidationResult } from \"../../interfaces/IPlugin\";\nimport { ISchema, IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport Event from \"sap/ui/base/Event\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport { SCHEMA_TYPE, UI5_EVENT } from \"../../constants/MetaUIConstants\";\n\nexport class ObjectPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Button` to open a nested Object form dialog.\n * \n * @param field The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Button control.\n */\n public render(field: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = field;\n const propKey = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n \n const subSchema: ISchema = {\n type: SCHEMA_TYPE.OBJECT,\n title: field.ui?.label || propKey,\n properties: field.properties || {}\n };\n \n if (field.uiLayout) {\n subSchema.uiLayout = field.uiLayout;\n }\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? \"View Details\" : \"Edit Details\",\n icon: !this.isEditable ? \"sap-icon://display\" : \"sap-icon://form\",\n press: (oEvent: Event) => {\n const btn = oEvent.getSource() as Button;\n const parentModel = btn.getModel(modelName) as JSONModel;\n if (!parentModel) return;\n \n const bindingContext = btn.getBindingContext(modelName);\n let updatePath = bindingPath;\n if (bindingContext && !bindingPath.startsWith(\"/\")) {\n const ctxPath = bindingContext.getPath();\n updatePath = ctxPath.endsWith(\"/\") ? ctxPath + bindingPath : (ctxPath === \"/\" ? \"/\" + bindingPath : ctxPath + \"/\" + bindingPath);\n }\n \n // Deep clone to prevent live-mutations on the parent model before 'Submit' is clicked\n const nestedData = JSON.parse(JSON.stringify(parentModel.getProperty(updatePath) || {}));\n\n sap.ui.require([\"nz/co/siliconst/ui5/metaui/controls/DynamicHost\"], (DynamicHostClass: typeof import(\"../../controls/DynamicHost\").default) => {\n const host = new DynamicHostClass({\n schemaDefinition: subSchema,\n data: nestedData,\n editable: this.isEditable,\n layoutBudget: this.metadata?.ui?.layoutBudget || 0\n } as object);\n\n if (!!this.isEditable) {\n host.attachEvent(UI5_EVENT.SUBMIT, (e: Event) => {\n const payload = e.getParameter(\"payload\");\n parentModel.setProperty(updatePath, payload);\n \n // CRITICAL: Notify the parent Engine that this field mutated\n // so it can trigger LiveUpdate syncs and validate!\n if (this.onChange) {\n this.onChange(true, propKey);\n }\n });\n }\n\n const buttonText = field.ui?.dialogButtonText || (!this.isEditable ? \"Close\" : \"OK\");\n host.openInDialog(`Nested Details: ${field.ui?.label || propKey}`, buttonText);\n });\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Validates the object plugin (always true as validation is deferred to the dialog host).\n * @returns {IPluginValidationResult} The validation result.\n */\n public validate(): IPluginValidationResult {\n return { isValid: true };\n }\n\n /**\n * Read-only component for the engine, returns null.\n */\n protected getValue(): null {\n return null;\n }\n\n /**\n * Read-only component, no dynamic state handling needed for the button itself.\n */\n protected applyState(): void {\n // No dynamic state handling needed for the button\n }\n}\n"],"mappings":"AAAA,4KAAA,MAKSA,EAAUC,EAAA,oBAOVC,EAAWC,EAAA,qBAAEC,EAASD,EAAA,aAExB,MAAME,UAAqBL,EAWvBM,OAAOC,EAA2BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAC/GC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChB,MAAMO,EAAUN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,MAAMS,EAAqB,CACvBC,KAAMhB,EAAYiB,OAClBC,MAAOb,EAAMc,IAAIC,OAASR,EAC1BS,WAAYhB,EAAMgB,YAAc,CAAC,GAGrC,GAAIhB,EAAMiB,SAAU,CAChBP,EAAUO,SAAWjB,EAAMiB,QAC/B,CAEAZ,KAAKa,QAAU,IAAIC,EAAO,CACtBC,GAAIf,KAAKgB,iBAAiBlB,EAAeF,GACzCqB,MAAOjB,KAAKkB,WAAa,eAAiB,eAC1CC,MAAOnB,KAAKkB,WAAa,qBAAuB,kBAChDE,MAAQC,IACJ,MAAMC,EAAMD,EAAOE,YACnB,MAAMC,EAAcF,EAAIG,SAAS5B,GACjC,IAAK2B,EAAa,OAElB,MAAME,EAAiBJ,EAAIK,kBAAkB9B,GAC7C,IAAI+B,EAAahC,EACjB,GAAI8B,IAAmB9B,EAAYO,WAAW,KAAM,CAChD,MAAM0B,EAAUH,EAAeI,UAC/BF,EAAaC,EAAQE,SAAS,KAAOF,EAAUjC,EAAeiC,IAAY,IAAM,IAAMjC,EAAciC,EAAU,IAAMjC,CACxH,CAGA,MAAMoC,EAAaC,KAAKC,MAAMD,KAAKE,UAAUX,EAAYY,YAAYR,IAAe,CAAC,IAErFS,IAAI5B,GAAG6B,QAAQ,CAAC,mDAAqDC,IACjE,MAAMC,EAAO,IAAID,EAAiB,CAC9BE,iBAAkBpC,EAClBqC,KAAMV,EACNW,SAAU3C,KAAKkB,WACf0B,aAAc5C,KAAKC,UAAUQ,IAAImC,cAAgB,IAGrD,KAAM5C,KAAKkB,WAAY,CACnBsB,EAAKK,YAAYrD,EAAUsD,OAASC,IAChC,MAAMC,EAAUD,EAAEE,aAAa,WAC/BzB,EAAY0B,YAAYtB,EAAYoB,GAIpC,GAAIhD,KAAKD,SAAU,CACfC,KAAKD,SAAS,KAAMG,EACxB,GAER,CAEA,MAAMiD,EAAaxD,EAAMc,IAAI2C,oBAAsBpD,KAAKkB,WAAa,QAAU,MAC/EsB,EAAKa,aAAa,mBAAmB1D,EAAMc,IAAIC,OAASR,IAAWiD,QAK/E,OAAOnD,KAAKa,OAChB,CAMOyC,WACH,MAAO,CAAEC,QAAS,KACtB,CAKUC,WACN,OAAO,IACX,CAKUC,aACN,EAEP,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAjE,eAAA,OAAAiE,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":68,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","PasswordPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","applyCommonDirectives","Input","value","generateBindingInfo","type","maxLength","required","change","oEvent","result","validate","isValid","errorMessage","getValue","getMetadata","getName","getProperty","applyState","input","setEditable","ui","readOnly","setRequired","__exports","__esModule"],"sources":["PasswordPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\nexport class PasswordPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\");\n \n if (!this.isEditable) {\n // Password in read-only should be masked natively\n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: \"********\" \n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n type: \"Password\",\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const result = this.validate();\n if (this.onChange) this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n protected getValue(): unknown {\n return this.control && this.control.getMetadata().getName() === \"sap.m.Input\" ? (this.control as Input).getProperty('value') : null;\n }\n\n protected applyState(): void {\n if (!this.control || !this.metadata || this.control.getMetadata().getName() !== \"sap.m.Input\") return;\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n}\n"],"mappings":"AAAA,8JAASA,EAAUC,EAAA,cAMZ,MAAMC,UAAuBF,EACzBG,OAAOC,EAAkCC,EAAqBC,EAAoB,OAAQC,EAAwBC,GACrHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAElBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAM,aAEVT,KAAKU,sBAAsBV,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIM,EAAM,CACrBJ,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCgB,MAAOZ,KAAKa,oBAAoBjB,EAAaC,GAC7CiB,KAAM,WACNC,UAAWpB,EAAcoB,WAAa,EACtCC,WAAYrB,EAAcqB,SAC1BC,OAASC,IACL,MAAMC,EAASnB,KAAKoB,WACpB,GAAIpB,KAAKD,SAAUC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKE,SAAUiB,EAAOG,iBAI/EtB,KAAKU,sBAAsBV,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEUkB,WACN,OAAOvB,KAAKK,SAAWL,KAAKK,QAAQmB,cAAcC,YAAc,cAAiBzB,KAAKK,QAAkBqB,YAAY,SAAW,IACnI,CAEUC,aACN,IAAK3B,KAAKK,UAAYL,KAAKC,UAAYD,KAAKK,QAAQmB,cAAcC,YAAc,cAAe,OAC/F,MAAMG,EAAQ5B,KAAKK,QACnBuB,EAAMC,aAAa7B,KAAKC,SAAS6B,IAAIC,UACrCH,EAAMI,cAAchC,KAAKC,SAASe,SACtC,EACH,IAAAiB,EAAA,CAAAC,WAAA,MAAAD,EAAAxC,iBAAA,OAAAwC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":69,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","RatingIndicatorPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","RatingIndicator","value","enabled","ui","readOnly","maxValue","maximum","undefined","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setEnabled","__exports","__esModule"],"sources":["RatingIndicatorPlugin.ts"],"sourcesContent":["/**\n * @file RatingIndicatorPlugin.ts\n * @description Renders a sap.m.RatingIndicator for 1-5 numeric feedback.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport RatingIndicator from \"sap/m/RatingIndicator\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for rating feedback.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class RatingIndicatorPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.RatingIndicator` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured RatingIndicator control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n \n this.control = new RatingIndicator({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n maxValue: fieldMetadata.maximum !== undefined ? fieldMetadata.maximum : 5,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as any).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current rating value.\n * @returns {unknown} The rating value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as RatingIndicator).getProperty('value') : 0;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as RatingIndicator).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,yKAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAA8BF,EAWhCG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIO,EAAgB,CAC/BL,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCkB,MAAOd,KAAKW,oBAAoBf,EAAaC,GAC7CkB,SAAUpB,EAAcqB,IAAIC,SAC5BC,SAAUvB,EAAcwB,UAAYC,UAAYzB,EAAcwB,QAAU,EACxEE,OAASC,IACL,MAAMC,EAAOD,EAAeE,aAAa,SACzC,MAAMC,EAASzB,KAAK0B,WACpB,GAAI1B,KAAKD,SAAU,CACfC,KAAKD,SAAS0B,EAAOE,QAAS3B,KAAKE,SAAUuB,EAAOG,aACxD,KAIR5B,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUuB,WACN,OAAO7B,KAAKM,QAAWN,KAAKM,QAA4BwB,YAAY,SAAW,CACnF,CAKUC,aACN,GAAI/B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAA4B0B,YAAYhC,KAAKC,SAASe,IAAIC,SACpE,CACJ,EACH,IAAAgB,EAAA,CAAAC,WAAA,MAAAD,EAAAxC,wBAAA,OAAAwC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":70,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","UI5_EVENT","____constants_MetaUIConstants","GlobalPipeline","____core_PipelineManager","Logger","____utils_Logger","ReferencePlugin","_asHost","control","host","getSchemaDefinition","findParentHost","parent","getParent","this","render","field","bindingPath","modelName","engineScopeId","onChange","metadata","propKey","startsWith","substring","label","ui","Button","id","generateStableId","text","isEditable","icon","press","oEvent","btn","getSource","$ref","error","rawParentHost","parentHost","subSchema","keys","Object","getProperty","join","parentModel","getModel","bindingContext","getBindingContext","updatePath","ctxPath","getPath","endsWith","rawData","nestedData","JSON","parse","stringify","sap","require","DynamicHostModule","DynamicHostClass","default","schemaDefinition","schemaDefinitions","data","editable","useMessageManager","attachEvent","e","fireEvent","getParameters","SUBMIT","payload","getParameter","setProperty","buttonText","dialogButtonText","openInDialog","undefined","message","validate","isValid","properties","getAbsoluteBindingPath","key","propMeta","val","required","errMsg","setVisualValidationState","errorMessage","validatorsToRun","argsMap","maxLength","push","minLength","pattern","regex","minimum","maximum","min","max","format","length","res","executeValidation","getValue","applyState","setEnabled","readOnly","__exports","__esModule"],"sources":["ReferencePlugin.ts"],"sourcesContent":["/**\n * @file ReferencePlugin.ts\n * @description Renders a button that lazily loads a referenced schema definition from the global dictionary\n * and opens it in a nested dialog. Implements headless validation for the deferred schema.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPluginValidationResult } from \"../../interfaces/IPlugin\";\nimport { UI5_EVENT, UI5_AGGREGATION } from \"../../constants/MetaUIConstants\";\nimport { ISchema, IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport Event from \"sap/ui/base/Event\";\nimport Button from \"sap/m/Button\";\nimport JSONModel from \"sap/ui/model/json/JSONModel\";\nimport { GlobalPipeline } from \"../../core/PipelineManager\";\nimport { Logger } from \"../../utils/Logger\";\n\nexport class ReferencePlugin extends BasePlugin {\n /**\n * Interface for the duck-typed parent GeneratorHost.\n */\n private _asHost(control: Control): { getSchemaDefinition(ref: string): ISchema; getProperty(name: string): unknown; fireEvent(name: string, params?: unknown): void; } | null {\n const host = control as unknown as { getSchemaDefinition?: Function; getProperty?: Function; fireEvent?: Function; };\n if (typeof host.getSchemaDefinition === \"function\") {\n return host as { getSchemaDefinition(ref: string): ISchema; getProperty(name: string): unknown; fireEvent(name: string, params?: unknown): void; };\n }\n return null;\n }\n\n /**\n * Finds the closest GeneratorHost in the control hierarchy.\n */\n private findParentHost(control: Control): unknown {\n let parent = control.getParent();\n while (parent) {\n if (this._asHost(parent)) {\n return parent;\n }\n parent = parent.getParent();\n }\n return null;\n }\n\n public render(field: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = field;\n const propKey = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n const label = field.ui?.label || propKey;\n\n this.control = new Button({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: !this.isEditable ? `View Link: ${label}` : `Edit Link: ${label}`,\n icon: \"sap-icon://chain-link\",\n press: (oEvent: Event) => {\n const btn = oEvent.getSource() as Button;\n if (!this.metadata?.$ref) {\n Logger.error(`[ReferencePlugin] FATAL: this.metadata.$ref is MISSING or UNDEFINED! Cannot resolve child schema.`);\n return;\n }\n \n const rawParentHost = this.findParentHost(btn) as Control;\n const parentHost = rawParentHost ? this._asHost(rawParentHost) : null;\n if (!parentHost) {\n Logger.error(\"[ReferencePlugin] FATAL: Could not locate parent GeneratorHost via duck typing `getSchemaDefinition`.\");\n return;\n }\n\n const subSchema = parentHost.getSchemaDefinition(this.metadata.$ref);\n if (!subSchema) {\n const keys = Object.keys(parentHost.getProperty(\"schemaDefinitions\") || {});\n Logger.error(`[ReferencePlugin] FATAL: Schema definition not found for reference: ${this.metadata.$ref}. Dumping parent schemaDefinitions keys: ${keys.join(\", \")}`);\n return;\n }\n\n const parentModel = btn.getModel(modelName) as JSONModel;\n if (!parentModel) {\n Logger.error(`[ReferencePlugin] FATAL: Could not get JSONModel named '${modelName}' from the button.`);\n return;\n }\n \n const bindingContext = btn.getBindingContext(modelName);\n let updatePath = bindingPath;\n if (bindingContext && !bindingPath.startsWith(\"/\")) {\n const ctxPath = bindingContext.getPath();\n updatePath = ctxPath.endsWith(\"/\") ? ctxPath + bindingPath : (ctxPath === \"/\" ? \"/\" + bindingPath : ctxPath + \"/\" + bindingPath);\n }\n \n const rawData = parentModel.getProperty(updatePath);\n const nestedData = rawData ? JSON.parse(JSON.stringify(rawData)) : {};\n\n sap.ui.require([\"nz/co/siliconst/ui5/metaui/controls/DynamicHost\"], (DynamicHostModule: unknown) => {\n const DynamicHostClass = (DynamicHostModule as any).default || DynamicHostModule;\n const host = new DynamicHostClass({\n schemaDefinition: subSchema,\n schemaDefinitions: parentHost.getProperty(\"schemaDefinitions\"), // Pass the dictionary down\n data: nestedData,\n editable: this.isEditable,\n useMessageManager: this.useMessageManager\n });\n\n // Event Piping: Bubble validation events up to the parent host\n host.attachEvent(\"validationError\", (e: Event) => {\n parentHost.fireEvent(\"validationError\", e.getParameters());\n });\n host.attachEvent(\"validationSuccess\", (e: Event) => {\n parentHost.fireEvent(\"validationSuccess\", e.getParameters());\n });\n\n if (!!this.isEditable) {\n host.attachEvent(UI5_EVENT.SUBMIT, (e: Event) => {\n const payload = (e.getParameter(\"payload\") as unknown);\n parentModel.setProperty(updatePath, payload);\n \n if (this.onChange) {\n this.onChange(true, propKey);\n }\n });\n }\n\n const buttonText = field.ui?.dialogButtonText || (!this.isEditable ? \"Close\" : \"OK\");\n try {\n host.openInDialog(`Nested Link: ${label}`, buttonText, undefined, undefined, btn);\n } catch (e) {\n Logger.error(`[ReferencePlugin] FATAL ERROR CALLING openInDialog:`, (e as Error).message);\n }\n });\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Headless validation: since child controls are not rendered, we manually validate the nested payload against the lazily resolved schema.\n */\n public validate(): IPluginValidationResult {\n if (!this.metadata?.$ref || !this.control) return { isValid: true };\n \n const rawParentHost = this.findParentHost(this.control) as Control;\n const parentHost = rawParentHost ? this._asHost(rawParentHost) : null;\n if (!parentHost) return { isValid: true };\n \n const subSchema = parentHost.getSchemaDefinition(this.metadata.$ref);\n if (!subSchema || !subSchema.properties) return { isValid: true };\n \n const parentModel = this.control.getModel(this.modelName) as JSONModel;\n if (!parentModel) return { isValid: true };\n \n let updatePath = this.getAbsoluteBindingPath();\n \n const nestedData = parentModel.getProperty(updatePath) || {};\n \n // Basic headless validation over the subSchema properties\n for (const key of Object.keys(subSchema.properties)) {\n const propMeta = subSchema.properties[key] as IPropertyMetadata;\n const val = nestedData[key];\n \n if (propMeta.required && (val === undefined || val === null || val === \"\")) {\n const errMsg = `Field '${key}' is required in referenced object.`;\n this.setVisualValidationState(false, errMsg);\n return { isValid: false, errorMessage: errMsg };\n }\n \n const validatorsToRun: string[] = [];\n const argsMap: Record<string, unknown> = {};\n\n if (propMeta.maxLength !== undefined) {\n validatorsToRun.push(\"maxLength\");\n argsMap[\"maxLength\"] = propMeta.maxLength;\n }\n if (propMeta.minLength !== undefined) {\n validatorsToRun.push(\"minLength\");\n argsMap[\"minLength\"] = propMeta.minLength;\n }\n if (propMeta.pattern !== undefined) {\n validatorsToRun.push(\"pattern\");\n argsMap[\"pattern\"] = { regex: propMeta.pattern };\n }\n if (propMeta.minimum !== undefined || propMeta.maximum !== undefined) {\n validatorsToRun.push(\"range\");\n argsMap[\"range\"] = { min: propMeta.minimum, max: propMeta.maximum };\n }\n \n const format = propMeta.ui?.format;\n if (format === \"email\" || format === \"url\" || format === \"iban\") {\n validatorsToRun.push(format);\n }\n \n if (validatorsToRun.length > 0) {\n const res = GlobalPipeline.executeValidation(val, validatorsToRun, argsMap);\n if (!res.isValid) {\n const errMsg = `Field '${key}' in reference: ${res.errorMessage}`;\n this.setVisualValidationState(false, errMsg);\n return { isValid: false, errorMessage: errMsg };\n }\n }\n }\n \n this.setVisualValidationState(true);\n return { isValid: true };\n }\n\n protected getValue(): null {\n return null;\n }\n\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as Button).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":71,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","RichTextControl","_interopRequireDefault","__RichTextControl","isValueAccessor","control","getValue","RichTextPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","FormattedTextControl","id","generateStableId","htmlText","generateBindingInfo","applyCommonDirectives","value","schemaMetadata","readOnly","ui","attachCapture","attachEvent","result","validate","isValid","errorMessage","getProperty","applyState","setProperty","__exports","__esModule"],"sources":["RichTextPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport RichTextControl from \"../../controls/RichTextControl\";\nimport FormattedTextControl from \"sap/m/FormattedText\";\n\ninterface IValueAccessor {\n getValue(): unknown;\n attachCapture?(fn: Function): void;\n}\n\nfunction isValueAccessor(control: unknown): control is IValueAccessor {\n return control !== null && typeof (control as IValueAccessor).getValue === 'function';\n}\n\nexport class RichTextPlugin extends BasePlugin {\n /**\n * Renders a `RichTextControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured RichTextControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new FormattedTextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n htmlText: this.generateBindingInfo(bindingPath, modelName)\n }) as Control;\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new RichTextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n }) as Control;\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n if (isValueAccessor(this.control) && this.control.attachCapture) {\n this.control.attachEvent('capture', () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n }\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current HTML string value.\n * @returns {unknown} The string value.\n */\n protected getValue(): unknown {\n if (isValueAccessor(this.control)) {\n return this.control.getProperty('value');\n }\n return null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,qRAASA,EAAUC,EAAA,oBAGZC,EAAeC,EAAAC,GAQtB,SAASC,EAAgBC,GACrB,OAAOA,IAAY,aAAgBA,EAA2BC,WAAa,UAC/E,CAEO,MAAMC,UAAuBR,EAWzBS,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKT,QAAU,IAAIa,EAAqB,CACpCC,GAAIL,KAAKM,iBAAiBR,EAAeF,GACzCW,SAAUP,KAAKQ,oBAAoBZ,EAAaC,KAEpDG,KAAKS,sBAAsBT,KAAKT,QAASI,EAAUE,GACnD,OAAOG,KAAKT,OAChB,CAEAS,KAAKT,QAAU,IAAIJ,EAAgB,CAC/BkB,GAAIL,KAAKM,iBAAiBR,EAAeF,GACzCc,MAAOV,KAAKQ,oBAAoBZ,EAAaC,GAC7Cc,eAAgBhB,EAChBiB,WAAYjB,EAASkB,IAAID,WAG7BZ,KAAKS,sBAAsBT,KAAKT,QAASI,EAAUE,GAEnD,GAAIP,EAAgBU,KAAKT,UAAYS,KAAKT,QAAQuB,cAAe,CAC7Dd,KAAKT,QAAQwB,YAAY,UAAW,KAChC,MAAMC,EAAShB,KAAKiB,WACpB,GAAIjB,KAAKD,SAAU,CACfC,KAAKD,SAASiB,EAAOE,QAASlB,KAAKC,SAAUe,EAAOG,aACxD,GAER,CAEA,OAAOnB,KAAKT,OAChB,CAMUC,WACN,GAAIF,EAAgBU,KAAKT,SAAU,CAC/B,OAAOS,KAAKT,QAAQ6B,YAAY,QACpC,CACA,OAAO,IACX,CAKUC,aACN,GAAIrB,KAAKT,SAAWS,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKT,QAAgC+B,YAAY,aAActB,KAAKL,SAASkB,IAAID,SACtF,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAA9B,iBAAA,OAAA8B,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":72,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","SignatureControl","_interopRequireDefault","__SignatureControl","SignaturePlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","ImageControl","id","generateStableId","src","generateBindingInfo","width","alt","ui","label","applyCommonDirectives","value","schemaMetadata","readOnly","attachEvent","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setProperty","__exports","__esModule"],"sources":["SignaturePlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport SignatureControl from \"../../controls/SignatureControl\";\nimport ImageControl from \"sap/m/Image\";\n\nexport class SignaturePlugin extends BasePlugin {\n /**\n * Renders a `SignatureControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured SignatureControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new ImageControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n src: this.generateBindingInfo(bindingPath, modelName),\n width: \"400px\",\n alt: metadata.ui?.label || \"Signature\"\n }) as Control;\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new SignatureControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n }) as Control;\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n (this.control as SignatureControl).attachEvent('capture', () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current base64 signature image state.\n * @returns {unknown} The signature image value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as SignatureControl).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,+QAASA,EAAUC,EAAA,oBAGZC,EAAgBC,EAAAC,GAGhB,MAAMC,UAAwBL,EAW1BM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAa,CAC5BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,IAAKR,KAAKS,oBAAoBb,EAAaC,GAC3Ca,MAAO,QACPC,IAAKhB,EAASiB,IAAIC,OAAS,cAE/Bb,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAiB,CAChCgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCmB,MAAOf,KAAKS,oBAAoBb,EAAaC,GAC7CmB,eAAgBrB,EAChBsB,WAAYtB,EAASiB,IAAIK,WAG7BjB,KAAKc,sBAAsBd,KAAKI,QAAST,EAAUE,GAElDG,KAAKI,QAA6Bc,YAAY,UAAW,KACtD,MAAMC,EAASnB,KAAKoB,WAChB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SAAUkB,EAAOG,aACxD,IAGR,OAAOtB,KAAKI,OAChB,CAMUmB,WACN,OAAOvB,KAAKI,QAAWJ,KAAKI,QAA6BoB,YAAY,SAAW,IACpF,CAKUC,aACN,GAAIzB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCsB,YAAY,aAAc1B,KAAKL,SAASiB,IAAIK,SACtF,CACJ,EACH,IAAAU,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,kBAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":73,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","SliderPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","Slider","value","enabled","ui","readOnly","min","minimum","undefined","max","maximum","step","multipleOf","enableTickmarks","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setEnabled","__exports","__esModule"],"sources":["SliderPlugin.ts"],"sourcesContent":["/**\n * @file SliderPlugin.ts\n * @description Renders a sap.m.Slider for picking numbers in a range.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Slider from \"sap/m/Slider\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for numeric sliders.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class SliderPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Slider` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Slider control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Slider({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n min: fieldMetadata.minimum !== undefined ? fieldMetadata.minimum : 0,\n max: fieldMetadata.maximum !== undefined ? fieldMetadata.maximum : 100,\n step: fieldMetadata.multipleOf !== undefined ? fieldMetadata.multipleOf : 1,\n enableTickmarks: true,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current slider value.\n * @returns {unknown} The numeric value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Slider).getProperty('value') : 0;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as Slider).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,uJAAA,MAKSA,EAAUC,EAAA,cAYZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIO,EAAO,CACtBL,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCkB,MAAOd,KAAKW,oBAAoBf,EAAaC,GAC7CkB,SAAUpB,EAAcqB,IAAIC,SAC5BC,IAAKvB,EAAcwB,UAAYC,UAAYzB,EAAcwB,QAAU,EACnEE,IAAK1B,EAAc2B,UAAYF,UAAYzB,EAAc2B,QAAU,IACnEC,KAAM5B,EAAc6B,aAAeJ,UAAYzB,EAAc6B,WAAa,EAC1EC,gBAAiB,KACjBC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,SACvD,MAAMC,EAAS9B,KAAK+B,WACpB,GAAI/B,KAAKD,SAAU,CACfC,KAAKD,SAAS+B,EAAOE,QAAShC,KAAKE,SAAU4B,EAAOG,aACxD,KAIRjC,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMU4B,WACN,OAAOlC,KAAKM,QAAWN,KAAKM,QAAmB6B,YAAY,SAAW,CAC1E,CAKUC,aACN,GAAIpC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACrBL,KAAKM,QAAmB+B,YAAYrC,KAAKC,SAASe,IAAIC,SAC3D,CACJ,EACH,IAAAqB,EAAA,CAAAC,WAAA,MAAAD,EAAA7C,eAAA,OAAA6C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":74,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","StepInputPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","StepInput","value","displayValuePrecision","scale","undefined","type","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","input","setEditable","setRequired","__exports","__esModule"],"sources":["StepInputPlugin.ts"],"sourcesContent":["/**\n * @file StepInputPlugin.ts\n * @description Renders a sap.m.StepInput for numeric data requiring step increments.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport StepInput from \"sap/m/StepInput\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for step-based numeric inputs.\n */\nexport class StepInputPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.StepInput` component for numeric evaluation.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured StepInput control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new StepInput({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n displayValuePrecision: fieldMetadata.scale !== undefined ? fieldMetadata.scale : (fieldMetadata.type === \"integer\" ? 0 : 3),\n editable: !fieldMetadata.ui?.readOnly,\n required: !!fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent.getParameter(\"value\") as unknown) as number;\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current numeric state.\n * @returns {unknown} The numeric value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as StepInput).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as StepInput;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,6JAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAwBF,EAW1BG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,KAEhDG,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIO,EAAU,CACzBL,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCkB,MAAOd,KAAKW,oBAAoBf,EAAaC,GAC7CkB,sBAAuBpB,EAAcqB,QAAUC,UAAYtB,EAAcqB,MAASrB,EAAcuB,OAAS,UAAY,EAAI,EACzHC,UAAWxB,EAAcyB,IAAIC,SAC7BC,WAAY3B,EAAc2B,SAC1BC,OAASC,IACL,MAAMC,EAAOD,EAAOE,aAAa,SACjC,MAAMC,EAAS3B,KAAK4B,WACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SAAUyB,EAAOG,aACxD,KAIR9B,KAAKY,sBAAsBZ,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUyB,WACN,OAAO/B,KAAKM,QAAWN,KAAKM,QAAsB0B,YAAY,SAAW,IAC7E,CAKUC,aACN,GAAIjC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM6B,EAAQlC,KAAKM,QACnB4B,EAAMC,aAAanC,KAAKC,SAASmB,IAAIC,UACrCa,EAAME,cAAcpC,KAAKC,SAASqB,SACtC,CACJ,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAA5C,kBAAA,OAAA4C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":75,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","StringPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","applyCommonDirectives","Input","value","maxLength","required","showValueHelp","ui","widget","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","input","setEditable","readOnly","setRequired","__exports","__esModule"],"sources":["StringPlugin.ts"],"sourcesContent":["/**\n * @file StringPlugin.ts\n * @description Renders a sap.m.Input for string data and validates lengths.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for basic text inputs.\n * Maps schema properties like `maxLength` and `required` natively to `sap.m.Input`.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.controls\n * @public\n */\nexport class StringPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Input` control configured via the provided schema metadata.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Input control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\"); // For EventBus\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName)\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Input({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n showValueHelp: fieldMetadata.ui?.widget === \"searchHelp\",\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current string value from the input.\n * @returns {unknown} The string value.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Input).getProperty('value') : null;\n }\n\n /**\n * Adjusts dynamic state properties (editable/required) based on ConditionEngine mutations.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) {\n // Text doesn't have editable/required state\n return;\n }\n const input = this.control as Input;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,sJAAA,MAKSA,EAAUC,EAAA,cAaZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAEzC,IAAKH,KAAKI,WAAY,CAElBJ,KAAKK,QAAU,IAAIC,EAAY,CAC3BC,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCa,KAAMT,KAAKU,oBAAoBd,EAAaC,KAEhDG,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GACxD,OAAOG,KAAKK,OAChB,CAEAL,KAAKK,QAAU,IAAIO,EAAM,CACrBL,GAAIP,KAAKQ,iBAAiBV,EAAeF,GACzCiB,MAAOb,KAAKU,oBAAoBd,EAAaC,GAC7CiB,UAAWnB,EAAcmB,WAAa,EACtCC,WAAYpB,EAAcoB,SAC1BC,cAAerB,EAAcsB,IAAIC,SAAW,aAC5CC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,SACvD,MAAMC,EAASvB,KAAKwB,WACpB,GAAIxB,KAAKD,SAAU,CACfC,KAAKD,SAASwB,EAAOE,QAASzB,KAAKE,SAAUqB,EAAOG,aACxD,KAIR1B,KAAKW,sBAAsBX,KAAKK,QAASV,EAAeE,GAExD,OAAOG,KAAKK,OAChB,CAMUsB,WACN,OAAO3B,KAAKK,QAAWL,KAAKK,QAAkBuB,YAAY,SAAW,IACzE,CAKUC,aACN,GAAI7B,KAAKK,SAAWL,KAAKC,SAAU,CAC/B,IAAKD,KAAKI,WAAY,CAElB,MACJ,CACA,MAAM0B,EAAQ9B,KAAKK,QACnByB,EAAMC,aAAa/B,KAAKC,SAASgB,IAAIe,UACrCF,EAAMG,YAAYjC,KAAKC,SAASc,SACpC,CACJ,EACH,IAAAmB,EAAA,CAAAC,WAAA,MAAAD,EAAAzC,eAAA,OAAAyC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":76,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","SwitchPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","applyCommonDirectives","Switch","state","enabled","ui","readOnly","change","oEvent","getParameter","result","validate","isValid","errorMessage","getValue","getState","applyState","sw","setEnabled","__exports","__esModule"],"sources":["SwitchPlugin.ts"],"sourcesContent":["/**\n * @file SwitchPlugin.ts\n * @description Renders a sap.m.Switch for boolean data specifically marked with the switch widget.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Switch from \"sap/m/Switch\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering logic for toggleable boolean switches.\n */\nexport class SwitchPlugin extends BasePlugin {\n /**\n * Renders a `sap.m.Switch` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Switch control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: boolean) => val ? \"Yes\" : \"No\"\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new Switch({\n id: this.generateStableId(engineScopeId, bindingPath),\n state: this.generateBindingInfo(bindingPath, modelName),\n enabled: !fieldMetadata.ui?.readOnly,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"state\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current switch state.\n * @returns {unknown} The boolean state.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Switch).getState() : false;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const sw = this.control as Switch;\n sw.setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,uJAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAqBF,EAWvBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAWe,UAAW,CAC9DC,UAAYC,GAAiBA,EAAM,MAAQ,SAGnDd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAO,CACtBR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,GAC7CqB,SAAUvB,EAAcwB,IAAIC,SAC5BC,OAASC,IACL,MAAMR,EAAOQ,EAA6BC,aAAa,SACvD,MAAMC,EAASxB,KAAKyB,WACpB,GAAIzB,KAAKD,SAAU,CACfC,KAAKD,SAASyB,EAAOE,QAAS1B,KAAKE,SAAUsB,EAAOG,aACxD,KAIR3B,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUsB,WACN,OAAO5B,KAAKM,QAAWN,KAAKM,QAAmBuB,WAAa,KAChE,CAKUC,aACN,GAAI9B,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM0B,EAAK/B,KAAKM,QAChByB,EAAGC,YAAYhC,KAAKC,SAASkB,IAAIC,SACrC,CACJ,EACH,IAAAa,EAAA,CAAAC,WAAA,MAAAD,EAAAxC,eAAA,OAAAwC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":77,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","TextAreaPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","replace","schemaRows","ui","rows","useDialog","expandable","textArea","TextArea","id","generateStableId","value","generateBindingInfo","maxLength","required","editable","isEditable","readOnly","growing","growingMaxLines","width","change","result","validate","isValid","errorMessage","textAreaRef","mainControl","expandBtn","Button","icon","type","tooltip","press","dlg","Dialog","title","label","contentWidth","contentHeight","verticalScrolling","resizable","content","height","beginButton","text","close","afterClose","destroy","control","addDependent","open","setLayoutData","FlexItemData","growFactor","HBox","alignItems","items","applyCommonDirectives","getValue","getProperty","applyState","setEditable","setRequired","__exports","__esModule"],"sources":["TextAreaPlugin.ts"],"sourcesContent":["/**\n * @file TextAreaPlugin.ts\n * @description Renders a sap.m.TextArea for string data specifically marked with the textArea widget.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport TextArea from \"sap/m/TextArea\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\nimport HBox from \"sap/m/HBox\";\nimport Button from \"sap/m/Button\";\nimport Dialog from \"sap/m/Dialog\";\nimport FlexItemData from \"sap/m/FlexItemData\";\n\n/**\n * Handles rendering and logic for multi-line text areas.\n */\nexport class TextAreaPlugin extends BasePlugin {\n private textAreaRef?: TextArea;\n \n /**\n * Renders a `sap.m.TextArea` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured TextArea control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.replace(\"/\", \"\"); // For EventBus\n \n\n\n const schemaRows = fieldMetadata.ui?.rows;\n const useDialog = fieldMetadata.ui?.expandable !== false;\n\n const textArea = new TextArea({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n maxLength: fieldMetadata.maxLength || 0,\n required: !!fieldMetadata.required,\n editable: !this.isEditable ? false : !fieldMetadata.ui?.readOnly,\n rows: schemaRows || 10,\n growing: true,\n growingMaxLines: schemaRows || 15,\n width: \"100%\",\n change: () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n this.textAreaRef = textArea;\n this.mainControl = textArea;\n\n if (useDialog) {\n const expandBtn = new Button({\n icon: \"sap-icon://full-screen\",\n type: \"Transparent\",\n tooltip: \"Expand Editor\",\n press: () => {\n const dlg = new Dialog({\n title: fieldMetadata.title || fieldMetadata.ui?.label || \"Edit Text\",\n contentWidth: \"80%\",\n contentHeight: \"80%\",\n verticalScrolling: false,\n resizable: true,\n content: new TextArea({\n value: this.generateBindingInfo(bindingPath, modelName),\n width: \"100%\",\n height: \"100%\",\n editable: !this.isEditable ? false : !fieldMetadata.ui?.readOnly,\n growing: false\n }),\n beginButton: new Button({\n text: \"Close\",\n press: () => dlg.close()\n }),\n afterClose: () => dlg.destroy()\n });\n this.control?.addDependent(dlg);\n dlg.open();\n }\n });\n\n textArea.setLayoutData(new FlexItemData({ growFactor: 1 }));\n\n this.control = new HBox({\n width: \"100%\",\n alignItems: \"Start\",\n items: [textArea, expandBtn]\n });\n } else {\n this.control = textArea;\n }\n\n this.mainControl = textArea;\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n\n\n /**\n * Retrieves the current text string.\n * @returns {unknown} The text string.\n */\n protected getValue(): unknown {\n return this.textAreaRef ? this.textAreaRef.getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.textAreaRef && this.metadata) {\n if (!this.isEditable) return;\n this.textAreaRef.setEditable(!this.metadata.ui?.readOnly);\n this.textAreaRef.setRequired(!!this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,oNAAA,MAKSA,EAAUC,EAAA,cAaZ,MAAMC,UAAuBF,EAazBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,QAAQ,IAAK,IAIzC,MAAMC,EAAaT,EAAcU,IAAIC,KACrC,MAAMC,EAAYZ,EAAcU,IAAIG,aAAe,MAEnD,MAAMC,EAAW,IAAIC,EAAS,CAC1BC,GAAIX,KAAKY,iBAAiBd,EAAeF,GACzCiB,MAAOb,KAAKc,oBAAoBlB,EAAaC,GAC7CkB,UAAWpB,EAAcoB,WAAa,EACtCC,WAAYrB,EAAcqB,SAC1BC,UAAWjB,KAAKkB,WAAa,OAASvB,EAAcU,IAAIc,SACxDb,KAAMF,GAAc,GACpBgB,QAAS,KACTC,gBAAiBjB,GAAc,GAC/BkB,MAAO,OACPC,OAAQA,KACJ,MAAMC,EAASxB,KAAKyB,WACpB,GAAIzB,KAAKD,SAAU,CACfC,KAAKD,SAASyB,EAAOE,QAAS1B,KAAKE,SAAUsB,EAAOG,aACxD,KAGR3B,KAAK4B,YAAcnB,EACnBT,KAAK6B,YAAcpB,EAEnB,GAAIF,EAAW,CACX,MAAMuB,EAAY,IAAIC,EAAO,CACzBC,KAAM,yBACNC,KAAM,cACNC,QAAS,gBACTC,MAAOA,KACH,MAAMC,EAAM,IAAIC,EAAO,CACnBC,MAAO3C,EAAc2C,OAAS3C,EAAcU,IAAIkC,OAAS,YACzDC,aAAc,MACdC,cAAe,MACfC,kBAAmB,MACnBC,UAAW,KACXC,QAAS,IAAIlC,EAAS,CAClBG,MAAOb,KAAKc,oBAAoBlB,EAAaC,GAC7CyB,MAAO,OACPuB,OAAQ,OACR5B,UAAWjB,KAAKkB,WAAa,OAASvB,EAAcU,IAAIc,SACxDC,QAAS,QAEb0B,YAAa,IAAIf,EAAO,CACpBgB,KAAM,QACNZ,MAAOA,IAAMC,EAAIY,UAErBC,WAAYA,IAAMb,EAAIc,YAE1BlD,KAAKmD,SAASC,aAAahB,GAC3BA,EAAIiB,UAIZ5C,EAAS6C,cAAc,IAAIC,EAAa,CAAEC,WAAY,KAEtDxD,KAAKmD,QAAU,IAAIM,EAAK,CACpBnC,MAAO,OACPoC,WAAY,QACZC,MAAO,CAAClD,EAAUqB,IAE1B,KAAO,CACH9B,KAAKmD,QAAU1C,CACnB,CAEAT,KAAK6B,YAAcpB,EACnBT,KAAK4D,sBAAsB5D,KAAKmD,QAASxD,EAAeE,GAExD,OAAOG,KAAKmD,OAChB,CAQUU,WACN,OAAO7D,KAAK4B,YAAc5B,KAAK4B,YAAYkC,YAAY,SAAW,IACtE,CAKUC,aACN,GAAI/D,KAAK4B,aAAe5B,KAAKC,SAAU,CACnC,IAAKD,KAAKkB,WAAY,OACtBlB,KAAK4B,YAAYoC,aAAahE,KAAKC,SAASI,IAAIc,UAChDnB,KAAK4B,YAAYqC,cAAcjE,KAAKC,SAASe,SACjD,CACJ,EACH,IAAAkD,EAAA,CAAAC,WAAA,MAAAD,EAAAzE,iBAAA,OAAAyE,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":78,"column":0},"map":{"version":3,"names":["BasePlugin","___BasePlugin","TimePlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","fieldKey","startsWith","substring","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","formatOptions","source","pattern","applyCommonDirectives","TimePicker","value","displayFormat","editable","ui","readOnly","required","change","oEvent","val","getParameter","result","validate","isValid","errorMessage","getValue","getProperty","applyState","input","setEditable","setRequired","__exports","__esModule"],"sources":["TimePlugin.ts"],"sourcesContent":["/**\n * @file TimePlugin.ts\n * @description Handles rendering logic for Time strings.\n */\n\nimport { BasePlugin } from \"./BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport TimePicker from \"sap/m/TimePicker\";\nimport Control from \"sap/ui/core/Control\";\nimport TextControl from \"sap/m/Text\";\n\n/**\n * Handles rendering and logic for time inputs.\n */\nexport class TimePlugin extends BasePlugin {\n /**\n * Renders a `sap.m.TimePicker` component.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured TimePicker control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n this.fieldKey = bindingPath.startsWith('/') ? bindingPath.substring(1) : bindingPath;\n \n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Time\", {\n formatOptions: {\n source: { pattern: \"HH:mm:ss\" },\n pattern: \"HH:mm:ss\"\n }\n })\n });\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n this.control = new TimePicker({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName, \"sap.ui.model.type.Time\", {\n formatOptions: {\n source: { pattern: \"HH:mm:ss\" },\n pattern: \"HH:mm:ss\"\n }\n }),\n displayFormat: \"HH:mm:ss\",\n editable: !fieldMetadata.ui?.readOnly,\n required: fieldMetadata.required,\n change: (oEvent: sap.ui.base.Event) => {\n const val = (oEvent as sap.ui.base.Event).getParameter(\"value\");\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n }\n });\n\n this.applyCommonDirectives(this.control, fieldMetadata, modelName);\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current time string.\n * @returns {unknown} The time string.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as TimePicker).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const input = this.control as TimePicker;\n input.setEditable(!this.metadata.ui?.readOnly);\n input.setRequired(this.metadata.required);\n }\n }\n}\n"],"mappings":"AAAA,yJAAA,MAKSA,EAAUC,EAAA,cASZ,MAAMC,UAAmBF,EAWrBG,OAAOC,EAAmCC,EAAsBC,EAAoB,OAAQC,EAAwBC,GACvHC,KAAKD,SAAWA,EAChBC,KAAKC,SAAWN,EAChBK,KAAKE,SAAWN,EAAYO,WAAW,KAAOP,EAAYQ,UAAU,GAAKR,EAEzE,IAAKI,KAAKK,WAAY,CAElBL,KAAKM,QAAU,IAAIC,EAAY,CAC3BC,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCc,KAAMV,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC7Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,YACnBA,QAAS,gBAIrBd,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GACxD,OAAOG,KAAKM,OAChB,CAEAN,KAAKM,QAAU,IAAIU,EAAW,CAC1BR,GAAIR,KAAKS,iBAAiBX,EAAeF,GACzCqB,MAAOjB,KAAKW,oBAAoBf,EAAaC,EAAW,yBAA0B,CAC9Ee,cAAe,CACXC,OAAQ,CAAEC,QAAS,YACnBA,QAAS,cAGjBI,cAAe,WACfC,UAAWxB,EAAcyB,IAAIC,SAC7BC,SAAU3B,EAAc2B,SACxBC,OAASC,IACL,MAAMC,EAAOD,EAA6BE,aAAa,SACvD,MAAMC,EAAS3B,KAAK4B,WACpB,GAAI5B,KAAKD,SAAU,CACfC,KAAKD,SAAS4B,EAAOE,QAAS7B,KAAKE,SAAUyB,EAAOG,aACxD,KAIR9B,KAAKe,sBAAsBf,KAAKM,QAASX,EAAeE,GAExD,OAAOG,KAAKM,OAChB,CAMUyB,WACN,OAAO/B,KAAKM,QAAWN,KAAKM,QAAuB0B,YAAY,SAAW,IAC9E,CAKUC,aACN,GAAIjC,KAAKM,SAAWN,KAAKC,SAAU,CAC/B,IAAKD,KAAKK,WAAY,OACtB,MAAM6B,EAAQlC,KAAKM,QACnB4B,EAAMC,aAAanC,KAAKC,SAASmB,IAAIC,UACrCa,EAAME,YAAYpC,KAAKC,SAASqB,SACpC,CACJ,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAA5C,aAAA,OAAA4C,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":79,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","VoiceInputControl","_interopRequireDefault","__VoiceInputControl","VoiceInputPlugin","render","metadata","bindingPath","modelName","engineScopeId","onChange","this","fieldKey","replace","isEditable","control","TextControl","id","generateStableId","text","generateBindingInfo","undefined","formatter","val","applyCommonDirectives","value","schemaMetadata","readOnly","ui","attachEvent","result","validate","isValid","errorMessage","getValue","getProperty","applyState","setProperty","__exports","__esModule"],"sources":["VoiceInputPlugin.ts"],"sourcesContent":["import { BasePlugin } from \"../controls/BasePlugin\";\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport Control from \"sap/ui/core/Control\";\nimport VoiceInputControl from \"../../controls/VoiceInputControl\";\nimport TextControl from \"sap/m/Text\";\n\nexport class VoiceInputPlugin extends BasePlugin {\n /**\n * Renders a `VoiceInputControl` component.\n * \n * @param metadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured VoiceInputControl.\n */\n public render(metadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = metadata;\n this.fieldKey = bindingPath.replace('/', '');\n this.modelName = modelName;\n\n if (!this.isEditable) {\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: this.generateBindingInfo(bindingPath, modelName, undefined, {\n formatter: (val: unknown) => {\n if (!val || val === \"undefined\" || val === \"null\") return \"\";\n return val;\n }\n })\n }) as Control;\n this.applyCommonDirectives(this.control, metadata, modelName);\n return this.control as Control;\n }\n\n this.control = new VoiceInputControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n value: this.generateBindingInfo(bindingPath, modelName),\n schemaMetadata: metadata,\n readOnly: !!metadata.ui?.readOnly\n }) as Control;\n\n this.applyCommonDirectives(this.control, metadata, modelName);\n\n (this.control as VoiceInputControl).attachEvent('capture', () => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage);\n }\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current voice transcription text.\n * @returns {unknown} The text string.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as VoiceInputControl).getProperty('value') : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n (this.control as sap.ui.core.Control).setProperty(\"readOnly\", !!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,gRAASA,EAAUC,EAAA,oBAGZC,EAAiBC,EAAAC,GAGjB,MAAMC,UAAyBL,EAW3BM,OAAOC,EAA8BC,EAAsBC,EAAoB,OAAQC,EAAwBC,GAClHC,KAAKD,SAAWA,EAChBC,KAAKL,SAAWA,EAChBK,KAAKC,SAAWL,EAAYM,QAAQ,IAAK,IACzCF,KAAKH,UAAYA,EAEjB,IAAKG,KAAKG,WAAY,CAElBH,KAAKI,QAAU,IAAIC,EAAY,CAC3BC,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCY,KAAMR,KAAKS,oBAAoBb,EAAaC,EAAWa,UAAW,CAC9DC,UAAYC,IACR,IAAKA,GAAOA,IAAQ,aAAeA,IAAQ,OAAQ,MAAO,GAC1D,OAAOA,OAInBZ,KAAKa,sBAAsBb,KAAKI,QAAST,EAAUE,GACnD,OAAOG,KAAKI,OAChB,CAEAJ,KAAKI,QAAU,IAAId,EAAkB,CACjCgB,GAAIN,KAAKO,iBAAiBT,EAAeF,GACzCkB,MAAOd,KAAKS,oBAAoBb,EAAaC,GAC7CkB,eAAgBpB,EAChBqB,WAAYrB,EAASsB,IAAID,WAG7BhB,KAAKa,sBAAsBb,KAAKI,QAAST,EAAUE,GAElDG,KAAKI,QAA8Bc,YAAY,UAAW,KACvD,MAAMC,EAASnB,KAAKoB,WAChB,GAAIpB,KAAKD,SAAU,CACfC,KAAKD,SAASoB,EAAOE,QAASrB,KAAKC,SAAUkB,EAAOG,aACxD,IAGR,OAAOtB,KAAKI,OAChB,CAMUmB,WACN,OAAOvB,KAAKI,QAAWJ,KAAKI,QAA8BoB,YAAY,SAAW,IACrF,CAKUC,aACN,GAAIzB,KAAKI,SAAWJ,KAAKL,SAAU,CAC/B,IAAKK,KAAKG,WAAY,OACrBH,KAAKI,QAAgCsB,YAAY,aAAc1B,KAAKL,SAASsB,IAAID,SACtF,CACJ,EACH,IAAAW,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,mBAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"plugins/controls"}},{"offset":{"line":80,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","Logger","____utils_Logger","LiveSearchPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","input","Input","value","enabled","ui","readOnly","placeholder","showSuggestion","suggest","oEvent","query","getParameter","fetchSuggestions","change","validate","control","vhConfig","valueHelp","url","error","removeAllSuggestionItems","setBusy","fetch","then","res","json","data","keyPath","textPath","lowerQuery","toLowerCase","filteredData","filter","item","textValue","String","includes","forEach","itemData","addSuggestionItem","Item","key","text","catch","err","message","finally","getValue","applyState","setEnabled","__exports","__esModule"],"sources":["LiveSearchPlugin.ts"],"sourcesContent":["/**\n * @file LiveSearchPlugin.ts\n * @description A custom datasource plugin that provides asynchronous live search (autocomplete) functionality.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport Event from \"sap/ui/base/Event\";\n\nimport { IPropertyMetadata, IRemoteValueHelpConfig } from \"../../interfaces/ISchema\";\nimport Input from \"sap/m/Input\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * A custom datasource plugin that provides asynchronous live search (autocomplete) functionality.\n * As the user types, it fetches suggestions from a remote endpoint.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class LiveSearchPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n const input = new Input({\n value: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: \"Type to search...\",\n showSuggestion: true,\n suggest: (oEvent: Event) => {\n const query = (oEvent as Event).getParameter(\"suggestValue\");\n this.fetchSuggestions(input, query);\n },\n change: (oEvent: Event) => {\n this.validate();\n }\n });\n\n this.control = input;\n return this.control as Control;\n }\n\n /**\n * Executes the REST fetch for suggestions based on a query. Can be overridden by mock subclasses.\n * @param input The UI5 Input to populate with suggestions.\n * @param query The text typed by the user.\n */\n protected fetchSuggestions(input: Input, query: string): void {\n const vhConfig = this.metadata?.valueHelp as IRemoteValueHelpConfig;\n if (!vhConfig || !vhConfig.url) {\n Logger.error(\"LiveSearchPlugin requires a valid valueHelp configuration with a URL.\", \"\", \"LiveSearchPlugin\");\n return;\n }\n\n if (!query) {\n input.removeAllSuggestionItems();\n return;\n }\n \n input.setBusy(true);\n \n // In a real application, the query parameter would be passed to the backend (e.g. ?q=query)\n // Here, we simulate fetching and filter locally, but subclasses can override this entirely.\n fetch(vhConfig.url)\n .then(res => res.json())\n .then((data: Record<string, unknown>[]) => {\n const keyPath = vhConfig.keyPath || \"key\";\n const textPath = vhConfig.textPath || \"text\";\n \n input.removeAllSuggestionItems();\n\n // Simple client-side filter for demonstration\n const lowerQuery = query.toLowerCase();\n const filteredData = data.filter(item => {\n const textValue = String(item[textPath] || item[keyPath]).toLowerCase();\n return textValue.includes(lowerQuery);\n });\n \n filteredData.forEach(itemData => {\n input.addSuggestionItem(new Item({ \n key: String(itemData[keyPath]), \n text: String(itemData[textPath] || itemData[keyPath])\n }));\n });\n })\n .catch(err => {\n Logger.error(\"Failed to load value help from \" + vhConfig.url, err.message, \"LiveSearchPlugin\");\n })\n .finally(() => {\n input.setBusy(false);\n });\n }\n\n /**\n * Retrieves the current input value.\n * @returns {unknown} The input text.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as Input).getValue() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as Input).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,oMAAA,MAKSA,EAAUC,EAAA,oBAOVC,EAAMC,EAAA,UASR,MAAMC,UAAyBJ,EAC3BK,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,MAAMK,EAAQ,IAAIC,EAAM,CACpBC,MAAO,IAAIL,KAAaD,KACxBO,SAAUR,EAAcS,IAAIC,SAC5BC,YAAa,oBACbC,eAAgB,KAChBC,QAAUC,IACN,MAAMC,EAASD,EAAiBE,aAAa,gBAC7Cb,KAAKc,iBAAiBZ,EAAOU,IAEjCG,OAASJ,IACLX,KAAKgB,cAIbhB,KAAKiB,QAAUf,EACf,OAAOF,KAAKiB,OAChB,CAOUH,iBAAiBZ,EAAcU,GACrC,MAAMM,EAAWlB,KAAKC,UAAUkB,UAChC,IAAKD,IAAaA,EAASE,IAAK,CAC5B3B,EAAO4B,MAAM,wEAAyE,GAAI,oBAC1F,MACJ,CAEA,IAAKT,EAAO,CACRV,EAAMoB,2BACN,MACJ,CAEApB,EAAMqB,QAAQ,MAIdC,MAAMN,EAASE,KACVK,KAAKC,GAAOA,EAAIC,QAChBF,KAAMG,IACH,MAAMC,EAAUX,EAASW,SAAW,MACpC,MAAMC,EAAWZ,EAASY,UAAY,OAEtC5B,EAAMoB,2BAGN,MAAMS,EAAanB,EAAMoB,cACzB,MAAMC,EAAeL,EAAKM,OAAOC,IAC7B,MAAMC,EAAYC,OAAOF,EAAKL,IAAaK,EAAKN,IAAUG,cAC1D,OAAOI,EAAUE,SAASP,KAG9BE,EAAaM,QAAQC,IACjBtC,EAAMuC,kBAAkB,IAAIC,EAAK,CAC7BC,IAAKN,OAAOG,EAASX,IACrBe,KAAMP,OAAOG,EAASV,IAAaU,EAASX,WAIvDgB,MAAMC,IACHrD,EAAO4B,MAAM,kCAAoCH,EAASE,IAAK0B,EAAIC,QAAS,sBAE/EC,QAAQ,KACL9C,EAAMqB,QAAQ,QAE1B,CAMU0B,WACN,OAAOjD,KAAKiB,QAAWjB,KAAKiB,QAAkBgC,WAAa,IAC/D,CAKUC,aACN,GAAIlD,KAAKiB,SAAWjB,KAAKC,SAAU,CAC9BD,KAAKiB,QAAkBkC,YAAYnD,KAAKC,SAASK,IAAIC,SAC1D,CACJ,EACH,IAAA6C,EAAA,CAAAC,WAAA,MAAAD,EAAAzD,mBAAA,OAAAyD,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":81,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","ODataListBindingPlugin","render","fieldMetadata","bindingPath","modelName","this","metadata","args","ui","path","key","text","control","ComboBox","selectedKey","enabled","readOnly","placeholder","label","change","oEvent","selectedItem","getParameter","val","getKey","validate","bindAggregation","template","Item","templateShareable","getValue","getSelectedKey","applyState","setEnabled","__exports","__esModule"],"sources":["ODataListBindingPlugin.ts"],"sourcesContent":["/**\n * @file ODataListBindingPlugin.ts\n * @description A custom datasource plugin that binds a ComboBox to an OData EntitySet.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport Event from \"sap/ui/base/Event\";\n\nimport { IPropertyMetadata } from \"../../interfaces/ISchema\";\nimport ComboBox from \"sap/m/ComboBox\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\n\n/**\n * Renders a ComboBox natively bound to an OData Model entity set.\n * Expects args: { path: \"/Categories\", key: \"ID\", text: \"Name\" }\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class ODataListBindingPlugin extends BasePlugin {\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n const args = (fieldMetadata.ui?.args as Record<string, string>) || { path: \"/\", key: \"ID\", text: \"Name\" };\n \n this.control = new ComboBox({\n selectedKey: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: fieldMetadata.ui?.label || \"Select...\",\n change: (oEvent: Event) => {\n const selectedItem = (oEvent.getParameter(\"selectedItem\") as unknown) as Item;\n const val = selectedItem?.getKey();\n this.validate();\n }\n });\n\n // Natively bind aggregation to the default model (OData)\n (this.control as ComboBox).bindAggregation(\"items\", {\n path: args.path,\n template: new Item({\n key: `{${args.key}}`,\n text: `{${args.text}}`\n }),\n templateShareable: false\n });\n\n return this.control as Control;\n }\n\n /**\n * Retrieves the current selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as ComboBox).getSelectedKey() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as ComboBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,sLAAA,MAKSA,EAAUC,EAAA,cAeZ,MAAMC,UAA+BF,EACjCG,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,MAAMK,EAAQL,EAAcM,IAAID,MAAmC,CAAEE,KAAM,IAAKC,IAAK,KAAMC,KAAM,QAEjGN,KAAKO,QAAU,IAAIC,EAAS,CACxBC,YAAa,IAAIV,KAAaD,KAC9BY,SAAUb,EAAcM,IAAIQ,SAC5BC,YAAaf,EAAcM,IAAIU,OAAS,YACxCC,OAASC,IACL,MAAMC,EAAgBD,EAAOE,aAAa,gBAC1C,MAAMC,EAAMF,GAAcG,SAC1BnB,KAAKoB,cAKZpB,KAAKO,QAAqBc,gBAAgB,QAAS,CAChDjB,KAAMF,EAAKE,KACXkB,SAAU,IAAIC,EAAK,CACflB,IAAK,IAAIH,EAAKG,OACdC,KAAM,IAAIJ,EAAKI,UAEnBkB,kBAAmB,QAGvB,OAAOxB,KAAKO,OAChB,CAMUkB,WACN,OAAOzB,KAAKO,QAAWP,KAAKO,QAAqBmB,iBAAmB,IACxE,CAKUC,aACN,GAAI3B,KAAKO,SAAWP,KAAKC,SAAU,CAC9BD,KAAKO,QAAqBqB,YAAY5B,KAAKC,SAASE,IAAIQ,SAC7D,CACJ,EACH,IAAAkB,EAAA,CAAAC,WAAA,MAAAD,EAAAlC,yBAAA,OAAAkC,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":82,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","Logger","____utils_Logger","RemoteDropdownPlugin","render","fieldMetadata","bindingPath","modelName","engineScopeId","onChange","this","metadata","config","valueHelp","url","warn","sap","m","Text","text","isEditable","ui","requireSync","TextControl","require","control","id","generateStableId","applyCommonDirectives","select","Select","selectedKey","enabled","readOnly","forceSelection","busy","attachChange","result","validate","isValid","fieldKey","errorMessage","getId","useMessageManager","setVisualValidationState","addItem","Item","key","fetch","then","res","ok","Error","status","json","data","bIsDestroyed","arr","Array","isArray","value","forEach","item","k","keyPath","t","textPath","String","setBusy","catch","err","error","message","getValue","getBusy","binding","getBinding","val","getSelectedKey","type","undefined","Number","applyState","setEnabled","__exports","__esModule"],"sources":["RemoteDropdownPlugin.ts"],"sourcesContent":["/**\n * @file RemoteDropdownPlugin.ts\n * @description Renders a sap.m.Select that fetches valueHelp remotely via a JSON URL.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport Event from \"sap/ui/base/Event\";\n\nimport { IPropertyMetadata, IRemoteValueHelpConfig } from \"../../interfaces/ISchema\";\nimport Select from \"sap/m/Select\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * Handles rendering logic for dropdown inputs fetching data remotely.\n * Maps a URL response array to `Item` elements.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class RemoteDropdownPlugin extends BasePlugin {\n \n /**\n * Renders a `Select` dropdown that fetches data remotely.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @param engineScopeId The deterministic scope ID.\n * @param onChange The callback fired on value change.\n * @returns {Control} The configured Select control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\", engineScopeId?: string, onChange?: (isValid: boolean, fieldKey?: string, errorMessage?: string, controlId?: string) => void): Control {\n this.onChange = onChange;\n this.metadata = fieldMetadata;\n\n const config = fieldMetadata.valueHelp as IRemoteValueHelpConfig;\n if (!config || !config.url) {\n Logger.warn(\"[MetaUI RemoteDropdownPlugin] No valid URL provided for remoteDropdown.\");\n return new (sap as any).m.Text({ text: \"Error: No URL provided\" }) as Control;\n }\n \n if (!this.isEditable) {\n (sap.ui as any).requireSync(\"sap/m/Text\");\n const TextControl = sap.ui.require(\"sap/m/Text\");\n \n this.control = new TextControl({\n id: this.generateStableId(engineScopeId, bindingPath),\n text: `{${modelName}>${bindingPath}}` // We might not have the text mapping synchronously\n });\n \n // Optionally, we could fetch data and update the text formatter here\n \n this.applyCommonDirectives(this.control!, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n const select = new Select({\n id: this.generateStableId(engineScopeId, bindingPath),\n selectedKey: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n forceSelection: false,\n busy: true // Show busy indicator while fetching\n });\n\n select.attachChange(() => {\n const result = this.validate();\n if (this.onChange) {\n this.onChange(result.isValid, this.fieldKey, result.errorMessage, this.control?.getId());\n }\n if (this.useMessageManager) {\n this.setVisualValidationState(result.isValid, result.errorMessage);\n }\n });\n\n // Add empty placeholder\n select.addItem(new Item({ key: \"\", text: \"--- Select ---\" }));\n\n // Fetch data remotely\n fetch(config.url)\n .then(res => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n return res.json();\n })\n .then(data => {\n if ((select as any).bIsDestroyed) return;\n const arr = Array.isArray(data) ? data : (data.value || []);\n arr.forEach((item: Record<string, unknown>) => {\n const k = config.keyPath ? item[config.keyPath] : item;\n const t = config.textPath ? item[config.textPath] : item;\n select.addItem(new Item({ key: String(k), text: String(t) }));\n });\n select.setBusy(false);\n })\n .catch(err => {\n if ((select as any).bIsDestroyed) return;\n Logger.error(`[MetaUI RemoteDropdownPlugin] Failed to fetch remote data from ${config.url}`, err.message);\n select.addItem(new Item({ key: \"\", text: \"Error loading data\" }));\n select.setBusy(false);\n });\n\n this.control = select;\n this.applyCommonDirectives(this.control!, fieldMetadata, modelName);\n return this.control as Control;\n }\n\n /**\n * Retrieves the current selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n if (!this.control) return null;\n \n const select = this.control as Select;\n if (select.getBusy()) {\n // Prevent false negatives during fast form submissions: \n // If still fetching items, getSelectedKey() is blank, so fallback to raw model data.\n const binding = select.getBinding(\"selectedKey\");\n if (binding && typeof (binding as any).getValue === \"function\") {\n return (binding as any).getValue();\n }\n }\n \n let val: unknown = select.getSelectedKey();\n \n // Defect #8: Dropdown Type Coercion Crash\n if (this.metadata && (this.metadata.type === \"number\" || this.metadata.type === \"integer\")) {\n if (val === \"\" || val === null || val === undefined) return null;\n return Number(val);\n }\n \n return val;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n if (!this.isEditable) return;\n const select = this.control as Select;\n select.setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":83,"column":0},"map":{"version":3,"names":["BasePlugin","___controls_BasePlugin","Logger","____utils_Logger","RemoteValueHelpPlugin","isLoaded","render","fieldMetadata","bindingPath","modelName","this","metadata","comboBox","ComboBox","selectedKey","enabled","ui","readOnly","placeholder","change","oEvent","item","getParameter","val","getKey","validate","attachEventOnce","fetchData","control","vhConfig","valueHelp","url","error","setBusy","fetch","then","res","json","data","keyPath","textPath","forEach","itemData","addItem","Item","key","String","text","catch","err","message","finally","getValue","getSelectedKey","applyState","setEnabled","__exports","__esModule"],"sources":["RemoteValueHelpPlugin.ts"],"sourcesContent":["/**\n * @file RemoteValueHelpPlugin.ts\n * @description A custom datasource plugin that simulates fetching data from a remote server.\n */\n\nimport { BasePlugin } from \"../controls/BasePlugin\";\nimport Event from \"sap/ui/base/Event\";\n\nimport { IPropertyMetadata, IRemoteValueHelpConfig } from \"../../interfaces/ISchema\";\nimport ComboBox from \"sap/m/ComboBox\";\nimport Item from \"sap/ui/core/Item\";\nimport Control from \"sap/ui/core/Control\";\nimport { Logger } from \"../../utils/Logger\";\n\n/**\n * A custom datasource plugin that simulates fetching data from a remote server.\n * Proves out custom data sources that dynamically load value help.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.datasources\n * @public\n */\nexport class RemoteValueHelpPlugin extends BasePlugin {\n private isLoaded = false;\n\n /**\n * Renders a `ComboBox` that simulates fetching data from a remote server.\n * \n * @param fieldMetadata The specific JSON schema properties for this field.\n * @param bindingPath The JSON path bound to this control.\n * @param modelName The UI5 JSONModel name.\n * @returns {Control} The configured ComboBox control.\n */\n public render(fieldMetadata: IPropertyMetadata, bindingPath: string, modelName: string = \"meta\"): Control {\n this.metadata = fieldMetadata;\n \n const comboBox = new ComboBox({\n selectedKey: `{${modelName}>${bindingPath}}`,\n enabled: !fieldMetadata.ui?.readOnly,\n placeholder: \"Select a country...\",\n change: (oEvent: Event) => {\n const item = (oEvent as Event).getParameter(\"selectedItem\");\n const val = item ? item.getKey() : (oEvent as Event).getParameter(\"value\"); // Allow free text as well\n this.validate();\n }\n });\n\n // Perform an async load against the REST endpoint\n comboBox.attachEventOnce(\"loadItems\", () => {\n this.fetchData(comboBox);\n });\n\n this.control = comboBox;\n return this.control as Control;\n }\n\n /**\n * Executes the REST fetch for data.\n * @param comboBox The UI5 ComboBox to populate.\n */\n protected fetchData(comboBox: ComboBox): void {\n const vhConfig = this.metadata?.valueHelp as IRemoteValueHelpConfig;\n if (!vhConfig || !vhConfig.url) {\n Logger.error(\"RemoteValueHelpPlugin requires a valid valueHelp configuration with a URL.\", \"\", \"RemoteValueHelpPlugin\");\n return;\n }\n \n comboBox.setBusy(true);\n \n fetch(vhConfig.url)\n .then(res => res.json())\n .then((data: Record<string, unknown>[]) => {\n const keyPath = vhConfig.keyPath || \"key\";\n const textPath = vhConfig.textPath || \"text\";\n \n data.forEach(itemData => {\n comboBox.addItem(new Item({ \n key: String(itemData[keyPath]), \n text: String(itemData[textPath] || itemData[keyPath])\n }));\n });\n })\n .catch(err => {\n Logger.error(\"Failed to load value help from \" + vhConfig.url, err.message, \"RemoteValueHelpPlugin\");\n })\n .finally(() => {\n comboBox.setBusy(false);\n this.isLoaded = true;\n });\n }\n\n /**\n * Retrieves the current selected key.\n * @returns {unknown} The selected key.\n */\n protected getValue(): unknown {\n return this.control ? (this.control as ComboBox).getSelectedKey() : null;\n }\n\n /**\n * Applies dynamic read-only state.\n */\n protected applyState(): void {\n if (this.control && this.metadata) {\n (this.control as ComboBox).setEnabled(!this.metadata.ui?.readOnly);\n }\n }\n}\n"],"mappings":"AAAA,4MAAA,MAKSA,EAAUC,EAAA,oBAOVC,EAAMC,EAAA,UASR,MAAMC,UAA8BJ,EAC/BK,SAAW,MAUZC,OAAOC,EAAkCC,EAAqBC,EAAoB,QACrFC,KAAKC,SAAWJ,EAEhB,MAAMK,EAAW,IAAIC,EAAS,CAC1BC,YAAa,IAAIL,KAAaD,KAC9BO,SAAUR,EAAcS,IAAIC,SAC5BC,YAAa,sBACbC,OAASC,IACL,MAAMC,EAAQD,EAAiBE,aAAa,gBAC5C,MAAMC,EAAMF,EAAOA,EAAKG,SAAYJ,EAAiBE,aAAa,SAClEZ,KAAKe,cAKbb,EAASc,gBAAgB,YAAa,KAClChB,KAAKiB,UAAUf,KAGnBF,KAAKkB,QAAUhB,EACf,OAAOF,KAAKkB,OAChB,CAMUD,UAAUf,GAChB,MAAMiB,EAAWnB,KAAKC,UAAUmB,UAChC,IAAKD,IAAaA,EAASE,IAAK,CAC5B7B,EAAO8B,MAAM,6EAA8E,GAAI,yBAC/F,MACJ,CAEApB,EAASqB,QAAQ,MAEjBC,MAAML,EAASE,KACVI,KAAKC,GAAOA,EAAIC,QAChBF,KAAMG,IACH,MAAMC,EAAUV,EAASU,SAAW,MACpC,MAAMC,EAAWX,EAASW,UAAY,OAEtCF,EAAKG,QAAQC,IACT9B,EAAS+B,QAAQ,IAAIC,EAAK,CACtBC,IAAKC,OAAOJ,EAASH,IACrBQ,KAAMD,OAAOJ,EAASF,IAAaE,EAASH,WAIvDS,MAAMC,IACH/C,EAAO8B,MAAM,kCAAoCH,EAASE,IAAKkB,EAAIC,QAAS,2BAE/EC,QAAQ,KACLvC,EAASqB,QAAQ,OACjBvB,KAAKL,SAAW,MAE5B,CAMU+C,WACN,OAAO1C,KAAKkB,QAAWlB,KAAKkB,QAAqByB,iBAAmB,IACxE,CAKUC,aACN,GAAI5C,KAAKkB,SAAWlB,KAAKC,SAAU,CAC9BD,KAAKkB,QAAqB2B,YAAY7C,KAAKC,SAASK,IAAIC,SAC7D,CACJ,EACH,IAAAuC,EAAA,CAAAC,WAAA,MAAAD,EAAApD,wBAAA,OAAAoD,CAAA","ignoreList":[],"sourceRoot":"plugins/datasources"}},{"offset":{"line":84,"column":0},"map":{"version":3,"names":["CurrencyFormatterPlugin","constructor","this","currencyFormat","NumberFormat","getCurrencyInstance","showMeasure","format","rawValue","args","undefined","__exports","__esModule"],"sources":["CurrencyFormatterPlugin.ts"],"sourcesContent":["/**\n * @file CurrencyFormatterPlugin.ts\n * @description Standard data formatter for currency values.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\nimport NumberFormat from \"sap/ui/core/format/NumberFormat\";\n\n/**\n * Standard data formatter for currency values.\n * Uses sap.ui.core.format.NumberFormat to format raw numbers into localized currency strings.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class CurrencyFormatterPlugin implements IFormatter {\n private currencyFormat: NumberFormat;\n\n constructor() {\n this.currencyFormat = NumberFormat.getCurrencyInstance({\n showMeasure: false\n });\n }\n\n /**\n * Formats raw JSON model data into a UI-friendly currency string.\n * @param rawValue The raw numeric value from the JSON payload.\n * @returns The formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (rawValue === null || rawValue === undefined) {\n return \"\";\n }\n return \"$\" + this.currencyFormat.format(rawValue as number);\n }\n}\n"],"mappings":"AAAA,uJAeO,MAAMA,EAGTC,cACIC,KAAKC,eAAiBC,EAAaC,oBAAoB,CACnDC,YAAa,OAErB,CAOOC,OAAOC,EAAmBC,GAC7B,GAAID,IAAa,MAAQA,IAAaE,UAAW,CAC7C,MAAO,EACX,CACA,MAAO,IAAMR,KAAKC,eAAeI,OAAOC,EAC5C,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAX,0BAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":85,"column":0},"map":{"version":3,"names":["DateFormatterPlugin","constructor","this","dateFormat","DateFormat","getDateInstance","style","format","rawValue","args","dateObj","Date","e","__exports","__esModule"],"sources":["DateFormatterPlugin.ts"],"sourcesContent":["/**\n * @file DateFormatterPlugin.ts\n * @description Standard data formatter for dates.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\nimport DateFormat from \"sap/ui/core/format/DateFormat\";\n\n/**\n * Formats ISO date strings to localized Medium formats (e.g., \"Oct 15, 2026\").\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class DateFormatterPlugin implements IFormatter {\n private dateFormat: DateFormat;\n\n constructor() {\n this.dateFormat = DateFormat.getDateInstance({ style: \"medium\" });\n }\n\n /**\n * Formats raw JSON model data into a medium-style date string.\n * @param rawValue The raw date string.\n * @returns The formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (!rawValue) return \"\";\n try {\n const dateObj = new Date(rawValue as string);\n return this.dateFormat.format(dateObj);\n } catch (e) {\n return rawValue as string; // Fallback to raw string if invalid date\n }\n }\n}\n"],"mappings":"AAAA,iJAcO,MAAMA,EAGTC,cACIC,KAAKC,WAAaC,EAAWC,gBAAgB,CAAEC,MAAO,UAC1D,CAOOC,OAAOC,EAAmBC,GAC7B,IAAKD,EAAU,MAAO,GACtB,IACI,MAAME,EAAU,IAAIC,KAAKH,GACzB,OAAON,KAAKC,WAAWI,OAAOG,EAClC,CAAE,MAAOE,GACL,OAAOJ,CACX,CACJ,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAAb,sBAAA,OAAAa,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":86,"column":0},"map":{"version":3,"names":["PhoneFormatterPlugin","format","rawValue","args","String","cleaned","replace","match","__exports","__esModule"],"sources":["PhoneFormatterPlugin.ts"],"sourcesContent":["/**\n * @file PhoneFormatterPlugin.ts\n * @description Standard data formatter for phone numbers.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\n\n/**\n * Simple mask for 10-digit phone numbers (e.g. 5551234567 -> (555) 123-4567).\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class PhoneFormatterPlugin implements IFormatter {\n /**\n * Formats raw JSON model data into a masked phone number.\n * @param rawValue The raw phone string.\n * @returns The formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (!rawValue || typeof rawValue !== \"string\") return String(rawValue || \"\");\n \n const cleaned = ('' + rawValue).replace(/\\D/g, '');\n const match = cleaned.match(/^(\\d{3})(\\d{3})(\\d{4})$/);\n \n if (match) {\n return '(' + match[1] + ') ' + match[2] + '-' + match[3];\n }\n \n return rawValue as string;\n }\n}\n"],"mappings":"AAAA,kHAaO,MAAMA,EAMFC,OAAOC,EAAmBC,GAC7B,IAAKD,UAAmBA,IAAa,SAAU,OAAOE,OAAOF,GAAY,IAEzE,MAAMG,GAAW,GAAKH,GAAUI,QAAQ,MAAO,IAC/C,MAAMC,EAAQF,EAAQE,MAAM,2BAE5B,GAAIA,EAAO,CACP,MAAO,IAAMA,EAAM,GAAK,KAAOA,EAAM,GAAK,IAAMA,EAAM,EAC1D,CAEA,OAAOL,CACX,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAR,uBAAA,OAAAQ,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":87,"column":0},"map":{"version":3,"names":["TextCaseFormatterPlugin","format","rawValue","args","String","toUpperCase","__exports","__esModule"],"sources":["TextCaseFormatterPlugin.ts"],"sourcesContent":["/**\n * @file TextCaseFormatterPlugin.ts\n * @description Standard data formatter for text casing.\n */\n\nimport { IFormatter } from \"../../interfaces/IPipeline\";\n\n/**\n * Transforms text to UPPERCASE, lowercase, or Title Case.\n * Defaults to uppercase.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.formatters\n * @public\n */\nexport class TextCaseFormatterPlugin implements IFormatter {\n /**\n * Formats raw JSON model data into uppercase.\n * @param rawValue The raw string.\n * @returns The uppercase formatted string for the UI control.\n */\n public format(rawValue: unknown, args?: unknown): string {\n if (typeof rawValue !== \"string\") return String(rawValue || \"\");\n \n // Default to uppercase if no specific arg could be easily parsed by simple formatter \n // (could be enhanced to support schema args if formatters allowed args).\n return rawValue.toUpperCase();\n }\n}\n"],"mappings":"AAAA,qHAcO,MAAMA,EAMFC,OAAOC,EAAmBC,GAC7B,UAAWD,IAAa,SAAU,OAAOE,OAAOF,GAAY,IAI5D,OAAOA,EAASG,aACpB,EACH,IAAAC,EAAA,CAAAC,WAAA,MAAAD,EAAAN,0BAAA,OAAAM,CAAA","ignoreList":[],"sourceRoot":"plugins/formatters"}},{"offset":{"line":88,"column":0},"map":{"version":3,"names":["IsNotNullConditionPlugin","canHandle","conditionKey","evaluate","conditionPayload","data","resolvePointer","payload","Array","isArray","path","val","undefined","__exports","__esModule"],"sources":["IsNotNullConditionPlugin.ts"],"sourcesContent":["import { IPolicyConditionPlugin } from \"../../../interfaces/IPolicyPlugin\";\n\n/**\n * Evaluates whether a set of JSON pointers currently point to valid, non-empty data.\n * Used for triggering advanced sections once basic information is filled.\n */\nexport class IsNotNullConditionPlugin implements IPolicyConditionPlugin {\n /**\n * Determines if this plugin can handle the given schema condition block.\n * @param conditionKey The key found in the schema (e.g., \"IsNotNull\").\n * @returns True if the key is \"IsNotNull\".\n */\n public canHandle(conditionKey: string): boolean {\n return conditionKey === \"IsNotNull\";\n }\n\n /**\n * Evaluates whether the configured property paths contain data.\n * @param conditionPayload An array of JSON pointer strings.\n * @param data The live JSON model payload.\n * @param resolvePointer A function to resolve a JSON pointer against the data payload.\n * @returns True if all mapped properties have a value (not null, not undefined, not empty string).\n */\n public evaluate(conditionPayload: unknown, data: unknown, resolvePointer: (d: unknown, p: string) => unknown): boolean {\n const payload = conditionPayload as string[];\n if (!payload || !Array.isArray(payload)) return true;\n\n for (const path of payload) {\n const val = resolvePointer(data, path);\n if (val === undefined || val === null || val === \"\") return false;\n }\n return true;\n }\n}\n"],"mappings":"AAAA,+HAMO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAiB,WAC5B,CASOC,SAASC,EAA2BC,EAAeC,GACtD,MAAMC,EAAUH,EAChB,IAAKG,IAAYC,MAAMC,QAAQF,GAAU,OAAO,KAEhD,IAAK,MAAMG,KAAQH,EAAS,CACxB,MAAMI,EAAML,EAAeD,EAAMK,GACjC,GAAIC,IAAQC,WAAaD,IAAQ,MAAQA,IAAQ,GAAI,OAAO,KAChE,CACA,OAAO,IACX,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAb,2BAAA,OAAAa,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/conditions"}},{"offset":{"line":89,"column":0},"map":{"version":3,"names":["IsNullConditionPlugin","canHandle","conditionKey","evaluate","conditionPayload","data","resolvePointer","payload","Array","isArray","path","val","undefined","__exports","__esModule"],"sources":["IsNullConditionPlugin.ts"],"sourcesContent":["import { IPolicyConditionPlugin } from \"../../../interfaces/IPolicyPlugin\";\n\n/**\n * Evaluates whether a set of JSON pointers currently point to empty or undefined values.\n * Useful for conditionally hiding/disabling fields until prerequisites are filled out.\n */\nexport class IsNullConditionPlugin implements IPolicyConditionPlugin {\n /**\n * Determines if this plugin can handle the given schema condition block.\n * @param conditionKey The key found in the schema (e.g., \"IsNull\").\n * @returns True if the key is \"IsNull\".\n */\n public canHandle(conditionKey: string): boolean {\n return conditionKey === \"IsNull\";\n }\n\n /**\n * Evaluates whether the configured property paths are empty.\n * @param conditionPayload An array of JSON pointer strings.\n * @param data The live JSON model payload.\n * @param resolvePointer A function to resolve a JSON pointer against the data payload.\n * @returns True if all mapped properties evaluate to null, undefined, or empty string.\n */\n public evaluate(conditionPayload: unknown, data: unknown, resolvePointer: (d: unknown, p: string) => unknown): boolean {\n const payload = conditionPayload as string[];\n if (!payload || !Array.isArray(payload)) return true;\n\n for (const path of payload) {\n const val = resolvePointer(data, path);\n if (val !== undefined && val !== null && val !== \"\") return false;\n }\n return true;\n }\n}\n"],"mappings":"AAAA,4HAMO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAiB,QAC5B,CASOC,SAASC,EAA2BC,EAAeC,GACtD,MAAMC,EAAUH,EAChB,IAAKG,IAAYC,MAAMC,QAAQF,GAAU,OAAO,KAEhD,IAAK,MAAMG,KAAQH,EAAS,CACxB,MAAMI,EAAML,EAAeD,EAAMK,GACjC,GAAIC,IAAQC,WAAaD,IAAQ,MAAQA,IAAQ,GAAI,OAAO,KAChE,CACA,OAAO,IACX,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAb,wBAAA,OAAAa,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/conditions"}},{"offset":{"line":90,"column":0},"map":{"version":3,"names":["NumericGreaterThanConditionPlugin","canHandle","conditionKey","evaluate","conditionPayload","data","resolvePointer","payload","path","threshold","Object","entries","val","num","this","coerceToNumber","isNaN","value","undefined","NaN","Number","__exports","__esModule"],"sources":["NumericGreaterThanConditionPlugin.ts"],"sourcesContent":["import { IPolicyConditionPlugin } from \"../../../interfaces/IPolicyPlugin\";\n\n/**\n * Evaluates whether a numeric value is strictly greater than a defined threshold.\n * Used for dynamic UI policies like age restrictions or minimum order quantities.\n */\nexport class NumericGreaterThanConditionPlugin implements IPolicyConditionPlugin {\n /**\n * Determines if this plugin can handle the given schema condition block.\n * @param conditionKey The key found in the schema (e.g., \"NumericGreaterThan\").\n * @returns True if the key is \"NumericGreaterThan\".\n */\n public canHandle(conditionKey: string): boolean {\n return conditionKey === \"NumericGreaterThan\";\n }\n\n /**\n * Evaluates the configured thresholds against the live state payload.\n * @param conditionPayload A record mapping JSON pointers to numeric thresholds.\n * @param data The live JSON model payload.\n * @param resolvePointer A function to resolve a JSON pointer against the data payload.\n * @returns True if all mapped properties exceed their numeric thresholds, false otherwise.\n */\n public evaluate(conditionPayload: unknown, data: unknown, resolvePointer: (d: unknown, p: string) => unknown): boolean {\n const payload = conditionPayload as Record<string, number>;\n if (!payload) return true;\n\n for (const [path, threshold] of Object.entries(payload)) {\n const val = resolvePointer(data, path);\n const num = this.coerceToNumber(val);\n if (isNaN(num) || num <= threshold) return false;\n }\n return true;\n }\n\n /**\n * Safely coerces an arbitrary value into a number.\n * @param value The value to coerce.\n * @returns The parsed number, or NaN if the value is empty/invalid.\n */\n private coerceToNumber(value: unknown): number {\n if (value === undefined || value === null || value === \"\") return NaN;\n return Number(value);\n }\n}\n"],"mappings":"AAAA,wIAMO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAiB,oBAC5B,CASOC,SAASC,EAA2BC,EAAeC,GACtD,MAAMC,EAAUH,EAChB,IAAKG,EAAS,OAAO,KAErB,IAAK,MAAOC,EAAMC,KAAcC,OAAOC,QAAQJ,GAAU,CACrD,MAAMK,EAAMN,EAAeD,EAAMG,GACjC,MAAMK,EAAMC,KAAKC,eAAeH,GAChC,GAAII,MAAMH,IAAQA,GAAOJ,EAAW,OAAO,KAC/C,CACA,OAAO,IACX,CAOQM,eAAeE,GACnB,GAAIA,IAAUC,WAAaD,IAAU,MAAQA,IAAU,GAAI,OAAOE,IAClE,OAAOC,OAAOH,EAClB,EACH,IAAAI,EAAA,CAAAC,WAAA,MAAAD,EAAArB,oCAAA,OAAAqB,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/conditions"}},{"offset":{"line":91,"column":0},"map":{"version":3,"names":["NumericLessThanConditionPlugin","canHandle","conditionKey","evaluate","conditionPayload","data","resolvePointer","payload","path","threshold","Object","entries","val","num","this","coerceToNumber","isNaN","value","undefined","NaN","Number","__exports","__esModule"],"sources":["NumericLessThanConditionPlugin.ts"],"sourcesContent":["import { IPolicyConditionPlugin } from \"../../../interfaces/IPolicyPlugin\";\n\n/**\n * Evaluates whether a numeric value is strictly less than a defined threshold.\n * Used for dynamic UI policies like maximum allowed quantities.\n */\nexport class NumericLessThanConditionPlugin implements IPolicyConditionPlugin {\n /**\n * Determines if this plugin can handle the given schema condition block.\n * @param conditionKey The key found in the schema (e.g., \"NumericLessThan\").\n * @returns True if the key is \"NumericLessThan\".\n */\n public canHandle(conditionKey: string): boolean {\n return conditionKey === \"NumericLessThan\";\n }\n\n /**\n * Evaluates the configured thresholds against the live state payload.\n * @param conditionPayload A record mapping JSON pointers to numeric thresholds.\n * @param data The live JSON model payload.\n * @param resolvePointer A function to resolve a JSON pointer against the data payload.\n * @returns True if all mapped properties are below their numeric thresholds, false otherwise.\n */\n public evaluate(conditionPayload: unknown, data: unknown, resolvePointer: (d: unknown, p: string) => unknown): boolean {\n const payload = conditionPayload as Record<string, number>;\n if (!payload) return true;\n\n for (const [path, threshold] of Object.entries(payload)) {\n const val = resolvePointer(data, path);\n const num = this.coerceToNumber(val);\n if (isNaN(num) || num >= threshold) return false;\n }\n return true;\n }\n\n /**\n * Safely coerces an arbitrary value into a number.\n * @param value The value to coerce.\n * @returns The parsed number, or NaN if the value is empty/invalid.\n */\n private coerceToNumber(value: unknown): number {\n if (value === undefined || value === null || value === \"\") return NaN;\n return Number(value);\n }\n}\n"],"mappings":"AAAA,qIAMO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAiB,iBAC5B,CASOC,SAASC,EAA2BC,EAAeC,GACtD,MAAMC,EAAUH,EAChB,IAAKG,EAAS,OAAO,KAErB,IAAK,MAAOC,EAAMC,KAAcC,OAAOC,QAAQJ,GAAU,CACrD,MAAMK,EAAMN,EAAeD,EAAMG,GACjC,MAAMK,EAAMC,KAAKC,eAAeH,GAChC,GAAII,MAAMH,IAAQA,GAAOJ,EAAW,OAAO,KAC/C,CACA,OAAO,IACX,CAOQM,eAAeE,GACnB,GAAIA,IAAUC,WAAaD,IAAU,MAAQA,IAAU,GAAI,OAAOE,IAClE,OAAOC,OAAOH,EAClB,EACH,IAAAI,EAAA,CAAAC,WAAA,MAAAD,EAAArB,iCAAA,OAAAqB,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/conditions"}},{"offset":{"line":92,"column":0},"map":{"version":3,"names":["StringEqualsConditionPlugin","canHandle","conditionKey","evaluate","conditionPayload","data","resolvePointer","payload","path","targetStr","Object","entries","val","String","__exports","__esModule"],"sources":["StringEqualsConditionPlugin.ts"],"sourcesContent":["import { IPolicyConditionPlugin } from \"../../../interfaces/IPolicyPlugin\";\n\n/**\n * Evaluates whether a target property matches a specific string exactly.\n * Used for routing logic, like hiding fields based on a dropdown selection.\n */\nexport class StringEqualsConditionPlugin implements IPolicyConditionPlugin {\n /**\n * Determines if this plugin can handle the given schema condition block.\n * @param conditionKey The key found in the schema (e.g., \"StringEquals\").\n * @returns True if the key is \"StringEquals\".\n */\n public canHandle(conditionKey: string): boolean {\n return conditionKey === \"StringEquals\";\n }\n\n /**\n * Evaluates the configured equality strings against the live state payload.\n * @param conditionPayload A record mapping JSON pointers to target string values.\n * @param data The live JSON model payload.\n * @param resolvePointer A function to resolve a JSON pointer against the data payload.\n * @returns True if all mapped properties strictly equal their targets, false otherwise.\n */\n public evaluate(conditionPayload: unknown, data: unknown, resolvePointer: (d: unknown, p: string) => unknown): boolean {\n const payload = conditionPayload as Record<string, string>;\n if (!payload) return true;\n\n for (const [path, targetStr] of Object.entries(payload)) {\n const val = resolvePointer(data, path);\n if (String(val) !== String(targetStr)) return false;\n }\n return true;\n }\n}\n"],"mappings":"AAAA,kIAMO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAiB,cAC5B,CASOC,SAASC,EAA2BC,EAAeC,GACtD,MAAMC,EAAUH,EAChB,IAAKG,EAAS,OAAO,KAErB,IAAK,MAAOC,EAAMC,KAAcC,OAAOC,QAAQJ,GAAU,CACrD,MAAMK,EAAMN,EAAeD,EAAMG,GACjC,GAAIK,OAAOD,KAASC,OAAOJ,GAAY,OAAO,KAClD,CACA,OAAO,IACX,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAAd,8BAAA,OAAAc,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/conditions"}},{"offset":{"line":93,"column":0},"map":{"version":3,"names":["EditableEffectPlugin","canHandle","effect","resolveState","isConditionMet","originalEffect","isEnable","baseValue","property","value","__exports","__esModule"],"sources":["EditableEffectPlugin.ts"],"sourcesContent":["import { IPolicyEffectPlugin } from \"../../../interfaces/IPolicyPlugin\";\nimport { PropertyName } from \"../../../core/PolicyEngine\";\n\n/**\n * Translates semantic 'Enable' and 'Disable' effects into structural editable states.\n * Ties the UI5 `editable` or `enabled` states directly into the rules engine.\n */\nexport class EditableEffectPlugin implements IPolicyEffectPlugin {\n /**\n * Determines if this plugin handles the given semantic effect string.\n * @param effect The effect defined in the schema (e.g., \"Enable\", \"Disable\").\n * @returns True if the effect is handled by this plugin.\n */\n public canHandle(effect: string): boolean {\n return effect === \"Enable\" || effect === \"Disable\";\n }\n\n /**\n * Resolves the \"Enable\" or \"Disable\" effect into a concrete structural delta property.\n * Ensures symmetrical reversal when the governing condition fails.\n * @param isConditionMet Whether the governing policy condition passed.\n * @param originalEffect The original semantic effect declared in the schema.\n * @returns The resolved state mapping to the \"editable\" property.\n */\n public resolveState(isConditionMet: boolean, originalEffect: string): { property: PropertyName, value: boolean } {\n const isEnable = originalEffect === \"Enable\";\n const baseValue = isEnable ? true : false;\n \n return {\n property: \"editable\",\n value: isConditionMet ? baseValue : !baseValue\n };\n }\n}\n"],"mappings":"AAAA,wHAOO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAW,UAAYA,IAAW,SAC7C,CASOC,aAAaC,EAAyBC,GACzC,MAAMC,EAAWD,IAAmB,SACpC,MAAME,EAAYD,EAAW,KAAO,MAEpC,MAAO,CACHE,SAAU,WACVC,MAAOL,EAAiBG,GAAaA,EAE7C,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAV,uBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/effects"}},{"offset":{"line":94,"column":0},"map":{"version":3,"names":["RequirementEffectPlugin","canHandle","effect","resolveState","isConditionMet","originalEffect","isRequire","baseValue","property","value","__exports","__esModule"],"sources":["RequirementEffectPlugin.ts"],"sourcesContent":["import { IPolicyEffectPlugin } from \"../../../interfaces/IPolicyPlugin\";\nimport { PropertyName } from \"../../../core/PolicyEngine\";\n\n/**\n * Translates semantic 'Require' and 'Optional' effects into structural requirement states.\n * Ensures the UI5 `required` property dynamically responds to data thresholds.\n */\nexport class RequirementEffectPlugin implements IPolicyEffectPlugin {\n /**\n * Determines if this plugin handles the given semantic effect string.\n * @param effect The effect defined in the schema (e.g., \"Require\", \"Optional\").\n * @returns True if the effect is handled by this plugin.\n */\n public canHandle(effect: string): boolean {\n return effect === \"Require\" || effect === \"Optional\";\n }\n\n /**\n * Resolves the \"Require\" or \"Optional\" effect into a concrete structural delta property.\n * Ensures symmetrical reversal when the governing condition fails.\n * @param isConditionMet Whether the governing policy condition passed.\n * @param originalEffect The original semantic effect declared in the schema.\n * @returns The resolved state mapping to the \"required\" property.\n */\n public resolveState(isConditionMet: boolean, originalEffect: string): { property: PropertyName, value: boolean } {\n const isRequire = originalEffect === \"Require\";\n const baseValue = isRequire ? true : false;\n \n return {\n property: \"required\",\n value: isConditionMet ? baseValue : !baseValue\n };\n }\n}\n"],"mappings":"AAAA,2HAOO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAW,WAAaA,IAAW,UAC9C,CASOC,aAAaC,EAAyBC,GACzC,MAAMC,EAAYD,IAAmB,UACrC,MAAME,EAAYD,EAAY,KAAO,MAErC,MAAO,CACHE,SAAU,WACVC,MAAOL,EAAiBG,GAAaA,EAE7C,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAV,0BAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/effects"}},{"offset":{"line":95,"column":0},"map":{"version":3,"names":["ValidityEffectPlugin","canHandle","effect","resolveState","isConditionMet","originalEffect","isValid","baseValue","property","value","__exports","__esModule"],"sources":["ValidityEffectPlugin.ts"],"sourcesContent":["import { IPolicyEffectPlugin } from \"../../../interfaces/IPolicyPlugin\";\nimport { PropertyName } from \"../../../core/PolicyEngine\";\n\n/**\n * Translates semantic 'Validate' and 'Invalidate' effects into structural validity states.\n * Connects arbitrary cross-field logic to standard UI5 value states (e.g., Error vs None).\n */\nexport class ValidityEffectPlugin implements IPolicyEffectPlugin {\n /**\n * Determines if this plugin handles the given semantic effect string.\n * @param effect The effect defined in the schema (e.g., \"Validate\", \"Invalidate\").\n * @returns True if the effect is handled by this plugin.\n */\n public canHandle(effect: string): boolean {\n return effect === \"Validate\" || effect === \"Invalidate\";\n }\n\n /**\n * Resolves the \"Validate\" or \"Invalidate\" effect into a concrete structural delta property.\n * Ensures symmetrical reversal when the governing condition fails.\n * @param isConditionMet Whether the governing policy condition passed.\n * @param originalEffect The original semantic effect declared in the schema.\n * @returns The resolved state mapping to the \"validity\" property.\n */\n public resolveState(isConditionMet: boolean, originalEffect: string): { property: PropertyName, value: boolean } {\n const isValid = originalEffect === \"Validate\";\n const baseValue = isValid ? true : false;\n \n return {\n property: \"validity\",\n value: isConditionMet ? baseValue : !baseValue\n };\n }\n}\n"],"mappings":"AAAA,wHAOO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAW,YAAcA,IAAW,YAC/C,CASOC,aAAaC,EAAyBC,GACzC,MAAMC,EAAUD,IAAmB,WACnC,MAAME,EAAYD,EAAU,KAAO,MAEnC,MAAO,CACHE,SAAU,WACVC,MAAOL,EAAiBG,GAAaA,EAE7C,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAV,uBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/effects"}},{"offset":{"line":96,"column":0},"map":{"version":3,"names":["VisibilityEffectPlugin","canHandle","effect","resolveState","isConditionMet","originalEffect","isShow","baseValue","property","value","__exports","__esModule"],"sources":["VisibilityEffectPlugin.ts"],"sourcesContent":["import { IPolicyEffectPlugin } from \"../../../interfaces/IPolicyPlugin\";\nimport { PropertyName } from \"../../../core/PolicyEngine\";\n\n/**\n * Translates semantic 'Show' and 'Hide' effects into boolean structural visibility states.\n * Enables conditions to toggle the visual presence of form fields dynamically.\n */\nexport class VisibilityEffectPlugin implements IPolicyEffectPlugin {\n /**\n * Determines if this plugin handles the given semantic effect string.\n * @param effect The effect defined in the schema (e.g., \"Show\", \"Hide\").\n * @returns True if the effect is handled by this plugin.\n */\n public canHandle(effect: string): boolean {\n return effect === \"Show\" || effect === \"Hide\";\n }\n\n /**\n * Resolves the \"Show\" or \"Hide\" effect into a concrete structural delta property.\n * Ensures symmetrical reversal when the governing condition fails.\n * @param isConditionMet Whether the governing policy condition passed.\n * @param originalEffect The original semantic effect declared in the schema.\n * @returns The resolved state mapping to the \"visibility\" property.\n */\n public resolveState(isConditionMet: boolean, originalEffect: string): { property: PropertyName, value: boolean } {\n const isShow = originalEffect === \"Show\";\n const baseValue = isShow ? true : false;\n \n return {\n property: \"visibility\",\n value: isConditionMet ? baseValue : !baseValue\n };\n }\n}\n"],"mappings":"AAAA,0HAOO,MAAMA,EAMFC,UAAUC,GACb,OAAOA,IAAW,QAAUA,IAAW,MAC3C,CASOC,aAAaC,EAAyBC,GACzC,MAAMC,EAASD,IAAmB,OAClC,MAAME,EAAYD,EAAS,KAAO,MAElC,MAAO,CACHE,SAAU,aACVC,MAAOL,EAAiBG,GAAaA,EAE7C,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAV,yBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/policies/effects"}},{"offset":{"line":97,"column":0},"map":{"version":3,"names":["EmailValidatorPlugin","validate","parsedValue","args","isValid","emailRegex","test","errorMessage","__exports","__esModule"],"sources":["EmailValidatorPlugin.ts"],"sourcesContent":["/**\n * @file EmailValidatorPlugin.ts\n * @description Standard business logic validator for email addresses.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Standard business logic validator for email addresses.\n * Extracts the email regex validation logic into a standalone, modular plugin.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class EmailValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n if (typeof parsedValue !== \"string\" || !emailRegex.test(parsedValue)) {\n return { isValid: false, errorMessage: \"Please enter a valid email address.\" };\n }\n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,kHAcO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,MAAMC,EAAa,6BACnB,UAAWH,IAAgB,WAAaG,EAAWC,KAAKJ,GAAc,CAClE,MAAO,CAAEE,QAAS,MAAOG,aAAc,sCAC3C,CACA,MAAO,CAAEH,QAAS,KACtB,EACH,IAAAI,EAAA,CAAAC,WAAA,MAAAD,EAAAR,uBAAA,OAAAQ,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":98,"column":0},"map":{"version":3,"names":["IbanValidatorPlugin","validate","parsedValue","args","isValid","ibanRegex","test","replace","toUpperCase","errorMessage","__exports","__esModule"],"sources":["IbanValidatorPlugin.ts"],"sourcesContent":["/**\n * @file IbanValidatorPlugin.ts\n * @description Standard business logic validator for International Bank Account Numbers.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Validates a standard IBAN string.\n * This provides a simplified check for demonstration (starts with 2 chars, followed by digits/chars).\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class IbanValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n \n // Very basic IBAN structure regex (e.g. DE89370400440532013000)\n // A true IBAN check requires modulo 97 arithmetic which is out of scope for a basic mock.\n const ibanRegex = /^[A-Z]{2}\\d{2}[A-Z0-9]{1,30}$/;\n \n if (typeof parsedValue !== \"string\" || !ibanRegex.test(parsedValue.replace(/\\s+/g, '').toUpperCase())) {\n return { isValid: false, errorMessage: \"Please enter a valid IBAN.\" };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,iHAcO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MAIpC,MAAMC,EAAY,gCAElB,UAAWH,IAAgB,WAAaG,EAAUC,KAAKJ,EAAYK,QAAQ,OAAQ,IAAIC,eAAgB,CACnG,MAAO,CAAEJ,QAAS,MAAOK,aAAc,6BAC3C,CAEA,MAAO,CAAEL,QAAS,KACtB,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAV,sBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":99,"column":0},"map":{"version":3,"names":["MinLengthValidatorPlugin","validate","parsedValue","args","isValid","length","errorMessage","__exports","__esModule"],"sources":["MinLengthValidatorPlugin.ts"],"sourcesContent":["/**\n * @file MinLengthValidatorPlugin.ts\n * @description Standard business logic validator for string minimum lengths.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Ensures string length meets a minimum threshold.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class MinLengthValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n if (typeof args !== \"number\") return { isValid: true }; // Invalid config\n\n if (typeof parsedValue === \"string\" && parsedValue.length < args) {\n return { isValid: false, errorMessage: `Minimum length is ${args} characters.` };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,sHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,UAAWD,IAAS,SAAU,MAAO,CAAEC,QAAS,MAEhD,UAAWF,IAAgB,UAAYA,EAAYG,OAASF,EAAM,CAC9D,MAAO,CAAEC,QAAS,MAAOE,aAAc,qBAAqBH,gBAChE,CAEA,MAAO,CAAEC,QAAS,KACtB,EACH,IAAAG,EAAA,CAAAC,WAAA,MAAAD,EAAAP,2BAAA,OAAAO,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":100,"column":0},"map":{"version":3,"names":["PatternValidatorPlugin","validate","parsedValue","args","isValid","regex","RegExp","test","errorMessage","e","__exports","__esModule"],"sources":["PatternValidatorPlugin.ts"],"sourcesContent":["/**\n * @file PatternValidatorPlugin.ts\n * @description Standard business logic validator for Regex patterns.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Validates a string against a regular expression pattern provided in the schema args.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class PatternValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n if (typeof args !== \"string\") {\n return { isValid: true }; // Invalid config, skip\n }\n\n try {\n const regex = new RegExp(args);\n if (typeof parsedValue !== \"string\" || !regex.test(parsedValue)) {\n return { isValid: false, errorMessage: `Input does not match the required pattern.` };\n }\n } catch (e) {\n // Invalid regex string provided\n return { isValid: false, errorMessage: `Schema configuration error: Invalid regex pattern.` };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,oHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,UAAWD,IAAS,SAAU,CAC1B,MAAO,CAAEC,QAAS,KACtB,CAEA,IACI,MAAMC,EAAQ,IAAIC,OAAOH,GACzB,UAAWD,IAAgB,WAAaG,EAAME,KAAKL,GAAc,CAC7D,MAAO,CAAEE,QAAS,MAAOI,aAAc,6CAC3C,CACJ,CAAE,MAAOC,GAEL,MAAO,CAAEL,QAAS,MAAOI,aAAc,qDAC3C,CAEA,MAAO,CAAEJ,QAAS,KACtB,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAV,yBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":101,"column":0},"map":{"version":3,"names":["RangeValidatorPlugin","validate","parsedValue","args","undefined","isValid","rangeArgs","min","max","errorMessage","__exports","__esModule"],"sources":["RangeValidatorPlugin.ts"],"sourcesContent":["/**\n * @file RangeValidatorPlugin.ts\n * @description Standard business logic validator for numeric ranges.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Ensures a numeric value falls within an optionally provided min and max range.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class RangeValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (parsedValue === null || parsedValue === undefined) return { isValid: true }; \n if (typeof parsedValue !== \"number\") return { isValid: true };\n\n const rangeArgs = args as { min?: number, max?: number } | undefined;\n const min = rangeArgs?.min;\n const max = rangeArgs?.max;\n\n if (min !== undefined && typeof min === \"number\" && parsedValue < min) {\n return { isValid: false, errorMessage: `Value must be greater than or equal to ${min}.` };\n }\n\n if (max !== undefined && typeof max === \"number\" && parsedValue > max) {\n return { isValid: false, errorMessage: `Value must be less than or equal to ${max}.` };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,kHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,GAAID,IAAgB,MAAQA,IAAgBE,UAAW,MAAO,CAAEC,QAAS,MACzE,UAAWH,IAAgB,SAAU,MAAO,CAAEG,QAAS,MAEvD,MAAMC,EAAYH,EAClB,MAAMI,EAAMD,GAAWC,IACvB,MAAMC,EAAMF,GAAWE,IAEvB,GAAID,IAAQH,kBAAoBG,IAAQ,UAAYL,EAAcK,EAAK,CACnE,MAAO,CAAEF,QAAS,MAAOI,aAAc,0CAA0CF,KACrF,CAEA,GAAIC,IAAQJ,kBAAoBI,IAAQ,UAAYN,EAAcM,EAAK,CACnE,MAAO,CAAEH,QAAS,MAAOI,aAAc,uCAAuCD,KAClF,CAEA,MAAO,CAAEH,QAAS,KACtB,EACH,IAAAK,EAAA,CAAAC,WAAA,MAAAD,EAAAV,uBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":102,"column":0},"map":{"version":3,"names":["UrlValidatorPlugin","validate","parsedValue","args","isValid","url","URL","protocol","errorMessage","e","__exports","__esModule"],"sources":["UrlValidatorPlugin.ts"],"sourcesContent":["/**\n * @file UrlValidatorPlugin.ts\n * @description Standard business logic validator for URL formats.\n */\n\nimport { IValidator, IValidationResult } from \"../../interfaces/IPipeline\";\n\n/**\n * Ensures a string is a valid HTTP/HTTPS URL.\n * \n * @namespace nz.co.siliconst.ui5.metaui.plugins.validators\n * @public\n */\nexport class UrlValidatorPlugin implements IValidator {\n /**\n * Validates parsed data before it enters the JSON model.\n * @param parsedValue The cleaned data to validate.\n * @param args Optional arguments provided in the schema.\n * @returns IValidationResult containing status and optional error message.\n */\n public validate(parsedValue: unknown, args?: unknown): IValidationResult {\n if (!parsedValue) return { isValid: true }; // Let RequiredValidator handle empty\n if (typeof parsedValue !== \"string\") return { isValid: true };\n \n try {\n const url = new URL(parsedValue);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return { isValid: false, errorMessage: \"URL must use http or https protocol.\" };\n }\n } catch (e) {\n return { isValid: false, errorMessage: \"Please enter a valid URL.\" };\n }\n \n return { isValid: true };\n }\n}\n"],"mappings":"AAAA,gHAaO,MAAMA,EAOFC,SAASC,EAAsBC,GAClC,IAAKD,EAAa,MAAO,CAAEE,QAAS,MACpC,UAAWF,IAAgB,SAAU,MAAO,CAAEE,QAAS,MAEvD,IACI,MAAMC,EAAM,IAAIC,IAAIJ,GACpB,GAAIG,EAAIE,WAAa,SAAWF,EAAIE,WAAa,SAAU,CACvD,MAAO,CAAEH,QAAS,MAAOI,aAAc,uCAC3C,CACJ,CAAE,MAAOC,GACL,MAAO,CAAEL,QAAS,MAAOI,aAAc,4BAC3C,CAEA,MAAO,CAAEJ,QAAS,KACtB,EACH,IAAAM,EAAA,CAAAC,WAAA,MAAAD,EAAAV,qBAAA,OAAAU,CAAA","ignoreList":[],"sourceRoot":"plugins/validators"}},{"offset":{"line":103,"column":0},"map":{"version":3,"names":["Logger","___utils_Logger","SchemaProvider","resolve","url","response","fetch","ok","Error","status","json","e","warn","__exports","__esModule"],"sources":["SchemaProvider.ts"],"sourcesContent":["import { Logger } from \"../utils/Logger\";\n\n/**\n * Service class responsible for resolving schemas from remote network locations.\n */\nexport class SchemaProvider {\n /**\n * Fetches a schema remotely over HTTP.\n * @param url The target URL.\n * @returns A promise resolving to the JSON schema object.\n */\n public static async resolve(url: string): Promise<Record<string, unknown>> {\n try {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n return await response.json();\n } catch (e) {\n Logger.warn(\"[MetaUI SchemaProvider]\", \"Failed to fetch remote schema: \" + e, \"SchemaProvider\");\n throw e;\n }\n }\n}\n"],"mappings":"AAAA,0HAASA,EAAMC,EAAA,UAKR,MAAMC,EAMT,oBAAoBC,CAAQC,GACxB,IACI,MAAMC,QAAiBC,MAAMF,GAC7B,IAAKC,EAASE,GAAI,CACd,MAAM,IAAIC,MAAM,QAAQH,EAASI,SACrC,CACA,aAAaJ,EAASK,MAC1B,CAAE,MAAOC,GACLX,EAAOY,KAAK,0BAA2B,kCAAoCD,EAAG,kBAC9E,MAAMA,CACV,CACJ,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAX,iBAAA,OAAAW,CAAA","ignoreList":[],"sourceRoot":"services"}},{"offset":{"line":104,"column":0},"map":{"version":3,"names":["OpenApiExtractor","UI5Object","extend","extractTargets","rawSchema","aTargets","oSchema","openapi","startsWith","components","schemas","Object","keys","forEach","sKey","push","key","text","swagger","definitions","paths","sPath","methods","sMethod","escapedPath","replace","toUpperCase","length","bestScore","bestIndex","info","title","toLowerCase","titleWords","split","target","index","score","includes","name","pop","nameLower","nameClean","word","genericRoots","some","r","schemaDef","scoreSchemaNode","node","nodeObj","properties","values","prop","propObj","$ref","items","required","Array","isArray","allOf","anyOf","oneOf","primary","splice","unshift"],"sources":["OpenApiExtractor.ts"],"sourcesContent":["import UI5Object from \"sap/ui/base/Object\";\n\nexport interface OpenApiTarget {\n key: string;\n text: string;\n}\n\n/**\n * @class\n * OpenApiExtractor utility.\n * Dynamically crawls OpenAPI/Swagger JSON specifications to find all valid \n * root endpoints and schema definitions that can be used as a schemaTarget.\n * \n * @extends sap.ui.base.Object\n * @alias nz.co.siliconst.ui5.metaui.swagger.OpenApiExtractor\n */\nexport default class OpenApiExtractor extends UI5Object {\n\n /**\n * Parses an OpenAPI document and extracts an array of valid targets.\n * \n * @public\n * @param oSchema The parsed JSON schema object.\n * @returns Array of target bindings.\n */\n public static extractTargets(rawSchema: unknown): OpenApiTarget[] {\n const aTargets: OpenApiTarget[] = [];\n if (!rawSchema || typeof rawSchema !== \"object\") {\n return aTargets;\n }\n\n const oSchema = rawSchema as Record<string, unknown>;\n\n // OpenAPI 3.0 (components/schemas)\n if (typeof oSchema.openapi === \"string\" && oSchema.openapi.startsWith(\"3.\") && oSchema.components && typeof (oSchema.components as Record<string,unknown>).schemas === \"object\") {\n Object.keys((oSchema.components as Record<string,unknown>).schemas as Record<string,unknown>).forEach((sKey) => {\n aTargets.push({\n key: \"#/components/schemas/\" + sKey,\n text: \"Schema: \" + sKey\n });\n });\n }\n \n // Swagger 2.0 (definitions)\n if (typeof oSchema.swagger === \"string\" && oSchema.swagger.startsWith(\"2.\") && typeof oSchema.definitions === \"object\" && oSchema.definitions !== null) {\n Object.keys(oSchema.definitions as Record<string,unknown>).forEach((sKey) => {\n aTargets.push({\n key: \"#/definitions/\" + sKey,\n text: \"Definition: \" + sKey\n });\n });\n }\n\n // Extract endpoints\n if (typeof oSchema.paths === \"object\" && oSchema.paths !== null) {\n Object.keys(oSchema.paths as Record<string,unknown>).forEach((sPath) => {\n const methods = (oSchema.paths as Record<string,unknown>)[sPath];\n if (methods && typeof methods === \"object\") {\n Object.keys(methods).forEach((sMethod) => {\n const escapedPath = sPath.replace(/\\//g, \"~1\");\n aTargets.push({\n key: \"#/paths/\" + escapedPath + \"/\" + sMethod,\n text: \"Operation: \" + sMethod.toUpperCase() + \" \" + sPath\n });\n });\n }\n });\n }\n\n // Primary Schema Detection\n if (aTargets.length > 1) {\n let bestScore = -1;\n let bestIndex = -1;\n \n const info = oSchema.info as Record<string, unknown> | undefined;\n const title = (info && typeof info.title === \"string\") ? info.title.toLowerCase().replace(/[^a-z0-9]/g, \"\") : \"\";\n const titleWords = (info && typeof info.title === \"string\") ? info.title.toLowerCase().split(/[\\s_-]+/) : [];\n \n aTargets.forEach((target, index) => {\n let score = 0;\n \n // Only score Schemas/Definitions, not operations for the primary node heuristic\n if (target.key.includes(\"/schemas/\") || target.key.includes(\"/definitions/\")) {\n const name = target.key.split(\"/\").pop() || \"\";\n const nameLower = name.toLowerCase();\n const nameClean = nameLower.replace(/[^a-z0-9]/g, \"\");\n \n if (title && nameClean === title) score += 30; // Reduced from 100\n else if (title && title.includes(nameClean)) score += 15; // Reduced from 50\n else if (title && nameClean.includes(title)) score += 15; // Reduced from 50\n \n titleWords.forEach((word: string) => {\n if (word.length > 3 && nameLower.includes(word)) score += 5; // Reduced from 10\n });\n \n const genericRoots = [\"root\", \"main\", \"app\", \"application\", \"payload\", \"document\"];\n if (genericRoots.some(r => nameLower.includes(r))) score += 5;\n\n // Complexity Fallback\n let schemaDef: Record<string, unknown> | null = null;\n if (target.key.startsWith(\"#/components/schemas/\") && typeof oSchema.components === \"object\" && oSchema.components !== null) {\n const components = oSchema.components as Record<string, unknown>;\n if (typeof components.schemas === \"object\" && components.schemas !== null) {\n schemaDef = (components.schemas as Record<string, Record<string, unknown>>)[name] || null;\n }\n } else if (target.key.startsWith(\"#/definitions/\") && typeof oSchema.definitions === \"object\" && oSchema.definitions !== null) {\n schemaDef = (oSchema.definitions as Record<string, Record<string, unknown>>)[name] || null;\n }\n\n if (schemaDef && typeof schemaDef === \"object\") {\n const scoreSchemaNode = (node: unknown) => {\n if (!node || typeof node !== \"object\") return;\n const nodeObj = node as Record<string, unknown>;\n if (nodeObj.properties && typeof nodeObj.properties === \"object\") {\n score += Object.keys(nodeObj.properties).length * 2; // +2 per property\n Object.values(nodeObj.properties).forEach((prop: unknown) => {\n if (prop && typeof prop === \"object\") {\n const propObj = prop as Record<string, unknown>;\n if (propObj.$ref) score += 20; // +20 for referencing sub-schemas (aggregate root)\n if (propObj.items && typeof propObj.items === \"object\" && (propObj.items as Record<string, unknown>).$ref) score += 20;\n }\n });\n }\n \n if (nodeObj.required && Array.isArray(nodeObj.required)) {\n score += nodeObj.required.length * 5; // +5 per required constraint\n }\n };\n\n scoreSchemaNode(schemaDef);\n\n // Handle OpenAPI composition structures\n if (schemaDef.allOf && Array.isArray(schemaDef.allOf)) {\n schemaDef.allOf.forEach(scoreSchemaNode);\n }\n if (schemaDef.anyOf && Array.isArray(schemaDef.anyOf)) {\n schemaDef.anyOf.forEach(scoreSchemaNode);\n }\n if (schemaDef.oneOf && Array.isArray(schemaDef.oneOf)) {\n schemaDef.oneOf.forEach(scoreSchemaNode);\n }\n }\n }\n \n if (score > bestScore) {\n bestScore = score;\n bestIndex = index;\n }\n });\n\n if (bestIndex !== -1 && bestScore > 0) {\n const primary = aTargets.splice(bestIndex, 1)[0];\n primary.text = `(Recommended) ${primary.text}`;\n aTargets.unshift(primary);\n }\n }\n\n return aTargets;\n }\n}\n"],"mappings":"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","ignoreList":[],"sourceRoot":"swagger"}},{"offset":{"line":105,"column":0},"map":{"version":3,"names":["ExpressionBuilder","build","rule","bindingPath","modelName","parsedRule","replace","match","path","reserved","includes","basePath","startsWith","substring","parts","split","pop","contextPrefix","length","join","__exports","__esModule"],"sources":["ExpressionBuilder.ts"],"sourcesContent":["/**\n * @file ExpressionBuilder.ts\n * @description Safely parses and builds UI5 expression bindings from JSON Schema condition rules.\n */\n\nexport class ExpressionBuilder {\n /**\n * Safely converts a raw condition rule (e.g. \"$root.Status === 'NEW'\") into a valid UI5 \n * expression binding string, preserving relative vs absolute paths.\n * \n * @param rule The raw schema condition rule (e.g., \"$root.Category === 'A' || SubCategory === 'B'\").\n * @param bindingPath The absolute binding path of the current field (e.g., \"/Items/0/Category\").\n * @param modelName The UI5 JSONModel name (default \"meta\").\n * @returns {string} The fully formed UI5 expression binding (e.g., \"{= ${meta>/Status} === 'NEW' }\").\n */\n public static build(rule: string, bindingPath: string, modelName: string = \"meta\"): string {\n if (!rule) return \"{= true }\";\n\n let parsedRule = rule;\n\n // 1. Replace absolute $root paths\n // $root.Status -> ${meta>/Status}\n parsedRule = parsedRule.replace(/\\$root\\.([a-zA-Z0-9_.]+)/g, (match, path) => {\n return `\\${${modelName}>/${path.replace(/\\./g, '/')}}`;\n });\n\n // 2. Replace relative paths\n parsedRule = parsedRule.replace(/(?<!['\"\\${a-zA-Z0-9_.>/-])([a-zA-Z_][a-zA-Z0-9_.]+)(?!['\"a-zA-Z0-9_.(])/g, (match, path) => {\n const reserved = [\"true\", \"false\", \"null\", \"undefined\", \"Math\", \"String\", \"Number\", \"Array\", \"Object\"];\n if (reserved.includes(path)) return path;\n\n // Resolve relative to the current binding path context\n let basePath = bindingPath.startsWith(\"/\") ? bindingPath.substring(1) : bindingPath;\n const parts = basePath.split('/');\n parts.pop(); \n const contextPrefix = parts.length > 0 ? parts.join('/') + '/' : '';\n \n return `\\${${modelName}>/${contextPrefix}${path.replace(/\\./g, '/')}}`;\n });\n\n return `{= ${parsedRule} }`;\n }\n}\n"],"mappings":"AAAA,kGAKO,MAAMA,EAUT,YAAcC,CAAMC,EAAcC,EAAqBC,EAAoB,QACvE,IAAKF,EAAM,MAAO,YAElB,IAAIG,EAAaH,EAIjBG,EAAaA,EAAWC,QAAQ,4BAA6B,CAACC,EAAOC,IAC1D,MAAMJ,MAAcI,EAAKF,QAAQ,MAAO,SAInDD,EAAaA,EAAWC,QAAQ,2EAA4E,CAACC,EAAOC,KAChH,MAAMC,EAAW,CAAC,OAAQ,QAAS,OAAQ,YAAa,OAAQ,SAAU,SAAU,QAAS,UAC7F,GAAIA,EAASC,SAASF,GAAO,OAAOA,EAGpC,IAAIG,EAAWR,EAAYS,WAAW,KAAOT,EAAYU,UAAU,GAAKV,EACxE,MAAMW,EAAQH,EAASI,MAAM,KAC7BD,EAAME,MACN,MAAMC,EAAgBH,EAAMI,OAAS,EAAIJ,EAAMK,KAAK,KAAO,IAAM,GAEjE,MAAO,MAAMf,MAAca,IAAgBT,EAAKF,QAAQ,MAAO,UAGnE,MAAO,MAAMD,KACjB,EACH,IAAAe,EAAA,CAAAC,WAAA,MAAAD,EAAApB,oBAAA,OAAAoB,CAAA","ignoreList":[],"sourceRoot":"utils"}},{"offset":{"line":106,"column":0},"map":{"version":3,"names":["Logger","static","setDebugMode","enabled","this","debugMode","logInstance","sap","ui","require","Log","isDebugMode","debug","message","details","component","console","info","warn","warning","error","showErrorPopup","title","MessageBox","__exports","__esModule"],"sources":["Logger.ts"],"sourcesContent":["/**\n * @file Logger.ts\n * @description Centralized logging utility for MetaUI.\n * Wraps sap/base/Log and provides a global toggle for debug mode.\n */\n\nexport class Logger {\n private static debugMode: boolean = false;\n private static logInstance: any = null;\n\n /**\n * Toggles the global debug mode for MetaUI.\n * @param enabled Set to true to enable logging.\n */\n public static setDebugMode(enabled: boolean): void {\n this.debugMode = enabled;\n if (enabled && !this.logInstance) {\n sap.ui.require([\"sap/base/Log\"], (Log: Record<string, Function>) => {\n this.logInstance = Log;\n });\n }\n }\n\n /**\n * Checks if debug mode is currently active.\n */\n public static isDebugMode(): boolean {\n return this.debugMode;\n }\n\n public static debug(message: string, details?: string, component?: string): void {\n if (!this.debugMode) return;\n if (this.logInstance) {\n this.logInstance.debug(message, details, component || \"MetaUI\");\n } else {\n console.debug(`[MetaUI] ${message}`, details || \"\");\n }\n }\n\n public static info(message: string, details?: string, component?: string): void {\n if (!this.debugMode) return;\n if (this.logInstance) {\n this.logInstance.info(message, details, component || \"MetaUI\");\n } else {\n console.info(`[MetaUI] ${message}`, details || \"\");\n }\n }\n\n public static warn(message: string, details?: string, component?: string): void {\n if (!this.debugMode) return;\n if (this.logInstance) {\n this.logInstance.warning(message, details, component || \"MetaUI\");\n } else {\n console.warn(`[MetaUI] ${message}`, details || \"\");\n }\n }\n\n public static error(message: string, details?: string, component?: string): void {\n if (this.logInstance) {\n this.logInstance.error(message, details, component || \"MetaUI\");\n } else {\n console.error(`[MetaUI Error] ${message}`, details || \"\");\n }\n }\n\n /**\n * Pops up a MessageBox UI alert if debug mode is active.\n */\n public static showErrorPopup(message: string, title?: string): void {\n if (!this.debugMode) return;\n sap.ui.require([\"sap/m/MessageBox\"], (MessageBox: Record<string, Function>) => {\n (MessageBox as Record<string, Function>).error(message, { title: title || \"MetaUI Error\" });\n });\n }\n}\n"],"mappings":"AAAA,uFAMO,MAAMA,EACTC,iBAAoC,MACpCA,mBAAkC,KAMlC,mBAAcC,CAAaC,GACvBC,KAAKC,UAAYF,EACjB,GAAIA,IAAYC,KAAKE,YAAa,CAC9BC,IAAIC,GAAGC,QAAQ,CAAC,gBAAkBC,IAC9BN,KAAKE,YAAcI,GAE3B,CACJ,CAKA,kBAAcC,GACV,OAAOP,KAAKC,SAChB,CAEA,YAAcO,CAAMC,EAAiBC,EAAkBC,GACnD,IAAKX,KAAKC,UAAW,OACrB,GAAID,KAAKE,YAAa,CAClBF,KAAKE,YAAYM,MAAMC,EAASC,EAASC,GAAa,SAC1D,KAAO,CACHC,QAAQJ,MAAM,YAAYC,IAAWC,GAAW,GACpD,CACJ,CAEA,WAAcG,CAAKJ,EAAiBC,EAAkBC,GAClD,IAAKX,KAAKC,UAAW,OACrB,GAAID,KAAKE,YAAa,CAClBF,KAAKE,YAAYW,KAAKJ,EAASC,EAASC,GAAa,SACzD,KAAO,CACHC,QAAQC,KAAK,YAAYJ,IAAWC,GAAW,GACnD,CACJ,CAEA,WAAcI,CAAKL,EAAiBC,EAAkBC,GAClD,IAAKX,KAAKC,UAAW,OACrB,GAAID,KAAKE,YAAa,CAClBF,KAAKE,YAAYa,QAAQN,EAASC,EAASC,GAAa,SAC5D,KAAO,CACHC,QAAQE,KAAK,YAAYL,IAAWC,GAAW,GACnD,CACJ,CAEA,YAAcM,CAAMP,EAAiBC,EAAkBC,GACnD,GAAIX,KAAKE,YAAa,CAClBF,KAAKE,YAAYc,MAAMP,EAASC,EAASC,GAAa,SAC1D,KAAO,CACHC,QAAQI,MAAM,kBAAkBP,IAAWC,GAAW,GAC1D,CACJ,CAKA,qBAAcO,CAAeR,EAAiBS,GAC1C,IAAKlB,KAAKC,UAAW,OACrBE,IAAIC,GAAGC,QAAQ,CAAC,oBAAsBc,IACjCA,EAAwCH,MAAMP,EAAS,CAAES,MAAOA,GAAS,kBAElF,EACH,IAAAE,EAAA,CAAAC,WAAA,MAAAD,EAAAxB,SAAA,OAAAwB,CAAA","ignoreList":[],"sourceRoot":"utils"}},{"offset":{"line":107,"column":0},"map":{"version":3,"names":[],"sources":["library-preload.js?bundle-code-0"],"mappings":"AAAA;AACA","sourcesContent":["sap.ui.require.preload({\n"],"sourceRoot":""}},{"offset":{"line":109,"column":0},"map":{"version":3,"file":"ILayoutManager.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":112,"column":0},"map":{"version":3,"file":"IPipeline.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":115,"column":0},"map":{"version":3,"file":"IPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":118,"column":0},"map":{"version":3,"file":"IPolicyPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":121,"column":0},"map":{"version":3,"file":"ISchema.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":124,"column":0},"map":{"version":3,"file":"ISchemaBuilderPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"interfaces"}},{"offset":{"line":128,"column":0},"map":{"version":3,"file":"IHeuristicPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"openapi/heuristics/interfaces"}},{"offset":{"line":131,"column":0},"map":{"version":3,"file":"IOpenApiParserPlugin.js","names":[],"sources":[],"mappings":"AAAA","ignoreList":[],"sourceRoot":"openapi/interfaces"}}]}