cyberia 2.8.885

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 (525) hide show
  1. package/.dockerignore +15 -0
  2. package/.env.development +45 -0
  3. package/.env.production +50 -0
  4. package/.env.test +45 -0
  5. package/.github/workflows/engine-cyberia.cd.yml +31 -0
  6. package/.github/workflows/engine-cyberia.ci.yml +60 -0
  7. package/.github/workflows/ghpkg.ci.yml +87 -0
  8. package/.github/workflows/npmpkg.ci.yml +72 -0
  9. package/.github/workflows/publish.ci.yml +84 -0
  10. package/.github/workflows/publish.cyberia.ci.yml +84 -0
  11. package/.github/workflows/pwa-microservices-template-page.cd.yml +72 -0
  12. package/.github/workflows/pwa-microservices-template-test.ci.yml +33 -0
  13. package/.github/workflows/release.cd.yml +37 -0
  14. package/.nycrc +9 -0
  15. package/.prettierignore +13 -0
  16. package/.prettierrc +9 -0
  17. package/.vscode/extensions.json +51 -0
  18. package/.vscode/settings.json +87 -0
  19. package/AUTHORS.md +21 -0
  20. package/CHANGELOG.md +205 -0
  21. package/Dockerfile +28 -0
  22. package/LICENSE +21 -0
  23. package/README.md +85 -0
  24. package/bin/build.js +209 -0
  25. package/bin/cron.js +47 -0
  26. package/bin/cyberia.js +145 -0
  27. package/bin/db.js +199 -0
  28. package/bin/deploy.js +1293 -0
  29. package/bin/file.js +197 -0
  30. package/bin/hwt.js +49 -0
  31. package/bin/index.js +145 -0
  32. package/bin/ssl.js +63 -0
  33. package/bin/util.js +80 -0
  34. package/bin/vs.js +74 -0
  35. package/cli.md +714 -0
  36. package/conf.js +204 -0
  37. package/deployment.yaml +138 -0
  38. package/jsconfig.json +7 -0
  39. package/jsdoc.json +32 -0
  40. package/manifests/deployment/adminer/deployment.yaml +32 -0
  41. package/manifests/deployment/adminer/kustomization.yaml +7 -0
  42. package/manifests/deployment/adminer/service.yaml +13 -0
  43. package/manifests/deployment/dd-default-development/deployment.yaml +167 -0
  44. package/manifests/deployment/dd-default-development/proxy.yaml +46 -0
  45. package/manifests/deployment/dd-test-development/deployment.yaml +174 -0
  46. package/manifests/deployment/dd-test-development/proxy.yaml +51 -0
  47. package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
  48. package/manifests/deployment/fastapi/backend-service.yml +19 -0
  49. package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
  50. package/manifests/deployment/fastapi/frontend-service.yml +15 -0
  51. package/manifests/deployment/fastapi/initial_data.sh +56 -0
  52. package/manifests/deployment/kafka/deployment.yaml +69 -0
  53. package/manifests/deployment/mongo-express/deployment.yaml +60 -0
  54. package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
  55. package/manifests/deployment/spark/spark-pi-py.yaml +21 -0
  56. package/manifests/deployment/tensorflow/tf-gpu-test.yaml +65 -0
  57. package/manifests/envoy-service-nodeport.yaml +23 -0
  58. package/manifests/grafana/deployment.yaml +57 -0
  59. package/manifests/grafana/kustomization.yaml +7 -0
  60. package/manifests/grafana/pvc.yaml +12 -0
  61. package/manifests/grafana/service.yaml +14 -0
  62. package/manifests/kind-config-dev.yaml +12 -0
  63. package/manifests/kind-config.yaml +12 -0
  64. package/manifests/kubeadm-calico-config.yaml +119 -0
  65. package/manifests/kubelet-config.yaml +65 -0
  66. package/manifests/letsencrypt-prod.yaml +15 -0
  67. package/manifests/lxd/lxd-admin-profile.yaml +17 -0
  68. package/manifests/lxd/lxd-preseed.yaml +30 -0
  69. package/manifests/lxd/underpost-setup.sh +163 -0
  70. package/manifests/mariadb/config.yaml +10 -0
  71. package/manifests/mariadb/kustomization.yaml +9 -0
  72. package/manifests/mariadb/pv.yaml +12 -0
  73. package/manifests/mariadb/pvc.yaml +10 -0
  74. package/manifests/mariadb/secret.yaml +8 -0
  75. package/manifests/mariadb/service.yaml +10 -0
  76. package/manifests/mariadb/statefulset.yaml +56 -0
  77. package/manifests/mariadb/storage-class.yaml +10 -0
  78. package/manifests/mongodb/backup-access.yaml +16 -0
  79. package/manifests/mongodb/backup-cronjob.yaml +42 -0
  80. package/manifests/mongodb/backup-pv-pvc.yaml +22 -0
  81. package/manifests/mongodb/configmap.yaml +26 -0
  82. package/manifests/mongodb/headless-service.yaml +10 -0
  83. package/manifests/mongodb/kustomization.yaml +11 -0
  84. package/manifests/mongodb/pv-pvc.yaml +23 -0
  85. package/manifests/mongodb/statefulset.yaml +126 -0
  86. package/manifests/mongodb/storage-class.yaml +9 -0
  87. package/manifests/mongodb-4.4/kustomization.yaml +7 -0
  88. package/manifests/mongodb-4.4/pv-pvc.yaml +23 -0
  89. package/manifests/mongodb-4.4/service-deployment.yaml +63 -0
  90. package/manifests/mysql/kustomization.yaml +7 -0
  91. package/manifests/mysql/pv-pvc.yaml +27 -0
  92. package/manifests/mysql/statefulset.yaml +55 -0
  93. package/manifests/postgresql/configmap.yaml +9 -0
  94. package/manifests/postgresql/kustomization.yaml +10 -0
  95. package/manifests/postgresql/pv.yaml +15 -0
  96. package/manifests/postgresql/pvc.yaml +13 -0
  97. package/manifests/postgresql/service.yaml +10 -0
  98. package/manifests/postgresql/statefulset.yaml +37 -0
  99. package/manifests/prometheus/deployment.yaml +82 -0
  100. package/manifests/valkey/kustomization.yaml +7 -0
  101. package/manifests/valkey/service.yaml +11 -0
  102. package/manifests/valkey/statefulset.yaml +38 -0
  103. package/nodemon.json +6 -0
  104. package/package.json +118 -0
  105. package/proxy.yaml +35 -0
  106. package/scripts/device-scan.sh +43 -0
  107. package/scripts/gpu-diag.sh +19 -0
  108. package/scripts/maas-setup.sh +120 -0
  109. package/scripts/nat-iptables.sh +26 -0
  110. package/scripts/nvim.sh +91 -0
  111. package/scripts/snap-clean.sh +26 -0
  112. package/scripts/ssh-cluster-info.sh +14 -0
  113. package/scripts/ssl.sh +164 -0
  114. package/src/api/blockchain/blockchain.controller.js +51 -0
  115. package/src/api/blockchain/blockchain.model.js +90 -0
  116. package/src/api/blockchain/blockchain.router.js +21 -0
  117. package/src/api/blockchain/blockchain.service.js +24 -0
  118. package/src/api/core/core.controller.js +69 -0
  119. package/src/api/core/core.model.js +11 -0
  120. package/src/api/core/core.router.js +24 -0
  121. package/src/api/core/core.service.js +35 -0
  122. package/src/api/crypto/crypto.controller.js +51 -0
  123. package/src/api/crypto/crypto.model.js +23 -0
  124. package/src/api/crypto/crypto.router.js +20 -0
  125. package/src/api/crypto/crypto.service.js +64 -0
  126. package/src/api/default/default.controller.js +74 -0
  127. package/src/api/default/default.model.js +20 -0
  128. package/src/api/default/default.router.js +27 -0
  129. package/src/api/default/default.service.js +40 -0
  130. package/src/api/document/document.controller.js +66 -0
  131. package/src/api/document/document.model.js +51 -0
  132. package/src/api/document/document.router.js +24 -0
  133. package/src/api/document/document.service.js +133 -0
  134. package/src/api/file/file.controller.js +67 -0
  135. package/src/api/file/file.model.js +19 -0
  136. package/src/api/file/file.router.js +22 -0
  137. package/src/api/file/file.service.js +100 -0
  138. package/src/api/instance/instance.controller.js +69 -0
  139. package/src/api/instance/instance.model.js +40 -0
  140. package/src/api/instance/instance.router.js +34 -0
  141. package/src/api/instance/instance.service.js +70 -0
  142. package/src/api/ipfs/ipfs.controller.js +51 -0
  143. package/src/api/ipfs/ipfs.model.js +17 -0
  144. package/src/api/ipfs/ipfs.router.js +20 -0
  145. package/src/api/ipfs/ipfs.service.js +25 -0
  146. package/src/api/object-layer/README.md +85 -0
  147. package/src/api/object-layer/object-layer.controller.js +69 -0
  148. package/src/api/object-layer/object-layer.model.js +181 -0
  149. package/src/api/object-layer/object-layer.router.js +29 -0
  150. package/src/api/object-layer/object-layer.service.js +49 -0
  151. package/src/api/test/test.controller.js +59 -0
  152. package/src/api/test/test.model.js +14 -0
  153. package/src/api/test/test.router.js +21 -0
  154. package/src/api/test/test.service.js +35 -0
  155. package/src/api/user/postman_collection.json +216 -0
  156. package/src/api/user/user.build.js +16 -0
  157. package/src/api/user/user.controller.js +35 -0
  158. package/src/api/user/user.model.js +100 -0
  159. package/src/api/user/user.router.js +400 -0
  160. package/src/api/user/user.service.js +500 -0
  161. package/src/api.js +23 -0
  162. package/src/cli/baremetal.js +1310 -0
  163. package/src/cli/cloud-init.js +548 -0
  164. package/src/cli/cluster.js +834 -0
  165. package/src/cli/cron.js +95 -0
  166. package/src/cli/db.js +414 -0
  167. package/src/cli/deploy.js +661 -0
  168. package/src/cli/env.js +101 -0
  169. package/src/cli/fs.js +256 -0
  170. package/src/cli/image.js +156 -0
  171. package/src/cli/index.js +436 -0
  172. package/src/cli/lxd.js +402 -0
  173. package/src/cli/monitor.js +260 -0
  174. package/src/cli/repository.js +274 -0
  175. package/src/cli/run.js +728 -0
  176. package/src/cli/script.js +85 -0
  177. package/src/cli/secrets.js +71 -0
  178. package/src/cli/ssh.js +46 -0
  179. package/src/cli/test.js +159 -0
  180. package/src/client/Cyberia.index.js +50 -0
  181. package/src/client/CyberiaAdmin.index.js +34 -0
  182. package/src/client/CyberiaPortal.index.js +36 -0
  183. package/src/client/Default.index.js +84 -0
  184. package/src/client/components/core/404.js +20 -0
  185. package/src/client/components/core/500.js +20 -0
  186. package/src/client/components/core/Account.js +326 -0
  187. package/src/client/components/core/AgGrid.js +191 -0
  188. package/src/client/components/core/Alert.js +77 -0
  189. package/src/client/components/core/Auth.js +342 -0
  190. package/src/client/components/core/Badge.js +32 -0
  191. package/src/client/components/core/Blockchain.js +41 -0
  192. package/src/client/components/core/Blog.js +9 -0
  193. package/src/client/components/core/BtnIcon.js +111 -0
  194. package/src/client/components/core/CalendarCore.js +464 -0
  195. package/src/client/components/core/Chat.js +64 -0
  196. package/src/client/components/core/ColorPalette.js +5267 -0
  197. package/src/client/components/core/CommonJs.js +1010 -0
  198. package/src/client/components/core/Content.js +196 -0
  199. package/src/client/components/core/Css.js +1099 -0
  200. package/src/client/components/core/CssCore.js +882 -0
  201. package/src/client/components/core/D3Chart.js +44 -0
  202. package/src/client/components/core/Docs.js +376 -0
  203. package/src/client/components/core/DropDown.js +223 -0
  204. package/src/client/components/core/EventsUI.js +133 -0
  205. package/src/client/components/core/FileExplorer.js +707 -0
  206. package/src/client/components/core/FullScreen.js +36 -0
  207. package/src/client/components/core/Input.js +383 -0
  208. package/src/client/components/core/JoyStick.js +80 -0
  209. package/src/client/components/core/Keyboard.js +73 -0
  210. package/src/client/components/core/LoadingAnimation.js +159 -0
  211. package/src/client/components/core/LogIn.js +190 -0
  212. package/src/client/components/core/LogOut.js +63 -0
  213. package/src/client/components/core/Logger.js +29 -0
  214. package/src/client/components/core/Modal.js +2494 -0
  215. package/src/client/components/core/NotificationManager.js +84 -0
  216. package/src/client/components/core/ObjectLayerEngine.js +1229 -0
  217. package/src/client/components/core/ObjectLayerEngineModal.js +443 -0
  218. package/src/client/components/core/Pagination.js +207 -0
  219. package/src/client/components/core/Panel.js +772 -0
  220. package/src/client/components/core/PanelForm.js +627 -0
  221. package/src/client/components/core/Polyhedron.js +162 -0
  222. package/src/client/components/core/Recover.js +207 -0
  223. package/src/client/components/core/Responsive.js +82 -0
  224. package/src/client/components/core/RichText.js +43 -0
  225. package/src/client/components/core/Router.js +317 -0
  226. package/src/client/components/core/Scroll.js +76 -0
  227. package/src/client/components/core/SignUp.js +125 -0
  228. package/src/client/components/core/SocketIo.js +74 -0
  229. package/src/client/components/core/Stream.js +113 -0
  230. package/src/client/components/core/ToggleSwitch.js +101 -0
  231. package/src/client/components/core/ToolTip.js +90 -0
  232. package/src/client/components/core/Translate.js +522 -0
  233. package/src/client/components/core/Validator.js +115 -0
  234. package/src/client/components/core/VanillaJs.js +423 -0
  235. package/src/client/components/core/Wallet.js +106 -0
  236. package/src/client/components/core/WebComponent.js +44 -0
  237. package/src/client/components/core/Webhook.js +25 -0
  238. package/src/client/components/core/Worker.js +371 -0
  239. package/src/client/components/core/windowGetDimensions.js +269 -0
  240. package/src/client/components/cyberia/BagCyberia.js +1253 -0
  241. package/src/client/components/cyberia/BiomeCyberia.js +130 -0
  242. package/src/client/components/cyberia/CharacterCyberia.js +321 -0
  243. package/src/client/components/cyberia/CommonCyberia.js +1834 -0
  244. package/src/client/components/cyberia/CssCyberia.js +816 -0
  245. package/src/client/components/cyberia/ElementPreviewCyberia.js +183 -0
  246. package/src/client/components/cyberia/ElementsCyberia.js +146 -0
  247. package/src/client/components/cyberia/InteractionPanelCyberia.js +1043 -0
  248. package/src/client/components/cyberia/JoyStickCyberia.js +53 -0
  249. package/src/client/components/cyberia/LogInCyberia.js +68 -0
  250. package/src/client/components/cyberia/LogOutCyberia.js +24 -0
  251. package/src/client/components/cyberia/MainUserCyberia.js +424 -0
  252. package/src/client/components/cyberia/MapCyberia.js +160 -0
  253. package/src/client/components/cyberia/MatrixCyberia.js +147 -0
  254. package/src/client/components/cyberia/MenuCyberia.js +575 -0
  255. package/src/client/components/cyberia/PixiCyberia.js +1639 -0
  256. package/src/client/components/cyberia/PointAndClickMovementCyberia.js +146 -0
  257. package/src/client/components/cyberia/QuestCyberia.js +1420 -0
  258. package/src/client/components/cyberia/RoutesCyberia.js +47 -0
  259. package/src/client/components/cyberia/SettingsCyberia.js +16 -0
  260. package/src/client/components/cyberia/SignUpCyberia.js +14 -0
  261. package/src/client/components/cyberia/SkillCyberia.js +124 -0
  262. package/src/client/components/cyberia/SocketIoCyberia.js +211 -0
  263. package/src/client/components/cyberia/TileCyberia.js +685 -0
  264. package/src/client/components/cyberia/TranslateCyberia.js +96 -0
  265. package/src/client/components/cyberia/UniverseCyberia.js +14 -0
  266. package/src/client/components/cyberia/WebhookCyberia.js +13 -0
  267. package/src/client/components/cyberia/WikiCyberia.js +144 -0
  268. package/src/client/components/cyberia/WorldCyberia.js +680 -0
  269. package/src/client/components/cyberia-admin/BiomeCyberiaAdmin.js +978 -0
  270. package/src/client/components/cyberia-admin/CommonCyberiaAdmin.js +29 -0
  271. package/src/client/components/cyberia-admin/CssCyberiaAdmin.js +15 -0
  272. package/src/client/components/cyberia-admin/ElementsCyberiaAdmin.js +38 -0
  273. package/src/client/components/cyberia-admin/InstanceEngineCyberiaAdmin.js +180 -0
  274. package/src/client/components/cyberia-admin/LogInCyberiaAdmin.js +34 -0
  275. package/src/client/components/cyberia-admin/LogOutCyberiaAdmin.js +24 -0
  276. package/src/client/components/cyberia-admin/MenuCyberiaAdmin.js +660 -0
  277. package/src/client/components/cyberia-admin/RoutesCyberiaAdmin.js +57 -0
  278. package/src/client/components/cyberia-admin/ServerCyberiaAdmin.js +129 -0
  279. package/src/client/components/cyberia-admin/SettingsCyberiaAdmin.js +16 -0
  280. package/src/client/components/cyberia-admin/SignUpCyberiaAdmin.js +11 -0
  281. package/src/client/components/cyberia-admin/SocketIoCyberiaAdmin.js +53 -0
  282. package/src/client/components/cyberia-admin/TranslateCyberiaAdmin.js +7 -0
  283. package/src/client/components/cyberia-biome/CityCyberiaBiome.js +209 -0
  284. package/src/client/components/cyberia-biome/CityInteriorCyberiaBiome.js +253 -0
  285. package/src/client/components/cyberia-biome/ColorChaosCyberiaBiome.js +26 -0
  286. package/src/client/components/cyberia-biome/ForestCyberiaBiome.js +191 -0
  287. package/src/client/components/cyberia-biome/GridBaseCyberiaBiome.js +364 -0
  288. package/src/client/components/cyberia-biome/SeedCityCyberiaBiome.js +347 -0
  289. package/src/client/components/cyberia-biome/ShopCyberiaBiome.js +12 -0
  290. package/src/client/components/cyberia-biome/SpaceCyberiaBiome.js +58 -0
  291. package/src/client/components/cyberia-portal/CommonCyberiaPortal.js +29 -0
  292. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +132 -0
  293. package/src/client/components/cyberia-portal/ElementsCyberiaPortal.js +38 -0
  294. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +18 -0
  295. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +12 -0
  296. package/src/client/components/cyberia-portal/MenuCyberiaPortal.js +487 -0
  297. package/src/client/components/cyberia-portal/RoutesCyberiaPortal.js +45 -0
  298. package/src/client/components/cyberia-portal/ServerCyberiaPortal.js +136 -0
  299. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +16 -0
  300. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +11 -0
  301. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +52 -0
  302. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +12 -0
  303. package/src/client/components/default/CommonDefault.js +29 -0
  304. package/src/client/components/default/CssDefault.js +27 -0
  305. package/src/client/components/default/ElementsDefault.js +38 -0
  306. package/src/client/components/default/LogInDefault.js +14 -0
  307. package/src/client/components/default/LogOutDefault.js +10 -0
  308. package/src/client/components/default/MenuDefault.js +743 -0
  309. package/src/client/components/default/RoutesDefault.js +48 -0
  310. package/src/client/components/default/SettingsDefault.js +16 -0
  311. package/src/client/components/default/SignUpDefault.js +9 -0
  312. package/src/client/components/default/SocketIoDefault.js +54 -0
  313. package/src/client/components/default/TranslateDefault.js +7 -0
  314. package/src/client/public/default/android-chrome-144x144.png +0 -0
  315. package/src/client/public/default/android-chrome-192x192.png +0 -0
  316. package/src/client/public/default/android-chrome-256x256.png +0 -0
  317. package/src/client/public/default/android-chrome-36x36.png +0 -0
  318. package/src/client/public/default/android-chrome-384x384.png +0 -0
  319. package/src/client/public/default/android-chrome-48x48.png +0 -0
  320. package/src/client/public/default/android-chrome-512x512.png +0 -0
  321. package/src/client/public/default/android-chrome-72x72.png +0 -0
  322. package/src/client/public/default/android-chrome-96x96.png +0 -0
  323. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  324. package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
  325. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  326. package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
  327. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  328. package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
  329. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  330. package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
  331. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  332. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  333. package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
  334. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  335. package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
  336. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  337. package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
  338. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  339. package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
  340. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  341. package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
  342. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  343. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  344. package/src/client/public/default/apple-touch-icon.png +0 -0
  345. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  346. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  347. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  348. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  349. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  350. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  351. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  352. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  353. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  354. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  355. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  356. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  357. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  358. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  359. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  360. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  361. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  362. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  363. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  364. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  365. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  366. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  367. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  368. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  369. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  370. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  371. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  372. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  373. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  374. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  375. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  376. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  377. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  378. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  379. package/src/client/public/default/assets/background/dark.jpg +0 -0
  380. package/src/client/public/default/assets/background/dark.svg +557 -0
  381. package/src/client/public/default/assets/background/white.jpg +0 -0
  382. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  383. package/src/client/public/default/assets/background/white0.jpg +0 -0
  384. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  385. package/src/client/public/default/assets/logo/underpost.gif +0 -0
  386. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  387. package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
  388. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  389. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  390. package/src/client/public/default/browserconfig.xml +12 -0
  391. package/src/client/public/default/favicon-16x16.png +0 -0
  392. package/src/client/public/default/favicon-32x32.png +0 -0
  393. package/src/client/public/default/favicon-48x48.png +0 -0
  394. package/src/client/public/default/favicon.ico +0 -0
  395. package/src/client/public/default/manifest.webmanifest +69 -0
  396. package/src/client/public/default/mstile-144x144.png +0 -0
  397. package/src/client/public/default/mstile-150x150.png +0 -0
  398. package/src/client/public/default/mstile-310x150.png +0 -0
  399. package/src/client/public/default/mstile-310x310.png +0 -0
  400. package/src/client/public/default/mstile-70x70.png +0 -0
  401. package/src/client/public/default/plantuml/client-conf.svg +1 -0
  402. package/src/client/public/default/plantuml/client-schema.svg +1 -0
  403. package/src/client/public/default/plantuml/cron-conf.svg +1 -0
  404. package/src/client/public/default/plantuml/cron-schema.svg +1 -0
  405. package/src/client/public/default/plantuml/server-conf.svg +1 -0
  406. package/src/client/public/default/plantuml/server-schema.svg +1 -0
  407. package/src/client/public/default/plantuml/ssr-conf.svg +1 -0
  408. package/src/client/public/default/plantuml/ssr-schema.svg +1 -0
  409. package/src/client/public/default/safari-pinned-tab.svg +24 -0
  410. package/src/client/public/default/site.webmanifest +69 -0
  411. package/src/client/public/default/sitemap +148 -0
  412. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  413. package/src/client/public/default/yandex-browser-manifest.json +9 -0
  414. package/src/client/public/doc/favicon.ico +0 -0
  415. package/src/client/public/doc/sitemap +148 -0
  416. package/src/client/public/test/favicon.ico +0 -0
  417. package/src/client/public/test/sitemap +148 -0
  418. package/src/client/services/blockchain/blockchain.service.js +73 -0
  419. package/src/client/services/core/core.service.js +165 -0
  420. package/src/client/services/crypto/crypto.service.js +73 -0
  421. package/src/client/services/default/default.management.js +450 -0
  422. package/src/client/services/default/default.service.js +98 -0
  423. package/src/client/services/document/document.service.js +97 -0
  424. package/src/client/services/file/file.service.js +72 -0
  425. package/src/client/services/instance/instance.management.js +78 -0
  426. package/src/client/services/instance/instance.service.js +97 -0
  427. package/src/client/services/ipfs/ipfs.service.js +73 -0
  428. package/src/client/services/object-layer/object-layer.service.js +93 -0
  429. package/src/client/services/test/test.service.js +73 -0
  430. package/src/client/services/user/user.management.js +56 -0
  431. package/src/client/services/user/user.service.js +108 -0
  432. package/src/client/ssr/Render.js +237 -0
  433. package/src/client/ssr/body/404.js +73 -0
  434. package/src/client/ssr/body/500.js +72 -0
  435. package/src/client/ssr/body/CacheControl.js +114 -0
  436. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +90 -0
  437. package/src/client/ssr/body/CyberiaSplashScreenLore.js +424 -0
  438. package/src/client/ssr/body/DefaultSplashScreen.js +90 -0
  439. package/src/client/ssr/email/DefaultRecoverEmail.js +21 -0
  440. package/src/client/ssr/email/DefaultVerifyEmail.js +17 -0
  441. package/src/client/ssr/head/Css.js +241 -0
  442. package/src/client/ssr/head/CyberiaAdminScripts.js +6 -0
  443. package/src/client/ssr/head/CyberiaPortalScripts.js +6 -0
  444. package/src/client/ssr/head/CyberiaScripts.js +6 -0
  445. package/src/client/ssr/head/DefaultScripts.js +6 -0
  446. package/src/client/ssr/head/Microdata.js +11 -0
  447. package/src/client/ssr/head/Production.js +1 -0
  448. package/src/client/ssr/head/Pwa.js +146 -0
  449. package/src/client/ssr/head/Seo.js +15 -0
  450. package/src/client/ssr/mailer/DefaultRecoverEmail.js +21 -0
  451. package/src/client/ssr/mailer/DefaultVerifyEmail.js +17 -0
  452. package/src/client/ssr/offline/Maintenance.js +63 -0
  453. package/src/client/ssr/offline/NoNetworkConnection.js +67 -0
  454. package/src/client/ssr/pages/404.js +12 -0
  455. package/src/client/ssr/pages/500.js +12 -0
  456. package/src/client/ssr/pages/Test.js +198 -0
  457. package/src/client/ssr/pages/maintenance.js +14 -0
  458. package/src/client/ssr/pages/offline.js +21 -0
  459. package/src/client/sw/default.sw.js +108 -0
  460. package/src/client/sw/template.sw.js +84 -0
  461. package/src/client.build.js +22 -0
  462. package/src/client.dev.js +24 -0
  463. package/src/db/DataBaseProvider.js +98 -0
  464. package/src/db/mariadb/MariaDB.js +66 -0
  465. package/src/db/mongo/MongooseDB.js +70 -0
  466. package/src/index.js +198 -0
  467. package/src/mailer/EmailRender.js +116 -0
  468. package/src/mailer/MailerProvider.js +213 -0
  469. package/src/monitor.js +24 -0
  470. package/src/proxy.js +22 -0
  471. package/src/runtime/express/Express.js +256 -0
  472. package/src/runtime/lampp/Dockerfile +50 -0
  473. package/src/runtime/lampp/Lampp.js +343 -0
  474. package/src/server/auth.js +689 -0
  475. package/src/server/backup.js +96 -0
  476. package/src/server/client-build-docs.js +205 -0
  477. package/src/server/client-build-live.js +109 -0
  478. package/src/server/client-build.js +690 -0
  479. package/src/server/client-dev-server.js +87 -0
  480. package/src/server/client-formatted.js +87 -0
  481. package/src/server/client-icons.js +108 -0
  482. package/src/server/conf.js +1071 -0
  483. package/src/server/crypto.js +210 -0
  484. package/src/server/dns.js +276 -0
  485. package/src/server/downloader.js +74 -0
  486. package/src/server/json-schema.js +77 -0
  487. package/src/server/logger.js +197 -0
  488. package/src/server/network.js +72 -0
  489. package/src/server/object-layer.js +294 -0
  490. package/src/server/peer.js +69 -0
  491. package/src/server/process.js +171 -0
  492. package/src/server/proxy.js +110 -0
  493. package/src/server/runtime.js +170 -0
  494. package/src/server/ssr.js +127 -0
  495. package/src/server/start.js +161 -0
  496. package/src/server/tls.js +251 -0
  497. package/src/server/valkey.js +293 -0
  498. package/src/server.js +25 -0
  499. package/src/ws/IoInterface.js +139 -0
  500. package/src/ws/IoServer.js +88 -0
  501. package/src/ws/core/channels/core.ws.chat.js +23 -0
  502. package/src/ws/core/channels/core.ws.mailer.js +35 -0
  503. package/src/ws/core/channels/core.ws.stream.js +31 -0
  504. package/src/ws/core/core.ws.connection.js +62 -0
  505. package/src/ws/core/core.ws.emit.js +53 -0
  506. package/src/ws/core/core.ws.server.js +76 -0
  507. package/src/ws/core/management/core.ws.chat.js +8 -0
  508. package/src/ws/core/management/core.ws.mailer.js +16 -0
  509. package/src/ws/core/management/core.ws.stream.js +8 -0
  510. package/src/ws/cyberia/channels/cyberia.ws.bot.js +56 -0
  511. package/src/ws/cyberia/channels/cyberia.ws.skill.js +51 -0
  512. package/src/ws/cyberia/channels/cyberia.ws.user.js +437 -0
  513. package/src/ws/cyberia/cyberia.ws.connection.js +36 -0
  514. package/src/ws/cyberia/cyberia.ws.emit.js +14 -0
  515. package/src/ws/cyberia/cyberia.ws.server.js +67 -0
  516. package/src/ws/cyberia/management/cyberia.ws.bot.js +669 -0
  517. package/src/ws/cyberia/management/cyberia.ws.skill.js +441 -0
  518. package/src/ws/cyberia/management/cyberia.ws.user.js +188 -0
  519. package/src/ws/default/channels/default.ws.main.js +16 -0
  520. package/src/ws/default/default.ws.connection.js +22 -0
  521. package/src/ws/default/default.ws.emit.js +14 -0
  522. package/src/ws/default/default.ws.server.js +20 -0
  523. package/src/ws/default/management/default.ws.main.js +8 -0
  524. package/test/api.test.js +53 -0
  525. package/test/crypto.test.js +117 -0
