@underpostnet/cyberia 3.2.80

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 (821) hide show
  1. package/.dockerignore +14 -0
  2. package/.env.example +144 -0
  3. package/.github/workflows/cyberia-client.cd.yml +40 -0
  4. package/.github/workflows/cyberia-server.cd.yml +40 -0
  5. package/.github/workflows/docker-image.cyberia-client.ci.yml +71 -0
  6. package/.github/workflows/docker-image.cyberia-client.dev.ci.yml +70 -0
  7. package/.github/workflows/docker-image.cyberia-server.ci.yml +71 -0
  8. package/.github/workflows/docker-image.cyberia-server.dev.ci.yml +71 -0
  9. package/.github/workflows/docker-image.engine-cyberia.ci.yml +53 -0
  10. package/.github/workflows/docker-image.engine-cyberia.dev.ci.yml +53 -0
  11. package/.github/workflows/engine-cyberia.cd.yml +157 -0
  12. package/.github/workflows/engine-cyberia.ci.yml +125 -0
  13. package/.github/workflows/ghpkg.ci.yml +160 -0
  14. package/.github/workflows/gitlab.ci.yml +20 -0
  15. package/.github/workflows/hardhat.ci.yml +82 -0
  16. package/.github/workflows/npmpkg.ci.yml +126 -0
  17. package/.github/workflows/publish.ci.yml +87 -0
  18. package/.github/workflows/publish.cyberia.ci.yml +79 -0
  19. package/.github/workflows/pwa-microservices-template-page.cd.yml +65 -0
  20. package/.github/workflows/pwa-microservices-template-test.ci.yml +33 -0
  21. package/.github/workflows/release.cd.yml +46 -0
  22. package/.nycrc +9 -0
  23. package/.prettierignore +12 -0
  24. package/.prettierrc +9 -0
  25. package/.vscode/extensions.json +10 -0
  26. package/.vscode/settings.json +26 -0
  27. package/CHANGELOG.md +2516 -0
  28. package/CLI-HELP.md +1099 -0
  29. package/Dockerfile +161 -0
  30. package/Dockerfile.dev +161 -0
  31. package/Dockerfile.test +165 -0
  32. package/LICENSE +21 -0
  33. package/README.md +259 -0
  34. package/baremetal/commission-workflows.json +211 -0
  35. package/baremetal/packer-workflows.json +24 -0
  36. package/bin/build.js +261 -0
  37. package/bin/build.template.js +33 -0
  38. package/bin/cyberia.js +5627 -0
  39. package/bin/deploy.js +1547 -0
  40. package/bin/index.js +5627 -0
  41. package/bump.config.js +27 -0
  42. package/compose.env +144 -0
  43. package/conf.js +952 -0
  44. package/deployment.yaml +418 -0
  45. package/docker-compose.yml +434 -0
  46. package/examples/static-page/README.md +150 -0
  47. package/examples/static-page/ssr-components/CustomPage.js +554 -0
  48. package/examples/static-page/static-config-example.json +57 -0
  49. package/hardhat/.env.example +31 -0
  50. package/hardhat/contracts/ObjectLayerToken.sol +391 -0
  51. package/hardhat/deployments/.gitkeep +0 -0
  52. package/hardhat/deployments/hardhat-ObjectLayerToken.json +11 -0
  53. package/hardhat/hardhat.config.js +136 -0
  54. package/hardhat/ignition/modules/.gitkeep +0 -0
  55. package/hardhat/ignition/modules/ObjectLayerToken.js +21 -0
  56. package/hardhat/networks/besu-object-layer.network.json +138 -0
  57. package/hardhat/package-lock.json +2871 -0
  58. package/hardhat/package.json +43 -0
  59. package/hardhat/scripts/deployObjectLayerToken.js +98 -0
  60. package/hardhat/test/ObjectLayerToken.js +696 -0
  61. package/hardhat/types/ethers-contracts/ObjectLayerToken.ts +690 -0
  62. package/hardhat/types/ethers-contracts/common.ts +92 -0
  63. package/hardhat/types/ethers-contracts/factories/ObjectLayerToken__factory.ts +1055 -0
  64. package/hardhat/types/ethers-contracts/factories/index.ts +4 -0
  65. package/hardhat/types/ethers-contracts/hardhat.d.ts +47 -0
  66. package/hardhat/types/ethers-contracts/index.ts +6 -0
  67. package/ipfs/configure-ipfs.sh +13 -0
  68. package/jsconfig.json +9 -0
  69. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +48 -0
  70. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +48 -0
  71. package/manifests/deployment/adminer/deployment.yaml +32 -0
  72. package/manifests/deployment/adminer/kustomization.yaml +7 -0
  73. package/manifests/deployment/adminer/service.yaml +13 -0
  74. package/manifests/deployment/dd-cyberia-development/deployment.yaml +418 -0
  75. package/manifests/deployment/dd-cyberia-development/grpc-service.yaml +17 -0
  76. package/manifests/deployment/dd-cyberia-development/proxy.yaml +189 -0
  77. package/manifests/deployment/dd-cyberia-development/pv-pvc.yaml +164 -0
  78. package/manifests/deployment/dd-default-development/deployment.yaml +163 -0
  79. package/manifests/deployment/dd-default-development/proxy.yaml +46 -0
  80. package/manifests/deployment/fastapi/backend-deployment.yml +120 -0
  81. package/manifests/deployment/fastapi/backend-service.yml +19 -0
  82. package/manifests/deployment/fastapi/frontend-deployment.yml +54 -0
  83. package/manifests/deployment/fastapi/frontend-service.yml +15 -0
  84. package/manifests/deployment/fastapi/initial_data.sh +8 -0
  85. package/manifests/deployment/kafka/deployment.yaml +67 -0
  86. package/manifests/deployment/mongo-express/deployment.yaml +62 -0
  87. package/manifests/deployment/phpmyadmin/deployment.yaml +54 -0
  88. package/manifests/deployment/playwright/deployment.yaml +52 -0
  89. package/manifests/deployment/spark/spark-pi-py.yaml +20 -0
  90. package/manifests/deployment/tensorflow/tf-gpu-test.yaml +63 -0
  91. package/manifests/envoy-service-nodeport.yaml +22 -0
  92. package/manifests/grafana/deployment.yaml +64 -0
  93. package/manifests/grafana/kustomization.yaml +7 -0
  94. package/manifests/grafana/pvc.yaml +12 -0
  95. package/manifests/grafana/service.yaml +14 -0
  96. package/manifests/grafana/storage-class.yaml +9 -0
  97. package/manifests/ipfs/configmap.yaml +64 -0
  98. package/manifests/ipfs/headless-service.yaml +35 -0
  99. package/manifests/ipfs/kustomization.yaml +8 -0
  100. package/manifests/ipfs/statefulset.yaml +149 -0
  101. package/manifests/ipfs/storage-class.yaml +9 -0
  102. package/manifests/kind-config-dev.yaml +20 -0
  103. package/manifests/kind-config.yaml +12 -0
  104. package/manifests/kubeadm-calico-config.yaml +14 -0
  105. package/manifests/letsencrypt-prod.yaml +14 -0
  106. package/manifests/lxd/lxd-admin-profile.yaml +26 -0
  107. package/manifests/lxd/lxd-preseed.yaml +30 -0
  108. package/manifests/mariadb/kustomization.yaml +9 -0
  109. package/manifests/mariadb/pv.yaml +12 -0
  110. package/manifests/mariadb/pvc.yaml +10 -0
  111. package/manifests/mariadb/service.yaml +10 -0
  112. package/manifests/mariadb/statefulset.yaml +56 -0
  113. package/manifests/mariadb/storage-class.yaml +10 -0
  114. package/manifests/mongodb/headless-service.yaml +10 -0
  115. package/manifests/mongodb/kustomization.yaml +11 -0
  116. package/manifests/mongodb/pv-pvc.yaml +59 -0
  117. package/manifests/mongodb/statefulset.yaml +113 -0
  118. package/manifests/mongodb/storage-class.yaml +9 -0
  119. package/manifests/mongodb-4.4/headless-service.yaml +10 -0
  120. package/manifests/mongodb-4.4/kustomization.yaml +9 -0
  121. package/manifests/mongodb-4.4/mongodb-nodeport.yaml +17 -0
  122. package/manifests/mongodb-4.4/pv-pvc.yaml +19 -0
  123. package/manifests/mongodb-4.4/service-deployment.yaml +61 -0
  124. package/manifests/mongodb-4.4/statefulset.yaml +79 -0
  125. package/manifests/mongodb-4.4/storage-class.yaml +9 -0
  126. package/manifests/mysql/kustomization.yaml +7 -0
  127. package/manifests/mysql/pv-pvc.yaml +27 -0
  128. package/manifests/mysql/statefulset.yaml +55 -0
  129. package/manifests/postgresql/configmap.yaml +9 -0
  130. package/manifests/postgresql/kustomization.yaml +10 -0
  131. package/manifests/postgresql/pv.yaml +15 -0
  132. package/manifests/postgresql/pvc.yaml +13 -0
  133. package/manifests/postgresql/service.yaml +10 -0
  134. package/manifests/postgresql/statefulset.yaml +37 -0
  135. package/manifests/prometheus/deployment.yaml +82 -0
  136. package/manifests/pv-pvc-dd.yaml +34 -0
  137. package/manifests/valkey/kustomization.yaml +7 -0
  138. package/manifests/valkey/service.yaml +10 -0
  139. package/manifests/valkey/statefulset.yaml +37 -0
  140. package/manifests/valkey/valkey-nodeport.yaml +17 -0
  141. package/mongodb/entrypoint.sh +76 -0
  142. package/nginx.conf +128 -0
  143. package/nodemon.json +6 -0
  144. package/package.json +101 -0
  145. package/packer/images/Rocky9Amd64/Makefile +62 -0
  146. package/packer/images/Rocky9Amd64/QUICKSTART.md +113 -0
  147. package/packer/images/Rocky9Amd64/README.md +122 -0
  148. package/packer/images/Rocky9Amd64/http/rocky9.ks.pkrtpl.hcl +114 -0
  149. package/packer/images/Rocky9Amd64/rocky9.pkr.hcl +164 -0
  150. package/packer/images/Rocky9Arm64/Makefile +69 -0
  151. package/packer/images/Rocky9Arm64/README.md +122 -0
  152. package/packer/images/Rocky9Arm64/http/rocky9.ks.pkrtpl.hcl +114 -0
  153. package/packer/images/Rocky9Arm64/rocky9.pkr.hcl +171 -0
  154. package/packer/scripts/fuse-nbd +64 -0
  155. package/packer/scripts/fuse-tar-root +63 -0
  156. package/proxy.yaml +189 -0
  157. package/pv-pvc.yaml +164 -0
  158. package/scripts/device-scan.sh +65 -0
  159. package/scripts/disk-clean.sh +182 -0
  160. package/scripts/disk-devices.sh +13 -0
  161. package/scripts/gen-fqdns.sh +14 -0
  162. package/scripts/gpu-diag.sh +19 -0
  163. package/scripts/ip-info.sh +118 -0
  164. package/scripts/ipxe-setup.sh +200 -0
  165. package/scripts/k3s-node-setup.sh +124 -0
  166. package/scripts/kubeadm-node-setup.sh +317 -0
  167. package/scripts/link-local-underpost-cli.sh +6 -0
  168. package/scripts/lxd-vm-setup.sh +208 -0
  169. package/scripts/maas-nat-firewalld.sh +145 -0
  170. package/scripts/maas-setup.sh +135 -0
  171. package/scripts/maas-upload-boot-resource.sh +183 -0
  172. package/scripts/nat-iptables.sh +111 -0
  173. package/scripts/nvim.sh +91 -0
  174. package/scripts/packer-init-vars-file.sh +40 -0
  175. package/scripts/packer-setup.sh +289 -0
  176. package/scripts/ports-ls.sh +33 -0
  177. package/scripts/quick-tftp.sh +19 -0
  178. package/scripts/rhel-grpc-setup.sh +56 -0
  179. package/scripts/rocky-kickstart.sh +986 -0
  180. package/scripts/rocky-pwa.sh +200 -0
  181. package/scripts/rocky-setup.sh +106 -0
  182. package/scripts/rpmfusion-ffmpeg-setup.sh +32 -0
  183. package/scripts/ssl.sh +170 -0
  184. package/scripts/test-monitor.sh +248 -0
  185. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.controller.js +30 -0
  186. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.model.js +155 -0
  187. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.router.js +39 -0
  188. package/src/api/atlas-sprite-sheet/atlas-sprite-sheet.service.js +382 -0
  189. package/src/api/core/core.controller.js +8 -0
  190. package/src/api/core/core.model.js +11 -0
  191. package/src/api/core/core.router.js +23 -0
  192. package/src/api/core/core.service.js +30 -0
  193. package/src/api/crypto/crypto.controller.js +10 -0
  194. package/src/api/crypto/crypto.model.js +23 -0
  195. package/src/api/crypto/crypto.router.js +23 -0
  196. package/src/api/crypto/crypto.service.js +64 -0
  197. package/src/api/cyberia-action/cyberia-action.controller.js +8 -0
  198. package/src/api/cyberia-action/cyberia-action.model.js +79 -0
  199. package/src/api/cyberia-action/cyberia-action.router.js +21 -0
  200. package/src/api/cyberia-action/cyberia-action.service.js +58 -0
  201. package/src/api/cyberia-client-hints/cyberia-client-hints.controller.js +27 -0
  202. package/src/api/cyberia-client-hints/cyberia-client-hints.model.js +100 -0
  203. package/src/api/cyberia-client-hints/cyberia-client-hints.router.js +70 -0
  204. package/src/api/cyberia-client-hints/cyberia-client-hints.service.js +152 -0
  205. package/src/api/cyberia-dialogue/cyberia-dialogue.controller.js +8 -0
  206. package/src/api/cyberia-dialogue/cyberia-dialogue.model.js +36 -0
  207. package/src/api/cyberia-dialogue/cyberia-dialogue.router.js +20 -0
  208. package/src/api/cyberia-dialogue/cyberia-dialogue.service.js +57 -0
  209. package/src/api/cyberia-entity/cyberia-entity.controller.js +6 -0
  210. package/src/api/cyberia-entity/cyberia-entity.model.js +25 -0
  211. package/src/api/cyberia-entity/cyberia-entity.router.js +17 -0
  212. package/src/api/cyberia-entity/cyberia-entity.service.js +42 -0
  213. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.controller.js +6 -0
  214. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.model.js +67 -0
  215. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.router.js +17 -0
  216. package/src/api/cyberia-entity-type-default/cyberia-entity-type-default.service.js +46 -0
  217. package/src/api/cyberia-instance/cyberia-fallback-world.js +337 -0
  218. package/src/api/cyberia-instance/cyberia-instance-boot.service.js +57 -0
  219. package/src/api/cyberia-instance/cyberia-instance-map.service.js +583 -0
  220. package/src/api/cyberia-instance/cyberia-instance.controller.js +42 -0
  221. package/src/api/cyberia-instance/cyberia-instance.model.js +117 -0
  222. package/src/api/cyberia-instance/cyberia-instance.router.js +75 -0
  223. package/src/api/cyberia-instance/cyberia-instance.service.js +190 -0
  224. package/src/api/cyberia-instance/cyberia-portal-connector.js +260 -0
  225. package/src/api/cyberia-instance/cyberia-world-generator.js +618 -0
  226. package/src/api/cyberia-instance-conf/cyberia-instance-conf.controller.js +6 -0
  227. package/src/api/cyberia-instance-conf/cyberia-instance-conf.model.js +200 -0
  228. package/src/api/cyberia-instance-conf/cyberia-instance-conf.router.js +17 -0
  229. package/src/api/cyberia-instance-conf/cyberia-instance-conf.service.js +46 -0
  230. package/src/api/cyberia-map/cyberia-map.controller.js +6 -0
  231. package/src/api/cyberia-map/cyberia-map.model.js +33 -0
  232. package/src/api/cyberia-map/cyberia-map.router.js +19 -0
  233. package/src/api/cyberia-map/cyberia-map.service.js +76 -0
  234. package/src/api/cyberia-quest/cyberia-quest.controller.js +9 -0
  235. package/src/api/cyberia-quest/cyberia-quest.model.js +67 -0
  236. package/src/api/cyberia-quest/cyberia-quest.router.js +26 -0
  237. package/src/api/cyberia-quest/cyberia-quest.service.js +97 -0
  238. package/src/api/cyberia-quest-progress/cyberia-quest-progress.controller.js +6 -0
  239. package/src/api/cyberia-quest-progress/cyberia-quest-progress.model.js +49 -0
  240. package/src/api/cyberia-quest-progress/cyberia-quest-progress.router.js +21 -0
  241. package/src/api/cyberia-quest-progress/cyberia-quest-progress.service.js +42 -0
  242. package/src/api/cyberia-saga/cyberia-saga.controller.js +6 -0
  243. package/src/api/cyberia-saga/cyberia-saga.model.js +59 -0
  244. package/src/api/cyberia-saga/cyberia-saga.router.js +17 -0
  245. package/src/api/cyberia-saga/cyberia-saga.service.js +42 -0
  246. package/src/api/cyberia-server-defaults/cyberia-server-defaults.js +1076 -0
  247. package/src/api/cyberia-skill/cyberia-skill.controller.js +6 -0
  248. package/src/api/cyberia-skill/cyberia-skill.model.js +50 -0
  249. package/src/api/cyberia-skill/cyberia-skill.router.js +17 -0
  250. package/src/api/cyberia-skill/cyberia-skill.service.js +42 -0
  251. package/src/api/default/default.controller.js +6 -0
  252. package/src/api/default/default.model.js +20 -0
  253. package/src/api/default/default.router.js +21 -0
  254. package/src/api/default/default.service.js +42 -0
  255. package/src/api/document/document.controller.js +9 -0
  256. package/src/api/document/document.model.js +95 -0
  257. package/src/api/document/document.router.js +32 -0
  258. package/src/api/document/document.service.js +633 -0
  259. package/src/api/file/file.controller.js +15 -0
  260. package/src/api/file/file.model.js +127 -0
  261. package/src/api/file/file.ref.json +39 -0
  262. package/src/api/file/file.router.js +36 -0
  263. package/src/api/file/file.service.js +499 -0
  264. package/src/api/instance/instance.controller.js +8 -0
  265. package/src/api/instance/instance.model.js +34 -0
  266. package/src/api/instance/instance.router.js +27 -0
  267. package/src/api/instance/instance.service.js +75 -0
  268. package/src/api/ipfs/ipfs.controller.js +8 -0
  269. package/src/api/ipfs/ipfs.model.js +77 -0
  270. package/src/api/ipfs/ipfs.router.js +26 -0
  271. package/src/api/ipfs/ipfs.service.js +145 -0
  272. package/src/api/object-layer/object-layer.controller.js +18 -0
  273. package/src/api/object-layer/object-layer.model.js +200 -0
  274. package/src/api/object-layer/object-layer.router.js +729 -0
  275. package/src/api/object-layer/object-layer.service.js +894 -0
  276. package/src/api/object-layer-render-frames/object-layer-render-frames.controller.js +6 -0
  277. package/src/api/object-layer-render-frames/object-layer-render-frames.model.js +93 -0
  278. package/src/api/object-layer-render-frames/object-layer-render-frames.router.js +17 -0
  279. package/src/api/object-layer-render-frames/object-layer-render-frames.service.js +46 -0
  280. package/src/api/test/test.controller.js +14 -0
  281. package/src/api/test/test.model.js +14 -0
  282. package/src/api/test/test.router.js +23 -0
  283. package/src/api/test/test.service.js +35 -0
  284. package/src/api/types.js +24 -0
  285. package/src/api/user/guest.service.js +100 -0
  286. package/src/api/user/postman_collection.json +216 -0
  287. package/src/api/user/user.build.js +16 -0
  288. package/src/api/user/user.controller.js +35 -0
  289. package/src/api/user/user.model.js +142 -0
  290. package/src/api/user/user.router.js +367 -0
  291. package/src/api/user/user.service.js +582 -0
  292. package/src/api.js +23 -0
  293. package/src/cli/baremetal.js +3947 -0
  294. package/src/cli/cloud-init.js +673 -0
  295. package/src/cli/cluster.js +1395 -0
  296. package/src/cli/db.js +1533 -0
  297. package/src/cli/deploy.js +1542 -0
  298. package/src/cli/docker-compose.js +802 -0
  299. package/src/cli/env.js +177 -0
  300. package/src/cli/fs.js +380 -0
  301. package/src/cli/image.js +389 -0
  302. package/src/cli/index.js +1059 -0
  303. package/src/cli/ipfs.js +182 -0
  304. package/src/cli/kickstart.js +271 -0
  305. package/src/cli/kubectl.js +214 -0
  306. package/src/cli/lxd.js +1232 -0
  307. package/src/cli/monitor.js +659 -0
  308. package/src/cli/release.js +595 -0
  309. package/src/cli/repository.js +1969 -0
  310. package/src/cli/run.js +3326 -0
  311. package/src/cli/secrets.js +151 -0
  312. package/src/cli/ssh.js +975 -0
  313. package/src/cli/static.js +653 -0
  314. package/src/cli/system.js +332 -0
  315. package/src/cli/test.js +176 -0
  316. package/src/client/Cryptokoyn.index.js +30 -0
  317. package/src/client/CyberiaPortal.index.js +31 -0
  318. package/src/client/Default.index.js +77 -0
  319. package/src/client/Itemledger.index.js +35 -0
  320. package/src/client/Underpost.index.js +31 -0
  321. package/src/client/components/core/404.js +20 -0
  322. package/src/client/components/core/500.js +20 -0
  323. package/src/client/components/core/Account.js +630 -0
  324. package/src/client/components/core/AgGrid.js +238 -0
  325. package/src/client/components/core/Alert.js +76 -0
  326. package/src/client/components/core/AppStore.js +69 -0
  327. package/src/client/components/core/Auth.js +353 -0
  328. package/src/client/components/core/Badge.js +26 -0
  329. package/src/client/components/core/Blockchain.js +41 -0
  330. package/src/client/components/core/Blog.js +9 -0
  331. package/src/client/components/core/BtnIcon.js +109 -0
  332. package/src/client/components/core/CalendarCore.js +437 -0
  333. package/src/client/components/core/Chat.js +62 -0
  334. package/src/client/components/core/ClientEvents.js +163 -0
  335. package/src/client/components/core/ColorPaletteElement.js +309 -0
  336. package/src/client/components/core/CommonJs.js +1014 -0
  337. package/src/client/components/core/Content.js +349 -0
  338. package/src/client/components/core/Css.js +1134 -0
  339. package/src/client/components/core/CssCore.js +881 -0
  340. package/src/client/components/core/D3Chart.js +44 -0
  341. package/src/client/components/core/Docs.js +478 -0
  342. package/src/client/components/core/DropDown.js +321 -0
  343. package/src/client/components/core/EventBus.js +96 -0
  344. package/src/client/components/core/EventsUI.js +130 -0
  345. package/src/client/components/core/FileExplorer.js +1406 -0
  346. package/src/client/components/core/FullScreen.js +201 -0
  347. package/src/client/components/core/Input.js +537 -0
  348. package/src/client/components/core/Keyboard.js +80 -0
  349. package/src/client/components/core/KeyboardAvoidance.js +145 -0
  350. package/src/client/components/core/LoadingAnimation.js +152 -0
  351. package/src/client/components/core/LogIn.js +212 -0
  352. package/src/client/components/core/LogOut.js +72 -0
  353. package/src/client/components/core/Logger.js +22 -0
  354. package/src/client/components/core/Modal.js +2956 -0
  355. package/src/client/components/core/NotificationManager.js +80 -0
  356. package/src/client/components/core/Pagination.js +252 -0
  357. package/src/client/components/core/Panel.js +1308 -0
  358. package/src/client/components/core/PanelForm.js +915 -0
  359. package/src/client/components/core/Polyhedron.js +947 -0
  360. package/src/client/components/core/PublicProfile.js +895 -0
  361. package/src/client/components/core/Recover.js +211 -0
  362. package/src/client/components/core/Responsive.js +146 -0
  363. package/src/client/components/core/RichText.js +33 -0
  364. package/src/client/components/core/Router.js +523 -0
  365. package/src/client/components/core/Scroll.js +76 -0
  366. package/src/client/components/core/SearchBox.js +1007 -0
  367. package/src/client/components/core/SignUp.js +153 -0
  368. package/src/client/components/core/SocketIo.js +163 -0
  369. package/src/client/components/core/SocketIoHandler.js +75 -0
  370. package/src/client/components/core/Stream.js +161 -0
  371. package/src/client/components/core/ToggleSwitch.js +89 -0
  372. package/src/client/components/core/ToolTip.js +78 -0
  373. package/src/client/components/core/Translate.js +694 -0
  374. package/src/client/components/core/Validator.js +140 -0
  375. package/src/client/components/core/VanillaJs.js +485 -0
  376. package/src/client/components/core/Wallet.js +95 -0
  377. package/src/client/components/core/WebComponent.js +44 -0
  378. package/src/client/components/core/Webhook.js +58 -0
  379. package/src/client/components/core/Worker.js +313 -0
  380. package/src/client/components/core/windowGetDimensions.js +269 -0
  381. package/src/client/components/cryptokoyn/AppShellCryptokoyn.js +352 -0
  382. package/src/client/components/cryptokoyn/AppStoreCryptokoyn.js +5 -0
  383. package/src/client/components/cryptokoyn/CssCryptokoyn.js +212 -0
  384. package/src/client/components/cryptokoyn/LogInCryptokoyn.js +16 -0
  385. package/src/client/components/cryptokoyn/LogOutCryptokoyn.js +12 -0
  386. package/src/client/components/cryptokoyn/RouterCryptokoyn.js +37 -0
  387. package/src/client/components/cryptokoyn/SettingsCryptokoyn.js +16 -0
  388. package/src/client/components/cryptokoyn/SignUpCryptokoyn.js +11 -0
  389. package/src/client/components/cryptokoyn/SocketIoCryptokoyn.js +6 -0
  390. package/src/client/components/cyberia/ActionEngineCyberia.js +1867 -0
  391. package/src/client/components/cyberia/EntityEngineCyberia.js +585 -0
  392. package/src/client/components/cyberia/InstanceEngineCyberia.js +1088 -0
  393. package/src/client/components/cyberia/InstanceSelectionView.js +900 -0
  394. package/src/client/components/cyberia/MapEngineCyberia.js +1976 -0
  395. package/src/client/components/cyberia/ObjectLayerEngine.js +1540 -0
  396. package/src/client/components/cyberia/ObjectLayerEngineModal.js +2420 -0
  397. package/src/client/components/cyberia/ObjectLayerEngineViewer.js +1522 -0
  398. package/src/client/components/cyberia/SharedDefaultsCyberia.js +528 -0
  399. package/src/client/components/cyberia-portal/AppShellCyberiaPortal.js +772 -0
  400. package/src/client/components/cyberia-portal/AppStoreCyberiaPortal.js +5 -0
  401. package/src/client/components/cyberia-portal/CssCyberiaPortal.js +254 -0
  402. package/src/client/components/cyberia-portal/LogInCyberiaPortal.js +21 -0
  403. package/src/client/components/cyberia-portal/LogOutCyberiaPortal.js +16 -0
  404. package/src/client/components/cyberia-portal/MainBodyCyberiaPortal.js +518 -0
  405. package/src/client/components/cyberia-portal/RouterCyberiaPortal.js +72 -0
  406. package/src/client/components/cyberia-portal/SettingsCyberiaPortal.js +16 -0
  407. package/src/client/components/cyberia-portal/SignUpCyberiaPortal.js +13 -0
  408. package/src/client/components/cyberia-portal/SocketIoCyberiaPortal.js +6 -0
  409. package/src/client/components/cyberia-portal/TranslateCyberiaPortal.js +48 -0
  410. package/src/client/components/default/AppShellDefault.js +765 -0
  411. package/src/client/components/default/AppStoreDefault.js +5 -0
  412. package/src/client/components/default/CommonDefault.js +29 -0
  413. package/src/client/components/default/CssDefault.js +27 -0
  414. package/src/client/components/default/LogInDefault.js +16 -0
  415. package/src/client/components/default/LogOutDefault.js +12 -0
  416. package/src/client/components/default/RouterDefault.js +47 -0
  417. package/src/client/components/default/SettingsDefault.js +16 -0
  418. package/src/client/components/default/SignUpDefault.js +11 -0
  419. package/src/client/components/default/SocketIoDefault.js +6 -0
  420. package/src/client/components/default/TranslateDefault.js +7 -0
  421. package/src/client/components/itemledger/AppShellItemledger.js +353 -0
  422. package/src/client/components/itemledger/AppStoreItemledger.js +5 -0
  423. package/src/client/components/itemledger/CssItemledger.js +212 -0
  424. package/src/client/components/itemledger/LogInItemledger.js +17 -0
  425. package/src/client/components/itemledger/LogOutItemledger.js +12 -0
  426. package/src/client/components/itemledger/RouterItemledger.js +38 -0
  427. package/src/client/components/itemledger/SettingsItemledger.js +16 -0
  428. package/src/client/components/itemledger/SignUpItemledger.js +11 -0
  429. package/src/client/components/itemledger/SocketIoItemledger.js +6 -0
  430. package/src/client/components/itemledger/TranslateItemledger.js +7 -0
  431. package/src/client/components/underpost/AppShellUnderpost.js +691 -0
  432. package/src/client/components/underpost/AppStoreUnderpost.js +5 -0
  433. package/src/client/components/underpost/CssUnderpost.js +281 -0
  434. package/src/client/components/underpost/CyberpunkBloggerUnderpost.js +879 -0
  435. package/src/client/components/underpost/DocumentSearchProvider.js +448 -0
  436. package/src/client/components/underpost/LabGalleryUnderpost.js +79 -0
  437. package/src/client/components/underpost/LogInUnderpost.js +25 -0
  438. package/src/client/components/underpost/LogOutUnderpost.js +17 -0
  439. package/src/client/components/underpost/RouterUnderpost.js +45 -0
  440. package/src/client/components/underpost/SettingsUnderpost.js +16 -0
  441. package/src/client/components/underpost/SignUpUnderpost.js +11 -0
  442. package/src/client/components/underpost/SocketIoUnderpost.js +6 -0
  443. package/src/client/components/underpost/TranslateUnderpost.js +10 -0
  444. package/src/client/public/cryptokoyn/assets/banner/koyn-social.png +0 -0
  445. package/src/client/public/cryptokoyn/assets/logo/base-icon.png +0 -0
  446. package/src/client/public/cryptokoyn/assets/logo/cryptokoyn.png +0 -0
  447. package/src/client/public/cryptokoyn/assets/splash/android-chrome-144x144.png +0 -0
  448. package/src/client/public/cryptokoyn/assets/splash/android-chrome-192x192.png +0 -0
  449. package/src/client/public/cryptokoyn/assets/splash/android-chrome-256x256.png +0 -0
  450. package/src/client/public/cryptokoyn/assets/splash/android-chrome-36x36.png +0 -0
  451. package/src/client/public/cryptokoyn/assets/splash/android-chrome-48x48.png +0 -0
  452. package/src/client/public/cryptokoyn/assets/splash/android-chrome-72x72.png +0 -0
  453. package/src/client/public/cryptokoyn/assets/splash/android-chrome-96x96.png +0 -0
  454. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-114x114-precomposed.png +0 -0
  455. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-114x114.png +0 -0
  456. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-120x120-precomposed.png +0 -0
  457. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-120x120.png +0 -0
  458. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-144x144-precomposed.png +0 -0
  459. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-144x144.png +0 -0
  460. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-152x152-precomposed.png +0 -0
  461. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-152x152.png +0 -0
  462. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-180x180-precomposed.png +0 -0
  463. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-180x180.png +0 -0
  464. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-57x57-precomposed.png +0 -0
  465. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-57x57.png +0 -0
  466. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-60x60-precomposed.png +0 -0
  467. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-60x60.png +0 -0
  468. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-72x72-precomposed.png +0 -0
  469. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-72x72.png +0 -0
  470. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-76x76-precomposed.png +0 -0
  471. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-76x76.png +0 -0
  472. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon-precomposed.png +0 -0
  473. package/src/client/public/cryptokoyn/assets/splash/apple-touch-icon.png +0 -0
  474. package/src/client/public/cryptokoyn/assets/splash/favicon-16x16.png +0 -0
  475. package/src/client/public/cryptokoyn/assets/splash/favicon-32x32.png +0 -0
  476. package/src/client/public/cryptokoyn/assets/splash/mstile-144x144.png +0 -0
  477. package/src/client/public/cryptokoyn/assets/splash/mstile-150x150.png +0 -0
  478. package/src/client/public/cryptokoyn/assets/splash/mstile-310x150.png +0 -0
  479. package/src/client/public/cryptokoyn/assets/splash/mstile-310x310.png +0 -0
  480. package/src/client/public/cryptokoyn/assets/splash/mstile-70x70.png +0 -0
  481. package/src/client/public/cryptokoyn/assets/splash/safari-pinned-tab.svg +42 -0
  482. package/src/client/public/cryptokoyn/browserconfig.xml +12 -0
  483. package/src/client/public/cryptokoyn/favicon.ico +0 -0
  484. package/src/client/public/cryptokoyn/microdata.json +85 -0
  485. package/src/client/public/cryptokoyn/site.webmanifest +57 -0
  486. package/src/client/public/cryptokoyn/sitemap +148 -0
  487. package/src/client/public/cyberia-docs/ACTION-SYSTEM.md +307 -0
  488. package/src/client/public/cyberia-docs/ARCHITECTURE.md +309 -0
  489. package/src/client/public/cyberia-docs/CYBERIA-CLI.md +204 -0
  490. package/src/client/public/cyberia-docs/CYBERIA-CLIENT.md +341 -0
  491. package/src/client/public/cyberia-docs/CYBERIA-LORE.md +84 -0
  492. package/src/client/public/cyberia-docs/CYBERIA-SAGA.md +394 -0
  493. package/src/client/public/cyberia-docs/CYBERIA-SERVER.md +294 -0
  494. package/src/client/public/cyberia-docs/CYBERIA.md +259 -0
  495. package/src/client/public/cyberia-docs/ENTITY-PROFILE.md +242 -0
  496. package/src/client/public/cyberia-docs/HARDHAT-MODULE.md +300 -0
  497. package/src/client/public/cyberia-docs/OFF-CHAIN-ECONOMY.md +309 -0
  498. package/src/client/public/cyberia-docs/QUEST-SYSTEM.md +228 -0
  499. package/src/client/public/cyberia-docs/ROADMAP.md +240 -0
  500. package/src/client/public/cyberia-docs/UNDERPOST-PLATFORM.md +106 -0
  501. package/src/client/public/cyberia-docs/WHITE-PAPER.md +740 -0
  502. package/src/client/public/default/android-chrome-144x144.png +0 -0
  503. package/src/client/public/default/android-chrome-192x192.png +0 -0
  504. package/src/client/public/default/android-chrome-256x256.png +0 -0
  505. package/src/client/public/default/android-chrome-36x36.png +0 -0
  506. package/src/client/public/default/android-chrome-384x384.png +0 -0
  507. package/src/client/public/default/android-chrome-48x48.png +0 -0
  508. package/src/client/public/default/android-chrome-512x512.png +0 -0
  509. package/src/client/public/default/android-chrome-72x72.png +0 -0
  510. package/src/client/public/default/android-chrome-96x96.png +0 -0
  511. package/src/client/public/default/apple-touch-icon-1024x1024.png +0 -0
  512. package/src/client/public/default/apple-touch-icon-114x114-precomposed.png +0 -0
  513. package/src/client/public/default/apple-touch-icon-114x114.png +0 -0
  514. package/src/client/public/default/apple-touch-icon-120x120-precomposed.png +0 -0
  515. package/src/client/public/default/apple-touch-icon-120x120.png +0 -0
  516. package/src/client/public/default/apple-touch-icon-144x144-precomposed.png +0 -0
  517. package/src/client/public/default/apple-touch-icon-144x144.png +0 -0
  518. package/src/client/public/default/apple-touch-icon-152x152-precomposed.png +0 -0
  519. package/src/client/public/default/apple-touch-icon-152x152.png +0 -0
  520. package/src/client/public/default/apple-touch-icon-167x167.png +0 -0
  521. package/src/client/public/default/apple-touch-icon-180x180-precomposed.png +0 -0
  522. package/src/client/public/default/apple-touch-icon-180x180.png +0 -0
  523. package/src/client/public/default/apple-touch-icon-57x57-precomposed.png +0 -0
  524. package/src/client/public/default/apple-touch-icon-57x57.png +0 -0
  525. package/src/client/public/default/apple-touch-icon-60x60-precomposed.png +0 -0
  526. package/src/client/public/default/apple-touch-icon-60x60.png +0 -0
  527. package/src/client/public/default/apple-touch-icon-72x72-precomposed.png +0 -0
  528. package/src/client/public/default/apple-touch-icon-72x72.png +0 -0
  529. package/src/client/public/default/apple-touch-icon-76x76-precomposed.png +0 -0
  530. package/src/client/public/default/apple-touch-icon-76x76.png +0 -0
  531. package/src/client/public/default/apple-touch-icon-precomposed.png +0 -0
  532. package/src/client/public/default/apple-touch-icon.png +0 -0
  533. package/src/client/public/default/apple-touch-startup-image-1125x2436.png +0 -0
  534. package/src/client/public/default/apple-touch-startup-image-1136x640.png +0 -0
  535. package/src/client/public/default/apple-touch-startup-image-1170x2532.png +0 -0
  536. package/src/client/public/default/apple-touch-startup-image-1179x2556.png +0 -0
  537. package/src/client/public/default/apple-touch-startup-image-1242x2208.png +0 -0
  538. package/src/client/public/default/apple-touch-startup-image-1242x2688.png +0 -0
  539. package/src/client/public/default/apple-touch-startup-image-1284x2778.png +0 -0
  540. package/src/client/public/default/apple-touch-startup-image-1290x2796.png +0 -0
  541. package/src/client/public/default/apple-touch-startup-image-1334x750.png +0 -0
  542. package/src/client/public/default/apple-touch-startup-image-1488x2266.png +0 -0
  543. package/src/client/public/default/apple-touch-startup-image-1536x2048.png +0 -0
  544. package/src/client/public/default/apple-touch-startup-image-1620x2160.png +0 -0
  545. package/src/client/public/default/apple-touch-startup-image-1640x2160.png +0 -0
  546. package/src/client/public/default/apple-touch-startup-image-1668x2224.png +0 -0
  547. package/src/client/public/default/apple-touch-startup-image-1668x2388.png +0 -0
  548. package/src/client/public/default/apple-touch-startup-image-1792x828.png +0 -0
  549. package/src/client/public/default/apple-touch-startup-image-2048x1536.png +0 -0
  550. package/src/client/public/default/apple-touch-startup-image-2048x2732.png +0 -0
  551. package/src/client/public/default/apple-touch-startup-image-2160x1620.png +0 -0
  552. package/src/client/public/default/apple-touch-startup-image-2160x1640.png +0 -0
  553. package/src/client/public/default/apple-touch-startup-image-2208x1242.png +0 -0
  554. package/src/client/public/default/apple-touch-startup-image-2224x1668.png +0 -0
  555. package/src/client/public/default/apple-touch-startup-image-2266x1488.png +0 -0
  556. package/src/client/public/default/apple-touch-startup-image-2388x1668.png +0 -0
  557. package/src/client/public/default/apple-touch-startup-image-2436x1125.png +0 -0
  558. package/src/client/public/default/apple-touch-startup-image-2532x1170.png +0 -0
  559. package/src/client/public/default/apple-touch-startup-image-2556x1179.png +0 -0
  560. package/src/client/public/default/apple-touch-startup-image-2688x1242.png +0 -0
  561. package/src/client/public/default/apple-touch-startup-image-2732x2048.png +0 -0
  562. package/src/client/public/default/apple-touch-startup-image-2778x1284.png +0 -0
  563. package/src/client/public/default/apple-touch-startup-image-2796x1290.png +0 -0
  564. package/src/client/public/default/apple-touch-startup-image-640x1136.png +0 -0
  565. package/src/client/public/default/apple-touch-startup-image-750x1334.png +0 -0
  566. package/src/client/public/default/apple-touch-startup-image-828x1792.png +0 -0
  567. package/src/client/public/default/assets/background/dark.jpg +0 -0
  568. package/src/client/public/default/assets/background/dark.svg +557 -0
  569. package/src/client/public/default/assets/background/white.jpg +0 -0
  570. package/src/client/public/default/assets/background/white0-min.jpg +0 -0
  571. package/src/client/public/default/assets/background/white0.jpg +0 -0
  572. package/src/client/public/default/assets/logo/base-icon.png +0 -0
  573. package/src/client/public/default/assets/logo/underpost.gif +0 -0
  574. package/src/client/public/default/assets/mailer/api-user-check.png +0 -0
  575. package/src/client/public/default/assets/mailer/api-user-default-avatar.png +0 -0
  576. package/src/client/public/default/assets/mailer/api-user-invalid-token.png +0 -0
  577. package/src/client/public/default/assets/mailer/api-user-recover.png +0 -0
  578. package/src/client/public/default/browserconfig.xml +12 -0
  579. package/src/client/public/default/favicon-16x16.png +0 -0
  580. package/src/client/public/default/favicon-32x32.png +0 -0
  581. package/src/client/public/default/favicon-48x48.png +0 -0
  582. package/src/client/public/default/favicon.ico +0 -0
  583. package/src/client/public/default/manifest.webmanifest +69 -0
  584. package/src/client/public/default/mstile-144x144.png +0 -0
  585. package/src/client/public/default/mstile-150x150.png +0 -0
  586. package/src/client/public/default/mstile-310x150.png +0 -0
  587. package/src/client/public/default/mstile-310x310.png +0 -0
  588. package/src/client/public/default/mstile-70x70.png +0 -0
  589. package/src/client/public/default/safari-pinned-tab.svg +24 -0
  590. package/src/client/public/default/site.webmanifest +69 -0
  591. package/src/client/public/default/sitemap +148 -0
  592. package/src/client/public/default/yandex-browser-50x50.png +0 -0
  593. package/src/client/public/default/yandex-browser-manifest.json +9 -0
  594. package/src/client/public/doc/favicon.ico +0 -0
  595. package/src/client/public/doc/sitemap +148 -0
  596. package/src/client/public/itemledger/android-chrome-144x144.png +0 -0
  597. package/src/client/public/itemledger/android-chrome-192x192.png +0 -0
  598. package/src/client/public/itemledger/android-chrome-256x256.png +0 -0
  599. package/src/client/public/itemledger/android-chrome-36x36.png +0 -0
  600. package/src/client/public/itemledger/android-chrome-384x384.png +0 -0
  601. package/src/client/public/itemledger/android-chrome-48x48.png +0 -0
  602. package/src/client/public/itemledger/android-chrome-512x512.png +0 -0
  603. package/src/client/public/itemledger/android-chrome-72x72.png +0 -0
  604. package/src/client/public/itemledger/android-chrome-96x96.png +0 -0
  605. package/src/client/public/itemledger/apple-touch-icon-1024x1024.png +0 -0
  606. package/src/client/public/itemledger/apple-touch-icon-114x114.png +0 -0
  607. package/src/client/public/itemledger/apple-touch-icon-120x120.png +0 -0
  608. package/src/client/public/itemledger/apple-touch-icon-144x144.png +0 -0
  609. package/src/client/public/itemledger/apple-touch-icon-152x152.png +0 -0
  610. package/src/client/public/itemledger/apple-touch-icon-167x167.png +0 -0
  611. package/src/client/public/itemledger/apple-touch-icon-180x180.png +0 -0
  612. package/src/client/public/itemledger/apple-touch-icon-57x57.png +0 -0
  613. package/src/client/public/itemledger/apple-touch-icon-60x60.png +0 -0
  614. package/src/client/public/itemledger/apple-touch-icon-72x72.png +0 -0
  615. package/src/client/public/itemledger/apple-touch-icon-76x76.png +0 -0
  616. package/src/client/public/itemledger/apple-touch-icon-precomposed.png +0 -0
  617. package/src/client/public/itemledger/apple-touch-icon.png +0 -0
  618. package/src/client/public/itemledger/apple-touch-startup-image-1125x2436.png +0 -0
  619. package/src/client/public/itemledger/apple-touch-startup-image-1136x640.png +0 -0
  620. package/src/client/public/itemledger/apple-touch-startup-image-1170x2532.png +0 -0
  621. package/src/client/public/itemledger/apple-touch-startup-image-1179x2556.png +0 -0
  622. package/src/client/public/itemledger/apple-touch-startup-image-1242x2208.png +0 -0
  623. package/src/client/public/itemledger/apple-touch-startup-image-1242x2688.png +0 -0
  624. package/src/client/public/itemledger/apple-touch-startup-image-1284x2778.png +0 -0
  625. package/src/client/public/itemledger/apple-touch-startup-image-1290x2796.png +0 -0
  626. package/src/client/public/itemledger/apple-touch-startup-image-1334x750.png +0 -0
  627. package/src/client/public/itemledger/apple-touch-startup-image-1488x2266.png +0 -0
  628. package/src/client/public/itemledger/apple-touch-startup-image-1536x2048.png +0 -0
  629. package/src/client/public/itemledger/apple-touch-startup-image-1620x2160.png +0 -0
  630. package/src/client/public/itemledger/apple-touch-startup-image-1640x2160.png +0 -0
  631. package/src/client/public/itemledger/apple-touch-startup-image-1668x2224.png +0 -0
  632. package/src/client/public/itemledger/apple-touch-startup-image-1668x2388.png +0 -0
  633. package/src/client/public/itemledger/apple-touch-startup-image-1792x828.png +0 -0
  634. package/src/client/public/itemledger/apple-touch-startup-image-2048x1536.png +0 -0
  635. package/src/client/public/itemledger/apple-touch-startup-image-2048x2732.png +0 -0
  636. package/src/client/public/itemledger/apple-touch-startup-image-2160x1620.png +0 -0
  637. package/src/client/public/itemledger/apple-touch-startup-image-2160x1640.png +0 -0
  638. package/src/client/public/itemledger/apple-touch-startup-image-2208x1242.png +0 -0
  639. package/src/client/public/itemledger/apple-touch-startup-image-2224x1668.png +0 -0
  640. package/src/client/public/itemledger/apple-touch-startup-image-2266x1488.png +0 -0
  641. package/src/client/public/itemledger/apple-touch-startup-image-2388x1668.png +0 -0
  642. package/src/client/public/itemledger/apple-touch-startup-image-2436x1125.png +0 -0
  643. package/src/client/public/itemledger/apple-touch-startup-image-2532x1170.png +0 -0
  644. package/src/client/public/itemledger/apple-touch-startup-image-2556x1179.png +0 -0
  645. package/src/client/public/itemledger/apple-touch-startup-image-2688x1242.png +0 -0
  646. package/src/client/public/itemledger/apple-touch-startup-image-2732x2048.png +0 -0
  647. package/src/client/public/itemledger/apple-touch-startup-image-2778x1284.png +0 -0
  648. package/src/client/public/itemledger/apple-touch-startup-image-2796x1290.png +0 -0
  649. package/src/client/public/itemledger/apple-touch-startup-image-640x1136.png +0 -0
  650. package/src/client/public/itemledger/apple-touch-startup-image-750x1334.png +0 -0
  651. package/src/client/public/itemledger/apple-touch-startup-image-828x1792.png +0 -0
  652. package/src/client/public/itemledger/assets/logo/base-icon.png +0 -0
  653. package/src/client/public/itemledger/browserconfig.xml +12 -0
  654. package/src/client/public/itemledger/favicon-16x16.png +0 -0
  655. package/src/client/public/itemledger/favicon-32x32.png +0 -0
  656. package/src/client/public/itemledger/favicon-48x48.png +0 -0
  657. package/src/client/public/itemledger/favicon.ico +0 -0
  658. package/src/client/public/itemledger/manifest.webmanifest +69 -0
  659. package/src/client/public/itemledger/microdata.json +71 -0
  660. package/src/client/public/itemledger/mstile-144x144.png +0 -0
  661. package/src/client/public/itemledger/mstile-150x150.png +0 -0
  662. package/src/client/public/itemledger/mstile-310x150.png +0 -0
  663. package/src/client/public/itemledger/mstile-310x310.png +0 -0
  664. package/src/client/public/itemledger/mstile-70x70.png +0 -0
  665. package/src/client/public/itemledger/sitemap +148 -0
  666. package/src/client/public/itemledger/yandex-browser-50x50.png +0 -0
  667. package/src/client/public/itemledger/yandex-browser-manifest.json +9 -0
  668. package/src/client/public/test/favicon.ico +0 -0
  669. package/src/client/public/test/sitemap +148 -0
  670. package/src/client/services/atlas-sprite-sheet/atlas-sprite-sheet.service.js +137 -0
  671. package/src/client/services/core/core.service.js +309 -0
  672. package/src/client/services/crypto/crypto.service.js +68 -0
  673. package/src/client/services/cyberia-action/cyberia-action.service.js +99 -0
  674. package/src/client/services/cyberia-client-hints/cyberia-client-hints.service.js +99 -0
  675. package/src/client/services/cyberia-dialogue/cyberia-dialogue.service.js +99 -0
  676. package/src/client/services/cyberia-entity/cyberia-entity.management.js +57 -0
  677. package/src/client/services/cyberia-entity/cyberia-entity.service.js +99 -0
  678. package/src/client/services/cyberia-entity-type-default/cyberia-entity-type-default.service.js +99 -0
  679. package/src/client/services/cyberia-instance/cyberia-instance.management.js +194 -0
  680. package/src/client/services/cyberia-instance/cyberia-instance.service.js +137 -0
  681. package/src/client/services/cyberia-instance-conf/cyberia-instance-conf.service.js +99 -0
  682. package/src/client/services/cyberia-map/cyberia-map.management.js +193 -0
  683. package/src/client/services/cyberia-map/cyberia-map.service.js +120 -0
  684. package/src/client/services/cyberia-quest/cyberia-quest.service.js +99 -0
  685. package/src/client/services/cyberia-quest-progress/cyberia-quest-progress.service.js +99 -0
  686. package/src/client/services/cyberia-saga/cyberia-saga.service.js +99 -0
  687. package/src/client/services/cyberia-skill/cyberia-skill.service.js +99 -0
  688. package/src/client/services/default/default.management.js +1015 -0
  689. package/src/client/services/default/default.service.js +99 -0
  690. package/src/client/services/document/document.service.js +134 -0
  691. package/src/client/services/file/file.service.js +94 -0
  692. package/src/client/services/instance/instance.management.js +78 -0
  693. package/src/client/services/instance/instance.service.js +107 -0
  694. package/src/client/services/ipfs/ipfs.service.js +118 -0
  695. package/src/client/services/object-layer/object-layer.management.js +414 -0
  696. package/src/client/services/object-layer/object-layer.service.js +208 -0
  697. package/src/client/services/object-layer-render-frames/object-layer-render-frames.service.js +99 -0
  698. package/src/client/services/test/test.service.js +68 -0
  699. package/src/client/services/user/guest.service.js +86 -0
  700. package/src/client/services/user/user.management.js +51 -0
  701. package/src/client/services/user/user.service.js +106 -0
  702. package/src/client/ssr/RootDocument.js +237 -0
  703. package/src/client/ssr/body/404.js +77 -0
  704. package/src/client/ssr/body/500.js +76 -0
  705. package/src/client/ssr/body/CacheControl.js +117 -0
  706. package/src/client/ssr/body/CyberiaDefaultSplashScreen.js +97 -0
  707. package/src/client/ssr/body/DefaultSplashScreen.js +97 -0
  708. package/src/client/ssr/body/SwaggerDarkMode.js +285 -0
  709. package/src/client/ssr/body/UnderpostDefaultSplashScreen.js +90 -0
  710. package/src/client/ssr/head/CryptokoynScripts.js +4 -0
  711. package/src/client/ssr/head/Css.js +241 -0
  712. package/src/client/ssr/head/CyberiaPortalScripts.js +6 -0
  713. package/src/client/ssr/head/DefaultScripts.js +6 -0
  714. package/src/client/ssr/head/ItemledgerScripts.js +4 -0
  715. package/src/client/ssr/head/Microdata.js +11 -0
  716. package/src/client/ssr/head/Production.js +1 -0
  717. package/src/client/ssr/head/Pwa.js +146 -0
  718. package/src/client/ssr/head/PwaItemledger.js +197 -0
  719. package/src/client/ssr/head/Seo.js +15 -0
  720. package/src/client/ssr/head/UnderpostScripts.js +6 -0
  721. package/src/client/ssr/mailer/DefaultRecoverEmail.js +20 -0
  722. package/src/client/ssr/mailer/DefaultVerifyEmail.js +16 -0
  723. package/src/client/ssr/views/Cyberia404.js +328 -0
  724. package/src/client/ssr/views/CyberiaServerMetrics.js +1070 -0
  725. package/src/client/ssr/views/Maintenance.js +64 -0
  726. package/src/client/ssr/views/NoNetworkConnection.js +68 -0
  727. package/src/client/ssr/views/Test.js +199 -0
  728. package/src/client/sw/core.sw.js +274 -0
  729. package/src/client-builder/client-build-docs.js +493 -0
  730. package/src/client-builder/client-build-live.js +100 -0
  731. package/src/client-builder/client-build.js +1092 -0
  732. package/src/client-builder/client-dev-server.js +88 -0
  733. package/src/client-builder/client-formatted.js +170 -0
  734. package/src/client-builder/client-icons.js +108 -0
  735. package/src/client-builder/ssr.js +124 -0
  736. package/src/client.build.js +17 -0
  737. package/src/client.dev.js +21 -0
  738. package/src/db/DataBaseProvider.js +213 -0
  739. package/src/db/mariadb/MariaDB.js +72 -0
  740. package/src/db/mongo/MongoBootstrap.js +657 -0
  741. package/src/db/mongo/MongooseDB.js +199 -0
  742. package/src/grpc/cyberia/grpc-server.js +162 -0
  743. package/src/index.js +357 -0
  744. package/src/mailer/EmailRender.js +116 -0
  745. package/src/mailer/MailerProvider.js +213 -0
  746. package/src/projects/cyberia/atlas-sprite-sheet-generator.js +413 -0
  747. package/src/projects/cyberia/besu-genesis-generator.js +1630 -0
  748. package/src/projects/cyberia/catalog-cyberia.js +90 -0
  749. package/src/projects/cyberia/gemini-client.js +175 -0
  750. package/src/projects/cyberia/generate-saga.js +2137 -0
  751. package/src/projects/cyberia/hot-reload-trigger.js +163 -0
  752. package/src/projects/cyberia/instance-data.js +719 -0
  753. package/src/projects/cyberia/ipfs-client.js +599 -0
  754. package/src/projects/cyberia/map-preview-generator.js +304 -0
  755. package/src/projects/cyberia/object-layer.js +978 -0
  756. package/src/projects/cyberia/semantic-layer-generator-floor.js +319 -0
  757. package/src/projects/cyberia/semantic-layer-generator-resource.js +259 -0
  758. package/src/projects/cyberia/semantic-layer-generator-skin.js +1164 -0
  759. package/src/projects/cyberia/semantic-layer-generator.js +753 -0
  760. package/src/projects/cyberia/shape-generator.js +1060 -0
  761. package/src/projects/underpost/catalog-underpost.js +60 -0
  762. package/src/proxy.js +19 -0
  763. package/src/runtime/cyberia-client/Dockerfile +49 -0
  764. package/src/runtime/cyberia-client/Dockerfile.dev +75 -0
  765. package/src/runtime/cyberia-server/Dockerfile +43 -0
  766. package/src/runtime/cyberia-server/Dockerfile.dev +56 -0
  767. package/src/runtime/engine-cyberia/Dockerfile +161 -0
  768. package/src/runtime/engine-cyberia/Dockerfile.dev +161 -0
  769. package/src/runtime/engine-cyberia/Dockerfile.test +165 -0
  770. package/src/runtime/engine-cyberia/compose.env +144 -0
  771. package/src/runtime/engine-cyberia/docker-compose.yml +434 -0
  772. package/src/runtime/engine-cyberia/ipfs/configure-ipfs.sh +13 -0
  773. package/src/runtime/engine-cyberia/mongodb/entrypoint.sh +76 -0
  774. package/src/runtime/engine-cyberia/nginx.conf +128 -0
  775. package/src/runtime/express/Dockerfile +45 -0
  776. package/src/runtime/express/Express.js +285 -0
  777. package/src/runtime/lampp/Dockerfile +62 -0
  778. package/src/runtime/lampp/Lampp.js +359 -0
  779. package/src/runtime/nginx/Nginx.js +250 -0
  780. package/src/runtime/wp/Dockerfile +62 -0
  781. package/src/runtime/wp/Wp.js +642 -0
  782. package/src/server/auth.js +713 -0
  783. package/src/server/backup.js +102 -0
  784. package/src/server/catalog.js +72 -0
  785. package/src/server/conf.js +2316 -0
  786. package/src/server/cron.js +476 -0
  787. package/src/server/crypto.js +210 -0
  788. package/src/server/data-query.js +461 -0
  789. package/src/server/dns.js +553 -0
  790. package/src/server/downloader.js +73 -0
  791. package/src/server/logger.js +229 -0
  792. package/src/server/middlewares.js +152 -0
  793. package/src/server/peer.js +75 -0
  794. package/src/server/process.js +299 -0
  795. package/src/server/proxy.js +139 -0
  796. package/src/server/runtime-status.js +252 -0
  797. package/src/server/runtime.js +183 -0
  798. package/src/server/start.js +272 -0
  799. package/src/server/tls.js +254 -0
  800. package/src/server/valkey.js +201 -0
  801. package/src/server.js +25 -0
  802. package/src/ws/IoInterface.js +129 -0
  803. package/src/ws/IoServer.js +68 -0
  804. package/src/ws/core/channels/core.ws.chat.js +68 -0
  805. package/src/ws/core/channels/core.ws.mailer.js +116 -0
  806. package/src/ws/core/channels/core.ws.stream.js +90 -0
  807. package/src/ws/core/core.ws.connection.js +41 -0
  808. package/src/ws/core/core.ws.emit.js +37 -0
  809. package/src/ws/core/core.ws.server.js +44 -0
  810. package/src/ws/default/channels/default.ws.main.js +57 -0
  811. package/src/ws/default/default.ws.connection.js +35 -0
  812. package/src/ws/default/default.ws.emit.js +14 -0
  813. package/src/ws/default/default.ws.server.js +39 -0
  814. package/test/api.test.js +53 -0
  815. package/test/crypto.test.js +117 -0
  816. package/test/cyberia-instance-conf-defaults.test.js +140 -0
  817. package/test/deploy-monitor.test.js +267 -0
  818. package/test/shape-generator.test.js +463 -0
  819. package/tsconfig.docs.json +15 -0
  820. package/typedoc.dd-cyberia.json +31 -0
  821. package/typedoc.json +31 -0
