@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,1060 @@
1
+ /**
2
+ * Parametric shape generator with procedural noise, seeded RNG, and arc-length resampling.
3
+ * Exports a single pure function `generateShape` that returns ordered contour points.
4
+ * @module src/projects/cyberia/shape-generator.js
5
+ * @namespace ShapeGenerator
6
+ */
7
+
8
+ /* ═══════════════════════════════════════════════════════════════════════════
9
+ * SEEDED PRNG – Mulberry32 (32-bit, fast, deterministic)
10
+ * ═══════════════════════════════════════════════════════════════════════════ */
11
+
12
+ /**
13
+ * Creates a seeded pseudo-random number generator (Mulberry32).
14
+ * @param {number} seed - Integer seed value.
15
+ * @returns {function(): number} Returns a function that yields 0..1 on each call.
16
+ * @memberof ShapeGenerator
17
+ */
18
+ export function createRng(seed) {
19
+ let s = seed | 0;
20
+ return function () {
21
+ s |= 0;
22
+ s = (s + 0x6d2b79f5) | 0;
23
+ let t = Math.imul(s ^ (s >>> 15), 1 | s);
24
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
25
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Converts an arbitrary seed (string or number) into a 32-bit integer.
31
+ * @param {number|string} seed
32
+ * @returns {number}
33
+ * @memberof ShapeGenerator
34
+ */
35
+ export function seedToInt(seed) {
36
+ if (typeof seed === 'number') return seed | 0;
37
+ let h = 0;
38
+ for (let i = 0; i < seed.length; i++) {
39
+ h = (Math.imul(31, h) + seed.charCodeAt(i)) | 0;
40
+ }
41
+ return h;
42
+ }
43
+
44
+ /* ═══════════════════════════════════════════════════════════════════════════
45
+ * SIMPLEX-LIKE 2-D NOISE (value noise with smooth interpolation)
46
+ * ═══════════════════════════════════════════════════════════════════════════ */
47
+
48
+ /**
49
+ * Creates a 2D value-noise function seeded by the provided RNG.
50
+ * Uses smooth Hermite interpolation for organic feel.
51
+ * @param {function(): number} rng - Seeded random number generator.
52
+ * @returns {function(number, number): number} Noise function returning -1..1.
53
+ * @memberof ShapeGenerator
54
+ */
55
+ export function createNoise2D(rng) {
56
+ const SIZE = 256;
57
+ const perm = new Uint8Array(SIZE * 2);
58
+ const grad = new Float64Array(SIZE);
59
+
60
+ // Fill gradient table
61
+ for (let i = 0; i < SIZE; i++) {
62
+ grad[i] = rng() * 2 - 1;
63
+ }
64
+
65
+ // Fill permutation table
66
+ const p = Array.from({ length: SIZE }, (_, i) => i);
67
+ for (let i = SIZE - 1; i > 0; i--) {
68
+ const j = (rng() * (i + 1)) | 0;
69
+ [p[i], p[j]] = [p[j], p[i]];
70
+ }
71
+ for (let i = 0; i < SIZE * 2; i++) perm[i] = p[i & (SIZE - 1)];
72
+
73
+ function fade(t) {
74
+ return t * t * t * (t * (t * 6 - 15) + 10);
75
+ }
76
+
77
+ function lerp(a, b, t) {
78
+ return a + t * (b - a);
79
+ }
80
+
81
+ function hash(ix, iy) {
82
+ return perm[(perm[ix & (SIZE - 1)] + iy) & (SIZE - 1)];
83
+ }
84
+
85
+ return function noise2D(x, y) {
86
+ const ix = Math.floor(x);
87
+ const iy = Math.floor(y);
88
+ const fx = x - ix;
89
+ const fy = y - iy;
90
+
91
+ const u = fade(fx);
92
+ const v = fade(fy);
93
+
94
+ const g00 = grad[hash(ix, iy) & (SIZE - 1)];
95
+ const g10 = grad[hash(ix + 1, iy) & (SIZE - 1)];
96
+ const g01 = grad[hash(ix, iy + 1) & (SIZE - 1)];
97
+ const g11 = grad[hash(ix + 1, iy + 1) & (SIZE - 1)];
98
+
99
+ const n0 = lerp(g00, g10, u);
100
+ const n1 = lerp(g01, g11, u);
101
+ return lerp(n0, n1, v);
102
+ };
103
+ }
104
+
105
+ /* ═══════════════════════════════════════════════════════════════════════════
106
+ * PARAMETRIC SHAPE REGISTRY
107
+ * Each shape function receives (t, params) where t ∈ [0, 1]
108
+ * and returns {x, y} in arbitrary local coordinates.
109
+ * ═══════════════════════════════════════════════════════════════════════════ */
110
+
111
+ /**
112
+ * @typedef {Object} ShapePoint
113
+ * @property {number} x
114
+ * @property {number} y
115
+ * @memberof ShapeGenerator
116
+ */
117
+
118
+ /**
119
+ * Registry of parametric shape functions.
120
+ * Each entry maps a key string to a function (t, params) → {x, y}.
121
+ * @type {Object<string, function(number, Object): ShapePoint>}
122
+ * @memberof ShapeGenerator
123
+ */
124
+ const shapeRegistry = {};
125
+
126
+ /**
127
+ * Registers a new parametric shape function.
128
+ * @param {string} key - Unique shape identifier.
129
+ * @param {function(number, Object): ShapePoint} fn - Parametric function.
130
+ * @memberof ShapeGenerator
131
+ */
132
+ export function registerShape(key, fn) {
133
+ shapeRegistry[key] = fn;
134
+ }
135
+
136
+ // ---- Built-in shapes -------------------------------------------------------
137
+
138
+ registerShape('circle', (t, params) => {
139
+ const r = params.r ?? 1;
140
+ const angle = t * Math.PI * 2;
141
+ return { x: r * Math.cos(angle), y: r * Math.sin(angle) };
142
+ });
143
+
144
+ registerShape('ellipse', (t, params) => {
145
+ const a = params.a ?? 1;
146
+ const b = params.b ?? 0.6;
147
+ const angle = t * Math.PI * 2;
148
+ return { x: a * Math.cos(angle), y: b * Math.sin(angle) };
149
+ });
150
+
151
+ registerShape('parabola', (t, params) => {
152
+ const a = params.a ?? 1;
153
+ const rangeX = params.rangeX ?? 2;
154
+ const x = (t - 0.5) * rangeX;
155
+ return { x, y: a * x * x };
156
+ });
157
+
158
+ registerShape('thick-parabola', (t, params) => {
159
+ // Closed parabolic band — traces the outer curve forward then the inner
160
+ // curve backward, producing a thick filled crescent when rasterized.
161
+ // `a` controls curvature, `rangeX` controls horizontal span, and
162
+ // `thickness` controls band width (vertical gap between outer/inner).
163
+ const a = params.a ?? 0.6;
164
+ const rangeX = params.rangeX ?? 2.0;
165
+ const thickness = params.thickness ?? 0.35;
166
+ if (t <= 0.5) {
167
+ // Outer parabola (forward: left → right)
168
+ const u = t * 2;
169
+ const xNorm = -rangeX + 2 * rangeX * u;
170
+ return { x: xNorm, y: a * xNorm * xNorm };
171
+ }
172
+ // Inner parabola (reverse: right → left, shifted up by thickness)
173
+ const u = 1 - (t - 0.5) * 2;
174
+ const xNorm = -rangeX + 2 * rangeX * u;
175
+ return { x: xNorm, y: a * xNorm * xNorm + thickness };
176
+ });
177
+
178
+ registerShape('heart', (t) => {
179
+ const angle = t * Math.PI * 2;
180
+ const x = 16 * Math.pow(Math.sin(angle), 3);
181
+ const y = 13 * Math.cos(angle) - 5 * Math.cos(2 * angle) - 2 * Math.cos(3 * angle) - Math.cos(4 * angle);
182
+ return { x: x / 17, y: -y / 17 }; // normalize roughly to -1..1 and flip y
183
+ });
184
+
185
+ registerShape('skull-bone', (t) => {
186
+ // Skull-and-crossbones: cranium dome, two eyes, nose V, mouth with teeth,
187
+ // goatee/chin, jaw, flattened X-bones with knobs.
188
+ // All segment endpoints are carefully matched so there are no stray diagonal lines.
189
+ const PI = Math.PI;
190
+ const mix = (ax, ay, bx, by, f) => ({ x: ax + (bx - ax) * f, y: ay + (by - ay) * f });
191
+
192
+ const crR = 0.6; // cranium radius
193
+ const crCY = -0.1; // cranium vertical center (shifted up a bit for room)
194
+ const eyeR = 0.13; // eye socket radius
195
+ const eyeY = 0.01; // eye socket center Y
196
+ const eyeRX = 0.22; // right eye center X
197
+ const eyeLX = -0.22; // left eye center X
198
+ const noseY = 0.27; // nose tip Y
199
+ const mouthY = 0.38; // mouth line Y
200
+ const mouthW = 0.22; // mouth half-width
201
+ const teethN = 3; // number of teeth
202
+ const goateeY = 0.52; // goatee tip Y
203
+ const goateeW = 0.08; // goatee half-width at top
204
+ const jawW = 0.34; // jaw half-width
205
+ const jawY = 0.46; // jaw bottom Y
206
+ const boneStartY = 0.56; // bone origin Y (just below jaw)
207
+ const crossY = 0.68; // bone crossing Y (flatter — closer to start/end)
208
+ const endY = 0.78; // bone knob center Y (much closer to crossY)
209
+ const boneX = 0.52; // bone knob spread X (wider for flatter angle)
210
+ const knob = 0.06; // knob radius
211
+ const crA0 = PI * 1.15; // cranium start angle (left temple)
212
+ const crA1 = PI * 1.85; // cranium end angle (right temple)
213
+
214
+ // Key anchor points for seamless transitions:
215
+ // Right eye: inner-bottom at angle ~(PI*0.75) from center, outer-top at angle ~(-PI*0.35)
216
+ // Left eye: inner-bottom at angle ~(PI*0.25) from center, outer-top at angle ~(-PI*0.65+2PI)
217
+ const reInnerA = PI * 0.75; // right eye angle toward nose (inner-bottom)
218
+ const reOuterA = -PI * 0.35; // right eye angle toward right temple (outer-top)
219
+ const leInnerA = PI * 0.25; // left eye angle toward nose (inner-bottom)
220
+ const leOuterA = PI + PI * 0.35; // left eye angle toward left temple (outer-top)
221
+
222
+ // Precomputed anchor coords
223
+ const rTempleX = Math.cos(crA1) * crR;
224
+ const rTempleY = crCY + Math.sin(crA1) * crR;
225
+ const reOuterX = eyeRX + Math.cos(reOuterA) * eyeR;
226
+ const reOuterY = eyeY + Math.sin(reOuterA) * eyeR;
227
+ const reInnerX = eyeRX + Math.cos(reInnerA) * eyeR;
228
+ const reInnerY = eyeY + Math.sin(reInnerA) * eyeR;
229
+ const leInnerX = eyeLX + Math.cos(leInnerA) * eyeR;
230
+ const leInnerY = eyeY + Math.sin(leInnerA) * eyeR;
231
+ const leOuterX = eyeLX + Math.cos(leOuterA) * eyeR;
232
+ const leOuterY = eyeY + Math.sin(leOuterA) * eyeR;
233
+ const lTempleX = Math.cos(crA0) * crR;
234
+ const lTempleY = crCY + Math.sin(crA0) * crR;
235
+
236
+ // 0.00–0.14 : cranium dome (left temple → top → right temple)
237
+ if (t < 0.14) {
238
+ const a = crA0 + (t / 0.14) * (crA1 - crA0);
239
+ return { x: Math.cos(a) * crR, y: crCY + Math.sin(a) * crR };
240
+ }
241
+ // 0.14–0.16 : right temple → right eye outer-top (short connector)
242
+ if (t < 0.16) {
243
+ return mix(rTempleX, rTempleY, reOuterX, reOuterY, (t - 0.14) / 0.02);
244
+ }
245
+ // 0.16–0.22 : right eye socket (from outer-top, clockwise full circle back to outer-top)
246
+ if (t < 0.22) {
247
+ const a = reOuterA - ((t - 0.16) / 0.06) * PI * 2;
248
+ return { x: eyeRX + Math.cos(a) * eyeR, y: eyeY + Math.sin(a) * eyeR };
249
+ }
250
+ // 0.22–0.23 : right eye outer-top → right eye inner-bottom (short connector along bottom)
251
+ if (t < 0.23) {
252
+ // small arc along bottom of right eye from outer to inner
253
+ const aStart = reOuterA - PI * 2; // same as reOuterA but after full circle
254
+ const aEnd = reInnerA;
255
+ // go the short way: outer-top → bottom → inner-bottom
256
+ const a = reOuterA + ((t - 0.22) / 0.01) * (reInnerA - reOuterA);
257
+ return { x: eyeRX + Math.cos(a) * eyeR, y: eyeY + Math.sin(a) * eyeR };
258
+ }
259
+ // 0.23–0.27 : nose V (inner-bottom of right eye → nose tip → inner-bottom of left eye)
260
+ if (t < 0.27) {
261
+ const s = (t - 0.23) / 0.04;
262
+ if (s < 0.5) return mix(reInnerX, reInnerY, 0, noseY, s / 0.5);
263
+ return mix(0, noseY, leInnerX, leInnerY, (s - 0.5) / 0.5);
264
+ }
265
+ // 0.27–0.28 : left eye inner-bottom → left eye outer-top (short connector along bottom)
266
+ if (t < 0.28) {
267
+ const a = leInnerA + ((t - 0.27) / 0.01) * (leOuterA - leInnerA);
268
+ return { x: eyeLX + Math.cos(a) * eyeR, y: eyeY + Math.sin(a) * eyeR };
269
+ }
270
+ // 0.28–0.34 : left eye socket (from outer-top, counter-clockwise full circle)
271
+ if (t < 0.34) {
272
+ const a = leOuterA + ((t - 0.28) / 0.06) * PI * 2;
273
+ return { x: eyeLX + Math.cos(a) * eyeR, y: eyeY + Math.sin(a) * eyeR };
274
+ }
275
+ // 0.34–0.36 : left eye outer-top → left temple (short connector)
276
+ if (t < 0.36) {
277
+ return mix(leOuterX, leOuterY, lTempleX, lTempleY, (t - 0.34) / 0.02);
278
+ }
279
+ // 0.36–0.38 : left temple → mouth start (travel down along left cheek to mouth)
280
+ if (t < 0.38) {
281
+ return mix(lTempleX, lTempleY, -mouthW, mouthY, (t - 0.36) / 0.02);
282
+ }
283
+ // 0.38–0.44 : mouth with teeth (zigzag line from left to right)
284
+ if (t < 0.44) {
285
+ const s = (t - 0.38) / 0.06; // 0..1 across mouth
286
+ const x = -mouthW + s * mouthW * 2;
287
+ // zigzag teeth: go up/down based on segment
288
+ const toothPhase = s * teethN * 2; // each tooth = up + down
289
+ const inTooth = toothPhase % 2;
290
+ const toothAmp = 0.05;
291
+ const y = mouthY + (inTooth < 1 ? -toothAmp * inTooth : -toothAmp * (2 - inTooth));
292
+ return { x, y };
293
+ }
294
+ // 0.44–0.49 : goatee / chin tuft (down to point and back)
295
+ if (t < 0.49) {
296
+ const s = (t - 0.44) / 0.05;
297
+ if (s < 0.33) {
298
+ // from mouth right end → goatee left start → down to tip
299
+ return mix(0, mouthY + 0.04, 0, goateeY, s / 0.33);
300
+ }
301
+ if (s < 0.66) {
302
+ // goatee tip → back up, widening
303
+ return mix(0, goateeY, goateeW, mouthY + 0.06, (s - 0.33) / 0.33);
304
+ }
305
+ // close back to center bottom
306
+ return mix(goateeW, mouthY + 0.06, 0, jawY, (s - 0.66) / 0.34);
307
+ }
308
+ // 0.49–0.51 : center jaw → left jaw corner
309
+ if (t < 0.51) {
310
+ return mix(0, jawY, -jawW, jawY, (t - 0.49) / 0.02);
311
+ }
312
+ // 0.51–0.53 : left jaw corner → center below jaw (bone start)
313
+ if (t < 0.53) {
314
+ const s = (t - 0.51) / 0.02;
315
+ return mix(-jawW, jawY, 0, boneStartY, s);
316
+ }
317
+ // 0.53–0.565 : left-down bone arm → left-bottom knob arc
318
+ if (t < 0.545) {
319
+ return mix(0, boneStartY, -boneX, endY, (t - 0.53) / 0.015);
320
+ }
321
+ if (t < 0.565) {
322
+ const a = PI * 0.65 + ((t - 0.545) / 0.02) * PI * 1.7;
323
+ return { x: -boneX + Math.cos(a) * knob, y: endY + Math.sin(a) * knob };
324
+ }
325
+ // 0.565–0.605 : left-bottom knob → cross center → right-bottom knob
326
+ if (t < 0.585) {
327
+ return mix(-boneX, endY, 0, crossY, (t - 0.565) / 0.02);
328
+ }
329
+ if (t < 0.605) {
330
+ return mix(0, crossY, boneX, endY, (t - 0.585) / 0.02);
331
+ }
332
+ // 0.605–0.64 : right-bottom knob arc → back up to center
333
+ if (t < 0.625) {
334
+ const a = PI * 0.35 - ((t - 0.605) / 0.02) * PI * 1.7;
335
+ return { x: boneX + Math.cos(a) * knob, y: endY + Math.sin(a) * knob };
336
+ }
337
+ if (t < 0.64) {
338
+ return mix(boneX, endY, 0, boneStartY, (t - 0.625) / 0.015);
339
+ }
340
+ // --- second bone of the X (top-left to bottom-right, crossing the first) ---
341
+ // 0.64–0.675 : center → left-top knob
342
+ if (t < 0.655) {
343
+ return mix(0, boneStartY, -boneX, boneStartY, (t - 0.64) / 0.015);
344
+ }
345
+ if (t < 0.675) {
346
+ const a = -PI * 0.35 - ((t - 0.655) / 0.02) * PI * 1.7;
347
+ return { x: -boneX + Math.cos(a) * knob, y: boneStartY + Math.sin(a) * knob };
348
+ }
349
+ // 0.675–0.715 : left-top knob → cross center → right-top knob area
350
+ if (t < 0.695) {
351
+ return mix(-boneX, boneStartY, 0, crossY, (t - 0.675) / 0.02);
352
+ }
353
+ if (t < 0.715) {
354
+ return mix(0, crossY, boneX, boneStartY, (t - 0.695) / 0.02);
355
+ }
356
+ // 0.715–0.75 : right-top knob arc → back to center
357
+ if (t < 0.735) {
358
+ const a = -PI * 0.65 + ((t - 0.715) / 0.02) * PI * 1.7;
359
+ return { x: boneX + Math.cos(a) * knob, y: boneStartY + Math.sin(a) * knob };
360
+ }
361
+ if (t < 0.75) {
362
+ return mix(boneX, boneStartY, 0, boneStartY, (t - 0.735) / 0.015);
363
+ }
364
+ // 0.75–0.78 : center below jaw → right jaw corner
365
+ if (t < 0.78) {
366
+ return mix(0, boneStartY, jawW, jawY, (t - 0.75) / 0.03);
367
+ }
368
+ // 0.78–0.80 : right jaw corner → right temple
369
+ if (t < 0.8) {
370
+ return mix(jawW, jawY, rTempleX, rTempleY, (t - 0.78) / 0.02);
371
+ }
372
+ // 0.80–1.00 : closing arc around cranium bottom back to left temple
373
+ {
374
+ const s = (t - 0.8) / 0.2;
375
+ const a = crA1 + s * (crA0 + PI * 2 - crA1);
376
+ return { x: Math.cos(a) * crR, y: crCY + Math.sin(a) * crR };
377
+ }
378
+ });
379
+
380
+ registerShape('star', (t, params) => {
381
+ const spikes = params.spikes ?? 5;
382
+ const outerR = params.outerR ?? 1;
383
+ const innerR = params.innerR ?? 0.4;
384
+ const angle = t * Math.PI * 2;
385
+ // Alternate between outer and inner radius based on angular position
386
+ const segAngle = Math.PI / spikes;
387
+ const mod = ((angle % (2 * segAngle)) + 2 * segAngle) % (2 * segAngle);
388
+ const r =
389
+ mod < segAngle
390
+ ? outerR + (innerR - outerR) * (mod / segAngle)
391
+ : innerR + (outerR - innerR) * ((mod - segAngle) / segAngle);
392
+ return { x: r * Math.cos(angle), y: r * Math.sin(angle) };
393
+ });
394
+
395
+ registerShape('cactus', (t) => {
396
+ // Organic cactus silhouette using additive sine harmonics
397
+ const angle = t * Math.PI * 2;
398
+ const r = 0.5 + 0.15 * Math.sin(3 * angle) + 0.1 * Math.sin(5 * angle) + 0.08 * Math.cos(7 * angle);
399
+ return { x: r * Math.cos(angle), y: r * Math.sin(angle) };
400
+ });
401
+
402
+ registerShape('pixel-art', (t, params) => {
403
+ // Generates a blocky pixel-art shape — a rounded square with stepped edges
404
+ const gridSize = params.gridSize ?? 8;
405
+ const angle = t * Math.PI * 2;
406
+ // Superellipse (Lamé curve) for rounded-square feel
407
+ const n = params.n ?? 4;
408
+ const cosA = Math.cos(angle);
409
+ const sinA = Math.sin(angle);
410
+ const r = 1 / Math.pow(Math.pow(Math.abs(cosA), n) + Math.pow(Math.abs(sinA), n), 1 / n);
411
+ let x = r * cosA;
412
+ let y = r * sinA;
413
+ // Snap to grid for pixel-art effect
414
+ x = Math.round(x * gridSize) / gridSize;
415
+ y = Math.round(y * gridSize) / gridSize;
416
+ return { x, y };
417
+ });
418
+
419
+ registerShape('bezier-path', (t, params) => {
420
+ // Cubic Bézier through default control points (or user-supplied)
421
+ const p0 = params.p0 ?? { x: 0, y: 0 };
422
+ const p1 = params.p1 ?? { x: 0.3, y: 1 };
423
+ const p2 = params.p2 ?? { x: 0.7, y: 1 };
424
+ const p3 = params.p3 ?? { x: 1, y: 0 };
425
+ const u = 1 - t;
426
+ const x = u * u * u * p0.x + 3 * u * u * t * p1.x + 3 * u * t * t * p2.x + t * t * t * p3.x;
427
+ const y = u * u * u * p0.y + 3 * u * u * t * p1.y + 3 * u * t * t * p2.y + t * t * t * p3.y;
428
+ return { x, y };
429
+ });
430
+
431
+ registerShape('regular-polygon', (t, params) => {
432
+ // Regular convex polygon with `sides` edges.
433
+ // Traces straight vertex-to-vertex segments for perfect geometric figures.
434
+ const sides = Math.max(3, params.sides ?? 4);
435
+ const r = params.r ?? 1;
436
+ const segAngle = (2 * Math.PI) / sides;
437
+ const angle = t * Math.PI * 2;
438
+ // Which segment are we in?
439
+ const seg = Math.floor(angle / segAngle);
440
+ const frac = (angle - seg * segAngle) / segAngle;
441
+ // Offset: -π/2 puts first vertex at top (flat bottom for odd-sided).
442
+ // For even-sided polygons, shift by half a segment so edges are axis-aligned.
443
+ const offset = -Math.PI / 2 + (sides % 2 === 0 ? Math.PI / sides : 0);
444
+ const a0 = seg * segAngle + offset;
445
+ const a1 = (seg + 1) * segAngle + offset;
446
+ const x = r * ((1 - frac) * Math.cos(a0) + frac * Math.cos(a1));
447
+ const y = r * ((1 - frac) * Math.sin(a0) + frac * Math.sin(a1));
448
+ return { x, y };
449
+ });
450
+
451
+ registerShape('rectangle', (t, params) => {
452
+ // Axis-aligned rectangle with configurable aspect ratio.
453
+ // `width` and `height` control proportions (default: 1.4 × 1.0).
454
+ const w = params.width ?? 1.4;
455
+ const h = params.height ?? 1.0;
456
+ const hw = w / 2,
457
+ hh = h / 2;
458
+ const perim = 2 * (w + h);
459
+ const d = t * perim;
460
+ // Traverse: bottom-left → bottom-right → top-right → top-left
461
+ if (d < w) return { x: -hw + d, y: hh };
462
+ if (d < w + h) return { x: hw, y: hh - (d - w) };
463
+ if (d < 2 * w + h) return { x: hw - (d - w - h), y: -hh };
464
+ return { x: -hw, y: -hh + (d - 2 * w - h) };
465
+ });
466
+
467
+ /* ═══════════════════════════════════════════════════════════════════════════
468
+ * GEOMETRY HELPERS
469
+ * ═══════════════════════════════════════════════════════════════════════════ */
470
+
471
+ /**
472
+ * Arc-length resamples a parametric curve to produce `count` evenly-spaced points.
473
+ * @param {function(number): ShapePoint} curveFn - Function from t→{x,y}.
474
+ * @param {number} count - Number of output points.
475
+ * @param {boolean} closed - If true, the curve wraps so last point connects to first.
476
+ * @returns {ShapePoint[]}
477
+ * @memberof ShapeGenerator
478
+ */
479
+ function arcLengthResample(curveFn, count, closed) {
480
+ // 1. Sample at high resolution to build cumulative arc-length table
481
+ const SAMPLES = Math.max(count * 8, 2000);
482
+ const rawPoints = [];
483
+ for (let i = 0; i <= SAMPLES; i++) {
484
+ rawPoints.push(curveFn(i / SAMPLES));
485
+ }
486
+
487
+ const cumLen = new Float64Array(SAMPLES + 1);
488
+ cumLen[0] = 0;
489
+ for (let i = 1; i <= SAMPLES; i++) {
490
+ const dx = rawPoints[i].x - rawPoints[i - 1].x;
491
+ const dy = rawPoints[i].y - rawPoints[i - 1].y;
492
+ cumLen[i] = cumLen[i - 1] + Math.sqrt(dx * dx + dy * dy);
493
+ }
494
+
495
+ const totalLen = cumLen[SAMPLES];
496
+ if (totalLen === 0) {
497
+ // Degenerate — all points overlap
498
+ const p = rawPoints[0];
499
+ return Array.from({ length: count }, () => ({ x: p.x, y: p.y }));
500
+ }
501
+
502
+ // 2. Walk the arc-length table to pick `count` evenly-spaced distances
503
+ const numSegments = closed ? count : count - 1;
504
+ const step = totalLen / (numSegments || 1);
505
+ const result = [];
506
+ let idx = 0;
507
+
508
+ for (let i = 0; i < count; i++) {
509
+ const target = i * step;
510
+ while (idx < SAMPLES - 1 && cumLen[idx + 1] < target) idx++;
511
+ // Clamp so we never read past rawPoints[SAMPLES]
512
+ const safeIdx = Math.min(idx, SAMPLES - 1);
513
+ // Linear interpolation between safeIdx and safeIdx+1
514
+ const segLen = cumLen[safeIdx + 1] - cumLen[safeIdx];
515
+ const frac = segLen > 0 ? (target - cumLen[safeIdx]) / segLen : 0;
516
+ const x = rawPoints[safeIdx].x + frac * (rawPoints[safeIdx + 1].x - rawPoints[safeIdx].x);
517
+ const y = rawPoints[safeIdx].y + frac * (rawPoints[safeIdx + 1].y - rawPoints[safeIdx].y);
518
+ result.push({ x, y });
519
+ }
520
+
521
+ return result;
522
+ }
523
+
524
+ /**
525
+ * Applies 2D rotation (in radians) to a set of points around their centroid.
526
+ * @param {ShapePoint[]} points
527
+ * @param {number} radians
528
+ * @returns {ShapePoint[]}
529
+ * @memberof ShapeGenerator
530
+ */
531
+ function rotatePoints(points, radians) {
532
+ if (radians === 0) return points;
533
+ // Compute centroid
534
+ let cx = 0,
535
+ cy = 0;
536
+ for (const p of points) {
537
+ cx += p.x;
538
+ cy += p.y;
539
+ }
540
+ cx /= points.length;
541
+ cy /= points.length;
542
+
543
+ const cosR = Math.cos(radians);
544
+ const sinR = Math.sin(radians);
545
+ return points.map((p) => {
546
+ const dx = p.x - cx;
547
+ const dy = p.y - cy;
548
+ return {
549
+ x: cx + dx * cosR - dy * sinR,
550
+ y: cy + dx * sinR + dy * cosR,
551
+ };
552
+ });
553
+ }
554
+
555
+ /**
556
+ * Scales points from their centroid.
557
+ * @param {ShapePoint[]} points
558
+ * @param {number} sx - X scale factor.
559
+ * @param {number} sy - Y scale factor.
560
+ * @returns {ShapePoint[]}
561
+ * @memberof ShapeGenerator
562
+ */
563
+ function scalePoints(points, sx, sy) {
564
+ if (sx === 1 && sy === 1) return points;
565
+ let cx = 0,
566
+ cy = 0;
567
+ for (const p of points) {
568
+ cx += p.x;
569
+ cy += p.y;
570
+ }
571
+ cx /= points.length;
572
+ cy /= points.length;
573
+ return points.map((p) => ({
574
+ x: cx + (p.x - cx) * sx,
575
+ y: cy + (p.y - cy) * sy,
576
+ }));
577
+ }
578
+
579
+ /**
580
+ * Normalizes points into the 0..1 bounding box.
581
+ * @param {ShapePoint[]} points
582
+ * @returns {ShapePoint[]}
583
+ * @memberof ShapeGenerator
584
+ */
585
+ function normalizePoints(points) {
586
+ let minX = Infinity,
587
+ minY = Infinity,
588
+ maxX = -Infinity,
589
+ maxY = -Infinity;
590
+ for (const p of points) {
591
+ if (p.x < minX) minX = p.x;
592
+ if (p.y < minY) minY = p.y;
593
+ if (p.x > maxX) maxX = p.x;
594
+ if (p.y > maxY) maxY = p.y;
595
+ }
596
+ const rangeX = maxX - minX || 1;
597
+ const rangeY = maxY - minY || 1;
598
+ // Uniform scale to fit inside [0..1] while preserving aspect ratio
599
+ const range = Math.max(rangeX, rangeY);
600
+ const offsetX = (range - rangeX) / 2;
601
+ const offsetY = (range - rangeY) / 2;
602
+ return points.map((p) => ({
603
+ x: (p.x - minX + offsetX) / range,
604
+ y: (p.y - minY + offsetY) / range,
605
+ }));
606
+ }
607
+
608
+ /**
609
+ * Computes the axis-aligned bounding box for a set of points.
610
+ * @param {ShapePoint[]} points
611
+ * @returns {{minX: number, minY: number, maxX: number, maxY: number}}
612
+ * @memberof ShapeGenerator
613
+ */
614
+ function computeBbox(points) {
615
+ let minX = Infinity,
616
+ minY = Infinity,
617
+ maxX = -Infinity,
618
+ maxY = -Infinity;
619
+ for (const p of points) {
620
+ if (p.x < minX) minX = p.x;
621
+ if (p.y < minY) minY = p.y;
622
+ if (p.x > maxX) maxX = p.x;
623
+ if (p.y > maxY) maxY = p.y;
624
+ }
625
+ return { minX, minY, maxX, maxY };
626
+ }
627
+
628
+ /**
629
+ * Converts normalized (0..1) points to pixel coordinates.
630
+ * @param {ShapePoint[]} points - Normalized points.
631
+ * @param {number} width - Target pixel width.
632
+ * @param {number} height - Target pixel height.
633
+ * @returns {ShapePoint[]}
634
+ * @memberof ShapeGenerator
635
+ */
636
+ export function toPixelCoords(points, width, height) {
637
+ return points.map((p) => ({
638
+ x: p.x * width,
639
+ y: p.y * height,
640
+ }));
641
+ }
642
+
643
+ /* ═══════════════════════════════════════════════════════════════════════════
644
+ * BRESENHAM RASTERIZATION – connected integer-grid contour
645
+ * ═══════════════════════════════════════════════════════════════════════════ */
646
+
647
+ /**
648
+ * Bresenham line algorithm — returns all integer grid cells between two points.
649
+ * @param {number} x0
650
+ * @param {number} y0
651
+ * @param {number} x1
652
+ * @param {number} y1
653
+ * @returns {ShapePoint[]}
654
+ * @memberof ShapeGenerator
655
+ */
656
+ function bresenhamLine(x0, y0, x1, y1) {
657
+ const pts = [];
658
+ let dx = Math.abs(x1 - x0);
659
+ let dy = -Math.abs(y1 - y0);
660
+ const sx = x0 < x1 ? 1 : -1;
661
+ const sy = y0 < y1 ? 1 : -1;
662
+ let err = dx + dy;
663
+
664
+ for (;;) {
665
+ pts.push({ x: x0, y: y0 });
666
+ if (x0 === x1 && y0 === y1) break;
667
+ const e2 = 2 * err;
668
+ if (e2 >= dy) {
669
+ err += dy;
670
+ x0 += sx;
671
+ }
672
+ if (e2 <= dx) {
673
+ err += dx;
674
+ y0 += sy;
675
+ }
676
+ }
677
+ return pts;
678
+ }
679
+
680
+ /**
681
+ * Rasterizes a contour of normalized (0..1) points onto an integer grid,
682
+ * using Bresenham lines between consecutive points so the outline is fully
683
+ * connected — even on grids as small as 16×16.
684
+ *
685
+ * @param {ShapePoint[]} normalizedPoints - Points in 0..1.
686
+ * @param {number} gridW - Grid width in cells.
687
+ * @param {number} gridH - Grid height in cells.
688
+ * @param {boolean} closed - Whether to connect last point back to first.
689
+ * @returns {ShapePoint[]} Unique integer {x,y} cells ordered along the contour.
690
+ * @memberof ShapeGenerator
691
+ */
692
+ function rasterizeContour(normalizedPoints, gridW, gridH, closed) {
693
+ const maxX = gridW - 1;
694
+ const maxY = gridH - 1;
695
+
696
+ // Map normalized → grid integers
697
+ const gridPts = normalizedPoints.map((p) => ({
698
+ x: Math.round(Math.min(Math.max(p.x, 0), 1) * maxX),
699
+ y: Math.round(Math.min(Math.max(p.y, 0), 1) * maxY),
700
+ }));
701
+
702
+ // Bresenham between every consecutive pair (+ wrap if closed)
703
+ const allCells = [];
704
+ const len = gridPts.length;
705
+ const segments = closed ? len : len - 1;
706
+
707
+ for (let i = 0; i < segments; i++) {
708
+ const a = gridPts[i];
709
+ const b = gridPts[(i + 1) % len];
710
+ const lineCells = bresenhamLine(a.x, a.y, b.x, b.y);
711
+ // Append all except the last cell (it will be the first of the next segment)
712
+ // to avoid trivial duplicates at joints.
713
+ for (let j = 0; j < lineCells.length - 1; j++) {
714
+ allCells.push(lineCells[j]);
715
+ }
716
+ // For the very last segment, include its endpoint too
717
+ if (i === segments - 1) {
718
+ allCells.push(lineCells[lineCells.length - 1]);
719
+ }
720
+ }
721
+
722
+ // Deduplicate while preserving contour order
723
+ const seen = new Set();
724
+ const unique = [];
725
+ for (const p of allCells) {
726
+ const k = p.x * 100000 + p.y;
727
+ if (!seen.has(k)) {
728
+ seen.add(k);
729
+ unique.push(p);
730
+ }
731
+ }
732
+
733
+ return unique;
734
+ }
735
+
736
+ /**
737
+ * Scanline-fills the interior of a closed contour on an integer grid.
738
+ * Takes the contour points produced by `rasterizeContour` and returns a
739
+ * new array containing both the contour AND all interior cells.
740
+ *
741
+ * Uses the standard even-odd scanline algorithm: for each row, find the
742
+ * leftmost and rightmost contour cell then fill everything in between.
743
+ *
744
+ * @param {ShapePoint[]} contourPoints - Contour cells from rasterizeContour.
745
+ * @param {number} gridW - Grid width.
746
+ * @param {number} gridH - Grid height.
747
+ * @returns {ShapePoint[]} All unique filled cells (contour + interior).
748
+ * @memberof ShapeGenerator
749
+ */
750
+ function scanlineFill(contourPoints, gridW, gridH) {
751
+ // Build per-row min/max from contour
752
+ const rowBounds = new Map();
753
+ for (const p of contourPoints) {
754
+ const b = rowBounds.get(p.y);
755
+ if (b) {
756
+ if (p.x < b.min) b.min = p.x;
757
+ if (p.x > b.max) b.max = p.x;
758
+ } else {
759
+ rowBounds.set(p.y, { min: p.x, max: p.x });
760
+ }
761
+ }
762
+
763
+ const seen = new Set();
764
+ const filled = [];
765
+
766
+ for (const [y, { min, max }] of rowBounds) {
767
+ for (let x = min; x <= max; x++) {
768
+ const k = x * 100000 + y;
769
+ if (!seen.has(k)) {
770
+ seen.add(k);
771
+ filled.push({ x, y });
772
+ }
773
+ }
774
+ }
775
+
776
+ return filled;
777
+ }
778
+
779
+ /**
780
+ * Renders an integer-coordinate ShapeResult as an ASCII grid string.
781
+ * Useful for quick visual verification of pixel-art shapes.
782
+ *
783
+ * @param {ShapeResult} shapeResult - Result from generateShape with intCoords enabled.
784
+ * @param {object} [opts] - Render options.
785
+ * @param {string} [opts.filled='█'] - Character for filled cells.
786
+ * @param {string} [opts.empty='·'] - Character for empty cells.
787
+ * @returns {string} Multi-line ASCII grid.
788
+ * @memberof ShapeGenerator
789
+ */
790
+ export function renderGrid(shapeResult, opts = {}) {
791
+ const { filled = '█', empty = '·' } = opts;
792
+ const { points, metadata } = shapeResult;
793
+ const w = metadata.gridWidth;
794
+ const h = metadata.gridHeight;
795
+
796
+ if (w == null || h == null) {
797
+ throw new Error('renderGrid requires a ShapeResult generated with intCoords enabled.');
798
+ }
799
+
800
+ // Build set of occupied cells
801
+ const occupied = new Set();
802
+ for (const p of points) {
803
+ occupied.add(p.y * w + p.x);
804
+ }
805
+
806
+ const rows = [];
807
+ for (let y = 0; y < h; y++) {
808
+ let row = '';
809
+ for (let x = 0; x < w; x++) {
810
+ row += occupied.has(y * w + x) ? filled : empty;
811
+ }
812
+ rows.push(row);
813
+ }
814
+ return rows.join('\n');
815
+ }
816
+
817
+ /* ═══════════════════════════════════════════════════════════════════════════
818
+ * MAIN PUBLIC API
819
+ * ═══════════════════════════════════════════════════════════════════════════ */
820
+
821
+ /**
822
+ * @typedef {Object} ShapeOptions
823
+ * @property {number} [count=200] - Number of XY points to generate.
824
+ * @property {number|number[]} [scale=1] - Uniform number or [sx, sy] scale factors.
825
+ * @property {number} [rotation=0] - Rotation in degrees.
826
+ * @property {number} [jitter=0] - Max random offset in normalized units (0..1).
827
+ * @property {number} [noise=0] - 0..1 strength of procedural noise displacement.
828
+ * @property {number|string} [seed] - Seed for deterministic randomness.
829
+ * @property {boolean} [closed=true] - Whether last point connects to the first.
830
+ * @property {boolean} [normalize=true] - Return points in 0..1 coordinate box.
831
+ * @property {string} [color] - RGBA or hex color metadata.
832
+ * @property {boolean|number|number[]} [intCoords=false] - Integer pixel-art grid mode.
833
+ * - `true` → use a grid of size `count × count` (or `count` as single dim).
834
+ * - `number` (e.g. 16) → square grid of that size (`16×16`).
835
+ * - `[width, height]` → rectangular grid.
836
+ * When enabled, output points are unique integer {x,y} pairs in `0..gridW-1`
837
+ * with Bresenham rasterization so that even on a 16×16 grid the full contour
838
+ * is visible as a connected set of cells. `count` is ignored in this mode;
839
+ * the number of output points equals the number of unique rasterized cells.
840
+ * @property {boolean} [fill=false] - When true (and intCoords is enabled),
841
+ * scanline-fills the interior of the closed contour, producing a solid
842
+ * silhouette instead of an outline-only shape.
843
+ * @memberof ShapeGenerator
844
+ */
845
+
846
+ /**
847
+ * @typedef {Object} ShapeBbox
848
+ * @property {number} minX
849
+ * @property {number} minY
850
+ * @property {number} maxX
851
+ * @property {number} maxY
852
+ * @memberof ShapeGenerator
853
+ */
854
+
855
+ /**
856
+ * @typedef {Object} ShapeMetadata
857
+ * @property {string} key - The shape key used.
858
+ * @property {number} count - Number of points generated.
859
+ * @property {number} seed - Effective integer seed used.
860
+ * @property {string} [color] - Color metadata if provided.
861
+ * @property {ShapeBbox} [bbox] - Bounding box of the output points.
862
+ * @property {number} [gridWidth] - Grid width when intCoords is used.
863
+ * @property {number} [gridHeight] - Grid height when intCoords is used.
864
+ * @memberof ShapeGenerator
865
+ */
866
+
867
+ /**
868
+ * @typedef {Object} ShapeResult
869
+ * @property {ShapePoint[]} points - Ordered contour points.
870
+ * @property {ShapeMetadata} metadata - Descriptive metadata about the generation.
871
+ * @memberof ShapeGenerator
872
+ */
873
+
874
+ /**
875
+ * Generates a parametric shape as an array of ordered contour points.
876
+ *
877
+ * @param {string} key - Shape identifier (e.g. "circle", "heart", "star").
878
+ * @param {ShapeOptions} [options={}] - Generation options.
879
+ * @returns {ShapeResult} The generated shape data.
880
+ * @throws {Error} If the requested shape key is not registered.
881
+ * @memberof ShapeGenerator
882
+ *
883
+ * @example
884
+ * import { generateShape } from './shape-generator.js';
885
+ *
886
+ * const result = generateShape('heart', {
887
+ * count: 300,
888
+ * scale: 0.9,
889
+ * rotation: 10,
890
+ * jitter: 0.002,
891
+ * noise: 0.15,
892
+ * seed: 'fx-42',
893
+ * color: 'rgba(220,20,60,1)',
894
+ * });
895
+ * // result.points -> [{x: 0.51, y: 0.86}, ...]
896
+ */
897
+ export function generateShape(key, options = {}) {
898
+ const shapeFn = shapeRegistry[key];
899
+ if (!shapeFn) {
900
+ const available = Object.keys(shapeRegistry).join(', ');
901
+ throw new Error(`Unknown shape key "${key}". Available shapes: ${available}`);
902
+ }
903
+
904
+ // ---- Destructure options with defaults ------------------------------------
905
+ const {
906
+ count = 200,
907
+ scale = 1,
908
+ rotation = 0,
909
+ jitter = 0,
910
+ noise = 0,
911
+ seed: rawSeed,
912
+ closed = true,
913
+ normalize = true,
914
+ intCoords = false,
915
+ fill = false,
916
+ color,
917
+ ...extraParams
918
+ } = options;
919
+
920
+ // ---- Parse intCoords into grid dimensions ---------------------------------
921
+ let gridW = 0;
922
+ let gridH = 0;
923
+ const useIntCoords = intCoords !== false && intCoords !== 0;
924
+
925
+ if (useIntCoords) {
926
+ if (Array.isArray(intCoords)) {
927
+ gridW = intCoords[0] | 0;
928
+ gridH = intCoords[1] | 0;
929
+ } else if (typeof intCoords === 'number') {
930
+ gridW = intCoords | 0;
931
+ gridH = intCoords | 0;
932
+ } else {
933
+ // true → derive from count, minimum 8 to be useful
934
+ gridW = Math.max(count, 8) | 0;
935
+ gridH = gridW;
936
+ }
937
+ if (gridW < 2 || gridH < 2) {
938
+ throw new Error(`intCoords grid must be at least 2×2, got ${gridW}×${gridH}`);
939
+ }
940
+ }
941
+
942
+ // When rasterizing, oversample the parametric curve so small grids get
943
+ // enough raw points for Bresenham to trace the full contour.
944
+ const sampleCount = useIntCoords ? Math.max(count, (gridW + gridH) * 4) : count;
945
+
946
+ // ---- Seeded RNG -----------------------------------------------------------
947
+ const intSeed = rawSeed != null ? seedToInt(rawSeed) : (Math.random() * 0x7fffffff) | 0;
948
+ const rng = createRng(intSeed);
949
+
950
+ // ---- Noise function -------------------------------------------------------
951
+ let noise2D = null;
952
+ if (noise > 0) {
953
+ noise2D = createNoise2D(rng);
954
+ }
955
+
956
+ // ---- Scale factors --------------------------------------------------------
957
+ const sx = Array.isArray(scale) ? scale[0] : scale;
958
+ const sy = Array.isArray(scale) ? scale[1] : scale;
959
+
960
+ // ---- Build raw parametric curve function -----------------------------------
961
+ const curveFn = (t) => shapeFn(t, extraParams);
962
+
963
+ // ---- Arc-length resample to evenly-spaced points --------------------------
964
+ let points = arcLengthResample(curveFn, sampleCount, closed);
965
+
966
+ // ---- Apply scale ----------------------------------------------------------
967
+ points = scalePoints(points, sx, sy);
968
+
969
+ // ---- Apply rotation (degrees → radians) -----------------------------------
970
+ if (rotation !== 0) {
971
+ points = rotatePoints(points, (rotation * Math.PI) / 180);
972
+ }
973
+
974
+ // ---- Apply procedural noise displacement ----------------------------------
975
+ if (noise > 0 && noise2D) {
976
+ const noiseScale = 3; // frequency multiplier
977
+ points = points.map((p, i) => {
978
+ const t = i / sampleCount;
979
+ const nx = noise2D(t * noiseScale * 10, 0.0) * noise * 0.1;
980
+ const ny = noise2D(0.0, t * noiseScale * 10) * noise * 0.1;
981
+ return { x: p.x + nx, y: p.y + ny };
982
+ });
983
+ }
984
+
985
+ // ---- Apply jitter ---------------------------------------------------------
986
+ if (jitter > 0) {
987
+ points = points.map((p) => ({
988
+ x: p.x + (rng() * 2 - 1) * jitter,
989
+ y: p.y + (rng() * 2 - 1) * jitter,
990
+ }));
991
+ }
992
+
993
+ // ---- Normalize to 0..1 (always needed before intCoords rasterization) -----
994
+ if (normalize || useIntCoords) {
995
+ points = normalizePoints(points);
996
+ }
997
+
998
+ // ---- Integer grid rasterization (Bresenham) -------------------------------
999
+ if (useIntCoords) {
1000
+ points = rasterizeContour(points, gridW, gridH, closed);
1001
+
1002
+ // ---- Scanline fill (solid silhouette) -----------------------------------
1003
+ if (fill && closed) {
1004
+ points = scanlineFill(points, gridW, gridH);
1005
+ }
1006
+
1007
+ // Build metadata for integer grid mode
1008
+ const bbox = computeBbox(points);
1009
+ /** @type {ShapeMetadata} */
1010
+ const metadata = {
1011
+ key,
1012
+ count: points.length,
1013
+ seed: intSeed,
1014
+ gridWidth: gridW,
1015
+ gridHeight: gridH,
1016
+ bbox: {
1017
+ minX: bbox.minX,
1018
+ minY: bbox.minY,
1019
+ maxX: bbox.maxX,
1020
+ maxY: bbox.maxY,
1021
+ },
1022
+ };
1023
+ if (color != null) metadata.color = color;
1024
+
1025
+ return { points, metadata };
1026
+ }
1027
+
1028
+ // ---- Round for cleanliness (6 decimal places) -----------------------------
1029
+ points = points.map((p) => ({
1030
+ x: Math.round(p.x * 1e6) / 1e6,
1031
+ y: Math.round(p.y * 1e6) / 1e6,
1032
+ }));
1033
+
1034
+ // ---- Build metadata -------------------------------------------------------
1035
+ const bbox = computeBbox(points);
1036
+ /** @type {ShapeMetadata} */
1037
+ const metadata = {
1038
+ key,
1039
+ count: points.length,
1040
+ seed: intSeed,
1041
+ bbox: {
1042
+ minX: Math.round(bbox.minX * 1e6) / 1e6,
1043
+ minY: Math.round(bbox.minY * 1e6) / 1e6,
1044
+ maxX: Math.round(bbox.maxX * 1e6) / 1e6,
1045
+ maxY: Math.round(bbox.maxY * 1e6) / 1e6,
1046
+ },
1047
+ };
1048
+ if (color != null) metadata.color = color;
1049
+
1050
+ return { points, metadata };
1051
+ }
1052
+
1053
+ /**
1054
+ * Returns the list of currently registered shape keys.
1055
+ * @returns {string[]}
1056
+ * @memberof ShapeGenerator
1057
+ */
1058
+ export function listShapes() {
1059
+ return Object.keys(shapeRegistry);
1060
+ }