@@ -0,0 +1,2494 @@
1
+ import { getId, newInstance, s4 } from './CommonJs.js';
2
+ import { Draggable } from '@neodrag/vanilla';
3
+ import { append, s, prepend, htmls, sa, getAllChildNodes, isActiveElement } from './VanillaJs.js';
4
+ import { BtnIcon } from './BtnIcon.js';
5
+ import { Responsive } from './Responsive.js';
6
+ import { loggerFactory } from './Logger.js';
7
+ import {
8
+ Css,
9
+ ThemeEvents,
10
+ Themes,
11
+ ThemesScope,
12
+ darkTheme,
13
+ renderStyleTag,
14
+ renderStatus,
15
+ renderCssAttr,
16
+ } from './Css.js';
17
+ import {
18
+ setDocTitle,
19
+ closeModalRouteChangeEvent,
20
+ handleModalViewRoute,
21
+ getProxyPath,
22
+ setPath,
23
+ coreUI,
24
+ sanitizeRoute,
25
+ getQueryParams,
26
+ } from './Router.js';
27
+ import { NotificationManager } from './NotificationManager.js';
28
+ import { EventsUI } from './EventsUI.js';
29
+ import { Translate } from './Translate.js';
30
+ import { Input, isTextInputFocused } from './Input.js';
31
+ import { DropDown } from './DropDown.js';
32
+ import { Keyboard } from './Keyboard.js';
33
+ import { Badge } from './Badge.js';
34
+ import { Worker } from './Worker.js';
35
+ import { Scroll } from './Scroll.js';
36
+ import { windowGetH, windowGetW } from './windowGetDimensions.js';
37
+
38
+ const logger = loggerFactory(import.meta, { trace: true });
39
+
40
+ const Modal = {
41
+ Data: {},
42
+
43
+ Render: async function (
44
+ options = {
45
+ id: '',
46
+ barConfig: {},
47
+ title: '',
48
+ html: '',
49
+ handleType: 'bar',
50
+ mode: '' /* slide-menu */,
51
+ RouterInstance: {},
52
+ disableTools: [],
53
+ observer: false,
54
+ disableBoxShadow: false,
55
+ },
56
+ ) {
57
+ if (options.heightBottomBar === undefined) options.heightBottomBar = 50;
58
+ if (options.heightTopBar === undefined) options.heightTopBar = 50;
59
+ let originHeightBottomBar = options.heightBottomBar ? newInstance(options.heightBottomBar) : 0;
60
+ let originHeightTopBar = options.heightTopBar ? newInstance(options.heightTopBar) : 0;
61
+ let width = 300;
62
+ let height = 400;
63
+ let top = options.style?.top ? options.style.top : 0;
64
+ let left = options.style?.left ? options.style.left : 0;
65
+ const topBottomBarEnable = options && options.barMode && options.barMode === 'top-bottom-bar';
66
+ if (!topBottomBarEnable) {
67
+ options.heightTopBar = options.heightTopBar + options.heightBottomBar;
68
+ options.heightBottomBar = 0;
69
+ }
70
+ let transition = `opacity 0.3s, box-shadow 0.3s, bottom 0.3s`;
71
+ const originSlideMenuWidth = 320;
72
+ const collapseSlideMenuWidth = 50;
73
+ let slideMenuWidth = originSlideMenuWidth;
74
+ const minWidth = width;
75
+ const heightDefaultTopBar = 50;
76
+ const heightDefaultBottomBar = 0;
77
+ const idModal = options && 'id' in options ? options.id : getId(this.Data, 'modal-');
78
+ this.Data[idModal] = {
79
+ options,
80
+ onCloseListener: {},
81
+ onMenuListener: {},
82
+ onCollapseMenuListener: {},
83
+ onExtendMenuListener: {},
84
+ onDragEndListener: {},
85
+ onObserverListener: {},
86
+ onClickListener: {},
87
+ onExpandUiListener: {},
88
+ onBarUiOpen: {},
89
+ onBarUiClose: {},
90
+ onHome: {},
91
+ homeModals: options.homeModals ? options.homeModals : [],
92
+ query: options.query ? `${window.location.search}` : undefined,
93
+ getTop: () => {
94
+ const result = windowGetH() - (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar);
95
+ return result;
96
+ },
97
+ getHeight: () => {
98
+ return (
99
+ windowGetH() -
100
+ (s(`.main-body-btn-ui-close`) && !s(`.main-body-btn-ui-close`).classList.contains('hide')
101
+ ? (options.heightTopBar ? options.heightTopBar : heightDefaultTopBar) +
102
+ (options.heightBottomBar ? options.heightBottomBar : heightDefaultBottomBar)
103
+ : 0)
104
+ );
105
+ },
106
+ getMenuLeftStyle: (ops = { open: false }) =>
107
+ `${
108
+ options.mode === 'slide-menu-right'
109
+ ? `${
110
+ windowGetW() +
111
+ (ops?.open
112
+ ? -1 * originSlideMenuWidth +
113
+ (options.mode === 'slide-menu-right' && s(`.btn-icon-menu-mode-right`).classList.contains('hide')
114
+ ? originSlideMenuWidth - collapseSlideMenuWidth
115
+ : 0)
116
+ : originSlideMenuWidth)
117
+ }px`
118
+ : `-${ops?.open ? '0px' : originSlideMenuWidth}px`
119
+ }`,
120
+ center: () => {
121
+ top = `${windowGetH() / 2 - height / 2}px`;
122
+ left = `${windowGetW() / 2 - width / 2}px`;
123
+ },
124
+ };
125
+
126
+ if (options && 'mode' in options) {
127
+ Modal.Data[idModal][options.mode] = {};
128
+ switch (options.mode) {
129
+ case 'view':
130
+ // if (options && options.slideMenu) s(`.btn-close-${options.slideMenu}`).click();
131
+ options.zIndexSync = true;
132
+
133
+ options.style = { width: '100%', ...options.style, 'min-width': `${minWidth}px` };
134
+
135
+ if (Modal.mobileModal()) {
136
+ options.barConfig.buttons.restore.disabled = true;
137
+ options.barConfig.buttons.minimize.disabled = true;
138
+ options.dragDisabled = true;
139
+ options.style.resize = 'none';
140
+ setTimeout(() => {
141
+ s(`.btn-close-modal-menu`).click();
142
+ });
143
+ }
144
+
145
+ Responsive.Event[`view-${idModal}`] = () => {
146
+ if (!this.Data[idModal]) return delete Responsive.Event[`view-${idModal}`];
147
+ if (this.Data[idModal].slideMenu) s(`.${idModal}`).style.height = `${this.Data[idModal].getHeight()}px`;
148
+ };
149
+ Responsive.Event[`view-${idModal}`]();
150
+
151
+ // Handle view mode modal route
152
+ if (options.route) {
153
+ handleModalViewRoute({
154
+ route: options.route,
155
+ RouterInstance: options.RouterInstance,
156
+ });
157
+ }
158
+
159
+ break;
160
+ case 'slide-menu':
161
+ case 'slide-menu-right':
162
+ case 'slide-menu-left':
163
+ (async () => {
164
+ if (!options.slideMenuTopBarBannerFix) {
165
+ options.slideMenuTopBarBannerFix = async () => {
166
+ let style = html``;
167
+ if (options.barMode === 'top-bottom-bar') {
168
+ style = html`<style>
169
+ .default-slide-menu-top-bar-fix-logo-container {
170
+ width: 50px;
171
+ height: 50px;
172
+ }
173
+ .default-slide-menu-top-bar-fix-logo {
174
+ width: 40px;
175
+ height: 40px;
176
+ padding: 5px;
177
+ }
178
+ .default-slide-menu-top-bar-fix-title-container-text {
179
+ font-size: 26px;
180
+ top: 8px;
181
+ color: ${darkTheme ? '#ffffff' : '#000000'};
182
+ }
183
+ </style>`;
184
+ } else {
185
+ style = html`<style>
186
+ .default-slide-menu-top-bar-fix-logo-container {
187
+ width: 100px;
188
+ height: 100px;
189
+ }
190
+ .default-slide-menu-top-bar-fix-logo {
191
+ width: 50px;
192
+ height: 50px;
193
+ padding: 24px;
194
+ }
195
+ .default-slide-menu-top-bar-fix-title-container-text {
196
+ font-size: 30px;
197
+ top: 30px;
198
+ color: ${darkTheme ? '#ffffff' : '#000000'};
199
+ }
200
+ </style>`;
201
+ }
202
+ setTimeout(() => {
203
+ if (s(`.top-bar-app-icon`) && s(`.top-bar-app-icon`).src) {
204
+ s(`.default-slide-menu-top-bar-fix-logo`).src = s(`.top-bar-app-icon`).src;
205
+ if (s(`.top-bar-app-icon`).classList.contains('negative-color'))
206
+ s(`.default-slide-menu-top-bar-fix-logo`).classList.add('negative-color');
207
+ htmls(
208
+ `.default-slide-menu-top-bar-fix-title-container`,
209
+ html`
210
+ <div class="inl default-slide-menu-top-bar-fix-title-container-text">${options.title}</div>
211
+ `,
212
+ );
213
+ } else
214
+ htmls(
215
+ `.default-slide-menu-top-bar-fix-logo-container`,
216
+ html`<div class="abs center">${s(`.action-btn-app-icon-render`).innerHTML}</div>`,
217
+ );
218
+ });
219
+
220
+ return html`${style}
221
+ <div class="in fll default-slide-menu-top-bar-fix-logo-container">
222
+ <img class="default-slide-menu-top-bar-fix-logo in fll" />
223
+ </div>
224
+ <div class="in fll default-slide-menu-top-bar-fix-title-container"></div>`;
225
+ };
226
+ }
227
+ const { barConfig } = options;
228
+ options.style = {
229
+ height: `${windowGetH() - options.heightTopBar - options.heightBottomBar}px`,
230
+ width: `${slideMenuWidth}px`,
231
+ // 'overflow-x': 'hidden',
232
+ // overflow: 'visible', // required for tooltip
233
+ 'z-index': 6,
234
+ resize: 'none',
235
+ top: `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`,
236
+ };
237
+ const contentIconClass = 'abs center';
238
+ top = 'auto';
239
+ left = Modal.Data[idModal].getMenuLeftStyle();
240
+ transition = '.3s';
241
+ options.dragDisabled = true;
242
+ options.titleClass = 'hide';
243
+ options.disableCenter = true;
244
+
245
+ // barConfig.buttons.maximize.disabled = true;
246
+ // barConfig.buttons.minimize.disabled = true;
247
+ // barConfig.buttons.restore.disabled = true;
248
+ // barConfig.buttons.menu.disabled = true;
249
+ // barConfig.buttons.close.disabled = true;
250
+ options.btnBarModalClass = 'hide';
251
+ Responsive.Event[`slide-menu-${idModal}`] = () => {
252
+ for (const _idModal of Object.keys(this.Data)) {
253
+ if (this.Data[_idModal].slideMenu && this.Data[_idModal].slideMenu.id === idModal)
254
+ this.Data[_idModal].slideMenu.callBack();
255
+ }
256
+ s(`.${idModal}`).style.height = `${Modal.Data[idModal].getHeight()}px`;
257
+ s(`.${idModal}`).style.left = Modal.Data[idModal].getMenuLeftStyle({
258
+ open: s(`.btn-bar-center-icon-menu`).classList.contains('hide') ? true : false,
259
+ });
260
+ if (s(`.main-body-top`)) {
261
+ if (Modal.mobileModal()) {
262
+ if (s(`.btn-menu-${idModal}`).classList.contains('hide') && collapseSlideMenuWidth !== slideMenuWidth)
263
+ s(`.main-body-top`).classList.remove('hide');
264
+ if (s(`.btn-close-${idModal}`).classList.contains('hide')) s(`.main-body-top`).classList.add('hide');
265
+ } else if (!s(`.main-body-top`).classList.contains('hide')) s(`.main-body-top`).classList.add('hide');
266
+ }
267
+ };
268
+ barConfig.buttons.menu.onClick = () => {
269
+ Modal.Data[idModal][options.mode].width = slideMenuWidth;
270
+ s(`.btn-menu-${idModal}`).classList.add('hide');
271
+ s(`.btn-close-${idModal}`).classList.remove('hide');
272
+ // s(`.${idModal}`).style.width = `${this.Data[idModal][options.mode].width}px`;
273
+ s(`.html-${idModal}`).style.display = 'block';
274
+ // s(`.title-modal-${idModal}`).style.display = 'block';
275
+ s(`.main-body-btn-ui-menu-menu`).classList.add('hide');
276
+ s(`.main-body-btn-ui-menu-close`).classList.remove('hide');
277
+ if (s(`.btn-bar-center-icon-menu`)) {
278
+ s(`.btn-bar-center-icon-close`).classList.remove('hide');
279
+ s(`.btn-bar-center-icon-menu`).classList.add('hide');
280
+ }
281
+
282
+ s(`.main-body-btn-container`).style[
283
+ true || (options.mode && options.mode.match('right')) ? 'right' : 'left'
284
+ ] = options.mode && options.mode.match('right') ? `${slideMenuWidth}px` : '0px';
285
+ if (options.mode === 'slide-menu-right') {
286
+ s(`.${idModal}`).style.left = `${windowGetW() - originSlideMenuWidth}px`;
287
+ } else {
288
+ s(`.${idModal}`).style.left = `0px`;
289
+ }
290
+ Responsive.Event[`slide-menu-${idModal}`]();
291
+ };
292
+ barConfig.buttons.close.onClick = () => {
293
+ Modal.Data[idModal][options.mode].width = 0;
294
+ s(`.btn-close-${idModal}`).classList.add('hide');
295
+ s(`.btn-menu-${idModal}`).classList.remove('hide');
296
+ // s(`.${idModal}`).style.width = `${this.Data[idModal][options.mode].width}px`;
297
+ // s(`.html-${idModal}`).style.display = 'none';
298
+ // s(`.title-modal-${idModal}`).style.display = 'none';
299
+ s(`.main-body-btn-ui-menu-close`).classList.add('hide');
300
+ s(`.main-body-btn-ui-menu-menu`).classList.remove('hide');
301
+ if (s(`.btn-bar-center-icon-menu`)) {
302
+ s(`.btn-bar-center-icon-menu`).classList.remove('hide');
303
+ s(`.btn-bar-center-icon-close`).classList.add('hide');
304
+ }
305
+ s(`.main-body-btn-container`).style[
306
+ true || (options.mode && options.mode.match('right')) ? 'right' : 'left'
307
+ ] = `${0}px`;
308
+ if (options.mode === 'slide-menu-right') {
309
+ s(`.${idModal}`).style.left = `${windowGetW() + originSlideMenuWidth}px`;
310
+ } else {
311
+ s(`.${idModal}`).style.left = `-${originSlideMenuWidth}px`;
312
+ }
313
+ Responsive.Event[`slide-menu-${idModal}`]();
314
+ };
315
+ transition += `, width 0.3s`;
316
+
317
+ setTimeout(() => {
318
+ setTimeout(btnCloseEvent);
319
+ append(
320
+ 'body',
321
+ html`
322
+ <div
323
+ class="abs main-body-btn-container hide"
324
+ style="top: ${options.heightTopBar + 50}px; z-index: 9; ${true ||
325
+ (options.mode && options.mode.match('right'))
326
+ ? 'right'
327
+ : 'left'}: 0px; width: 50px; height: 150px; transition: .3s"
328
+ >
329
+ <div
330
+ class="abs main-body-btn main-body-btn-ui"
331
+ style="top: 0px; ${true || (options.mode && options.mode.match('right')) ? 'right' : 'left'}: 0px"
332
+ >
333
+ <div class="abs center">
334
+ <i class="fas fa-caret-down main-body-btn-ui-open hide"></i>
335
+ <i class="fas fa-caret-up main-body-btn-ui-close"></i>
336
+ </div>
337
+ </div>
338
+ <div
339
+ class="abs main-body-btn main-body-btn-menu"
340
+ style="top: 50px; ${true || (options.mode && options.mode.match('right'))
341
+ ? 'right'
342
+ : 'left'}: 0px"
343
+ >
344
+ <div class="abs center">
345
+ <i class="fa-solid fa-xmark hide main-body-btn-ui-menu-close"></i>
346
+ <i class="fa-solid fa-bars main-body-btn-ui-menu-menu"></i>
347
+ </div>
348
+ </div>
349
+ <div
350
+ class="abs main-body-btn main-body-btn-bar-custom ${options?.slideMenuTopBarBannerFix
351
+ ? ''
352
+ : 'hide'}"
353
+ style="top: 100px; ${true || (options.mode && options.mode.match('right'))
354
+ ? 'right'
355
+ : 'left'}: 0px"
356
+ >
357
+ <div class="abs center">
358
+ <i class="fa-solid fa-magnifying-glass main-body-btn-ui-bar-custom-open"></i>
359
+ <i class="fa-solid fa-home hide main-body-btn-ui-bar-custom-close"></i>
360
+ </div>
361
+ </div>
362
+ </div>
363
+ `,
364
+ );
365
+
366
+ s(`.main-body-btn-menu`).onclick = () => {
367
+ Modal.actionBtnCenter();
368
+ };
369
+
370
+ s(`.main-body-btn-bar-custom`).onclick = () => {
371
+ if (s(`.main-body-btn-ui-close`).classList.contains('hide')) {
372
+ s(`.main-body-btn-ui`).click();
373
+ }
374
+ if (s(`.main-body-btn-ui-bar-custom-open`).classList.contains('hide')) {
375
+ s(`.main-body-btn-ui-bar-custom-open`).classList.remove('hide');
376
+ s(`.main-body-btn-ui-bar-custom-close`).classList.add('hide');
377
+ s(`.slide-menu-top-bar-fix`).style.top = '0px';
378
+ } else {
379
+ s(`.main-body-btn-ui-bar-custom-open`).classList.add('hide');
380
+ s(`.main-body-btn-ui-bar-custom-close`).classList.remove('hide');
381
+ s(`.slide-menu-top-bar-fix`).style.top = '-100px';
382
+ s(`.top-bar-search-box-container`).click();
383
+ }
384
+ if (Modal.mobileModal()) {
385
+ btnCloseEvent();
386
+ }
387
+ };
388
+
389
+ let _heightTopBar, _heightBottomBar, _topMenu;
390
+ s(`.main-body-btn-ui`).onclick = () => {
391
+ if (s(`.main-body-btn-ui-open`).classList.contains('hide')) {
392
+ s(`.main-body-btn-ui-open`).classList.remove('hide');
393
+ s(`.main-body-btn-ui-close`).classList.add('hide');
394
+ _heightTopBar = newInstance(options.heightTopBar);
395
+ _heightBottomBar = newInstance(options.heightBottomBar);
396
+ _topMenu = newInstance(s(`.modal-menu`).style.top);
397
+ options.heightTopBar = 0;
398
+ options.heightBottomBar = 0;
399
+ s(`.slide-menu-top-bar`).classList.add('hide');
400
+ s(`.bottom-bar`).classList.add('hide');
401
+ s(`.modal-menu`).style.top = '0px';
402
+ s(`.main-body-btn-container`).style.top = '50px';
403
+ s(`.main-body`).style.top = '0px';
404
+ s(`.main-body`).style.height = `${windowGetH()}px`;
405
+ for (const event of Object.keys(Modal.Data[idModal].onBarUiClose))
406
+ Modal.Data[idModal].onBarUiClose[event]();
407
+ } else {
408
+ s(`.main-body-btn-ui-close`).classList.remove('hide');
409
+ s(`.main-body-btn-ui-open`).classList.add('hide');
410
+ options.heightTopBar = _heightTopBar;
411
+ options.heightBottomBar = _heightBottomBar;
412
+ s(`.modal-menu`).style.top = _topMenu;
413
+ s(`.main-body-btn-container`).style.top = `${options.heightTopBar + 50}px`;
414
+ s(`.slide-menu-top-bar`).classList.remove('hide');
415
+ s(`.bottom-bar`).classList.remove('hide');
416
+ s(`.main-body`).style.top = `${options.heightTopBar}px`;
417
+ s(`.main-body`).style.height = `${windowGetH() - options.heightTopBar}px`;
418
+ for (const event of Object.keys(Modal.Data[idModal].onBarUiOpen))
419
+ Modal.Data[idModal].onBarUiOpen[event]();
420
+ }
421
+ Responsive.Event[`slide-menu-modal-menu`]();
422
+ Object.keys(this.Data).map((_idModal) => {
423
+ if (this.Data[_idModal].slideMenu) {
424
+ if (s(`.btn-maximize-${_idModal}`)) s(`.btn-maximize-${_idModal}`).click();
425
+ }
426
+ });
427
+ Responsive.Event[`view-${'main-body'}`]();
428
+ if (Responsive.Event[`view-${'bottom-bar'}`]) Responsive.Event[`view-${'bottom-bar'}`]();
429
+ if (Responsive.Event[`view-${'main-body-top'}`]) Responsive.Event[`view-${'main-body-top'}`]();
430
+ for (const keyEvent of Object.keys(this.Data[idModal].onExpandUiListener)) {
431
+ this.Data[idModal].onExpandUiListener[keyEvent](
432
+ !s(`.main-body-btn-ui-open`).classList.contains('hide'),
433
+ );
434
+ }
435
+ };
436
+ Modal.setTopBannerLink();
437
+ });
438
+
439
+ const inputSearchBoxId = `top-bar-search-box`;
440
+ append(
441
+ 'body',
442
+ html` <div class="fix modal slide-menu-top-bar">
443
+ <div
444
+ class="fl top-bar ${options.barClass ? options.barClass : ''}"
445
+ style="height: ${originHeightTopBar}px;"
446
+ >
447
+ ${await BtnIcon.Render({
448
+ style: `height: 100%`,
449
+ class: 'in fll main-btn-menu action-bar-box action-btn-close hide',
450
+ label: html` <div class="${contentIconClass} action-btn-close-render">
451
+ <i class="fa-solid fa-xmark"></i>
452
+ </div>`,
453
+ })}
454
+ ${await BtnIcon.Render({
455
+ style: `height: 100%`,
456
+ class: `in fll main-btn-menu action-bar-box action-btn-app-icon ${
457
+ options?.disableTools?.includes('app-icon') ? 'hide' : ''
458
+ }`,
459
+ label: html` <div class="${contentIconClass} action-btn-app-icon-render"></div>`,
460
+ })}
461
+ <form
462
+ class="in fll top-bar-search-box-container hover ${options?.disableTools?.includes('text-box')
463
+ ? 'hide'
464
+ : ''}"
465
+ >
466
+ ${await Input.Render({
467
+ id: inputSearchBoxId,
468
+ placeholder: Modal.mobileModal() ? Translate.Render('search', '.top-bar-search-box') : undefined, // html`<i class="fa-solid fa-magnifying-glass"></i> ${Translate.Render('search')}`,
469
+ placeholderIcon: html`<div
470
+ class="in fll"
471
+ style="width: ${originHeightTopBar}px; height: ${originHeightTopBar}px;"
472
+ >
473
+ <div class="abs center"><i class="fa-solid fa-magnifying-glass"></i></div>
474
+ ${!Modal.mobileModal()
475
+ ? html` <div
476
+ class="inl wfm key-shortcut-container-info"
477
+ style="${renderCssAttr({ style: { top: '10px', left: '60px' } })}"
478
+ >
479
+ ${await Badge.Render({
480
+ id: 'shortcut-key-info-search',
481
+ text: 'Shift',
482
+ classList: 'inl',
483
+ style: { 'z-index': 1 },
484
+ })}
485
+ ${await Badge.Render({
486
+ id: 'shortcut-key-info-search',
487
+ text: '+',
488
+ classList: 'inl',
489
+ style: { 'z-index': 1, background: 'none', color: '#5f5f5f' },
490
+ })}
491
+ ${await Badge.Render({
492
+ id: 'shortcut-key-info-search',
493
+ text: 'k',
494
+ classList: 'inl',
495
+ style: { 'z-index': 1 },
496
+ })}
497
+ </div>`
498
+ : ''}
499
+ </div>`,
500
+ inputClass: 'in fll',
501
+ // containerClass: '',
502
+ })}
503
+ </form>
504
+ <div
505
+ class="abs top-box-profile-container ${options?.disableTools?.includes('profile') ? 'hide' : ''}"
506
+ >
507
+ ${await BtnIcon.Render({
508
+ style: `height: 100%`,
509
+ class: 'in fll session-in-log-in main-btn-menu action-bar-box action-btn-profile-log-in',
510
+ label: html` <div class="${contentIconClass} action-btn-profile-log-in-render"></div>`,
511
+ })}
512
+ ${await BtnIcon.Render({
513
+ style: `height: 100%`,
514
+ class: 'in fll session-in-log-out main-btn-menu action-bar-box action-btn-profile-log-out',
515
+ label: html` <div class="${contentIconClass} action-btn-profile-log-out-render">
516
+ <i class="fas fa-user-plus"></i>
517
+ </div>`,
518
+ })}
519
+ </div>
520
+ </div>
521
+ ${options?.slideMenuTopBarBannerFix
522
+ ? html`<div
523
+ class="abs modal slide-menu-top-bar-fix"
524
+ style="height: ${options.heightTopBar}px; top: 0px"
525
+ >
526
+ <a class="a-link-top-banner fl">
527
+ <div class="inl">${await options.slideMenuTopBarBannerFix()}</div></a
528
+ >
529
+ </div>`
530
+ : ''}
531
+ </div>`,
532
+ );
533
+ EventsUI.onClick(`.action-btn-profile-log-in`, () => {
534
+ if (Modal.mobileModal() && s(`.btn-close-search-box-history`)) {
535
+ s(`.btn-close-search-box-history`).click();
536
+ }
537
+ s(`.main-btn-account`).click();
538
+ });
539
+ EventsUI.onClick(`.action-btn-profile-log-out`, () => {
540
+ if (Modal.mobileModal() && s(`.btn-close-search-box-history`)) {
541
+ s(`.btn-close-search-box-history`).click();
542
+ }
543
+ s(`.main-btn-sign-up`).click();
544
+ });
545
+ s(`.input-info-${inputSearchBoxId}`).style.textAlign = 'left';
546
+ htmls(`.input-info-${inputSearchBoxId}`, '');
547
+ const inputInfoNode = s(`.input-info-${inputSearchBoxId}`).cloneNode(true);
548
+ s(`.input-info-${inputSearchBoxId}`).remove();
549
+ {
550
+ const id = 'search-box-history';
551
+ const searchBoxHistoryId = id;
552
+ const formDataInfoNode = [
553
+ {
554
+ model: 'search-box',
555
+ id: inputSearchBoxId,
556
+ rules: [] /*{ type: 'isEmpty' }, { type: 'isEmail' }*/,
557
+ },
558
+ ];
559
+ // Reusable hover/focus controller for search history panel
560
+ let unbindDocSearch = null;
561
+ const hoverFocusCtl = EventsUI.HoverFocusController({
562
+ inputSelector: `.top-bar-search-box-container`,
563
+ panelSelector: `.${id}`,
564
+ activeElementId: inputSearchBoxId,
565
+ onDismiss: () => dismissSearchBox(),
566
+ });
567
+ let currentKeyBoardSearchBoxIndex = 0;
568
+ let results = [];
569
+ let historySearchBox = [];
570
+
571
+ const checkHistoryBoxTitleStatus = () => {
572
+ if (s(`.search-box-result-title`) && s(`.search-box-result-title`).classList) {
573
+ if (!s(`.${inputSearchBoxId}`).value.trim()) {
574
+ s(`.search-box-result-title`).classList.add('hide');
575
+ s(`.search-box-recent-title`).classList.remove('hide');
576
+ } else {
577
+ s(`.search-box-recent-title`).classList.add('hide');
578
+ s(`.search-box-result-title`).classList.remove('hide');
579
+ }
580
+ }
581
+ };
582
+
583
+ const checkShortcutContainerInfoEnabled = () => {
584
+ if (Modal.mobileModal() || !s(`.key-shortcut-container-info`)) return;
585
+ if (!s(`.${inputSearchBoxId}`).value) {
586
+ s(`.key-shortcut-container-info`).classList.remove('hide');
587
+ } else s(`.key-shortcut-container-info`).classList.add('hide');
588
+ };
589
+
590
+ const renderSearchResult = async (results) => {
591
+ htmls(`.html-${searchBoxHistoryId}`, '');
592
+ if (results.length === 0) {
593
+ append(
594
+ `.html-${searchBoxHistoryId}`,
595
+ await BtnIcon.Render({
596
+ label: html`<i class="fas fa-exclamation-circle"></i> ${Translate.Render('no-result-found')}`,
597
+ class: `wfa`,
598
+ style: renderCssAttr({
599
+ style: {
600
+ padding: '3px',
601
+ margin: '2px',
602
+ 'text-align': 'center',
603
+ border: 'none',
604
+ cursor: 'default',
605
+ background: 'none !important',
606
+ },
607
+ }),
608
+ }),
609
+ );
610
+ }
611
+ let indexResult = -1;
612
+ for (const result of results) {
613
+ indexResult++;
614
+ const indexRender = indexResult;
615
+ append(
616
+ `.html-${searchBoxHistoryId}`,
617
+ await BtnIcon.Render({
618
+ label: `${
619
+ result.fontAwesomeIcon
620
+ ? html`<i class="${result.fontAwesomeIcon.classList.toString()}"></i> `
621
+ : result.imgElement
622
+ ? html`<img
623
+ class="inl"
624
+ src="${result.imgElement.src}"
625
+ style="${renderCssAttr({ style: { width: '25px', height: '25px' } })}"
626
+ />`
627
+ : ''
628
+ } ${Translate.Render(result.routerId)}`,
629
+ class: `wfa search-result-btn-${result.routerId} ${
630
+ indexResult === currentKeyBoardSearchBoxIndex ? 'main-btn-menu-active' : ''
631
+ } search-result-btn-${indexResult}`,
632
+ style: renderCssAttr({
633
+ style: { padding: '3px', margin: '2px', 'text-align': 'left' },
634
+ }),
635
+ }),
636
+ );
637
+ s(`.search-result-btn-${result.routerId}`).onclick = () => {
638
+ if (!s(`.html-${searchBoxHistoryId}`) || !s(`.html-${searchBoxHistoryId}`).hasChildNodes()) return;
639
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove(
640
+ `main-btn-menu-active`,
641
+ );
642
+ currentKeyBoardSearchBoxIndex = indexRender;
643
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add(
644
+ `main-btn-menu-active`,
645
+ );
646
+ setSearchValue(`.search-result-btn-${result.routerId}`);
647
+ };
648
+ }
649
+ };
650
+
651
+ const getResultSearchBox = (validatorData) => {
652
+ if (!s(`.html-${searchBoxHistoryId}`) || !s(`.html-${searchBoxHistoryId}`).hasChildNodes()) return;
653
+ const { model, id } = validatorData;
654
+ switch (model) {
655
+ case 'search-box':
656
+ {
657
+ if (
658
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] &&
659
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList
660
+ )
661
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove(
662
+ `main-btn-menu-active`,
663
+ );
664
+ currentKeyBoardSearchBoxIndex = 0;
665
+ if (
666
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] &&
667
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList
668
+ )
669
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add(
670
+ `main-btn-menu-active`,
671
+ );
672
+ results = [];
673
+ const routerInstance = Worker.RouterInstance.Routes();
674
+ for (const _routerId of Object.keys(routerInstance)) {
675
+ const routerId = _routerId.slice(1);
676
+ if (routerId) {
677
+ if (
678
+ s(`.main-btn-${routerId}`) &&
679
+ (routerId.toLowerCase().match(s(`.${id}`).value.toLowerCase()) ||
680
+ (Translate.Data[routerId] &&
681
+ Object.keys(Translate.Data[routerId]).filter((keyLang) =>
682
+ Translate.Data[routerId][keyLang]
683
+ .toLowerCase()
684
+ .match(s(`.${id}`).value.toLowerCase()),
685
+ ).length > 0))
686
+ ) {
687
+ const fontAwesomeIcon = getAllChildNodes(s(`.main-btn-${routerId}`)).find((e) => {
688
+ return (
689
+ e.classList &&
690
+ Array.from(e.classList).find((e) => e.match('fa-') && !e.match('fa-grip-vertical'))
691
+ );
692
+ });
693
+ const imgElement = getAllChildNodes(s(`.main-btn-${routerId}`)).find((e) => {
694
+ return (
695
+ typeof e.src === 'string' &&
696
+ e.src.match(routerId) &&
697
+ e.classList &&
698
+ Array.from(e.classList).find((e) => e.match('img-btn-square-menu'))
699
+ );
700
+ });
701
+ if (imgElement || fontAwesomeIcon) {
702
+ results.push({
703
+ routerId,
704
+ fontAwesomeIcon: fontAwesomeIcon,
705
+ imgElement,
706
+ });
707
+ }
708
+ }
709
+ }
710
+ }
711
+ }
712
+ break;
713
+
714
+ default:
715
+ break;
716
+ }
717
+ if (s(`.${inputSearchBoxId}`).value.trim()) renderSearchResult(results);
718
+ else renderSearchResult(historySearchBox);
719
+ };
720
+
721
+ const searchBoxCallBack = async (validatorData) => {
722
+ const isSearchBoxActiveElement = isActiveElement(inputSearchBoxId);
723
+ checkHistoryBoxTitleStatus();
724
+ checkShortcutContainerInfoEnabled();
725
+ if (!isSearchBoxActiveElement && !hoverFocusCtl.shouldStay()) {
726
+ Modal.removeModal(searchBoxHistoryId);
727
+ return;
728
+ }
729
+ setTimeout(() => {
730
+ getResultSearchBox(validatorData);
731
+
732
+ if (
733
+ s(`.slide-menu-top-bar-fix`) &&
734
+ !s(`.main-body-btn-ui-bar-custom-open`).classList.contains('hide')
735
+ ) {
736
+ s(`.main-body-btn-bar-custom`).click();
737
+ }
738
+ });
739
+ };
740
+
741
+ const getDefaultSearchBoxSelector = () => `.search-result-btn-${currentKeyBoardSearchBoxIndex}`;
742
+
743
+ const updateSearchBoxValue = (selector) => {
744
+ if (!selector) selector = getDefaultSearchBoxSelector();
745
+ // check exist childNodes
746
+ if (!s(selector) || !s(selector).hasChildNodes()) return;
747
+
748
+ if (s(selector).childNodes) {
749
+ if (
750
+ s(selector).childNodes[s(selector).childNodes.length - 1] &&
751
+ s(selector).childNodes[s(selector).childNodes.length - 1].data &&
752
+ s(selector).childNodes[s(selector).childNodes.length - 1].data.trim()
753
+ ) {
754
+ s(`.${inputSearchBoxId}`).value =
755
+ s(selector).childNodes[s(selector).childNodes.length - 1].data.trim();
756
+ } else if (
757
+ s(selector).childNodes[s(selector).childNodes.length - 2] &&
758
+ s(selector).childNodes[s(selector).childNodes.length - 2].outerText &&
759
+ s(selector).childNodes[s(selector).childNodes.length - 2].outerText.trim()
760
+ ) {
761
+ s(`.${inputSearchBoxId}`).value =
762
+ s(selector).childNodes[s(selector).childNodes.length - 2].outerText.trim();
763
+ }
764
+ }
765
+ checkHistoryBoxTitleStatus();
766
+ checkShortcutContainerInfoEnabled();
767
+ };
768
+
769
+ const setSearchValue = (selector) => {
770
+ if (!selector) selector = getDefaultSearchBoxSelector();
771
+
772
+ // check exist childNodes
773
+ if (!s(selector) || !s(selector).hasChildNodes()) return;
774
+
775
+ historySearchBox = historySearchBox.filter(
776
+ (h) => h.routerId !== results[currentKeyBoardSearchBoxIndex].routerId,
777
+ );
778
+ historySearchBox.unshift(results[currentKeyBoardSearchBoxIndex]);
779
+ updateSearchBoxValue(selector);
780
+ s(`.main-btn-${results[currentKeyBoardSearchBoxIndex].routerId}`).click();
781
+ Modal.removeModal(searchBoxHistoryId);
782
+ };
783
+ let boxHistoryDelayRender = 0;
784
+ const searchBoxHistoryOpen = async () => {
785
+ if (boxHistoryDelayRender) return;
786
+ if (Modal.mobileModal()) {
787
+ btnCloseEvent();
788
+ }
789
+ boxHistoryDelayRender = 1000;
790
+ setTimeout(() => (boxHistoryDelayRender = 0));
791
+ if (!s(`.${searchBoxHistoryId}`)) {
792
+ const { barConfig } = await Themes[Css.currentTheme]();
793
+ barConfig.buttons.maximize.disabled = true;
794
+ barConfig.buttons.minimize.disabled = true;
795
+ barConfig.buttons.restore.disabled = true;
796
+ barConfig.buttons.menu.disabled = true;
797
+ barConfig.buttons.close.disabled = false;
798
+ await Modal.Render({
799
+ id: searchBoxHistoryId,
800
+ barConfig,
801
+ title: html`<div class="search-box-recent-title">
802
+ ${renderViewTitle({
803
+ icon: html`<i class="fas fa-history mini-title"></i>`,
804
+ text: Translate.Render('recent'),
805
+ })}
806
+ </div>
807
+ <div class="search-box-result-title hide">
808
+ ${renderViewTitle({
809
+ icon: html`<i class="far fa-list-alt mini-title"></i>`,
810
+ text: Translate.Render('results'),
811
+ })}
812
+ </div>`,
813
+ html: () => html``,
814
+ titleClass: 'mini-title',
815
+ style: {
816
+ resize: 'none',
817
+ 'max-width': '450px',
818
+ height:
819
+ this.mobileModal() && windowGetW() < 445
820
+ ? `${windowGetH() - originHeightTopBar}px !important`
821
+ : '300px !important',
822
+ 'z-index': 7,
823
+ },
824
+ dragDisabled: true,
825
+ maximize: true,
826
+ heightBottomBar: 0,
827
+ heightTopBar: options.heightTopBar,
828
+ });
829
+
830
+ // Bind hover/focus and click-outside to dismiss
831
+ hoverFocusCtl.bind();
832
+ unbindDocSearch = EventsUI.bindDismissOnDocumentClick({
833
+ shouldStay: hoverFocusCtl.shouldStay,
834
+ onDismiss: () => dismissSearchBox(),
835
+ anchors: [`.top-bar-search-box-container`, `.${id}`],
836
+ });
837
+ // Ensure cleanup when modal closes
838
+ Modal.Data[id].onCloseListener[`unbind-doc-${id}`] = () => unbindDocSearch && unbindDocSearch();
839
+
840
+ Modal.MoveTitleToBar(id);
841
+
842
+ prepend(`.btn-bar-modal-container-${id}`, html`<div class="hide">${inputInfoNode.outerHTML}</div>`);
843
+ }
844
+ };
845
+
846
+ s('.top-bar-search-box').oninput = () => {
847
+ searchBoxHistoryOpen();
848
+ searchBoxCallBack(formDataInfoNode[0]);
849
+ };
850
+ s('.top-bar-search-box').onfocus = () => {
851
+ searchBoxHistoryOpen();
852
+ searchBoxCallBack(formDataInfoNode[0]);
853
+ };
854
+
855
+ const dismissSearchBox = () => {
856
+ if (unbindDocSearch) {
857
+ try {
858
+ unbindDocSearch();
859
+ } catch (e) {}
860
+ }
861
+ Modal.removeModal(searchBoxHistoryId);
862
+ };
863
+ s('.top-bar-search-box').onblur = () => {
864
+ hoverFocusCtl.checkDismiss();
865
+ };
866
+ EventsUI.onClick(`.top-bar-search-box-container`, () => {
867
+ searchBoxHistoryOpen();
868
+ searchBoxCallBack(formDataInfoNode[0]);
869
+ const inputEl = s(`.${inputSearchBoxId}`);
870
+ if (inputEl && inputEl.focus) inputEl.focus();
871
+ });
872
+
873
+ const timePressDelay = 100;
874
+ Keyboard.instanceMultiPressKey({
875
+ id: 'input-search-shortcut-ArrowUp',
876
+ keys: ['ArrowUp'],
877
+ eventCallBack: () => {
878
+ if (s(`.${id}`)) {
879
+ if (
880
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] &&
881
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex - 1]
882
+ ) {
883
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove(
884
+ `main-btn-menu-active`,
885
+ );
886
+ currentKeyBoardSearchBoxIndex--;
887
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add(
888
+ `main-btn-menu-active`,
889
+ );
890
+ } else {
891
+ if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex])
892
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove(
893
+ `main-btn-menu-active`,
894
+ );
895
+ currentKeyBoardSearchBoxIndex = s(`.html-${searchBoxHistoryId}`).childNodes.length - 1;
896
+ if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex])
897
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add(
898
+ `main-btn-menu-active`,
899
+ );
900
+ }
901
+ updateSearchBoxValue();
902
+ }
903
+ },
904
+ timePressDelay,
905
+ });
906
+
907
+ Keyboard.instanceMultiPressKey({
908
+ id: 'input-search-shortcut-ArrowDown',
909
+ keys: ['ArrowDown'],
910
+ eventCallBack: () => {
911
+ if (s(`.${id}`)) {
912
+ if (
913
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex] &&
914
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex + 1]
915
+ ) {
916
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove(
917
+ `main-btn-menu-active`,
918
+ );
919
+ currentKeyBoardSearchBoxIndex++;
920
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add(
921
+ `main-btn-menu-active`,
922
+ );
923
+ } else {
924
+ if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex])
925
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.remove(
926
+ `main-btn-menu-active`,
927
+ );
928
+ currentKeyBoardSearchBoxIndex = 0;
929
+ if (s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex])
930
+ s(`.html-${searchBoxHistoryId}`).childNodes[currentKeyBoardSearchBoxIndex].classList.add(
931
+ `main-btn-menu-active`,
932
+ );
933
+ }
934
+ updateSearchBoxValue();
935
+ }
936
+ },
937
+ timePressDelay,
938
+ });
939
+
940
+ s(`.top-bar-search-box-container`).onsubmit = (e) => {
941
+ e.preventDefault();
942
+ setSearchValue();
943
+ };
944
+ }
945
+ setTimeout(async () => {
946
+ // clone and change position
947
+
948
+ // s(`.btn-close-${idModal}`);
949
+ // s(`.btn-menu-${idModal}`);
950
+ if (originHeightBottomBar === 0) {
951
+ const btnCloseNode = s(`.btn-close-${idModal}`).cloneNode(true);
952
+ s(`.btn-close-${idModal}`).remove();
953
+ s(`.top-bar`).appendChild(btnCloseNode);
954
+ s(`.btn-close-${idModal}`).onclick = btnCloseEvent;
955
+
956
+ const btnMenuNode = s(`.btn-menu-${idModal}`).cloneNode(true);
957
+ s(`.btn-menu-${idModal}`).remove();
958
+ s(`.top-bar`).appendChild(btnMenuNode);
959
+ s(`.btn-menu-${idModal}`).onclick = btnMenuEvent;
960
+ }
961
+
962
+ // const titleNode = s(`.title-modal-${idModal}`).cloneNode(true);
963
+ // s(`.title-modal-${idModal}`).remove();
964
+ // s(`.top-bar`).appendChild(titleNode);
965
+
966
+ s(`.slide-menu-top-bar`).style.zIndex = 7;
967
+
968
+ // s('body').removeChild(`.${idModal}`);
969
+ // while (s(`.top-modal`).firstChild) s(`.top-modal`).removeChild(s(`.top-modal`).firstChild);
970
+
971
+ {
972
+ const { barConfig } = await Themes[Css.currentTheme]();
973
+ barConfig.buttons.maximize.disabled = true;
974
+ barConfig.buttons.minimize.disabled = true;
975
+ barConfig.buttons.restore.disabled = true;
976
+ barConfig.buttons.menu.disabled = true;
977
+ barConfig.buttons.close.disabled = true;
978
+ const id = 'main-body';
979
+ await Modal.Render({
980
+ id,
981
+ barConfig,
982
+ html: options.htmlMainBody ? options.htmlMainBody : () => html``,
983
+ titleClass: 'hide',
984
+ style: {
985
+ // overflow: 'hidden',
986
+ background: 'none',
987
+ resize: 'none',
988
+ 'min-width': `${minWidth}px`,
989
+ width: '100%',
990
+ // border: '3px solid red',
991
+ },
992
+ dragDisabled: true,
993
+ maximize: true,
994
+ slideMenu: 'modal-menu',
995
+ heightTopBar: originHeightTopBar,
996
+ heightBottomBar: originHeightBottomBar,
997
+ barMode: options.barMode,
998
+ observer: true,
999
+ disableBoxShadow: true,
1000
+ });
1001
+ const maxWidthInputSearchBox = 450;
1002
+ const paddingInputSearchBox = 5;
1003
+ const paddingRightSearchBox = 50;
1004
+ Responsive.Event[`view-${id}`] = () => {
1005
+ if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`];
1006
+ const widthInputSearchBox =
1007
+ windowGetW() > maxWidthInputSearchBox ? maxWidthInputSearchBox : windowGetW();
1008
+ s(`.top-bar-search-box-container`).style.width = `${
1009
+ widthInputSearchBox - originHeightTopBar - paddingRightSearchBox - 1
1010
+ }px`;
1011
+ s(`.top-bar-search-box`).style.width = `${
1012
+ widthInputSearchBox -
1013
+ originHeightTopBar * 2 -
1014
+ paddingRightSearchBox -
1015
+ paddingInputSearchBox * 2 /*padding input*/ -
1016
+ 10 /* right-margin */
1017
+ }px`;
1018
+ s(`.top-bar-search-box`).style.top = `${
1019
+ (originHeightTopBar - s(`.top-bar-search-box`).clientHeight) / 2
1020
+ }px`;
1021
+ if (this.Data[id].slideMenu) s(`.${id}`).style.height = `${Modal.Data[id].getHeight()}px`;
1022
+ };
1023
+ Responsive.Event[`view-${id}`]();
1024
+ Keyboard.instanceMultiPressKey({
1025
+ id: 'input-search-shortcut-k',
1026
+ keys: [
1027
+ ['Shift', 'k'],
1028
+ ['Alt', 'k'],
1029
+ ],
1030
+ eventCallBack: () => {
1031
+ if (isTextInputFocused()) return;
1032
+ if (s(`.top-bar-search-box`)) {
1033
+ if (s(`.main-body-btn-ui-close`).classList.contains('hide')) {
1034
+ s(`.main-body-btn-ui-open`).click();
1035
+ }
1036
+ s(`.top-bar-search-box`).blur();
1037
+ s(`.top-bar-search-box`).focus();
1038
+ s(`.top-bar-search-box`).select();
1039
+ }
1040
+ },
1041
+ });
1042
+ }
1043
+
1044
+ {
1045
+ const { barConfig } = await Themes[Css.currentTheme]();
1046
+ barConfig.buttons.maximize.disabled = true;
1047
+ barConfig.buttons.minimize.disabled = true;
1048
+ barConfig.buttons.restore.disabled = true;
1049
+ barConfig.buttons.menu.disabled = true;
1050
+ barConfig.buttons.close.disabled = true;
1051
+ const id = 'bottom-bar';
1052
+ if (!this.Data[idModal].homeModals) this.Data[idModal].homeModals = [];
1053
+ if (!this.Data[idModal].homeModals.includes(id)) {
1054
+ this.Data[idModal].homeModals.push(id);
1055
+ }
1056
+ const html = async () => html`
1057
+ <style>
1058
+ .top-bar-search-box-container {
1059
+ height: 100%;
1060
+ overflow: hidden;
1061
+ }
1062
+ .bottom-bar {
1063
+ overflow: hidden;
1064
+ }
1065
+ .action-bar-box {
1066
+ margin: 0px;
1067
+ border: none;
1068
+ width: 50px;
1069
+ min-height: 50px;
1070
+ }
1071
+ </style>
1072
+ <div
1073
+ class="fl ${options.barClass ? options.barClass : ''}"
1074
+ style="height: ${originHeightBottomBar}px;"
1075
+ >
1076
+ ${await BtnIcon.Render({
1077
+ style: `height: 100%`,
1078
+ class: `in fl${
1079
+ options.mode === 'slide-menu-right' ? 'r' : 'l'
1080
+ } main-btn-menu action-bar-box action-btn-center ${
1081
+ options?.disableTools?.includes('center') ? 'hide' : ''
1082
+ }`,
1083
+ label: html`
1084
+ <div class="${contentIconClass}">
1085
+ <i class="far fa-square btn-bar-center-icon-square hide"></i>
1086
+ <span class="btn-bar-center-icon-close hide">${barConfig.buttons.close.label}</span>
1087
+ <span class="btn-bar-center-icon-menu">${barConfig.buttons.menu.label}</span>
1088
+ </div>
1089
+ `,
1090
+ })}
1091
+ ${await BtnIcon.Render({
1092
+ style: `height: 100%`,
1093
+ class: `in flr main-btn-menu action-bar-box action-btn-lang ${
1094
+ options?.disableTools?.includes('lang') ? 'hide' : ''
1095
+ }`,
1096
+ label: html` <div class="${contentIconClass} action-btn-lang-render"></div>`,
1097
+ })}
1098
+ ${await BtnIcon.Render({
1099
+ style: `height: 100%`,
1100
+ class: `in flr main-btn-menu action-bar-box action-btn-theme ${
1101
+ options?.disableTools?.includes('theme') ? 'hide' : ''
1102
+ }`,
1103
+ label: html` <div class="${contentIconClass} action-btn-theme-render"></div>`,
1104
+ })}
1105
+ ${await BtnIcon.Render({
1106
+ style: `height: 100%`,
1107
+ class: `in flr main-btn-menu action-bar-box action-btn-home ${
1108
+ options?.disableTools?.includes('navigator') ? 'hide' : ''
1109
+ }`,
1110
+ label: html` <div class="${contentIconClass}"><i class="fas fa-home"></i></div>`,
1111
+ })}
1112
+ ${await BtnIcon.Render({
1113
+ style: `height: 100%`,
1114
+ class: `in flr main-btn-menu action-bar-box action-btn-right ${
1115
+ options?.disableTools?.includes('navigator') ? 'hide' : ''
1116
+ }`,
1117
+ label: html` <div class="${contentIconClass}"><i class="fas fa-chevron-right"></i></div>`,
1118
+ })}
1119
+ ${await BtnIcon.Render({
1120
+ style: `height: 100%`,
1121
+ class: `in flr main-btn-menu action-bar-box action-btn-left ${
1122
+ options?.disableTools?.includes('navigator') ? 'hide' : ''
1123
+ }`,
1124
+ label: html`<div class="${contentIconClass}"><i class="fas fa-chevron-left"></i></div>`,
1125
+ })}
1126
+ </div>
1127
+ `;
1128
+ if (options.heightBottomBar === 0 && options.heightTopBar > 0) {
1129
+ append(`.slide-menu-top-bar`, html` <div class="in ${id}">${await html()}</div>`);
1130
+ } else {
1131
+ await Modal.Render({
1132
+ id,
1133
+ barConfig,
1134
+ html,
1135
+ titleClass: 'hide',
1136
+ style: {
1137
+ resize: 'none',
1138
+ height: `${options.heightBottomBar}px`,
1139
+ 'min-width': `${minWidth}px`,
1140
+ 'z-index': 7,
1141
+ // bottom: '0px !important',
1142
+ width: `${windowGetW()}px`,
1143
+ top: `${Modal.Data['modal-menu'].getTop()}px`,
1144
+ },
1145
+ dragDisabled: true,
1146
+ disableCenter: true,
1147
+ // maximize: true,
1148
+ // barMode: options.barMode,
1149
+ });
1150
+ Responsive.Event[`view-${id}`] = () => {
1151
+ if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`];
1152
+ // <div class="in fll right-offset-menu-bottom-bar" style="height: 100%"></div>
1153
+ // s(`.right-offset-menu-bottom-bar`).style.width = `${windowGetW() - slideMenuWidth}px`;
1154
+ s(`.${id}`).style.top = `${Modal.Data['modal-menu'].getTop()}px`;
1155
+ s(`.${id}`).style.width = `${windowGetW()}px`;
1156
+ };
1157
+ // Responsive.Event[`view-${id}`]();
1158
+ }
1159
+ EventsUI.onClick(`.action-btn-left`, (e) => {
1160
+ e.preventDefault();
1161
+ window.history.back();
1162
+ });
1163
+ EventsUI.onClick(`.action-btn-center`, (e) => {
1164
+ e.preventDefault();
1165
+ Modal.actionBtnCenter();
1166
+ });
1167
+ EventsUI.onClick(`.action-btn-right`, (e) => {
1168
+ e.preventDefault();
1169
+ window.history.forward();
1170
+ });
1171
+ EventsUI.onClick(`.action-btn-home`, async () => {
1172
+ await Modal.onHomeRouterEvent();
1173
+ subMenuHandler(Object.keys(options.RouterInstance.Routes()));
1174
+ Object.keys(this.Data[idModal].onHome).map((keyListener) => this.Data[idModal].onHome[keyListener]());
1175
+ });
1176
+ EventsUI.onClick(`.action-btn-app-icon`, () => s(`.action-btn-home`).click());
1177
+ Keyboard.instanceMultiPressKey({
1178
+ id: 'input-shortcut-global-escape',
1179
+ keys: ['Escape'],
1180
+ eventCallBack: () => {
1181
+ if (s(`.btn-close-${this.currentTopModalId}`)) s(`.btn-close-${this.currentTopModalId}`).click();
1182
+ },
1183
+ });
1184
+ }
1185
+
1186
+ {
1187
+ ThemeEvents['action-btn-theme'] = async () => {
1188
+ htmls(
1189
+ `.action-btn-theme-render`,
1190
+ html` ${darkTheme ? html` <i class="fas fa-moon"></i>` : html`<i class="far fa-sun"></i>`}`,
1191
+ );
1192
+ if (s(`.slide-menu-top-bar-fix`)) {
1193
+ htmls(
1194
+ `.slide-menu-top-bar-fix`,
1195
+ html`<a class="a-link-top-banner fl">${await options.slideMenuTopBarBannerFix()}</a>`,
1196
+ );
1197
+ Modal.setTopBannerLink();
1198
+ }
1199
+ };
1200
+ ThemeEvents['action-btn-theme']();
1201
+
1202
+ EventsUI.onClick(`.action-btn-theme`, async () => {
1203
+ const themePair = ThemesScope.find((t) => t.theme === Css.currentTheme).themePair;
1204
+ const theme = themePair ? themePair : ThemesScope.find((t) => t.dark === !darkTheme).theme;
1205
+ if (s(`.dropdown-option-${theme}`))
1206
+ DropDown.Tokens['settings-theme'].onClickEvents[`dropdown-option-${theme}`]();
1207
+ else await Themes[theme]();
1208
+ });
1209
+ if (!(ThemesScope.find((t) => t.dark) && ThemesScope.find((t) => !t.dark))) {
1210
+ s(`.action-btn-theme`).classList.add('hide');
1211
+ }
1212
+ }
1213
+
1214
+ {
1215
+ htmls(`.action-btn-lang-render`, html` ${s('html').lang}`);
1216
+ // old method
1217
+ // EventsUI.onClick(`.action-btn-lang`, () => {
1218
+ // let lang = 'en';
1219
+ // if (s('html').lang === 'en') lang = 'es';
1220
+ // if (s(`.dropdown-option-${lang}`))
1221
+ // DropDown.Tokens['settings-lang'].onClickEvents[`dropdown-option-${lang}`]();
1222
+ // else Translate.renderLang(lang);
1223
+ // });
1224
+
1225
+ // Open lightweight empty modal on language button, with shared dismiss logic
1226
+ EventsUI.onClick(
1227
+ `.action-btn-lang`,
1228
+ async () => {
1229
+ const id = 'action-btn-lang-modal';
1230
+ if (s(`.${id}`)) {
1231
+ return s(`.btn-close-${id}`).click();
1232
+ }
1233
+ const { barConfig } = await Themes[Css.currentTheme]();
1234
+ barConfig.buttons.maximize.disabled = true;
1235
+ barConfig.buttons.minimize.disabled = true;
1236
+ barConfig.buttons.restore.disabled = true;
1237
+ barConfig.buttons.menu.disabled = true;
1238
+ barConfig.buttons.close.disabled = false;
1239
+ await Modal.Render({
1240
+ id,
1241
+ barConfig,
1242
+ title: html`${renderViewTitle({
1243
+ icon: html`<i class="fas fa-language mini-title"></i>`,
1244
+ text: Translate.Render('select lang'),
1245
+ })}`,
1246
+ html: async () => html`${await Translate.RenderSetting('action-drop-modal' + id)}`,
1247
+ titleClass: 'mini-title',
1248
+ style: {
1249
+ resize: 'none',
1250
+ width: '100% !important',
1251
+ height: '350px !important',
1252
+ 'max-width': '350px !important',
1253
+ 'z-index': 7,
1254
+ },
1255
+ dragDisabled: true,
1256
+ maximize: true,
1257
+ heightBottomBar: 0,
1258
+ heightTopBar: originHeightTopBar,
1259
+ barMode: options.barMode,
1260
+ });
1261
+
1262
+ // Move title inside the bar container to align with control buttons
1263
+ Modal.MoveTitleToBar(id);
1264
+
1265
+ // Position the language selection modal relative to the language button
1266
+ Modal.positionRelativeToAnchor({
1267
+ modalSelector: `.${id}`,
1268
+ anchorSelector: '.action-btn-lang',
1269
+ align: 'right',
1270
+ offset: { x: 0, y: 6 },
1271
+ autoVertical: true,
1272
+ });
1273
+
1274
+ // Hover/focus controller uses the button as input anchor
1275
+ const hoverFocusCtl = EventsUI.HoverFocusController({
1276
+ inputSelector: `.action-btn-lang`,
1277
+ panelSelector: `.${id}`,
1278
+ onDismiss: () => Modal.removeModal(id),
1279
+ });
1280
+ hoverFocusCtl.bind();
1281
+ const unbindDoc = EventsUI.bindDismissOnDocumentClick({
1282
+ shouldStay: hoverFocusCtl.shouldStay,
1283
+ onDismiss: () => Modal.removeModal(id),
1284
+ anchors: [`.action-btn-lang`, `.${id}`],
1285
+ });
1286
+ Modal.Data[id].onCloseListener[`unbind-doc-${id}`] = () => unbindDoc();
1287
+ },
1288
+ { context: 'modal', noGate: true, noLoading: true },
1289
+ );
1290
+ }
1291
+
1292
+ {
1293
+ const { barConfig } = await Themes[Css.currentTheme]();
1294
+ barConfig.buttons.maximize.disabled = true;
1295
+ barConfig.buttons.minimize.disabled = true;
1296
+ barConfig.buttons.restore.disabled = true;
1297
+ barConfig.buttons.menu.disabled = true;
1298
+ barConfig.buttons.close.disabled = true;
1299
+ const id = 'main-body-top';
1300
+ await Modal.Render({
1301
+ id,
1302
+ barConfig,
1303
+ html: () => html``,
1304
+ titleClass: 'hide',
1305
+ class: 'hide',
1306
+ style: {
1307
+ // overflow: 'hidden',
1308
+ background: 'none',
1309
+ resize: 'none',
1310
+ 'min-width': `${minWidth}px`,
1311
+ 'z-index': 5,
1312
+ background: `rgba(61, 61, 61, 0.5)`,
1313
+ // border: '3px solid red',
1314
+ },
1315
+ dragDisabled: true,
1316
+ maximize: true,
1317
+ heightTopBar: originHeightTopBar,
1318
+ heightBottomBar: originHeightBottomBar,
1319
+ barMode: options.barMode,
1320
+ });
1321
+
1322
+ Responsive.Event[`view-${id}`] = () => {
1323
+ if (!this.Data[id] || !s(`.${id}`)) return delete Responsive.Event[`view-${id}`];
1324
+ s(`.${id}`).style.height =
1325
+ s(`.main-body-btn-ui-close`).classList.contains('hide') &&
1326
+ s(`.btn-restore-${id}`).style.display !== 'none'
1327
+ ? `${windowGetH()}px`
1328
+ : `${Modal.Data[id].getHeight()}px`;
1329
+
1330
+ if (
1331
+ s(`.main-body-btn-ui-close`).classList.contains('hide') &&
1332
+ s(`.btn-restore-${id}`).style.display !== 'none'
1333
+ ) {
1334
+ s(`.${id}`).style.top = '0px';
1335
+ } else {
1336
+ s(`.${id}`).style.top = `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
1337
+ }
1338
+ };
1339
+ Responsive.Event[`view-${id}`]();
1340
+
1341
+ s(`.main-body-top`).onclick = () => s(`.btn-close-modal-menu`).click();
1342
+ }
1343
+
1344
+ await NotificationManager.RenderBoard(options);
1345
+
1346
+ const { removeEvent } = Scroll.setEvent('.main-body', async (payload) => {
1347
+ // console.warn('scroll', payload);
1348
+ if (payload.scrollTop > 100) {
1349
+ if (!s(`.main-body-btn-ui-close`).classList.contains('hide')) s(`.main-body-btn-ui-close`).click();
1350
+
1351
+ removeEvent();
1352
+ }
1353
+ });
1354
+ setTimeout(window.onresize);
1355
+ });
1356
+ })();
1357
+ break;
1358
+
1359
+ case 'dropNotification':
1360
+ (() => {
1361
+ setTimeout(() => {
1362
+ s(`.${idModal}`).style.top = 'auto';
1363
+ s(`.${idModal}`).style.left = 'auto';
1364
+ s(`.${idModal}`).style.height = 'auto';
1365
+ s(`.${idModal}`).style.position = 'absolute';
1366
+ let countDrop = 0;
1367
+ Object.keys(this.Data)
1368
+ .reverse()
1369
+ .map((_idModal) => {
1370
+ if (this.Data[_idModal][options.mode]) {
1371
+ s(`.${_idModal}`).style.bottom = `${countDrop * s(`.${_idModal}`).clientHeight * 1.05}px`;
1372
+ countDrop++;
1373
+ }
1374
+ });
1375
+ });
1376
+ })();
1377
+ break;
1378
+
1379
+ default:
1380
+ break;
1381
+ }
1382
+ }
1383
+
1384
+ if (options.zIndexSync) this.zIndexSync({ idModal });
1385
+
1386
+ if (s(`.${idModal}`)) {
1387
+ s(`.btn-maximize-${idModal}`).click();
1388
+ return;
1389
+ }
1390
+
1391
+ if (idModal !== 'main-body' && options.mode !== 'view' && !options.disableCenter) Modal.Data[idModal].center();
1392
+
1393
+ const render = html` <style class="style-${idModal}">
1394
+ .${idModal} {
1395
+ width: ${width}px;
1396
+ height: ${height}px;
1397
+ top: ${top};
1398
+ left: ${left};
1399
+ overflow: auto; /* resizable required */
1400
+ resize: both; /* resizable required */
1401
+ transition: ${transition};
1402
+ opacity: 0;
1403
+ z-index: 1;
1404
+ }
1405
+ .bar-default-modal-${idModal} {
1406
+ top: 0px;
1407
+ left: 0px;
1408
+ z-index: 3;
1409
+ }
1410
+
1411
+ .modal-html-${idModal} {
1412
+ }
1413
+
1414
+ .btn-modal-default-${idModal} {
1415
+ }
1416
+ .modal-handle-${idModal} {
1417
+ width: 90%;
1418
+ height: 90%;
1419
+ top: 5%;
1420
+ left: 5%;
1421
+ }
1422
+ .sub-menu-title-container-${idModal},
1423
+ .nav-path-container-${idModal} {
1424
+ top: 0px;
1425
+ left: 0px;
1426
+ width: 200px;
1427
+ height: 50px;
1428
+ overflow: hidden;
1429
+ font-size: 20px;
1430
+ cursor: default;
1431
+ }
1432
+ .nav-path-display-${idModal} {
1433
+ font-size: 11px;
1434
+ width: 100%;
1435
+ top: 35px;
1436
+ left: 37px;
1437
+ }
1438
+ .nav-title-display-${idModal} {
1439
+ font-size: 19px;
1440
+ width: 100%;
1441
+ top: 13px;
1442
+ left: 13px;
1443
+ }
1444
+ </style>
1445
+ ${renderStyleTag(`style-${idModal}`, `.${idModal}`, options)}
1446
+ <div
1447
+ class="fix ${options && options.class ? options.class : ''} modal ${options.disableBoxShadow
1448
+ ? ''
1449
+ : 'box-shadow'} ${idModal === 'main-body' ? `${idModal} modal-home` : idModal}"
1450
+ >
1451
+ <div class="abs modal-handle-${idModal}"></div>
1452
+ <div class="in modal-html-${idModal}">
1453
+ <div class="stq bar-default-modal bar-default-modal-${idModal}">
1454
+ <div
1455
+ class="fl btn-bar-modal-container btn-bar-modal-container-${idModal} ${options?.btnBarModalClass
1456
+ ? options.btnBarModalClass
1457
+ : ''}"
1458
+ >
1459
+ <div class="btn-bar-modal-container-render-${idModal}"></div>
1460
+ <div class="in flr bar-default-modal" style="z-index: 1">
1461
+ ${await BtnIcon.Render({
1462
+ class: `btn-minimize-${idModal} btn-modal-default btn-modal-default-${idModal} ${
1463
+ options?.btnContainerClass ? options.btnContainerClass : ''
1464
+ } ${options?.barConfig?.buttons?.minimize?.disabled ? 'hide' : ''}`,
1465
+ label: html`<div class="${options?.btnIconContainerClass ? options.btnIconContainerClass : ''}">
1466
+ ${options?.barConfig?.buttons?.minimize?.label ? options.barConfig.buttons.minimize.label : html`_`}
1467
+ </div>`,
1468
+ })}
1469
+ ${await BtnIcon.Render({
1470
+ class: `btn-restore-${idModal} btn-modal-default btn-modal-default-${idModal} ${
1471
+ options?.btnContainerClass ? options.btnContainerClass : ''
1472
+ } ${options?.barConfig?.buttons?.restore?.disabled ? 'hide' : ''}`,
1473
+ label: html`<div class="${options?.btnIconContainerClass ? options.btnIconContainerClass : ''}">
1474
+ ${options?.barConfig?.buttons?.restore?.label ? options.barConfig.buttons.restore.label : html`□`}
1475
+ </div>`,
1476
+ style: 'display: none',
1477
+ })}
1478
+ ${await BtnIcon.Render({
1479
+ class: `btn-maximize-${idModal} btn-modal-default btn-modal-default-${idModal} ${
1480
+ options?.btnContainerClass ? options.btnContainerClass : ''
1481
+ } ${options?.barConfig?.buttons?.maximize?.disabled ? 'hide' : ''}`,
1482
+ label: html`<div class="${options?.btnIconContainerClass ? options.btnIconContainerClass : ''}">
1483
+ ${options?.barConfig?.buttons?.maximize?.label ? options.barConfig.buttons.maximize.label : html`▢`}
1484
+ </div>`,
1485
+ })}
1486
+ ${await BtnIcon.Render({
1487
+ class: `btn-close-${idModal} btn-modal-default btn-modal-default-${idModal} ${
1488
+ options?.btnContainerClass ? options.btnContainerClass : ''
1489
+ } ${options?.barConfig?.buttons?.close?.disabled ? 'hide' : ''}`,
1490
+ label: html`<div class="${options?.btnIconContainerClass ? options.btnIconContainerClass : ''}">
1491
+ ${options?.barConfig?.buttons?.close?.label ? options.barConfig.buttons.close.label : html`X`}
1492
+ </div>`,
1493
+ })}
1494
+ ${await BtnIcon.Render({
1495
+ class: `btn-menu-${idModal} btn-modal-default btn-modal-default-${idModal} ${
1496
+ options?.btnContainerClass ? options.btnContainerClass : ''
1497
+ } ${options?.barConfig?.buttons?.menu?.disabled ? 'hide' : ''}`,
1498
+ label: html`<div class="${options?.btnIconContainerClass ? options.btnIconContainerClass : ''}">
1499
+ ${options?.barConfig?.buttons?.menu?.label ? options.barConfig.buttons.menu.label : html`≡`}
1500
+ </div>`,
1501
+ })}
1502
+ </div>
1503
+ </div>
1504
+ ${options && options.status
1505
+ ? html` <div class="abs modal-icon-container">${renderStatus(options.status)}</div> `
1506
+ : ''}
1507
+ <div
1508
+ class="inl title-modal-${idModal} ${options && options.titleClass
1509
+ ? options.titleClass
1510
+ : 'title-main-modal'}"
1511
+ >
1512
+ ${options && options.titleRender ? options.titleRender() : options.title ? options.title : ''}
1513
+ </div>
1514
+ </div>
1515
+
1516
+ <div class="in html-${idModal}">
1517
+ ${options.mode && options.mode.match('slide-menu')
1518
+ ? html`<div
1519
+ class="stq modal"
1520
+ style="${renderCssAttr({ style: { height: '50px', 'z-index': 1, top: '0px' } })}"
1521
+ >
1522
+ ${await BtnIcon.Render({
1523
+ style: renderCssAttr({ style: { height: '100%', color: '#5f5f5f' } }),
1524
+ class: `in flr main-btn-menu action-bar-box btn-icon-menu-mode`,
1525
+ label: html` <div class="abs center">
1526
+ <i
1527
+ class="fas fa-caret-right btn-icon-menu-mode-right ${options.mode && options.mode.match('right')
1528
+ ? ''
1529
+ : 'hide'}"
1530
+ ></i
1531
+ ><i
1532
+ class="fas fa-caret-left btn-icon-menu-mode-left ${options.mode && options.mode.match('right')
1533
+ ? 'hide'
1534
+ : ''}"
1535
+ ></i>
1536
+ </div>`,
1537
+ })}
1538
+ ${await BtnIcon.Render({
1539
+ style: renderCssAttr({ style: { height: '100%', color: '#5f5f5f' } }),
1540
+ class: `in flr main-btn-menu action-bar-box btn-icon-menu-back hide`,
1541
+ label: html`<div class="abs center"><i class="fas fa-undo-alt"></i></div>`,
1542
+ })}
1543
+ <div class="abs sub-menu-title-container-${idModal} ac">
1544
+ <div class="abs nav-title-display-${idModal}">
1545
+ <!-- <i class="fas fa-home"></i> ${Translate.Render('home')} -->
1546
+ </div>
1547
+ </div>
1548
+ <div class="abs nav-path-container-${idModal} ahc bold">
1549
+ <div class="abs nav-path-display-${idModal}"><!-- ${location.pathname} --></div>
1550
+ </div>
1551
+ </div>`
1552
+ : ''}
1553
+ ${options && options.html ? (typeof options.html === 'function' ? await options.html() : options.html) : ''}
1554
+ </div>
1555
+ </div>
1556
+ </div>`;
1557
+ const selector = options && options.selector ? options.selector : 'body';
1558
+ if (options) {
1559
+ switch (options.renderType) {
1560
+ case 'prepend':
1561
+ prepend(selector, render);
1562
+ break;
1563
+ default:
1564
+ append(selector, render);
1565
+ break;
1566
+ }
1567
+ } else append(selector, render);
1568
+ let handle = [s(`.bar-default-modal-${idModal}`), s(`.modal-handle-${idModal}`), s(`.modal-html-${idModal}`)];
1569
+ if (options && 'handleType' in options) {
1570
+ switch (options.handleType) {
1571
+ case 'bar':
1572
+ handle = [s(`.bar-default-modal-${idModal}`)];
1573
+
1574
+ break;
1575
+
1576
+ default:
1577
+ break;
1578
+ }
1579
+ }
1580
+ switch (options.mode) {
1581
+ case 'slide-menu':
1582
+ case 'slide-menu-right':
1583
+ case 'slide-menu-left':
1584
+ const backMenuButtonEvent = async () => {
1585
+ // htmls(`.nav-title-display-${'modal-menu'}`, html`<i class="fas fa-home"></i> ${Translate.Render('home')}`);
1586
+ htmls(`.nav-title-display-${'modal-menu'}`, html``);
1587
+ htmls(`.nav-path-display-${idModal}`, '');
1588
+ s(`.btn-icon-menu-back`).classList.add('hide');
1589
+ // sa(`.main-btn-menu`).forEach((el) => {
1590
+ // el.classList.remove('hide');
1591
+ // });
1592
+ };
1593
+ s(`.main-btn-home`).onclick = async () => {
1594
+ // await this.onHomeRouterEvent();
1595
+ s(`.action-btn-home`).click();
1596
+ };
1597
+ EventsUI.onClick(`.btn-icon-menu-back`, backMenuButtonEvent);
1598
+ EventsUI.onClick(`.btn-icon-menu-mode`, () => {
1599
+ if (s(`.btn-icon-menu-mode-right`).classList.contains('hide')) {
1600
+ s(`.btn-icon-menu-mode-right`).classList.remove('hide');
1601
+ s(`.btn-icon-menu-mode-left`).classList.add('hide');
1602
+ } else {
1603
+ s(`.btn-icon-menu-mode-left`).classList.remove('hide');
1604
+ s(`.btn-icon-menu-mode-right`).classList.add('hide');
1605
+ }
1606
+ if (slideMenuWidth === originSlideMenuWidth) {
1607
+ slideMenuWidth = collapseSlideMenuWidth;
1608
+ s(`.${idModal}`).style.width = `${slideMenuWidth}px`;
1609
+ sa(`.menu-label-text`).forEach((el) => el.classList.add('hide'));
1610
+ s(`.main-body-btn-container`).style[
1611
+ true || (options.mode && options.mode.match('right')) ? 'right' : 'left'
1612
+ ] = options.mode && options.mode.match('right') ? `${slideMenuWidth}px` : '0px';
1613
+ sa(`.handle-btn-container`).forEach((el) => el.classList.add('hide'));
1614
+ if (options.onCollapseMenu) options.onCollapseMenu();
1615
+ s(`.sub-menu-title-container-${'modal-menu'}`).classList.add('hide');
1616
+ s(`.nav-path-container-${'modal-menu'}`).classList.add('hide');
1617
+ Object.keys(this.Data[idModal].onCollapseMenuListener).map((keyListener) =>
1618
+ this.Data[idModal].onCollapseMenuListener[keyListener](),
1619
+ );
1620
+ } else {
1621
+ slideMenuWidth = originSlideMenuWidth;
1622
+ s(`.${idModal}`).style.width = `${slideMenuWidth}px`;
1623
+ sa(`.menu-label-text`).forEach((el) => el.classList.remove('hide'));
1624
+ s(`.main-body-btn-container`).style[
1625
+ true || (options.mode && options.mode.match('right')) ? 'right' : 'left'
1626
+ ] = options.mode && options.mode.match('right') ? `${slideMenuWidth}px` : '0px';
1627
+ sa(`.handle-btn-container`).forEach((el) => el.classList.remove('hide'));
1628
+
1629
+ Modal.menuTextLabelAnimation(idModal);
1630
+
1631
+ if (options.onExtendMenu) options.onExtendMenu();
1632
+ s(`.sub-menu-title-container-${'modal-menu'}`).classList.remove('hide');
1633
+ s(`.nav-path-container-${'modal-menu'}`).classList.remove('hide');
1634
+ Object.keys(this.Data[idModal].onExtendMenuListener).map((keyListener) =>
1635
+ this.Data[idModal].onExtendMenuListener[keyListener](),
1636
+ );
1637
+ }
1638
+ Modal.Data[idModal][options.mode].width = slideMenuWidth;
1639
+ Responsive.Event[`slide-menu-${idModal}`]();
1640
+ });
1641
+
1642
+ break;
1643
+
1644
+ default:
1645
+ break;
1646
+ }
1647
+ // Track drag position for consistency
1648
+ let dragPosition = { x: 0, y: 0 };
1649
+
1650
+ // Initialize drag options with proper bounds and smooth transitions
1651
+ let dragOptions = {
1652
+ handle: handle,
1653
+ bounds: {
1654
+ top: 0,
1655
+ left: 0,
1656
+ right: 0,
1657
+ bottom: 0,
1658
+ },
1659
+ preventDefault: true,
1660
+ position: { x: 0, y: 0 },
1661
+ onDragStart: () => {
1662
+ const modal = s(`.${idModal}`);
1663
+ if (!modal) return false; // Prevent drag if modal not found
1664
+
1665
+ // Store current position
1666
+ const computedStyle = window.getComputedStyle(modal);
1667
+ const matrix = new DOMMatrixReadOnly(computedStyle.transform);
1668
+ dragPosition = {
1669
+ x: matrix.m41 || 0,
1670
+ y: matrix.m42 || 0,
1671
+ };
1672
+
1673
+ modal.style.transition = 'none';
1674
+ modal.style.willChange = 'transform';
1675
+ return true; // Allow drag to start
1676
+ },
1677
+ onDrag: (data) => {
1678
+ // Update position based on drag delta
1679
+ dragPosition = { x: data.x, y: data.y };
1680
+ },
1681
+ onDragEnd: () => {
1682
+ const modal = s(`.${idModal}`);
1683
+ if (!modal) return;
1684
+
1685
+ modal.style.willChange = '';
1686
+ modal.style.transition = transition;
1687
+
1688
+ // Update drag instance with current position
1689
+ if (dragInstance) {
1690
+ dragInstance.updateOptions({
1691
+ position: dragPosition,
1692
+ });
1693
+ }
1694
+
1695
+ // Notify listeners
1696
+ Object.keys(this.Data[idModal].onDragEndListener || {}).forEach((keyListener) => {
1697
+ this.Data[idModal].onDragEndListener[keyListener]?.();
1698
+ });
1699
+ },
1700
+ };
1701
+
1702
+ let dragInstance = null;
1703
+
1704
+ // Initialize or update drag instance
1705
+ const setDragInstance = () => {
1706
+ if (options?.dragDisabled) {
1707
+ if (dragInstance) {
1708
+ dragInstance.destroy();
1709
+ dragInstance = null;
1710
+ }
1711
+ return null;
1712
+ }
1713
+
1714
+ const modal = s(`.${idModal}`);
1715
+ if (!modal) {
1716
+ console.warn(`Modal element .${idModal} not found for drag initialization`);
1717
+ return null;
1718
+ }
1719
+
1720
+ // Ensure the modal has position: absolute for proper dragging
1721
+ if (window.getComputedStyle(modal).position !== 'absolute') {
1722
+ modal.style.position = 'absolute';
1723
+ }
1724
+
1725
+ // Clean up existing instance
1726
+ if (dragInstance) {
1727
+ dragInstance.destroy();
1728
+ }
1729
+
1730
+ try {
1731
+ // Create new instance with updated options
1732
+ dragInstance = new Draggable(modal, dragOptions);
1733
+ return dragInstance;
1734
+ } catch (error) {
1735
+ console.error('Failed to initialize draggable:', error);
1736
+ return null;
1737
+ }
1738
+ };
1739
+
1740
+ // Expose method to update drag options
1741
+ this.Data[idModal].setDragInstance = (updateDragOptions) => {
1742
+ if (updateDragOptions) {
1743
+ dragOptions = { ...dragOptions, ...updateDragOptions };
1744
+ }
1745
+ dragInstance = setDragInstance();
1746
+ this.Data[idModal].dragInstance = dragInstance;
1747
+ this.Data[idModal].dragOptions = dragOptions;
1748
+ };
1749
+ // Initialize modal with proper transitions
1750
+ const modal = s(`.${idModal}`);
1751
+ if (modal) {
1752
+ // Initial state
1753
+ modal.style.transition = 'opacity 0.15s ease, transform 0.3s ease';
1754
+ modal.style.opacity = '0';
1755
+
1756
+ // Trigger fade-in after a small delay to allow initial render
1757
+ requestAnimationFrame(() => {
1758
+ if (!modal) return;
1759
+ modal.style.opacity = '1';
1760
+
1761
+ // Set final transition after initial animation completes
1762
+ setTimeout(() => {
1763
+ if (modal) {
1764
+ modal.style.transition = transition;
1765
+
1766
+ // Initialize drag after transitions are set
1767
+ if (!options.dragDisabled) {
1768
+ setDragInstance();
1769
+ if (!options.mode) {
1770
+ dragInstance.updateOptions({
1771
+ position: { x: 0, y: 0 },
1772
+ disabled: false, // Ensure drag is enabled after restore
1773
+ });
1774
+ }
1775
+ }
1776
+ }
1777
+ }, 150);
1778
+ });
1779
+ }
1780
+
1781
+ const btnCloseEvent = () => {
1782
+ Object.keys(this.Data[idModal].onCloseListener).map((keyListener) =>
1783
+ this.Data[idModal].onCloseListener[keyListener](),
1784
+ );
1785
+ if (options && 'barConfig' in options && options.barConfig.buttons.close.onClick)
1786
+ return options.barConfig.buttons.close.onClick();
1787
+ s(`.${idModal}`).style.opacity = '0';
1788
+ if (this.Data[idModal].observer) {
1789
+ this.Data[idModal].observer.disconnect();
1790
+ // this.Data[idModal].observer.unobserve();
1791
+ }
1792
+ setTimeout(() => {
1793
+ if (!s(`.${idModal}`)) return;
1794
+ this.removeModal(idModal);
1795
+ // Handle modal route change
1796
+ closeModalRouteChangeEvent({ closedId: idModal });
1797
+ // history.back();
1798
+ }, 300);
1799
+ };
1800
+ s(`.btn-close-${idModal}`).onclick = btnCloseEvent;
1801
+
1802
+ // Minimize button handler
1803
+ s(`.btn-minimize-${idModal}`).onclick = () => {
1804
+ const modal = s(`.${idModal}`);
1805
+ if (!modal) return;
1806
+
1807
+ if (options.slideMenu) {
1808
+ delete this.Data[idModal].slideMenu;
1809
+ }
1810
+
1811
+ // Keep drag enabled when minimized
1812
+ if (dragInstance) {
1813
+ dragInstance.updateOptions({ disabled: false });
1814
+ }
1815
+
1816
+ // Set up transition
1817
+ modal.style.transition = 'height 0.3s ease, transform 0.3s ease';
1818
+
1819
+ // Update button states
1820
+ s(`.btn-minimize-${idModal}`).style.display = 'none';
1821
+ s(`.btn-maximize-${idModal}`).style.display = null;
1822
+ s(`.btn-restore-${idModal}`).style.display = null;
1823
+
1824
+ // Collapse to header height
1825
+ const header = s(`.bar-default-modal-${idModal}`);
1826
+ if (header) {
1827
+ modal.style.height = `${header.clientHeight}px`;
1828
+ modal.style.overflow = 'hidden';
1829
+ }
1830
+
1831
+ // Restore transition after animation
1832
+ setTimeout(() => {
1833
+ if (modal) {
1834
+ modal.style.transition = transition;
1835
+ }
1836
+ }, 300);
1837
+ };
1838
+ // Restore button handler
1839
+ s(`.btn-restore-${idModal}`).onclick = () => {
1840
+ const modal = s(`.${idModal}`);
1841
+ if (!modal) return;
1842
+
1843
+ if (options.slideMenu) {
1844
+ delete this.Data[idModal].slideMenu;
1845
+ }
1846
+
1847
+ // Re-enable dragging
1848
+ if (dragInstance) {
1849
+ dragInstance.updateOptions({ disabled: false });
1850
+ }
1851
+
1852
+ // Set up transition
1853
+ modal.style.transition = 'all 0.3s ease';
1854
+
1855
+ // Update button states
1856
+ s(`.btn-restore-${idModal}`).style.display = 'none';
1857
+ s(`.btn-minimize-${idModal}`).style.display = null;
1858
+ s(`.btn-maximize-${idModal}`).style.display = null;
1859
+
1860
+ // Restore original dimensions and position
1861
+ this.Data[idModal].center();
1862
+ modal.style.transform = '';
1863
+ modal.style.height = `${height}px`;
1864
+ modal.style.left = left;
1865
+ modal.style.top = top;
1866
+ modal.style.width = `${width}px`;
1867
+ modal.style.overflow = '';
1868
+
1869
+ // Re-enable drag after restore
1870
+ if (dragInstance) {
1871
+ dragInstance.updateOptions({
1872
+ position: { x: 0, y: 0 },
1873
+ disabled: false, // Ensure drag is enabled after restore
1874
+ });
1875
+ }
1876
+ setTimeout(() => (s(`.${idModal}`) ? (s(`.${idModal}`).style.transition = transition) : null), 300);
1877
+ };
1878
+ s(`.btn-maximize-${idModal}`).onclick = () => {
1879
+ const modal = s(`.${idModal}`);
1880
+ if (!modal) return;
1881
+
1882
+ // Disable drag when maximizing
1883
+ if (dragInstance) {
1884
+ dragInstance.updateOptions({ disabled: true });
1885
+ }
1886
+
1887
+ modal.style.transition = '0.3s';
1888
+ setTimeout(() => (modal ? (modal.style.transition = transition) : null), 300);
1889
+
1890
+ s(`.btn-maximize-${idModal}`).style.display = 'none';
1891
+ s(`.btn-restore-${idModal}`).style.display = null;
1892
+ s(`.btn-minimize-${idModal}`).style.display = null;
1893
+ modal.style.transform = null;
1894
+
1895
+ if (options.slideMenu) {
1896
+ const idSlide = this.Data[options.slideMenu]['slide-menu']
1897
+ ? 'slide-menu'
1898
+ : this.Data[options.slideMenu]['slide-menu-right']
1899
+ ? 'slide-menu-right'
1900
+ : 'slide-menu-left';
1901
+ const callBack = () => {
1902
+ s(`.${idModal}`).style.transition = '0.3s';
1903
+ s(`.${idModal}`).style.width = `${windowGetW() - this.Data[options.slideMenu][idSlide].width}px`;
1904
+ s(`.${idModal}`).style.left =
1905
+ idSlide === 'slide-menu-right' ? `0px` : `${this.Data[options.slideMenu][idSlide].width}px`;
1906
+ setTimeout(() => (s(`.${idModal}`) ? (s(`.${idModal}`).style.transition = transition) : null), 300);
1907
+ };
1908
+
1909
+ callBack();
1910
+ this.Data[idModal].slideMenu = {
1911
+ callBack,
1912
+ id: options.slideMenu,
1913
+ };
1914
+ Responsive.Event['h-ui-hide-' + idModal] = () => {
1915
+ setTimeout(() => {
1916
+ if (!s(`.${idModal}`) || !s(`.main-body-btn-ui-close`)) return;
1917
+ if (s(`.btn-restore-${idModal}`) && s(`.btn-restore-${idModal}`).style.display !== 'none') {
1918
+ s(`.${idModal}`).style.height = s(`.main-body-btn-ui-close`).classList.contains('hide')
1919
+ ? `${windowGetH()}px`
1920
+ : `${Modal.Data[idModal].getHeight()}px`;
1921
+ }
1922
+ s(`.${idModal}`).style.top = s(`.main-body-btn-ui-close`).classList.contains('hide')
1923
+ ? `0px`
1924
+ : `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
1925
+ });
1926
+ };
1927
+ Responsive.Event['h-ui-hide-' + idModal]();
1928
+ } else {
1929
+ delete Responsive.Event['h-ui-hide-' + idModal];
1930
+ s(`.${idModal}`).style.width = '100%';
1931
+ s(`.${idModal}`).style.height = '100%';
1932
+ s(`.${idModal}`).style.top = `${options.heightTopBar ? options.heightTopBar : heightDefaultTopBar}px`;
1933
+ s(`.${idModal}`).style.left = `0px`;
1934
+ }
1935
+ dragInstance = setDragInstance();
1936
+ };
1937
+
1938
+ const btnMenuEvent = () => {
1939
+ Modal.menuTextLabelAnimation(idModal);
1940
+ Object.keys(this.Data[idModal].onMenuListener).map((keyListener) =>
1941
+ this.Data[idModal].onMenuListener[keyListener](),
1942
+ );
1943
+ if (options && 'barConfig' in options && options.barConfig.buttons.menu.onClick)
1944
+ options.barConfig.buttons.menu.onClick();
1945
+ };
1946
+ s(`.btn-menu-${idModal}`).onclick = btnMenuEvent;
1947
+
1948
+ dragInstance = setDragInstance();
1949
+ if (options && options.maximize) s(`.btn-maximize-${idModal}`).click();
1950
+ if (options.observer) {
1951
+ this.Data[idModal].onObserverListener = {};
1952
+ this.Data[idModal].observerCallBack = () => {
1953
+ // logger.info('ResizeObserver', `.${idModal}`, s(`.${idModal}`).offsetWidth, s(`.${idModal}`).offsetHeight);
1954
+ if (this.Data[idModal] && this.Data[idModal].onObserverListener)
1955
+ Object.keys(this.Data[idModal].onObserverListener).map((eventKey) =>
1956
+ this.Data[idModal].onObserverListener[eventKey]({
1957
+ width: s(`.${idModal}`).offsetWidth,
1958
+ height: s(`.${idModal}`).offsetHeight,
1959
+ }),
1960
+ );
1961
+ else console.warn('observer not found', idModal);
1962
+ };
1963
+ this.Data[idModal].observer = new ResizeObserver(this.Data[idModal].observerCallBack);
1964
+ this.Data[idModal].observer.observe(s(`.${idModal}`));
1965
+ setTimeout(this.Data[idModal].observerCallBack);
1966
+ }
1967
+ // cancel: [cancel1, cancel2]
1968
+ s(`.${idModal}`).onclick = () => {
1969
+ this.Data[idModal]?.onClickListener
1970
+ ? Object.keys(this.Data[idModal].onClickListener).map((keyListener) =>
1971
+ this.Data[idModal].onClickListener[keyListener](),
1972
+ )
1973
+ : null;
1974
+ };
1975
+ return {
1976
+ id: idModal,
1977
+ ...this.Data[idModal],
1978
+ };
1979
+ },
1980
+ subMenuBtnClass: {},
1981
+
1982
+ onHomeRouterEvent: async () => {
1983
+ // 1. Get list of modals to close.
1984
+ const modalsToClose = Object.keys(Modal.Data).filter((idModal) => {
1985
+ const modal = Modal.Data[idModal];
1986
+ if (!modal) return false;
1987
+ // Don't close the core UI elements
1988
+
1989
+ if (coreUI.find((id) => idModal.startsWith(id))) {
1990
+ return false;
1991
+ }
1992
+ // Don't close modals that are part of the "home" screen itself
1993
+ const homeModals = Modal.Data['modal-menu']?.homeModals || [];
1994
+ if (homeModals.includes(idModal)) {
1995
+ return false;
1996
+ }
1997
+ return true;
1998
+ });
1999
+
2000
+ // 2. Navigate to home first, creating a new history entry.
2001
+ setPath(`${getProxyPath()}${location.search ?? ''}${location.hash ?? ''}`);
2002
+ setDocTitle();
2003
+
2004
+ // 3. Close the modals without them affecting the URL.
2005
+ for (const id of modalsToClose) {
2006
+ Modal.removeModal(id);
2007
+ }
2008
+
2009
+ // 4. Finally, handle UI cleanup for the slide-menu.
2010
+
2011
+ if (s(`.nav-title-display-modal-menu`)) htmls(`.nav-title-display-modal-menu`, '');
2012
+ if (s(`.nav-path-display-modal-menu`)) htmls(`.nav-path-display-modal-menu`, '');
2013
+ if (s(`.btn-icon-menu-back`)) s(`.btn-icon-menu-back`).classList.add('hide');
2014
+ // sa(`.main-btn-menu`).forEach((el) => {
2015
+ // el.classList.remove('hide');
2016
+ // });
2017
+
2018
+ // And close the slide menu if it's open
2019
+ if (s(`.btn-close-modal-menu`) && !s(`.btn-close-modal-menu`).classList.contains('hide')) {
2020
+ s(`.btn-close-modal-menu`).click();
2021
+ }
2022
+ },
2023
+ currentTopModalId: '',
2024
+ zIndexSync: function ({ idModal }) {
2025
+ setTimeout(() => {
2026
+ if (!this.Data[idModal]) return;
2027
+ const cleanTopModal = () => {
2028
+ Object.keys(this.Data).map((_idModal) => {
2029
+ if (this.Data[_idModal].options.zIndexSync && s(`.${_idModal}`)) s(`.${_idModal}`).style.zIndex = '3';
2030
+ });
2031
+ };
2032
+ const setTopModal = () => {
2033
+ if (s(`.${idModal}`)) {
2034
+ this.setTopModalCallback(idModal);
2035
+ } else setTimeout(setTopModal, 100);
2036
+ };
2037
+ cleanTopModal();
2038
+ setTopModal();
2039
+ this.Data[idModal].onClickListener[`${idModal}-z-index`] = () => {
2040
+ if (s(`.${idModal}`) && s(`.${idModal}`).style.zIndex === '3') {
2041
+ if (this.Data[idModal].options.route) setPath(`${getProxyPath()}${this.Data[idModal].options.route}`);
2042
+ cleanTopModal();
2043
+ setTopModal();
2044
+ }
2045
+ };
2046
+ });
2047
+ },
2048
+ setTopModalCallback: function (idModal) {
2049
+ s(`.${idModal}`).style.zIndex = '4';
2050
+ this.currentTopModalId = `${idModal}`;
2051
+ },
2052
+ mobileModal: () => windowGetW() < 600 || windowGetH() < 600,
2053
+ writeHTML: ({ idModal, html }) => htmls(`.html-${idModal}`, html),
2054
+ viewModalOpen: function () {
2055
+ return Object.keys(this.Data).find((idModal) => s(`.${idModal}`) && this.Data[idModal].options.mode === 'view');
2056
+ },
2057
+ removeModal: function (idModal) {
2058
+ if (!s(`.${idModal}`)) return;
2059
+ s(`.${idModal}`).remove();
2060
+ sa(`.style-${idModal}`).forEach((element) => {
2061
+ element.remove();
2062
+ });
2063
+ delete this.Data[idModal];
2064
+ },
2065
+ RenderConfirm: async function (options) {
2066
+ const { id } = options;
2067
+ append(
2068
+ 'body',
2069
+ html`
2070
+ <div
2071
+ class="fix background-confirm-modal-${id}"
2072
+ style="${renderCssAttr({
2073
+ style: {
2074
+ 'z-index': '10',
2075
+ background: 'rgba(0,0,0,0.5)',
2076
+ width: '100%',
2077
+ height: '100%',
2078
+ top: '0px',
2079
+ left: '0px',
2080
+ transition: '0.3s',
2081
+ opacity: '1',
2082
+ },
2083
+ })}"
2084
+ ></div>
2085
+ `,
2086
+ );
2087
+ const removeBackgroundConfirmModal = () => {
2088
+ s(`.background-confirm-modal-${id}`).style.opacity = '0';
2089
+ setTimeout(() => {
2090
+ s(`.background-confirm-modal-${id}`).remove();
2091
+ });
2092
+ };
2093
+
2094
+ return new Promise(async (resolve, reject) => {
2095
+ const { barConfig } = await Themes[Css.currentTheme]();
2096
+ barConfig.buttons.maximize.disabled = true;
2097
+ barConfig.buttons.minimize.disabled = true;
2098
+ barConfig.buttons.restore.disabled = true;
2099
+ barConfig.buttons.menu.disabled = true;
2100
+ barConfig.buttons.close.disabled = false;
2101
+ const htmlRender = html`
2102
+ <br />
2103
+ <div class="in section-mp" style="font-size: 40px; text-align: center">
2104
+ ${options.icon ? options.icon : html` <i class="fas fa-question-circle"></i>`}
2105
+ </div>
2106
+ ${await options.html()}
2107
+ <div class="in section-mp">
2108
+ ${await BtnIcon.Render({
2109
+ class: `in section-mp form-button btn-confirm-${id}`,
2110
+ label: Translate.Render('confirm'),
2111
+ type: 'submit',
2112
+ style: `margin: auto`,
2113
+ })}
2114
+ </div>
2115
+ <div class="in section-mp ${options.disableBtnCancel ? 'hide' : ''}">
2116
+ ${await BtnIcon.Render({
2117
+ class: `in section-mp form-button btn-cancel-${id}`,
2118
+ label: Translate.Render('cancel'),
2119
+ type: 'submit',
2120
+ style: `margin: auto`,
2121
+ })}
2122
+ </div>
2123
+ `;
2124
+ await Modal.Render({
2125
+ id,
2126
+ barConfig,
2127
+ titleClass: 'hide',
2128
+ style: {
2129
+ width: '300px',
2130
+ height: '400px',
2131
+ overflow: 'hidden',
2132
+ 'z-index': '11',
2133
+ resize: 'none',
2134
+ },
2135
+ dragDisabled: true,
2136
+ ...options,
2137
+ html: htmlRender,
2138
+ });
2139
+
2140
+ const end = () => {
2141
+ removeBackgroundConfirmModal();
2142
+ Modal.removeModal(id);
2143
+ };
2144
+ barConfig.buttons.close.onClick = () => {
2145
+ end();
2146
+ resolve({ status: 'cancelled' });
2147
+ };
2148
+ s(`.background-confirm-modal-${id}`).onclick = () => {
2149
+ end();
2150
+ resolve({ status: 'cancelled' });
2151
+ };
2152
+ s(`.btn-cancel-${id}`).onclick = () => {
2153
+ end();
2154
+ resolve({ status: 'cancelled' });
2155
+ };
2156
+ s(`.btn-confirm-${id}`).onclick = () => {
2157
+ end();
2158
+ resolve({ status: 'confirm' });
2159
+ };
2160
+ });
2161
+ },
2162
+ menuTextLabelAnimation: (idModal, subMenuId) => {
2163
+ if (
2164
+ !s(
2165
+ `.btn-icon-menu-mode-${Modal.Data[idModal].options.mode === 'slide-menu-right' ? 'left' : 'right'}`,
2166
+ ).classList.contains('hide')
2167
+ ) {
2168
+ return;
2169
+ }
2170
+ const btnSelector = `.main-btn-menu`;
2171
+ const labelSelector = `.menu-label-text`;
2172
+
2173
+ const _data = subMenuId
2174
+ ? {
2175
+ [subMenuId]: Modal.subMenuBtnClass[subMenuId],
2176
+ }
2177
+ : { ...Modal.subMenuBtnClass, _: { btnSelector, labelSelector } };
2178
+
2179
+ for (const keyDataBtn of Object.keys(_data)) {
2180
+ const { labelSelector, top } = _data[keyDataBtn];
2181
+ if (top)
2182
+ setTimeout(() => {
2183
+ top();
2184
+ });
2185
+ sa(labelSelector).forEach((el) => {
2186
+ if (!el.classList.contains('hide')) el.classList.add('hide');
2187
+ el.style.transition = null;
2188
+ });
2189
+
2190
+ setTimeout(() => {
2191
+ sa(labelSelector).forEach((el) => {
2192
+ el.classList.remove('hide');
2193
+ el.style.transition = null;
2194
+ });
2195
+ sa(labelSelector).forEach((el) => {
2196
+ el.style.top = '-40px';
2197
+ });
2198
+ }, 300);
2199
+ setTimeout(() => {
2200
+ sa(labelSelector).forEach((el) => {
2201
+ el.style.top = '-3px';
2202
+ });
2203
+ }, 400);
2204
+ }
2205
+ },
2206
+ // Move modal title element into the bar's render container so it aligns with control buttons
2207
+ /**
2208
+ * Position a modal relative to an anchor element
2209
+ * @param {Object} options - Positioning options
2210
+ * @param {string} options.modalSelector - CSS selector for the modal element
2211
+ * @param {string} options.anchorSelector - CSS selector for the anchor element
2212
+ * @param {Object} [options.offset={x: 0, y: 6}] - Offset from anchor
2213
+ * @param {string} [options.align='right'] - Horizontal alignment ('left' or 'right')
2214
+ * @param {boolean} [options.autoVertical=true] - Whether to automatically determine vertical position
2215
+ * @param {boolean} [options.placeAbove] - Force position above/below anchor (overrides autoVertical)
2216
+ */
2217
+ positionRelativeToAnchor({
2218
+ modalSelector,
2219
+ anchorSelector,
2220
+ offset = { x: 0, y: 6 },
2221
+ align = 'right',
2222
+ autoVertical = true,
2223
+ placeAbove,
2224
+ }) {
2225
+ try {
2226
+ const modal = s(modalSelector);
2227
+ const anchor = s(anchorSelector);
2228
+
2229
+ if (!modal || !anchor || !anchor.getBoundingClientRect) return;
2230
+
2231
+ // First, position the modal near its final position but off-screen
2232
+ const arect = anchor.getBoundingClientRect();
2233
+ const vh = windowGetH();
2234
+ const vw = windowGetW();
2235
+ const safeMargin = 6;
2236
+
2237
+ // Determine vertical position
2238
+ let finalPlaceAbove = placeAbove;
2239
+ if (autoVertical && placeAbove === undefined) {
2240
+ const inBottomBar = anchor.closest && anchor.closest('.bottom-bar');
2241
+ const inTopBar = anchor.closest && anchor.closest('.slide-menu-top-bar');
2242
+
2243
+ if (inBottomBar) finalPlaceAbove = true;
2244
+ else if (inTopBar) finalPlaceAbove = false;
2245
+ else finalPlaceAbove = arect.top > vh / 2; // heuristic fallback
2246
+ }
2247
+
2248
+ // Set initial position (slightly offset from final position)
2249
+ const initialOffset = finalPlaceAbove ? 20 : -20;
2250
+ modal.style.position = 'fixed';
2251
+ modal.style.opacity = '0';
2252
+ modal.style.transition = 'opacity 150ms ease-out, transform 150ms ease-out';
2253
+
2254
+ // Position near the anchor but slightly offset
2255
+ modal.style.top = `${finalPlaceAbove ? arect.top - 40 : arect.bottom + 20}px`;
2256
+ modal.style.left = `${align === 'right' ? arect.right - 200 : arect.left}px`;
2257
+ modal.style.transform = 'translateY(0)';
2258
+
2259
+ // Force reflow to ensure initial styles are applied
2260
+ modal.offsetHeight;
2261
+
2262
+ // Now calculate final position
2263
+ const mrect = modal.getBoundingClientRect();
2264
+
2265
+ // Calculate final top position
2266
+ const top = finalPlaceAbove ? arect.top - mrect.height - offset.y : arect.bottom + offset.y;
2267
+
2268
+ // Calculate final left position based on alignment
2269
+ let left;
2270
+ if (align === 'right') {
2271
+ left = arect.right - mrect.width - offset.x; // align right edges
2272
+ } else {
2273
+ left = arect.left + offset.x; // align left edges
2274
+ }
2275
+
2276
+ // Ensure modal stays within viewport bounds
2277
+ left = Math.max(safeMargin, Math.min(left, vw - mrect.width - safeMargin));
2278
+ const finalTop = Math.max(safeMargin, Math.min(top, vh - mrect.height - safeMargin));
2279
+
2280
+ // Apply final position with smooth transition
2281
+ requestAnimationFrame(() => {
2282
+ modal.style.top = `${Math.round(finalTop)}px`;
2283
+ modal.style.left = `${Math.round(left)}px`;
2284
+ modal.style.opacity = '1';
2285
+ });
2286
+ } catch (e) {
2287
+ console.error('Error positioning modal:', e);
2288
+ }
2289
+ },
2290
+
2291
+ MoveTitleToBar(idModal) {
2292
+ try {
2293
+ const titleEl = s(`.title-modal-${idModal}`);
2294
+ const container = s(`.btn-bar-modal-container-render-${idModal}`);
2295
+ if (!titleEl || !container) return;
2296
+ const titleNode = titleEl.cloneNode(true);
2297
+ titleEl.remove();
2298
+ container.classList.add('in');
2299
+ container.classList.add('fll');
2300
+ container.appendChild(titleNode);
2301
+ } catch (e) {
2302
+ // non-fatal: keep default placement if structure not present
2303
+ }
2304
+ },
2305
+ setTopBannerLink: function () {
2306
+ if (s(`.a-link-top-banner`)) {
2307
+ s(`.a-link-top-banner`).setAttribute('href', `${location.origin}${getProxyPath()}`);
2308
+ EventsUI.onClick(`.a-link-top-banner`, (e) => {
2309
+ e.preventDefault();
2310
+ s(`.action-btn-home`).click();
2311
+ });
2312
+ }
2313
+ },
2314
+ headerTitleHeight: 40,
2315
+ actionBtnCenter: function () {
2316
+ if (!s(`.btn-close-modal-menu`).classList.contains('hide')) {
2317
+ return s(`.btn-close-modal-menu`).click();
2318
+ }
2319
+ if (!s(`.btn-menu-modal-menu`).classList.contains('hide')) {
2320
+ return s(`.btn-menu-modal-menu`).click();
2321
+ }
2322
+ },
2323
+ cleanUI: function () {
2324
+ s(`.top-bar`).classList.add('hide');
2325
+ s(`.bottom-bar`).classList.add('hide');
2326
+ s(`.modal-menu`).classList.add('hide');
2327
+ },
2328
+ restoreUI: function () {
2329
+ s(`.top-bar`).classList.remove('hide');
2330
+ s(`.bottom-bar`).classList.remove('hide');
2331
+ s(`.modal-menu`).classList.remove('hide');
2332
+ },
2333
+ RenderSeoSanitizer: async () => {
2334
+ sa('img').forEach((img) => {
2335
+ if (!img.getAttribute('alt')) img.setAttribute('alt', 'image ' + Worker.title + ' ' + s4());
2336
+ });
2337
+ },
2338
+ };
2339
+
2340
+ const renderMenuLabel = ({ img, text, icon }) => {
2341
+ if (!img) return html`<span class="inl menu-btn-icon">${icon}</span> ${text}`;
2342
+ return html`<img class="abs center img-btn-square-menu" src="${getProxyPath()}assets/ui-icons/${img}" />
2343
+ <div class="abs center main-btn-menu-text">${text}</div>`;
2344
+ };
2345
+
2346
+ const renderViewTitle = (
2347
+ options = { icon: '', img: '', text: '', assetFolder: '', 'ui-icons': '', dim, top, topText: '' },
2348
+ ) => {
2349
+ if (options.dim === undefined) options.dim = 30;
2350
+ const { img, text, icon, dim, top } = options;
2351
+ if (!img && !options['ui-icon']) return html`<span class="view-title-icon">${icon}</span> ${text}`;
2352
+ return html`<img
2353
+ class="abs img-btn-square-view-title"
2354
+ style="${renderCssAttr({
2355
+ style: {
2356
+ width: `${dim}px`,
2357
+ height: `${dim}px`,
2358
+ top: top !== undefined ? `${top}px !important` : undefined,
2359
+ },
2360
+ })}"
2361
+ src="${options['ui-icon']
2362
+ ? `${getProxyPath()}assets/${options.assetFolder ? options.assetFolder : 'ui-icons'}/${options['ui-icon']}`
2363
+ : img}"
2364
+ />
2365
+ <div
2366
+ class="in text-btn-square-view-title"
2367
+ style="${renderCssAttr({
2368
+ style: {
2369
+ // 'padding-left': `${20 + dim}px`,
2370
+ ...(options.topText !== undefined ? { top: options.topText + 'px !important' } : {}),
2371
+ },
2372
+ })}"
2373
+ >
2374
+ ${text}
2375
+ </div>`;
2376
+ };
2377
+
2378
+ const buildBadgeToolTipMenuOption = (id, sideKey = 'left') => {
2379
+ const option = {
2380
+ id: `tooltip-content-main-btn-${id}`,
2381
+ text: `${Translate.Render(`${id}`)}`,
2382
+ classList: 'tooltip-menu',
2383
+ style: { top: `-40px` },
2384
+ };
2385
+ switch (sideKey) {
2386
+ case 'left':
2387
+ option.style.left = '60px';
2388
+
2389
+ break;
2390
+
2391
+ case 'right':
2392
+ option.style.right = '60px';
2393
+ break;
2394
+
2395
+ default:
2396
+ break;
2397
+ }
2398
+ return option;
2399
+ };
2400
+
2401
+ const isSubMenuOpen = (subMenuId) => {
2402
+ return s(`.down-arrow-submenu-${subMenuId}`) && s(`.down-arrow-submenu-${subMenuId}`).style.rotate === '180deg';
2403
+ };
2404
+
2405
+ const subMenuRender = async (subMenuId) => {
2406
+ const _hBtn = 51;
2407
+ const menuBtn = s(`.main-btn-${subMenuId}`);
2408
+ const menuContainer = s(`.menu-btn-container-children-${subMenuId}`);
2409
+ const arrow = s(`.down-arrow-submenu-${subMenuId}`);
2410
+
2411
+ if (!menuBtn || !menuContainer || !arrow) return;
2412
+
2413
+ const top = () => {
2414
+ let value = menuBtn.offsetTop + Modal.Data['modal-menu'].options.heightTopBar;
2415
+
2416
+ const isHidden = s('.main-body-btn-ui-open').classList.contains('hide');
2417
+ const isTopBottom = Modal.Data['modal-menu'].options.barMode === 'top-bottom-bar';
2418
+
2419
+ if (!isTopBottom && isHidden) value -= 51;
2420
+ else if (!isHidden) value += 51;
2421
+
2422
+ menuContainer.style.top = `${value}px`;
2423
+ };
2424
+
2425
+ Modal.subMenuBtnClass[subMenuId] = {
2426
+ ...Modal.subMenuBtnClass[subMenuId],
2427
+ btnSelector: `.btn-${subMenuId}`,
2428
+ labelSelector: `.menu-label-text-${subMenuId}`,
2429
+ top,
2430
+ };
2431
+
2432
+ menuBtn.style.transition = '.3s';
2433
+ arrow.style.transition = '.3s';
2434
+
2435
+ if (isSubMenuOpen(subMenuId)) {
2436
+ // Close animation
2437
+ menuContainer.style.overflow = 'hidden';
2438
+ menuContainer.style.height = '0px';
2439
+ arrow.style.rotate = '180deg';
2440
+ setTimeout(() => {
2441
+ menuBtn.style.marginBottom = '0px';
2442
+ arrow.style.rotate = '0deg';
2443
+ });
2444
+ } else {
2445
+ sa(`.menu-label-text-${subMenuId}`).forEach((el) => {
2446
+ if (!el.classList.contains('hide')) el.classList.add('hide');
2447
+ });
2448
+ setTimeout(() => {
2449
+ Modal.menuTextLabelAnimation('modal-menu', subMenuId);
2450
+ });
2451
+ // Open animation
2452
+ setTimeout(top, 360);
2453
+ menuContainer.style.width = '320px';
2454
+ menuContainer.style.overflow = null;
2455
+ menuContainer.style.height = '0px';
2456
+ menuContainer.style.height = `${_hBtn * 6}px`;
2457
+ arrow.style.rotate = '0deg';
2458
+ setTimeout(() => {
2459
+ menuBtn.style.marginBottom = `${_hBtn * sa(`.menu-label-text-${subMenuId}`).length + 4}px`;
2460
+ arrow.style.rotate = '180deg';
2461
+ });
2462
+ }
2463
+
2464
+ setTimeout(() => {
2465
+ menuBtn.style.transition = null;
2466
+ }, 500);
2467
+ };
2468
+
2469
+ const subMenuHandler = (routes, route) => {
2470
+ route = sanitizeRoute(route);
2471
+ for (let _route of routes) {
2472
+ _route = sanitizeRoute(_route);
2473
+ if (_route !== route) {
2474
+ if (isSubMenuOpen(_route)) subMenuRender(_route);
2475
+ }
2476
+ }
2477
+ setTimeout(() => {
2478
+ let cid = getQueryParams().cid;
2479
+ if (s(`.main-sub-btn-active`)) s(`.main-sub-btn-active`).classList.remove('main-sub-btn-active');
2480
+ if (cid && s(`.btn-${route}-${cid}`)) {
2481
+ s(`.btn-${route}-${cid}`).classList.add('main-sub-btn-active');
2482
+ }
2483
+ });
2484
+ };
2485
+
2486
+ export {
2487
+ Modal,
2488
+ renderMenuLabel,
2489
+ renderViewTitle,
2490
+ buildBadgeToolTipMenuOption,
2491
+ subMenuRender,
2492
+ isSubMenuOpen,
2493
+ subMenuHandler,
2494
+ };