@@ -0,0 +1,894 @@
1
+ /**
2
+ * Object Layer service module for handling CRUD operations on object layer assets.
3
+ * Provides REST API handlers for creating, reading, updating, and deleting object layers
4
+ * including frame image management, metadata processing, and WebP animation generation.
5
+ *
6
+ * Delegates shared object layer creation and update logic to {@link ObjectLayerEngine} in
7
+ * `src/projects/cyberia/object-layer.js` to keep a single source of truth shared with the Cyberia CLI.
8
+ *
9
+ * @module src/api/object-layer/object-layer.service.js
10
+ * @namespace CyberiaObjectLayerService
11
+ */
12
+
13
+ import { DataBaseProviderService } from '../../db/DataBaseProvider.js';
14
+ import { loggerFactory } from '../../server/logger.js';
15
+ import { ObjectLayerRenderFramesDto } from '../object-layer-render-frames/object-layer-render-frames.model.js';
16
+ import { FileFactory } from '../file/file.service.js';
17
+ import fs from 'fs-extra';
18
+ import { ObjectLayerDto } from './object-layer.model.js';
19
+ import { ObjectLayerEngine } from '../../projects/cyberia/object-layer.js';
20
+ import { shellExec } from '../../server/process.js';
21
+ import { DataQuery } from '../../server/data-query.js';
22
+ import { AtlasSpriteSheetService } from '../atlas-sprite-sheet/atlas-sprite-sheet.service.js';
23
+ import { IpfsClient } from '../../projects/cyberia/ipfs-client.js';
24
+ import { createPinRecord, removePinRecordsAndUnpin } from '../ipfs/ipfs.service.js';
25
+
26
+ /**
27
+ * Logger instance for this module.
28
+ * @type {Function}
29
+ * @memberof CyberiaObjectLayerService
30
+ * @private
31
+ */
32
+ const logger = loggerFactory(import.meta);
33
+
34
+ /**
35
+ * Object Layer Service providing REST API handlers for object layer operations.
36
+ * @namespace CyberiaObjectLayerService.ObjectLayerService
37
+ * @memberof CyberiaObjectLayerService
38
+ */
39
+ class ObjectLayerService {
40
+ /**
41
+ * POST handler for creating object layers and uploading frame images.
42
+ *
43
+ * Supports three sub-routes:
44
+ * - `/frame-image/:itemType/:itemId/:directionCode` — Upload PNG frame images for a direction.
45
+ * - `/metadata/:itemType/:itemId` — Create an object layer from uploaded frames and metadata.
46
+ * - Default — Create an object layer directly from the request body.
47
+ *
48
+ * The `/metadata` and default routes delegate to {@link ObjectLayerEngine.createObjectLayerDocuments}
49
+ * for document creation, atlas generation, SHA-256 computation, and IPFS pinning.
50
+ *
51
+ * @async
52
+ * @function post
53
+ * @memberof CyberiaObjectLayerService.ObjectLayerService
54
+ * @param {Object} req - Express request object.
55
+ * @param {Object} res - Express response object.
56
+ * @param {Object} options - Server options containing host and path.
57
+ * @param {string} options.host - The deployment host.
58
+ * @param {string} options.path - The deployment path.
59
+ * @returns {Promise<Object>} The created object layer document or frame upload result.
60
+ * @throws {Error} If file validation fails or required parameters are missing.
61
+ */
62
+ static post = async (req, res, options) => {
63
+ /** @type {import('./object-layer.model.js').ObjectLayerModel} */
64
+
65
+ if (req.path.startsWith('/frame-image')) {
66
+ const itemType = req.params.itemType;
67
+ const itemId = req.params.itemId;
68
+ const directionCode = req.params.directionCode;
69
+
70
+ // Debug: Log request files structure
71
+ logger.info(`POST Request files for direction ${directionCode}:`, {
72
+ filesKeys: req.files ? Object.keys(req.files) : [],
73
+ filesCount: req.files ? Object.keys(req.files).length : 0,
74
+ });
75
+
76
+ // Extract all frames for this direction
77
+ const files = FileFactory.filesExtract(req);
78
+
79
+ // Allow empty files to remove all frames from direction
80
+ if (!files || files.length === 0) {
81
+ logger.info(`No files received for direction ${directionCode} - will remove all frames from this direction`);
82
+ } else {
83
+ // Validate each file has data
84
+ for (let i = 0; i < files.length; i++) {
85
+ if (!files[i].data) {
86
+ logger.error(`File ${files[i].name || i} has no data for direction ${directionCode}`);
87
+ throw new Error(`File ${files[i].name || i} has no data`);
88
+ }
89
+ if (!Buffer.isBuffer(files[i].data)) {
90
+ logger.error(`File ${files[i].name || i} data is not a Buffer for direction ${directionCode}`);
91
+ throw new Error(`File ${files[i].name || i} data is not a Buffer`);
92
+ }
93
+ }
94
+ }
95
+
96
+ logger.info(
97
+ `Processing ${files?.length || 0} file(s) for direction ${directionCode}: ${files?.map((f) => f.name).join(', ') || 'none'}`,
98
+ );
99
+
100
+ // Always clear and rewrite ALL frames for this direction code
101
+ for (const basePath of ['./src/client/public/cyberia/', `./public/${options.host}${options.path}`]) {
102
+ const folder = `${basePath}assets/${itemType}/${itemId}/${directionCode}`;
103
+
104
+ // Always remove entire direction folder to ensure clean state
105
+ if (fs.existsSync(folder)) {
106
+ await fs.remove(folder);
107
+ logger.info(`Cleared folder: ${folder}`);
108
+ }
109
+
110
+ // Only create and write files if we have frames to upload
111
+ if (files && files.length > 0) {
112
+ // Create fresh folder
113
+ fs.mkdirSync(folder, { recursive: true });
114
+
115
+ // Write all frames sent in this request
116
+ for (const file of files) {
117
+ const filePath = `${folder}/${file.name}`;
118
+ try {
119
+ fs.writeFileSync(filePath, file.data);
120
+ logger.info(`Wrote file: ${filePath} (${file.data.length} bytes)`);
121
+ } catch (error) {
122
+ logger.error(`Error writing file ${filePath}:`, error);
123
+ throw new Error(`Failed to write ${file.name}: ${error.message}`);
124
+ }
125
+ }
126
+ } else {
127
+ logger.info(`No frames to write for direction ${directionCode} - folder removed`);
128
+ }
129
+ }
130
+
131
+ logger.info(`Successfully processed ${files?.length || 0} frame(s) for direction ${directionCode}`);
132
+
133
+ return { success: true, directionCode, frameCount: files?.length || 0 };
134
+ }
135
+
136
+ if (req.path.startsWith('/metadata')) {
137
+ const itemType = req.params.itemType;
138
+ const itemId = req.params.itemId;
139
+ const folder = `./src/client/public/cyberia/assets/${itemType}/${itemId}`;
140
+ const publicFolder = `./public/${options.host}${options.path}/assets/${itemType}/${itemId}`;
141
+
142
+ // Ensure both folders exist
143
+ if (!fs.existsSync(folder)) fs.mkdirSync(folder, { recursive: true });
144
+ if (!fs.existsSync(publicFolder)) fs.mkdirSync(publicFolder, { recursive: true });
145
+
146
+ // Write metadata.json to both locations
147
+ const metadataContent = JSON.stringify(req.body);
148
+ fs.writeFileSync(`${folder}/metadata.json`, metadataContent);
149
+ fs.writeFileSync(`${publicFolder}/metadata.json`, metadataContent);
150
+
151
+ // Build object layer data from the asset directory
152
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
153
+ const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
154
+
155
+ const { objectLayerRenderFramesData, objectLayerData } =
156
+ await ObjectLayerEngine.buildObjectLayerDataFromDirectory({
157
+ folder,
158
+ objectLayerType: itemType,
159
+ objectLayerId: itemId,
160
+ metadataOverride: req.body,
161
+ });
162
+
163
+ const { objectLayer } = await ObjectLayerEngine.createObjectLayerDocuments({
164
+ ObjectLayer,
165
+ ObjectLayerRenderFrames,
166
+ objectLayerRenderFramesData,
167
+ objectLayerData,
168
+ createOptions: {
169
+ generateAtlas: true,
170
+ atlasServiceContext: {
171
+ req,
172
+ res,
173
+ options,
174
+ AtlasSpriteSheetService,
175
+ IpfsClient,
176
+ createPinRecord,
177
+ },
178
+ },
179
+ });
180
+
181
+ return objectLayer;
182
+ }
183
+
184
+ // create object layer from body – cut-over consistency: stage all CIDs before writing to DB
185
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
186
+ const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
187
+
188
+ const bodyData = { ...req.body };
189
+ if (!bodyData.data) bodyData.data = {};
190
+ if (!bodyData.data.render) bodyData.data.render = {};
191
+ bodyData.data.render.cid = '';
192
+ bodyData.data.render.metadataCid = '';
193
+
194
+ // If has render frames, generate atlas + CIDs BEFORE creating the ObjectLayer
195
+ if (bodyData.objectLayerRenderFramesId) {
196
+ const renderFramesDoc = await ObjectLayerRenderFrames.findById(bodyData.objectLayerRenderFramesId);
197
+ if (renderFramesDoc) {
198
+ try {
199
+ const stagingOL = {
200
+ data: bodyData.data,
201
+ objectLayerRenderFramesId: renderFramesDoc,
202
+ };
203
+ const result = await AtlasSpriteSheetService.generate(
204
+ { objectLayer: stagingOL, auth: req.auth },
205
+ res,
206
+ options,
207
+ { skipObjectLayerSave: true },
208
+ );
209
+ bodyData.data.render.cid = result.atlasCid;
210
+ bodyData.data.render.metadataCid = result.atlasMetadataCid;
211
+ bodyData.atlasSpriteSheetId = result.atlasDoc._id;
212
+ } catch (atlasError) {
213
+ logger.error('Failed to auto-generate atlas for new ObjectLayer:', atlasError);
214
+ }
215
+ }
216
+ }
217
+
218
+ // Compute final SHA-256 with all CIDs
219
+ bodyData.sha256 = ObjectLayerEngine.computeSha256(bodyData.data);
220
+
221
+ // Pin data JSON to IPFS
222
+ try {
223
+ const itemId = bodyData.data.item.id;
224
+ const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
225
+ const ipfsResult = await IpfsClient.addJsonToIpfs(bodyData.data, `${itemId}_data.json`, mfsPath);
226
+ if (ipfsResult) {
227
+ bodyData.cid = ipfsResult.cid;
228
+ await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
229
+ }
230
+ } catch (ipfsError) {
231
+ logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
232
+ }
233
+
234
+ // Atomic create/replace – ObjectLayer is fully populated with all CIDs
235
+ let newObjectLayer;
236
+ const existingByItemId = await ObjectLayer.findOne({ 'data.item.id': bodyData.data.item.id });
237
+ if (existingByItemId) {
238
+ newObjectLayer = await ObjectLayer.findByIdAndUpdate(existingByItemId._id, bodyData, {
239
+ returnDocument: 'after',
240
+ }).populate('objectLayerRenderFramesId');
241
+ } else {
242
+ newObjectLayer = await (await new ObjectLayer(bodyData).save()).populate('objectLayerRenderFramesId');
243
+ }
244
+
245
+ return newObjectLayer;
246
+ };
247
+
248
+ /**
249
+ * GET handler for retrieving object layers.
250
+ *
251
+ * Supports multiple sub-routes:
252
+ * - `/frame-counts/:id` — Get frame counts for each direction using numeric codes.
253
+ * - `/render/:id` — Get only render data (populated ObjectLayerRenderFrames) for a specific object layer.
254
+ * - `/metadata/:id` — Get metadata (no full render frames/colors) with atlas sprite sheet validation.
255
+ * - `/:id` — Get a single object layer by ID.
256
+ * - `/` — Get a paginated list of object layers.
257
+ *
258
+ * @async
259
+ * @function get
260
+ * @memberof CyberiaObjectLayerService.ObjectLayerService
261
+ * @param {Object} req - Express request object.
262
+ * @param {Object} res - Express response object.
263
+ * @param {Object} options - Server options containing host and path.
264
+ * @param {string} options.host - The deployment host.
265
+ * @param {string} options.path - The deployment path.
266
+ * @returns {Promise<Object>} The requested object layer data, list, or frame counts.
267
+ * @throws {Error} If the requested object layer is not found.
268
+ */
269
+ static get = async (req, res, options) => {
270
+ /** @type {import('./object-layer.model.js').ObjectLayerModel} */
271
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
272
+
273
+ // GET /search-item-ids?q=<partial> - Fast partial match search on data.item.id
274
+ if (req.path.startsWith('/search-item-ids')) {
275
+ const q = (req.query.q || '').trim();
276
+ if (!q) return { itemIds: [] };
277
+ // Escape regex special characters for safe partial matching
278
+ const escaped = q.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
279
+ const results = await ObjectLayer.find(
280
+ { 'data.item.id': { $regex: escaped, $options: 'i' } },
281
+ { 'data.item.id': 1, _id: 0 },
282
+ )
283
+ .limit(20)
284
+ .lean();
285
+ const itemIds = [...new Set(results.map((r) => r.data.item.id))];
286
+ return { itemIds };
287
+ }
288
+
289
+ // GET /frame-counts/:id - Get frame counts for each direction using numeric codes
290
+ if (req.path.startsWith('/frame-counts/')) {
291
+ const objectLayer = await ObjectLayer.findById(req.params.id)
292
+ .select(ObjectLayerDto.select.getMetadata())
293
+ .populate('objectLayerRenderFramesId');
294
+ if (!objectLayer) {
295
+ throw new Error('ObjectLayer not found');
296
+ }
297
+
298
+ const itemType = objectLayer.data.item.type;
299
+ const itemId = objectLayer.data.item.id;
300
+ const frameCounts = {};
301
+
302
+ // Define numeric direction codes (as used in file system)
303
+ const numericDirectionCodes = ['08', '18', '02', '12', '04', '14', '06', '16'];
304
+
305
+ // Check each numeric direction code folder and count PNG files
306
+ for (const numericCode of numericDirectionCodes) {
307
+ const folder = `./src/client/public/cyberia/assets/${itemType}/${itemId}/${numericCode}`;
308
+
309
+ if (fs.existsSync(folder)) {
310
+ try {
311
+ const files = await fs.readdir(folder);
312
+ const pngFiles = files.filter((file) => file.endsWith('.png'));
313
+ frameCounts[numericCode] = pngFiles.length;
314
+ } catch (error) {
315
+ logger.warn(`Error reading folder ${folder}:`, error);
316
+ frameCounts[numericCode] = 0;
317
+ }
318
+ } else {
319
+ frameCounts[numericCode] = 0;
320
+ }
321
+ }
322
+
323
+ return {
324
+ _id: objectLayer._id,
325
+ itemType,
326
+ itemId,
327
+ frameDuration: objectLayer.objectLayerRenderFramesId?.frame_duration || 250,
328
+ frameCounts,
329
+ };
330
+ }
331
+
332
+ // GET /render/:id - Get only render data for specific object layer
333
+ if (req.path.startsWith('/render/')) {
334
+ const objectLayer = await ObjectLayer.findById(req.params.id)
335
+ .select(ObjectLayerDto.select.getRender())
336
+ .populate('objectLayerRenderFramesId');
337
+ if (!objectLayer) {
338
+ throw new Error('ObjectLayer not found');
339
+ }
340
+ // Return the populated render frames data with consistent naming
341
+ return {
342
+ _id: objectLayer._id,
343
+ objectLayerRenderFramesId: objectLayer.objectLayerRenderFramesId,
344
+ };
345
+ }
346
+
347
+ // GET /metadata/:id - Get only metadata (no render frames/colors) for specific object layer
348
+ if (req.path.startsWith('/metadata/')) {
349
+ const objectLayer = await ObjectLayer.findById(req.params.id)
350
+ .select(ObjectLayerDto.select.getMetadata())
351
+ .populate('objectLayerRenderFramesId', ObjectLayerRenderFramesDto.select.get());
352
+ if (!objectLayer) {
353
+ throw new Error('ObjectLayer not found');
354
+ }
355
+
356
+ // If object layer references an atlas sprite sheet, validate that the atlas and its file actually exist.
357
+ // If the atlas or its file is missing, clear the reference so the UI can offer to generate a new atlas.
358
+ if (objectLayer.atlasSpriteSheetId) {
359
+ try {
360
+ const AtlasSpriteSheet = DataBaseProviderService.getModel('AtlasSpriteSheet', options);
361
+ const File = DataBaseProviderService.getModel('File', options);
362
+
363
+ const atlasDoc = await AtlasSpriteSheet.findById(objectLayer.atlasSpriteSheetId);
364
+
365
+ // If the atlas doc is gone, clear the reference
366
+ if (!atlasDoc) {
367
+ logger.warn(
368
+ `ObjectLayer ${objectLayer._id} referenced missing AtlasSpriteSheet ${objectLayer.atlasSpriteSheetId} - clearing reference`,
369
+ );
370
+ objectLayer.atlasSpriteSheetId = undefined;
371
+ await objectLayer.save();
372
+ } else if (!atlasDoc.fileId) {
373
+ // Atlas exists but has no fileId - remove atlas and clear reference
374
+ logger.warn(
375
+ `AtlasSpriteSheet ${atlasDoc._id} has no fileId - deleting atlas and clearing ObjectLayer reference`,
376
+ );
377
+ await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
378
+ objectLayer.atlasSpriteSheetId = undefined;
379
+ await objectLayer.save();
380
+ } else {
381
+ // Atlas has a fileId - verify the File exists
382
+ const fileDoc = await File.findById(atlasDoc.fileId);
383
+ if (!fileDoc) {
384
+ logger.warn(
385
+ `AtlasSpriteSheet ${atlasDoc._id} references missing File ${atlasDoc.fileId} - deleting atlas and clearing reference on ObjectLayer ${objectLayer._id}`,
386
+ );
387
+ await AtlasSpriteSheet.findByIdAndDelete(atlasDoc._id);
388
+ objectLayer.atlasSpriteSheetId = undefined;
389
+ await objectLayer.save();
390
+ }
391
+ }
392
+ } catch (err) {
393
+ logger.warn('Error validating atlas sprite sheet reference:', err);
394
+ }
395
+ }
396
+
397
+ return objectLayer;
398
+ }
399
+
400
+ // GET / - Get paginated list of object layers
401
+ const id = req.params.id || req.query.id;
402
+ logger.info(`ObjectLayerService.get - filtering check - id: ${id}`);
403
+ if (id && id !== 'undefined' && !['render', 'metadata', 'frame-counts'].includes(id)) {
404
+ try {
405
+ const objectLayer = await ObjectLayer.findById(id)
406
+ .select(ObjectLayerDto.select.get())
407
+ .populate('atlasSpriteSheetId', 'cid')
408
+ .populate('objectLayerRenderFramesId', ObjectLayerRenderFramesDto.select.get());
409
+ if (objectLayer) {
410
+ logger.info(`ObjectLayerService.get - found record by id: ${id}`);
411
+ return { data: [objectLayer], total: 1, page: 1, totalPages: 1 };
412
+ }
413
+ logger.warn(`ObjectLayerService.get - record NOT found for id: ${id}`);
414
+ } catch (e) {
415
+ logger.warn(`Invalid ID format or not found: ${id}`);
416
+ }
417
+ }
418
+
419
+ const { query, sort, skip, limit, page } = DataQuery.parse(req.query);
420
+
421
+ const [data, total] = await Promise.all([
422
+ ObjectLayer.find(query) // { userId: req.auth.user._id }
423
+ .sort(sort)
424
+ .limit(limit)
425
+ .skip(skip)
426
+ .select(ObjectLayerDto.select.get())
427
+ .populate('atlasSpriteSheetId', 'cid')
428
+ .populate('objectLayerRenderFramesId', ObjectLayerRenderFramesDto.select.get()),
429
+ ObjectLayer.countDocuments(query), // { userId: req.auth.user._id }
430
+ ]);
431
+ return { data, total, page, totalPages: Math.ceil(total / limit) };
432
+ };
433
+
434
+ /**
435
+ * Generates a WebP animation from PNG frame images for a specific direction of an object layer.
436
+ * Uses the `img2webp` CLI tool to assemble the animation.
437
+ *
438
+ * @async
439
+ * @function generateWebp
440
+ * @memberof CyberiaObjectLayerService.ObjectLayerService
441
+ * @param {Object} req - Express request object with params: itemType, itemId, directionCode.
442
+ * @param {Object} res - Express response object.
443
+ * @param {Object} options - Server options containing host and path.
444
+ * @param {string} options.host - The deployment host.
445
+ * @param {string} options.path - The deployment path.
446
+ * @returns {Promise<Buffer>} The generated WebP animation as a Buffer.
447
+ * @throws {Error} If required parameters are missing, frames directory is not found, or img2webp fails.
448
+ */
449
+ static generateWebp = async (req, res, options) => {
450
+ /** @type {import('./object-layer.model.js').ObjectLayerModel} */
451
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
452
+
453
+ // GET /generate-webp/:itemType/:itemId/:directionCode - Generate webp animation from PNG frames
454
+ const itemType = req.params.itemType;
455
+ const itemId = req.params.itemId;
456
+ const directionCode = req.params.directionCode;
457
+
458
+ if (!itemType || !itemId || !directionCode) {
459
+ throw new Error('Missing required parameters: itemType, itemId, directionCode');
460
+ }
461
+
462
+ // Path to the PNG frames directory
463
+ const framesFolder = `./src/client/public/cyberia/assets/${itemType}/${itemId}/${directionCode}`;
464
+
465
+ // Check if the folder exists
466
+ if (!fs.existsSync(framesFolder)) {
467
+ throw new Error(`Frames directory not found: ${framesFolder}`);
468
+ }
469
+
470
+ // Check if there are PNG files in the directory
471
+ const files = await fs.readdir(framesFolder);
472
+ const pngFiles = files.filter((file) => file.endsWith('.png')).sort();
473
+
474
+ if (pngFiles.length === 0) {
475
+ throw new Error(`No PNG frames found in directory: ${framesFolder}`);
476
+ }
477
+
478
+ logger.info(`Found ${pngFiles.length} PNG frames in ${framesFolder}`);
479
+
480
+ // Get frame duration from the object layer metadata
481
+ let frameDuration = 100; // Default to 100ms
482
+
483
+ try {
484
+ // Find object layer by itemType and itemId
485
+ const objectLayer = await ObjectLayer.findOne({
486
+ 'data.item.type': itemType,
487
+ 'data.item.id': itemId,
488
+ })
489
+ .select(ObjectLayerDto.select.getMetadata())
490
+ .populate('objectLayerRenderFramesId');
491
+
492
+ if (objectLayer && objectLayer.objectLayerRenderFramesId?.frame_duration) {
493
+ frameDuration = objectLayer.objectLayerRenderFramesId.frame_duration;
494
+ logger.info(`Using frame duration from object layer: ${frameDuration}ms`);
495
+ } else {
496
+ logger.warn(`Object layer not found or no frame_duration set, using default: ${frameDuration}ms`);
497
+ }
498
+ } catch (error) {
499
+ logger.warn(
500
+ `Error fetching object layer metadata: ${error.message}. Using default frame duration: ${frameDuration}ms`,
501
+ );
502
+ }
503
+
504
+ const tmpOutputFileName = `output_${Date.now()}_${Math.floor(Math.random() * 1000)}.webp`;
505
+
506
+ // Create temporary output file path
507
+ const tempOutputPath = `${framesFolder}/${tmpOutputFileName}`;
508
+
509
+ try {
510
+ // Change to the frames directory and execute img2webp command
511
+ const cmd = `cd "${framesFolder}" && img2webp -d ${frameDuration} -loop 0 *.png -o ${tmpOutputFileName}`;
512
+
513
+ logger.info(`Executing command: ${cmd}`);
514
+
515
+ // silentOnError so we can build a domain-specific Error with the
516
+ // captured stderr/stdout context (callers want a friendly message,
517
+ // not a generic ShellExecError).
518
+ const result = shellExec(cmd, { silent: false, silentOnError: true });
519
+
520
+ if (result.code !== 0) {
521
+ throw new Error(`img2webp command failed: ${result.stderr || result.stdout}`);
522
+ }
523
+
524
+ logger.info(`Successfully generated webp: ${tempOutputPath}`);
525
+
526
+ // Check if the output file was created
527
+ if (!fs.existsSync(tempOutputPath)) {
528
+ throw new Error(`Output file was not created: ${tempOutputPath}`);
529
+ }
530
+
531
+ // Read the webp file as a buffer
532
+ const webpBuffer = await fs.readFile(tempOutputPath);
533
+
534
+ logger.info(`WebP file size: ${webpBuffer.length} bytes`);
535
+
536
+ // Delete the temporary file after sending the response
537
+ // Use setImmediate to ensure the response is fully sent before cleanup
538
+ setImmediate(async () => {
539
+ try {
540
+ if (fs.existsSync(tempOutputPath)) {
541
+ await fs.remove(tempOutputPath);
542
+ logger.info(`Cleaned up temporary file: ${tempOutputPath}`);
543
+ }
544
+ } catch (cleanupError) {
545
+ logger.error(`Error cleaning up temporary file: ${cleanupError.message}`);
546
+ }
547
+ });
548
+
549
+ return webpBuffer;
550
+ } catch (error) {
551
+ // Clean up on error
552
+ try {
553
+ if (fs.existsSync(tempOutputPath)) {
554
+ await fs.remove(tempOutputPath);
555
+ logger.info(`Cleaned up temporary file after error: ${tempOutputPath}`);
556
+ }
557
+ } catch (cleanupError) {
558
+ logger.error(`Error cleaning up temporary file after error: ${cleanupError.message}`);
559
+ }
560
+
561
+ throw error;
562
+ }
563
+ };
564
+
565
+ /**
566
+ * PUT handler for updating object layers, their frame images, and metadata.
567
+ *
568
+ * Supports three sub-routes:
569
+ * - `/:id/frame-image/:itemType/:itemId/:directionCode` — Replace frame images for a direction.
570
+ * - `/:id/metadata/:itemType/:itemId` — Update metadata and reprocess all frames.
571
+ * - `/:id` — Standard update from request body.
572
+ *
573
+ * The `/metadata` route delegates to {@link ObjectLayerEngine.updateObjectLayerDocuments}
574
+ * for document update, atlas regeneration, SHA-256 computation, and IPFS pinning.
575
+ *
576
+ * @async
577
+ * @function put
578
+ * @memberof CyberiaObjectLayerService.ObjectLayerService
579
+ * @param {Object} req - Express request object.
580
+ * @param {Object} res - Express response object.
581
+ * @param {Object} options - Server options containing host and path.
582
+ * @param {string} options.host - The deployment host.
583
+ * @param {string} options.path - The deployment path.
584
+ * @returns {Promise<Object>} The updated object layer document or frame upload result.
585
+ * @throws {Error} If file validation fails, object layer is not found, or required parameters are missing.
586
+ */
587
+ static put = async (req, res, options) => {
588
+ /** @type {import('./object-layer.model.js').ObjectLayerModel} */
589
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
590
+
591
+ // PUT /:id/frame-image/:itemType/:itemId/:directionCode - Update frame images for specific direction
592
+ if (req.path.includes('/frame-image/')) {
593
+ const objectLayerId = req.params.id;
594
+ const itemType = req.params.itemType;
595
+ const itemId = req.params.itemId;
596
+ const directionCode = req.params.directionCode;
597
+
598
+ // Debug: Log request files structure
599
+ logger.info(`Request files for direction ${directionCode}:`, {
600
+ filesKeys: req.files ? Object.keys(req.files) : [],
601
+ filesCount: req.files ? Object.keys(req.files).length : 0,
602
+ });
603
+
604
+ // Extract all frames for this direction
605
+ const files = FileFactory.filesExtract(req);
606
+
607
+ // Allow empty files to remove all frames from direction
608
+ if (!files || files.length === 0) {
609
+ logger.info(`No files received for direction ${directionCode} - will remove all frames from this direction`);
610
+ } else {
611
+ // Validate each file has data
612
+ for (let i = 0; i < files.length; i++) {
613
+ if (!files[i].data) {
614
+ logger.error(`File ${files[i].name || i} has no data for direction ${directionCode}`);
615
+ throw new Error(`File ${files[i].name || i} has no data`);
616
+ }
617
+ if (!Buffer.isBuffer(files[i].data)) {
618
+ logger.error(`File ${files[i].name || i} data is not a Buffer for direction ${directionCode}`);
619
+ throw new Error(`File ${files[i].name || i} data is not a Buffer`);
620
+ }
621
+ }
622
+ }
623
+
624
+ logger.info(
625
+ `Processing ${files?.length || 0} file(s) for direction ${directionCode}: ${files?.map((f) => f.name).join(', ') || 'none'}`,
626
+ );
627
+
628
+ // Always clear and rewrite ALL frames for this direction code
629
+ for (const basePath of ['./src/client/public/cyberia/', `./public/${options.host}${options.path}`]) {
630
+ const folder = `${basePath}assets/${itemType}/${itemId}/${directionCode}`;
631
+
632
+ // Always remove entire direction folder to ensure clean state
633
+ if (fs.existsSync(folder)) {
634
+ await fs.remove(folder);
635
+ logger.info(`Cleared folder: ${folder}`);
636
+ }
637
+
638
+ // Only create and write files if we have frames to upload
639
+ if (files && files.length > 0) {
640
+ // Create fresh folder
641
+ fs.mkdirSync(folder, { recursive: true });
642
+
643
+ // Write all frames sent in this request
644
+ for (const file of files) {
645
+ const filePath = `${folder}/${file.name}`;
646
+ try {
647
+ fs.writeFileSync(filePath, file.data);
648
+ logger.info(`Wrote file: ${filePath}`);
649
+ } catch (error) {
650
+ logger.error(`Error writing file ${filePath}:`, error);
651
+ throw new Error(`Failed to write ${file.name}: ${error.message}`);
652
+ }
653
+ }
654
+ } else {
655
+ logger.info(`No frames to write for direction ${directionCode} - folder removed`);
656
+ }
657
+ }
658
+
659
+ logger.info(
660
+ `Successfully processed ${files?.length || 0} frame(s) for direction ${directionCode} in object layer ${objectLayerId}`,
661
+ );
662
+
663
+ return { success: true, directionCode, frameCount: files?.length || 0 };
664
+ }
665
+
666
+ // PUT /:id/metadata/:itemType/:itemId - Update object layer metadata and reprocess all frames
667
+ if (req.path.includes('/metadata/')) {
668
+ const objectLayerId = req.params.id;
669
+ const itemType = req.params.itemType;
670
+ const itemId = req.params.itemId;
671
+
672
+ const folder = `./src/client/public/cyberia/assets/${itemType}/${itemId}`;
673
+ const publicFolder = `./public/${options.host}${options.path}/assets/${itemType}/${itemId}`;
674
+
675
+ // Ensure both folders exist
676
+ if (!fs.existsSync(folder)) {
677
+ fs.mkdirSync(folder, { recursive: true });
678
+ }
679
+ if (!fs.existsSync(publicFolder)) {
680
+ fs.mkdirSync(publicFolder, { recursive: true });
681
+ }
682
+
683
+ // Write metadata.json to both locations
684
+ const metadataContent = JSON.stringify(req.body);
685
+ fs.writeFileSync(`${folder}/metadata.json`, metadataContent);
686
+ fs.writeFileSync(`${publicFolder}/metadata.json`, metadataContent);
687
+
688
+ const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
689
+
690
+ // Build object layer data from the asset directory
691
+ const { objectLayerRenderFramesData, objectLayerData } =
692
+ await ObjectLayerEngine.buildObjectLayerDataFromDirectory({
693
+ folder,
694
+ objectLayerType: itemType,
695
+ objectLayerId: itemId,
696
+ metadataOverride: req.body,
697
+ });
698
+
699
+ // Update documents using engine method (with atlas generation)
700
+ const { objectLayer } = await ObjectLayerEngine.updateObjectLayerDocuments({
701
+ objectLayerId,
702
+ ObjectLayer,
703
+ ObjectLayerRenderFrames,
704
+ objectLayerRenderFramesData,
705
+ objectLayerData,
706
+ updateOptions: {
707
+ generateAtlas: true,
708
+ atlasServiceContext: {
709
+ req,
710
+ res,
711
+ options,
712
+ AtlasSpriteSheetService,
713
+ IpfsClient,
714
+ createPinRecord,
715
+ },
716
+ },
717
+ });
718
+
719
+ return objectLayer;
720
+ }
721
+
722
+ // PUT /:id - Standard update with cut-over consistency
723
+ const existingOL = await ObjectLayer.findById(req.params.id).populate('objectLayerRenderFramesId');
724
+ if (!existingOL) {
725
+ throw new Error('ObjectLayer not found');
726
+ }
727
+
728
+ // Apply body updates to staging data in memory
729
+ const updateData = { ...req.body };
730
+ const stagingData = updateData.data || existingOL.data.toObject();
731
+ if (!stagingData.render) stagingData.render = {};
732
+
733
+ // Use existing render frames if available
734
+ const renderFramesData = existingOL.objectLayerRenderFramesId;
735
+ if (renderFramesData) {
736
+ try {
737
+ const stagingOL = {
738
+ data: stagingData,
739
+ objectLayerRenderFramesId: renderFramesData,
740
+ };
741
+ const result = await AtlasSpriteSheetService.generate(
742
+ { objectLayer: stagingOL, auth: req.auth },
743
+ res,
744
+ options,
745
+ { skipObjectLayerSave: true },
746
+ );
747
+ stagingData.render.cid = result.atlasCid;
748
+ stagingData.render.metadataCid = result.atlasMetadataCid;
749
+ updateData.atlasSpriteSheetId = result.atlasDoc._id;
750
+ } catch (atlasError) {
751
+ logger.error('Failed to auto-update atlas for ObjectLayer:', atlasError);
752
+ }
753
+ }
754
+
755
+ updateData.data = stagingData;
756
+ updateData.sha256 = ObjectLayerEngine.computeSha256(stagingData);
757
+
758
+ // Pin data JSON to IPFS
759
+ try {
760
+ const itemId = stagingData.item.id;
761
+ const mfsPath = `/object-layer/${itemId}/${itemId}_data.json`;
762
+ const ipfsResult = await IpfsClient.addJsonToIpfs(stagingData, `${itemId}_data.json`, mfsPath);
763
+ if (ipfsResult) {
764
+ updateData.cid = ipfsResult.cid;
765
+ await createPinRecord({ cid: ipfsResult.cid, resourceType: 'object-layer-data', mfsPath, options });
766
+ }
767
+ } catch (ipfsError) {
768
+ logger.warn('Failed to pin data JSON to IPFS:', ipfsError.message);
769
+ }
770
+
771
+ // Atomic update with all CIDs populated
772
+ let updatedObjectLayer = await ObjectLayer.findByIdAndUpdate(req.params.id, updateData, {
773
+ returnDocument: 'after',
774
+ }).populate('objectLayerRenderFramesId');
775
+
776
+ return updatedObjectLayer;
777
+ };
778
+
779
+ /**
780
+ * DELETE handler for removing object layers and all associated resources.
781
+ *
782
+ * When a specific ID is provided, performs a cascading delete that removes:
783
+ * 1. The AtlasSpriteSheet and its File document.
784
+ * 2. The ObjectLayerRenderFrames document.
785
+ * 3. IPFS pin records and CIDs (both data JSON and atlas PNG).
786
+ * 4. The MFS directory for this object layer.
787
+ * 5. Static asset files from disk.
788
+ * 6. The ObjectLayer document itself.
789
+ *
790
+ * When no ID is provided, performs a bulk delete of all object layers.
791
+ *
792
+ * @async
793
+ * @function delete
794
+ * @memberof CyberiaObjectLayerService.ObjectLayerService
795
+ * @param {Object} req - Express request object.
796
+ * @param {Object} res - Express response object.
797
+ * @param {Object} options - Server options containing host and path.
798
+ * @param {string} options.host - The deployment host.
799
+ * @param {string} options.path - The deployment path.
800
+ * @returns {Promise<Object>} The deleted object layer document or bulk delete count.
801
+ * @throws {Error} If the object layer is not found.
802
+ */
803
+ static delete = async (req, res, options) => {
804
+ /** @type {import('./object-layer.model.js').ObjectLayerModel} */
805
+ const ObjectLayer = DataBaseProviderService.getModel('ObjectLayer', options);
806
+ const ObjectLayerRenderFrames = DataBaseProviderService.getModel('ObjectLayerRenderFrames', options);
807
+
808
+ if (req.params.id) {
809
+ // Load the full object layer so we can access all references
810
+ const objectLayer = await ObjectLayer.findById(req.params.id);
811
+ if (!objectLayer) {
812
+ throw new Error('ObjectLayer not found');
813
+ }
814
+
815
+ const itemType = objectLayer.data?.item?.type;
816
+ const itemId = objectLayer.data?.item?.id;
817
+
818
+ // ── 1. Clean up AtlasSpriteSheet, its File, and atlas IPFS CID ──
819
+ try {
820
+ await AtlasSpriteSheetService.deleteByObjectLayerId(req, res, options);
821
+ } catch (atlasError) {
822
+ logger.error('Failed to clean up atlas during ObjectLayer deletion:', atlasError);
823
+ }
824
+
825
+ // ── 2. Clean up ObjectLayerRenderFrames document ──
826
+ if (objectLayer.objectLayerRenderFramesId) {
827
+ try {
828
+ await ObjectLayerRenderFrames.findByIdAndDelete(objectLayer.objectLayerRenderFramesId);
829
+ logger.info(
830
+ `Deleted ObjectLayerRenderFrames ${objectLayer.objectLayerRenderFramesId} for ObjectLayer ${req.params.id}`,
831
+ );
832
+ } catch (renderFramesError) {
833
+ logger.error('Failed to delete ObjectLayerRenderFrames:', renderFramesError);
834
+ }
835
+ }
836
+
837
+ // ── 3. Remove pin records and unpin object layer data JSON CID from IPFS ──
838
+ if (objectLayer.cid) {
839
+ try {
840
+ await removePinRecordsAndUnpin(objectLayer.cid, options);
841
+ logger.info(`Cleaned up IPFS data CID ${objectLayer.cid} for ObjectLayer ${req.params.id}`);
842
+ } catch (ipfsError) {
843
+ logger.warn(`Failed to clean up IPFS data CID ${objectLayer.cid}: ${ipfsError.message}`);
844
+ }
845
+ }
846
+
847
+ // ── 4. Remove MFS directory for this object layer (covers both data JSON and atlas PNG) ──
848
+ if (itemId) {
849
+ try {
850
+ await IpfsClient.removeMfsPath(`/object-layer/${itemId}`);
851
+ logger.info(`Removed MFS directory /object-layer/${itemId}`);
852
+ } catch (mfsError) {
853
+ logger.warn(`Failed to remove MFS path /object-layer/${itemId}: ${mfsError.message}`);
854
+ }
855
+ }
856
+
857
+ // ── 5. Remove static asset files from disk ──
858
+ if (itemType && itemId) {
859
+ const staticPaths = [
860
+ `./src/client/public/cyberia/assets/${itemType}/${itemId}`,
861
+ `./public/${options.host}${options.path}/assets/${itemType}/${itemId}`,
862
+ ];
863
+ for (const assetDir of staticPaths) {
864
+ try {
865
+ if (fs.existsSync(assetDir)) {
866
+ await fs.remove(assetDir);
867
+ logger.info(`Removed static asset directory: ${assetDir}`);
868
+ }
869
+ } catch (fsError) {
870
+ logger.warn(`Failed to remove static asset directory ${assetDir}: ${fsError.message}`);
871
+ }
872
+ }
873
+ }
874
+
875
+ // ── 6. Delete the ObjectLayer document itself ──
876
+ const deleted = await ObjectLayer.findByIdAndDelete(req.params.id);
877
+ logger.info(`ObjectLayer ${req.params.id} and all associated resources deleted successfully`);
878
+ return deleted;
879
+ } else {
880
+ // Bulk delete: clean up all object layers
881
+ const allObjectLayers = await ObjectLayer.find({});
882
+ for (const ol of allObjectLayers) {
883
+ try {
884
+ await ObjectLayerService.delete({ params: { id: ol._id.toString() }, auth: req.auth }, res, options);
885
+ } catch (err) {
886
+ logger.error(`Failed to delete ObjectLayer ${ol._id} during bulk delete: ${err.message}`);
887
+ }
888
+ }
889
+ return { deletedCount: allObjectLayers.length };
890
+ }
891
+ };
892
+ }
893
+
894
+ export { ObjectLayerService };