@cimplify/sdk 0.109.0 → 0.110.2

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 (337) hide show
  1. package/dist/advanced.d.mts +4 -4
  2. package/dist/advanced.d.ts +4 -4
  3. package/dist/{audio-XU2sFNyO.d.mts → audio-DhvyjqdA.d.mts} +2 -2
  4. package/dist/{audio-8Igdy2WK.d.ts → audio-m0w8cnxq.d.ts} +2 -2
  5. package/dist/avatars.js +21 -21
  6. package/dist/avatars.mjs +3 -3
  7. package/dist/{backend-L4d_Ha0J.d.mts → backend-gUCzs5Kg.d.mts} +16 -2
  8. package/dist/{backend-L4d_Ha0J.d.ts → backend-gUCzs5Kg.d.ts} +16 -2
  9. package/dist/{catalogue-BeBFWlHF.d.mts → catalogue-CPTMyBUz.d.mts} +2 -2
  10. package/dist/{catalogue-DLLsfuNg.d.ts → catalogue-OTuS5zp-.d.ts} +2 -2
  11. package/dist/{chunk-HF2MZKP2.mjs → chunk-22BD3RHN.mjs} +6 -3
  12. package/dist/{chunk-B54P6RL2.js → chunk-2AQ237Y4.js} +30 -30
  13. package/dist/{chunk-W3VVG4NL.js → chunk-2O2CG465.js} +14 -2
  14. package/dist/{chunk-UPHTPBNQ.mjs → chunk-2QTQ6BUH.mjs} +1 -1
  15. package/dist/{chunk-BS65NRDW.js → chunk-3S6WPBZL.js} +16 -16
  16. package/dist/{chunk-PEZYNYJE.js → chunk-3TUOUP5T.js} +3 -3
  17. package/dist/{chunk-EB6EAOM5.mjs → chunk-3VEH23I5.mjs} +7 -10
  18. package/dist/{chunk-FB6YH2WW.js → chunk-4C7I3ELN.js} +4 -4
  19. package/dist/{chunk-UQYO3OM7.js → chunk-4ZDR72SG.js} +1 -2
  20. package/dist/{chunk-HPKKCUHU.js → chunk-52YS45RR.js} +13 -13
  21. package/dist/{chunk-6YVELDFK.mjs → chunk-5BYDGGWO.mjs} +1 -1
  22. package/dist/{chunk-YN24DET4.js → chunk-5HFMY3D7.js} +10 -10
  23. package/dist/{chunk-4CVB2ZTC.js → chunk-5LH2QN3T.js} +32 -29
  24. package/dist/{chunk-4A24F4ZV.mjs → chunk-5YFBGGCK.mjs} +4 -1
  25. package/dist/{chunk-NLAT3DB2.mjs → chunk-6DAEZKIG.mjs} +1 -1
  26. package/dist/{chunk-F6CHJXXK.mjs → chunk-6DATW7TB.mjs} +3 -3
  27. package/dist/{chunk-4RYATNVK.mjs → chunk-6H254EVP.mjs} +6 -11
  28. package/dist/{chunk-32U4BVJA.mjs → chunk-6PJWXIFX.mjs} +1 -1
  29. package/dist/{chunk-BHAGIIBI.js → chunk-6WUBSMTX.js} +82 -85
  30. package/dist/{chunk-EPYFN2A3.js → chunk-7AAIAVAA.js} +24 -20
  31. package/dist/{chunk-HZC27ICH.mjs → chunk-7BHW5GTC.mjs} +3 -3
  32. package/dist/{chunk-MB425DVA.mjs → chunk-7IQQQENP.mjs} +2 -2
  33. package/dist/{chunk-DJUUL67Z.js → chunk-7KFTYENS.js} +296 -296
  34. package/dist/{chunk-XLQSNQMP.js → chunk-7SM6XSPZ.js} +339 -339
  35. package/dist/{chunk-NBH64BDP.mjs → chunk-A33OORT7.mjs} +13 -1
  36. package/dist/{chunk-G2SXLGFY.js → chunk-A7BU3BK4.js} +7 -7
  37. package/dist/{chunk-ZNWS7NOW.mjs → chunk-A7V4L2IT.mjs} +2 -2
  38. package/dist/{chunk-O3SITS4R.mjs → chunk-AGV33FWC.mjs} +4 -4
  39. package/dist/{chunk-Z2DE3EHS.js → chunk-AHNR3BXI.js} +7 -7
  40. package/dist/{chunk-UQ4BHMLS.mjs → chunk-AQ5RLBU2.mjs} +5 -5
  41. package/dist/{chunk-J4HU2YQB.js → chunk-AQOE6WCG.js} +2 -2
  42. package/dist/{chunk-X57B7VQC.js → chunk-AYJPHKYV.js} +22 -22
  43. package/dist/{chunk-6XTWY6MH.js → chunk-AZAXD44P.js} +126 -42
  44. package/dist/{chunk-QDW4EPWS.mjs → chunk-BBGKQIJJ.mjs} +1 -1
  45. package/dist/{chunk-NHYTO4VU.js → chunk-BP4JLSUA.js} +111 -120
  46. package/dist/{chunk-7INQVOHY.mjs → chunk-BU6OK542.mjs} +25 -8
  47. package/dist/{chunk-W23VX5MY.js → chunk-CVSRWM6W.js} +5 -5
  48. package/dist/{chunk-A7DK7QAG.mjs → chunk-CYBMFMJD.mjs} +1 -1
  49. package/dist/{chunk-BOTUAHP2.mjs → chunk-DS2VU4WW.mjs} +5 -20
  50. package/dist/{chunk-HMMFNLXZ.js → chunk-DSAG7T5P.js} +2 -2
  51. package/dist/{chunk-7GG4KNTL.mjs → chunk-E65WCTIG.mjs} +8 -4
  52. package/dist/{chunk-WXDVEXTW.mjs → chunk-ECDK6QBF.mjs} +1 -1
  53. package/dist/{chunk-5IRV36MS.mjs → chunk-EIB4OWVQ.mjs} +1 -1
  54. package/dist/{chunk-JLJ4FD5H.js → chunk-EQUZYCGO.js} +18 -18
  55. package/dist/{chunk-AKTWH3KJ.mjs → chunk-F3UJ6ZRM.mjs} +2 -2
  56. package/dist/{chunk-J6HRY5EQ.js → chunk-F63N2ZTQ.js} +232 -232
  57. package/dist/{chunk-MUEFTPNN.js → chunk-FE6VCE4K.js} +34 -34
  58. package/dist/{chunk-2UYTS7SL.mjs → chunk-GCX7TY4D.mjs} +16 -16
  59. package/dist/{chunk-QDLMIHUH.js → chunk-GDB6TCSD.js} +7 -7
  60. package/dist/{chunk-7S7LDFGH.js → chunk-GDZT5LZ5.js} +12 -12
  61. package/dist/{chunk-TB2LS4CE.mjs → chunk-GHS6MIL6.mjs} +7 -11
  62. package/dist/{chunk-7OHZ56N7.mjs → chunk-GXKI64OT.mjs} +4 -4
  63. package/dist/{chunk-HRSIIDOZ.js → chunk-H3OQKK6X.js} +41 -41
  64. package/dist/{chunk-56BM75QX.js → chunk-H5DFSCJ6.js} +2 -2
  65. package/dist/{chunk-LMK775I4.mjs → chunk-HAGEIC2L.mjs} +1 -1
  66. package/dist/{chunk-6FZDMICK.js → chunk-HAJ4JRFO.js} +15 -15
  67. package/dist/{chunk-AWR2G5QN.js → chunk-HDR72GB6.js} +6 -11
  68. package/dist/{chunk-PTT6KIM6.js → chunk-HSEO6TPU.js} +9 -9
  69. package/dist/{chunk-CQSA2D2O.js → chunk-I5FOHCLH.js} +4 -31
  70. package/dist/{chunk-TMFB55IR.js → chunk-J2U6PJSO.js} +3 -30
  71. package/dist/{chunk-W77VO6LP.js → chunk-J5AJNY2N.js} +13 -13
  72. package/dist/{chunk-UKA7LHIT.js → chunk-JR3TNEQC.js} +98 -98
  73. package/dist/{chunk-P2O34BIO.mjs → chunk-JURRXY2J.mjs} +1 -1
  74. package/dist/{chunk-PKMVOVUA.mjs → chunk-K3HW5I2A.mjs} +1 -1
  75. package/dist/{chunk-BXUGKBMK.mjs → chunk-KDQOR4QQ.mjs} +1 -14
  76. package/dist/{chunk-KVZSYGTX.mjs → chunk-KGHJH5KJ.mjs} +1 -1
  77. package/dist/{chunk-3AKWZF3X.mjs → chunk-KK6HYVBI.mjs} +1 -1
  78. package/dist/{chunk-K6GK5B5J.js → chunk-KMKWGXMK.js} +6 -6
  79. package/dist/{chunk-EH4UG7IL.mjs → chunk-KU7O4IXU.mjs} +4 -4
  80. package/dist/{chunk-IHRMR3WV.mjs → chunk-KVFNRJOR.mjs} +9 -9
  81. package/dist/{chunk-HBZQ5HSV.mjs → chunk-LIV3KXJG.mjs} +1 -1
  82. package/dist/{chunk-S75PBSSL.mjs → chunk-ME6HGG4I.mjs} +92 -8
  83. package/dist/{chunk-FKYZCXFM.js → chunk-MIPO6F72.js} +3 -3
  84. package/dist/{chunk-MFWIHTEN.js → chunk-MTIHEW2M.js} +5 -5
  85. package/dist/{chunk-M53GR3ZV.mjs → chunk-NHJUGZUR.mjs} +43 -5
  86. package/dist/{chunk-FAYK2MN6.js → chunk-NZTKLY2W.js} +14 -18
  87. package/dist/{chunk-EQW6PFC2.js → chunk-O2ICABUD.js} +2 -2
  88. package/dist/{chunk-5PW6DVHF.js → chunk-OIVVQQ22.js} +55 -37
  89. package/dist/{chunk-GBJ5CW3A.js → chunk-PKOZXD2Q.js} +30 -30
  90. package/dist/{chunk-NGN3JE5A.js → chunk-PQTQKNKD.js} +16 -7
  91. package/dist/{chunk-PCVVQNBD.js → chunk-QS6TRHMR.js} +5 -5
  92. package/dist/{chunk-DXZZ27CV.js → chunk-RKBLPGPV.js} +245 -207
  93. package/dist/{chunk-765P2G7G.mjs → chunk-RUVGVNOF.mjs} +1 -1
  94. package/dist/{chunk-NJ7ZWH4U.mjs → chunk-SAFJIGYB.mjs} +1 -1
  95. package/dist/{chunk-AOPH2IZV.js → chunk-SKQFLBDD.js} +60 -22
  96. package/dist/{chunk-BUUA5XJV.js → chunk-TWM6DLYF.js} +2 -2
  97. package/dist/{chunk-YPL5TKI4.mjs → chunk-U6UVWEAK.mjs} +1 -1
  98. package/dist/{chunk-6YQDHXPL.mjs → chunk-UCEPNO6N.mjs} +46 -9
  99. package/dist/{chunk-U7RULAEP.mjs → chunk-UG5BTOTF.mjs} +2 -2
  100. package/dist/{chunk-MITGBWV7.mjs → chunk-UGH37BQW.mjs} +1 -1
  101. package/dist/{chunk-URRZ2SMI.mjs → chunk-V7ZRH3PY.mjs} +2 -2
  102. package/dist/{chunk-3H76N7G5.mjs → chunk-VBGHBL3E.mjs} +8 -17
  103. package/dist/{chunk-AZC2LTUI.js → chunk-VVE3Y76O.js} +2 -2
  104. package/dist/{chunk-BRAA7U3I.mjs → chunk-W65JIRI4.mjs} +1 -1
  105. package/dist/{chunk-KU4EDEKA.js → chunk-WKWTDZS7.js} +9 -9
  106. package/dist/{chunk-NTTHAXHI.js → chunk-X5A5FOWW.js} +11 -8
  107. package/dist/{chunk-ODL55PYL.mjs → chunk-XD2PMH46.mjs} +16 -7
  108. package/dist/{chunk-OADW5BSV.js → chunk-XK6UDWJS.js} +2 -2
  109. package/dist/{chunk-7ZTEVNXO.mjs → chunk-Y65LXQGA.mjs} +8 -8
  110. package/dist/{chunk-Z3PGQRTX.mjs → chunk-Y66WVMO5.mjs} +3 -30
  111. package/dist/{chunk-VZAJDN5C.mjs → chunk-Y7JWLB25.mjs} +1 -1
  112. package/dist/{chunk-ZJGPD42I.js → chunk-YCDXAJKU.js} +3 -3
  113. package/dist/{chunk-NCTLCSLE.mjs → chunk-Z3A3AFVU.mjs} +1 -1
  114. package/dist/{chunk-AEEF3T2E.mjs → chunk-ZCY6YKKP.mjs} +3 -3
  115. package/dist/{chunk-M5FWHML6.js → chunk-ZMIL4ZOA.js} +5 -18
  116. package/dist/{chunk-D3JMTFOX.mjs → chunk-ZR5ULMN2.mjs} +1 -1
  117. package/dist/{client-CO8lw80Q.d.mts → client-CX_WR0-J.d.mts} +2 -2
  118. package/dist/{client-C9hsiaki.d.ts → client-dqOhP9Nc.d.ts} +2 -2
  119. package/dist/{courier-CJasuxTU.d.ts → courier-Cnn-edJ4.d.ts} +5 -5
  120. package/dist/{courier-C2Vo2VlH.d.mts → courier-FmGfkvIN.d.mts} +5 -5
  121. package/dist/{crowd-D1ljcic8.d.ts → crowd-DdHFbqKK.d.ts} +1 -1
  122. package/dist/{crowd-B37S1apB.d.mts → crowd-hOVSAmA3.d.mts} +1 -1
  123. package/dist/{danfo-BsaPzhGi.d.mts → danfo-BEBapFlX.d.mts} +3 -3
  124. package/dist/{danfo-CCv23CPy.d.ts → danfo-UQ_PTIIx.d.ts} +3 -3
  125. package/dist/{elements-Bsfk7CPw.d.ts → elements-DdsRig-2.d.mts} +20 -0
  126. package/dist/{elements-Bsfk7CPw.d.mts → elements-DdsRig-2.d.ts} +20 -0
  127. package/dist/engines/godot.d.mts +1 -1
  128. package/dist/engines/godot.d.ts +1 -1
  129. package/dist/engines/wasm.d.mts +1 -1
  130. package/dist/engines/wasm.d.ts +1 -1
  131. package/dist/fallback-KDB4Y2CE.mjs +6 -0
  132. package/dist/fallback-Y26TQENE.js +19 -0
  133. package/dist/{five-a-side-DP84gMuh.d.mts → five-a-side-Bv1AOUy3.d.mts} +4 -4
  134. package/dist/{five-a-side-DO8SDqMb.d.ts → five-a-side-EC51SJY1.d.ts} +4 -4
  135. package/dist/{fluid-BkxNBD2t.d.ts → fluid-ARr0qUIL.d.ts} +168 -4
  136. package/dist/{fluid-BZ42EMds.d.mts → fluid-DLlEj2cs.d.mts} +168 -4
  137. package/dist/game/conformance.d.mts +7 -7
  138. package/dist/game/conformance.d.ts +7 -7
  139. package/dist/game/conformance.js +39 -41
  140. package/dist/game/conformance.mjs +17 -19
  141. package/dist/game/heap.d.mts +3 -3
  142. package/dist/game/heap.d.ts +3 -3
  143. package/dist/game/heap.js +13 -15
  144. package/dist/game/heap.mjs +4 -6
  145. package/dist/game/kit/canvas.d.mts +33 -34
  146. package/dist/game/kit/canvas.d.ts +33 -34
  147. package/dist/game/kit/canvas.js +569 -570
  148. package/dist/game/kit/canvas.mjs +52 -53
  149. package/dist/game/kit/courier.d.mts +9 -9
  150. package/dist/game/kit/courier.d.ts +9 -9
  151. package/dist/game/kit/courier.js +20 -20
  152. package/dist/game/kit/courier.mjs +17 -17
  153. package/dist/game/kit/danfo.d.mts +7 -7
  154. package/dist/game/kit/danfo.d.ts +7 -7
  155. package/dist/game/kit/danfo.js +30 -30
  156. package/dist/game/kit/danfo.mjs +15 -15
  157. package/dist/game/kit/engine.d.mts +12 -12
  158. package/dist/game/kit/engine.d.ts +12 -12
  159. package/dist/game/kit/engine.js +40 -41
  160. package/dist/game/kit/engine.mjs +11 -12
  161. package/dist/game/kit/five-a-side.d.mts +7 -7
  162. package/dist/game/kit/five-a-side.d.ts +7 -7
  163. package/dist/game/kit/five-a-side.js +24 -24
  164. package/dist/game/kit/five-a-side.mjs +14 -14
  165. package/dist/game/kit/frontier.d.mts +7 -7
  166. package/dist/game/kit/frontier.d.ts +7 -7
  167. package/dist/game/kit/genesis.d.mts +7 -7
  168. package/dist/game/kit/genesis.d.ts +7 -7
  169. package/dist/game/kit/ludo.d.mts +8 -8
  170. package/dist/game/kit/ludo.d.ts +8 -8
  171. package/dist/game/kit/ludo.js +24 -24
  172. package/dist/game/kit/ludo.mjs +14 -14
  173. package/dist/game/kit/runner.d.mts +8 -8
  174. package/dist/game/kit/runner.d.ts +8 -8
  175. package/dist/game/kit/runner.js +22 -22
  176. package/dist/game/kit/runner.mjs +14 -14
  177. package/dist/game/kit/shootout.d.mts +9 -9
  178. package/dist/game/kit/shootout.d.ts +9 -9
  179. package/dist/game/kit/shootout.js +33 -34
  180. package/dist/game/kit/shootout.mjs +18 -19
  181. package/dist/game/kit/tycoon.d.mts +9 -9
  182. package/dist/game/kit/tycoon.d.ts +9 -9
  183. package/dist/game/kit/tycoon.js +38 -38
  184. package/dist/game/kit/tycoon.mjs +14 -14
  185. package/dist/game/kit/word.d.mts +7 -7
  186. package/dist/game/kit/word.d.ts +7 -7
  187. package/dist/game/kit/word.js +22 -22
  188. package/dist/game/kit/word.mjs +14 -14
  189. package/dist/game/kit/worlds.d.mts +10 -10
  190. package/dist/game/kit/worlds.d.ts +10 -10
  191. package/dist/game/kit/worlds.js +22 -22
  192. package/dist/game/kit/worlds.mjs +17 -17
  193. package/dist/game/kit.d.mts +31 -32
  194. package/dist/game/kit.d.ts +31 -32
  195. package/dist/game/kit.js +523 -524
  196. package/dist/game/kit.mjs +38 -39
  197. package/dist/game/prepared.d.mts +6 -7
  198. package/dist/game/prepared.d.ts +6 -7
  199. package/dist/game/prepared.js +23 -24
  200. package/dist/game/prepared.mjs +12 -13
  201. package/dist/{game-BZAfgKV6.d.mts → game-Bx8onkhX.d.mts} +5 -97
  202. package/dist/{game-UoJWopvD.d.ts → game-fgQy2YIm.d.ts} +5 -97
  203. package/dist/game.d.mts +56 -18
  204. package/dist/game.d.ts +56 -18
  205. package/dist/game.js +922 -927
  206. package/dist/game.mjs +16 -17
  207. package/dist/{graphics-DNIAV5Mi.d.ts → graphics-C6YjWYvP.d.ts} +1 -1
  208. package/dist/{graphics-CGJDdtdT.d.mts → graphics-Dk2yQnYN.d.mts} +1 -1
  209. package/dist/{guest-CMCZeyh5.d.mts → guest-DrsA00XD.d.mts} +2 -7
  210. package/dist/{guest-CB458Hgw.d.ts → guest-wIdfoT05.d.ts} +2 -7
  211. package/dist/{hit-stop-D2Ca-i9-.d.mts → hit-stop-BKkVwTq7.d.mts} +1 -1
  212. package/dist/{hit-stop-Ca1OYk15.d.ts → hit-stop-D-8pPYnM.d.ts} +1 -1
  213. package/dist/{hot-B9BTmDz6.d.ts → hot-Crn9XpHJ.d.ts} +1 -1
  214. package/dist/{hot-B_L-GEHZ.d.mts → hot-DH3nOhQD.d.mts} +1 -1
  215. package/dist/{index-C3KORE2U.d.mts → index-6gkHMGAq.d.mts} +2 -2
  216. package/dist/{index-DPeyo938.d.ts → index-B8ybCKJI.d.ts} +3 -3
  217. package/dist/{index-DFDeJxFQ.d.ts → index-B98Xac8e.d.ts} +2 -2
  218. package/dist/{index-Cv_rL5X0.d.ts → index-B_ByTtIT.d.ts} +2 -2
  219. package/dist/{index-D8ZDzms9.d.mts → index-DHjNHb1c.d.mts} +3 -3
  220. package/dist/{index-C76o9Pj4.d.mts → index-DbAN_VQE.d.mts} +2 -2
  221. package/dist/index.d.mts +8 -8
  222. package/dist/index.d.ts +8 -8
  223. package/dist/interactives-authoring.js +12 -1
  224. package/dist/interactives-authoring.mjs +12 -1
  225. package/dist/interactives-canvas.global.js +14 -39
  226. package/dist/interactives-guest.d.mts +2 -2
  227. package/dist/interactives-guest.d.ts +2 -2
  228. package/dist/interactives-guest.js +10 -10
  229. package/dist/interactives-guest.mjs +6 -6
  230. package/dist/interactives-jsc.global.js +4 -23
  231. package/dist/interactives-meters.d.mts +11 -11
  232. package/dist/interactives-meters.d.ts +11 -11
  233. package/dist/interactives-meters.js +65 -66
  234. package/dist/interactives-meters.mjs +17 -18
  235. package/dist/interactives-production.d.mts +5 -5
  236. package/dist/interactives-production.d.ts +5 -5
  237. package/dist/interactives-production.js +15 -16
  238. package/dist/interactives-production.mjs +3 -4
  239. package/dist/interactives-record.d.mts +3 -9
  240. package/dist/interactives-record.d.ts +3 -9
  241. package/dist/interactives-record.js +45 -65
  242. package/dist/interactives-record.mjs +19 -39
  243. package/dist/interactives-runtime.d.mts +3 -3
  244. package/dist/interactives-runtime.d.ts +3 -3
  245. package/dist/interactives-runtime.js +101 -105
  246. package/dist/interactives-runtime.mjs +6 -6
  247. package/dist/interactives-studio-kernel.global.js +1 -1
  248. package/dist/interactives-studio.d.mts +7 -7
  249. package/dist/interactives-studio.d.ts +7 -7
  250. package/dist/interactives-studio.js +136 -82
  251. package/dist/interactives-studio.mjs +65 -11
  252. package/dist/interactives-web.d.mts +14 -14
  253. package/dist/interactives-web.d.ts +14 -14
  254. package/dist/interactives-web.js +201 -198
  255. package/dist/interactives-web.mjs +33 -34
  256. package/dist/interactives.d.mts +7 -28
  257. package/dist/interactives.d.ts +7 -28
  258. package/dist/interactives.js +267 -313
  259. package/dist/interactives.mjs +26 -24
  260. package/dist/{juice-Dfgc1B1q.d.ts → juice-CoHxlpKA.d.ts} +1 -1
  261. package/dist/{juice-CsnrmTOk.d.mts → juice-DQztFS43.d.mts} +1 -1
  262. package/dist/{launch-CCsmv8HC.d.mts → launch-T2f4_Di4.d.mts} +6 -6
  263. package/dist/{launch-8W_Tojpz.d.ts → launch-d6oreMzR.d.ts} +6 -6
  264. package/dist/{local-DA_HpPOj.d.mts → local-D8_I6UeL.d.mts} +0 -5
  265. package/dist/{local-_mD0x-p_.d.ts → local-VZkqsCzR.d.ts} +0 -5
  266. package/dist/{ludo-BVHycBP-.d.ts → ludo-B8ClkDqr.d.ts} +4 -4
  267. package/dist/{ludo-BRaTcI3E.d.mts → ludo-BOuohQ-M.d.mts} +4 -4
  268. package/dist/{native-CcMUV7rL.d.mts → native-BodxSh03.d.mts} +2 -2
  269. package/dist/{native-3f4Ht82c.d.ts → native-DUHMT8gA.d.ts} +2 -2
  270. package/dist/{online-CCy8pwOn.d.ts → online-XeymeM9s.d.ts} +1 -1
  271. package/dist/{online-smW2BO3Y.d.mts → online-d7W_Al9a.d.mts} +1 -1
  272. package/dist/{play-BhHHX1jD.d.ts → play-BRRlfLhX.d.ts} +5 -5
  273. package/dist/{play-Bn7NfGNE.d.mts → play-ClrMd_e8.d.mts} +5 -5
  274. package/dist/{policy-Dvnzg8ki.d.mts → policy-CCw8tXLm.d.mts} +19 -19
  275. package/dist/{policy-b3MVXMQu.d.ts → policy-CMqOSQIu.d.ts} +19 -19
  276. package/dist/{ports-CNeZdgVm.d.mts → ports-B_0v_P3A.d.mts} +1 -1
  277. package/dist/{ports-Vno6MDaR.d.ts → ports-CGU_3e_0.d.ts} +1 -1
  278. package/dist/{prefetch-BFg6lJyD.d.ts → prefetch-BHnicOQj.d.ts} +3 -3
  279. package/dist/{prefetch-BOoKX3qx.d.mts → prefetch-CBXgYacv.d.mts} +3 -3
  280. package/dist/{price-BIKJla_G.d.mts → price-BOzexBww.d.mts} +1 -1
  281. package/dist/{price-D1gE7Ek6.d.ts → price-C1h9sPxE.d.ts} +1 -1
  282. package/dist/react.d.mts +16 -16
  283. package/dist/react.d.ts +16 -16
  284. package/dist/react.js +29 -18
  285. package/dist/react.mjs +26 -15
  286. package/dist/{runner-BAG8EglP.d.ts → runner-CQcLL7By.d.ts} +6 -6
  287. package/dist/{runner-CKtKtIzc.d.mts → runner-D46Yj-wE.d.mts} +6 -6
  288. package/dist/{runtime-DfZp1Kwg.d.mts → runtime-BRWfkf_q.d.mts} +1 -8
  289. package/dist/{runtime-yHPgIJV-.d.ts → runtime-DyuBMkKM.d.ts} +1 -8
  290. package/dist/{scheduling-CnRAhWQL.d.ts → scheduling-D2ajXpMC.d.ts} +1 -1
  291. package/dist/{scheduling-lHyYoCa7.d.mts → scheduling-DSRbbaZb.d.mts} +1 -1
  292. package/dist/{server-DxcxjER1.d.ts → server-D29IIuDV.d.ts} +2 -2
  293. package/dist/{server-lU3Sznd4.d.mts → server-DQMWPnc8.d.mts} +2 -2
  294. package/dist/server.d.mts +4 -4
  295. package/dist/server.d.ts +4 -4
  296. package/dist/{shootout-rK-oblpb.d.ts → shootout-BJZeX6FG.d.ts} +6 -6
  297. package/dist/{shootout-D998OWa-.d.mts → shootout-tcZd1Rxt.d.mts} +6 -6
  298. package/dist/styles.css +1 -1
  299. package/dist/{template-Byaueo34.d.mts → template-AhCdB1kW.d.mts} +3 -3
  300. package/dist/{template-BXE2L654.d.ts → template-BkEGVTQj.d.ts} +3 -3
  301. package/dist/{terrain-vgYkJPNx.d.ts → terrain-BMxEc6Oc.d.ts} +3 -3
  302. package/dist/{terrain-CR0NQZPl.d.mts → terrain-C-XC1Oui.d.mts} +3 -3
  303. package/dist/testing/msw.d.mts +3 -3
  304. package/dist/testing/msw.d.ts +3 -3
  305. package/dist/testing/suite.d.mts +6 -6
  306. package/dist/testing/suite.d.ts +6 -6
  307. package/dist/testing.d.mts +5 -5
  308. package/dist/testing.d.ts +5 -5
  309. package/dist/{tick-transport-Q_8syS8J.d.mts → tick-transport-C8QEh8Uw.d.mts} +1 -1
  310. package/dist/{tick-transport-xpMcMTs2.d.ts → tick-transport-UjHY3xK1.d.ts} +1 -1
  311. package/dist/{tree-BsXFWKQ6.d.mts → tree-C-Io2Hbx.d.mts} +1 -1
  312. package/dist/{tree-DW9x29Vv.d.ts → tree-CP_qSW4H.d.ts} +1 -1
  313. package/dist/{tycoon-BMAE5Wea.d.mts → tycoon-B5KHk2Xx.d.mts} +5 -5
  314. package/dist/{tycoon-dWvWTbE4.d.ts → tycoon-hmHo-3HX.d.ts} +5 -5
  315. package/dist/{types-AkQEePZo.d.mts → types-BQkxPwZP.d.mts} +1 -1
  316. package/dist/{types-BWaZJDla.d.ts → types-D_f6UUxM.d.ts} +1 -1
  317. package/dist/utils.d.mts +3 -3
  318. package/dist/utils.d.ts +3 -3
  319. package/dist/{weave-delivery-3G03LdMM.d.mts → weave-delivery-CW-Kstut.d.mts} +10 -1
  320. package/dist/{weave-delivery-3G03LdMM.d.ts → weave-delivery-CW-Kstut.d.ts} +10 -1
  321. package/dist/{web-C8B9uVx_.d.ts → web-Dss74a7v.d.ts} +7 -7
  322. package/dist/{web-BqSEfX2o.d.mts → web-f9ZQPoyw.d.mts} +7 -7
  323. package/dist/{weight-BDABC8cN.d.ts → weight-CPGjsgjV.d.ts} +3 -3
  324. package/dist/{weight-Cee73u3d.d.mts → weight-tF1ODR1p.d.mts} +3 -3
  325. package/dist/{word-DB2CcI9q.d.mts → word-BcX9Jcmv.d.mts} +3 -3
  326. package/dist/{word-C1Q8oXuy.d.ts → word-C7sVPLHm.d.ts} +3 -3
  327. package/dist/{world-Bmh7K4tQ.d.ts → world-PvILHDR1.d.ts} +1 -1
  328. package/dist/{world-CPEjuctH.d.mts → world-qekkXjJv.d.mts} +1 -1
  329. package/dist/{worlds-ShY5h6Z_.d.ts → worlds-Br2Pb0Cs.d.ts} +6 -6
  330. package/dist/{worlds-CQgN3GnR.d.mts → worlds-D5ydYr7d.d.mts} +6 -6
  331. package/package.json +1 -1
  332. package/dist/chunk-2LKAOU3L.mjs +0 -96
  333. package/dist/chunk-UWPQL2IQ.js +0 -104
  334. package/dist/fallback-Q5YYIMVJ.js +0 -20
  335. package/dist/fallback-XGBE3RXC.mjs +0 -7
  336. package/dist/split-Di9wBpNx.d.mts +0 -68
  337. package/dist/split-Di9wBpNx.d.ts +0 -68
@@ -1 +1 @@
1
- (function(){'use strict';function Xt(r){let e=[];for(let n=0;n<r.length;n++){let o=r.charCodeAt(n);if(o>=55296&&o<56320&&n+1<r.length){let i=r.charCodeAt(n+1);i>=56320&&i<57344&&(o=65536+((o&1023)<<10)+(i&1023),n++);}o<128?e.push(o):o<2048?e.push(192|o>>6,128|o&63):o<65536?e.push(224|o>>12,128|o>>6&63,128|o&63):e.push(240|o>>18,128|o>>12&63,128|o>>6&63,128|o&63);}return Uint8Array.from(e)}function ai(r){let e="";for(let n=0;n<r.length;){let o=r[n],i=65533,s=1;o<128?i=o:o>=240&&n+3<r.length?(i=(o&7)<<18|(r[n+1]&63)<<12|(r[n+2]&63)<<6|r[n+3]&63,s=4):o>=224&&n+2<r.length?(i=(o&15)<<12|(r[n+1]&63)<<6|r[n+2]&63,s=3):o>=192&&n+1<r.length&&(i=(o&31)<<6|r[n+1]&63,s=2),e+=String.fromCodePoint(i),n+=s;}return e}var Je=class{constructor(){this.encoding="utf-8";}encode(e=""){return Xt(e)}encodeInto(e,n){let o=Xt(e),i=Math.min(o.length,n.length);return n.set(o.subarray(0,i)),{read:i===o.length?e.length:0,written:i}}},et=class{constructor(){this.encoding="utf-8";}decode(e){if(e===void 0)return "";let n=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return ai(n)}},Ae=globalThis;typeof Ae.TextEncoder!="function"&&(Ae.TextEncoder=Je);typeof Ae.TextDecoder!="function"&&(Ae.TextDecoder=et);var Ee={bench:{footprint:[1.6,.6],height:.9,size:"medium",tags:["street","seat","rest"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,.05],front:[0,0,.6],edge:[.8,.45,0]}},street_lamp:{footprint:[.4,.4],height:4.5,size:"tiny",tags:["street","light"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,4.5,0],front:[0,0,.5]}},bus_stop:{footprint:[3.5,1.5],height:2.6,size:"medium",tags:["street","transit","shelter"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,-0.3],front:[0,0,1.2],top:[0,2.6,0]}},trash_bin:{footprint:[.5,.5],height:1,size:"small",tags:["street","utility"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.5],top:[0,1,0]}},bollard:{footprint:[.25,.25],height:1,size:"tiny",tags:["street","barrier"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1,0]}},fire_hydrant:{footprint:[.4,.4],height:.8,size:"tiny",tags:["street","utility"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.5]}},mailbox:{footprint:[.5,.5],height:1.2,size:"small",tags:["street","utility"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.6],top:[0,1.2,0]}},bike_rack:{footprint:[2,.6],height:.9,size:"medium",tags:["street","transit"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1],edge:[1,.5,0]}},planter:{footprint:[1.2,1.2],height:.8,size:"small",tags:["street","plant"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.8,0],edge:[.6,.5,0]}},fountain:{footprint:[4,4],height:2.2,size:"large",tags:["street","landmark","water"],up:"+y",forward:"+z",solid:true,anchors:{edge:[2,.5,0],front:[0,0,2.4]}},kiosk:{footprint:[2.5,2.5],height:3,size:"medium",tags:["street","shop"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1.6],door:[0,0,1.25],top:[0,3,0]}},parked_car:{footprint:[1.9,4.5],height:1.5,size:"large",tags:["street","vehicle"],up:"+y",forward:"+z",solid:true,anchors:{door:[1,0,.3],front:[0,0,2.6],back:[0,0,-2.6]}},spawn_point:{footprint:[.8,.8],height:0,size:"small",tags:["street","marker","gameplay"],up:"+y",forward:"+z",solid:false,anchors:{front:[0,0,0]}},waypoint:{footprint:[.5,.5],height:0,size:"small",tags:["street","marker","gameplay"],up:"+y",forward:"+z",solid:false,anchors:{front:[0,0,0]}},market_stall:{footprint:[3,2],height:2.6,size:"medium",tags:["market","shop","shelter"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1.3],edge:[0,.9,.9],top:[0,.9,.2],back:[0,0,-1.2]}},crate_stack:{footprint:[1.2,1.2],height:1.4,size:"small",tags:["market","storage"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1.4,0]}},barrel:{footprint:[.7,.7],height:1,size:"small",tags:["market","storage"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1,0]}},produce_table:{footprint:[2,1],height:.9,size:"medium",tags:["market","shop","table"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.9,0],front:[0,0,.8],edge:[0,.9,.5]}},parasol:{footprint:[2.4,2.4],height:2.5,size:"medium",tags:["market","shade"],up:"+y",forward:"+z",solid:false,anchors:{top:[0,2.5,0]}},cart:{footprint:[1.2,2.2],height:1.3,size:"medium",tags:["market","vehicle","shop"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.9,0],front:[0,0,1.4]}},goal:{footprint:[7.3,2],height:2.44,size:"large",tags:["sports","football"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1.5],edge:[3.65,1.2,0]}},basketball_hoop:{footprint:[1.8,2],height:3.95,size:"medium",tags:["sports","basketball"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,2.2],top:[0,3.05,1.2]}},bleacher:{footprint:[8,3],height:2.4,size:"large",tags:["sports","seat","crowd"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,1.2,0],front:[0,0,1.8]}},scoreboard:{footprint:[4,.6],height:5,size:"large",tags:["sports","display"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1]}},corner_flag:{footprint:[.2,.2],height:1.5,size:"tiny",tags:["sports","football","marker"],up:"+y",forward:"+z",solid:false,anchors:{top:[0,1.5,0]}},ball_rack:{footprint:[1.5,.6],height:1.1,size:"medium",tags:["sports","storage"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.7],top:[0,1.1,0]}},table:{footprint:[1.6,.9],height:.75,size:"medium",tags:["interior","table"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.75,0],edge:[0,.75,.45],front:[0,0,.9]}},chair:{footprint:[.5,.5],height:.9,size:"small",tags:["interior","seat"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,0],front:[0,0,.5]}},sofa:{footprint:[2.2,.9],height:.85,size:"medium",tags:["interior","seat","rest"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,.1],front:[0,0,.9]}},bed:{footprint:[1.6,2.1],height:.6,size:"medium",tags:["interior","rest"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.6,0],edge:[.8,.5,0],front:[.95,0,0]}},shelf:{footprint:[1.2,.4],height:2,size:"small",tags:["interior","storage"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,2,0],front:[0,0,.6]}},counter:{footprint:[3,.8],height:1.05,size:"medium",tags:["interior","shop","table"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1.05,0],front:[0,0,.9],back:[0,0,-0.9]}},door:{footprint:[1,.2],height:2.1,size:"small",tags:["interior","passage"],up:"+y",forward:"+z",solid:false,anchors:{door:[0,0,0],front:[0,0,.6],back:[0,0,-0.6]}},rug:{footprint:[2,3],height:.02,size:"medium",tags:["interior","decor","flat"],up:"+y",forward:"+z",solid:false,anchors:{top:[0,.02,0]}},lamp:{footprint:[.3,.3],height:.5,size:"tiny",tags:["interior","light"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.5,0]}},tree:{footprint:[1,1],height:7,size:"small",tags:["nature","plant","shade"],up:"+y",forward:"+z",solid:true,anchors:{edge:[.5,0,0]}},bush:{footprint:[1.4,1.4],height:1.2,size:"small",tags:["nature","plant"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1.2,0]}},rock:{footprint:[1.6,1.2],height:.9,size:"medium",tags:["nature","stone"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.9,0],seat:[0,.6,.3]}},log:{footprint:[2.5,.5],height:.5,size:"medium",tags:["nature","seat","wood"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.5,0],front:[0,0,.6]}},flower_bed:{footprint:[2,1],height:.4,size:"medium",tags:["nature","plant","flat"],up:"+y",forward:"+z",solid:false,anchors:{edge:[1,.2,0]}}};var Qt=new Float64Array(1),Yt=new Uint32Array(Qt.buffer),nt=new Float32Array(1),Zt=new Uint32Array(nt.buffer),Q=Math.fround;function se(r){return nt[0]=r,Zt[0]}function ae(r){return Zt[0]=r>>>0,nt[0]}function li(r,e){return Yt[0]=e>>>0,Yt[1]=r>>>0,Qt[0]}function x(r){return li(Number.parseInt(r.slice(0,8),16),Number.parseInt(r.slice(8),16))}var Jt=["3ff0000000000000","3fefd9b0d3158574","3fefb5586cf9890f","3fef9301d0125b51","3fef72b83c7d517b","3fef54873168b9aa","3fef387a6e756238","3fef1e9df51fdee1","3fef06fe0a31b715","3feef1a7373aa9cb","3feedea64c123422","3feece086061892d","3feebfdad5362a27","3feeb42b569d4f82","3feeab07dd485429","3feea47eb03a5585","3feea09e667f3bcd","3fee9f75e8ec5f74","3feea11473eb0187","3feea589994cce13","3feeace5422aa0db","3feeb737b0cdc5e5","3feec49182a3f090","3feed503b23e255d","3feee89f995ad3ad","3feeff76f2fb5e47","3fef199bdd85529c","3fef3720dcef9069","3fef5818dcfba487","3fef7c97337b9b5f","3fefa4afa2a490da","3fefd0765b6e4540"];Jt.map(r=>Number.parseInt(r.slice(0,8),16));Jt.map(r=>Number.parseInt(r.slice(8),16));[x("3fac6af84b912394"),x("3fcebfce50fac4f3"),x("3fe62e42ff0c52d6")];[x("3ebc6af84b912394"),x("3f2ebfce50fac4f3"),x("3f962e42ff0c52d6")];x("40471547652b82fe");x("4338000000000000");x("42e8000000000000");["3ff661ec79f8f3be","3ff571ed4aaf883d","3ff49539f0f010b0","3ff3c995b0b80385","3ff30d190c8864a5","3ff25e227b0b8ea0","3ff1bb4a4a1a343f","3ff12358f08ae5ba","3ff0953f419900a7","3ff0000000000000","3fee608cfd9a47ac","3feca4b31f026aa0","3feb2036576afce6","3fe9c2d163a1aa2d","3fe886e6037841ed","3fe767dcf5534862"].map(x);["bfd57bf7808caade","bfd2bef0a7c06ddb","bfd01eae7f513a67","bfcb31d8a68224e9","bfc6574f0ac07758","bfc1aa2bc79c8100","bfba4e76ce8c0e5e","bfb1973c5a611ccc","bfa252f438e10c1e","0000000000000000","3faaa5aa5df25984","3fbc5e53aa362eb4","3fc526e57720db08","3fcbc2860d224770","3fd1058bc8a07ee1","3fd4043057b6ee09"].map(x);["bfdefec65b963019","bfdb0b6832d4fca4","bfd7418b0a1fb77b","bfd39de91a6dcf7b","bfd01d9bf3f2b631","bfc97c1d1b3b7af0","bfc2f9e393af3c9f","bfb960cbbf788d5c","bfaa6f9db6475fce","0000000000000000","3fb338ca9f24f53d","3fc476a9543891ba","3fce840b4ac4e4d2","3fd40645f0c6651c","3fd88e9c2c1b9ff8","3fdce0a44eb17bcc"].map(x);x("3fe62e42fefa39ef");["bfd00ea348b88334","3fd5575b0be00b6a","bfdffffef20a4123"].map(x);["bfd712b6f70a7e4d","3fdecabf496832e0","bfe715479ffae3de","3ff715475f35c8b8"].map(x);["3fd27616c9496e0b","bfd71969a075c67a","3fdec70a6ca7badd","bfe7154748bef6c8","3ff71547652ab82b"].map(x);x("405fffffffd1d571");x("405fffffffa3aae2");ae(2139095039);var ci=x("41645f306dc9c883"),ui=x("3ff921fb54442d18"),di=x("3c1921fb54442d18"),mi=x("bfdffffffd0c621c"),pi=x("3fa55553e1068f19"),hi=x("bf56c087e89a359d"),fi=x("3ef99343027bf8c3"),_i=x("bfc555545995a603"),yi=x("3f81107605230bc4"),bi=x("bf2994eb3774cf24"),jt=[1,-1,-1,1],gi=1071,xi=8388608,tt=[162,41721,10680707,2734261102,4186140238,2205044292,1850622997,1313084713,1142237692,355073063,704390999,4230436817,660066805,1473377588,3522507997,4113882560,886948059,3720403810,3235603093,3680671129,1653971260,2509847619,2570863504,1011060801],Si=Math.PI/4,Ai=Math.PI/2,Ei=x("3fda827999fcef34"),en=14,vi=Array.from({length:en},(r,e)=>(e%2===0?1:-1)*(1/(2*e+1))),ve=(1n<<64n)-1n,Ti=(1n<<32n)-1n;function $t(r,e,n,o){let i=r*o,s=r*r,a=s*i,l=s*s,u=a*s,d=l*s,m=hi*n+s*(fi*n),p=yi+s*bi,h=n+s*(mi*n),f=i+a*_i,y=h+l*(pi*n),_=f+u*p,b=y+d*m;return (e&1)!==0?[b,_]:[_,b]}function tn(r){let e=Q(r),n=se(e);if((n>>>20&2047)<gi){let b=(e*ci|0)+xi>>24;return $t(e-b*ui,b,(b&2)!==0?-1:1,jt[b&3])}if(!Number.isFinite(e))return [Number.NaN,Number.NaN];let o=n>>>31,i=n>>>26&15,s=n>>>23&7,a=BigInt((n&16777215|8388608)<<s>>>0),l=a*BigInt(tt[i])&Ti,u=a*BigInt(tt[i+4]),m=(a*BigInt(tt[i+8])>>32n|l<<32n)&ve;m=m+u&ve;let p=(m+(1n<<61n)&ve)>>62n;m=m-(p<<62n)&ve;let h=m>=1n<<63n?m-(1n<<64n):m,f=Number(h)*di,y=Number(p)+o|0;return $t(f,Number(p),(y&2)!==0?-1:1,jt[y&3])}function rt(r){return Q(tn(r)[0])}function ot(r){return Q(tn(r)[1])}function Ii(r){let e=r>Ei,n=e?(r-1)/(r+1):r,o=n*n,i=0;for(let s=en-1;s>=0;s--)i=vi[s]+o*i;return (e?Si:0)+n*i}function wi(r,e){if(Number.isNaN(e)||Number.isNaN(r))return Number.NaN;let n=Math.abs(e),o=Math.abs(r),i=Math.max(n,o),s=Math.min(n,o),a=i===0?0:s===Number.POSITIVE_INFINITY?1:s/i,l=Ii(a);return o>n&&(l=Ai-l),(e<0||Object.is(e,-0))&&(l=Math.PI-l),r<0||Object.is(r,-0)?-l:l}function it(r,e){return Q(wi(Q(r),Q(e)))}var Te=Math.fround;function v(r){return rt(Te(r))}function w(r){return ot(Te(r))}function rn(r,e){return it(Te(r),Te(e))}var Di=new Uint8Array(Uint16Array.of(1).buffer)[0]===1,Ie=Di?Int32Array.of(0,1,2,3):Int32Array.of(3,2,1,0);function le(r,e){let n=(r&65535)+(e&65535);return (r>>>16)+(e>>>16)+(n>>>16)<<16|n&65535}var we=class{constructor(e){this.state=new Uint32Array(4);this.output=new Uint32Array(2);this.words=new Int32Array(this.state.buffer);this.drawn=new Int32Array(this.output.buffer);this.limbs=new Int32Array(7);this.cell=new Float64Array(1);this.halves=new Uint16Array(this.cell.buffer);this.views=[this.state,this.output];this.reseed(e);}rollbackViews(){return this.views}get seed(){return this.output[1]}reseed(e){this.output[1]=e;let n=this.output[1];for(let o=0;o<4;o++){n=n+2654435769>>>0;let i=n;i=Math.imul(i^i>>>16,2246822507),i=Math.imul(i^i>>>13,3266489909),this.state[o]=(i^i>>>16)>>>0;}for(let o=0;o<12;o++)this.advance();}nextUint32(){return this.advance(),this.output[0]}float(){return this.advance(),this.output[0]/4294967296}range(e,n){return this.advance(),e+(n-e)*(this.output[0]/4294967296)}rangeInto(e,n,o,i){this.advance(),e[n]=o+(i-o)*(this.output[0]/4294967296);}int(e,n){return this.advance(),e+(this.output[0]/4294967296*(n-e+1)|0)}chance(e){return this.advance(),this.output[0]/4294967296<e}centeredInto(e,n,o,i,s){this.advance();let a=this.drawn[0]^-2147483648,l=a>>>31,u=l===1?~a:a,d=(u&65535)+l,m=u>>>16;d>65535&&(d=0,m++);let p=o*d,h=o*m;h+=p>>>16,p&=65535;let f=h>>>7;if(i[s]=(f^-l)+l,h===0&&p===0){e[n]=0;return}let y=h!==0?47-Math.clz32(h):31-Math.clz32(p),_=this.limbs;_[0]=p,_[1]=h&65535,_[2]=h>>>16,_[y>>4]&=~(1<<(y&15)),_[3]=0,_[4]=0,_[5]=0,_[6]=0;let b=52-y;for(let I=0;I<3;I++){let $=_[I];if($===0)continue;let ie=I*16+b,Ze=ie>>4,Se=ie&15;_[3+Ze]|=($&65535>>>Se)<<Se,Se>0&&Ze+1<4&&(_[3+Ze+1]|=$>>>16-Se);}let O=this.halves,N=l<<15|y+992<<4|_[6]&15;O[Ie[0]]=_[3],O[Ie[1]]=_[4],O[Ie[2]]=_[5],O[Ie[3]]=N,e.set(this.cell,n);}advance(){let e=this.words,n=e[0],o=e[1],i=e[2],s=e[3],a=le(le(n,o),s);e[3]=le(s,1),e[0]=o^o>>>9,e[1]=le(i,i<<3);let l=i<<21|i>>>11;e[2]=le(l,a),this.drawn[0]=a;}saveState(e){e.set(this.state);}restoreState(e){this.state.set(e);}};var H=1,ue=2,ce=4,Re=.5,at=class{constructor(e,n=Re){this.size=e;this.cell=n;this.columns=Math.max(1,Math.ceil(e[0]/n)),this.rows=Math.max(1,Math.ceil(e[1]/n)),this.cells=new Uint8Array(this.columns*this.rows);}index(e,n){let o=Math.floor(e/this.cell),i=Math.floor(n/this.cell);return o<0||i<0||o>=this.columns||i>=this.rows?-1:i*this.columns+o}at(e,n){let o=this.index(e,n);return o<0?H:this.cells[o]}centre(e){return [(e%this.columns+.5)*this.cell,(Math.floor(e/this.columns)+.5)*this.cell]}forRect(e,n,o,i){let s=w(o),a=v(o),l=n[0]/2,u=n[1]/2,d=Math.hypot(l,u),m=Math.max(0,Math.floor((e[0]-d)/this.cell)),p=Math.min(this.columns-1,Math.floor((e[0]+d)/this.cell)),h=Math.max(0,Math.floor((e[1]-d)/this.cell)),f=Math.min(this.rows-1,Math.floor((e[1]+d)/this.cell));for(let y=h;y<=f;y++)for(let _=m;_<=p;_++){let b=(_+.5)*this.cell-e[0],O=(y+.5)*this.cell-e[1],N=b*s-O*a,I=b*a+O*s;if(Math.abs(N)<=l&&Math.abs(I)<=u&&!i(y*this.columns+_))return false}return true}mark(e,n,o,i){this.forRect(e,n,o,s=>(this.cells[s]|=i,true));}clear(e,n,o,i){return e[0]>=0&&e[1]>=0&&e[0]<=this.size[0]&&e[1]<=this.size[1]&&this.forRect(e,n,o,a=>(this.cells[a]&i)===0)}markRoad(e){let n=e.width/2;for(let o=0;o+1<e.points.length;o++){let i=e.points[o],s=e.points[o+1],a=Math.hypot(s[0]-i[0],s[1]-i[1]);if(a===0)continue;let l=rn(s[0]-i[0],s[1]-i[1]);this.mark([(i[0]+s[0])/2,(i[1]+s[1])/2],[e.width,a+n],l,ue);}}},Pi=[.5,.5];function de(r,e){let n=r[e];return n===void 0?{footprint:Pi,solid:true}:{footprint:n.footprint,solid:n.solid}}function lt(r,e,n){let{footprint:o,solid:i}=de(e,n.kind);r.mark(n.at,o,n.yaw,i?H|ce:ce);}function on(r,e,n,o=Re){let i=new at(r.size,o);for(let s of r.roads)i.markRoad(s);for(let s of n)lt(i,e,s);return i}var Fi=12,sn=2*Math.PI,an=[.5,.5];function ct(r,e,n){if(r.kinds.length===0||r.count<=0)return [];let o=new we(r.seed),i=r.layer==="props"?H|ce|ue:H,s=[],a=r.spacing*r.spacing,l=r.count*Fi;for(let u=0;u<l&&s.length<r.count;u++){let d=o.float()*sn,m=Math.sqrt(o.float())*r.radius,p=[r.at[0]+w(d)*m,r.at[1]+v(d)*m],h=r.kinds[o.int(0,r.kinds.length-1)],f=o.float()*sn;if(s.some(b=>(b.at[0]-p[0])**2+(b.at[1]-p[1])**2<a))continue;let y=r.layer==="crowds"?an:de(n,h).footprint;if(!e.clear(p,y,f,i))continue;let _={kind:h,at:p,yaw:f};r.layer==="props"?lt(e,n,_):e.mark(p,an,f,ce),s.push(_);}return s}function ln(r,e){if(r.length<=2)return [...r];let n=new Uint8Array(r.length);n[0]=1,n[r.length-1]=1;let o=[[0,r.length-1]];for(;o.length>0;){let[i,s]=o.pop(),a=r[i],l=r[s],u=l[0]-a[0],d=l[1]-a[1],m=Math.hypot(u,d),p=-1,h=e;for(let f=i+1;f<s;f++){let y=r[f],_=m===0?Math.hypot(y[0]-a[0],y[1]-a[1]):Math.abs(d*y[0]-u*y[1]+l[0]*a[1]-l[1]*a[0])/m;_>h&&(h=_,p=f);}p<0||(n[p]=1,o.push([i,p],[p,s]));}return r.filter((i,s)=>n[s]===1)}var Ui="shop",Hi=0,cn=1;function Bi(r,e){let n=new Uint8Array(r.cells.length),o=new Int32Array(r.cells.length),i=0,s=0,a=l=>{l<0||n[l]!==Hi||(r.cells[l]&H)!==0||(n[l]=cn,o[s++]=l);};for(let l of e)a(r.index(l[0],l[1]));if(e.length===0){for(let l=0;l<r.columns;l++)a(l),a((r.rows-1)*r.columns+l);for(let l=0;l<r.rows;l++)a(l*r.columns),a(l*r.columns+r.columns-1);}for(;i<s;){let l=o[i++],u=l%r.columns;u>0&&a(l-1),u<r.columns-1&&a(l+1),l>=r.columns&&a(l-r.columns),l+r.columns<r.cells.length&&a(l+r.columns);}return n}function Gi(r,e,n,o){let{footprint:i}=de(n,o.kind),s=[i[0]+r.cell*2,i[1]+r.cell*2],a=false;return r.forRect(o.at,s,o.yaw,l=>(e[l]===cn&&(a=true),!a)),a}function un(r,e,n,o){let i=Bi(e,r.gates.filter(u=>(e.at(u[0],u[1])&H)===0)),s=[];o.forEach((u,d)=>{n[u.kind]?.tags.includes(Ui)&&!Gi(e,i,n,u)&&s.push(d);});let a=[];r.gates.forEach((u,d)=>{(e.at(u[0],u[1])&H)!==0&&a.push(d);});let l=[];return o.forEach((u,d)=>{(u.at[0]<0||u.at[1]<0||u.at[0]>r.size[0]||u.at[1]>r.size[1])&&l.push(d);}),[{id:"reachable",ok:s.length===0,summary:s.length===0?"Every stall can be reached on foot":`${s.length} ${s.length===1?"stall cannot":"stalls cannot"} be reached on foot`,offenders:s},{id:"gates",ok:a.length===0,summary:a.length===0?"Nothing blocks the gates":`${a.length} ${a.length===1?"gate is":"gates are"} blocked`,offenders:a},{id:"inside",ok:l.length===0,summary:l.length===0?"Everything sits inside the place":`${l.length} ${l.length===1?"thing sits":"things sit"} outside the place`,offenders:l}]}var K={ground:40,roads:20,buildings:300,props:60,crowds:120,lights:80,sounds:10},Wi=1e3,me={low:3e4,mid:8e4,high:2e5},Vi=.6,qi=.95,dn={};function mn(r,e){return {ground:Math.ceil(r.size[0]*r.size[1]/Wi),roads:r.roads.reduce((n,o)=>n+Math.max(0,o.points.length-1),0),buildings:r.buildings.length,props:r.props.length+e.props,crowds:r.crowds.reduce((n,o)=>n+o.count,0)+e.crowds,lights:r.lights.length,sounds:r.sounds.length}}function ut(r,e){let n=me[e];return r<=n*Vi?"light":r<=n?"fine":"heavy"}function pn(r,e,n){let o=e[n];return o==null?r:Math.max(0,Math.min(r,Math.floor(o)))}function hn(r,e=dn){let n=Object.keys(K).map(l=>({layer:l,count:r[l],cost:r[l]*K[l],share:0})),o=n.reduce((l,u)=>l+u.cost,0),i=o-r.crowds*K.crowds,s=l=>pn(r.crowds,e,l),a=l=>i+s(l)*K.crowds;return {total:o,layers:n.map(l=>({...l,share:o===0?0:l.cost/o})).sort((l,u)=>u.cost-l.cost),tiers:{low:ut(a("low"),"low"),mid:ut(a("mid"),"mid"),high:ut(a("high"),"high")},tierTotals:{low:a("low"),mid:a("mid"),high:a("high")},tierPeople:{low:s("low"),mid:s("mid"),high:s("high")}}}function zi(r,e,n="crowds"){let o=me[e]*qi,i=r.tierTotals[e];if(i<=me[e])return null;let s=r.layers.find(d=>d.layer===n);if(s===void 0)return null;let a=n==="crowds"?r.tierPeople[e]:s.count;if(a===0)return null;let l=i-a*K[n];if(l>me[e])return null;let u=Math.max(0,Math.floor((o-l)/K[n]));return u>=a?null:{tier:e,layer:n,from:a,to:u}}var Ki=["low","mid","high"],Xi=3;function Yi(r,e){let n=r.tierTotals[e]-r.tierPeople[e]*K.crowds,o=me[e];if(n<=o)return null;let i=[],s=n;for(let a of r.layers)if(!(a.layer==="crowds"||a.cost<=0)&&(i.push(a),s-=a.cost,s<=o||i.length===Xi))break;return {tier:e,withoutPeople:n,budget:o,layers:i}}function fn(r,e=dn){let n={...e},o=[],i=[];for(let s of Ki){if(r.tiers[s]!=="heavy")continue;let a=Yi(r,s);if(a!==null){i.push(a);continue}let l=zi(r,s);l!==null&&(n[s]=l.to,o.push(l));}return o.length===0&&i.length===0?null:{caps:n,fixes:o,stillHeavy:i}}function _n(r,e=Ee,n=Re){let o=[...r.buildings,...r.props],i=on(r,e,o,n),s=[];for(let u of r.scatters)u.layer==="props"&&s.push(...ct(u,i,e));let a=[];for(let u of r.scatters)u.layer==="crowds"&&a.push(...ct(u,i,e));let l=[...o,...s];return {placements:l,people:a,grid:i,weight:hn(mn(r,{props:s.length,crowds:a.length}),r.crowdCaps),checks:un(r,i,e,l)}}var dt=class r{constructor(e,n){this.normal=e;this.w=n;}static through(e,n,o){let i=n[0]-e[0],s=n[1]-e[1],a=n[2]-e[2],l=o[0]-e[0],u=o[1]-e[1],d=o[2]-e[2],m=s*d-a*u,p=a*l-i*d,h=i*u-s*l,f=Math.sqrt(m*m+p*p+h*h);if(f<1e-5*1e-5)return null;let y=[m/f,p/f,h/f];return new r(y,y[0]*e[0]+y[1]*e[1]+y[2]*e[2])}flipped(){return new r([-this.normal[0],-this.normal[1],-this.normal[2]],-this.w)}distance(e){return this.normal[0]*e[0]+this.normal[1]*e[1]+this.normal[2]*e[2]-this.w}split(e,n,o,i,s){let a=0,l=[];for(let p of e.vertices){let h=this.distance(p.p),f=h<-1e-5?2:h>1e-5?1:0;a|=f,l.push(f);}if(a===0){(this.normal[0]*e.plane.normal[0]+this.normal[1]*e.plane.normal[1]+this.normal[2]*e.plane.normal[2]>0?n:o).push(e);return}if(a===1){i.push(e);return}if(a===2){s.push(e);return}let u=[],d=[],m=e.vertices.length;for(let p=0;p<m;p++){let h=(p+1)%m,f=l[p],y=l[h],_=e.vertices[p],b=e.vertices[h];if(f!==2&&u.push(_),f!==1&&d.push(_),(f|y)===3){let O=(this.w-(this.normal[0]*_.p[0]+this.normal[1]*_.p[1]+this.normal[2]*_.p[2]))/(this.normal[0]*(b.p[0]-_.p[0])+this.normal[1]*(b.p[1]-_.p[1])+this.normal[2]*(b.p[2]-_.p[2])),N=ji(_,b,O);u.push(N),d.push(N);}}u.length>=3&&i.push(new Z(u,e.shared,e.plane)),d.length>=3&&s.push(new Z(d,e.shared,e.plane));}};function ji(r,e,n){let o=r.n[0]+(e.n[0]-r.n[0])*n,i=r.n[1]+(e.n[1]-r.n[1])*n,s=r.n[2]+(e.n[2]-r.n[2])*n,a=Math.sqrt(o*o+i*i+s*s)||1;return {p:[r.p[0]+(e.p[0]-r.p[0])*n,r.p[1]+(e.p[1]-r.p[1])*n,r.p[2]+(e.p[2]-r.p[2])*n],n:[o/a,i/a,s/a]}}var Z=class r{constructor(e,n,o){this.vertices=e;this.shared=n;this.plane=o;}static of(e,n){if(e.length<3)return null;let o=dt.through(e[0].p,e[1].p,e[2].p);return o===null?null:new r(e,n,o)}flipped(){let e=[];for(let n=this.vertices.length-1;n>=0;n--){let o=this.vertices[n];e.push({p:o.p,n:[-o.n[0],-o.n[1],-o.n[2]]});}return new r(e,this.shared,this.plane.flipped())}},mt=class r{constructor(){this.plane=null;this.front=null;this.back=null;this.polygons=[];}invert(){let e=[this];for(;e.length>0;){let n=e.pop();n.polygons=n.polygons.map(i=>i.flipped()),n.plane!==null&&(n.plane=n.plane.flipped());let o=n.front;n.front=n.back,n.back=o,n.front!==null&&e.push(n.front),n.back!==null&&e.push(n.back);}}clipPolygons(e){let n=[],o=[{node:this,polygons:e}];for(;o.length>0;){let{node:i,polygons:s}=o.pop();if(i.plane===null){for(let u of s)n.push(u);continue}let a=[],l=[];for(let u of s)i.plane.split(u,a,l,a,l);if(i.front!==null)o.push({node:i.front,polygons:a});else for(let u of a)n.push(u);i.back!==null&&o.push({node:i.back,polygons:l});}return n}clipTo(e){let n=[this];for(;n.length>0;){let o=n.pop();o.polygons=e.clipPolygons(o.polygons),o.front!==null&&n.push(o.front),o.back!==null&&n.push(o.back);}}allPolygons(){let e=[],n=[this];for(;n.length>0;){let o=n.pop();for(let i of o.polygons)e.push(i);o.back!==null&&n.push(o.back),o.front!==null&&n.push(o.front);}return e}build(e){let n=[{node:this,polygons:e}];for(;n.length>0;){let{node:o,polygons:i}=n.pop();if(i.length===0)continue;o.plane===null&&(o.plane=i[0].plane);let s=[],a=[];for(let l of i)o.plane.split(l,o.polygons,o.polygons,s,a);s.length>0&&(o.front??(o.front=new r),n.push({node:o.front,polygons:s})),a.length>0&&(o.back??(o.back=new r),n.push({node:o.back,polygons:a}));}}};function yn(r){let e=new mt;return e.build(r),e}function pt(r,e,n){if(r.length===0)return n==="union"?[...e]:[];if(e.length===0)return n==="intersect"?[]:[...r];let o=yn(r),i=yn(e);return n==="union"?(o.clipTo(i),i.clipTo(o),i.invert(),i.clipTo(o),i.invert(),o.build(i.allPolygons()),o.allPolygons()):n==="subtract"?(o.invert(),o.clipTo(i),i.clipTo(o),i.invert(),i.clipTo(o),i.invert(),o.build(i.allPolygons()),o.invert(),o.allPolygons()):(o.invert(),i.clipTo(o),i.invert(),o.clipTo(i),i.clipTo(o),o.build(i.allPolygons()),o.invert(),o.allPolygons())}function S(r,e,n,o,i,s,a={}){return {id:r,label:e,density:n,friction:o,restitution:i,look:{roughness:.6,metalness:0,opacity:1,...s},species:a.species??null,fluid:a.fluid??null,burns:a.burns??false,conductsHeat:a.conductsHeat??false,breaks:a.breaks??"never"}}var J=[S("iroko_wood","Iroko wood",650,.5,.25,{color:9067059,roughness:.7},{species:"wood",burns:true,breaks:"splinters"}),S("pine_wood","Pine wood",500,.5,.25,{color:13146978,roughness:.75},{species:"wood",burns:true,breaks:"splinters"}),S("copper","Copper",8960,.4,.2,{color:13138251,roughness:.3,metalness:1},{species:"Cu",conductsHeat:true,breaks:"dents"}),S("steel","Steel",7850,.45,.25,{color:10133928,roughness:.35,metalness:1},{species:"steel",conductsHeat:true,breaks:"dents"}),S("iron","Iron",7874,.5,.2,{color:6250339,roughness:.55,metalness:1},{species:"Fe",conductsHeat:true,breaks:"dents"}),S("aluminium","Aluminium",2700,.4,.25,{color:13093841,roughness:.35,metalness:1},{species:"Al",conductsHeat:true,breaks:"dents"}),S("gold","Gold",19300,.35,.15,{color:14199099,roughness:.25,metalness:1},{species:"Au",conductsHeat:true,breaks:"dents"}),S("rubber","Rubber",1100,.9,.8,{color:2829099,roughness:.9},{species:"plastic",burns:true}),S("plastic","Plastic",950,.4,.4,{color:15262940,roughness:.45},{species:"plastic",burns:true,breaks:"shatters"}),S("glass","Glass",2500,.3,.3,{color:14216944,roughness:.05,opacity:.35},{breaks:"shatters"}),S("stone","Stone",2600,.7,.15,{color:9209728,roughness:.9},{breaks:"shatters"}),S("brick","Brick",1900,.75,.1,{color:10835003,roughness:.9},{breaks:"shatters"}),S("bone","Bone",1900,.5,.3,{color:15327695,roughness:.6},{breaks:"splinters"}),S("cloth","Cloth",300,.8,.05,{color:11745850,roughness:1},{burns:true,breaks:"tears"}),S("paper","Paper",700,.6,.05,{color:15986662,roughness:1},{burns:true,breaks:"tears"}),S("ice","Ice",917,.05,.1,{color:13625589,roughness:.1,opacity:.8},{species:"H2O",breaks:"shatters"}),S("jelly","Jelly",1050,.6,.6,{color:14698063,roughness:.2,opacity:.85},{fluid:"jelly"}),S("water","Water",1e3,.02,0,{color:3903446,roughness:.05,opacity:.6},{species:"H2O",fluid:"water"}),S("sand","Sand",1600,.7,.05,{color:14268793,roughness:1},{fluid:"sand"}),S("snow","Snow",300,.3,.05,{color:16054266,roughness:.9},{fluid:"snow"}),S("mud","Mud",1700,.8,.02,{color:6047280,roughness:1},{fluid:"mud"})],ht="plastic",bn=new Map(J.map(r=>[r.id,r]));function ft(r){return bn.get(r)??bn.get(ht)}var $i=["shatters","splinters","tears","dents"];function gn(r){let e=new Set(r.map(n=>ft(n).breaks));return $i.find(n=>e.has(n))??"never"}var Sn=["box","sphere","cylinder","tube","rounded"],yt=2*Math.PI,Qi=Math.PI,_t=Math.PI/180,Zi=3;function Ji(r){let[e,n,o]=[r[0]*_t,r[1]*_t,r[2]*_t],i=w(e),s=v(e),a=w(n),l=v(n),u=w(o),d=v(o);return [a*u,-a*d,l,i*d+s*l*u,i*u-s*l*d,-s*a,s*d-i*l*u,s*u+i*l*d,i*a]}function es(r,e,n,o){let i=r.p,s=r.n,a=e[0]*i[0]+e[1]*i[1]+e[2]*i[2]+n[0],l=e[3]*i[0]+e[4]*i[1]+e[5]*i[2]+n[1],u=e[6]*i[0]+e[7]*i[1]+e[8]*i[2]+n[2],d=e[0]*s[0]+e[1]*s[1]+e[2]*s[2],m=e[3]*s[0]+e[4]*s[1]+e[5]*s[2],p=e[6]*s[0]+e[7]*s[1]+e[8]*s[2];return o===0?(a=-a,d=-d):o===1?(l=-l,m=-m):o===2&&(u=-u,p=-p),{p:[a,l,u],n:[d,m,p]}}function ts(r,e,n,o,i){let s=e.map(l=>es(l,i,o.at,o.mirror));o.mirror>=0&&s.reverse();let a=Z.of(s,n);a!==null&&r.push(a);}function B(r,e,n,o,i,s){return {p:[r,e,n],n:[o,i,s]}}function ns(r){let[e,n,o]=[r[0]/2,r[1]/2,r[2]/2];return [[[1,0,0],[[e,-n,-o],[e,n,-o],[e,n,o],[e,-n,o]]],[[-1,0,0],[[-e,-n,o],[-e,n,o],[-e,n,-o],[-e,-n,-o]]],[[0,1,0],[[-e,n,-o],[-e,n,o],[e,n,o],[e,n,-o]]],[[0,-1,0],[[-e,-n,o],[-e,-n,-o],[e,-n,-o],[e,-n,o]]],[[0,0,1],[[-e,-n,o],[e,-n,o],[e,n,o],[-e,n,o]]],[[0,0,-1],[[e,-n,-o],[-e,-n,-o],[-e,n,-o],[e,n,-o]]]].map(([s,a])=>a.map(l=>B(l[0],l[1],l[2],s[0],s[1],s[2])))}function rs(r,e){let n=Math.max(2,e>>1),o=(s,a)=>{let l=a/e*yt,u=s/n*Qi,d=w(l)*v(u),m=w(u),p=v(l)*v(u);return B(d*r,m*r,p*r,d,m,p)},i=[];for(let s=0;s<n;s++)for(let a=0;a<e;a++){let l=[o(s,a),o(s+1,a),o(s+1,a+1),o(s,a+1)];s===0?l.splice(0,1):s===n-1&&l.splice(1,1),i.push(l);}return i.map(s=>s.reverse())}function xn(r,e,n){let o=e/2,i=[],s=[],a=[];for(let l=0;l<n;l++){let u=l/n*yt,d=(l+1)/n*yt,m=w(u),p=v(u),h=w(d),f=v(d);i.push([B(m*r,-o,p*r,m,0,p),B(m*r,o,p*r,m,0,p),B(h*r,o,f*r,h,0,f),B(h*r,-o,f*r,h,0,f)]),s.push(B(m*r,o,p*r,0,1,0)),a.push(B(m*r,-o,p*r,0,-1,0));}return i.push(s.reverse()),i.push(a),i}function os(r,e,n){let o=[r[0]/2,r[1]/2,r[2]/2],i=Math.max(0,Math.min(e,o[0],o[1],o[2])),s=Math.max(2,n>>1),a=(d,m,p)=>{let h=Math.min(Math.max(d,-o[0]+i),o[0]-i),f=Math.min(Math.max(m,-o[1]+i),o[1]-i),y=Math.min(Math.max(p,-o[2]+i),o[2]-i),_=d-h,b=m-f,O=p-y,N=Math.sqrt(_*_+b*b+O*O);if(N===0||i===0)return B(d,m,p,0,0,0);let I=_/N,$=b/N,ie=O/N;return B(h+I*i,f+$*i,y+ie*i,I,$,ie)},l=[],u=[[0,1,2,1],[0,1,2,-1],[1,2,0,1],[1,2,0,-1],[2,0,1,1],[2,0,1,-1]];for(let[d,m,p,h]of u)for(let f=0;f<s;f++)for(let y=0;y<s;y++){let _=(O,N)=>{let I=[0,0,0];return I[d]=-o[d]+2*o[d]*O/s,I[m]=-o[m]+2*o[m]*N/s,I[p]=h*o[p],a(I[0],I[1],I[2])},b=[_(f,y),_(f+1,y),_(f+1,y+1),_(f,y+1)];l.push(h>0?b:b.reverse());}return l}function is(r,e){let n=Math.max(Zi,Math.floor(e));switch(r.kind){case "box":return ns(r.size);case "sphere":return rs(r.radius,n);case "cylinder":return xn(r.radius,r.height,n);case "tube":return xn(r.radius,r.length,n).map(o=>o.map(i=>B(i.p[1],-i.p[0],i.p[2],i.n[1],-i.n[0],i.n[2])));case "rounded":return os(r.size,r.radius,n)}}function bt(r,e,n,o){let i=Ji(e.turn),s=[];for(let a of is(r,o))ts(s,a,n,e,i);return s}function An(r){switch(r.kind){case "box":case "rounded":return Math.hypot(r.size[0],r.size[1],r.size[2])/2;case "sphere":return r.radius;case "cylinder":return Math.hypot(r.radius,r.height/2);case "tube":return Math.hypot(r.radius,r.length/2)}}var wn=["join","cut","overlap"],Rn=["none","x","y","z"],On=["fire","smoke","steam","sparks","confetti","water","rain","break","sound"],ss=32,as=12,ls=.08,cs=4e3,us=16e3,ds=1e3,En=64,ms={join:"union",cut:"subtract",overlap:"intersect"},kn={none:-1,x:0,y:1,z:2},gt=Math.PI/180,vn=2,ps=6,xt=4,ee=class extends Error{constructor(e){super(e),this.name="ThingError";}};function hs(r,e,n){let o={at:r.at,turn:r.turn,mirror:-1},i=bt(r.shape,o,e,n),s=kn[r.mirror];return s<0?i:pt(i,bt(r.shape,{...o,mirror:s},e,n),"union")}function Tn(r,e,n){let o=[];for(let i of r)o=pt(o,hs(i,e.indexOf(i.material),n),ms[i.combine]);return o}function In(r,e){let n=[],o=[],i=[],s=[];for(let a=0;a<e.length;a++){let l=i.length;for(let u of r){if(u.shared!==a)continue;let d=n.length/3;for(let m of u.vertices)n.push(m.p[0],m.p[1],m.p[2]),o.push(m.n[0],m.n[1],m.n[2]);for(let m=1;m<u.vertices.length-1;m++)i.push(d,d+m,d+m+1);}i.length>l&&s.push({material:e[a],start:l,count:i.length-l});}return {positions:Float32Array.from(n),normals:Float32Array.from(o),indices:Uint32Array.from(i),groups:s,triangles:i.length/3}}function fs(r,e,n){let o=(r[0]+e[0])/2,i=(r[2]+e[2])/2,s=Math.max(e[0]-r[0],e[2]-r[2])/2,a=Float32Array.from([o-s,r[1],i,o+s,r[1],i,o+s,e[1],i,o-s,e[1],i]),l=Float32Array.from([0,0,1,0,0,1,0,0,1,0,0,1]);return {positions:a,normals:l,indices:Uint32Array.from([0,1,2,0,2,3]),groups:[{material:n,start:0,count:vn*3}],triangles:vn}}function _s(r){let e=[1/0,1/0,1/0],n=[-1/0,-1/0,-1/0],o=r.positions;for(let i=0;i<o.length;i+=3)for(let s=0;s<3;s++)o[i+s]<e[s]&&(e[s]=o[i+s]),o[i+s]>n[s]&&(n[s]=o[i+s]);return o.length===0?{min:[0,0,0],max:[0,0,0]}:{min:[e[0],e[1],e[2]],max:[n[0],n[1],n[2]]}}function ys(r){let e=r.positions,n=r.indices,o=0,i=0,s=0,a=0,l=0;for(let u of r.groups){let d=ft(u.material).density;for(let m=u.start;m<u.start+u.count;m+=3){let p=n[m]*3,h=n[m+1]*3,f=n[m+2]*3,y=(e[p]*(e[h+1]*e[f+2]-e[h+2]*e[f+1])-e[p+1]*(e[h]*e[f+2]-e[h+2]*e[f])+e[p+2]*(e[h]*e[f+1]-e[h+1]*e[f]))/ps;o+=y,l+=y*d,i+=y*(e[p]+e[h]+e[f])/xt,s+=y*(e[p+1]+e[h+1]+e[f+1])/xt,a+=y*(e[p+2]+e[h+2]+e[f+2])/xt;}}return Math.abs(o)<Number.EPSILON?{volume:0,mass:0,centre:[0,0,0]}:{volume:o,mass:Math.max(0,l),centre:[i/o,s/o,a/o]}}function bs(r){switch(r.kind){case "box":return {shape:{kind:"cuboid",halfExtents:[r.size[0]/2,r.size[1]/2,r.size[2]/2]},tube:false};case "rounded":return {shape:{kind:"round_cuboid",halfExtents:[Math.max(0,r.size[0]/2-r.radius),Math.max(0,r.size[1]/2-r.radius),Math.max(0,r.size[2]/2-r.radius)],border:r.radius},tube:false};case "sphere":return {shape:{kind:"ball",radius:r.radius},tube:false};case "cylinder":return {shape:{kind:"cylinder",halfHeight:r.height/2,radius:r.radius},tube:false};case "tube":return {shape:{kind:"cylinder",halfHeight:r.length/2,radius:r.radius},tube:true}}}function gs(r,e){let n=r[0]*gt/2,o=r[1]*gt/2,i=r[2]*gt/2,s=v(n),a=w(n),l=v(o),u=w(o),d=v(i),m=w(i),p=[s*u*m+a*l*d,a*l*m-s*u*d,a*u*d+s*l*m,a*u*m-s*l*d];if(!e)return p;let h=Math.SQRT1_2;return [(p[0]-p[1])*h,(p[0]+p[1])*h,(p[2]-p[3])*h,(p[3]+p[2])*h]}function xs(r){let e=[];for(let n of r.parts){if(n.combine!=="join")continue;let{shape:o,tube:i}=bs(n.shape),s=gs(n.turn,i);e.push({shape:o,offset:n.at,rotation:s});let a=kn[n.mirror];if(a!==-1){let l=[n.at[0],n.at[1],n.at[2]];l[a]=-l[a];let u=[-s[0],-s[1],-s[2],s[3]];u[a]=s[a],e.push({shape:o,offset:l,rotation:u});}}return {kind:"compound",parts:e}}function Ss(r,e){let n=r+e*ds;return n<=cs?"light":n<=us?"medium":"heavy"}function Cn(r){if(r.parts.length===0)throw new ee("a thing needs at least one part");if(r.parts.length>En)throw new ee(`a thing holds at most ${En} parts`);let e=[...new Set(r.parts.map(d=>d.material))],n=In(Tn(r.parts,e,ss),e),o=_s(n),i=Math.hypot(o.max[0]-o.min[0],o.max[1]-o.min[1],o.max[2]-o.min[2])/2,s=r.parts.filter(d=>d.combine!=="join"||An(d.shape)>=i*ls),a=r.parts.filter(d=>!s.includes(d)).map(d=>d.name),l=In(Tn(s.length>0?s:r.parts,e,as),e),u=fs(o.min,o.max,n.groups[0]?.material??e[0]);return {levels:[{name:"close",mesh:n,dropped:[]},{name:"middle",mesh:l,dropped:a},{name:"far",mesh:u,dropped:r.parts.map(d=>d.name)}],mass:ys(n),collider:xs(r),bounds:o,cost:Ss(n.triangles,r.effects.length),effects:r.effects}}var Nn={low:{download_bytes:67108864,first_play_bytes:8388608,stream_bytes_per_second:187500,stream_latency_ms:150},mid:{download_bytes:268435456,first_play_bytes:25165824,stream_bytes_per_second:75e4,stream_latency_ms:80},high:{download_bytes:1073741824,first_play_bytes:67108864,stream_bytes_per_second:3125e3,stream_latency_ms:40}};var vs=4;function St(r){let e=Nn[r];return {downloadBytes:e.download_bytes,firstPlayBytes:e.first_play_bytes,link:{bytesPerSecond:e.stream_bytes_per_second,latencyMs:e.stream_latency_ms,concurrency:vs}}}var At={low:St("low"),mid:St("mid"),high:St("high")},ke=At.low.link,Ln=2,Mn=5;function Et(r){return r!==null&&r.runs>0}function Dn(r,e){let n=null;for(let o of r)o.tier!==e||o.runs===0||(n===null||o.runs>n.runs)&&(n=o);return n}var Ts=.5,Is=.2,ws=3;function Rs(r){return r>=Ts?"most":r>=Is?"some":"a_little"}function Pn(r,e=ws){let n=0;for(let o of r)o.cost>0&&(n+=o.cost);return n<=0?[]:r.filter(o=>o.cost>0).map(o=>({label:o.label,share:o.cost/n,amount:Rs(o.cost/n)})).sort((o,i)=>i.share-o.share||o.label.localeCompare(i.label)).slice(0,e)}var Os=1e3;function ks(r,e,n){return r<=0||e<=0?0:Math.ceil(e/Math.max(1,n.concurrency))*n.latencyMs/Os+r/n.bytesPerSecond}function vt(r){return r<Ln?"instant":r<=Mn?"quick":"slow"}function Cs(r,e){return r.tier===null||r.tier===e}function Fn(r,e,n=ke){let o=0,i=0,s=0,a=[];for(let d of r)Cs(d,e)&&(i+=d.bytes,d.beforePlay&&(o+=d.bytes,s++,a.push({label:d.label,cost:d.bytes})));let l=ks(o,s,n),u=At[e];return {tier:e,firstPlayBytes:o,downloadBytes:i,firstPlayRequests:s,openSeconds:l,open:vt(l),fitsDownload:i<=u.downloadBytes,fitsFirstPlay:o<=u.firstPlayBytes,causes:Pn(a)}}var Ns="low";function Un(r,e,n=[],o=Ns){let i=Fn(r,o,ke),s=Dn(n,o),a=Et(s)?i.openSeconds*s.openScale:i.openSeconds,l=e!==null&&e.tier===o;return {opensOn3g:{seconds:a,open:vt(a),calibrated:Et(s)},firstLoadBytes:i.firstPlayBytes,delivery:i,cheaperPhones:l?e.frames:null,memory:l?e.memory:null,heat:l?e.heat:null}}var Ls=["X","Y","Z","W"];function L(r,e){return {description:r,group:e.group??null,label:e.label??null,heavy:e.heavy??false,advanced:e.advanced??false}}function Ms(r){return typeof r=="number"?String(r):Ds(r)}function Ds(r){let e=r.replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").trim().toLowerCase();return e.length===0?e:e[0].toUpperCase()+e.slice(1)}var t={number(r,e){return {kind:"number",...L(r,e),min:e.min,max:e.max,step:e.step??null,unit:e.unit,scale:e.scale??"linear",default:e.default}},integer(r,e){return {kind:"integer",...L(r,e),min:e.min,max:e.max,unit:e.unit??"count",default:e.default}},boolean(r,e,n={}){return {kind:"boolean",...L(r,n),default:e}},choice(r,e,n,o={}){let i=o.labels;return {kind:"choice",...L(r,o),options:e.map(s=>({value:s,label:i?.[String(s)]??Ms(s)})),default:n}},color(r,e,n={}){return {kind:"color",...L(r,n),format:"hex",default:e}},rgb(r,e,n={}){return {kind:"color",...L(r,n),format:"rgb",default:e}},vector(r,e){let n=e.axes??Ls.slice(0,e.default.length);return {kind:"vector",...L(r,e),axes:n,min:e.min,max:e.max,unit:e.unit,default:e.default}},text(r,e="",n=200,o={}){return {kind:"text",...L(r,o),maxLength:n,default:e}},asset(r,e,n={}){return {kind:"asset",...L(r,n),asset:e,default:null}},thing(r,e="any",n={}){return {kind:"thing",...L(r,n),role:e,default:null}},settings(r,e,n={}){return {kind:"settings",...L(r,n),settings:e,default:null}},list(r,e,n){return {kind:"list",...L(r,n),item:e,maxItems:n.maxItems,default:n.default??[]}},wiring(r,e={}){return {kind:"wiring",...L(r,e),default:null}}};function c(r,e){return {name:r,title:e.title,description:e.description,group:e.group??e.title,extends:e.extends??[],omit:e.omit??[],fields:e.fields}}var Hn=140;function D(r){return typeof r=="number"&&Number.isFinite(r)}function Ps(r,e){return e==="hex"?D(r)&&Number.isInteger(r)&&r>=0&&r<=16777215:Array.isArray(r)&&r.length===3&&r.every(n=>D(n)&&n>=0&&n<=1)}function Bn(r,e){let n=[],o=s=>{n.push({field:e,reason:s});},i=r.description.trim();switch(i.length===0&&o("has no description"),i.length>Hn&&o(`description is longer than ${Hn} characters`),/[\n—]/.test(r.description)&&o("description must be one line with no em dash"),r.kind){case "number":case "integer":(!D(r.min)||!D(r.max)||r.min>r.max)&&o("range is not a finite min below max"),(!D(r.default)||r.default<r.min||r.default>r.max)&&o(`default ${r.default} is outside ${r.min} to ${r.max}`),r.kind==="integer"&&(!Number.isInteger(r.min)||!Number.isInteger(r.max)||!Number.isInteger(r.default))&&o("integer range or default is not whole"),r.kind==="number"&&r.scale==="log"&&r.min<=0&&o("log scale needs a positive minimum"),r.kind==="number"&&r.step!==null&&!(r.step>0)&&o("step must be positive");break;case "vector":(!D(r.min)||!D(r.max)||r.min>r.max)&&o("range is not a finite min below max"),(r.axes.length!==r.default.length||r.default.length===0)&&o("axes and default differ in length"),r.default.some(s=>!D(s)||s<r.min||s>r.max)&&o("default is outside the range");break;case "choice":r.options.length<2&&o("a choice needs at least two options"),r.options.some(s=>s.value===r.default)||o(`default ${String(r.default)} is not an option`),new Set(r.options.map(s=>s.value)).size!==r.options.length&&o("options repeat");break;case "color":Ps(r.default,r.format)||o("default is not a colour in its format");break;case "text":(!(r.maxLength>0)||r.default.length>r.maxLength)&&o("text default is longer than its limit");break;case "list":(!(r.maxItems>0)||r.default.length>r.maxItems)&&o("list default is longer than its limit");for(let s of Bn(r.item,`${e}[]`))n.push(s);break;case "settings":r.settings.length===0&&o("names no settings");break;}return n}function Gn(r){let e=[];r.title.trim().length===0&&e.push({field:"",reason:"has no title"}),r.description.trim().length===0&&e.push({field:"",reason:"has no description"}),r.group.trim().length===0&&e.push({field:"",reason:"has no group"});for(let[n,o]of Object.entries(r.fields))for(let i of Bn(o,n))e.push(i);return e}function Fs(r,e){return {path:r,reason:e}}function Us(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function te(r,e,n){return r<e?e:r>n?n:r}function G(r){return {ok:true,value:r}}function M(r,e){return {ok:false,issue:Fs(r,e)}}function Tt(r,e,n=""){switch(r.kind){case "number":{if(!D(e))return M(n,"needs a number");let o=te(e,r.min,r.max);return G(r.step===null?o:te(r.min+Math.round((o-r.min)/r.step)*r.step,r.min,r.max))}case "integer":return D(e)?G(te(Math.round(e),r.min,r.max)):M(n,"needs a whole number");case "boolean":return typeof e=="boolean"?G(e):M(n,"needs on or off");case "choice":{let o=r.options.find(i=>i.value===e);return o===void 0?M(n,`needs one of ${r.options.map(i=>i.label).join(", ")}`):G(o.value)}case "color":return r.format==="hex"?D(e)?G(te(Math.round(e),0,16777215)):M(n,"needs a colour"):!Array.isArray(e)||e.length!==3||!e.every(D)?M(n,"needs a colour"):G(e.map(o=>te(o,0,1)));case "vector":return !Array.isArray(e)||e.length!==r.default.length||!e.every(D)?M(n,`needs ${r.default.length} numbers`):G(e.map(o=>te(o,r.min,r.max)));case "text":return typeof e=="string"?G(e.slice(0,r.maxLength)):M(n,"needs text");case "asset":case "thing":return e===null||typeof e=="string"?G(e):M(n,"needs a reference");case "list":{if(!Array.isArray(e))return M(n,"needs a list");if(e.length>r.maxItems)return M(n,`holds at most ${r.maxItems}`);let o=[];for(let i=0;i<e.length;i++){let s=Tt(r.item,e[i],`${n}[${i}]`);if(!s.ok)return s;o.push(s.value);}return G(o)}case "settings":return e===null||Us(e)?G(e):M(n,"needs a group of settings");case "wiring":return M(n,"is set by code")}}var pe=class extends Error{constructor(e){super(e),this.name="SettingsRegistryError";}},Ce=class{constructor(e){this.schemas=new Map;this.resolved=new Map;for(let n of e){if(this.schemas.has(n.name))throw new pe(`settings ${n.name} are defined twice`);this.schemas.set(n.name,n);}}names(){return [...this.schemas.keys()]}has(e){return this.schemas.has(e)}schema(e){let n=this.schemas.get(e);if(n===void 0)throw new pe(`no settings named ${e}`);return n}resolve(e){let n=this.resolved.get(e);if(n!==void 0)return n;let o=this.build(e,[]);return this.resolved.set(e,o),o}build(e,n){if(n.includes(e))throw new pe(`settings ${[...n,e].join(" > ")} extend themselves`);let o=this.schema(e),i=new Map;for(let s of o.extends)for(let a of this.build(s,[...n,e]).fields)o.omit.includes(a.name)||i.set(a.name,a);for(let[s,a]of Object.entries(o.fields))i.set(s,{name:s,setting:a,group:a.group??o.group,owner:o.name});return {schema:o,fields:[...i.values()],byName:i}}fields(e){let n={};for(let o of this.resolve(e).fields)n[o.name]=o.setting;return n}field(e,n){let o=e;for(let i=0;i<n.length;i++){let s=this.resolve(o).byName.get(n[i]);if(s===void 0)return null;if(i===n.length-1)return s;if(s.setting.kind!=="settings")return null;o=s.setting.settings;}return null}gaps(){let e=[];for(let n of this.schemas.values()){for(let o of Gn(n))e.push({schema:n.name,...o});for(let o of n.extends)this.schemas.has(o)||e.push({schema:n.name,field:"",reason:`extends unknown settings ${o}`});for(let[o,i]of Object.entries(n.fields)){let s=i.kind==="list"?i.item:i;s.kind==="settings"&&!this.schemas.has(s.settings)&&e.push({schema:n.name,field:o,reason:`refers to unknown settings ${s.settings}`});}}return e}normalize(e,n,o){let i=n.join("."),s=this.field(e,n);return s===null?{ok:false,issue:{path:i,reason:`is not a setting of ${this.schema(e).title}`}}:this.normalizeField(s.setting,o,i,[e])}normalizeField(e,n,o,i){if(e.kind==="settings"&&n!==null)return this.normalizeGroup(e.settings,n,o,i);if(e.kind==="list"&&e.item.kind==="settings"&&Array.isArray(n)){let s=[];for(let a=0;a<n.length;a++){let l=this.normalizeGroup(e.item.settings,n[a],`${o}[${a}]`,i);if(!l.ok)return l;s.push(l.value);}return s.length>e.maxItems?{ok:false,issue:{path:o,reason:`holds at most ${e.maxItems}`}}:{ok:true,value:s}}return Tt(e,n,o)}normalizeGroup(e,n,o,i){if(typeof n!="object"||n===null||Array.isArray(n))return {ok:false,issue:{path:o,reason:"needs a group of settings"}};if(i.includes(e))return {ok:false,issue:{path:o,reason:"nests itself"}};let s=this.resolve(e),a={};for(let[l,u]of Object.entries(n)){let d=s.byName.get(l),m=o===""?l:`${o}.${l}`;if(d===void 0)return {ok:false,issue:{path:m,reason:`is not a setting of ${s.schema.title}`}};let p=this.normalizeField(d.setting,u,m,[...i,e]);if(!p.ok)return p;a[l]=p.value;}return {ok:true,value:a}}defaults(e){let n={};for(let o of this.resolve(e).fields)o.setting.kind!=="wiring"&&(n[o.name]=o.setting.default);return n}};var Wn=1024;var Vn=2048;var qn=.8,zn=-100,Kn=-30;var Hs=[32,64,128,256,512,1024,2048,4096,8192,16384,32768],Bs=65536,Gs=1<<20,Ws=120,Vs=8,Xn=[c("EmitterOptions",{title:"Sound crowd",description:"One sound played from many things at once, like rain on leaves or a cheering crowd.",fields:{sound:t.asset("The sound each thing plays","sound"),capacity:t.integer("Most things making the sound",{default:Wn,min:1,max:65536,heavy:true}),panner:t.wiring("How the sound fades and turns with distance")}}),c("AnalyserSettings",{title:"Sound meter",description:"Reads how loud each pitch is, so visuals can move with the music.",fields:{fftSize:t.choice("Detail of the pitch reading",Hs,Vn,{heavy:true}),smoothing:t.number("How much the reading is smoothed between frames",{default:qn,min:0,max:1,unit:"fraction"}),minDecibels:t.number("Quietest level shown",{default:zn,min:-160,max:0,unit:"dB"}),maxDecibels:t.number("Loudest level shown",{default:Kn,min:-160,max:0,unit:"dB"})}}),c("WorkletAudioOptions",{title:"Browser sound",description:"How sound plays in a browser tab.",fields:{context:t.wiring("The browser's sound output"),module:t.wiring("The sound mixer the tab loads"),idlePumps:t.integer("Quiet frames before the mixer rests",{default:Ws,min:1,max:1e4,advanced:true}),voices:t.integer("Most sounds playing at once",{default:64,min:1,max:256}),sizes:t.wiring("Room set aside inside the mixer"),shared:t.boolean("Share memory with the mixer when the browser allows it",true,{advanced:true}),pumpWords:t.integer("Room for sound commands each frame",{default:Bs,min:1024,max:1<<24,unit:"count",advanced:true}),ringWords:t.integer("Room for sound waiting to play",{default:Gs,min:1024,max:1<<26,unit:"count",advanced:true}),reportQuanta:t.integer("How often the mixer reports back, in sound blocks",{default:Vs,min:1,max:1024,advanced:true}),moduleUrl:t.wiring("Where the tab loads the mixer from"),createNode:t.wiring("Makes the mixer's output node")}}),c("WebAudioOptions",{title:"Browser streams",description:"How long sounds and music stream in a browser tab.",fields:{createMediaElement:t.wiring("Makes the player each stream plays through")}})];function A(r,e){for(let n=0;n<e.length;n++){let o=e[n],i=r[o];Reflect.set(r,o,.5),Reflect.set(r,o,i);}}function wt(r,e,n,o,i,s,a,l,u,d,m){let p=n+a+m,h,f,y,_;if(p>0){let b=.5/Math.sqrt(p+1);_=.25/b,h=(l-d)*b,f=(u-i)*b,y=(o-s)*b;}else if(n>a&&n>m){let b=2*Math.sqrt(1+n-a-m);_=(l-d)/b,h=.25*b,f=(s+o)/b,y=(u+i)/b;}else if(a>m){let b=2*Math.sqrt(1+a-n-m);_=(u-i)/b,h=(s+o)/b,f=.25*b,y=(d+l)/b;}else {let b=2*Math.sqrt(1+m-n-a);_=(o-s)/b,h=(u+i)/b,f=(d+l)/b,y=.25*b;}r[e]=h,r[e+1]=f,r[e+2]=y,r[e+3]=_;}var Rt=class{constructor(e=0,n=0){this.x=e,this.y=n;}set(e,n){return this.x=e,this.y=n,this}copy(e){return this.x=e.x,this.y=e.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}add(e){return this.x+=e.x,this.y+=e.y,this}sub(e){return this.x-=e.x,this.y-=e.y,this}scale(e){return this.x*=e,this.y*=e,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}normalize(){let e=this.length();return e>1e-6&&this.scale(1/e),this}distanceTo(e){return Math.hypot(this.x-e.x,this.y-e.y)}lerp(e,n,o){return this.x=e.x+(n.x-e.x)*o,this.y=e.y+(n.y-e.y)*o,this}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}rotateAround(e,n){let o=Math.cos(n),i=Math.sin(n),s=this.x-e.x,a=this.y-e.y;return this.x=s*o-a*i+e.x,this.y=s*i+a*o+e.y,this}},Ot=class{constructor(e=0,n=0,o=0,i=1){this.x=e,this.y=n,this.z=o,this.w=i;}set(e,n,o,i){return this.x=e,this.y=n,this.z=o,this.w=i,this}copy(e){return this.set(e.x,e.y,e.z,e.w)}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}length(){return Math.sqrt(this.dot(this))}scale(e){return this.set(this.x*e,this.y*e,this.z*e,this.w*e)}lerp(e,n,o){return this.set(e.x+(n.x-e.x)*o,e.y+(n.y-e.y)*o,e.z+(n.z-e.z)*o,e.w+(n.w-e.w)*o)}applyMat4(e,n){let{x:o,y:i,z:s,w:a}=this;return this.set(e[n]*o+e[n+4]*i+e[n+8]*s+e[n+12]*a,e[n+1]*o+e[n+5]*i+e[n+9]*s+e[n+13]*a,e[n+2]*o+e[n+6]*i+e[n+10]*s+e[n+14]*a,e[n+3]*o+e[n+7]*i+e[n+11]*s+e[n+15]*a)}readFrom(e,n){return this.set(e[n],e[n+1],e[n+2],e[n+3])}writeTo(e,n){e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3]=this.w;}},R=class{constructor(e=0,n=0,o=0){this.x=e,this.y=n,this.z=o;}set(e,n,o){return this.x=e,this.y=n,this.z=o,this}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}scale(e){return this.x*=e,this.y*=e,this.z*=e,this}addScaled(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z}cross(e,n){let o=e.y*n.z-e.z*n.y,i=e.z*n.x-e.x*n.z,s=e.x*n.y-e.y*n.x;return this.x=o,this.y=i,this.z=s,this}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.lengthSq())}normalize(){let e=this.length();return e>1e-6&&this.scale(1/e),this}lerp(e,n,o){return this.x=e.x+(n.x-e.x)*o,this.y=e.y+(n.y-e.y)*o,this.z=e.z+(n.z-e.z)*o,this}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){let n=this.x-e.x,o=this.y-e.y,i=this.z-e.z;return n*n+o*o+i*i}negate(){return this.set(-this.x,-this.y,-this.z)}min(e){return this.set(Math.min(this.x,e.x),Math.min(this.y,e.y),Math.min(this.z,e.z))}max(e){return this.set(Math.max(this.x,e.x),Math.max(this.y,e.y),Math.max(this.z,e.z))}clamp(e,n){return this.set(Math.max(e.x,Math.min(n.x,this.x)),Math.max(e.y,Math.min(n.y,this.y)),Math.max(e.z,Math.min(n.z,this.z)))}clampLength(e,n){let o=this.length();return o<1e-6?this:this.scale(Math.max(e,Math.min(n,o))/o)}subVectors(e,n){return this.set(e.x-n.x,e.y-n.y,e.z-n.z)}addVectors(e,n){return this.set(e.x+n.x,e.y+n.y,e.z+n.z)}applyQuat(e){return e.rotate(this),this}applyMat4(e,n){let o=this.x,i=this.y,s=this.z,a=e[n+3]*o+e[n+7]*i+e[n+11]*s+e[n+15],l=Math.abs(a)>1e-6?1/a:1;return this.set((e[n]*o+e[n+4]*i+e[n+8]*s+e[n+12])*l,(e[n+1]*o+e[n+5]*i+e[n+9]*s+e[n+13])*l,(e[n+2]*o+e[n+6]*i+e[n+10]*s+e[n+14])*l)}transformDirection(e,n){let o=this.x,i=this.y,s=this.z;return this.set(e[n]*o+e[n+4]*i+e[n+8]*s,e[n+1]*o+e[n+5]*i+e[n+9]*s,e[n+2]*o+e[n+6]*i+e[n+10]*s),this.normalize()}projectOnVector(e){let n=e.x*e.x+e.y*e.y+e.z*e.z;if(n<1e-6)return this.set(0,0,0);let o=this.dot(e)/n;return this.set(e.x*o,e.y*o,e.z*o)}projectOnPlane(e){let n=this.dot(e);return this.set(this.x-e.x*n,this.y-e.y*n,this.z-e.z*n)}reflect(e){let n=2*this.dot(e);return this.set(this.x-e.x*n,this.y-e.y*n,this.z-e.z*n)}angleTo(e){let n=Math.sqrt(this.lengthSq()*(e.x*e.x+e.y*e.y+e.z*e.z));return n<1e-6?Math.PI/2:Math.acos(Math.max(-1,Math.min(1,this.dot(e)/n)))}setFromSpherical(e,n,o){let i=Math.sin(n)*e;return this.set(i*Math.sin(o),Math.cos(n)*e,i*Math.cos(o))}setFromMatrixColumn(e,n,o){return this.readFrom(e,n+o*4)}equals(e,n=0){return Math.abs(this.x-e.x)<=n&&Math.abs(this.y-e.y)<=n&&Math.abs(this.z-e.z)<=n}readFrom(e,n){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this}writeTo(e,n){e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z;}},Le=class{constructor(e=0,n=0,o=0,i=1){this.x=e,this.y=n,this.z=o,this.w=i;}set(e,n,o,i){return this.x=e,this.y=n,this.z=o,this.w=i,this}identity(){return this.set(0,0,0,1)}copy(e){return this.set(e.x,e.y,e.z,e.w)}setAxisAngle(e,n){let o=n*.5,i=Math.sin(o);return this.set(e.x*i,e.y*i,e.z*i,Math.cos(o))}setEuler(e,n,o){let i=Math.cos(e*.5),s=Math.sin(e*.5),a=Math.cos(n*.5),l=Math.sin(n*.5),u=Math.cos(o*.5),d=Math.sin(o*.5);return this.set(s*a*u+i*l*d,i*l*u-s*a*d,i*a*d+s*l*u,i*a*u-s*l*d)}multiply(e,n){return this.set(e.w*n.x+e.x*n.w+e.y*n.z-e.z*n.y,e.w*n.y-e.x*n.z+e.y*n.w+e.z*n.x,e.w*n.z+e.x*n.y-e.y*n.x+e.z*n.w,e.w*n.w-e.x*n.x-e.y*n.y-e.z*n.z)}normalize(){let e=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);if(e<1e-6)return this.identity();let n=1/e;return this.set(this.x*n,this.y*n,this.z*n,this.w*n)}rotate(e){let{x:n,y:o,z:i,w:s}=this,a=s*e.x+o*e.z-i*e.y,l=s*e.y+i*e.x-n*e.z,u=s*e.z+n*e.y-o*e.x,d=-n*e.x-o*e.y-i*e.z;return e.set(a*s+d*-n+l*-i-u*-o,l*s+d*-o+u*-n-a*-i,u*s+d*-i+a*-o-l*-n)}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}conjugate(){return this.set(-this.x,-this.y,-this.z,this.w)}invert(){let e=this.dot(this);if(e<1e-6)return this.identity();let n=1/e;return this.set(-this.x*n,-this.y*n,-this.z*n,this.w*n)}premultiply(e){return this.multiply(e,this)}slerp(e,n,o){let i=n.x,s=n.y,a=n.z,l=n.w,u=e.x*i+e.y*s+e.z*a+e.w*l;u<0&&(u=-u,i=-i,s=-s,a=-a,l=-l);let d=1-o,m=o;if(u<=.9995){let p=Math.acos(u),h=Math.sin(p);d=Math.sin((1-o)*p)/h,m=Math.sin(o*p)/h;}return this.set(e.x*d+i*m,e.y*d+s*m,e.z*d+a*m,e.w*d+l*m),this.normalize()}rotateTowards(e,n){let o=this.angleTo(e);return o<1e-6?this:this.slerp(this,e,Math.min(1,n/o))}angleTo(e){return 2*Math.acos(Math.min(1,Math.abs(this.dot(e))))}setFromUnitVectors(e,n){let o=e.x*n.x+e.y*n.y+e.z*n.z+1;return o<1e-6?(o=0,Math.abs(e.x)>Math.abs(e.z)?this.set(-e.y,e.x,0,o).normalize():this.set(0,-e.z,e.y,o).normalize()):this.set(e.y*n.z-e.z*n.y,e.z*n.x-e.x*n.z,e.x*n.y-e.y*n.x,o).normalize()}setFromRotationMatrix(e,n){return wt(W,0,e[n],e[n+1],e[n+2],e[n+4],e[n+5],e[n+6],e[n+8],e[n+9],e[n+10]),this.set(W[0],W[1],W[2],W[3])}lookRotation(e,n,o,i=0,s=1,a=0){let l=-e,u=-n,d=-o,m=Math.sqrt(l*l+u*u+d*d);if(m<1e-6)return this.identity();l/=m,u/=m,d/=m;let p=s*d-a*u,h=a*l-i*d,f=i*u-s*l;m=Math.sqrt(p*p+h*h+f*f),m<1e-6&&(p=1,h=0,f=0,m=1),p/=m,h/=m,f/=m;let y=u*f-d*h,_=d*p-l*f,b=l*h-u*p;return wt(W,0,p,h,f,y,_,b,l,u,d),this.set(W[0],W[1],W[2],W[3])}toEuler(e){let{x:n,y:o,z:i,w:s}=this,a=1-2*(o*o+i*i),l=2*(n*o-s*i),u=2*(n*i+s*o),d=1-2*(n*n+i*i),m=2*(o*i-s*n),p=2*(o*i+s*n),h=1-2*(n*n+o*o),f=Math.asin(Math.max(-1,Math.min(1,u)));return Math.abs(u)<1-1e-6?e.set(Math.atan2(-m,h),f,Math.atan2(-l,a)):e.set(Math.atan2(p,d),f,0)}readFrom(e,n){return this.set(e[n],e[n+1],e[n+2],e[n+3])}writeTo(e,n){e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3]=this.w;}},W=new Float64Array(4);A(new Rt,["x","y"]);A(new Ot,["x","y","z","w"]);A(new R,["x","y","z"]);A(new Le,["x","y","z","w"]);var fe=class{constructor(){this.kind="ball";this.params=new R(.5,0,0);this.origin=new R;this.rotation=new Float32Array([0,0,0,1]);this.direction=new R(0,-1,0);this.maxDistance=Number.MAX_VALUE;this.includeSensors=false;this.excludeBody=-1;}ball(e){return this.kind="ball",this.params.set(e,0,0),this}cuboid(e,n,o){return this.kind="cuboid",this.params.set(e,n,o),this}capsule(e,n){return this.kind="capsule",this.params.set(e,n,0),this}cylinder(e,n){return this.kind="cylinder",this.params.set(e,n,0),this}};A(new fe,["maxDistance"]);var Qn=4,Zn=1,Jn=1,er=64,tr=16,nr=16;var Me=class{constructor(){this.origin=new R;this.direction=new R(0,-1,0);this.maxDistance=Number.MAX_VALUE;this.solid=true;this.includeSensors=false;this.excludeCollider=-1;}set(e,n,o,i,s,a,l){return this.origin.set(e,n,o),this.direction.set(i,s,a),this.maxDistance=l,this}},_e=class{constructor(){this.hit=false;this.collider=-1;this.distance=0;this.pointX=0;this.pointY=0;this.pointZ=0;this.normalX=0;this.normalY=0;this.normalZ=0;}},De=class{constructor(){this.grounded=false;this.x=0;this.y=0;this.z=0;}};A(new Me,["maxDistance"]);A(new _e,["distance","pointX","pointY","pointZ","normalX","normalY","normalZ"]);A(new De,["x","y","z"]);var qs=new Float64Array(1);new Uint32Array(qs.buffer);var sr=.22;var cr=.0062,ur=3.4;var dr=60,mr=1;var F=1e6,T=Math.PI,Pe=r=>t.number("How wide the camera sees",{default:r,min:5,max:170,unit:"deg"}),kt=(r,e)=>t.number(`Extra width when ${e}, for a sense of speed`,{default:r,min:0,max:60,unit:"deg"}),U=(r,e,n)=>t.number(r,{default:e,min:0,max:100,unit:"none",group:n,advanced:true}),ne=(r,e)=>t.number(r,{default:e,min:-T/2,max:T/2,unit:"rad"}),$s=()=>t.number("Picture shape, width over height",{default:mr,min:.1,max:10,unit:"none",advanced:true}),Fe=r=>t.wiring(r),Ct=r=>t.text("Name the movement controls are listed under",r,64,{advanced:true}),pr=[c("CameraBoomOptions",{title:"Camera bump",description:"Keeps a following camera from going through walls.",fields:{radius:t.number("Size of the camera's bump",{default:sr,min:.01,max:5,unit:"m"}),margin:t.number("Gap kept from walls",{default:.06,min:0,max:5,unit:"m"})}}),c("LookOptions",{title:"Looking around",description:"How dragging, the mouse and a gamepad turn the camera.",group:"Looking",fields:{lookSensitivity:t.number("How far the camera turns for each drag",{default:cr,min:1e-4,max:.1,unit:"rad",scale:"log"}),gamepadLookSpeed:t.number("How fast a gamepad stick turns the camera",{default:ur,min:.1,max:20,unit:"rad/s"}),invertY:t.boolean("Push up to look down",false)}}),c("FollowCameraOptions",{title:"Over the shoulder",description:"A camera behind and over the shoulder of a character.",extends:["LookOptions","CameraBoomOptions"],fields:{distance:t.number("Distance behind the character",{default:4.2,min:.5,max:100,unit:"m"}),height:t.number("Height of the camera's aim",{default:1.55,min:0,max:20,unit:"m"}),crouchHeight:t.number("Height of the aim while crouching",{default:1.05,min:0,max:20,unit:"m"}),shoulder:t.number("How far to the side the camera sits",{default:.55,min:0,max:5,unit:"m"}),shoulderSide:t.choice("Which shoulder",[1,-1],1,{labels:{1:"Right",[-1]:"Left"}}),pitch:ne("Starting tilt, below 0 looks down",-0.3),minPitch:ne("Furthest the camera looks down",-1.25),maxPitch:ne("Furthest the camera looks up",.95),followSharpness:U("How tightly the camera follows",22,"Smoothing"),verticalSharpness:U("How tightly it follows jumps and falls",8,"Smoothing"),shoulderSharpness:U("How quickly it swaps shoulders",9,"Smoothing"),recoverSharpness:U("How quickly it pulls back out after a wall",4.5,"Smoothing"),autoRecenter:t.boolean("Swing back behind the character after looking around",true,{group:"Recentre"}),recenterDelay:t.number("Wait before swinging back",{default:1.5,min:0,max:10,unit:"s",group:"Recentre"}),recenterSharpness:U("How quickly it swings back",1.8,"Recentre"),fov:Pe(62),sprintFovKick:kt(8,"sprinting"),fovSharpness:U("How quickly the view widens and narrows",6),lockSoftZone:t.number("Room a locked-on target can move before the camera turns",{default:.12,min:0,max:1,unit:"fraction",group:"Lock on"}),lockSharpness:U("How quickly it turns to a locked-on target",7,"Lock on"),lockMaxDistance:t.number("Furthest a target can be locked on to",{default:30,min:1,max:1e3,unit:"m",group:"Lock on"}),lockHeight:t.number("Height on the target the camera aims at",{default:1.2,min:0,max:20,unit:"m",group:"Lock on"}),lens:t.wiring("Depth of field and other lens effects")}}),c("FirstPersonViewOptions",{title:"Eyes view",description:"A camera that sees through the character's eyes.",extends:["LookOptions"],fields:{eyeHeight:t.number("Eye height",{default:1.62,min:.1,max:20,unit:"m"}),crouchEyeHeight:t.number("Eye height while crouching",{default:1.02,min:.1,max:20,unit:"m"}),headBob:t.boolean("The view bobs with each step",true,{group:"Steps"}),bobAmplitude:t.number("How much the view bobs",{default:.04,min:0,max:.5,unit:"m",group:"Steps"}),bobStride:t.number("Distance of one step",{default:2.1,min:.1,max:10,unit:"m",group:"Steps"}),landDip:t.number("How far the view dips on landing",{default:.12,min:0,max:1,unit:"m",group:"Steps"}),minPitch:ne("Furthest the view looks down",-1.45),maxPitch:ne("Furthest the view looks up",1.45),fov:Pe(74),sprintFovKick:kt(6,"sprinting"),fovSharpness:U("How quickly the view widens and narrows",6),lens:t.wiring("Depth of field and other lens effects")}}),c("ChaseCameraOptions",{title:"Chase camera",description:"A camera behind a car, boat or bike.",extends:["LookOptions","CameraBoomOptions"],fields:{distance:t.number("Distance behind the vehicle",{default:6,min:.5,max:100,unit:"m"}),lookHeight:t.number("Height of the camera's aim",{default:1.6,min:0,max:20,unit:"m"}),pitch:ne("Tilt, below 0 looks down",-0.22),speedForEffects:t.number("Speed where the speed effects are strongest",{default:22,min:1,max:200,unit:"m/s",group:"Speed"}),distanceGain:t.number("How much the camera pulls back at speed",{default:.18,min:0,max:2,unit:"fraction",group:"Speed"}),fov:Pe(62),speedFovKick:kt(10,"going fast"),followSharpness:U("How tightly the camera follows",14,"Smoothing"),yawSharpness:U("How quickly it swings round in turns",3.5,"Smoothing"),lookReturnDelay:t.number("Wait before swinging back after looking around",{default:1.2,min:0,max:10,unit:"s"}),lookReturnSharpness:U("How quickly it swings back",3,"Smoothing"),recoverSharpness:U("How quickly it pulls back out after a wall",3.5,"Smoothing"),lens:t.wiring("Depth of field and other lens effects")}}),c("ControlViewOptions",{title:"Camera view",description:"The view a camera control moves.",fields:{fov:Pe(dr),aspect:$s()}}),c("OrbitControlsOptions",{title:"Orbit",description:"Drag to circle round a point, pinch to zoom.",extends:["ControlViewOptions"],fields:{target:t.vector("The point the camera circles",{default:[0,0,0],min:-F,max:F,unit:"m"}),enableDamping:t.boolean("Keep gliding after letting go",false),dampingFactor:t.number("How quickly the glide stops",{default:.05,min:0,max:1,unit:"fraction"}),minDistance:t.number("Closest it can zoom in",{default:0,min:0,max:F,unit:"m",group:"Limits"}),maxDistance:t.number("Furthest it can zoom out",{default:F,min:0,max:F,unit:"m",group:"Limits"}),minPolarAngle:t.number("Highest it can look down from",{default:0,min:0,max:T,unit:"rad",group:"Limits"}),maxPolarAngle:t.number("Lowest it can look up from",{default:T,min:0,max:T,unit:"rad",group:"Limits"}),minAzimuthAngle:t.number("Furthest it circles one way",{default:-2*T,min:-2*T,max:2*T,unit:"rad",group:"Limits"}),maxAzimuthAngle:t.number("Furthest it circles the other way",{default:2*T,min:-2*T,max:2*T,unit:"rad",group:"Limits"}),autoRotate:t.boolean("Circle on its own",false),autoRotateSpeed:t.number("How fast it circles on its own",{default:2,min:-60,max:60,unit:"none"}),screenSpacePanning:t.boolean("Panning moves across the screen rather than along the ground",true),zoomToCursor:t.boolean("Zoom towards the pointer",false),orthographicHeight:t.number("Height shown in a flat view, 0 to keep it",{default:0,min:0,max:F,unit:"m"})}}),c("FirstPersonControlsOptions",{title:"Walk around",description:"Look by dragging and move with keys, for exploring a scene.",extends:["ControlViewOptions"],fields:{lookSpeed:t.number("How fast dragging turns the view",{default:Math.PI,min:.01,max:20,unit:"rad"}),movementSpeed:t.number("Walking speed",{default:5,min:0,max:1e3,unit:"m/s"}),lookMode:t.choice("How looking works",["drag","pointer","none"],"drag",{labels:{drag:"Drag",pointer:"Follow the pointer",none:"Off"}}),lookVertical:t.boolean("Can look up and down",true),maxPitch:t.number("Furthest it looks up or down",{default:85*Math.PI/180,min:0,max:T/2,unit:"rad"}),keys:Fe("The keys that move"),actionPrefix:Ct("firstPerson")}}),c("PointerLockControlsOptions",{title:"Mouse look",description:"The mouse turns the view, as in a desktop shooter.",fields:{pointerSpeed:t.number("How fast the mouse turns the view",{default:1,min:.01,max:20,unit:"times"}),minPolarAngle:t.number("Furthest it looks up",{default:0,min:0,max:T,unit:"rad"}),maxPolarAngle:t.number("Furthest it looks down",{default:T,min:0,max:T,unit:"rad"}),movementSpeed:t.number("Walking speed, 0 to only look",{default:0,min:0,max:1e3,unit:"m/s"}),keys:Fe("The keys that move"),actionPrefix:Ct("pointerLock")}}),c("FlyControlsOptions",{title:"Fly around",description:"Fly freely through a scene.",extends:["ControlViewOptions"],fields:{movementSpeed:t.number("Flying speed",{default:5,min:0,max:1e4,unit:"m/s"}),rollSpeed:t.number("How fast it rolls",{default:.8,min:0,max:20,unit:"rad/s"}),dragToLook:t.boolean("Only turn while dragging",true),dragSpeed:t.number("How fast dragging turns the view",{default:Math.PI,min:.01,max:20,unit:"rad"}),keys:Fe("The keys that move"),rotationKeys:Fe("The keys that turn and roll"),actionPrefix:Ct("fly")}}),c("TrackballControlsOptions",{title:"Trackball",description:"Spin a scene freely in any direction.",extends:["ControlViewOptions"],fields:{target:t.vector("The point the camera spins round",{default:[0,0,0],min:-F,max:F,unit:"m"}),rotateSpeed:t.number("How fast it spins",{default:1,min:0,max:20,unit:"times"}),zoomSpeed:t.number("How fast it zooms",{default:1.2,min:0,max:20,unit:"times"}),panSpeed:t.number("How fast it pans",{default:.3,min:0,max:20,unit:"times"}),staticMoving:t.boolean("Stop as soon as the finger lifts",false),dynamicDampingFactor:t.number("How quickly the spin slows after letting go",{default:.2,min:0,max:1,unit:"fraction"}),minDistance:t.number("Closest it can zoom in",{default:0,min:0,max:F,unit:"m"}),maxDistance:t.number("Furthest it can zoom out",{default:F,min:0,max:F,unit:"m"})}}),c("DragControlsOptions",{title:"Drag things",description:"Pick up and drag things in the scene with a finger.",fields:{layers:t.integer("Which things can be dragged",{default:4294967295,min:0,max:4294967295,unit:"none",advanced:true}),far:t.number("Furthest a thing can be picked, 0 for no limit",{default:0,min:0,max:F,unit:"m"})}}),c("GyroLookOptions",{title:"Look by tilting",description:"Turning the phone turns the view.",fields:{alphaOffset:t.number("Turn added to the phone's heading",{default:0,min:-T,max:T,unit:"rad"}),smoothing:t.number("How much shaky hands are smoothed",{default:0,min:0,max:1,unit:"fraction"}),screenOrientation:t.choice("How the screen is turned",[0,90,180,270],0,{labels:{0:"Upright",90:"Turned left",180:"Upside down",270:"Turned right"}})}})];var hr=.08,fr=.2,_r=.25,yr=Math.PI/6,br=.5;var Qs=63,gr=()=>t.choice("Which way the model faces when it was made",[1,-1],1,{labels:{1:"Forward",[-1]:"Backward"},advanced:true}),xr=[c("CharacterMotorOptions",{title:"Character movement",description:"How a character walks, runs, jumps, climbs and turns.",fields:{radius:t.number("Body width from the middle",{default:.35,min:.05,max:5,unit:"m",group:"Body"}),height:t.number("Standing height",{default:1.8,min:.1,max:20,unit:"m",group:"Body"}),crouchHeight:t.number("Crouching height",{default:1.15,min:.1,max:20,unit:"m",group:"Body"}),walkSpeed:t.number("Walking speed",{default:2,min:0,max:50,unit:"m/s",group:"Speed"}),runSpeed:t.number("Running speed",{default:5.4,min:0,max:50,unit:"m/s",group:"Speed"}),sprintSpeed:t.number("Sprinting speed",{default:8,min:0,max:100,unit:"m/s",group:"Speed"}),crouchSpeed:t.number("Crouching speed",{default:1.9,min:0,max:50,unit:"m/s",group:"Speed"}),groundAcceleration:t.number("How quickly it speeds up on the ground",{default:45,min:0,max:500,unit:"m/s2",group:"Speed"}),groundDeceleration:t.number("How quickly it stops on the ground",{default:60,min:0,max:500,unit:"m/s2",group:"Speed"}),airAcceleration:t.number("How much it can steer in the air",{default:14,min:0,max:500,unit:"m/s2",group:"Jumping"}),jumpHeight:t.number("How high it jumps",{default:1.3,min:0,max:50,unit:"m",group:"Jumping"}),gravity:t.number("How hard it falls",{default:24,min:0,max:200,unit:"m/s2",group:"Jumping"}),fallGravityScale:t.number("Extra pull on the way down, for snappy jumps",{default:1.55,min:.1,max:10,unit:"times",group:"Jumping"}),jumpCutGravityScale:t.number("Extra pull when the jump button is let go early",{default:2.8,min:.1,max:10,unit:"times",group:"Jumping"}),maxFallSpeed:t.number("Fastest it can fall",{default:42,min:1,max:500,unit:"m/s",group:"Jumping"}),coyoteSeconds:t.number("Grace time to jump after walking off a ledge",{default:.11,min:0,max:1,unit:"s",group:"Jumping"}),jumpBufferSeconds:t.number("How early a jump press is remembered before landing",{default:.13,min:0,max:1,unit:"s",group:"Jumping"}),maxSlopeDegrees:t.number("Steepest slope it can walk up",{default:46,min:0,max:89,unit:"deg",group:"Ground"}),slideSlopeDegrees:t.number("Slope where it starts sliding down",{default:50,min:0,max:90,unit:"deg",group:"Ground"}),stepHeight:t.number("Tallest step it climbs without jumping",{default:.35,min:0,max:5,unit:"m",group:"Ground"}),snapDistance:t.number("How far it sticks to the ground going downhill",{default:.3,min:0,max:5,unit:"m",group:"Ground"}),skin:t.number("Gap kept from walls so it never sticks",{default:.02,min:.001,max:.5,unit:"m",group:"Ground",advanced:true}),turnSharpness:t.number("How quickly it turns to face where it moves",{default:16,min:0,max:100,unit:"none",group:"Turning"}),maxTurnSpeed:t.number("Fastest it can turn",{default:14,min:0,max:100,unit:"rad/s",group:"Turning"}),crouchSharpness:t.number("How quickly it crouches and stands",{default:14,min:0,max:100,unit:"none",group:"Body"}),groundStickSpeed:t.number("Downward push that keeps it on moving floors",{default:2,min:0,max:50,unit:"m/s",group:"Ground",advanced:true}),modelForward:gr()}}),c("CharacterAnimatorOptions",{title:"Character animation",description:"How a character's walk, run, crouch and jump animations blend with its movement.",fields:{locomotion:t.wiring("The blend of walk and run animations"),directional:t.boolean("Steps sideways and backwards instead of always turning to face the way it goes",false),crouch:t.wiring("The blend of crouching animations"),air:t.wiring("The animation played in the air"),blendSharpness:t.number("How quickly animations blend into each other",{default:12,min:0,max:100,unit:"none"}),footIk:t.settings("Feet that land on the ground instead of floating or sinking","FootIkOptions",{group:"Feet"}),rootMotion:t.wiring("Movement taken from the animation itself"),modelForward:gr()}}),c("FootContactOptions",{title:"Foot contact",description:"When a foot is planted, read from the animation.",fields:{footDown:t.wiring("The animation moment a foot lands"),footUp:t.wiring("The animation moment a foot lifts"),actions:t.wiring("Animations that carry foot moments"),curves:t.wiring("Animation curves that say when a foot is down"),tilt:t.wiring("The joint that tilts the foot to the slope")}}),c("FootIkOptions",{title:"Feet on the ground",description:"Feet that land on stairs and slopes instead of floating or sinking.",fields:{left:t.wiring("The left leg"),right:t.wiring("The right leg"),physics:t.wiring("The world the feet test the ground against"),spacing:t.number("Distance between the feet",{default:.12,min:0,max:2,unit:"m"}),ankleHeight:t.number("Height of the ankle above the sole",{default:.08,min:0,max:1,unit:"m"}),reach:t.number("Furthest a foot stretches to find the ground",{default:.5,min:0,max:5,unit:"m"}),leftContact:t.settings("When the left foot is down","FootContactOptions",{advanced:true}),rightContact:t.settings("When the right foot is down","FootContactOptions",{advanced:true}),events:t.wiring("Reads foot moments from the animations"),feet:t.wiring("The foot bones"),lock:t.boolean("Planted feet stay still instead of sliding",true),weightSeconds:t.number("How quickly a landing foot takes weight",{default:hr,min:0,max:2,unit:"s"}),releaseSeconds:t.number("How quickly a lifting foot lets go",{default:fr,min:0,max:2,unit:"s"}),maxSlide:t.number("Furthest a planted foot is dragged before it lets go",{default:_r,min:0,max:5,unit:"m"}),maxTilt:t.number("Most a foot tilts to match a slope",{default:yr,min:0,max:Math.PI/2,unit:"rad"}),plantThreshold:t.number("How firmly a foot must be down to count as planted",{default:br,min:0,max:1,unit:"fraction"})}}),c("AvatarRosterOptions",{title:"Avatars",description:"Shows the player and their friends as their own avatars.",fields:{rig:t.choice("Kind of avatar",["humanoid","head","sprite"],"humanoid",{labels:{humanoid:"Full body",head:"Head only",sprite:"Flat picture"}}),maxFriends:t.integer("Most friends shown",{default:8,min:0,max:Qs}),models:t.wiring("A stand-in model for each kind of avatar")}}),c("FaceSessionOptions",{title:"Face tracking",description:"Follows the player's face with the phone camera, with their permission.",fields:{facing:t.choice("Which camera",["front","back"],"front",{labels:{front:"Selfie",back:"Back"}}),recording:t.boolean("Also ask to record what the camera sees",false),smoothingSeconds:t.number("How much face movement is smoothed",{default:.06,min:0,max:1,unit:"s"})}})];var Sr=4294967295,ra=293,oa=7999,vr=[c("LoopOptions",{title:"Timing",description:"How often the world moves forward and how it catches up after a slow frame.",fields:{fixedHz:t.integer("Simulation steps every second",{default:60,min:10,max:240,unit:"Hz",heavy:true}),maxSubsteps:t.integer("Most steps taken in one frame to catch up",{default:5,min:1,max:16,advanced:true}),maxFrameDeltaMs:t.number("Longest pause the world catches up on before it skips ahead",{default:250,min:16,max:2e3,unit:"ms",advanced:true})}}),c("GameOptions",{title:"Game",description:"The whole Interactive: its world, timing, physics, nature and limits.",extends:["LoopOptions"],fields:{backend:t.wiring("Where the world draws, simulates and plays sound"),seed:t.integer("Starting point for everything random, so every play repeats exactly",{default:0,min:0,max:Sr,unit:"none"}),capacity:t.integer("Most things alive at once",{default:4096,min:64,max:1048575,heavy:true,advanced:true}),surface:t.wiring("The screen the game draws into"),ui:t.wiring("The host that shows the game's on-screen interface"),physics:t.settings("How things move, collide and fall","PhysicsOptions",{group:"Physics"}),animation:t.settings("How many animations can play at once","AnimationOptions",{group:"Animation"}),gestures:t.settings("How swipes and long presses are recognised","GestureOptions",{group:"Touch"}),scratch:t.wiring("Working memory set aside for maths each frame"),maxVoices:t.integer("Most sounds playing at once",{default:64,min:1,max:256,group:"Sound"}),maxHudSlots:t.integer("Most on-screen readouts shown at once",{default:64,min:1,max:512,advanced:true}),nature:t.settings("Temperature, air and gravity for burning, melting and mixing","NatureOptions",{group:"Nature"}),assets:t.wiring("Where the game fetches its pictures, models and sounds ahead of time")}}),c("AnimationOptions",{title:"Animation",description:"Room for tweens, clips and animated values.",fields:{maxTweens:t.integer("Most tweens running at once",{default:1024,min:16,max:16384,advanced:true}),maxClipPlayers:t.integer("Most animation clips playing at once",{default:256,min:8,max:4096,advanced:true}),maxValueSlots:t.integer("Most animated values at once",{default:256,min:8,max:4096,advanced:true})}}),c("GestureOptions",{title:"Gestures",description:"When a touch counts as a swipe or a long press.",fields:{swipeMinDistance:t.number("Shortest movement that counts as a swipe, as a share of the screen",{default:.04,min:.005,max:.5,unit:"fraction"}),swipeMaxDurationMs:t.number("Longest a swipe can take",{default:800,min:50,max:3e3,unit:"ms"}),longPressMs:t.number("How long a finger stays down before it counts as a long press",{default:500,min:100,max:3e3,unit:"ms"})}}),c("DomInputOptions",{title:"Browser input",description:"Which browser inputs reach the game.",fields:{wheel:t.boolean("Read the mouse wheel and trackpad scroll",true),preventWheel:t.boolean("Stop the page from scrolling while the wheel moves the game",false),orientation:t.boolean("Read the device tilt",false),preventContextMenu:t.boolean("Stop the right-click menu over the game",false)}}),c("EngineGraphicsOptions",{title:"Picture",description:"Picture features chosen when the game starts.",fields:{pointShadows:t.boolean("Lamps and point lights cast shadows",true,{heavy:true})}}),c("PlatformBackendOptions",{title:"Device",description:"How the game starts on each device.",fields:{engine:t.wiring("Device start-up choices"),prepared:t.wiring("The fallback used on devices without native drawing"),assets:t.wiring("The Production's packed files")}}),c("NatureOptions",{title:"Nature",description:"The temperature, air pressure and gravity that burning, melting and mixing follow.",fields:{tickHz:t.integer("Nature updates every second",{default:30,min:1,max:240,unit:"Hz",heavy:true}),ambientK:t.number("Air temperature",{default:ra,min:1,max:oa,unit:"K"}),pressureAtm:t.number("Air pressure",{default:1,min:0,max:50,unit:"atm"}),gravity:t.number("Gravity for liquids, powders and gases, where 1 is Earth",{default:1,min:0,max:20,unit:"times"}),conduction:t.number("How fast heat spreads, where 1 is natural",{default:1,min:0,max:64,unit:"times"}),rateShift:t.number("Speeds up or slows every reaction, where 0 is natural",{default:0,min:-16,max:16,unit:"none"}),radiation:t.number("How fast hot things glow their heat away, where 1 is natural",{default:1,min:0,max:64,unit:"times"}),atmosphere:t.choice("The air mix things burn and breathe in",["earth","mars"],"earth")}}),c("RegionOptions",{title:"Nature region",description:"A box of cells where materials burn, melt, flow and react.",fields:{width:t.integer("Cells across",{default:64,min:1,max:1024,unit:"cells",heavy:true}),height:t.integer("Cells up",{default:64,min:1,max:1024,unit:"cells",heavy:true}),depth:t.integer("Cells deep, 1 for a flat region",{default:1,min:1,max:256,unit:"cells",heavy:true}),seed:t.integer("Starting point for randomness in the region",{default:0,min:0,max:Sr,unit:"none"}),open:t.boolean("Edges let material and heat out instead of acting as walls",false)}})];var ia=4294967295,Ue=10,Tr=[c("SeaOptions",{title:"Sea",description:"Open water that boats float on and waves roll across.",fields:{windDirection:t.number("Where the wind blows the waves from",{default:0,min:-Math.PI,max:Math.PI,unit:"rad"}),seed:t.integer("Starting point for the wave pattern",{default:1,min:0,max:ia,unit:"none"})}}),c("PuddleOptions",{title:"Puddles",description:"Shallow water that pools, runs downhill and splashes.",fields:{origin:t.vector("Corner of the puddle area on the ground",{default:[0,0],min:-1e5,max:1e5,unit:"m",axes:["X","Z"]}),cell:t.number("Size of each water cell",{default:.25,min:.01,max:10,unit:"m",heavy:true}),width:t.integer("Cells across",{default:128,min:1,max:2048,unit:"cells",heavy:true}),height:t.integer("Cells deep",{default:128,min:1,max:2048,unit:"cells",heavy:true}),maxDepth:t.number("Deepest the water can pool",{default:.5,min:.01,max:10,unit:"m"})}}),c("RippleOptions",{title:"Ripples",description:"Wakes and ripples that follow a boat or the camera across the water.",fields:{size:t.choice("Cells across the ripple area",[16,32,64,128,256],128,{heavy:true}),cell:t.number("Size of each ripple cell",{default:.25,min:.01,max:10,unit:"m"}),speed:t.number("How fast ripples travel",{default:1.5,min:.1,max:20,unit:"m/s"})}}),c("CraftOptions",{title:"Craft",description:"Anything that floats or flies: its hull, weight and whether it starts running.",fields:{collider:t.wiring("The collision shape the craft uses instead of its own box"),body:t.wiring("Hull size, weight and wings"),running:t.boolean("Starts with its motor on",false)}}),c("PresetOptions",{title:"Craft handling",description:"How strongly a craft pushes, drags, turns and lifts.",extends:["CraftOptions"],fields:{mode:t.choice("Easy handling or true to life",["arcade","sim"],"arcade",{labels:{arcade:"Easy",sim:"True to life"}}),thrust:t.number("Push of the motor, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"}),drag:t.number("Resistance of air and water, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"}),response:t.number("How quickly controls take effect, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"}),lift:t.number("Lift of wings and floats, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"})}}),c("BoatOptions",{title:"Boat",description:"A canoe, speedboat, ferry, cargo ship or sailboat.",extends:["PresetOptions"],fields:{preset:t.choice("Kind of boat",["canoe","speedboat","ferry","cargo_ship","sailboat"],"speedboat")}}),c("AircraftOptions",{title:"Aircraft",description:"A light plane, jet, glider or tiltrotor.",extends:["PresetOptions"],fields:{preset:t.choice("Kind of aircraft",["light_plane","jet","glider","tiltrotor"],"light_plane")}}),c("HelicopterOptions",{title:"Hovering craft",description:"A helicopter, quadcopter or blimp.",extends:["PresetOptions"],fields:{preset:t.choice("Kind of hovering craft",["helicopter","quadcopter","blimp"],"helicopter")}}),c("CraftInputOptions",{title:"Craft controls",description:"How a person steers a craft.",fields:{steering:t.choice("Steer with an on-screen stick or by tilting the phone",["stick","tilt"],"stick",{labels:{stick:"Stick",tilt:"Tilt"}}),invertPitch:t.boolean("Pull back to climb",false)}}),c("TiltOptions",{title:"Tilt steering",description:"How tilting the phone steers.",fields:{rangeDegrees:t.number("Tilt for full steering",{default:30,min:5,max:90,unit:"deg"}),deadzoneDegrees:t.number("Small tilts ignored around rest",{default:2,min:0,max:20,unit:"deg"}),smoothing:t.number("How much shaky hands are smoothed out",{default:.25,min:0,max:1,unit:"fraction"})}})];var sa=4294967295,k=1e6,Ir=["camera","tumble"],wr={camera:"Face the camera",tumble:"Tumble freely"},Rr=[c("ShakeOptions",{title:"Camera shake",description:"The jolt of a hit, an explosion or a landing.",fields:{maxOffset:t.number("Furthest the camera jumps",{default:.35,min:0,max:5,unit:"m"}),maxRoll:t.number("Most the camera tilts",{default:.06,min:0,max:1,unit:"rad"}),decayPerSecond:t.number("How fast the shake settles",{default:1.6,min:.1,max:20,unit:"1/s"}),frequency:t.number("How fast it rattles",{default:22,min:1,max:120,unit:"Hz"}),seed:t.integer("Starting point for the shake pattern",{default:0,min:0,max:sa,unit:"none"})}}),c("SpringOptions",{title:"Bounce",description:"A springy pop, wobble or squash.",fields:{stiffness:t.number("How snappy the spring is",{default:320,min:1,max:5e3,unit:"none",scale:"log"}),damping:t.number("How quickly the bounce settles",{default:16,min:0,max:200,unit:"none"})}}),c("CameraRigOptions",{title:"Follow camera",description:"A camera that keeps one or more players in view.",fields:{smoothSeconds:t.number("How softly the camera catches up",{default:.22,min:1e-4,max:5,unit:"s"}),offset:t.vector("Where the camera sits from the players",{default:[0,0,0],min:-1e3,max:1e3,unit:"m"}),deadZone:t.vector("How far players move before the camera follows",{default:[0,0,0],min:0,max:100,unit:"m"}),lookAheadSeconds:t.number("How far ahead of movement the camera leads",{default:0,min:0,max:5,unit:"s"}),min:t.vector("Lowest corner the camera may move to",{default:[-k,-k,-k],min:-k,max:k,unit:"m",group:"Bounds"}),max:t.vector("Highest corner the camera may move to",{default:[k,k,k],min:-k,max:k,unit:"m",group:"Bounds"}),fovDegrees:t.number("How wide the camera sees",{default:60,min:5,max:170,unit:"deg"}),aspect:t.number("Picture shape, width over height",{default:1,min:.1,max:10,unit:"none"}),padding:t.number("Room kept around the players",{default:0,min:0,max:100,unit:"m"})}}),c("ParticleOptions",{title:"Particles",description:"Sparks, confetti, dust and debris.",fields:{capacity:t.integer("Most particles at once",{default:256,min:1,max:65536,heavy:true}),gravity:t.vector("Pull of gravity on each particle",{default:[0,-9.81,0],min:-100,max:100,unit:"m/s2"}),drag:t.number("How quickly particles slow down in the air",{default:.5,min:0,max:20,unit:"1/s"}),facing:t.choice("Whether particles face the camera or tumble",Ir,"camera",{labels:wr}),additive:t.boolean("Particles glow where they overlap",false),tint:t.boolean("Each particle can have its own colour",true),aspect:t.number("Particle shape, width over height",{default:1,min:.05,max:20,unit:"none"}),plane:t.vector("The floor particles bounce off: which way is up, then its offset",{default:[0,1,0,0],min:-k,max:k,unit:"none",axes:["Up X","Up Y","Up Z","Offset"]}),bounce:t.number("How much particles bounce off the floor",{default:.3,min:0,max:1,unit:"fraction"})}}),c("SprayOptions",{title:"Spray",description:"A stream of particles, such as a fountain, smoke puff or sparkler.",fields:{emitter:t.wiring("How fast, how wide and how long the particles fly"),material:t.wiring("How each particle looks"),cell:t.vector("Part of the picture each particle shows",{default:[0,0,1,1],min:0,max:1,unit:"fraction",axes:["Left","Top","Width","Height"]}),facing:t.choice("Whether particles face the camera or tumble",Ir,"camera",{labels:wr}),aspect:t.number("Particle shape, width over height",{default:1,min:.05,max:20,unit:"none"})}}),c("WavesOptions",{title:"Waves",description:"Enemies or targets that arrive in rounds.",fields:{waitForClear:t.boolean("Wait until a round is cleared before the next",true),endless:t.boolean("Keep going after the last round",false),growth:t.number("Extra arrivals added each endless round",{default:0,min:0,max:10,unit:"fraction"})}}),c("ScoreTimerOptions",{title:"Score and timer",description:"Points, combos and a clock.",fields:{seconds:t.number("Countdown length, 0 for a stopwatch",{default:0,min:0,max:86400,unit:"s"}),comboWindow:t.number("Time between scores that keeps a combo going, 0 for no combos",{default:0,min:0,max:30,unit:"s"}),maxCombo:t.integer("Highest combo multiplier",{default:1,min:1,max:100,unit:"times"}),clockSeconds:t.number("Longest a stopwatch shows",{default:3600,min:1,max:864e3,unit:"s"})}}),c("CheckpointOptions",{title:"Checkpoints",description:"Places a player must reach, and where they come back after a fall.",fields:{radius:t.number("How close counts as reached",{default:2,min:.1,max:100,unit:"m"}),ordered:t.boolean("Checkpoints must be reached in order",true),killY:t.number("Height below which a player falls back to the last checkpoint",{default:-k,min:-k,max:k,unit:"m"})}}),c("ArenaOptions",{title:"Arena",description:"A walled square floor to play on.",fields:{half:t.number("Half the width of the floor",{default:10,min:1,max:1e3,unit:"m"}),wallHeight:t.number("Wall height",{default:1,min:0,max:100,unit:"m"}),wallThickness:t.number("Wall thickness",{default:.4,min:.01,max:10,unit:"m"}),groundDepth:t.number("Floor thickness",{default:.5,min:.01,max:10,unit:"m"})}}),c("DaylightOptions",{title:"Daylight",description:"A simple sun and sky to light a scene.",fields:{sun:t.number("Sun brightness",{default:2,min:0,max:100,unit:"times"}),sky:t.number("Sky brightness",{default:.7,min:0,max:100,unit:"times"}),sunX:t.number("Sun position east to west",{default:3,min:-1e3,max:1e3,unit:"m",group:"Sun position"}),sunY:t.number("Sun height",{default:10,min:-1e3,max:1e3,unit:"m",group:"Sun position"}),sunZ:t.number("Sun position north to south",{default:4,min:-1e3,max:1e3,unit:"m",group:"Sun position"})}}),c("SeekBotOptions",{title:"Chaser",description:"A character that runs after a target.",fields:{arrive:t.number("How close counts as caught",{default:.6,min:.01,max:100,unit:"m"}),jumpEvery:t.integer("Steps between jumps, 0 for never",{default:0,min:0,max:1e4}),jumpHold:t.integer("Steps each jump is held for",{default:9,min:1,max:600})}})];var V=128;var be=8;var ma=new Float32Array(1);new Uint32Array(ma.buffer);var Ge=2,We=16;var Lt=2,Ve=4;var Pr=.5;var Fr=.05;new TextDecoder("utf-8",{fatal:true});var ba=new Float64Array(1);new Uint32Array(ba.buffer);var Aa=new Float64Array(1);new Uint32Array(Aa.buffer);var Ea=new Float32Array(1);new Uint32Array(Ea.buffer);var Na=new Float32Array(1);new Uint32Array(Na.buffer);var za=new Float64Array(1);new Uint32Array(za.buffer);var Dt=65536;var Wr=4294967295,X=4294967295,Xa=4,Vr=["beforeScene","afterOpaque","afterTransparent","post","afterPost"],qr={beforeScene:"Before the scene",afterOpaque:"After solid things",afterTransparent:"After see-through things",post:"With picture effects",afterPost:"Last"},zr=[c("EntityTableOptions",{title:"Crowd table",description:"Room for a large crowd of similar things, such as particles, fish or people.",fields:{capacity:t.integer("Most things in the crowd",{default:1024,min:1,max:1<<22,heavy:true}),selections:t.integer("Saved groups picked out of the crowd",{default:4,min:0,max:64,advanced:true}),cell:t.number("Size of the grid used to find neighbours",{default:4,min:.01,max:1e3,unit:"m"}),gridTable:t.integer("Room for neighbour lookups",{default:16384,min:64,max:1<<22,advanced:true})}}),c("QueryWhere",{title:"Neighbour filter",description:"Only neighbours whose flags match.",fields:{field:t.text("The flags to read","",64),equals:t.integer("Flags must equal this",{default:0,min:0,max:X,unit:"none"}),any:t.integer("At least one of these flags is set",{default:0,min:0,max:X,unit:"none"}),none:t.integer("None of these flags is set",{default:0,min:0,max:X,unit:"none"}),mask:t.integer("Only these flags are compared",{default:X,min:0,max:X,unit:"none"})}}),c("QueryOptions",{title:"Neighbour search",description:"How a crowd member finds the others near it.",fields:{limit:t.integer("Most neighbours returned",{default:X,min:1,max:X}),cell:t.number("Size of the search grid, 0 to use the crowd's",{default:0,min:0,max:1e3,unit:"m"}),field:t.text("Position used for the search","position",64),where:t.settings("Only neighbours whose flags match","QueryWhere")}}),c("NearestFeatureOptions",{title:"Nearest neighbour features",description:"Where the nearest crowd members are and how they move, ready to feed a network.",extends:["QueryOptions"],fields:{velocity:t.text("Speed read from each neighbour, empty for position only","",64)}}),c("KernelOptions",{title:"Crowd behaviour",description:"Where a behaviour that runs on every member of a crowd works and how much it matters.",fields:{device:t.choice("Which part of the phone runs it",["auto","cpu","gpu"],"auto",{labels:{auto:"Automatic",cpu:"Main chip",gpu:"Graphics chip"}}),feeds:t.choice("Who reads its results",["host","render","auto"],"auto",{labels:{host:"Game logic",render:"Drawing only",auto:"Automatic"}}),priority:t.choice("What happens when the phone is busy",["simulation","presentation","optional"],"simulation",{labels:{simulation:"Always runs",presentation:"Can drop to keep frames smooth",optional:"Skipped first"}})}}),c("KernelSettings",{title:"Crowd running",description:"How every crowd behaviour runs, checks itself and splits work across the phone.",fields:{mode:t.choice("How behaviours run",["auto","native","vm","js","dev"],"auto",{labels:{auto:"Automatic",native:"Fastest",vm:"Portable",js:"Script",dev:"Checked while making"}}),checkEvery:t.integer("Frames between self checks while making",{default:30,min:1,max:1e4,advanced:true}),tolerance:t.number("Difference allowed in a self check",{default:.001,min:1e-9,max:1,unit:"none",scale:"log",advanced:true}),report:t.wiring("Hears about a failed self check"),gpu:t.choice("Allow the graphics chip to run behaviours",["auto","off"],"auto",{labels:{auto:"Automatic",off:"Off"}}),gpuRows:t.integer("Crowd size before the graphics chip takes over, 0 picks itself",{default:0,min:0,max:1<<24,advanced:true}),gpuClass:t.choice("Kind of graphics chip to plan for",["unknown","mobile","desktop","discrete"],"mobile",{labels:{unknown:"Unknown",mobile:"Phone",desktop:"Computer",discrete:"Gaming computer"}}),cpuLanes:t.integer("Crowd members worked on side by side",{default:4,min:1,max:16,advanced:true}),cpuBackend:t.choice("How the main chip runs behaviours",["auto","interpreter","cranelift","wasm"],"auto",{labels:{auto:"Automatic",interpreter:"Steady",cranelift:"Fast",wasm:"Portable"},advanced:true}),frameBudgetMs:t.number("Time behaviours may take each frame, 0 picks itself",{default:0,min:0,max:100,unit:"ms",heavy:true}),gpuCalibrate:t.integer("Frames spent measuring the graphics chip, 0 to skip",{default:0,min:0,max:1e3,advanced:true}),gpuPins:t.wiring("Behaviours fixed to one chip"),onRoute:t.wiring("Hears where each behaviour runs"),onCompute:t.wiring("Hears graphics chip problems")}}),c("LoopSettings",{title:"Loop running",description:"How simple loops over a crowd are sped up.",fields:{schedule:t.choice("How loops run",["auto","kernel","js"],"auto",{labels:{auto:"Automatic",kernel:"Sped up",js:"Script"}}),chunkRows:t.integer("Crowd members handled in one go",{default:Dt,min:1,max:Dt,advanced:true}),enabled:t.boolean("Speed up loops",true)}}),c("KernelRecordingOptions",{title:"Behaviour recording",description:"Records a crowd behaviour over time, to train from or compare against.",fields:{args:t.wiring("Inputs the behaviour is given"),objectiveArgs:t.wiring("Inputs the training goal is given"),steps:t.integer("Steps recorded",{default:600,min:1,max:1e6}),warmup:t.integer("Steps skipped before recording",{default:0,min:0,max:1e6}),fields:t.list("What is recorded about each member",t.text("A recorded value","",64),{maxItems:64})}}),c("MlpTrainingOptions",{title:"Training",description:"Teaches a small network to act like a recorded behaviour.",fields:{widths:t.list("Size of each layer of the network",t.integer("Layer size",{default:16,min:1,max:1024}),{maxItems:8,default:[16,16]}),epochs:t.integer("Times the recording is learned from",{default:20,min:1,max:1e4,heavy:true}),batch:t.integer("Examples learned from at once",{default:32,min:1,max:4096}),learningRate:t.number("How big each learning step is",{default:.02,min:1e-6,max:1,unit:"none",scale:"log"}),momentum:t.number("How much each step carries on from the last",{default:.9,min:0,max:.999,unit:"fraction"}),seed:t.integer("Starting point for training",{default:1,min:0,max:Wr,unit:"none"})}}),c("MoeTrainingOptions",{title:"Team training",description:"Teaches a team of small networks, each taking the cases it handles best, to act like a recorded behaviour.",fields:{experts:t.integer("Networks in the team",{default:Xa,min:Ge,max:We,heavy:true}),router:t.list("Size of each middle layer of the network that picks a team member",t.integer("Layer size",{default:16,min:1,max:V}),{maxItems:be-1,default:[]}),expert:t.list("Size of each middle layer of every team member",t.integer("Layer size",{default:16,min:1,max:V}),{maxItems:be-1,default:[]}),epochs:t.integer("Times the recording is learned from",{default:20,min:1,max:1e4,heavy:true}),batch:t.integer("Examples learned from at once",{default:32,min:1,max:4096}),learningRate:t.number("How big each learning step is",{default:.02,min:1e-6,max:1,unit:"none",scale:"log"}),momentum:t.number("How much each step carries on from the last",{default:.9,min:0,max:.999,unit:"fraction"}),seed:t.integer("Starting point for training",{default:1,min:0,max:Wr,unit:"none"}),balance:t.number("How evenly the cases are shared across the team",{default:Pr,min:0,max:10,unit:"none"})}}),c("ImportOptions",{title:"Network import",description:"Brings in a network made elsewhere and checks it still answers the same.",fields:{samples:t.wiring("Example inputs it is checked against"),maxDrift:t.number("Largest difference allowed from the original",{default:Fr,min:0,max:1,unit:"fraction"}),memory:t.integer(`Values carried to the next step, 0 for none or ${Lt} to ${Ve}`,{default:0,min:0,max:Ve})}}),c("GpuDrawOptions",{title:"Custom drawing",description:"When a hand-written drawing pass runs and what it draws into.",fields:{hook:t.choice("When it draws",Vr,"afterTransparent",{labels:qr}),target:t.wiring("What it draws into"),instances:t.integer("Copies drawn",{default:1,min:1,max:1<<24,heavy:true})}}),c("GpuDispatchOptions",{title:"Custom work",description:"When a hand-written graphics chip job runs.",fields:{hook:t.choice("When it runs",Vr,"beforeScene",{labels:qr}),indirect:t.wiring("Takes its size from a buffer")}})];var Kr=4;var Xr=()=>t.integer("Messages queued on each channel",{default:64,min:1,max:4096,advanced:true}),Yr=()=>t.integer("Largest single message",{default:1200,min:64,max:65536,unit:"bytes",advanced:true}),jr=()=>t.integer("Simulation steps every second shared by everyone in the room, 0 to follow the game",{default:0,min:0,max:240,unit:"Hz"}),$r=[c("ReplayRecorderOptions",{title:"Replays",description:"Lets players share the last moments of a game, which plays back exactly the same for anyone who opens it.",fields:{window_ticks:t.integer("How much of the game a replay keeps, in steps",{default:600,min:1,max:36e3}),keyframe_every:t.integer("How often a replay can begin, in steps",{default:60,min:1,max:3600,advanced:true}),input_stride:t.integer("Space for one step of a player's controls",{default:8,min:1,max:1024,unit:"bytes",advanced:true}),tick_hz:t.integer("Steps every second",{default:60,min:1,max:240,unit:"Hz",advanced:true}),interactive_id:t.wiring("Which game the replay belongs to"),revision:t.wiring("Which version of the game made the replay"),play_from_here:t.boolean("Players can pick up and play on from where a replay ends",false)}}),c("LoopbackOptions",{title:"Practice room",description:"A room that runs on this device alone, for trying out multiplayer.",fields:{slots:Xr(),slotBytes:Yr()}}),c("TickRoomOptions",{title:"Room",description:"A live room shared with other people.",fields:{renew:t.wiring("Fetches a fresh pass when the old one runs out"),slots:Xr(),slotBytes:Yr(),physicsHz:jr(),memory:t.wiring("Remembers which connection worked best"),network:t.wiring("Reports which network the device is on")}}),c("RoomClientOptions",{title:"Room connection",description:"How a device joins and stays in a live room.",fields:{tickets:t.wiring("Fetches a pass to join the room"),primary:t.wiring("The main way to connect"),fallback:t.wiring("The way to connect when the main one fails"),physicsHz:jr(),memory:t.wiring("Remembers which connection worked best"),network:t.wiring("Reports which network the device is on"),channels:t.wiring("Receives the room's messages"),motion:t.wiring("How other people's movement is smoothed"),spectatorAckEvery:t.integer("How often a watcher confirms what they have seen, in steps",{default:Kr,min:1,max:60,advanced:true})}}),c("TickLockstepLinkOptions",{title:"Turn sharing",description:"Everyone in the room moves forward together, step by step.",fields:{seats:t.integer("People who play together",{default:2,min:1,max:64}),channel:t.text("Name of the channel the steps travel on","lockstep",64,{advanced:true})}}),c("PlanarSnapshotOptions",{title:"Position sharing",description:"Sends where things are on a flat playing field to everyone in the room.",fields:{entities:t.integer("Things shared",{default:16,min:1,max:1024,heavy:true}),extent:t.number("Half the width of the playing field",{default:50,min:1,max:1e5,unit:"m"}),bits:t.integer("Precision of each position; more is finer and costs more data",{default:12,min:4,max:32,heavy:true}),history:t.integer("Past updates kept to smooth movement",{default:32,min:2,max:256,advanced:true})}}),c("LeaderboardOptions",{title:"Leaderboard",description:"Ranks scores across players.",fields:{name:t.text("Leaderboard name","high-scores",64),scope:t.choice("Whose scores it ranks",["personal","interactive","shared"],"interactive",{labels:{personal:"Just me",interactive:"Everyone who plays",shared:"Across Interactives"}}),mode:t.choice("What a new score does",["replace","keep_highest","keep_lowest","increment"],"keep_highest",{labels:{replace:"Replaces the old one",keep_highest:"Keeps the best high",keep_lowest:"Keeps the best low",increment:"Adds up"}}),direction:t.choice("Whether high or low scores rank first",["asc","desc"],"desc",{labels:{asc:"Lowest first",desc:"Highest first"}})}})];var q={mass:.01,stretch:1e-7,bend:1e-4,tetherSlack:.05,damping:.5,gravity:{y:-9.81},substeps:8,thickness:.005,friction:.2};var eo=4096;var to=.02;var z={stretch:1e-6,bend:1e-4,volume:0,damping:.5,gravity:{y:-9.81},substeps:10,radius:.01,friction:.3,contraction:.3};var ze=100,sl=16,al=4294967295,oo=1e3,io=r=>t.vector("Pull of gravity on it",{default:[0,r,0],min:-ze,max:ze,unit:"m/s2"}),so=[c("PhysicsOptions",{title:"Physics",description:"Gravity, how many things can move and collide, and how carefully they are solved.",fields:{gravity:t.vector("Pull of gravity",{default:[0,-9.81,0],min:-ze,max:ze,unit:"m/s2"}),maxBodies:t.integer("Most moving things",{default:2048,min:16,max:65536,heavy:true,group:"Limits"}),maxColliders:t.integer("Most collision shapes",{default:4096,min:16,max:131072,heavy:true,group:"Limits"}),maxJoints:t.integer("Most hinges, springs and links",{default:1024,min:0,max:65536,group:"Limits"}),maxContactEvents:t.integer("Most touches reported each step",{default:1024,min:16,max:65536,group:"Limits",advanced:true}),maxCharacterControllers:t.integer("Most walking characters",{default:64,min:0,max:4096,group:"Limits"}),rollback:t.wiring("Memory kept so the world can rewind and replay"),solver:t.settings("How carefully contacts and joints are solved","SolverSettings",{group:"Accuracy"})}}),c("SolverSettings",{title:"Accuracy",description:"How carefully stacks, joints and fast things are solved.",fields:{iterations:t.integer("Passes over contacts each step; more keeps tall stacks steady",{default:Qn,min:1,max:er,heavy:true}),pgsIterations:t.integer("Extra passes that settle resting things",{default:Zn,min:1,max:tr,heavy:true,advanced:true}),ccdSubsteps:t.integer("Extra checks that stop fast things passing through walls",{default:Jn,min:0,max:nr,heavy:true})}}),c("FluidColliderOptions",{title:"Fluid contact",description:"How water, sand, jelly and snow touch a solid thing.",fields:{friction:t.number("How much the fluid grips the surface",{default:0,min:0,max:2,unit:"none"}),feedback:t.boolean("The fluid pushes back on the thing, so it floats and gets carried",true)}}),c("CrumpleOptions",{title:"Crumple",description:"How a solid dents and crushes when it hits something hard.",fields:{cells:t.vector("Dent grid across, up and along",{default:[4,2,6],min:1,max:32,unit:"cells",heavy:true}),threshold:t.number("Impact speed before it dents",{default:3,min:0,max:100,unit:"m/s"}),crush:t.number("How far each hit pushes in",{default:.02,min:0,max:1,unit:"m"}),maxDepth:t.number("Deepest a dent can go",{default:.35,min:0,max:10,unit:"m"}),radius:t.number("Spread of each dent, 0 picks a quarter of its size",{default:0,min:0,max:50,unit:"m"}),stiffness:t.number("How much it resists bending back",{default:1e-5,min:1e-9,max:1,unit:"none",scale:"log"})}}),c("SoftBodyOptions",{title:"Soft body",description:"Squishy, stretchy things like jelly, rubber, muscle and rope.",fields:{stretch:t.number("Give when pulled; lower is stiffer",{default:z.stretch,min:1e-10,max:1,unit:"none",scale:"log"}),bend:t.number("Give when bent; lower is stiffer",{default:z.bend,min:1e-10,max:1,unit:"none",scale:"log"}),volume:t.number("How hard it keeps its size when squeezed, 0 for not at all",{default:z.volume,min:0,max:1,unit:"none"}),damping:t.number("How fast wobbling dies down",{default:z.damping,min:0,max:10,unit:"1/s"}),gravity:io(z.gravity.y),substeps:t.integer("Smaller steps each frame; more is steadier",{default:z.substeps,min:1,max:64,heavy:true}),radius:t.number("Thickness of each point for collisions",{default:z.radius,min:.001,max:1,unit:"m"}),friction:t.number("How much it grips what it touches",{default:z.friction,min:0,max:2,unit:"none"}),contraction:t.number("How strongly muscle fibres pull when flexed",{default:z.contraction,min:0,max:1,unit:"fraction",group:"Muscle"}),fibre:t.vector("Which way muscle fibres run, none when all zero",{default:[0,0,0],min:-1,max:1,unit:"none",group:"Muscle"}),plastic:t.wiring("How it keeps a dent once bent far enough"),geometry:t.asset("The shape that follows the soft body","geometry")}}),c("ClothOptions",{title:"Cloth",description:"Flags, curtains, capes and sails.",fields:{mass:t.number("Weight of each point of cloth",{default:q.mass,min:1e-4,max:10,unit:"kg",scale:"log"}),stretch:t.number("Give when pulled; lower is stiffer",{default:q.stretch,min:1e-10,max:1,unit:"none",scale:"log"}),bend:t.number("Give when folded; lower is stiffer",{default:q.bend,min:1e-10,max:1,unit:"none",scale:"log"}),tetherSlack:t.number("How far it can sag from where it hangs",{default:q.tetherSlack,min:0,max:1,unit:"fraction"}),damping:t.number("How fast flapping dies down",{default:q.damping,min:0,max:10,unit:"1/s"}),gravity:io(q.gravity.y),substeps:t.integer("Smaller steps each frame; more is steadier",{default:q.substeps,min:1,max:64,heavy:true}),thickness:t.number("Thickness for collisions",{default:q.thickness,min:1e-4,max:.1,unit:"m"}),friction:t.number("How much it grips what it touches",{default:q.friction,min:0,max:2,unit:"none"}),geometry:t.asset("The shape that follows the cloth","geometry")}}),c("FractureOptions",{title:"Breaking apart",description:"How a model is cut into pieces that fly apart when it breaks.",fields:{pieces:t.integer("Pieces it breaks into",{default:sl,min:1,max:eo,heavy:true}),seed:t.integer("Starting point for the cut pattern",{default:1,min:0,max:al,unit:"none"}),impact:t.vector("Where it is hit",{default:[0,0,0],min:-oo,max:oo,unit:"m"}),focus:t.number("Share of the pieces gathered around where it is hit",{default:0,min:0,max:1,unit:"fraction"}),interiorUvScale:t.number("Pattern size on the broken faces",{default:1,min:.01,max:100,unit:"times",advanced:true}),anchorHeight:t.number("Pieces this close to the bottom stay put",{default:to,min:0,max:10,unit:"m"})}})];var co="Placement",uo="position",mo="rotation",po="scale",ao=1e6,lo=180,ll=.001,cl=1e3,ho=[c(co,{title:"Placement",description:"Where a thing sits, which way it turns and how big it is.",fields:{[uo]:t.vector("Where it sits",{default:[0,0,0],min:-ao,max:ao,unit:"m"}),[mo]:t.vector("Which way it turns",{default:[0,0,0],min:-lo,max:lo,unit:"deg"}),[po]:t.vector("How big it is",{default:[1,1,1],min:ll,max:cl,unit:"times"})}})];new Uint8Array(new Uint32Array([1]).buffer)[0]===1;var Ft=class{constructor(){this.ready=false;this.startX=0;this.startY=0;this.endX=0;this.endY=0;this.deltaX=0;this.deltaY=0;this.distance=0;this.durationMs=0;this.velocityX=0;this.velocityY=0;this.curl=0;}},Ut=class{constructor(){this.ready=false;this.x=0;this.y=0;}},Ht=class{constructor(){this.active=false;this.down=false;this.x=0;this.y=0;this.buttons=0;this.count=0;}},Ke=class{constructor(){this.active=false;this.scale=1;this.totalScale=1;this.centerX=0;this.centerY=0;this.panX=0;this.panY=0;this.rotation=0;this.distance=0;}},Xe=class{constructor(){this.deltaX=0;this.deltaY=0;this.deltaZ=0;this.x=0;this.y=0;}},xe=class{constructor(){this.x=0;this.y=0;}},Bt=class{constructor(){this.drag=new xe;this.motion=new xe;this.wheel=new Xe;this.pinch=new Ke;this.pressed=false;this.released=false;this.releasedButtons=0;this.pressX=0;this.pressY=0;}dragging(e){return (e.down||this.released)&&e.count<=1}dragButtons(e){return e.down?e.buttons:this.releasedButtons}begin(){this.drag.x=0,this.drag.y=0,this.motion.x=0,this.motion.y=0,this.wheel.deltaX=0,this.wheel.deltaY=0,this.wheel.deltaZ=0,this.pinch.active=false,this.pinch.scale=1,this.pinch.panX=0,this.pinch.panY=0,this.pinch.rotation=0,this.pressed=false,this.released=false,this.releasedButtons=0;}},Gt=class{constructor(){this.ready=false;this.x=0;this.y=0;this.durationMs=0;}},Wt=class{constructor(){this.available=false;this.alpha=0;this.beta=0;this.gamma=0;}};A(new Ft,["startX","startY","endX","endY","deltaX","deltaY","distance","durationMs","velocityX","velocityY","curl"]);A(new Ut,["x","y"]);A(new Ht,["x","y"]);A(new Ke,["scale","totalScale","centerX","centerY","panX","panY","rotation","distance"]);A(new Xe,["deltaX","deltaY","deltaZ","x","y"]);A(new xe,["x","y"]);A(new Bt,["pressX","pressY"]);A(new Gt,["x","y","durationMs"]);A(new Wt,["alpha","beta","gamma"]);var fo=8;var fl=["leftStickRightButtons","twinStick","oneThumb","driving"],_l={leftStickRightButtons:"Stick and buttons",twinStick:"Two sticks",oneThumb:"One thumb",driving:"Driving"},Ye=1e6,_o=()=>t.choice("Arrangement of the on-screen controls",fl,"leftStickRightButtons",{labels:_l}),yo=()=>t.list("On-screen buttons",t.settings("A button","ButtonSpec"),{maxItems:fo}),bo=r=>t.text("Name the controls are listed under",r,64,{advanced:true}),go=[c("StickSpec",{title:"Stick",description:"An on-screen thumb stick.",fields:{x:t.text("Control the stick's left and right move","",64,{advanced:true}),y:t.text("Control the stick's up and down move","",64,{advanced:true}),tap:t.text("Control a quick tap on the stick presses","",64,{advanced:true}),mode:t.choice("Appears where the thumb lands, or stays put",["floating","fixed"],"floating",{labels:{floating:"Where the thumb lands",fixed:"Stays put"}}),axes:t.choice("Which ways the stick moves",["both","x","y"],"both",{labels:{both:"All ways",x:"Left and right",y:"Up and down"}}),radius:t.number("Stick size",{default:58,min:20,max:200,unit:"px"}),deadZone:t.number("Small movements ignored around the middle",{default:.12,min:0,max:.9,unit:"fraction"}),curve:t.number("Fine control near the middle, where 1 is even",{default:1,min:.25,max:4,unit:"none"}),follow:t.boolean("The stick slides along under the thumb",true),snapSeconds:t.number("How quickly the stick springs back",{default:.12,min:0,max:1,unit:"s"})}}),c("LookSpec",{title:"Look area",description:"Dragging on the screen turns the camera.",fields:{sensitivity:t.number("How far a drag turns the camera",{default:1,min:.05,max:10,unit:"times"}),inertiaSeconds:t.number("How long the turn glides after a flick",{default:.16,min:0,max:2,unit:"s"})}}),c("ButtonSpec",{title:"Button",description:"An on-screen button.",fields:{control:t.text("The control the button presses","jump",64),label:t.text("What a screen reader says for the button","",40),icon:t.integer("The picture on the button",{default:0,min:0,max:65535,unit:"none"}),mode:t.choice("Hold down, or tap on and off",["hold","toggle"],"hold",{labels:{hold:"Hold",toggle:"Tap on and off"}}),doubleTap:t.text("The control a double tap presses","",64,{advanced:true}),cooldownSeconds:t.number("Wait before it can be pressed again",{default:0,min:0,max:600,unit:"s"}),lookThrough:t.boolean("Dragging off the button still turns the camera",false),size:t.number("Button size, 0 for the layout's",{default:0,min:0,max:300,unit:"px"})}}),c("TouchControlsOptions",{title:"Touch controls",description:"On-screen sticks and buttons for playing on a phone.",fields:{ui:t.wiring("The interface the controls draw into"),theme:t.wiring("Colours and type of the controls"),layout:_o(),move:t.settings("The stick that moves","StickSpec",{group:"Sticks"}),aim:t.settings("The stick that aims","StickSpec",{group:"Sticks"}),look:t.settings("Dragging to look around","LookSpec",{group:"Sticks"}),buttons:yo(),viewport:t.wiring("The size of the screen area"),autoHide:t.boolean("Fade the controls when not touched",true),idleOpacity:t.number("How visible faded controls stay",{default:.5,min:0,max:1,unit:"fraction"}),z:t.integer("Stacking above other on-screen things",{default:50,min:0,max:1e3,unit:"none",advanced:true})}}),c("TouchOptions",{title:"Play controls",description:"The on-screen controls a ready-made player uses.",fields:{ui:t.wiring("The interface the controls draw into"),theme:t.wiring("Colours and type of the controls"),viewport:t.wiring("The size of the screen area"),surface:t.wiring("Reads the screen size as it changes"),layout:_o(),move:t.settings("The stick that moves","StickSpec",{group:"Sticks"}),look:t.settings("Dragging to look around","LookSpec",{group:"Sticks"}),buttons:yo()}}),c("CharacterRigOptions",{title:"Player",description:"A ready-made player character with its controls.",extends:["TouchOptions"],fields:{entity:t.thing("The character to control, or a new one","character"),position:t.vector("Where the player starts",{default:[0,0,0],min:-Ye,max:Ye,unit:"m"}),heading:t.number("Which way the player starts facing",{default:0,min:-Math.PI,max:Math.PI,unit:"rad"}),camera:t.thing("The camera that follows the player, or a new one","camera"),character:t.settings("How the player moves","CharacterMotorOptions",{group:"Movement"}),animation:t.wiring("The player's animations"),prefix:bo("play"),register:t.boolean("Starts running as soon as it is made",true,{advanced:true})}}),c("ThirdPersonOptions",{title:"Third person player",description:"A player seen from behind and over the shoulder.",extends:["CharacterRigOptions"],fields:{follow:t.settings("How the camera follows","FollowCameraOptions",{group:"Camera"})}}),c("FirstPersonOptions",{title:"First person player",description:"A player who sees through their own eyes.",extends:["CharacterRigOptions"],fields:{view:t.settings("How the eyes view moves","FirstPersonViewOptions",{group:"Camera"})}}),c("VehicleDriverOptions",{title:"Driver",description:"A ready-made vehicle a player drives, with its controls and camera.",extends:["TouchOptions"],fields:{vehicle:t.thing("The vehicle to drive, or a new one","vehicle"),preset:t.choice("Kind of vehicle",["danfo","keke","okada","car"],"danfo",{labels:{danfo:"Minibus",keke:"Tuk-tuk",okada:"Motorbike taxi",car:"Car"}}),model:t.choice("Easy handling or true to life",["arcade","sim"],"arcade",{labels:{arcade:"Easy",sim:"True to life"}}),position:t.vector("Where the vehicle starts",{default:[0,0,0],min:-Ye,max:Ye,unit:"m"}),camera:t.thing("The camera that follows, or a new one","camera"),chase:t.settings("How the camera follows","ChaseCameraOptions",{group:"Camera"}),prefix:bo("drive"),register:t.boolean("Starts running as soon as it is made",true,{advanced:true})}})];var xo=16;var So="UiMotion",Ao="MusicBed",Eo="CrowdVote",vo="CrowdCheer",yl=8,bl=10,gl=600,To=[c(So,{title:"When it changes",description:"How a shown value moves when it goes up, goes down or changes.",fields:{on:t.choice("When it plays",["up","down","change"],"up",{labels:{up:"When it goes up",down:"When it goes down",change:"Whenever it changes"}}),when:t.text("Only while this is true, for example on a streak; empty for always","",80),steps:t.list("What happens, in order",t.choice("A step",["count_up","pop","settle","flash"],"count_up",{labels:{count_up:"Count up",pop:"Pop",settle:"Settle",flash:"Flash"}}),{maxItems:yl,default:["count_up","pop","settle"]}),seconds:t.number("How long each step takes",{default:.3,min:0,max:bl,unit:"s"}),pop:t.number("How big a pop gets",{default:1.2,min:1,max:3,unit:"times"}),flash:t.color("Flash colour",16765286)}}),c(Ao,{title:"Music",description:"Music that follows the game: moods mix the stems in and out on the beat, and moments play cues.",fields:{bpm:t.number("Beats per minute",{default:110,min:30,max:240,unit:"none"}),beatsPerBar:t.integer("Beats in a bar",{default:4,min:1,max:12}),bars:t.integer("Bars before it loops",{default:8,min:1,max:64}),rampSeconds:t.number("How long a change of mood takes",{default:2,min:0,max:30,unit:"s"}),follows:t.text("What the mood follows, for example the time of day or how close the match is","hour",80)}}),c(Eo,{title:"Crowd vote",description:"A question the people watching answer together, such as player of the match.",fields:{question:t.text("The question","Player of the match?",120),choices:t.list("The answers",t.text("An answer","",60),{maxItems:xo,default:[]}),opensOn:t.text("The moment it opens on, for example full time","full_time",80),seconds:t.number("How long it stays open",{default:20,min:1,max:gl,unit:"s"})}}),c(vo,{title:"Cheer",description:"Taps from the crowd fill a noise meter that drains over time.",fields:{on:t.boolean("Let the crowd cheer",true),perTap:t.number("How much one tap fills",{default:.01,min:0,max:1,unit:"fraction"}),drainPerSecond:t.number("How fast it drains",{default:.1,min:0,max:1,unit:"1/s"})}})];var Io="WorldSky",wo="ScatterBrush",Ro="GroundBrush",xl=4294967295,Sl=24,Oo=[c(Io,{title:"Sky and time",description:"The time of day a place starts at, its weather and how fast the day passes.",fields:{hour:t.number("Time of day it starts at, in hours from midnight",{default:17.5,min:0,max:Sl,unit:"none",step:.25}),weather:t.choice("The weather",["clear","overcast","fog","drizzle","heavy_rain","thunderstorm","snow","blizzard","desert_dust","monsoon","golden_hour","night","harmattan_haze","real_sky"],"clear",{labels:{clear:"Clear",overcast:"Overcast",fog:"Fog",drizzle:"Drizzle",heavy_rain:"Heavy rain",thunderstorm:"Thunderstorm",snow:"Snow",blizzard:"Blizzard",desert_dust:"Desert haze and dust",monsoon:"Monsoon",golden_hour:"Golden hour",night:"Night",harmattan_haze:"Harmattan haze (West Africa)",real_sky:"Follows the real sky"}}),dayMinutes:t.number("Minutes of play for a full day, 0 to keep the time still",{default:12,min:0,max:1440,unit:"none"})}}),c(wo,{title:"Scatter",description:"Scatters props or people under the brush, keeping clear of walls and each other.",fields:{layer:t.choice("What the brush scatters",["props","crowds"],"crowds",{labels:{props:"Stalls and props",crowds:"People"}}),radius:t.number("Brush size",{default:4,min:.5,max:50,unit:"m"}),count:t.integer("How many each stroke adds",{default:12,min:1,max:200,heavy:true}),spacing:t.number("Smallest gap between them",{default:1,min:.2,max:20,unit:"m"}),seed:t.integer("Starting point for where they land",{default:1,min:0,max:xl,unit:"none",advanced:true})}}),c(Ro,{title:"Ground brush",description:"Raises, lowers, flattens, smooths or paints the ground under the brush.",fields:{op:t.choice("What the brush does",["raise","lower","smooth","flatten","paint"],"raise",{labels:{raise:"Raise",lower:"Lower",smooth:"Smooth",flatten:"Flatten",paint:"Paint"}}),radius:t.number("Brush size",{default:6,min:.5,max:100,unit:"m"}),strength:t.number("How much each stroke changes",{default:.5,min:0,max:1,unit:"fraction"}),layer:t.integer("The ground paint the brush lays down",{default:0,min:0,max:7,unit:"none"})}})];var ko=8192;var Co=64;var El=4294967295,Lo=16777215,Mo=1<<24,je=r=>t.integer(r,{default:4294967295,min:0,max:4294967295,unit:"none",advanced:true}),Do=[c("ExtrudeOptions",{title:"Extrude",description:"Turns a flat shape into a solid with depth and rounded edges.",fields:{curveSegments:t.integer("Smoothness of curved outlines",{default:12,min:1,max:64,heavy:true}),steps:t.integer("Slices along the depth",{default:1,min:1,max:64,heavy:true}),depth:t.number("How deep the solid is",{default:1,min:0,max:100,unit:"m"}),bevelEnabled:t.boolean("Round the front and back edges",true,{group:"Edges"}),bevelThickness:t.number("How far the rounded edge reaches into the depth",{default:.2,min:0,max:10,unit:"m",group:"Edges"}),bevelSize:t.number("How far the rounded edge reaches out from the outline",{default:.1,min:-10,max:10,unit:"m",group:"Edges"}),bevelOffset:t.number("Where the rounded edge starts from the outline",{default:0,min:-10,max:10,unit:"m",group:"Edges"}),bevelSegments:t.integer("Smoothness of the rounded edge",{default:3,min:1,max:32,group:"Edges",heavy:true}),extrudePath:t.wiring("A curve to sweep the shape along instead of straight back")}}),c("TextGeometryOptions",{title:"3D text",description:"Solid lettering made from a font.",extends:["ExtrudeOptions"],omit:["extrudePath"],fields:{size:t.number("Letter height",{default:1,min:.01,max:100,unit:"m"}),direction:t.choice("Which way the text runs",["ltr","rtl","tb"],"ltr",{labels:{ltr:"Left to right",rtl:"Right to left",tb:"Top to bottom"}}),depth:t.number("How deep the letters are",{default:.2,min:0,max:100,unit:"m"}),bevelEnabled:t.boolean("Round the letter edges",false,{group:"Edges"})}}),c("BatchedMeshOptions",{title:"Batched shapes",description:"Many different shapes drawn together in one go.",fields:{material:t.asset("The surface every shape in the batch shares","material"),maxVertices:t.integer("Room for corners across all shapes",{default:65536,min:3,max:16777216,heavy:true,advanced:true}),maxGeometries:t.integer("Most different shapes in the batch",{default:64,min:1,max:4096,advanced:true}),maxInstances:t.integer("Most copies drawn",{default:1024,min:1,max:1048576,heavy:true}),maxInstanceVertices:t.integer("Room for corners of the drawn copies",{default:65536,min:3,max:16777216,advanced:true}),colors:t.boolean("Each copy can have its own colour",false),castShadow:t.boolean("Casts shadows",true,{heavy:true}),receiveShadow:t.boolean("Shows shadows falling on it",true),native:t.boolean("Draw the batch on the device in one pass",true,{advanced:true})}}),c("CameraProjectionOptions",{title:"Lens",description:"How a camera turns the world into a picture.",fields:{mode:t.choice("Natural depth or flat, map-like view",["perspective","orthographic"],"perspective",{labels:{perspective:"Natural",orthographic:"Flat"}}),fov:t.number("How wide the camera sees, top to bottom",{default:60,min:5,max:170,unit:"deg"}),near:t.number("Closest distance the camera shows",{default:.1,min:.001,max:100,unit:"m",scale:"log"}),far:t.number("Furthest distance the camera shows",{default:1e3,min:1,max:1e6,unit:"m",scale:"log",heavy:true}),height:t.number("How much of the world a flat view shows top to bottom",{default:10,min:.01,max:1e5,unit:"m",scale:"log"}),zoom:t.number("Zoom",{default:1,min:.01,max:100,unit:"times",scale:"log"}),width:t.number("Picture width the lens is shaped for",{default:1,min:1,max:16384,unit:"px",advanced:true}),viewportHeight:t.number("Picture height the lens is shaped for",{default:1,min:1,max:16384,unit:"px",advanced:true})}}),c("DebugDrawOptions",{title:"Guide lines",description:"Lines drawn over the scene to show shapes, paths and contacts.",fields:{capacity:t.integer("Most line segments drawn each frame",{default:ko,min:16,max:1048576,advanced:true}),layers:je("Which views show the lines"),depthTest:t.boolean("Hide lines behind solid things",true),renderOrder:t.integer("Draw order against other see-through things",{default:0,min:-Mo,max:Mo,unit:"none",advanced:true})}}),c("ScreenLabelsOptions",{title:"Labels",description:"Name tags and markers that follow things across the screen.",fields:{capacity:t.integer("Most labels at once",{default:Co,min:1,max:4096}),anchors:t.wiring("Where each label reads its position"),ui:t.wiring("The on-screen interface the labels draw into"),engineText:t.wiring("Text drawn in the scene instead of on the interface"),occluder:t.wiring("Hides labels behind walls"),occlusionLayers:je("Which things can hide a label"),fadeNear:t.number("Distance where labels start to fade, 0 for never",{default:0,min:0,max:1e4,unit:"m"}),fadeFar:t.number("Distance where labels are gone, 0 for never",{default:0,min:0,max:1e4,unit:"m"}),clampToEdge:t.boolean("Keep labels of things off screen pinned to the edge",false),margin:t.number("Gap kept from the screen edge",{default:0,min:0,max:512,unit:"px"})}}),c("EnvironmentOptions",{title:"Sky",description:"The sky, sun and light that surround the scene.",fields:{width:t.integer("Sky picture width",{default:256,min:16,max:4096,unit:"px",heavy:true,advanced:true}),height:t.integer("Sky picture height",{default:128,min:8,max:2048,unit:"px",heavy:true,advanced:true}),intensity:t.number("Overall sky brightness",{default:1,min:0,max:20,unit:"times"}),format:t.choice("Colour precision of the sky",["rgba16f","rgba32f"],"rgba16f",{labels:{rgba16f:"Standard",rgba32f:"High"},heavy:true,advanced:true}),sunDirection:t.vector("Where the sun sits in the sky",{default:[.4,.6,.3],min:-1,max:1,unit:"none",group:"Sun"}),sunColor:t.color("Sun colour",Lo,{group:"Sun"}),sunIntensity:t.number("Sun brightness",{default:40,min:0,max:1e3,unit:"times",group:"Sun"}),skyColor:t.color("Colour overhead",3832789,{group:"Colours"}),horizonColor:t.color("Colour at the horizon",13624309,{group:"Colours"}),groundColor:t.color("Colour below the horizon",5919302,{group:"Colours"}),color:t.color("The single colour of a plain backdrop",8421504,{group:"Colours"}),moonDirection:t.vector("Where the moon sits in a night sky",{default:[-0.3,.5,-0.6],min:-1,max:1,unit:"none",group:"Night"}),starDensity:t.number("How many stars fill a night sky",{default:.004,min:0,max:.1,unit:"fraction",group:"Night"}),seed:t.integer("Starting point for where the stars fall",{default:0,min:0,max:El,unit:"none",group:"Night"})}}),c("ApplyEnvironmentOptions",{title:"Sky and exposure",description:"The sky with how it lights the scene and how bright the picture looks.",extends:["EnvironmentOptions"],fields:{background:t.boolean("Show the sky behind the scene",true,{group:"Picture"}),backgroundBlurriness:t.number("Blur the sky behind the scene",{default:0,min:0,max:1,unit:"fraction",group:"Picture"}),environmentIntensity:t.number("How strongly the sky lights things",{default:1,min:0,max:20,unit:"times",group:"Picture"}),toneMapping:t.choice("The look of bright and dark areas",["none","linear","reinhard","aces","agx","neutral","cineon","custom"],"agx",{labels:{none:"Raw",linear:"Linear",reinhard:"Soft",aces:"Film",agx:"Natural",neutral:"Neutral",cineon:"Classic film",custom:"Custom"},group:"Picture"}),exposure:t.number("Picture brightness, each sky look picks its own when unset",{default:.5,min:0,max:10,unit:"times",group:"Picture"})}}),c("TransitionOptions",{title:"Transition",description:"How one shot changes into the next.",fields:{color:t.color("Colour faded through",0),direction:t.vector("Which way a wipe travels",{default:[1,0],min:-1,max:1,unit:"none",axes:["X","Y"]}),softness:t.number("How soft the wipe or iris edge is",{default:.05,min:0,max:1,unit:"fraction"}),center:t.vector("Where an iris opens and closes on screen",{default:[.5,.5],min:0,max:1,unit:"fraction",axes:["X","Y"]}),cellSize:t.number("Block size of a pixelate change",{default:48,min:2,max:512,unit:"px"}),noiseScale:t.number("Grain of a dissolve",{default:6,min:.1,max:100,unit:"none"}),edge:t.number("Width of the dissolve's glowing edge",{default:.08,min:0,max:1,unit:"fraction"})}}),c("CrossfadeOptions",{title:"Crossfade",description:"Blends the last picture of one shot into the next.",fields:{camera:t.thing("The camera that films the blend","camera"),cameraNode:t.wiring("The drawn view of that camera"),width:t.integer("Width of the held picture",{default:1280,min:16,max:8192,unit:"px",heavy:true}),height:t.integer("Height of the held picture",{default:720,min:16,max:8192,unit:"px",heavy:true}),fovDegrees:t.number("How wide the camera sees",{default:60,min:5,max:170,unit:"deg"}),near:t.number("Closest distance the camera shows",{default:.1,min:.001,max:100,unit:"m",scale:"log"}),aspect:t.number("Picture shape, width over height",{default:16/9,min:.1,max:10,unit:"none"}),layers:je("Which things appear in the held picture"),overlayLayer:je("The view the blend shows in")}}),c("PortLightOptions",{title:"Light",description:"A sun, lamp, spotlight, panel or sky light.",fields:{color:t.color("Light colour",Lo),intensity:t.number("Brightness",{default:1,min:0,max:1e4,unit:"times",scale:"linear"}),distance:t.number("How far a lamp reaches, 0 for no limit",{default:0,min:0,max:1e4,unit:"m"}),decay:t.number("How quickly a lamp fades with distance",{default:2,min:0,max:4,unit:"none"}),angle:t.number("Width of a spotlight's beam",{default:Math.PI/3,min:0,max:Math.PI/2,unit:"rad"}),penumbra:t.number("How soft a spotlight's edge is",{default:0,min:0,max:1,unit:"fraction"}),groundColor:t.color("Light bouncing up from the ground for a sky light",4473924),castShadow:t.boolean("Casts shadows",false,{heavy:true,group:"Shadows"}),shadowMapSize:t.integer("Shadow sharpness, 0 picks for the phone",{default:0,min:0,max:8192,unit:"px",heavy:true,group:"Shadows"}),width:t.number("Width of a panel light",{default:1,min:.01,max:1e3,unit:"m"}),height:t.number("Height of a panel light",{default:1,min:.01,max:1e3,unit:"m"})}})];var Po=[.2,.2,.2],Fo=.1,Uo=.2;var Bo="ThingPart",Go="ThingEffect",Y=50,Ho=180,Vt=.001,vl=J.map(r=>r.id),Tl=Object.fromEntries(J.map(r=>[r.id,r.label])),Wo=[c(Bo,{title:"Part",description:"One shape in a thing: what it is, where it sits, what it is made of and how it combines.",fields:{shape:t.choice("The shape",Sn,"box",{labels:{box:"Box",sphere:"Sphere",cylinder:"Cylinder",tube:"Tube",rounded:"Rounded"},group:"Shape"}),size:t.vector("Width, height and depth of a box or rounded box",{default:Po,min:Vt,max:Y,unit:"m",axes:["Width","Height","Depth"],group:"Shape"}),radius:t.number("Radius of a sphere, cylinder or tube, or the rounding of a rounded box",{default:Fo,min:Vt,max:Y,unit:"m",group:"Shape"}),length:t.number("Height of a cylinder or length of a tube",{default:Uo,min:Vt,max:Y,unit:"m",group:"Shape"}),at:t.vector("Where it sits in the thing",{default:[0,0,0],min:-Y,max:Y,unit:"m",group:"Placement"}),turn:t.vector("Which way it turns",{default:[0,0,0],min:-Ho,max:Ho,unit:"deg",group:"Placement"}),mirror:t.choice("A matching copy on the other side",Rn,"none",{labels:{none:"No copy",x:"Left and right",y:"Top and bottom",z:"Front and back"},group:"Placement"}),material:t.choice("What it is made of, which sets its weight, grip, bounce and whether it burns",vl,ht,{labels:Tl,group:"Made of"}),combine:t.choice("How it meets the parts before it",wn,"join",{labels:{join:"Join",cut:"Cut away",overlap:"Keep only the overlap"},group:"Combine"})}}),c(Go,{title:"Effect",description:"Fire, smoke, steam, sparks, confetti, water, rain, breaking apart or a sound that comes off a thing.",fields:{kind:t.choice("The effect",On,"smoke",{labels:{fire:"Fire",smoke:"Smoke",steam:"Steam",sparks:"Sparks",confetti:"Confetti",water:"Water",rain:"Rain",break:"Breaks apart",sound:"Sound"}}),startsAfter:t.number("Starts this long after it is set off",{default:0,min:0,max:600,unit:"s"}),lasts:t.number("How long it lasts, 0 to keep going",{default:0,min:0,max:600,unit:"s"}),color:t.color("Colour, for sparks and confetti",16777215),sound:t.asset("The sound it plays","sound"),at:t.vector("Where it comes off the thing",{default:[0,0,0],min:-Y,max:Y,unit:"m"}),size:t.number("How big it is",{default:.2,min:.01,max:10,unit:"m",heavy:true})}})];new TextEncoder;new TextDecoder;new TextEncoder;new TextDecoder;var $e=[1,3,8],qo=10,zo=.35,Ko=1.5,Xo=3,Yo=6,jo=24*1024*1024,$o=8,Qo=2,Zo=1024,Jo=50,ei=.3;var ti=2;var qt=4294967295,Qe=1024*1024,wl=8*Qe,Rl=$e[$e.length-1]*2,zt=()=>t.choice("Phone class the detail is planned for",["low","mid","high"],"mid",{labels:{low:"Cheaper phones",mid:"Most phones",high:"Newest phones"},heavy:true}),ni=[c("WorldColliderOptions",{title:"World collisions",description:"How solid ground and buildings are kept around moving things in a big world.",fields:{budget:t.integer("Collision pieces added or removed each step",{default:16,min:1,max:1024,heavy:true}),actors:t.integer("Moving things that keep the ground solid around them",{default:8,min:1,max:256}),stepSeconds:t.number("Time between collision updates",{default:1/60,min:1/240,max:1,unit:"s",advanced:true})}}),c("WorldStreamOptions",{title:"Big world",description:"A large place that loads around the camera as people move.",fields:{world:t.asset("The world's map","pack"),packs:t.wiring("Every part of the world loaded up front"),packPaths:t.list("Parts of the world loaded as the camera needs them",t.asset("A part of the world","pack"),{maxItems:4096}),assets:t.wiring("Reads the parts of the world"),materials:t.list("Surfaces the world's parts use",t.asset("A surface","material"),{maxItems:256}),tier:zt(),colliders:t.settings("How the ground stays solid around moving things","WorldColliderOptions")}}),c("WorldPrefetchOptions",{title:"World look-ahead",description:"Fetches the parts of a big world people are heading towards.",fields:{paths:t.list("Parts of the world, in order",t.asset("A part of the world","pack"),{maxItems:4096}),bytes:t.wiring("Size of each part"),name:t.text("Name of this look-ahead layer","world",64,{advanced:true})}}),c("SceneryLoadOptions",{title:"Captured scenery",description:"A real place captured from photos.",fields:{assets:t.wiring("Reads the captured place"),cacheBytes:t.integer("Memory kept for parts of the place already seen",{default:wl,min:Qe,max:512*Qe,unit:"bytes",heavy:true})}}),c("TerrainRecipe",{title:"Landscape shape",description:"Hills, ridges, rock, snow and sand of a landscape.",fields:{base:t.number("Ground height before any hills",{default:0,min:-1e3,max:1e3,unit:"m"}),amplitude:t.number("Height of the tallest hills",{default:60,min:0,max:2e3,unit:"m"}),octaves:t.integer("Layers of detail, from mountains down to bumps",{default:7,min:1,max:12,heavy:true}),frequency:t.number("How close together hills are",{default:.004,min:1e-4,max:.1,unit:"none",scale:"log"}),lacunarity:t.number("How much finer each layer of detail is",{default:2,min:1,max:4,unit:"times"}),gain:t.number("How strong each finer layer is",{default:.5,min:0,max:1,unit:"fraction"}),seed:t.integer("Starting point for the landscape",{default:1,min:0,max:qt,unit:"none"}),ridged:t.number("Sharp mountain ridges instead of rounded hills",{default:0,min:0,max:1,unit:"fraction"}),warp:t.number("Twists the hills into winding shapes",{default:0,min:0,max:1,unit:"fraction"}),rockSlope:t.number("Steepness where bare rock shows",{default:.25,min:0,max:1,unit:"fraction",group:"Surfaces"}),snowHeight:t.number("Height where snow starts",{default:35,min:-1e3,max:5e3,unit:"m",group:"Surfaces"}),sandHeight:t.number("Height below which sand shows",{default:0,min:-1e3,max:5e3,unit:"m",group:"Surfaces"})}}),c("TerrainOptions",{title:"Landscape",description:"Ground you can sculpt, paint and walk on.",fields:{size:t.integer("Width of the landscape",{default:2048,min:64,max:65536,unit:"m",heavy:true}),spacing:t.number("Distance between height points",{default:1,min:.1,max:64,unit:"m",heavy:true}),center:t.vector("Middle of the landscape",{default:[0,0],min:-1e6,max:1e6,unit:"m",axes:["X","Z"]}),heightMin:t.number("Lowest ground",{default:-64,min:-1e4,max:1e4,unit:"m"}),heightRange:t.number("Height between the lowest and highest ground",{default:512,min:1,max:2e4,unit:"m"}),tier:zt(),recipe:t.settings("The shape of hills, rock, snow and sand","TerrainRecipe",{group:"Shape"}),pack:t.asset("A sculpted landscape saved earlier","pack")}}),c("GrassOptions",{title:"Grass",description:"Blades of grass that cover the ground and sway.",fields:{seed:t.integer("Starting point for where blades grow",{default:1,min:0,max:qt,unit:"none"}),density:t.number("Blades in each square metre",{default:96,min:1,max:1024,unit:"count",heavy:true}),height:t.vector("Shortest and tallest blades",{default:[.35,.8],min:.01,max:5,unit:"m",axes:["Shortest","Tallest"]}),width:t.vector("Thinnest and widest blades",{default:[.03,.06],min:.001,max:1,unit:"m",axes:["Thinnest","Widest"]}),radius:t.number("How far from the camera grass is drawn",{default:60,min:5,max:500,unit:"m",heavy:true}),maxSlope:t.number("Steepest ground grass grows on",{default:.35,min:0,max:1,unit:"fraction"}),layer:t.integer("Which painted ground layer grass grows on",{default:0,min:0,max:7,unit:"none"}),color:t.rgb("Blade colour",[.1,.22,.04]),tipBrightness:t.number("How much brighter the tips are",{default:3,min:0,max:10,unit:"times"})}}),c("LayerOptions",{title:"Ground paint",description:"A surface painted onto the landscape, such as grass, dirt or rock.",fields:{color:t.rgb("Surface colour",[.5,.45,.35]),roughness:t.number("How rough rather than shiny it looks",{default:.85,min:0,max:1,unit:"fraction"}),tiling:t.number("How often its pattern repeats",{default:4,min:.1,max:64,unit:"times"}),heightScale:t.number("Depth of its bumps",{default:1,min:0,max:4,unit:"times"}),variation:t.number("How much it varies across the ground",{default:.25,min:0,max:1,unit:"fraction"}),normalStrength:t.number("Strength of its fine surface detail",{default:1,min:0,max:4,unit:"times"})}}),c("PlanetOptions",{title:"Planet",description:"A whole round world you can fly around.",fields:{radius:t.number("Planet size from its centre to the ground",{default:6e3,min:10,max:1e7,unit:"m",scale:"log"}),levels:t.integer("Levels of detail as you get closer",{default:6,min:1,max:20,heavy:true}),amplitude:t.number("Height of the tallest mountains",{default:60,min:0,max:1e5,unit:"m"}),seed:t.integer("Starting point for the planet's shape",{default:1,min:0,max:qt,unit:"none"}),tier:zt()}}),c("PredictorOptions",{title:"Look-ahead",description:"Guesses where people are heading so what they need next is already there.",fields:{horizons:t.list("How far ahead to look",t.number("Seconds ahead",{default:1,min:.1,max:120,unit:"s"}),{maxItems:8,default:$e}),maxSpeed:t.number("Fastest people are expected to move",{default:qo,min:.1,max:1e3,unit:"m/s"}),spread:t.number("How much the guess widens with distance",{default:zo,min:0,max:5,unit:"none"}),minSpread:t.number("Narrowest the guess gets",{default:Ko,min:.01,max:100,unit:"m"}),turnPenalty:t.number("How unlikely sharp turns are",{default:Xo,min:1,max:20,unit:"times"}),interval:t.integer("Frames between new guesses",{default:Yo,min:1,max:120}),budgetBytes:t.integer("Most data fetched ahead of need",{default:jo,min:0,max:1024*Qe,unit:"bytes",heavy:true}),maxPending:t.integer("Most fetches at once",{default:$o,min:1,max:64}),maxSpeculative:t.integer("Most fetches on a hunch",{default:Qo,min:1,max:64}),releaseSeconds:t.number("How long unused things stay before they are let go",{default:Rl,min:.1,max:600,unit:"s"}),capacity:t.integer("Most things tracked",{default:Zo,min:1,max:65536,advanced:true}),teleport:t.number("A jump this far counts as a teleport and starts over",{default:Jo,min:1,max:1e5,unit:"m"}),smoothing:t.number("How much movement is smoothed before guessing",{default:ei,min:.001,max:1,unit:"fraction"}),saturationSeconds:t.number("How long a busy connection waits before new fetches",{default:ti,min:.01,max:60,unit:"s"}),reach:t.wiring("Where things can be reached from")}}),c("PrefetchStreamOptions",{title:"Look-ahead stream",description:"Look-ahead tied to the parts of a Production.",extends:["PredictorOptions"],fields:{stalled:t.wiring("Reports when play is waiting on data"),assets:t.wiring("Where the parts are fetched from")}}),c("CompileSceneOptions",{title:"Scene layout",description:"The kinds of things a laid-out scene can place.",fields:{catalogue:t.wiring("Sizes and anchors of every kind of thing")}}),c("SlotSceneOptions",{title:"Template scene",description:"Turns a laid-out scene into a template's scene slot.",fields:{area:t.vector("Size of the scene",{default:[20,20],min:0,max:1e5,unit:"m",axes:["Width","Depth"]}),points:t.wiring("Named points in the scene"),roles:t.wiring("Which template role each group or point plays"),catalogue:t.wiring("Sizes of every kind of thing")}}),c("RemixOptions",{title:"Remix",description:"Where a remix came from and what it was made from.",fields:{parent:t.wiring("The Production this remix came from"),sources:t.wiring("The parts the remix was made from")}}),c("AssignOptions",{title:"Fill template",description:"Fills a template's slots.",fields:{base:t.wiring("Slot values to start from"),readFile:t.wiring("Reads files the slots name")}})];var Kt=new Ce([...ho,...Wo,...Oo,...To,...vr,...Do,...so,...Tr,...Xn,...$r,...ni,...zr,...Rr,...xr,...pr,...go]);var Ol=["spawn_point","waypoint"],kl=[.5,.5],Cl=[{kind:"shopper",label:"Shoppers"},{kind:"trader",label:"Traders"},{kind:"walker",label:"Walkers"},{kind:"porter",label:"Porters"},{kind:"child",label:"Children"}];function Nl(r){let e=r.split("_").join(" ");return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function ri(r=Ee){let e=[];for(let[o,i]of Object.entries(r))Ol.includes(o)||e.push({kind:o,label:Nl(o),layer:"prop",footprint:i.footprint});let n=Cl.map(o=>({kind:o.kind,label:o.label,layer:"person",footprint:r[o.kind]?.footprint??kl}));return {placeables:e,people:n}}var oi="CimplifyStudioKernel",Ll=H|ue,Ml=["low","mid","high"],Dl={low:"cheaper phones",mid:"most phones",high:"newer phones"},Pl={ground:"the ground",roads:"roads",buildings:"buildings",props:"stalls and props",crowds:"people",lights:"lights",sounds:"sounds"};function j(r){try{return JSON.parse(r)}catch{return null}}function Fl(r){let e={};for(let n of r){if(!Kt.has(n))continue;let o=Kt.resolve(n),i={};for(let s of o.fields)i[s.name]={...s.setting,group:s.group};e[n]={name:n,title:o.schema.title,description:o.schema.description,order:o.fields.map(s=>s.name),fields:i};}return e}function Ul(){return J.map(r=>({id:r.id,label:r.label,color:r.look.color,breaks:r.breaks}))}function Hl(r){try{let e=Cn(r),n=e.levels[0].mesh;return {ok:!0,reason:null,cost:e.cost,mass_kg:e.mass.mass,breaks:gn(r.parts.map(o=>o.material)),levels:e.levels.map(o=>({name:o.name,triangles:o.mesh.triangles,dropped:o.dropped})),mesh:{positions:Array.from(n.positions),normals:Array.from(n.normals),indices:Array.from(n.indices),groups:n.groups}}}catch(e){if(e instanceof ee)return {ok:false,reason:e.message};throw e}}function Bl(r){return r.length<=1?r.join(""):`${r.slice(0,-1).join(", ")} and ${r[r.length-1]}`}function Gl(r){let e=Bl(r.layers.map(n=>Pl[n.layer]));return `${Wl(Dl[r.tier])} stay heavy even with no people: ${e} weigh too much on their own.`}function Wl(r){return r.length===0?r:r[0].toUpperCase()+r.slice(1)}function Vl(r,e){let n=fn(e,r.crowdCaps??{});if(n===null)return null;let o={};for(let i of Ml){let s=n.caps[i];typeof s=="number"&&(o[i]=s);}return {crowd_caps:o,fixes:n.fixes.map(i=>({tier:i.tier,from:i.from,to:i.to})),still_heavy:n.stillHeavy.map(i=>({tier:i.tier,without_people:i.withoutPeople,budget:i.budget,layers:i.layers.map(s=>({layer:s.layer,cost:s.cost,share:s.share})),summary:Gl(i)}))}}function ql(r){let e=_n(r),n=Array.from(e.grid.cells,o=>o&Ll);return {grid:{columns:e.grid.columns,rows:e.grid.rows,cell:e.grid.cell,cells:n},placements:e.placements,people:e.people,weight:{total:e.weight.total,layers:e.weight.layers,tiers:e.weight.tiers,tier_totals:e.weight.tierTotals,tier_people:e.weight.tierPeople},checks:e.checks.map(o=>({id:o.id,ok:o.ok,summary:o.summary})),fewer_people:Vl(r,e.weight)}}var zl=JSON.stringify({ok:false,reason:"That could not be read."}),ii=["low","mid","high"];function Kl(r){if(typeof r!="object"||r===null)return false;let e=r;return typeof e.label=="string"&&typeof e.bytes=="number"&&Number.isFinite(e.bytes)&&typeof e.beforePlay=="boolean"&&(e.tier===null||e.tier===void 0||ii.includes(e.tier))}function Xl(r){if(typeof r!="object"||r===null)return null;let e=r;return typeof e.tier=="string"&&ii.includes(e.tier)&&typeof e.frames=="object"&&typeof e.memory=="object"&&typeof e.heat=="object"?e:null}function si(){return {schemas(r){let e=j(r),n=Array.isArray(e)?e.filter(o=>typeof o=="string"):[];return JSON.stringify(Fl(n))},materials(){return JSON.stringify(Ul())},catalogue(){return JSON.stringify(ri())},compileThing(r){let e=j(r);return e===null||!Array.isArray(e.parts)?zl:JSON.stringify(Hl({...e,effects:e.effects??[]}))},buildPlace(r){let e=j(r);if(e===null||!Array.isArray(e.size))return "null";try{return JSON.stringify(ql(e))}catch{return "null"}},outcome(r,e){let n=j(r);return Array.isArray(n)?JSON.stringify(Un(n.filter(Kl),Xl(j(e)))):"null"},simplifyRoad(r,e){let n=j(r),o=j(e);return Array.isArray(n)?JSON.stringify(ln(n,typeof o=="number"&&o>0?o:0)):"[]"}}}globalThis[oi]=si();})();
1
+ (function(){'use strict';function Xt(r){let e=[];for(let n=0;n<r.length;n++){let o=r.charCodeAt(n);if(o>=55296&&o<56320&&n+1<r.length){let i=r.charCodeAt(n+1);i>=56320&&i<57344&&(o=65536+((o&1023)<<10)+(i&1023),n++);}o<128?e.push(o):o<2048?e.push(192|o>>6,128|o&63):o<65536?e.push(224|o>>12,128|o>>6&63,128|o&63):e.push(240|o>>18,128|o>>12&63,128|o>>6&63,128|o&63);}return Uint8Array.from(e)}function ai(r){let e="";for(let n=0;n<r.length;){let o=r[n],i=65533,s=1;o<128?i=o:o>=240&&n+3<r.length?(i=(o&7)<<18|(r[n+1]&63)<<12|(r[n+2]&63)<<6|r[n+3]&63,s=4):o>=224&&n+2<r.length?(i=(o&15)<<12|(r[n+1]&63)<<6|r[n+2]&63,s=3):o>=192&&n+1<r.length&&(i=(o&31)<<6|r[n+1]&63,s=2),e+=String.fromCodePoint(i),n+=s;}return e}var Je=class{constructor(){this.encoding="utf-8";}encode(e=""){return Xt(e)}encodeInto(e,n){let o=Xt(e),i=Math.min(o.length,n.length);return n.set(o.subarray(0,i)),{read:i===o.length?e.length:0,written:i}}},et=class{constructor(){this.encoding="utf-8";}decode(e){if(e===void 0)return "";let n=e instanceof ArrayBuffer?new Uint8Array(e):new Uint8Array(e.buffer,e.byteOffset,e.byteLength);return ai(n)}},Ae=globalThis;typeof Ae.TextEncoder!="function"&&(Ae.TextEncoder=Je);typeof Ae.TextDecoder!="function"&&(Ae.TextDecoder=et);var Ee={bench:{footprint:[1.6,.6],height:.9,size:"medium",tags:["street","seat","rest"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,.05],front:[0,0,.6],edge:[.8,.45,0]}},street_lamp:{footprint:[.4,.4],height:4.5,size:"tiny",tags:["street","light"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,4.5,0],front:[0,0,.5]}},bus_stop:{footprint:[3.5,1.5],height:2.6,size:"medium",tags:["street","transit","shelter"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,-0.3],front:[0,0,1.2],top:[0,2.6,0]}},trash_bin:{footprint:[.5,.5],height:1,size:"small",tags:["street","utility"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.5],top:[0,1,0]}},bollard:{footprint:[.25,.25],height:1,size:"tiny",tags:["street","barrier"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1,0]}},fire_hydrant:{footprint:[.4,.4],height:.8,size:"tiny",tags:["street","utility"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.5]}},mailbox:{footprint:[.5,.5],height:1.2,size:"small",tags:["street","utility"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.6],top:[0,1.2,0]}},bike_rack:{footprint:[2,.6],height:.9,size:"medium",tags:["street","transit"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1],edge:[1,.5,0]}},planter:{footprint:[1.2,1.2],height:.8,size:"small",tags:["street","plant"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.8,0],edge:[.6,.5,0]}},fountain:{footprint:[4,4],height:2.2,size:"large",tags:["street","landmark","water"],up:"+y",forward:"+z",solid:true,anchors:{edge:[2,.5,0],front:[0,0,2.4]}},kiosk:{footprint:[2.5,2.5],height:3,size:"medium",tags:["street","shop"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1.6],door:[0,0,1.25],top:[0,3,0]}},parked_car:{footprint:[1.9,4.5],height:1.5,size:"large",tags:["street","vehicle"],up:"+y",forward:"+z",solid:true,anchors:{door:[1,0,.3],front:[0,0,2.6],back:[0,0,-2.6]}},spawn_point:{footprint:[.8,.8],height:0,size:"small",tags:["street","marker","gameplay"],up:"+y",forward:"+z",solid:false,anchors:{front:[0,0,0]}},waypoint:{footprint:[.5,.5],height:0,size:"small",tags:["street","marker","gameplay"],up:"+y",forward:"+z",solid:false,anchors:{front:[0,0,0]}},market_stall:{footprint:[3,2],height:2.6,size:"medium",tags:["market","shop","shelter"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1.3],edge:[0,.9,.9],top:[0,.9,.2],back:[0,0,-1.2]}},crate_stack:{footprint:[1.2,1.2],height:1.4,size:"small",tags:["market","storage"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1.4,0]}},barrel:{footprint:[.7,.7],height:1,size:"small",tags:["market","storage"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1,0]}},produce_table:{footprint:[2,1],height:.9,size:"medium",tags:["market","shop","table"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.9,0],front:[0,0,.8],edge:[0,.9,.5]}},parasol:{footprint:[2.4,2.4],height:2.5,size:"medium",tags:["market","shade"],up:"+y",forward:"+z",solid:false,anchors:{top:[0,2.5,0]}},cart:{footprint:[1.2,2.2],height:1.3,size:"medium",tags:["market","vehicle","shop"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.9,0],front:[0,0,1.4]}},goal:{footprint:[7.3,2],height:2.44,size:"large",tags:["sports","football"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1.5],edge:[3.65,1.2,0]}},basketball_hoop:{footprint:[1.8,2],height:3.95,size:"medium",tags:["sports","basketball"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,2.2],top:[0,3.05,1.2]}},bleacher:{footprint:[8,3],height:2.4,size:"large",tags:["sports","seat","crowd"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,1.2,0],front:[0,0,1.8]}},scoreboard:{footprint:[4,.6],height:5,size:"large",tags:["sports","display"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,1]}},corner_flag:{footprint:[.2,.2],height:1.5,size:"tiny",tags:["sports","football","marker"],up:"+y",forward:"+z",solid:false,anchors:{top:[0,1.5,0]}},ball_rack:{footprint:[1.5,.6],height:1.1,size:"medium",tags:["sports","storage"],up:"+y",forward:"+z",solid:true,anchors:{front:[0,0,.7],top:[0,1.1,0]}},table:{footprint:[1.6,.9],height:.75,size:"medium",tags:["interior","table"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.75,0],edge:[0,.75,.45],front:[0,0,.9]}},chair:{footprint:[.5,.5],height:.9,size:"small",tags:["interior","seat"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,0],front:[0,0,.5]}},sofa:{footprint:[2.2,.9],height:.85,size:"medium",tags:["interior","seat","rest"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.45,.1],front:[0,0,.9]}},bed:{footprint:[1.6,2.1],height:.6,size:"medium",tags:["interior","rest"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.6,0],edge:[.8,.5,0],front:[.95,0,0]}},shelf:{footprint:[1.2,.4],height:2,size:"small",tags:["interior","storage"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,2,0],front:[0,0,.6]}},counter:{footprint:[3,.8],height:1.05,size:"medium",tags:["interior","shop","table"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1.05,0],front:[0,0,.9],back:[0,0,-0.9]}},door:{footprint:[1,.2],height:2.1,size:"small",tags:["interior","passage"],up:"+y",forward:"+z",solid:false,anchors:{door:[0,0,0],front:[0,0,.6],back:[0,0,-0.6]}},rug:{footprint:[2,3],height:.02,size:"medium",tags:["interior","decor","flat"],up:"+y",forward:"+z",solid:false,anchors:{top:[0,.02,0]}},lamp:{footprint:[.3,.3],height:.5,size:"tiny",tags:["interior","light"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.5,0]}},tree:{footprint:[1,1],height:7,size:"small",tags:["nature","plant","shade"],up:"+y",forward:"+z",solid:true,anchors:{edge:[.5,0,0]}},bush:{footprint:[1.4,1.4],height:1.2,size:"small",tags:["nature","plant"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,1.2,0]}},rock:{footprint:[1.6,1.2],height:.9,size:"medium",tags:["nature","stone"],up:"+y",forward:"+z",solid:true,anchors:{top:[0,.9,0],seat:[0,.6,.3]}},log:{footprint:[2.5,.5],height:.5,size:"medium",tags:["nature","seat","wood"],up:"+y",forward:"+z",solid:true,anchors:{seat:[0,.5,0],front:[0,0,.6]}},flower_bed:{footprint:[2,1],height:.4,size:"medium",tags:["nature","plant","flat"],up:"+y",forward:"+z",solid:false,anchors:{edge:[1,.2,0]}}};var Qt=new Float64Array(1),Yt=new Uint32Array(Qt.buffer),nt=new Float32Array(1),Zt=new Uint32Array(nt.buffer),Q=Math.fround;function se(r){return nt[0]=r,Zt[0]}function ae(r){return Zt[0]=r>>>0,nt[0]}function li(r,e){return Yt[0]=e>>>0,Yt[1]=r>>>0,Qt[0]}function x(r){return li(Number.parseInt(r.slice(0,8),16),Number.parseInt(r.slice(8),16))}var Jt=["3ff0000000000000","3fefd9b0d3158574","3fefb5586cf9890f","3fef9301d0125b51","3fef72b83c7d517b","3fef54873168b9aa","3fef387a6e756238","3fef1e9df51fdee1","3fef06fe0a31b715","3feef1a7373aa9cb","3feedea64c123422","3feece086061892d","3feebfdad5362a27","3feeb42b569d4f82","3feeab07dd485429","3feea47eb03a5585","3feea09e667f3bcd","3fee9f75e8ec5f74","3feea11473eb0187","3feea589994cce13","3feeace5422aa0db","3feeb737b0cdc5e5","3feec49182a3f090","3feed503b23e255d","3feee89f995ad3ad","3feeff76f2fb5e47","3fef199bdd85529c","3fef3720dcef9069","3fef5818dcfba487","3fef7c97337b9b5f","3fefa4afa2a490da","3fefd0765b6e4540"];Jt.map(r=>Number.parseInt(r.slice(0,8),16));Jt.map(r=>Number.parseInt(r.slice(8),16));[x("3fac6af84b912394"),x("3fcebfce50fac4f3"),x("3fe62e42ff0c52d6")];[x("3ebc6af84b912394"),x("3f2ebfce50fac4f3"),x("3f962e42ff0c52d6")];x("40471547652b82fe");x("4338000000000000");x("42e8000000000000");["3ff661ec79f8f3be","3ff571ed4aaf883d","3ff49539f0f010b0","3ff3c995b0b80385","3ff30d190c8864a5","3ff25e227b0b8ea0","3ff1bb4a4a1a343f","3ff12358f08ae5ba","3ff0953f419900a7","3ff0000000000000","3fee608cfd9a47ac","3feca4b31f026aa0","3feb2036576afce6","3fe9c2d163a1aa2d","3fe886e6037841ed","3fe767dcf5534862"].map(x);["bfd57bf7808caade","bfd2bef0a7c06ddb","bfd01eae7f513a67","bfcb31d8a68224e9","bfc6574f0ac07758","bfc1aa2bc79c8100","bfba4e76ce8c0e5e","bfb1973c5a611ccc","bfa252f438e10c1e","0000000000000000","3faaa5aa5df25984","3fbc5e53aa362eb4","3fc526e57720db08","3fcbc2860d224770","3fd1058bc8a07ee1","3fd4043057b6ee09"].map(x);["bfdefec65b963019","bfdb0b6832d4fca4","bfd7418b0a1fb77b","bfd39de91a6dcf7b","bfd01d9bf3f2b631","bfc97c1d1b3b7af0","bfc2f9e393af3c9f","bfb960cbbf788d5c","bfaa6f9db6475fce","0000000000000000","3fb338ca9f24f53d","3fc476a9543891ba","3fce840b4ac4e4d2","3fd40645f0c6651c","3fd88e9c2c1b9ff8","3fdce0a44eb17bcc"].map(x);x("3fe62e42fefa39ef");["bfd00ea348b88334","3fd5575b0be00b6a","bfdffffef20a4123"].map(x);["bfd712b6f70a7e4d","3fdecabf496832e0","bfe715479ffae3de","3ff715475f35c8b8"].map(x);["3fd27616c9496e0b","bfd71969a075c67a","3fdec70a6ca7badd","bfe7154748bef6c8","3ff71547652ab82b"].map(x);x("405fffffffd1d571");x("405fffffffa3aae2");ae(2139095039);var ci=x("41645f306dc9c883"),ui=x("3ff921fb54442d18"),di=x("3c1921fb54442d18"),mi=x("bfdffffffd0c621c"),pi=x("3fa55553e1068f19"),hi=x("bf56c087e89a359d"),fi=x("3ef99343027bf8c3"),_i=x("bfc555545995a603"),yi=x("3f81107605230bc4"),bi=x("bf2994eb3774cf24"),jt=[1,-1,-1,1],gi=1071,xi=8388608,tt=[162,41721,10680707,2734261102,4186140238,2205044292,1850622997,1313084713,1142237692,355073063,704390999,4230436817,660066805,1473377588,3522507997,4113882560,886948059,3720403810,3235603093,3680671129,1653971260,2509847619,2570863504,1011060801],Si=Math.PI/4,Ai=Math.PI/2,Ei=x("3fda827999fcef34"),en=14,vi=Array.from({length:en},(r,e)=>(e%2===0?1:-1)*(1/(2*e+1))),ve=(1n<<64n)-1n,Ti=(1n<<32n)-1n;function $t(r,e,n,o){let i=r*o,s=r*r,a=s*i,l=s*s,u=a*s,d=l*s,m=hi*n+s*(fi*n),p=yi+s*bi,h=n+s*(mi*n),f=i+a*_i,y=h+l*(pi*n),_=f+u*p,b=y+d*m;return (e&1)!==0?[b,_]:[_,b]}function tn(r){let e=Q(r),n=se(e);if((n>>>20&2047)<gi){let b=(e*ci|0)+xi>>24;return $t(e-b*ui,b,(b&2)!==0?-1:1,jt[b&3])}if(!Number.isFinite(e))return [Number.NaN,Number.NaN];let o=n>>>31,i=n>>>26&15,s=n>>>23&7,a=BigInt((n&16777215|8388608)<<s>>>0),l=a*BigInt(tt[i])&Ti,u=a*BigInt(tt[i+4]),m=(a*BigInt(tt[i+8])>>32n|l<<32n)&ve;m=m+u&ve;let p=(m+(1n<<61n)&ve)>>62n;m=m-(p<<62n)&ve;let h=m>=1n<<63n?m-(1n<<64n):m,f=Number(h)*di,y=Number(p)+o|0;return $t(f,Number(p),(y&2)!==0?-1:1,jt[y&3])}function rt(r){return Q(tn(r)[0])}function ot(r){return Q(tn(r)[1])}function Ii(r){let e=r>Ei,n=e?(r-1)/(r+1):r,o=n*n,i=0;for(let s=en-1;s>=0;s--)i=vi[s]+o*i;return (e?Si:0)+n*i}function wi(r,e){if(Number.isNaN(e)||Number.isNaN(r))return Number.NaN;let n=Math.abs(e),o=Math.abs(r),i=Math.max(n,o),s=Math.min(n,o),a=i===0?0:s===Number.POSITIVE_INFINITY?1:s/i,l=Ii(a);return o>n&&(l=Ai-l),(e<0||Object.is(e,-0))&&(l=Math.PI-l),r<0||Object.is(r,-0)?-l:l}function it(r,e){return Q(wi(Q(r),Q(e)))}var Te=Math.fround;function v(r){return rt(Te(r))}function w(r){return ot(Te(r))}function rn(r,e){return it(Te(r),Te(e))}var Di=new Uint8Array(Uint16Array.of(1).buffer)[0]===1,Ie=Di?Int32Array.of(0,1,2,3):Int32Array.of(3,2,1,0);function le(r,e){let n=(r&65535)+(e&65535);return (r>>>16)+(e>>>16)+(n>>>16)<<16|n&65535}var we=class{constructor(e){this.state=new Uint32Array(4);this.output=new Uint32Array(2);this.words=new Int32Array(this.state.buffer);this.drawn=new Int32Array(this.output.buffer);this.limbs=new Int32Array(7);this.cell=new Float64Array(1);this.halves=new Uint16Array(this.cell.buffer);this.views=[this.state,this.output];this.reseed(e);}rollbackViews(){return this.views}get seed(){return this.output[1]}reseed(e){this.output[1]=e;let n=this.output[1];for(let o=0;o<4;o++){n=n+2654435769>>>0;let i=n;i=Math.imul(i^i>>>16,2246822507),i=Math.imul(i^i>>>13,3266489909),this.state[o]=(i^i>>>16)>>>0;}for(let o=0;o<12;o++)this.advance();}nextUint32(){return this.advance(),this.output[0]}float(){return this.advance(),this.output[0]/4294967296}range(e,n){return this.advance(),e+(n-e)*(this.output[0]/4294967296)}rangeInto(e,n,o,i){this.advance(),e[n]=o+(i-o)*(this.output[0]/4294967296);}int(e,n){return this.advance(),e+(this.output[0]/4294967296*(n-e+1)|0)}chance(e){return this.advance(),this.output[0]/4294967296<e}centeredInto(e,n,o,i,s){this.advance();let a=this.drawn[0]^-2147483648,l=a>>>31,u=l===1?~a:a,d=(u&65535)+l,m=u>>>16;d>65535&&(d=0,m++);let p=o*d,h=o*m;h+=p>>>16,p&=65535;let f=h>>>7;if(i[s]=(f^-l)+l,h===0&&p===0){e[n]=0;return}let y=h!==0?47-Math.clz32(h):31-Math.clz32(p),_=this.limbs;_[0]=p,_[1]=h&65535,_[2]=h>>>16,_[y>>4]&=~(1<<(y&15)),_[3]=0,_[4]=0,_[5]=0,_[6]=0;let b=52-y;for(let I=0;I<3;I++){let $=_[I];if($===0)continue;let ie=I*16+b,Ze=ie>>4,Se=ie&15;_[3+Ze]|=($&65535>>>Se)<<Se,Se>0&&Ze+1<4&&(_[3+Ze+1]|=$>>>16-Se);}let O=this.halves,N=l<<15|y+992<<4|_[6]&15;O[Ie[0]]=_[3],O[Ie[1]]=_[4],O[Ie[2]]=_[5],O[Ie[3]]=N,e.set(this.cell,n);}advance(){let e=this.words,n=e[0],o=e[1],i=e[2],s=e[3],a=le(le(n,o),s);e[3]=le(s,1),e[0]=o^o>>>9,e[1]=le(i,i<<3);let l=i<<21|i>>>11;e[2]=le(l,a),this.drawn[0]=a;}saveState(e){e.set(this.state);}restoreState(e){this.state.set(e);}};var H=1,ue=2,ce=4,Re=.5,at=class{constructor(e,n=Re){this.size=e;this.cell=n;this.columns=Math.max(1,Math.ceil(e[0]/n)),this.rows=Math.max(1,Math.ceil(e[1]/n)),this.cells=new Uint8Array(this.columns*this.rows);}index(e,n){let o=Math.floor(e/this.cell),i=Math.floor(n/this.cell);return o<0||i<0||o>=this.columns||i>=this.rows?-1:i*this.columns+o}at(e,n){let o=this.index(e,n);return o<0?H:this.cells[o]}centre(e){return [(e%this.columns+.5)*this.cell,(Math.floor(e/this.columns)+.5)*this.cell]}forRect(e,n,o,i){let s=w(o),a=v(o),l=n[0]/2,u=n[1]/2,d=Math.hypot(l,u),m=Math.max(0,Math.floor((e[0]-d)/this.cell)),p=Math.min(this.columns-1,Math.floor((e[0]+d)/this.cell)),h=Math.max(0,Math.floor((e[1]-d)/this.cell)),f=Math.min(this.rows-1,Math.floor((e[1]+d)/this.cell));for(let y=h;y<=f;y++)for(let _=m;_<=p;_++){let b=(_+.5)*this.cell-e[0],O=(y+.5)*this.cell-e[1],N=b*s-O*a,I=b*a+O*s;if(Math.abs(N)<=l&&Math.abs(I)<=u&&!i(y*this.columns+_))return false}return true}mark(e,n,o,i){this.forRect(e,n,o,s=>(this.cells[s]|=i,true));}clear(e,n,o,i){return e[0]>=0&&e[1]>=0&&e[0]<=this.size[0]&&e[1]<=this.size[1]&&this.forRect(e,n,o,a=>(this.cells[a]&i)===0)}markRoad(e){let n=e.width/2;for(let o=0;o+1<e.points.length;o++){let i=e.points[o],s=e.points[o+1],a=Math.hypot(s[0]-i[0],s[1]-i[1]);if(a===0)continue;let l=rn(s[0]-i[0],s[1]-i[1]);this.mark([(i[0]+s[0])/2,(i[1]+s[1])/2],[e.width,a+n],l,ue);}}},Pi=[.5,.5];function de(r,e){let n=r[e];return n===void 0?{footprint:Pi,solid:true}:{footprint:n.footprint,solid:n.solid}}function lt(r,e,n){let{footprint:o,solid:i}=de(e,n.kind);r.mark(n.at,o,n.yaw,i?H|ce:ce);}function on(r,e,n,o=Re){let i=new at(r.size,o);for(let s of r.roads)i.markRoad(s);for(let s of n)lt(i,e,s);return i}var Fi=12,sn=2*Math.PI,an=[.5,.5];function ct(r,e,n){if(r.kinds.length===0||r.count<=0)return [];let o=new we(r.seed),i=r.layer==="props"?H|ce|ue:H,s=[],a=r.spacing*r.spacing,l=r.count*Fi;for(let u=0;u<l&&s.length<r.count;u++){let d=o.float()*sn,m=Math.sqrt(o.float())*r.radius,p=[r.at[0]+w(d)*m,r.at[1]+v(d)*m],h=r.kinds[o.int(0,r.kinds.length-1)],f=o.float()*sn;if(s.some(b=>(b.at[0]-p[0])**2+(b.at[1]-p[1])**2<a))continue;let y=r.layer==="crowds"?an:de(n,h).footprint;if(!e.clear(p,y,f,i))continue;let _={kind:h,at:p,yaw:f};r.layer==="props"?lt(e,n,_):e.mark(p,an,f,ce),s.push(_);}return s}function ln(r,e){if(r.length<=2)return [...r];let n=new Uint8Array(r.length);n[0]=1,n[r.length-1]=1;let o=[[0,r.length-1]];for(;o.length>0;){let[i,s]=o.pop(),a=r[i],l=r[s],u=l[0]-a[0],d=l[1]-a[1],m=Math.hypot(u,d),p=-1,h=e;for(let f=i+1;f<s;f++){let y=r[f],_=m===0?Math.hypot(y[0]-a[0],y[1]-a[1]):Math.abs(d*y[0]-u*y[1]+l[0]*a[1]-l[1]*a[0])/m;_>h&&(h=_,p=f);}p<0||(n[p]=1,o.push([i,p],[p,s]));}return r.filter((i,s)=>n[s]===1)}var Ui="shop",Hi=0,cn=1;function Bi(r,e){let n=new Uint8Array(r.cells.length),o=new Int32Array(r.cells.length),i=0,s=0,a=l=>{l<0||n[l]!==Hi||(r.cells[l]&H)!==0||(n[l]=cn,o[s++]=l);};for(let l of e)a(r.index(l[0],l[1]));if(e.length===0){for(let l=0;l<r.columns;l++)a(l),a((r.rows-1)*r.columns+l);for(let l=0;l<r.rows;l++)a(l*r.columns),a(l*r.columns+r.columns-1);}for(;i<s;){let l=o[i++],u=l%r.columns;u>0&&a(l-1),u<r.columns-1&&a(l+1),l>=r.columns&&a(l-r.columns),l+r.columns<r.cells.length&&a(l+r.columns);}return n}function Gi(r,e,n,o){let{footprint:i}=de(n,o.kind),s=[i[0]+r.cell*2,i[1]+r.cell*2],a=false;return r.forRect(o.at,s,o.yaw,l=>(e[l]===cn&&(a=true),!a)),a}function un(r,e,n,o){let i=Bi(e,r.gates.filter(u=>(e.at(u[0],u[1])&H)===0)),s=[];o.forEach((u,d)=>{n[u.kind]?.tags.includes(Ui)&&!Gi(e,i,n,u)&&s.push(d);});let a=[];r.gates.forEach((u,d)=>{(e.at(u[0],u[1])&H)!==0&&a.push(d);});let l=[];return o.forEach((u,d)=>{(u.at[0]<0||u.at[1]<0||u.at[0]>r.size[0]||u.at[1]>r.size[1])&&l.push(d);}),[{id:"reachable",ok:s.length===0,summary:s.length===0?"Every stall can be reached on foot":`${s.length} ${s.length===1?"stall cannot":"stalls cannot"} be reached on foot`,offenders:s},{id:"gates",ok:a.length===0,summary:a.length===0?"Nothing blocks the gates":`${a.length} ${a.length===1?"gate is":"gates are"} blocked`,offenders:a},{id:"inside",ok:l.length===0,summary:l.length===0?"Everything sits inside the place":`${l.length} ${l.length===1?"thing sits":"things sit"} outside the place`,offenders:l}]}var K={ground:40,roads:20,buildings:300,props:60,crowds:120,lights:80,sounds:10},Wi=1e3,me={low:3e4,mid:8e4,high:2e5},Vi=.6,qi=.95,dn={};function mn(r,e){return {ground:Math.ceil(r.size[0]*r.size[1]/Wi),roads:r.roads.reduce((n,o)=>n+Math.max(0,o.points.length-1),0),buildings:r.buildings.length,props:r.props.length+e.props,crowds:r.crowds.reduce((n,o)=>n+o.count,0)+e.crowds,lights:r.lights.length,sounds:r.sounds.length}}function ut(r,e){let n=me[e];return r<=n*Vi?"light":r<=n?"fine":"heavy"}function pn(r,e,n){let o=e[n];return o==null?r:Math.max(0,Math.min(r,Math.floor(o)))}function hn(r,e=dn){let n=Object.keys(K).map(l=>({layer:l,count:r[l],cost:r[l]*K[l],share:0})),o=n.reduce((l,u)=>l+u.cost,0),i=o-r.crowds*K.crowds,s=l=>pn(r.crowds,e,l),a=l=>i+s(l)*K.crowds;return {total:o,layers:n.map(l=>({...l,share:o===0?0:l.cost/o})).sort((l,u)=>u.cost-l.cost),tiers:{low:ut(a("low"),"low"),mid:ut(a("mid"),"mid"),high:ut(a("high"),"high")},tierTotals:{low:a("low"),mid:a("mid"),high:a("high")},tierPeople:{low:s("low"),mid:s("mid"),high:s("high")}}}function zi(r,e,n="crowds"){let o=me[e]*qi,i=r.tierTotals[e];if(i<=me[e])return null;let s=r.layers.find(d=>d.layer===n);if(s===void 0)return null;let a=n==="crowds"?r.tierPeople[e]:s.count;if(a===0)return null;let l=i-a*K[n];if(l>me[e])return null;let u=Math.max(0,Math.floor((o-l)/K[n]));return u>=a?null:{tier:e,layer:n,from:a,to:u}}var Ki=["low","mid","high"],Xi=3;function Yi(r,e){let n=r.tierTotals[e]-r.tierPeople[e]*K.crowds,o=me[e];if(n<=o)return null;let i=[],s=n;for(let a of r.layers)if(!(a.layer==="crowds"||a.cost<=0)&&(i.push(a),s-=a.cost,s<=o||i.length===Xi))break;return {tier:e,withoutPeople:n,budget:o,layers:i}}function fn(r,e=dn){let n={...e},o=[],i=[];for(let s of Ki){if(r.tiers[s]!=="heavy")continue;let a=Yi(r,s);if(a!==null){i.push(a);continue}let l=zi(r,s);l!==null&&(n[s]=l.to,o.push(l));}return o.length===0&&i.length===0?null:{caps:n,fixes:o,stillHeavy:i}}function _n(r,e=Ee,n=Re){let o=[...r.buildings,...r.props],i=on(r,e,o,n),s=[];for(let u of r.scatters)u.layer==="props"&&s.push(...ct(u,i,e));let a=[];for(let u of r.scatters)u.layer==="crowds"&&a.push(...ct(u,i,e));let l=[...o,...s];return {placements:l,people:a,grid:i,weight:hn(mn(r,{props:s.length,crowds:a.length}),r.crowdCaps),checks:un(r,i,e,l)}}var dt=class r{constructor(e,n){this.normal=e;this.w=n;}static through(e,n,o){let i=n[0]-e[0],s=n[1]-e[1],a=n[2]-e[2],l=o[0]-e[0],u=o[1]-e[1],d=o[2]-e[2],m=s*d-a*u,p=a*l-i*d,h=i*u-s*l,f=Math.sqrt(m*m+p*p+h*h);if(f<1e-5*1e-5)return null;let y=[m/f,p/f,h/f];return new r(y,y[0]*e[0]+y[1]*e[1]+y[2]*e[2])}flipped(){return new r([-this.normal[0],-this.normal[1],-this.normal[2]],-this.w)}distance(e){return this.normal[0]*e[0]+this.normal[1]*e[1]+this.normal[2]*e[2]-this.w}split(e,n,o,i,s){let a=0,l=[];for(let p of e.vertices){let h=this.distance(p.p),f=h<-1e-5?2:h>1e-5?1:0;a|=f,l.push(f);}if(a===0){(this.normal[0]*e.plane.normal[0]+this.normal[1]*e.plane.normal[1]+this.normal[2]*e.plane.normal[2]>0?n:o).push(e);return}if(a===1){i.push(e);return}if(a===2){s.push(e);return}let u=[],d=[],m=e.vertices.length;for(let p=0;p<m;p++){let h=(p+1)%m,f=l[p],y=l[h],_=e.vertices[p],b=e.vertices[h];if(f!==2&&u.push(_),f!==1&&d.push(_),(f|y)===3){let O=(this.w-(this.normal[0]*_.p[0]+this.normal[1]*_.p[1]+this.normal[2]*_.p[2]))/(this.normal[0]*(b.p[0]-_.p[0])+this.normal[1]*(b.p[1]-_.p[1])+this.normal[2]*(b.p[2]-_.p[2])),N=ji(_,b,O);u.push(N),d.push(N);}}u.length>=3&&i.push(new Z(u,e.shared,e.plane)),d.length>=3&&s.push(new Z(d,e.shared,e.plane));}};function ji(r,e,n){let o=r.n[0]+(e.n[0]-r.n[0])*n,i=r.n[1]+(e.n[1]-r.n[1])*n,s=r.n[2]+(e.n[2]-r.n[2])*n,a=Math.sqrt(o*o+i*i+s*s)||1;return {p:[r.p[0]+(e.p[0]-r.p[0])*n,r.p[1]+(e.p[1]-r.p[1])*n,r.p[2]+(e.p[2]-r.p[2])*n],n:[o/a,i/a,s/a]}}var Z=class r{constructor(e,n,o){this.vertices=e;this.shared=n;this.plane=o;}static of(e,n){if(e.length<3)return null;let o=dt.through(e[0].p,e[1].p,e[2].p);return o===null?null:new r(e,n,o)}flipped(){let e=[];for(let n=this.vertices.length-1;n>=0;n--){let o=this.vertices[n];e.push({p:o.p,n:[-o.n[0],-o.n[1],-o.n[2]]});}return new r(e,this.shared,this.plane.flipped())}},mt=class r{constructor(){this.plane=null;this.front=null;this.back=null;this.polygons=[];}invert(){let e=[this];for(;e.length>0;){let n=e.pop();n.polygons=n.polygons.map(i=>i.flipped()),n.plane!==null&&(n.plane=n.plane.flipped());let o=n.front;n.front=n.back,n.back=o,n.front!==null&&e.push(n.front),n.back!==null&&e.push(n.back);}}clipPolygons(e){let n=[],o=[{node:this,polygons:e}];for(;o.length>0;){let{node:i,polygons:s}=o.pop();if(i.plane===null){for(let u of s)n.push(u);continue}let a=[],l=[];for(let u of s)i.plane.split(u,a,l,a,l);if(i.front!==null)o.push({node:i.front,polygons:a});else for(let u of a)n.push(u);i.back!==null&&o.push({node:i.back,polygons:l});}return n}clipTo(e){let n=[this];for(;n.length>0;){let o=n.pop();o.polygons=e.clipPolygons(o.polygons),o.front!==null&&n.push(o.front),o.back!==null&&n.push(o.back);}}allPolygons(){let e=[],n=[this];for(;n.length>0;){let o=n.pop();for(let i of o.polygons)e.push(i);o.back!==null&&n.push(o.back),o.front!==null&&n.push(o.front);}return e}build(e){let n=[{node:this,polygons:e}];for(;n.length>0;){let{node:o,polygons:i}=n.pop();if(i.length===0)continue;o.plane===null&&(o.plane=i[0].plane);let s=[],a=[];for(let l of i)o.plane.split(l,o.polygons,o.polygons,s,a);s.length>0&&(o.front??(o.front=new r),n.push({node:o.front,polygons:s})),a.length>0&&(o.back??(o.back=new r),n.push({node:o.back,polygons:a}));}}};function yn(r){let e=new mt;return e.build(r),e}function pt(r,e,n){if(r.length===0)return n==="union"?[...e]:[];if(e.length===0)return n==="intersect"?[]:[...r];let o=yn(r),i=yn(e);return n==="union"?(o.clipTo(i),i.clipTo(o),i.invert(),i.clipTo(o),i.invert(),o.build(i.allPolygons()),o.allPolygons()):n==="subtract"?(o.invert(),o.clipTo(i),i.clipTo(o),i.invert(),i.clipTo(o),i.invert(),o.build(i.allPolygons()),o.invert(),o.allPolygons()):(o.invert(),i.clipTo(o),i.invert(),o.clipTo(i),i.clipTo(o),o.build(i.allPolygons()),o.invert(),o.allPolygons())}function S(r,e,n,o,i,s,a={}){return {id:r,label:e,density:n,friction:o,restitution:i,look:{roughness:.6,metalness:0,opacity:1,...s},species:a.species??null,fluid:a.fluid??null,burns:a.burns??false,conductsHeat:a.conductsHeat??false,breaks:a.breaks??"never"}}var J=[S("iroko_wood","Iroko wood",650,.5,.25,{color:9067059,roughness:.7},{species:"wood",burns:true,breaks:"splinters"}),S("pine_wood","Pine wood",500,.5,.25,{color:13146978,roughness:.75},{species:"wood",burns:true,breaks:"splinters"}),S("copper","Copper",8960,.4,.2,{color:13138251,roughness:.3,metalness:1},{species:"Cu",conductsHeat:true,breaks:"dents"}),S("steel","Steel",7850,.45,.25,{color:10133928,roughness:.35,metalness:1},{species:"steel",conductsHeat:true,breaks:"dents"}),S("iron","Iron",7874,.5,.2,{color:6250339,roughness:.55,metalness:1},{species:"Fe",conductsHeat:true,breaks:"dents"}),S("aluminium","Aluminium",2700,.4,.25,{color:13093841,roughness:.35,metalness:1},{species:"Al",conductsHeat:true,breaks:"dents"}),S("gold","Gold",19300,.35,.15,{color:14199099,roughness:.25,metalness:1},{species:"Au",conductsHeat:true,breaks:"dents"}),S("rubber","Rubber",1100,.9,.8,{color:2829099,roughness:.9},{species:"plastic",burns:true}),S("plastic","Plastic",950,.4,.4,{color:15262940,roughness:.45},{species:"plastic",burns:true,breaks:"shatters"}),S("glass","Glass",2500,.3,.3,{color:14216944,roughness:.05,opacity:.35},{breaks:"shatters"}),S("stone","Stone",2600,.7,.15,{color:9209728,roughness:.9},{breaks:"shatters"}),S("brick","Brick",1900,.75,.1,{color:10835003,roughness:.9},{breaks:"shatters"}),S("bone","Bone",1900,.5,.3,{color:15327695,roughness:.6},{breaks:"splinters"}),S("cloth","Cloth",300,.8,.05,{color:11745850,roughness:1},{burns:true,breaks:"tears"}),S("paper","Paper",700,.6,.05,{color:15986662,roughness:1},{burns:true,breaks:"tears"}),S("ice","Ice",917,.05,.1,{color:13625589,roughness:.1,opacity:.8},{species:"H2O",breaks:"shatters"}),S("jelly","Jelly",1050,.6,.6,{color:14698063,roughness:.2,opacity:.85},{fluid:"jelly"}),S("water","Water",1e3,.02,0,{color:3903446,roughness:.05,opacity:.6},{species:"H2O",fluid:"water"}),S("sand","Sand",1600,.7,.05,{color:14268793,roughness:1},{fluid:"sand"}),S("snow","Snow",300,.3,.05,{color:16054266,roughness:.9},{fluid:"snow"}),S("mud","Mud",1700,.8,.02,{color:6047280,roughness:1},{fluid:"mud"})],ht="plastic",bn=new Map(J.map(r=>[r.id,r]));function ft(r){return bn.get(r)??bn.get(ht)}var $i=["shatters","splinters","tears","dents"];function gn(r){let e=new Set(r.map(n=>ft(n).breaks));return $i.find(n=>e.has(n))??"never"}var Sn=["box","sphere","cylinder","tube","rounded"],yt=2*Math.PI,Qi=Math.PI,_t=Math.PI/180,Zi=3;function Ji(r){let[e,n,o]=[r[0]*_t,r[1]*_t,r[2]*_t],i=w(e),s=v(e),a=w(n),l=v(n),u=w(o),d=v(o);return [a*u,-a*d,l,i*d+s*l*u,i*u-s*l*d,-s*a,s*d-i*l*u,s*u+i*l*d,i*a]}function es(r,e,n,o){let i=r.p,s=r.n,a=e[0]*i[0]+e[1]*i[1]+e[2]*i[2]+n[0],l=e[3]*i[0]+e[4]*i[1]+e[5]*i[2]+n[1],u=e[6]*i[0]+e[7]*i[1]+e[8]*i[2]+n[2],d=e[0]*s[0]+e[1]*s[1]+e[2]*s[2],m=e[3]*s[0]+e[4]*s[1]+e[5]*s[2],p=e[6]*s[0]+e[7]*s[1]+e[8]*s[2];return o===0?(a=-a,d=-d):o===1?(l=-l,m=-m):o===2&&(u=-u,p=-p),{p:[a,l,u],n:[d,m,p]}}function ts(r,e,n,o,i){let s=e.map(l=>es(l,i,o.at,o.mirror));o.mirror>=0&&s.reverse();let a=Z.of(s,n);a!==null&&r.push(a);}function B(r,e,n,o,i,s){return {p:[r,e,n],n:[o,i,s]}}function ns(r){let[e,n,o]=[r[0]/2,r[1]/2,r[2]/2];return [[[1,0,0],[[e,-n,-o],[e,n,-o],[e,n,o],[e,-n,o]]],[[-1,0,0],[[-e,-n,o],[-e,n,o],[-e,n,-o],[-e,-n,-o]]],[[0,1,0],[[-e,n,-o],[-e,n,o],[e,n,o],[e,n,-o]]],[[0,-1,0],[[-e,-n,o],[-e,-n,-o],[e,-n,-o],[e,-n,o]]],[[0,0,1],[[-e,-n,o],[e,-n,o],[e,n,o],[-e,n,o]]],[[0,0,-1],[[e,-n,-o],[-e,-n,-o],[-e,n,-o],[e,n,-o]]]].map(([s,a])=>a.map(l=>B(l[0],l[1],l[2],s[0],s[1],s[2])))}function rs(r,e){let n=Math.max(2,e>>1),o=(s,a)=>{let l=a/e*yt,u=s/n*Qi,d=w(l)*v(u),m=w(u),p=v(l)*v(u);return B(d*r,m*r,p*r,d,m,p)},i=[];for(let s=0;s<n;s++)for(let a=0;a<e;a++){let l=[o(s,a),o(s+1,a),o(s+1,a+1),o(s,a+1)];s===0?l.splice(0,1):s===n-1&&l.splice(1,1),i.push(l);}return i.map(s=>s.reverse())}function xn(r,e,n){let o=e/2,i=[],s=[],a=[];for(let l=0;l<n;l++){let u=l/n*yt,d=(l+1)/n*yt,m=w(u),p=v(u),h=w(d),f=v(d);i.push([B(m*r,-o,p*r,m,0,p),B(m*r,o,p*r,m,0,p),B(h*r,o,f*r,h,0,f),B(h*r,-o,f*r,h,0,f)]),s.push(B(m*r,o,p*r,0,1,0)),a.push(B(m*r,-o,p*r,0,-1,0));}return i.push(s.reverse()),i.push(a),i}function os(r,e,n){let o=[r[0]/2,r[1]/2,r[2]/2],i=Math.max(0,Math.min(e,o[0],o[1],o[2])),s=Math.max(2,n>>1),a=(d,m,p)=>{let h=Math.min(Math.max(d,-o[0]+i),o[0]-i),f=Math.min(Math.max(m,-o[1]+i),o[1]-i),y=Math.min(Math.max(p,-o[2]+i),o[2]-i),_=d-h,b=m-f,O=p-y,N=Math.sqrt(_*_+b*b+O*O);if(N===0||i===0)return B(d,m,p,0,0,0);let I=_/N,$=b/N,ie=O/N;return B(h+I*i,f+$*i,y+ie*i,I,$,ie)},l=[],u=[[0,1,2,1],[0,1,2,-1],[1,2,0,1],[1,2,0,-1],[2,0,1,1],[2,0,1,-1]];for(let[d,m,p,h]of u)for(let f=0;f<s;f++)for(let y=0;y<s;y++){let _=(O,N)=>{let I=[0,0,0];return I[d]=-o[d]+2*o[d]*O/s,I[m]=-o[m]+2*o[m]*N/s,I[p]=h*o[p],a(I[0],I[1],I[2])},b=[_(f,y),_(f+1,y),_(f+1,y+1),_(f,y+1)];l.push(h>0?b:b.reverse());}return l}function is(r,e){let n=Math.max(Zi,Math.floor(e));switch(r.kind){case "box":return ns(r.size);case "sphere":return rs(r.radius,n);case "cylinder":return xn(r.radius,r.height,n);case "tube":return xn(r.radius,r.length,n).map(o=>o.map(i=>B(i.p[1],-i.p[0],i.p[2],i.n[1],-i.n[0],i.n[2])));case "rounded":return os(r.size,r.radius,n)}}function bt(r,e,n,o){let i=Ji(e.turn),s=[];for(let a of is(r,o))ts(s,a,n,e,i);return s}function An(r){switch(r.kind){case "box":case "rounded":return Math.hypot(r.size[0],r.size[1],r.size[2])/2;case "sphere":return r.radius;case "cylinder":return Math.hypot(r.radius,r.height/2);case "tube":return Math.hypot(r.radius,r.length/2)}}var wn=["join","cut","overlap"],Rn=["none","x","y","z"],On=["fire","smoke","steam","sparks","confetti","water","rain","break","sound"],ss=32,as=12,ls=.08,cs=4e3,us=16e3,ds=1e3,En=64,ms={join:"union",cut:"subtract",overlap:"intersect"},kn={none:-1,x:0,y:1,z:2},gt=Math.PI/180,vn=2,ps=6,xt=4,ee=class extends Error{constructor(e){super(e),this.name="ThingError";}};function hs(r,e,n){let o={at:r.at,turn:r.turn,mirror:-1},i=bt(r.shape,o,e,n),s=kn[r.mirror];return s<0?i:pt(i,bt(r.shape,{...o,mirror:s},e,n),"union")}function Tn(r,e,n){let o=[];for(let i of r)o=pt(o,hs(i,e.indexOf(i.material),n),ms[i.combine]);return o}function In(r,e){let n=[],o=[],i=[],s=[];for(let a=0;a<e.length;a++){let l=i.length;for(let u of r){if(u.shared!==a)continue;let d=n.length/3;for(let m of u.vertices)n.push(m.p[0],m.p[1],m.p[2]),o.push(m.n[0],m.n[1],m.n[2]);for(let m=1;m<u.vertices.length-1;m++)i.push(d,d+m,d+m+1);}i.length>l&&s.push({material:e[a],start:l,count:i.length-l});}return {positions:Float32Array.from(n),normals:Float32Array.from(o),indices:Uint32Array.from(i),groups:s,triangles:i.length/3}}function fs(r,e,n){let o=(r[0]+e[0])/2,i=(r[2]+e[2])/2,s=Math.max(e[0]-r[0],e[2]-r[2])/2,a=Float32Array.from([o-s,r[1],i,o+s,r[1],i,o+s,e[1],i,o-s,e[1],i]),l=Float32Array.from([0,0,1,0,0,1,0,0,1,0,0,1]);return {positions:a,normals:l,indices:Uint32Array.from([0,1,2,0,2,3]),groups:[{material:n,start:0,count:vn*3}],triangles:vn}}function _s(r){let e=[1/0,1/0,1/0],n=[-1/0,-1/0,-1/0],o=r.positions;for(let i=0;i<o.length;i+=3)for(let s=0;s<3;s++)o[i+s]<e[s]&&(e[s]=o[i+s]),o[i+s]>n[s]&&(n[s]=o[i+s]);return o.length===0?{min:[0,0,0],max:[0,0,0]}:{min:[e[0],e[1],e[2]],max:[n[0],n[1],n[2]]}}function ys(r){let e=r.positions,n=r.indices,o=0,i=0,s=0,a=0,l=0;for(let u of r.groups){let d=ft(u.material).density;for(let m=u.start;m<u.start+u.count;m+=3){let p=n[m]*3,h=n[m+1]*3,f=n[m+2]*3,y=(e[p]*(e[h+1]*e[f+2]-e[h+2]*e[f+1])-e[p+1]*(e[h]*e[f+2]-e[h+2]*e[f])+e[p+2]*(e[h]*e[f+1]-e[h+1]*e[f]))/ps;o+=y,l+=y*d,i+=y*(e[p]+e[h]+e[f])/xt,s+=y*(e[p+1]+e[h+1]+e[f+1])/xt,a+=y*(e[p+2]+e[h+2]+e[f+2])/xt;}}return Math.abs(o)<Number.EPSILON?{volume:0,mass:0,centre:[0,0,0]}:{volume:o,mass:Math.max(0,l),centre:[i/o,s/o,a/o]}}function bs(r){switch(r.kind){case "box":return {shape:{kind:"cuboid",halfExtents:[r.size[0]/2,r.size[1]/2,r.size[2]/2]},tube:false};case "rounded":return {shape:{kind:"round_cuboid",halfExtents:[Math.max(0,r.size[0]/2-r.radius),Math.max(0,r.size[1]/2-r.radius),Math.max(0,r.size[2]/2-r.radius)],border:r.radius},tube:false};case "sphere":return {shape:{kind:"ball",radius:r.radius},tube:false};case "cylinder":return {shape:{kind:"cylinder",halfHeight:r.height/2,radius:r.radius},tube:false};case "tube":return {shape:{kind:"cylinder",halfHeight:r.length/2,radius:r.radius},tube:true}}}function gs(r,e){let n=r[0]*gt/2,o=r[1]*gt/2,i=r[2]*gt/2,s=v(n),a=w(n),l=v(o),u=w(o),d=v(i),m=w(i),p=[s*u*m+a*l*d,a*l*m-s*u*d,a*u*d+s*l*m,a*u*m-s*l*d];if(!e)return p;let h=Math.SQRT1_2;return [(p[0]-p[1])*h,(p[0]+p[1])*h,(p[2]-p[3])*h,(p[3]+p[2])*h]}function xs(r){let e=[];for(let n of r.parts){if(n.combine!=="join")continue;let{shape:o,tube:i}=bs(n.shape),s=gs(n.turn,i);e.push({shape:o,offset:n.at,rotation:s});let a=kn[n.mirror];if(a!==-1){let l=[n.at[0],n.at[1],n.at[2]];l[a]=-l[a];let u=[-s[0],-s[1],-s[2],s[3]];u[a]=s[a],e.push({shape:o,offset:l,rotation:u});}}return {kind:"compound",parts:e}}function Ss(r,e){let n=r+e*ds;return n<=cs?"light":n<=us?"medium":"heavy"}function Cn(r){if(r.parts.length===0)throw new ee("a thing needs at least one part");if(r.parts.length>En)throw new ee(`a thing holds at most ${En} parts`);let e=[...new Set(r.parts.map(d=>d.material))],n=In(Tn(r.parts,e,ss),e),o=_s(n),i=Math.hypot(o.max[0]-o.min[0],o.max[1]-o.min[1],o.max[2]-o.min[2])/2,s=r.parts.filter(d=>d.combine!=="join"||An(d.shape)>=i*ls),a=r.parts.filter(d=>!s.includes(d)).map(d=>d.name),l=In(Tn(s.length>0?s:r.parts,e,as),e),u=fs(o.min,o.max,n.groups[0]?.material??e[0]);return {levels:[{name:"close",mesh:n,dropped:[]},{name:"middle",mesh:l,dropped:a},{name:"far",mesh:u,dropped:r.parts.map(d=>d.name)}],mass:ys(n),collider:xs(r),bounds:o,cost:Ss(n.triangles,r.effects.length),effects:r.effects}}var Nn={low:{download_bytes:67108864,first_play_bytes:8388608,stream_bytes_per_second:187500,stream_latency_ms:150},mid:{download_bytes:268435456,first_play_bytes:25165824,stream_bytes_per_second:75e4,stream_latency_ms:80},high:{download_bytes:1073741824,first_play_bytes:67108864,stream_bytes_per_second:3125e3,stream_latency_ms:40}};var vs=4;function St(r){let e=Nn[r];return {downloadBytes:e.download_bytes,firstPlayBytes:e.first_play_bytes,link:{bytesPerSecond:e.stream_bytes_per_second,latencyMs:e.stream_latency_ms,concurrency:vs}}}var At={low:St("low"),mid:St("mid"),high:St("high")},ke=At.low.link,Ln=2,Mn=5;function Et(r){return r!==null&&r.runs>0}function Dn(r,e){let n=null;for(let o of r)o.tier!==e||o.runs===0||(n===null||o.runs>n.runs)&&(n=o);return n}var Ts=.5,Is=.2,ws=3;function Rs(r){return r>=Ts?"most":r>=Is?"some":"a_little"}function Pn(r,e=ws){let n=0;for(let o of r)o.cost>0&&(n+=o.cost);return n<=0?[]:r.filter(o=>o.cost>0).map(o=>({label:o.label,share:o.cost/n,amount:Rs(o.cost/n)})).sort((o,i)=>i.share-o.share||o.label.localeCompare(i.label)).slice(0,e)}var Os=1e3;function ks(r,e,n){return r<=0||e<=0?0:Math.ceil(e/Math.max(1,n.concurrency))*n.latencyMs/Os+r/n.bytesPerSecond}function vt(r){return r<Ln?"instant":r<=Mn?"quick":"slow"}function Cs(r,e){return r.tier===null||r.tier===e}function Fn(r,e,n=ke){let o=0,i=0,s=0,a=[];for(let d of r)Cs(d,e)&&(i+=d.bytes,d.beforePlay&&(o+=d.bytes,s++,a.push({label:d.label,cost:d.bytes})));let l=ks(o,s,n),u=At[e];return {tier:e,firstPlayBytes:o,downloadBytes:i,firstPlayRequests:s,openSeconds:l,open:vt(l),fitsDownload:i<=u.downloadBytes,fitsFirstPlay:o<=u.firstPlayBytes,causes:Pn(a)}}var Ns="low";function Un(r,e,n=[],o=Ns){let i=Fn(r,o,ke),s=Dn(n,o),a=Et(s)?i.openSeconds*s.openScale:i.openSeconds,l=e!==null&&e.tier===o;return {opensOn3g:{seconds:a,open:vt(a),calibrated:Et(s)},firstLoadBytes:i.firstPlayBytes,delivery:i,cheaperPhones:l?e.frames:null,memory:l?e.memory:null,heat:l?e.heat:null}}var Ls=["X","Y","Z","W"];function L(r,e){return {description:r,group:e.group??null,label:e.label??null,heavy:e.heavy??false,advanced:e.advanced??false}}function Ms(r){return typeof r=="number"?String(r):Ds(r)}function Ds(r){let e=r.replace(/[_-]+/g," ").replace(/([a-z0-9])([A-Z])/g,"$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g,"$1 $2").trim().toLowerCase();return e.length===0?e:e[0].toUpperCase()+e.slice(1)}var t={number(r,e){return {kind:"number",...L(r,e),min:e.min,max:e.max,step:e.step??null,unit:e.unit,scale:e.scale??"linear",default:e.default}},integer(r,e){return {kind:"integer",...L(r,e),min:e.min,max:e.max,unit:e.unit??"count",default:e.default}},boolean(r,e,n={}){return {kind:"boolean",...L(r,n),default:e}},choice(r,e,n,o={}){let i=o.labels;return {kind:"choice",...L(r,o),options:e.map(s=>({value:s,label:i?.[String(s)]??Ms(s)})),default:n}},color(r,e,n={}){return {kind:"color",...L(r,n),format:"hex",default:e}},rgb(r,e,n={}){return {kind:"color",...L(r,n),format:"rgb",default:e}},vector(r,e){let n=e.axes??Ls.slice(0,e.default.length);return {kind:"vector",...L(r,e),axes:n,min:e.min,max:e.max,unit:e.unit,default:e.default}},text(r,e="",n=200,o={}){return {kind:"text",...L(r,o),maxLength:n,default:e}},asset(r,e,n={}){return {kind:"asset",...L(r,n),asset:e,default:null}},thing(r,e="any",n={}){return {kind:"thing",...L(r,n),role:e,default:null}},settings(r,e,n={}){return {kind:"settings",...L(r,n),settings:e,default:null}},list(r,e,n){return {kind:"list",...L(r,n),item:e,maxItems:n.maxItems,default:n.default??[]}},wiring(r,e={}){return {kind:"wiring",...L(r,e),default:null}}};function c(r,e){return {name:r,title:e.title,description:e.description,group:e.group??e.title,extends:e.extends??[],omit:e.omit??[],fields:e.fields}}var Hn=140;function D(r){return typeof r=="number"&&Number.isFinite(r)}function Ps(r,e){return e==="hex"?D(r)&&Number.isInteger(r)&&r>=0&&r<=16777215:Array.isArray(r)&&r.length===3&&r.every(n=>D(n)&&n>=0&&n<=1)}function Bn(r,e){let n=[],o=s=>{n.push({field:e,reason:s});},i=r.description.trim();switch(i.length===0&&o("has no description"),i.length>Hn&&o(`description is longer than ${Hn} characters`),/[\n—]/.test(r.description)&&o("description must be one line with no em dash"),r.kind){case "number":case "integer":(!D(r.min)||!D(r.max)||r.min>r.max)&&o("range is not a finite min below max"),(!D(r.default)||r.default<r.min||r.default>r.max)&&o(`default ${r.default} is outside ${r.min} to ${r.max}`),r.kind==="integer"&&(!Number.isInteger(r.min)||!Number.isInteger(r.max)||!Number.isInteger(r.default))&&o("integer range or default is not whole"),r.kind==="number"&&r.scale==="log"&&r.min<=0&&o("log scale needs a positive minimum"),r.kind==="number"&&r.step!==null&&!(r.step>0)&&o("step must be positive");break;case "vector":(!D(r.min)||!D(r.max)||r.min>r.max)&&o("range is not a finite min below max"),(r.axes.length!==r.default.length||r.default.length===0)&&o("axes and default differ in length"),r.default.some(s=>!D(s)||s<r.min||s>r.max)&&o("default is outside the range");break;case "choice":r.options.length<2&&o("a choice needs at least two options"),r.options.some(s=>s.value===r.default)||o(`default ${String(r.default)} is not an option`),new Set(r.options.map(s=>s.value)).size!==r.options.length&&o("options repeat");break;case "color":Ps(r.default,r.format)||o("default is not a colour in its format");break;case "text":(!(r.maxLength>0)||r.default.length>r.maxLength)&&o("text default is longer than its limit");break;case "list":(!(r.maxItems>0)||r.default.length>r.maxItems)&&o("list default is longer than its limit");for(let s of Bn(r.item,`${e}[]`))n.push(s);break;case "settings":r.settings.length===0&&o("names no settings");break;}return n}function Gn(r){let e=[];r.title.trim().length===0&&e.push({field:"",reason:"has no title"}),r.description.trim().length===0&&e.push({field:"",reason:"has no description"}),r.group.trim().length===0&&e.push({field:"",reason:"has no group"});for(let[n,o]of Object.entries(r.fields))for(let i of Bn(o,n))e.push(i);return e}function Fs(r,e){return {path:r,reason:e}}function Us(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function te(r,e,n){return r<e?e:r>n?n:r}function G(r){return {ok:true,value:r}}function M(r,e){return {ok:false,issue:Fs(r,e)}}function Tt(r,e,n=""){switch(r.kind){case "number":{if(!D(e))return M(n,"needs a number");let o=te(e,r.min,r.max);return G(r.step===null?o:te(r.min+Math.round((o-r.min)/r.step)*r.step,r.min,r.max))}case "integer":return D(e)?G(te(Math.round(e),r.min,r.max)):M(n,"needs a whole number");case "boolean":return typeof e=="boolean"?G(e):M(n,"needs on or off");case "choice":{let o=r.options.find(i=>i.value===e);return o===void 0?M(n,`needs one of ${r.options.map(i=>i.label).join(", ")}`):G(o.value)}case "color":return r.format==="hex"?D(e)?G(te(Math.round(e),0,16777215)):M(n,"needs a colour"):!Array.isArray(e)||e.length!==3||!e.every(D)?M(n,"needs a colour"):G(e.map(o=>te(o,0,1)));case "vector":return !Array.isArray(e)||e.length!==r.default.length||!e.every(D)?M(n,`needs ${r.default.length} numbers`):G(e.map(o=>te(o,r.min,r.max)));case "text":return typeof e=="string"?G(e.slice(0,r.maxLength)):M(n,"needs text");case "asset":case "thing":return e===null||typeof e=="string"?G(e):M(n,"needs a reference");case "list":{if(!Array.isArray(e))return M(n,"needs a list");if(e.length>r.maxItems)return M(n,`holds at most ${r.maxItems}`);let o=[];for(let i=0;i<e.length;i++){let s=Tt(r.item,e[i],`${n}[${i}]`);if(!s.ok)return s;o.push(s.value);}return G(o)}case "settings":return e===null||Us(e)?G(e):M(n,"needs a group of settings");case "wiring":return M(n,"is set by code")}}var pe=class extends Error{constructor(e){super(e),this.name="SettingsRegistryError";}},Ce=class{constructor(e){this.schemas=new Map;this.resolved=new Map;for(let n of e){if(this.schemas.has(n.name))throw new pe(`settings ${n.name} are defined twice`);this.schemas.set(n.name,n);}}names(){return [...this.schemas.keys()]}has(e){return this.schemas.has(e)}schema(e){let n=this.schemas.get(e);if(n===void 0)throw new pe(`no settings named ${e}`);return n}resolve(e){let n=this.resolved.get(e);if(n!==void 0)return n;let o=this.build(e,[]);return this.resolved.set(e,o),o}build(e,n){if(n.includes(e))throw new pe(`settings ${[...n,e].join(" > ")} extend themselves`);let o=this.schema(e),i=new Map;for(let s of o.extends)for(let a of this.build(s,[...n,e]).fields)o.omit.includes(a.name)||i.set(a.name,a);for(let[s,a]of Object.entries(o.fields))i.set(s,{name:s,setting:a,group:a.group??o.group,owner:o.name});return {schema:o,fields:[...i.values()],byName:i}}fields(e){let n={};for(let o of this.resolve(e).fields)n[o.name]=o.setting;return n}field(e,n){let o=e;for(let i=0;i<n.length;i++){let s=this.resolve(o).byName.get(n[i]);if(s===void 0)return null;if(i===n.length-1)return s;if(s.setting.kind!=="settings")return null;o=s.setting.settings;}return null}gaps(){let e=[];for(let n of this.schemas.values()){for(let o of Gn(n))e.push({schema:n.name,...o});for(let o of n.extends)this.schemas.has(o)||e.push({schema:n.name,field:"",reason:`extends unknown settings ${o}`});for(let[o,i]of Object.entries(n.fields)){let s=i.kind==="list"?i.item:i;s.kind==="settings"&&!this.schemas.has(s.settings)&&e.push({schema:n.name,field:o,reason:`refers to unknown settings ${s.settings}`});}}return e}normalize(e,n,o){let i=n.join("."),s=this.field(e,n);return s===null?{ok:false,issue:{path:i,reason:`is not a setting of ${this.schema(e).title}`}}:this.normalizeField(s.setting,o,i,[e])}normalizeField(e,n,o,i){if(e.kind==="settings"&&n!==null)return this.normalizeGroup(e.settings,n,o,i);if(e.kind==="list"&&e.item.kind==="settings"&&Array.isArray(n)){let s=[];for(let a=0;a<n.length;a++){let l=this.normalizeGroup(e.item.settings,n[a],`${o}[${a}]`,i);if(!l.ok)return l;s.push(l.value);}return s.length>e.maxItems?{ok:false,issue:{path:o,reason:`holds at most ${e.maxItems}`}}:{ok:true,value:s}}return Tt(e,n,o)}normalizeGroup(e,n,o,i){if(typeof n!="object"||n===null||Array.isArray(n))return {ok:false,issue:{path:o,reason:"needs a group of settings"}};if(i.includes(e))return {ok:false,issue:{path:o,reason:"nests itself"}};let s=this.resolve(e),a={};for(let[l,u]of Object.entries(n)){let d=s.byName.get(l),m=o===""?l:`${o}.${l}`;if(d===void 0)return {ok:false,issue:{path:m,reason:`is not a setting of ${s.schema.title}`}};let p=this.normalizeField(d.setting,u,m,[...i,e]);if(!p.ok)return p;a[l]=p.value;}return {ok:true,value:a}}defaults(e){let n={};for(let o of this.resolve(e).fields)o.setting.kind!=="wiring"&&(n[o.name]=o.setting.default);return n}};var Wn=1024;var Vn=2048;var qn=.8,zn=-100,Kn=-30;var Hs=[32,64,128,256,512,1024,2048,4096,8192,16384,32768],Bs=65536,Gs=1<<20,Ws=120,Vs=8,Xn=[c("EmitterOptions",{title:"Sound crowd",description:"One sound played from many things at once, like rain on leaves or a cheering crowd.",fields:{sound:t.asset("The sound each thing plays","sound"),capacity:t.integer("Most things making the sound",{default:Wn,min:1,max:65536,heavy:true}),panner:t.wiring("How the sound fades and turns with distance")}}),c("AnalyserSettings",{title:"Sound meter",description:"Reads how loud each pitch is, so visuals can move with the music.",fields:{fftSize:t.choice("Detail of the pitch reading",Hs,Vn,{heavy:true}),smoothing:t.number("How much the reading is smoothed between frames",{default:qn,min:0,max:1,unit:"fraction"}),minDecibels:t.number("Quietest level shown",{default:zn,min:-160,max:0,unit:"dB"}),maxDecibels:t.number("Loudest level shown",{default:Kn,min:-160,max:0,unit:"dB"})}}),c("WorkletAudioOptions",{title:"Browser sound",description:"How sound plays in a browser tab.",fields:{context:t.wiring("The browser's sound output"),module:t.wiring("The sound mixer the tab loads"),idlePumps:t.integer("Quiet frames before the mixer rests",{default:Ws,min:1,max:1e4,advanced:true}),voices:t.integer("Most sounds playing at once",{default:64,min:1,max:256}),sizes:t.wiring("Room set aside inside the mixer"),shared:t.boolean("Share memory with the mixer when the browser allows it",true,{advanced:true}),pumpWords:t.integer("Room for sound commands each frame",{default:Bs,min:1024,max:1<<24,unit:"count",advanced:true}),ringWords:t.integer("Room for sound waiting to play",{default:Gs,min:1024,max:1<<26,unit:"count",advanced:true}),reportQuanta:t.integer("How often the mixer reports back, in sound blocks",{default:Vs,min:1,max:1024,advanced:true}),moduleUrl:t.wiring("Where the tab loads the mixer from"),createNode:t.wiring("Makes the mixer's output node")}}),c("WebAudioOptions",{title:"Browser streams",description:"How long sounds and music stream in a browser tab.",fields:{createMediaElement:t.wiring("Makes the player each stream plays through")}})];function A(r,e){for(let n=0;n<e.length;n++){let o=e[n],i=r[o];Reflect.set(r,o,.5),Reflect.set(r,o,i);}}function wt(r,e,n,o,i,s,a,l,u,d,m){let p=n+a+m,h,f,y,_;if(p>0){let b=.5/Math.sqrt(p+1);_=.25/b,h=(l-d)*b,f=(u-i)*b,y=(o-s)*b;}else if(n>a&&n>m){let b=2*Math.sqrt(1+n-a-m);_=(l-d)/b,h=.25*b,f=(s+o)/b,y=(u+i)/b;}else if(a>m){let b=2*Math.sqrt(1+a-n-m);_=(u-i)/b,h=(s+o)/b,f=.25*b,y=(d+l)/b;}else {let b=2*Math.sqrt(1+m-n-a);_=(o-s)/b,h=(u+i)/b,f=(d+l)/b,y=.25*b;}r[e]=h,r[e+1]=f,r[e+2]=y,r[e+3]=_;}var Rt=class{constructor(e=0,n=0){this.x=e,this.y=n;}set(e,n){return this.x=e,this.y=n,this}copy(e){return this.x=e.x,this.y=e.y,this}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}add(e){return this.x+=e.x,this.y+=e.y,this}sub(e){return this.x-=e.x,this.y-=e.y,this}scale(e){return this.x*=e,this.y*=e,this}dot(e){return this.x*e.x+this.y*e.y}cross(e){return this.x*e.y-this.y*e.x}normalize(){let e=this.length();return e>1e-6&&this.scale(1/e),this}distanceTo(e){return Math.hypot(this.x-e.x,this.y-e.y)}lerp(e,n,o){return this.x=e.x+(n.x-e.x)*o,this.y=e.y+(n.y-e.y)*o,this}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}rotateAround(e,n){let o=Math.cos(n),i=Math.sin(n),s=this.x-e.x,a=this.y-e.y;return this.x=s*o-a*i+e.x,this.y=s*i+a*o+e.y,this}},Ot=class{constructor(e=0,n=0,o=0,i=1){this.x=e,this.y=n,this.z=o,this.w=i;}set(e,n,o,i){return this.x=e,this.y=n,this.z=o,this.w=i,this}copy(e){return this.set(e.x,e.y,e.z,e.w)}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}length(){return Math.sqrt(this.dot(this))}scale(e){return this.set(this.x*e,this.y*e,this.z*e,this.w*e)}lerp(e,n,o){return this.set(e.x+(n.x-e.x)*o,e.y+(n.y-e.y)*o,e.z+(n.z-e.z)*o,e.w+(n.w-e.w)*o)}applyMat4(e,n){let{x:o,y:i,z:s,w:a}=this;return this.set(e[n]*o+e[n+4]*i+e[n+8]*s+e[n+12]*a,e[n+1]*o+e[n+5]*i+e[n+9]*s+e[n+13]*a,e[n+2]*o+e[n+6]*i+e[n+10]*s+e[n+14]*a,e[n+3]*o+e[n+7]*i+e[n+11]*s+e[n+15]*a)}readFrom(e,n){return this.set(e[n],e[n+1],e[n+2],e[n+3])}writeTo(e,n){e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3]=this.w;}},R=class{constructor(e=0,n=0,o=0){this.x=e,this.y=n,this.z=o;}set(e,n,o){return this.x=e,this.y=n,this.z=o,this}copy(e){return this.x=e.x,this.y=e.y,this.z=e.z,this}add(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this}sub(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this}scale(e){return this.x*=e,this.y*=e,this.z*=e,this}addScaled(e,n){return this.x+=e.x*n,this.y+=e.y*n,this.z+=e.z*n,this}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z}cross(e,n){let o=e.y*n.z-e.z*n.y,i=e.z*n.x-e.x*n.z,s=e.x*n.y-e.y*n.x;return this.x=o,this.y=i,this.z=s,this}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.lengthSq())}normalize(){let e=this.length();return e>1e-6&&this.scale(1/e),this}lerp(e,n,o){return this.x=e.x+(n.x-e.x)*o,this.y=e.y+(n.y-e.y)*o,this.z=e.z+(n.z-e.z)*o,this}distanceTo(e){return Math.sqrt(this.distanceToSquared(e))}distanceToSquared(e){let n=this.x-e.x,o=this.y-e.y,i=this.z-e.z;return n*n+o*o+i*i}negate(){return this.set(-this.x,-this.y,-this.z)}min(e){return this.set(Math.min(this.x,e.x),Math.min(this.y,e.y),Math.min(this.z,e.z))}max(e){return this.set(Math.max(this.x,e.x),Math.max(this.y,e.y),Math.max(this.z,e.z))}clamp(e,n){return this.set(Math.max(e.x,Math.min(n.x,this.x)),Math.max(e.y,Math.min(n.y,this.y)),Math.max(e.z,Math.min(n.z,this.z)))}clampLength(e,n){let o=this.length();return o<1e-6?this:this.scale(Math.max(e,Math.min(n,o))/o)}subVectors(e,n){return this.set(e.x-n.x,e.y-n.y,e.z-n.z)}addVectors(e,n){return this.set(e.x+n.x,e.y+n.y,e.z+n.z)}applyQuat(e){return e.rotate(this),this}applyMat4(e,n){let o=this.x,i=this.y,s=this.z,a=e[n+3]*o+e[n+7]*i+e[n+11]*s+e[n+15],l=Math.abs(a)>1e-6?1/a:1;return this.set((e[n]*o+e[n+4]*i+e[n+8]*s+e[n+12])*l,(e[n+1]*o+e[n+5]*i+e[n+9]*s+e[n+13])*l,(e[n+2]*o+e[n+6]*i+e[n+10]*s+e[n+14])*l)}transformDirection(e,n){let o=this.x,i=this.y,s=this.z;return this.set(e[n]*o+e[n+4]*i+e[n+8]*s,e[n+1]*o+e[n+5]*i+e[n+9]*s,e[n+2]*o+e[n+6]*i+e[n+10]*s),this.normalize()}projectOnVector(e){let n=e.x*e.x+e.y*e.y+e.z*e.z;if(n<1e-6)return this.set(0,0,0);let o=this.dot(e)/n;return this.set(e.x*o,e.y*o,e.z*o)}projectOnPlane(e){let n=this.dot(e);return this.set(this.x-e.x*n,this.y-e.y*n,this.z-e.z*n)}reflect(e){let n=2*this.dot(e);return this.set(this.x-e.x*n,this.y-e.y*n,this.z-e.z*n)}angleTo(e){let n=Math.sqrt(this.lengthSq()*(e.x*e.x+e.y*e.y+e.z*e.z));return n<1e-6?Math.PI/2:Math.acos(Math.max(-1,Math.min(1,this.dot(e)/n)))}setFromSpherical(e,n,o){let i=Math.sin(n)*e;return this.set(i*Math.sin(o),Math.cos(n)*e,i*Math.cos(o))}setFromMatrixColumn(e,n,o){return this.readFrom(e,n+o*4)}equals(e,n=0){return Math.abs(this.x-e.x)<=n&&Math.abs(this.y-e.y)<=n&&Math.abs(this.z-e.z)<=n}readFrom(e,n){return this.x=e[n],this.y=e[n+1],this.z=e[n+2],this}writeTo(e,n){e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z;}},Le=class{constructor(e=0,n=0,o=0,i=1){this.x=e,this.y=n,this.z=o,this.w=i;}set(e,n,o,i){return this.x=e,this.y=n,this.z=o,this.w=i,this}identity(){return this.set(0,0,0,1)}copy(e){return this.set(e.x,e.y,e.z,e.w)}setAxisAngle(e,n){let o=n*.5,i=Math.sin(o);return this.set(e.x*i,e.y*i,e.z*i,Math.cos(o))}setEuler(e,n,o){let i=Math.cos(e*.5),s=Math.sin(e*.5),a=Math.cos(n*.5),l=Math.sin(n*.5),u=Math.cos(o*.5),d=Math.sin(o*.5);return this.set(s*a*u+i*l*d,i*l*u-s*a*d,i*a*d+s*l*u,i*a*u-s*l*d)}multiply(e,n){return this.set(e.w*n.x+e.x*n.w+e.y*n.z-e.z*n.y,e.w*n.y-e.x*n.z+e.y*n.w+e.z*n.x,e.w*n.z+e.x*n.y-e.y*n.x+e.z*n.w,e.w*n.w-e.x*n.x-e.y*n.y-e.z*n.z)}normalize(){let e=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);if(e<1e-6)return this.identity();let n=1/e;return this.set(this.x*n,this.y*n,this.z*n,this.w*n)}rotate(e){let{x:n,y:o,z:i,w:s}=this,a=s*e.x+o*e.z-i*e.y,l=s*e.y+i*e.x-n*e.z,u=s*e.z+n*e.y-o*e.x,d=-n*e.x-o*e.y-i*e.z;return e.set(a*s+d*-n+l*-i-u*-o,l*s+d*-o+u*-n-a*-i,u*s+d*-i+a*-o-l*-n)}dot(e){return this.x*e.x+this.y*e.y+this.z*e.z+this.w*e.w}conjugate(){return this.set(-this.x,-this.y,-this.z,this.w)}invert(){let e=this.dot(this);if(e<1e-6)return this.identity();let n=1/e;return this.set(-this.x*n,-this.y*n,-this.z*n,this.w*n)}premultiply(e){return this.multiply(e,this)}slerp(e,n,o){let i=n.x,s=n.y,a=n.z,l=n.w,u=e.x*i+e.y*s+e.z*a+e.w*l;u<0&&(u=-u,i=-i,s=-s,a=-a,l=-l);let d=1-o,m=o;if(u<=.9995){let p=Math.acos(u),h=Math.sin(p);d=Math.sin((1-o)*p)/h,m=Math.sin(o*p)/h;}return this.set(e.x*d+i*m,e.y*d+s*m,e.z*d+a*m,e.w*d+l*m),this.normalize()}rotateTowards(e,n){let o=this.angleTo(e);return o<1e-6?this:this.slerp(this,e,Math.min(1,n/o))}angleTo(e){return 2*Math.acos(Math.min(1,Math.abs(this.dot(e))))}setFromUnitVectors(e,n){let o=e.x*n.x+e.y*n.y+e.z*n.z+1;return o<1e-6?(o=0,Math.abs(e.x)>Math.abs(e.z)?this.set(-e.y,e.x,0,o).normalize():this.set(0,-e.z,e.y,o).normalize()):this.set(e.y*n.z-e.z*n.y,e.z*n.x-e.x*n.z,e.x*n.y-e.y*n.x,o).normalize()}setFromRotationMatrix(e,n){return wt(W,0,e[n],e[n+1],e[n+2],e[n+4],e[n+5],e[n+6],e[n+8],e[n+9],e[n+10]),this.set(W[0],W[1],W[2],W[3])}lookRotation(e,n,o,i=0,s=1,a=0){let l=-e,u=-n,d=-o,m=Math.sqrt(l*l+u*u+d*d);if(m<1e-6)return this.identity();l/=m,u/=m,d/=m;let p=s*d-a*u,h=a*l-i*d,f=i*u-s*l;m=Math.sqrt(p*p+h*h+f*f),m<1e-6&&(p=1,h=0,f=0,m=1),p/=m,h/=m,f/=m;let y=u*f-d*h,_=d*p-l*f,b=l*h-u*p;return wt(W,0,p,h,f,y,_,b,l,u,d),this.set(W[0],W[1],W[2],W[3])}toEuler(e){let{x:n,y:o,z:i,w:s}=this,a=1-2*(o*o+i*i),l=2*(n*o-s*i),u=2*(n*i+s*o),d=1-2*(n*n+i*i),m=2*(o*i-s*n),p=2*(o*i+s*n),h=1-2*(n*n+o*o),f=Math.asin(Math.max(-1,Math.min(1,u)));return Math.abs(u)<1-1e-6?e.set(Math.atan2(-m,h),f,Math.atan2(-l,a)):e.set(Math.atan2(p,d),f,0)}readFrom(e,n){return this.set(e[n],e[n+1],e[n+2],e[n+3])}writeTo(e,n){e[n]=this.x,e[n+1]=this.y,e[n+2]=this.z,e[n+3]=this.w;}},W=new Float64Array(4);A(new Rt,["x","y"]);A(new Ot,["x","y","z","w"]);A(new R,["x","y","z"]);A(new Le,["x","y","z","w"]);var fe=class{constructor(){this.kind="ball";this.params=new R(.5,0,0);this.origin=new R;this.rotation=new Float32Array([0,0,0,1]);this.direction=new R(0,-1,0);this.maxDistance=Number.MAX_VALUE;this.includeSensors=false;this.excludeBody=-1;}ball(e){return this.kind="ball",this.params.set(e,0,0),this}cuboid(e,n,o){return this.kind="cuboid",this.params.set(e,n,o),this}capsule(e,n){return this.kind="capsule",this.params.set(e,n,0),this}cylinder(e,n){return this.kind="cylinder",this.params.set(e,n,0),this}};A(new fe,["maxDistance"]);var Qn=4,Zn=1,Jn=1,er=64,tr=16,nr=16;var Me=class{constructor(){this.origin=new R;this.direction=new R(0,-1,0);this.maxDistance=Number.MAX_VALUE;this.solid=true;this.includeSensors=false;this.excludeCollider=-1;}set(e,n,o,i,s,a,l){return this.origin.set(e,n,o),this.direction.set(i,s,a),this.maxDistance=l,this}},_e=class{constructor(){this.hit=false;this.collider=-1;this.distance=0;this.pointX=0;this.pointY=0;this.pointZ=0;this.normalX=0;this.normalY=0;this.normalZ=0;}},De=class{constructor(){this.grounded=false;this.x=0;this.y=0;this.z=0;}};A(new Me,["maxDistance"]);A(new _e,["distance","pointX","pointY","pointZ","normalX","normalY","normalZ"]);A(new De,["x","y","z"]);var qs=new Float64Array(1);new Uint32Array(qs.buffer);var sr=.22;var cr=.0062,ur=3.4;var dr=60,mr=1;var F=1e6,T=Math.PI,Pe=r=>t.number("How wide the camera sees",{default:r,min:5,max:170,unit:"deg"}),kt=(r,e)=>t.number(`Extra width when ${e}, for a sense of speed`,{default:r,min:0,max:60,unit:"deg"}),U=(r,e,n)=>t.number(r,{default:e,min:0,max:100,unit:"none",group:n,advanced:true}),ne=(r,e)=>t.number(r,{default:e,min:-T/2,max:T/2,unit:"rad"}),$s=()=>t.number("Picture shape, width over height",{default:mr,min:.1,max:10,unit:"none",advanced:true}),Fe=r=>t.wiring(r),Ct=r=>t.text("Name the movement controls are listed under",r,64,{advanced:true}),pr=[c("CameraBoomOptions",{title:"Camera bump",description:"Keeps a following camera from going through walls.",fields:{radius:t.number("Size of the camera's bump",{default:sr,min:.01,max:5,unit:"m"}),margin:t.number("Gap kept from walls",{default:.06,min:0,max:5,unit:"m"})}}),c("LookOptions",{title:"Looking around",description:"How dragging, the mouse and a gamepad turn the camera.",group:"Looking",fields:{lookSensitivity:t.number("How far the camera turns for each drag",{default:cr,min:1e-4,max:.1,unit:"rad",scale:"log"}),gamepadLookSpeed:t.number("How fast a gamepad stick turns the camera",{default:ur,min:.1,max:20,unit:"rad/s"}),invertY:t.boolean("Push up to look down",false)}}),c("FollowCameraOptions",{title:"Over the shoulder",description:"A camera behind and over the shoulder of a character.",extends:["LookOptions","CameraBoomOptions"],fields:{distance:t.number("Distance behind the character",{default:4.2,min:.5,max:100,unit:"m"}),height:t.number("Height of the camera's aim",{default:1.55,min:0,max:20,unit:"m"}),crouchHeight:t.number("Height of the aim while crouching",{default:1.05,min:0,max:20,unit:"m"}),shoulder:t.number("How far to the side the camera sits",{default:.55,min:0,max:5,unit:"m"}),shoulderSide:t.choice("Which shoulder",[1,-1],1,{labels:{1:"Right",[-1]:"Left"}}),pitch:ne("Starting tilt, below 0 looks down",-0.3),minPitch:ne("Furthest the camera looks down",-1.25),maxPitch:ne("Furthest the camera looks up",.95),followSharpness:U("How tightly the camera follows",22,"Smoothing"),verticalSharpness:U("How tightly it follows jumps and falls",8,"Smoothing"),shoulderSharpness:U("How quickly it swaps shoulders",9,"Smoothing"),recoverSharpness:U("How quickly it pulls back out after a wall",4.5,"Smoothing"),autoRecenter:t.boolean("Swing back behind the character after looking around",true,{group:"Recentre"}),recenterDelay:t.number("Wait before swinging back",{default:1.5,min:0,max:10,unit:"s",group:"Recentre"}),recenterSharpness:U("How quickly it swings back",1.8,"Recentre"),fov:Pe(62),sprintFovKick:kt(8,"sprinting"),fovSharpness:U("How quickly the view widens and narrows",6),lockSoftZone:t.number("Room a locked-on target can move before the camera turns",{default:.12,min:0,max:1,unit:"fraction",group:"Lock on"}),lockSharpness:U("How quickly it turns to a locked-on target",7,"Lock on"),lockMaxDistance:t.number("Furthest a target can be locked on to",{default:30,min:1,max:1e3,unit:"m",group:"Lock on"}),lockHeight:t.number("Height on the target the camera aims at",{default:1.2,min:0,max:20,unit:"m",group:"Lock on"}),lens:t.wiring("Depth of field and other lens effects")}}),c("FirstPersonViewOptions",{title:"Eyes view",description:"A camera that sees through the character's eyes.",extends:["LookOptions"],fields:{eyeHeight:t.number("Eye height",{default:1.62,min:.1,max:20,unit:"m"}),crouchEyeHeight:t.number("Eye height while crouching",{default:1.02,min:.1,max:20,unit:"m"}),headBob:t.boolean("The view bobs with each step",true,{group:"Steps"}),bobAmplitude:t.number("How much the view bobs",{default:.04,min:0,max:.5,unit:"m",group:"Steps"}),bobStride:t.number("Distance of one step",{default:2.1,min:.1,max:10,unit:"m",group:"Steps"}),landDip:t.number("How far the view dips on landing",{default:.12,min:0,max:1,unit:"m",group:"Steps"}),minPitch:ne("Furthest the view looks down",-1.45),maxPitch:ne("Furthest the view looks up",1.45),fov:Pe(74),sprintFovKick:kt(6,"sprinting"),fovSharpness:U("How quickly the view widens and narrows",6),lens:t.wiring("Depth of field and other lens effects")}}),c("ChaseCameraOptions",{title:"Chase camera",description:"A camera behind a car, boat or bike.",extends:["LookOptions","CameraBoomOptions"],fields:{distance:t.number("Distance behind the vehicle",{default:6,min:.5,max:100,unit:"m"}),lookHeight:t.number("Height of the camera's aim",{default:1.6,min:0,max:20,unit:"m"}),pitch:ne("Tilt, below 0 looks down",-0.22),speedForEffects:t.number("Speed where the speed effects are strongest",{default:22,min:1,max:200,unit:"m/s",group:"Speed"}),distanceGain:t.number("How much the camera pulls back at speed",{default:.18,min:0,max:2,unit:"fraction",group:"Speed"}),fov:Pe(62),speedFovKick:kt(10,"going fast"),followSharpness:U("How tightly the camera follows",14,"Smoothing"),yawSharpness:U("How quickly it swings round in turns",3.5,"Smoothing"),lookReturnDelay:t.number("Wait before swinging back after looking around",{default:1.2,min:0,max:10,unit:"s"}),lookReturnSharpness:U("How quickly it swings back",3,"Smoothing"),recoverSharpness:U("How quickly it pulls back out after a wall",3.5,"Smoothing"),lens:t.wiring("Depth of field and other lens effects")}}),c("ControlViewOptions",{title:"Camera view",description:"The view a camera control moves.",fields:{fov:Pe(dr),aspect:$s()}}),c("OrbitControlsOptions",{title:"Orbit",description:"Drag to circle round a point, pinch to zoom.",extends:["ControlViewOptions"],fields:{target:t.vector("The point the camera circles",{default:[0,0,0],min:-F,max:F,unit:"m"}),enableDamping:t.boolean("Keep gliding after letting go",false),dampingFactor:t.number("How quickly the glide stops",{default:.05,min:0,max:1,unit:"fraction"}),minDistance:t.number("Closest it can zoom in",{default:0,min:0,max:F,unit:"m",group:"Limits"}),maxDistance:t.number("Furthest it can zoom out",{default:F,min:0,max:F,unit:"m",group:"Limits"}),minPolarAngle:t.number("Highest it can look down from",{default:0,min:0,max:T,unit:"rad",group:"Limits"}),maxPolarAngle:t.number("Lowest it can look up from",{default:T,min:0,max:T,unit:"rad",group:"Limits"}),minAzimuthAngle:t.number("Furthest it circles one way",{default:-2*T,min:-2*T,max:2*T,unit:"rad",group:"Limits"}),maxAzimuthAngle:t.number("Furthest it circles the other way",{default:2*T,min:-2*T,max:2*T,unit:"rad",group:"Limits"}),autoRotate:t.boolean("Circle on its own",false),autoRotateSpeed:t.number("How fast it circles on its own",{default:2,min:-60,max:60,unit:"none"}),screenSpacePanning:t.boolean("Panning moves across the screen rather than along the ground",true),zoomToCursor:t.boolean("Zoom towards the pointer",false),orthographicHeight:t.number("Height shown in a flat view, 0 to keep it",{default:0,min:0,max:F,unit:"m"})}}),c("FirstPersonControlsOptions",{title:"Walk around",description:"Look by dragging and move with keys, for exploring a scene.",extends:["ControlViewOptions"],fields:{lookSpeed:t.number("How fast dragging turns the view",{default:Math.PI,min:.01,max:20,unit:"rad"}),movementSpeed:t.number("Walking speed",{default:5,min:0,max:1e3,unit:"m/s"}),lookMode:t.choice("How looking works",["drag","pointer","none"],"drag",{labels:{drag:"Drag",pointer:"Follow the pointer",none:"Off"}}),lookVertical:t.boolean("Can look up and down",true),maxPitch:t.number("Furthest it looks up or down",{default:85*Math.PI/180,min:0,max:T/2,unit:"rad"}),keys:Fe("The keys that move"),actionPrefix:Ct("firstPerson")}}),c("PointerLockControlsOptions",{title:"Mouse look",description:"The mouse turns the view, as in a desktop shooter.",fields:{pointerSpeed:t.number("How fast the mouse turns the view",{default:1,min:.01,max:20,unit:"times"}),minPolarAngle:t.number("Furthest it looks up",{default:0,min:0,max:T,unit:"rad"}),maxPolarAngle:t.number("Furthest it looks down",{default:T,min:0,max:T,unit:"rad"}),movementSpeed:t.number("Walking speed, 0 to only look",{default:0,min:0,max:1e3,unit:"m/s"}),keys:Fe("The keys that move"),actionPrefix:Ct("pointerLock")}}),c("FlyControlsOptions",{title:"Fly around",description:"Fly freely through a scene.",extends:["ControlViewOptions"],fields:{movementSpeed:t.number("Flying speed",{default:5,min:0,max:1e4,unit:"m/s"}),rollSpeed:t.number("How fast it rolls",{default:.8,min:0,max:20,unit:"rad/s"}),dragToLook:t.boolean("Only turn while dragging",true),dragSpeed:t.number("How fast dragging turns the view",{default:Math.PI,min:.01,max:20,unit:"rad"}),keys:Fe("The keys that move"),rotationKeys:Fe("The keys that turn and roll"),actionPrefix:Ct("fly")}}),c("TrackballControlsOptions",{title:"Trackball",description:"Spin a scene freely in any direction.",extends:["ControlViewOptions"],fields:{target:t.vector("The point the camera spins round",{default:[0,0,0],min:-F,max:F,unit:"m"}),rotateSpeed:t.number("How fast it spins",{default:1,min:0,max:20,unit:"times"}),zoomSpeed:t.number("How fast it zooms",{default:1.2,min:0,max:20,unit:"times"}),panSpeed:t.number("How fast it pans",{default:.3,min:0,max:20,unit:"times"}),staticMoving:t.boolean("Stop as soon as the finger lifts",false),dynamicDampingFactor:t.number("How quickly the spin slows after letting go",{default:.2,min:0,max:1,unit:"fraction"}),minDistance:t.number("Closest it can zoom in",{default:0,min:0,max:F,unit:"m"}),maxDistance:t.number("Furthest it can zoom out",{default:F,min:0,max:F,unit:"m"})}}),c("DragControlsOptions",{title:"Drag things",description:"Pick up and drag things in the scene with a finger.",fields:{layers:t.integer("Which things can be dragged",{default:4294967295,min:0,max:4294967295,unit:"none",advanced:true}),far:t.number("Furthest a thing can be picked, 0 for no limit",{default:0,min:0,max:F,unit:"m"})}}),c("GyroLookOptions",{title:"Look by tilting",description:"Turning the phone turns the view.",fields:{alphaOffset:t.number("Turn added to the phone's heading",{default:0,min:-T,max:T,unit:"rad"}),smoothing:t.number("How much shaky hands are smoothed",{default:0,min:0,max:1,unit:"fraction"}),screenOrientation:t.choice("How the screen is turned",[0,90,180,270],0,{labels:{0:"Upright",90:"Turned left",180:"Upside down",270:"Turned right"}})}})];var hr=.08,fr=.2,_r=.25,yr=Math.PI/6,br=.5;var Qs=63,gr=()=>t.choice("Which way the model faces when it was made",[1,-1],1,{labels:{1:"Forward",[-1]:"Backward"},advanced:true}),xr=[c("CharacterMotorOptions",{title:"Character movement",description:"How a character walks, runs, jumps, climbs and turns.",fields:{radius:t.number("Body width from the middle",{default:.35,min:.05,max:5,unit:"m",group:"Body"}),height:t.number("Standing height",{default:1.8,min:.1,max:20,unit:"m",group:"Body"}),crouchHeight:t.number("Crouching height",{default:1.15,min:.1,max:20,unit:"m",group:"Body"}),walkSpeed:t.number("Walking speed",{default:2,min:0,max:50,unit:"m/s",group:"Speed"}),runSpeed:t.number("Running speed",{default:5.4,min:0,max:50,unit:"m/s",group:"Speed"}),sprintSpeed:t.number("Sprinting speed",{default:8,min:0,max:100,unit:"m/s",group:"Speed"}),crouchSpeed:t.number("Crouching speed",{default:1.9,min:0,max:50,unit:"m/s",group:"Speed"}),groundAcceleration:t.number("How quickly it speeds up on the ground",{default:45,min:0,max:500,unit:"m/s2",group:"Speed"}),groundDeceleration:t.number("How quickly it stops on the ground",{default:60,min:0,max:500,unit:"m/s2",group:"Speed"}),airAcceleration:t.number("How much it can steer in the air",{default:14,min:0,max:500,unit:"m/s2",group:"Jumping"}),jumpHeight:t.number("How high it jumps",{default:1.3,min:0,max:50,unit:"m",group:"Jumping"}),gravity:t.number("How hard it falls",{default:24,min:0,max:200,unit:"m/s2",group:"Jumping"}),fallGravityScale:t.number("Extra pull on the way down, for snappy jumps",{default:1.55,min:.1,max:10,unit:"times",group:"Jumping"}),jumpCutGravityScale:t.number("Extra pull when the jump button is let go early",{default:2.8,min:.1,max:10,unit:"times",group:"Jumping"}),maxFallSpeed:t.number("Fastest it can fall",{default:42,min:1,max:500,unit:"m/s",group:"Jumping"}),coyoteSeconds:t.number("Grace time to jump after walking off a ledge",{default:.11,min:0,max:1,unit:"s",group:"Jumping"}),jumpBufferSeconds:t.number("How early a jump press is remembered before landing",{default:.13,min:0,max:1,unit:"s",group:"Jumping"}),maxSlopeDegrees:t.number("Steepest slope it can walk up",{default:46,min:0,max:89,unit:"deg",group:"Ground"}),slideSlopeDegrees:t.number("Slope where it starts sliding down",{default:50,min:0,max:90,unit:"deg",group:"Ground"}),stepHeight:t.number("Tallest step it climbs without jumping",{default:.35,min:0,max:5,unit:"m",group:"Ground"}),snapDistance:t.number("How far it sticks to the ground going downhill",{default:.3,min:0,max:5,unit:"m",group:"Ground"}),skin:t.number("Gap kept from walls so it never sticks",{default:.02,min:.001,max:.5,unit:"m",group:"Ground",advanced:true}),turnSharpness:t.number("How quickly it turns to face where it moves",{default:16,min:0,max:100,unit:"none",group:"Turning"}),maxTurnSpeed:t.number("Fastest it can turn",{default:14,min:0,max:100,unit:"rad/s",group:"Turning"}),crouchSharpness:t.number("How quickly it crouches and stands",{default:14,min:0,max:100,unit:"none",group:"Body"}),groundStickSpeed:t.number("Downward push that keeps it on moving floors",{default:2,min:0,max:50,unit:"m/s",group:"Ground",advanced:true}),modelForward:gr()}}),c("CharacterAnimatorOptions",{title:"Character animation",description:"How a character's walk, run, crouch and jump animations blend with its movement.",fields:{locomotion:t.wiring("The blend of walk and run animations"),directional:t.boolean("Steps sideways and backwards instead of always turning to face the way it goes",false),crouch:t.wiring("The blend of crouching animations"),air:t.wiring("The animation played in the air"),blendSharpness:t.number("How quickly animations blend into each other",{default:12,min:0,max:100,unit:"none"}),footIk:t.settings("Feet that land on the ground instead of floating or sinking","FootIkOptions",{group:"Feet"}),rootMotion:t.wiring("Movement taken from the animation itself"),modelForward:gr()}}),c("FootContactOptions",{title:"Foot contact",description:"When a foot is planted, read from the animation.",fields:{footDown:t.wiring("The animation moment a foot lands"),footUp:t.wiring("The animation moment a foot lifts"),actions:t.wiring("Animations that carry foot moments"),curves:t.wiring("Animation curves that say when a foot is down"),tilt:t.wiring("The joint that tilts the foot to the slope")}}),c("FootIkOptions",{title:"Feet on the ground",description:"Feet that land on stairs and slopes instead of floating or sinking.",fields:{left:t.wiring("The left leg"),right:t.wiring("The right leg"),physics:t.wiring("The world the feet test the ground against"),spacing:t.number("Distance between the feet",{default:.12,min:0,max:2,unit:"m"}),ankleHeight:t.number("Height of the ankle above the sole",{default:.08,min:0,max:1,unit:"m"}),reach:t.number("Furthest a foot stretches to find the ground",{default:.5,min:0,max:5,unit:"m"}),leftContact:t.settings("When the left foot is down","FootContactOptions",{advanced:true}),rightContact:t.settings("When the right foot is down","FootContactOptions",{advanced:true}),events:t.wiring("Reads foot moments from the animations"),feet:t.wiring("The foot bones"),lock:t.boolean("Planted feet stay still instead of sliding",true),weightSeconds:t.number("How quickly a landing foot takes weight",{default:hr,min:0,max:2,unit:"s"}),releaseSeconds:t.number("How quickly a lifting foot lets go",{default:fr,min:0,max:2,unit:"s"}),maxSlide:t.number("Furthest a planted foot is dragged before it lets go",{default:_r,min:0,max:5,unit:"m"}),maxTilt:t.number("Most a foot tilts to match a slope",{default:yr,min:0,max:Math.PI/2,unit:"rad"}),plantThreshold:t.number("How firmly a foot must be down to count as planted",{default:br,min:0,max:1,unit:"fraction"})}}),c("AvatarRosterOptions",{title:"Avatars",description:"Shows the player and their friends as their own avatars.",fields:{rig:t.choice("Kind of avatar",["humanoid","head","sprite"],"humanoid",{labels:{humanoid:"Full body",head:"Head only",sprite:"Flat picture"}}),maxFriends:t.integer("Most friends shown",{default:8,min:0,max:Qs}),models:t.wiring("A stand-in model for each kind of avatar")}}),c("FaceSessionOptions",{title:"Face tracking",description:"Follows the player's face with the phone camera, with their permission.",fields:{facing:t.choice("Which camera",["front","back"],"front",{labels:{front:"Selfie",back:"Back"}}),recording:t.boolean("Also ask to record what the camera sees",false),smoothingSeconds:t.number("How much face movement is smoothed",{default:.06,min:0,max:1,unit:"s"})}})];var Sr=4294967295,ra=293,oa=7999,vr=[c("LoopOptions",{title:"Timing",description:"How often the world moves forward and how it catches up after a slow frame.",fields:{fixedHz:t.integer("Simulation steps every second",{default:60,min:10,max:240,unit:"Hz",heavy:true}),maxSubsteps:t.integer("Most steps taken in one frame to catch up",{default:5,min:1,max:16,advanced:true}),maxFrameDeltaMs:t.number("Longest pause the world catches up on before it skips ahead",{default:250,min:16,max:2e3,unit:"ms",advanced:true})}}),c("GameOptions",{title:"Game",description:"The whole Interactive: its world, timing, physics, nature and limits.",extends:["LoopOptions"],fields:{backend:t.wiring("Where the world draws, simulates and plays sound"),seed:t.integer("Starting point for everything random, so every play repeats exactly",{default:0,min:0,max:Sr,unit:"none"}),capacity:t.integer("Most things alive at once",{default:4096,min:64,max:1048575,heavy:true,advanced:true}),surface:t.wiring("The screen the game draws into"),ui:t.wiring("The host that shows the game's on-screen interface"),physics:t.settings("How things move, collide and fall","PhysicsOptions",{group:"Physics"}),animation:t.settings("How many animations can play at once","AnimationOptions",{group:"Animation"}),gestures:t.settings("How swipes and long presses are recognised","GestureOptions",{group:"Touch"}),scratch:t.wiring("Working memory set aside for maths each frame"),maxVoices:t.integer("Most sounds playing at once",{default:64,min:1,max:256,group:"Sound"}),maxHudSlots:t.integer("Most on-screen readouts shown at once",{default:64,min:1,max:512,advanced:true}),nature:t.settings("Temperature, air and gravity for burning, melting and mixing","NatureOptions",{group:"Nature"}),assets:t.wiring("Where the game fetches its pictures, models and sounds ahead of time")}}),c("AnimationOptions",{title:"Animation",description:"Room for tweens, clips and animated values.",fields:{maxTweens:t.integer("Most tweens running at once",{default:1024,min:16,max:16384,advanced:true}),maxClipPlayers:t.integer("Most animation clips playing at once",{default:256,min:8,max:4096,advanced:true}),maxValueSlots:t.integer("Most animated values at once",{default:256,min:8,max:4096,advanced:true})}}),c("GestureOptions",{title:"Gestures",description:"When a touch counts as a swipe or a long press.",fields:{swipeMinDistance:t.number("Shortest movement that counts as a swipe, as a share of the screen",{default:.04,min:.005,max:.5,unit:"fraction"}),swipeMaxDurationMs:t.number("Longest a swipe can take",{default:800,min:50,max:3e3,unit:"ms"}),longPressMs:t.number("How long a finger stays down before it counts as a long press",{default:500,min:100,max:3e3,unit:"ms"})}}),c("DomInputOptions",{title:"Browser input",description:"Which browser inputs reach the game.",fields:{wheel:t.boolean("Read the mouse wheel and trackpad scroll",true),preventWheel:t.boolean("Stop the page from scrolling while the wheel moves the game",false),orientation:t.boolean("Read the device tilt",false),preventContextMenu:t.boolean("Stop the right-click menu over the game",false)}}),c("EngineGraphicsOptions",{title:"Picture",description:"Picture features chosen when the game starts.",fields:{pointShadows:t.boolean("Lamps and point lights cast shadows",true,{heavy:true})}}),c("PlatformBackendOptions",{title:"Device",description:"How the game starts on each device.",fields:{engine:t.wiring("Device start-up choices"),prepared:t.wiring("The fallback used on devices without native drawing"),assets:t.wiring("The Production's packed files")}}),c("NatureOptions",{title:"Nature",description:"The temperature, air pressure and gravity that burning, melting and mixing follow.",fields:{tickHz:t.integer("Nature updates every second",{default:30,min:1,max:240,unit:"Hz",heavy:true}),ambientK:t.number("Air temperature",{default:ra,min:1,max:oa,unit:"K"}),pressureAtm:t.number("Air pressure",{default:1,min:0,max:50,unit:"atm"}),gravity:t.number("Gravity for liquids, powders and gases, where 1 is Earth",{default:1,min:0,max:20,unit:"times"}),conduction:t.number("How fast heat spreads, where 1 is natural",{default:1,min:0,max:64,unit:"times"}),rateShift:t.number("Speeds up or slows every reaction, where 0 is natural",{default:0,min:-16,max:16,unit:"none"}),radiation:t.number("How fast hot things glow their heat away, where 1 is natural",{default:1,min:0,max:64,unit:"times"}),atmosphere:t.choice("The air mix things burn and breathe in",["earth","mars"],"earth")}}),c("RegionOptions",{title:"Nature region",description:"A box of cells where materials burn, melt, flow and react.",fields:{width:t.integer("Cells across",{default:64,min:1,max:1024,unit:"cells",heavy:true}),height:t.integer("Cells up",{default:64,min:1,max:1024,unit:"cells",heavy:true}),depth:t.integer("Cells deep, 1 for a flat region",{default:1,min:1,max:256,unit:"cells",heavy:true}),seed:t.integer("Starting point for randomness in the region",{default:0,min:0,max:Sr,unit:"none"}),open:t.boolean("Edges let material and heat out instead of acting as walls",false)}})];var ia=4294967295,Ue=10,Tr=[c("SeaOptions",{title:"Sea",description:"Open water that boats float on and waves roll across.",fields:{windDirection:t.number("Where the wind blows the waves from",{default:0,min:-Math.PI,max:Math.PI,unit:"rad"}),seed:t.integer("Starting point for the wave pattern",{default:1,min:0,max:ia,unit:"none"})}}),c("PuddleOptions",{title:"Puddles",description:"Shallow water that pools, runs downhill and splashes.",fields:{origin:t.vector("Corner of the puddle area on the ground",{default:[0,0],min:-1e5,max:1e5,unit:"m",axes:["X","Z"]}),cell:t.number("Size of each water cell",{default:.25,min:.01,max:10,unit:"m",heavy:true}),width:t.integer("Cells across",{default:128,min:1,max:2048,unit:"cells",heavy:true}),height:t.integer("Cells deep",{default:128,min:1,max:2048,unit:"cells",heavy:true}),maxDepth:t.number("Deepest the water can pool",{default:.5,min:.01,max:10,unit:"m"})}}),c("RippleOptions",{title:"Ripples",description:"Wakes and ripples that follow a boat or the camera across the water.",fields:{size:t.choice("Cells across the ripple area",[16,32,64,128,256],128,{heavy:true}),cell:t.number("Size of each ripple cell",{default:.25,min:.01,max:10,unit:"m"}),speed:t.number("How fast ripples travel",{default:1.5,min:.1,max:20,unit:"m/s"})}}),c("CraftOptions",{title:"Craft",description:"Anything that floats or flies: its hull, weight and whether it starts running.",fields:{collider:t.wiring("The collision shape the craft uses instead of its own box"),body:t.wiring("Hull size, weight and wings"),running:t.boolean("Starts with its motor on",false)}}),c("PresetOptions",{title:"Craft handling",description:"How strongly a craft pushes, drags, turns and lifts.",extends:["CraftOptions"],fields:{mode:t.choice("Easy handling or true to life",["arcade","sim"],"arcade",{labels:{arcade:"Easy",sim:"True to life"}}),thrust:t.number("Push of the motor, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"}),drag:t.number("Resistance of air and water, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"}),response:t.number("How quickly controls take effect, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"}),lift:t.number("Lift of wings and floats, where 1 is the preset",{default:1,min:.05,max:Ue,unit:"times",group:"Handling"})}}),c("BoatOptions",{title:"Boat",description:"A canoe, speedboat, ferry, cargo ship or sailboat.",extends:["PresetOptions"],fields:{preset:t.choice("Kind of boat",["canoe","speedboat","ferry","cargo_ship","sailboat"],"speedboat")}}),c("AircraftOptions",{title:"Aircraft",description:"A light plane, jet, glider or tiltrotor.",extends:["PresetOptions"],fields:{preset:t.choice("Kind of aircraft",["light_plane","jet","glider","tiltrotor"],"light_plane")}}),c("HelicopterOptions",{title:"Hovering craft",description:"A helicopter, quadcopter or blimp.",extends:["PresetOptions"],fields:{preset:t.choice("Kind of hovering craft",["helicopter","quadcopter","blimp"],"helicopter")}}),c("CraftInputOptions",{title:"Craft controls",description:"How a person steers a craft.",fields:{steering:t.choice("Steer with an on-screen stick or by tilting the phone",["stick","tilt"],"stick",{labels:{stick:"Stick",tilt:"Tilt"}}),invertPitch:t.boolean("Pull back to climb",false)}}),c("TiltOptions",{title:"Tilt steering",description:"How tilting the phone steers.",fields:{rangeDegrees:t.number("Tilt for full steering",{default:30,min:5,max:90,unit:"deg"}),deadzoneDegrees:t.number("Small tilts ignored around rest",{default:2,min:0,max:20,unit:"deg"}),smoothing:t.number("How much shaky hands are smoothed out",{default:.25,min:0,max:1,unit:"fraction"})}})];var sa=4294967295,k=1e6,Ir=["camera","tumble"],wr={camera:"Face the camera",tumble:"Tumble freely"},Rr=[c("ShakeOptions",{title:"Camera shake",description:"The jolt of a hit, an explosion or a landing.",fields:{maxOffset:t.number("Furthest the camera jumps",{default:.35,min:0,max:5,unit:"m"}),maxRoll:t.number("Most the camera tilts",{default:.06,min:0,max:1,unit:"rad"}),decayPerSecond:t.number("How fast the shake settles",{default:1.6,min:.1,max:20,unit:"1/s"}),frequency:t.number("How fast it rattles",{default:22,min:1,max:120,unit:"Hz"}),seed:t.integer("Starting point for the shake pattern",{default:0,min:0,max:sa,unit:"none"})}}),c("SpringOptions",{title:"Bounce",description:"A springy pop, wobble or squash.",fields:{stiffness:t.number("How snappy the spring is",{default:320,min:1,max:5e3,unit:"none",scale:"log"}),damping:t.number("How quickly the bounce settles",{default:16,min:0,max:200,unit:"none"})}}),c("CameraRigOptions",{title:"Follow camera",description:"A camera that keeps one or more players in view.",fields:{smoothSeconds:t.number("How softly the camera catches up",{default:.22,min:1e-4,max:5,unit:"s"}),offset:t.vector("Where the camera sits from the players",{default:[0,0,0],min:-1e3,max:1e3,unit:"m"}),deadZone:t.vector("How far players move before the camera follows",{default:[0,0,0],min:0,max:100,unit:"m"}),lookAheadSeconds:t.number("How far ahead of movement the camera leads",{default:0,min:0,max:5,unit:"s"}),min:t.vector("Lowest corner the camera may move to",{default:[-k,-k,-k],min:-k,max:k,unit:"m",group:"Bounds"}),max:t.vector("Highest corner the camera may move to",{default:[k,k,k],min:-k,max:k,unit:"m",group:"Bounds"}),fovDegrees:t.number("How wide the camera sees",{default:60,min:5,max:170,unit:"deg"}),aspect:t.number("Picture shape, width over height",{default:1,min:.1,max:10,unit:"none"}),padding:t.number("Room kept around the players",{default:0,min:0,max:100,unit:"m"})}}),c("ParticleOptions",{title:"Particles",description:"Sparks, confetti, dust and debris.",fields:{capacity:t.integer("Most particles at once",{default:256,min:1,max:65536,heavy:true}),gravity:t.vector("Pull of gravity on each particle",{default:[0,-9.81,0],min:-100,max:100,unit:"m/s2"}),drag:t.number("How quickly particles slow down in the air",{default:.5,min:0,max:20,unit:"1/s"}),facing:t.choice("Whether particles face the camera or tumble",Ir,"camera",{labels:wr}),additive:t.boolean("Particles glow where they overlap",false),tint:t.boolean("Each particle can have its own colour",true),aspect:t.number("Particle shape, width over height",{default:1,min:.05,max:20,unit:"none"}),plane:t.vector("The floor particles bounce off: which way is up, then its offset",{default:[0,1,0,0],min:-k,max:k,unit:"none",axes:["Up X","Up Y","Up Z","Offset"]}),bounce:t.number("How much particles bounce off the floor",{default:.3,min:0,max:1,unit:"fraction"})}}),c("SprayOptions",{title:"Spray",description:"A stream of particles, such as a fountain, smoke puff or sparkler.",fields:{emitter:t.wiring("How fast, how wide and how long the particles fly"),material:t.wiring("How each particle looks"),cell:t.vector("Part of the picture each particle shows",{default:[0,0,1,1],min:0,max:1,unit:"fraction",axes:["Left","Top","Width","Height"]}),facing:t.choice("Whether particles face the camera or tumble",Ir,"camera",{labels:wr}),aspect:t.number("Particle shape, width over height",{default:1,min:.05,max:20,unit:"none"})}}),c("WavesOptions",{title:"Waves",description:"Enemies or targets that arrive in rounds.",fields:{waitForClear:t.boolean("Wait until a round is cleared before the next",true),endless:t.boolean("Keep going after the last round",false),growth:t.number("Extra arrivals added each endless round",{default:0,min:0,max:10,unit:"fraction"})}}),c("ScoreTimerOptions",{title:"Score and timer",description:"Points, combos and a clock.",fields:{seconds:t.number("Countdown length, 0 for a stopwatch",{default:0,min:0,max:86400,unit:"s"}),comboWindow:t.number("Time between scores that keeps a combo going, 0 for no combos",{default:0,min:0,max:30,unit:"s"}),maxCombo:t.integer("Highest combo multiplier",{default:1,min:1,max:100,unit:"times"}),clockSeconds:t.number("Longest a stopwatch shows",{default:3600,min:1,max:864e3,unit:"s"})}}),c("CheckpointOptions",{title:"Checkpoints",description:"Places a player must reach, and where they come back after a fall.",fields:{radius:t.number("How close counts as reached",{default:2,min:.1,max:100,unit:"m"}),ordered:t.boolean("Checkpoints must be reached in order",true),killY:t.number("Height below which a player falls back to the last checkpoint",{default:-k,min:-k,max:k,unit:"m"})}}),c("ArenaOptions",{title:"Arena",description:"A walled square floor to play on.",fields:{half:t.number("Half the width of the floor",{default:10,min:1,max:1e3,unit:"m"}),wallHeight:t.number("Wall height",{default:1,min:0,max:100,unit:"m"}),wallThickness:t.number("Wall thickness",{default:.4,min:.01,max:10,unit:"m"}),groundDepth:t.number("Floor thickness",{default:.5,min:.01,max:10,unit:"m"})}}),c("DaylightOptions",{title:"Daylight",description:"A simple sun and sky to light a scene.",fields:{sun:t.number("Sun brightness",{default:2,min:0,max:100,unit:"times"}),sky:t.number("Sky brightness",{default:.7,min:0,max:100,unit:"times"}),sunX:t.number("Sun position east to west",{default:3,min:-1e3,max:1e3,unit:"m",group:"Sun position"}),sunY:t.number("Sun height",{default:10,min:-1e3,max:1e3,unit:"m",group:"Sun position"}),sunZ:t.number("Sun position north to south",{default:4,min:-1e3,max:1e3,unit:"m",group:"Sun position"})}}),c("SeekBotOptions",{title:"Chaser",description:"A character that runs after a target.",fields:{arrive:t.number("How close counts as caught",{default:.6,min:.01,max:100,unit:"m"}),jumpEvery:t.integer("Steps between jumps, 0 for never",{default:0,min:0,max:1e4}),jumpHold:t.integer("Steps each jump is held for",{default:9,min:1,max:600})}})];var V=128;var be=8;var ma=new Float32Array(1);new Uint32Array(ma.buffer);var Ge=2,We=16;var Lt=2,Ve=4;var Pr=.5;var Fr=.05;new TextDecoder("utf-8",{fatal:true});var ba=new Float64Array(1);new Uint32Array(ba.buffer);var Aa=new Float64Array(1);new Uint32Array(Aa.buffer);var Ea=new Float32Array(1);new Uint32Array(Ea.buffer);var Na=new Float32Array(1);new Uint32Array(Na.buffer);var za=new Float64Array(1);new Uint32Array(za.buffer);var Dt=65536;var Wr=4294967295,X=4294967295,Xa=4,Vr=["beforeScene","afterOpaque","afterTransparent","post","afterPost"],qr={beforeScene:"Before the scene",afterOpaque:"After solid things",afterTransparent:"After see-through things",post:"With picture effects",afterPost:"Last"},zr=[c("EntityTableOptions",{title:"Crowd table",description:"Room for a large crowd of similar things, such as particles, fish or people.",fields:{capacity:t.integer("Most things in the crowd",{default:1024,min:1,max:1<<22,heavy:true}),selections:t.integer("Saved groups picked out of the crowd",{default:4,min:0,max:64,advanced:true}),cell:t.number("Size of the grid used to find neighbours",{default:4,min:.01,max:1e3,unit:"m"}),gridTable:t.integer("Room for neighbour lookups",{default:16384,min:64,max:1<<22,advanced:true})}}),c("QueryWhere",{title:"Neighbour filter",description:"Only neighbours whose flags match.",fields:{field:t.text("The flags to read","",64),equals:t.integer("Flags must equal this",{default:0,min:0,max:X,unit:"none"}),any:t.integer("At least one of these flags is set",{default:0,min:0,max:X,unit:"none"}),none:t.integer("None of these flags is set",{default:0,min:0,max:X,unit:"none"}),mask:t.integer("Only these flags are compared",{default:X,min:0,max:X,unit:"none"})}}),c("QueryOptions",{title:"Neighbour search",description:"How a crowd member finds the others near it.",fields:{limit:t.integer("Most neighbours returned",{default:X,min:1,max:X}),cell:t.number("Size of the search grid, 0 to use the crowd's",{default:0,min:0,max:1e3,unit:"m"}),field:t.text("Position used for the search","position",64),where:t.settings("Only neighbours whose flags match","QueryWhere")}}),c("NearestFeatureOptions",{title:"Nearest neighbour features",description:"Where the nearest crowd members are and how they move, ready to feed a network.",extends:["QueryOptions"],fields:{velocity:t.text("Speed read from each neighbour, empty for position only","",64)}}),c("KernelOptions",{title:"Crowd behaviour",description:"Where a behaviour that runs on every member of a crowd works and how much it matters.",fields:{device:t.choice("Which part of the phone runs it",["auto","cpu","gpu"],"auto",{labels:{auto:"Automatic",cpu:"Main chip",gpu:"Graphics chip"}}),feeds:t.choice("Who reads its results",["host","render","auto"],"auto",{labels:{host:"Game logic",render:"Drawing only",auto:"Automatic"}}),priority:t.choice("What happens when the phone is busy",["simulation","presentation","optional"],"simulation",{labels:{simulation:"Always runs",presentation:"Can drop to keep frames smooth",optional:"Skipped first"}})}}),c("KernelSettings",{title:"Crowd running",description:"How every crowd behaviour runs, checks itself and splits work across the phone.",fields:{mode:t.choice("How behaviours run",["auto","native","vm","js","dev"],"auto",{labels:{auto:"Automatic",native:"Fastest",vm:"Portable",js:"Script",dev:"Checked while making"}}),checkEvery:t.integer("Frames between self checks while making",{default:30,min:1,max:1e4,advanced:true}),tolerance:t.number("Difference allowed in a self check",{default:.001,min:1e-9,max:1,unit:"none",scale:"log",advanced:true}),report:t.wiring("Hears about a failed self check"),gpu:t.choice("Allow the graphics chip to run behaviours",["auto","off"],"auto",{labels:{auto:"Automatic",off:"Off"}}),gpuRows:t.integer("Crowd size before the graphics chip takes over, 0 picks itself",{default:0,min:0,max:1<<24,advanced:true}),gpuClass:t.choice("Kind of graphics chip to plan for",["unknown","mobile","desktop","discrete"],"mobile",{labels:{unknown:"Unknown",mobile:"Phone",desktop:"Computer",discrete:"Gaming computer"}}),cpuLanes:t.integer("Crowd members worked on side by side",{default:4,min:1,max:16,advanced:true}),cpuBackend:t.choice("How the main chip runs behaviours",["auto","interpreter","cranelift","wasm"],"auto",{labels:{auto:"Automatic",interpreter:"Steady",cranelift:"Fast",wasm:"Portable"},advanced:true}),frameBudgetMs:t.number("Time behaviours may take each frame, 0 picks itself",{default:0,min:0,max:100,unit:"ms",heavy:true}),gpuCalibrate:t.integer("Frames spent measuring the graphics chip, 0 to skip",{default:0,min:0,max:1e3,advanced:true}),gpuPins:t.wiring("Behaviours fixed to one chip"),onRoute:t.wiring("Hears where each behaviour runs"),onCompute:t.wiring("Hears graphics chip problems")}}),c("LoopSettings",{title:"Loop running",description:"How simple loops over a crowd are sped up.",fields:{schedule:t.choice("How loops run",["auto","kernel","js"],"auto",{labels:{auto:"Automatic",kernel:"Sped up",js:"Script"}}),chunkRows:t.integer("Crowd members handled in one go",{default:Dt,min:1,max:Dt,advanced:true}),enabled:t.boolean("Speed up loops",true)}}),c("KernelRecordingOptions",{title:"Behaviour recording",description:"Records a crowd behaviour over time, to train from or compare against.",fields:{args:t.wiring("Inputs the behaviour is given"),objectiveArgs:t.wiring("Inputs the training goal is given"),steps:t.integer("Steps recorded",{default:600,min:1,max:1e6}),warmup:t.integer("Steps skipped before recording",{default:0,min:0,max:1e6}),fields:t.list("What is recorded about each member",t.text("A recorded value","",64),{maxItems:64})}}),c("MlpTrainingOptions",{title:"Training",description:"Teaches a small network to act like a recorded behaviour.",fields:{widths:t.list("Size of each layer of the network",t.integer("Layer size",{default:16,min:1,max:1024}),{maxItems:8,default:[16,16]}),epochs:t.integer("Times the recording is learned from",{default:20,min:1,max:1e4,heavy:true}),batch:t.integer("Examples learned from at once",{default:32,min:1,max:4096}),learningRate:t.number("How big each learning step is",{default:.02,min:1e-6,max:1,unit:"none",scale:"log"}),momentum:t.number("How much each step carries on from the last",{default:.9,min:0,max:.999,unit:"fraction"}),seed:t.integer("Starting point for training",{default:1,min:0,max:Wr,unit:"none"})}}),c("MoeTrainingOptions",{title:"Team training",description:"Teaches a team of small networks, each taking the cases it handles best, to act like a recorded behaviour.",fields:{experts:t.integer("Networks in the team",{default:Xa,min:Ge,max:We,heavy:true}),router:t.list("Size of each middle layer of the network that picks a team member",t.integer("Layer size",{default:16,min:1,max:V}),{maxItems:be-1,default:[]}),expert:t.list("Size of each middle layer of every team member",t.integer("Layer size",{default:16,min:1,max:V}),{maxItems:be-1,default:[]}),epochs:t.integer("Times the recording is learned from",{default:20,min:1,max:1e4,heavy:true}),batch:t.integer("Examples learned from at once",{default:32,min:1,max:4096}),learningRate:t.number("How big each learning step is",{default:.02,min:1e-6,max:1,unit:"none",scale:"log"}),momentum:t.number("How much each step carries on from the last",{default:.9,min:0,max:.999,unit:"fraction"}),seed:t.integer("Starting point for training",{default:1,min:0,max:Wr,unit:"none"}),balance:t.number("How evenly the cases are shared across the team",{default:Pr,min:0,max:10,unit:"none"})}}),c("ImportOptions",{title:"Network import",description:"Brings in a network made elsewhere and checks it still answers the same.",fields:{samples:t.wiring("Example inputs it is checked against"),maxDrift:t.number("Largest difference allowed from the original",{default:Fr,min:0,max:1,unit:"fraction"}),memory:t.integer(`Values carried to the next step, 0 for none or ${Lt} to ${Ve}`,{default:0,min:0,max:Ve})}}),c("GpuDrawOptions",{title:"Custom drawing",description:"When a hand-written drawing pass runs and what it draws into.",fields:{hook:t.choice("When it draws",Vr,"afterTransparent",{labels:qr}),target:t.wiring("What it draws into"),instances:t.integer("Copies drawn",{default:1,min:1,max:1<<24,heavy:true})}}),c("GpuDispatchOptions",{title:"Custom work",description:"When a hand-written graphics chip job runs.",fields:{hook:t.choice("When it runs",Vr,"beforeScene",{labels:qr}),indirect:t.wiring("Takes its size from a buffer")}})];var Kr=4;var Xr=()=>t.integer("Messages queued on each channel",{default:64,min:1,max:4096,advanced:true}),Yr=()=>t.integer("Largest single message",{default:1200,min:64,max:65536,unit:"bytes",advanced:true}),jr=()=>t.integer("Simulation steps every second shared by everyone in the room, 0 to follow the game",{default:0,min:0,max:240,unit:"Hz"}),$r=[c("ReplayRecorderOptions",{title:"Replays",description:"Lets players share the last moments of a game, which plays back exactly the same for anyone who opens it.",fields:{window_ticks:t.integer("How much of the game a replay keeps, in steps",{default:600,min:1,max:36e3}),keyframe_every:t.integer("How often a replay can begin, in steps",{default:60,min:1,max:3600,advanced:true}),input_stride:t.integer("Space for one step of a player's controls",{default:8,min:1,max:1024,unit:"bytes",advanced:true}),tick_hz:t.integer("Steps every second",{default:60,min:1,max:240,unit:"Hz",advanced:true}),interactive_id:t.wiring("Which game the replay belongs to"),revision:t.wiring("Which version of the game made the replay"),play_from_here:t.boolean("Players can pick up and play on from where a replay ends",false)}}),c("LoopbackOptions",{title:"Practice room",description:"A room that runs on this device alone, for trying out multiplayer.",fields:{slots:Xr(),slotBytes:Yr()}}),c("TickRoomOptions",{title:"Room",description:"A live room shared with other people.",fields:{renew:t.wiring("Fetches a fresh pass when the old one runs out"),slots:Xr(),slotBytes:Yr(),physicsHz:jr(),memory:t.wiring("Remembers which connection worked best"),network:t.wiring("Reports which network the device is on")}}),c("RoomClientOptions",{title:"Room connection",description:"How a device joins and stays in a live room.",fields:{tickets:t.wiring("Fetches a pass to join the room"),primary:t.wiring("The main way to connect"),fallback:t.wiring("The way to connect when the main one fails"),physicsHz:jr(),memory:t.wiring("Remembers which connection worked best"),network:t.wiring("Reports which network the device is on"),channels:t.wiring("Receives the room's messages"),motion:t.wiring("How other people's movement is smoothed"),spectatorAckEvery:t.integer("How often a watcher confirms what they have seen, in steps",{default:Kr,min:1,max:60,advanced:true})}}),c("TickLockstepLinkOptions",{title:"Turn sharing",description:"Everyone in the room moves forward together, step by step.",fields:{seats:t.integer("People who play together",{default:2,min:1,max:64}),channel:t.text("Name of the channel the steps travel on","lockstep",64,{advanced:true})}}),c("PlanarSnapshotOptions",{title:"Position sharing",description:"Sends where things are on a flat playing field to everyone in the room.",fields:{entities:t.integer("Things shared",{default:16,min:1,max:1024,heavy:true}),extent:t.number("Half the width of the playing field",{default:50,min:1,max:1e5,unit:"m"}),bits:t.integer("Precision of each position; more is finer and costs more data",{default:12,min:4,max:32,heavy:true}),history:t.integer("Past updates kept to smooth movement",{default:32,min:2,max:256,advanced:true})}}),c("LeaderboardOptions",{title:"Leaderboard",description:"Ranks scores across players.",fields:{name:t.text("Leaderboard name","high-scores",64),scope:t.choice("Whose scores it ranks",["personal","interactive","shared"],"interactive",{labels:{personal:"Just me",interactive:"Everyone who plays",shared:"Across Interactives"}}),mode:t.choice("What a new score does",["replace","keep_highest","keep_lowest","increment"],"keep_highest",{labels:{replace:"Replaces the old one",keep_highest:"Keeps the best high",keep_lowest:"Keeps the best low",increment:"Adds up"}}),direction:t.choice("Whether high or low scores rank first",["asc","desc"],"desc",{labels:{asc:"Lowest first",desc:"Highest first"}})}})];var q={mass:.01,stretch:1e-7,bend:1e-4,tetherSlack:.05,damping:.5,gravity:{y:-9.81},substeps:8,thickness:.005,friction:.2};var eo=4096;var to=.02;var z={stretch:1e-6,bend:1e-4,volume:0,damping:.5,gravity:{y:-9.81},substeps:10,radius:.01,friction:.3,contraction:.3};var ze=100,sl=16,al=4294967295,oo=1e3,io=r=>t.vector("Pull of gravity on it",{default:[0,r,0],min:-ze,max:ze,unit:"m/s2"}),so=[c("PhysicsOptions",{title:"Physics",description:"Gravity, how many things can move and collide, and how carefully they are solved.",fields:{gravity:t.vector("Pull of gravity",{default:[0,-9.81,0],min:-ze,max:ze,unit:"m/s2"}),maxBodies:t.integer("Most moving things",{default:2048,min:16,max:65536,heavy:true,group:"Limits"}),maxColliders:t.integer("Most collision shapes",{default:4096,min:16,max:131072,heavy:true,group:"Limits"}),maxJoints:t.integer("Most hinges, springs and links",{default:1024,min:0,max:65536,group:"Limits"}),maxContactEvents:t.integer("Most touches reported each step",{default:1024,min:16,max:65536,group:"Limits",advanced:true}),maxCharacterControllers:t.integer("Most walking characters",{default:64,min:0,max:4096,group:"Limits"}),rollback:t.wiring("Memory kept so the world can rewind and replay"),solver:t.settings("How carefully contacts and joints are solved","SolverSettings",{group:"Accuracy"})}}),c("SolverSettings",{title:"Accuracy",description:"How carefully stacks, joints and fast things are solved.",fields:{iterations:t.integer("Passes over contacts each step; more keeps tall stacks steady",{default:Qn,min:1,max:er,heavy:true}),pgsIterations:t.integer("Extra passes that settle resting things",{default:Zn,min:1,max:tr,heavy:true,advanced:true}),ccdSubsteps:t.integer("Extra checks that stop fast things passing through walls",{default:Jn,min:0,max:nr,heavy:true})}}),c("FluidColliderOptions",{title:"Fluid contact",description:"How water, sand, jelly and snow touch a solid thing.",fields:{friction:t.number("How much the fluid grips the surface",{default:0,min:0,max:2,unit:"none"}),feedback:t.boolean("The fluid pushes back on the thing, so it floats and gets carried",true)}}),c("CrumpleOptions",{title:"Crumple",description:"How a solid dents and crushes when it hits something hard.",fields:{cells:t.vector("Dent grid across, up and along",{default:[4,2,6],min:1,max:32,unit:"cells",heavy:true}),threshold:t.number("Impact speed before it dents",{default:3,min:0,max:100,unit:"m/s"}),crush:t.number("How far each hit pushes in",{default:.02,min:0,max:1,unit:"m"}),maxDepth:t.number("Deepest a dent can go",{default:.35,min:0,max:10,unit:"m"}),radius:t.number("Spread of each dent, 0 picks a quarter of its size",{default:0,min:0,max:50,unit:"m"}),stiffness:t.number("How much it resists bending back",{default:1e-5,min:1e-9,max:1,unit:"none",scale:"log"})}}),c("SoftBodyOptions",{title:"Soft body",description:"Squishy, stretchy things like jelly, rubber, muscle and rope.",fields:{stretch:t.number("Give when pulled; lower is stiffer",{default:z.stretch,min:1e-10,max:1,unit:"none",scale:"log"}),bend:t.number("Give when bent; lower is stiffer",{default:z.bend,min:1e-10,max:1,unit:"none",scale:"log"}),volume:t.number("How hard it keeps its size when squeezed, 0 for not at all",{default:z.volume,min:0,max:1,unit:"none"}),damping:t.number("How fast wobbling dies down",{default:z.damping,min:0,max:10,unit:"1/s"}),gravity:io(z.gravity.y),substeps:t.integer("Smaller steps each frame; more is steadier",{default:z.substeps,min:1,max:64,heavy:true}),radius:t.number("Thickness of each point for collisions",{default:z.radius,min:.001,max:1,unit:"m"}),friction:t.number("How much it grips what it touches",{default:z.friction,min:0,max:2,unit:"none"}),contraction:t.number("How strongly muscle fibres pull when flexed",{default:z.contraction,min:0,max:1,unit:"fraction",group:"Muscle"}),fibre:t.vector("Which way muscle fibres run, none when all zero",{default:[0,0,0],min:-1,max:1,unit:"none",group:"Muscle"}),plastic:t.wiring("How it keeps a dent once bent far enough"),geometry:t.asset("The shape that follows the soft body","geometry")}}),c("ClothOptions",{title:"Cloth",description:"Flags, curtains, capes and sails.",fields:{mass:t.number("Weight of each point of cloth",{default:q.mass,min:1e-4,max:10,unit:"kg",scale:"log"}),stretch:t.number("Give when pulled; lower is stiffer",{default:q.stretch,min:1e-10,max:1,unit:"none",scale:"log"}),bend:t.number("Give when folded; lower is stiffer",{default:q.bend,min:1e-10,max:1,unit:"none",scale:"log"}),tetherSlack:t.number("How far it can sag from where it hangs",{default:q.tetherSlack,min:0,max:1,unit:"fraction"}),damping:t.number("How fast flapping dies down",{default:q.damping,min:0,max:10,unit:"1/s"}),gravity:io(q.gravity.y),substeps:t.integer("Smaller steps each frame; more is steadier",{default:q.substeps,min:1,max:64,heavy:true}),thickness:t.number("Thickness for collisions",{default:q.thickness,min:1e-4,max:.1,unit:"m"}),friction:t.number("How much it grips what it touches",{default:q.friction,min:0,max:2,unit:"none"}),geometry:t.asset("The shape that follows the cloth","geometry")}}),c("FractureOptions",{title:"Breaking apart",description:"How a model is cut into pieces that fly apart when it breaks.",fields:{pieces:t.integer("Pieces it breaks into",{default:sl,min:1,max:eo,heavy:true}),seed:t.integer("Starting point for the cut pattern",{default:1,min:0,max:al,unit:"none"}),impact:t.vector("Where it is hit",{default:[0,0,0],min:-oo,max:oo,unit:"m"}),focus:t.number("Share of the pieces gathered around where it is hit",{default:0,min:0,max:1,unit:"fraction"}),interiorUvScale:t.number("Pattern size on the broken faces",{default:1,min:.01,max:100,unit:"times",advanced:true}),anchorHeight:t.number("Pieces this close to the bottom stay put",{default:to,min:0,max:10,unit:"m"})}})];var co="Placement",uo="position",mo="rotation",po="scale",ao=1e6,lo=180,ll=.001,cl=1e3,ho=[c(co,{title:"Placement",description:"Where a thing sits, which way it turns and how big it is.",fields:{[uo]:t.vector("Where it sits",{default:[0,0,0],min:-ao,max:ao,unit:"m"}),[mo]:t.vector("Which way it turns",{default:[0,0,0],min:-lo,max:lo,unit:"deg"}),[po]:t.vector("How big it is",{default:[1,1,1],min:ll,max:cl,unit:"times"})}})];new Uint8Array(new Uint32Array([1]).buffer)[0]===1;var Ft=class{constructor(){this.ready=false;this.startX=0;this.startY=0;this.endX=0;this.endY=0;this.deltaX=0;this.deltaY=0;this.distance=0;this.durationMs=0;this.velocityX=0;this.velocityY=0;this.curl=0;}},Ut=class{constructor(){this.ready=false;this.x=0;this.y=0;}},Ht=class{constructor(){this.active=false;this.down=false;this.x=0;this.y=0;this.buttons=0;this.count=0;}},Ke=class{constructor(){this.active=false;this.scale=1;this.totalScale=1;this.centerX=0;this.centerY=0;this.panX=0;this.panY=0;this.rotation=0;this.distance=0;}},Xe=class{constructor(){this.deltaX=0;this.deltaY=0;this.deltaZ=0;this.x=0;this.y=0;}},xe=class{constructor(){this.x=0;this.y=0;}},Bt=class{constructor(){this.drag=new xe;this.motion=new xe;this.wheel=new Xe;this.pinch=new Ke;this.pressed=false;this.released=false;this.releasedButtons=0;this.pressX=0;this.pressY=0;}dragging(e){return (e.down||this.released)&&e.count<=1}dragButtons(e){return e.down?e.buttons:this.releasedButtons}begin(){this.drag.x=0,this.drag.y=0,this.motion.x=0,this.motion.y=0,this.wheel.deltaX=0,this.wheel.deltaY=0,this.wheel.deltaZ=0,this.pinch.active=false,this.pinch.scale=1,this.pinch.panX=0,this.pinch.panY=0,this.pinch.rotation=0,this.pressed=false,this.released=false,this.releasedButtons=0;}},Gt=class{constructor(){this.ready=false;this.x=0;this.y=0;this.durationMs=0;}},Wt=class{constructor(){this.available=false;this.alpha=0;this.beta=0;this.gamma=0;}};A(new Ft,["startX","startY","endX","endY","deltaX","deltaY","distance","durationMs","velocityX","velocityY","curl"]);A(new Ut,["x","y"]);A(new Ht,["x","y"]);A(new Ke,["scale","totalScale","centerX","centerY","panX","panY","rotation","distance"]);A(new Xe,["deltaX","deltaY","deltaZ","x","y"]);A(new xe,["x","y"]);A(new Bt,["pressX","pressY"]);A(new Gt,["x","y","durationMs"]);A(new Wt,["alpha","beta","gamma"]);var fo=8;var fl=["leftStickRightButtons","twinStick","oneThumb","driving"],_l={leftStickRightButtons:"Stick and buttons",twinStick:"Two sticks",oneThumb:"One thumb",driving:"Driving"},Ye=1e6,_o=()=>t.choice("Arrangement of the on-screen controls",fl,"leftStickRightButtons",{labels:_l}),yo=()=>t.list("On-screen buttons",t.settings("A button","ButtonSpec"),{maxItems:fo}),bo=r=>t.text("Name the controls are listed under",r,64,{advanced:true}),go=[c("StickSpec",{title:"Stick",description:"An on-screen thumb stick.",fields:{x:t.text("Control the stick's left and right move","",64,{advanced:true}),y:t.text("Control the stick's up and down move","",64,{advanced:true}),tap:t.text("Control a quick tap on the stick presses","",64,{advanced:true}),mode:t.choice("Appears where the thumb lands, or stays put",["floating","fixed"],"floating",{labels:{floating:"Where the thumb lands",fixed:"Stays put"}}),axes:t.choice("Which ways the stick moves",["both","x","y"],"both",{labels:{both:"All ways",x:"Left and right",y:"Up and down"}}),radius:t.number("Stick size",{default:58,min:20,max:200,unit:"px"}),deadZone:t.number("Small movements ignored around the middle",{default:.12,min:0,max:.9,unit:"fraction"}),curve:t.number("Fine control near the middle, where 1 is even",{default:1,min:.25,max:4,unit:"none"}),follow:t.boolean("The stick slides along under the thumb",true),snapSeconds:t.number("How quickly the stick springs back",{default:.12,min:0,max:1,unit:"s"})}}),c("LookSpec",{title:"Look area",description:"Dragging on the screen turns the camera.",fields:{sensitivity:t.number("How far a drag turns the camera",{default:1,min:.05,max:10,unit:"times"}),inertiaSeconds:t.number("How long the turn glides after a flick",{default:.16,min:0,max:2,unit:"s"})}}),c("ButtonSpec",{title:"Button",description:"An on-screen button.",fields:{control:t.text("The control the button presses","jump",64),label:t.text("What a screen reader says for the button","",40),icon:t.integer("The picture on the button",{default:0,min:0,max:65535,unit:"none"}),mode:t.choice("Hold down, or tap on and off",["hold","toggle"],"hold",{labels:{hold:"Hold",toggle:"Tap on and off"}}),doubleTap:t.text("The control a double tap presses","",64,{advanced:true}),cooldownSeconds:t.number("Wait before it can be pressed again",{default:0,min:0,max:600,unit:"s"}),lookThrough:t.boolean("Dragging off the button still turns the camera",false),size:t.number("Button size, 0 for the layout's",{default:0,min:0,max:300,unit:"px"})}}),c("TouchControlsOptions",{title:"Touch controls",description:"On-screen sticks and buttons for playing on a phone.",fields:{ui:t.wiring("The interface the controls draw into"),theme:t.wiring("Colours and type of the controls"),layout:_o(),move:t.settings("The stick that moves","StickSpec",{group:"Sticks"}),aim:t.settings("The stick that aims","StickSpec",{group:"Sticks"}),look:t.settings("Dragging to look around","LookSpec",{group:"Sticks"}),buttons:yo(),viewport:t.wiring("The size of the screen area"),autoHide:t.boolean("Fade the controls when not touched",true),idleOpacity:t.number("How visible faded controls stay",{default:.5,min:0,max:1,unit:"fraction"}),z:t.integer("Stacking above other on-screen things",{default:50,min:0,max:1e3,unit:"none",advanced:true})}}),c("TouchOptions",{title:"Play controls",description:"The on-screen controls a ready-made player uses.",fields:{ui:t.wiring("The interface the controls draw into"),theme:t.wiring("Colours and type of the controls"),viewport:t.wiring("The size of the screen area"),surface:t.wiring("Reads the screen size as it changes"),layout:_o(),move:t.settings("The stick that moves","StickSpec",{group:"Sticks"}),look:t.settings("Dragging to look around","LookSpec",{group:"Sticks"}),buttons:yo()}}),c("CharacterRigOptions",{title:"Player",description:"A ready-made player character with its controls.",extends:["TouchOptions"],fields:{entity:t.thing("The character to control, or a new one","character"),position:t.vector("Where the player starts",{default:[0,0,0],min:-Ye,max:Ye,unit:"m"}),heading:t.number("Which way the player starts facing",{default:0,min:-Math.PI,max:Math.PI,unit:"rad"}),camera:t.thing("The camera that follows the player, or a new one","camera"),character:t.settings("How the player moves","CharacterMotorOptions",{group:"Movement"}),animation:t.wiring("The player's animations"),prefix:bo("play"),register:t.boolean("Starts running as soon as it is made",true,{advanced:true})}}),c("ThirdPersonOptions",{title:"Third person player",description:"A player seen from behind and over the shoulder.",extends:["CharacterRigOptions"],fields:{follow:t.settings("How the camera follows","FollowCameraOptions",{group:"Camera"})}}),c("FirstPersonOptions",{title:"First person player",description:"A player who sees through their own eyes.",extends:["CharacterRigOptions"],fields:{view:t.settings("How the eyes view moves","FirstPersonViewOptions",{group:"Camera"})}}),c("VehicleDriverOptions",{title:"Driver",description:"A ready-made vehicle a player drives, with its controls and camera.",extends:["TouchOptions"],fields:{vehicle:t.thing("The vehicle to drive, or a new one","vehicle"),preset:t.choice("Kind of vehicle",["danfo","keke","okada","car"],"danfo",{labels:{danfo:"Minibus",keke:"Tuk-tuk",okada:"Motorbike taxi",car:"Car"}}),model:t.choice("Easy handling or true to life",["arcade","sim"],"arcade",{labels:{arcade:"Easy",sim:"True to life"}}),position:t.vector("Where the vehicle starts",{default:[0,0,0],min:-Ye,max:Ye,unit:"m"}),camera:t.thing("The camera that follows, or a new one","camera"),chase:t.settings("How the camera follows","ChaseCameraOptions",{group:"Camera"}),prefix:bo("drive"),register:t.boolean("Starts running as soon as it is made",true,{advanced:true})}})];var xo=16;var So="UiMotion",Ao="MusicBed",Eo="CrowdVote",vo="CrowdCheer",yl=8,bl=10,gl=600,To=[c(So,{title:"When it changes",description:"How a shown value moves when it goes up, goes down or changes.",fields:{on:t.choice("When it plays",["up","down","change"],"up",{labels:{up:"When it goes up",down:"When it goes down",change:"Whenever it changes"}}),when:t.text("Only while this is true, for example on a streak; empty for always","",80),steps:t.list("What happens, in order",t.choice("A step",["count_up","pop","settle","flash"],"count_up",{labels:{count_up:"Count up",pop:"Pop",settle:"Settle",flash:"Flash"}}),{maxItems:yl,default:["count_up","pop","settle"]}),seconds:t.number("How long each step takes",{default:.3,min:0,max:bl,unit:"s"}),pop:t.number("How big a pop gets",{default:1.2,min:1,max:3,unit:"times"}),flash:t.color("Flash colour",16765286)}}),c(Ao,{title:"Music",description:"Music that follows the game: moods mix the stems in and out on the beat, and moments play cues.",fields:{bpm:t.number("Beats per minute",{default:110,min:30,max:240,unit:"none"}),beatsPerBar:t.integer("Beats in a bar",{default:4,min:1,max:12}),bars:t.integer("Bars before it loops",{default:8,min:1,max:64}),rampSeconds:t.number("How long a change of mood takes",{default:2,min:0,max:30,unit:"s"}),follows:t.text("What the mood follows, for example the time of day or how close the match is","hour",80)}}),c(Eo,{title:"Crowd vote",description:"A question the people watching answer together, such as player of the match.",fields:{question:t.text("The question","Player of the match?",120),choices:t.list("The answers",t.text("An answer","",60),{maxItems:xo,default:[]}),opensOn:t.text("The moment it opens on, for example full time","full_time",80),seconds:t.number("How long it stays open",{default:20,min:1,max:gl,unit:"s"})}}),c(vo,{title:"Cheer",description:"Taps from the crowd fill a noise meter that drains over time.",fields:{on:t.boolean("Let the crowd cheer",true),perTap:t.number("How much one tap fills",{default:.01,min:0,max:1,unit:"fraction"}),drainPerSecond:t.number("How fast it drains",{default:.1,min:0,max:1,unit:"1/s"})}})];var Io="WorldSky",wo="ScatterBrush",Ro="GroundBrush",xl=4294967295,Sl=24,Oo=[c(Io,{title:"Sky and time",description:"The time of day a place starts at, its weather and how fast the day passes.",fields:{hour:t.number("Time of day it starts at, in hours from midnight",{default:17.5,min:0,max:Sl,unit:"none",step:.25}),weather:t.choice("The weather",["clear","overcast","fog","drizzle","heavy_rain","thunderstorm","snow","blizzard","desert_dust","monsoon","golden_hour","night","harmattan_haze","real_sky"],"clear",{labels:{clear:"Clear",overcast:"Overcast",fog:"Fog",drizzle:"Drizzle",heavy_rain:"Heavy rain",thunderstorm:"Thunderstorm",snow:"Snow",blizzard:"Blizzard",desert_dust:"Desert haze and dust",monsoon:"Monsoon",golden_hour:"Golden hour",night:"Night",harmattan_haze:"Harmattan haze (West Africa)",real_sky:"Follows the real sky"}}),dayMinutes:t.number("Minutes of play for a full day, 0 to keep the time still",{default:12,min:0,max:1440,unit:"none"})}}),c(wo,{title:"Scatter",description:"Scatters props or people under the brush, keeping clear of walls and each other.",fields:{layer:t.choice("What the brush scatters",["props","crowds"],"crowds",{labels:{props:"Stalls and props",crowds:"People"}}),radius:t.number("Brush size",{default:4,min:.5,max:50,unit:"m"}),count:t.integer("How many each stroke adds",{default:12,min:1,max:200,heavy:true}),spacing:t.number("Smallest gap between them",{default:1,min:.2,max:20,unit:"m"}),seed:t.integer("Starting point for where they land",{default:1,min:0,max:xl,unit:"none",advanced:true})}}),c(Ro,{title:"Ground brush",description:"Raises, lowers, flattens, smooths or paints the ground under the brush.",fields:{op:t.choice("What the brush does",["raise","lower","smooth","flatten","paint"],"raise",{labels:{raise:"Raise",lower:"Lower",smooth:"Smooth",flatten:"Flatten",paint:"Paint"}}),radius:t.number("Brush size",{default:6,min:.5,max:100,unit:"m"}),strength:t.number("How much each stroke changes",{default:.5,min:0,max:1,unit:"fraction"}),layer:t.integer("The ground paint the brush lays down",{default:0,min:0,max:7,unit:"none"})}})];var ko=8192;var Co=64;var El=4294967295,Lo=16777215,Mo=1<<24,je=r=>t.integer(r,{default:4294967295,min:0,max:4294967295,unit:"none",advanced:true}),Do=[c("ExtrudeOptions",{title:"Extrude",description:"Turns a flat shape into a solid with depth and rounded edges.",fields:{curveSegments:t.integer("Smoothness of curved outlines",{default:12,min:1,max:64,heavy:true}),steps:t.integer("Slices along the depth",{default:1,min:1,max:64,heavy:true}),depth:t.number("How deep the solid is",{default:1,min:0,max:100,unit:"m"}),bevelEnabled:t.boolean("Round the front and back edges",true,{group:"Edges"}),bevelThickness:t.number("How far the rounded edge reaches into the depth",{default:.2,min:0,max:10,unit:"m",group:"Edges"}),bevelSize:t.number("How far the rounded edge reaches out from the outline",{default:.1,min:-10,max:10,unit:"m",group:"Edges"}),bevelOffset:t.number("Where the rounded edge starts from the outline",{default:0,min:-10,max:10,unit:"m",group:"Edges"}),bevelSegments:t.integer("Smoothness of the rounded edge",{default:3,min:1,max:32,group:"Edges",heavy:true}),extrudePath:t.wiring("A curve to sweep the shape along instead of straight back")}}),c("TextGeometryOptions",{title:"3D text",description:"Solid lettering made from a font.",extends:["ExtrudeOptions"],omit:["extrudePath"],fields:{size:t.number("Letter height",{default:1,min:.01,max:100,unit:"m"}),direction:t.choice("Which way the text runs",["ltr","rtl","tb"],"ltr",{labels:{ltr:"Left to right",rtl:"Right to left",tb:"Top to bottom"}}),depth:t.number("How deep the letters are",{default:.2,min:0,max:100,unit:"m"}),bevelEnabled:t.boolean("Round the letter edges",false,{group:"Edges"})}}),c("BatchedMeshOptions",{title:"Batched shapes",description:"Many different shapes drawn together in one go.",fields:{material:t.asset("The surface every shape in the batch shares","material"),maxVertices:t.integer("Room for corners across all shapes",{default:65536,min:3,max:16777216,heavy:true,advanced:true}),maxGeometries:t.integer("Most different shapes in the batch",{default:64,min:1,max:4096,advanced:true}),maxInstances:t.integer("Most copies drawn",{default:1024,min:1,max:1048576,heavy:true}),maxInstanceVertices:t.integer("Room for corners of the drawn copies",{default:65536,min:3,max:16777216,advanced:true}),colors:t.boolean("Each copy can have its own colour",false),castShadow:t.boolean("Casts shadows",true,{heavy:true}),receiveShadow:t.boolean("Shows shadows falling on it",true),native:t.boolean("Draw the batch on the device in one pass",true,{advanced:true})}}),c("CameraProjectionOptions",{title:"Lens",description:"How a camera turns the world into a picture.",fields:{mode:t.choice("Natural depth or flat, map-like view",["perspective","orthographic"],"perspective",{labels:{perspective:"Natural",orthographic:"Flat"}}),fov:t.number("How wide the camera sees, top to bottom",{default:60,min:5,max:170,unit:"deg"}),near:t.number("Closest distance the camera shows",{default:.1,min:.001,max:100,unit:"m",scale:"log"}),far:t.number("Furthest distance the camera shows",{default:1e3,min:1,max:1e6,unit:"m",scale:"log",heavy:true}),height:t.number("How much of the world a flat view shows top to bottom",{default:10,min:.01,max:1e5,unit:"m",scale:"log"}),zoom:t.number("Zoom",{default:1,min:.01,max:100,unit:"times",scale:"log"}),width:t.number("Picture width the lens is shaped for",{default:1,min:1,max:16384,unit:"px",advanced:true}),viewportHeight:t.number("Picture height the lens is shaped for",{default:1,min:1,max:16384,unit:"px",advanced:true})}}),c("DebugDrawOptions",{title:"Guide lines",description:"Lines drawn over the scene to show shapes, paths and contacts.",fields:{capacity:t.integer("Most line segments drawn each frame",{default:ko,min:16,max:1048576,advanced:true}),layers:je("Which views show the lines"),depthTest:t.boolean("Hide lines behind solid things",true),renderOrder:t.integer("Draw order against other see-through things",{default:0,min:-Mo,max:Mo,unit:"none",advanced:true})}}),c("ScreenLabelsOptions",{title:"Labels",description:"Name tags and markers that follow things across the screen.",fields:{capacity:t.integer("Most labels at once",{default:Co,min:1,max:4096}),anchors:t.wiring("Where each label reads its position"),ui:t.wiring("The on-screen interface the labels draw into"),engineText:t.wiring("Text drawn in the scene instead of on the interface"),occluder:t.wiring("Hides labels behind walls"),occlusionLayers:je("Which things can hide a label"),fadeNear:t.number("Distance where labels start to fade, 0 for never",{default:0,min:0,max:1e4,unit:"m"}),fadeFar:t.number("Distance where labels are gone, 0 for never",{default:0,min:0,max:1e4,unit:"m"}),clampToEdge:t.boolean("Keep labels of things off screen pinned to the edge",false),margin:t.number("Gap kept from the screen edge",{default:0,min:0,max:512,unit:"px"})}}),c("EnvironmentOptions",{title:"Sky",description:"The sky, sun and light that surround the scene.",fields:{width:t.integer("Sky picture width",{default:256,min:16,max:4096,unit:"px",heavy:true,advanced:true}),height:t.integer("Sky picture height",{default:128,min:8,max:2048,unit:"px",heavy:true,advanced:true}),intensity:t.number("Overall sky brightness",{default:1,min:0,max:20,unit:"times"}),format:t.choice("Colour precision of the sky",["rgba16f","rgba32f"],"rgba16f",{labels:{rgba16f:"Standard",rgba32f:"High"},heavy:true,advanced:true}),sunDirection:t.vector("Where the sun sits in the sky",{default:[.4,.6,.3],min:-1,max:1,unit:"none",group:"Sun"}),sunColor:t.color("Sun colour",Lo,{group:"Sun"}),sunIntensity:t.number("Sun brightness",{default:40,min:0,max:1e3,unit:"times",group:"Sun"}),skyColor:t.color("Colour overhead",3832789,{group:"Colours"}),horizonColor:t.color("Colour at the horizon",13624309,{group:"Colours"}),groundColor:t.color("Colour below the horizon",5919302,{group:"Colours"}),color:t.color("The single colour of a plain backdrop",8421504,{group:"Colours"}),moonDirection:t.vector("Where the moon sits in a night sky",{default:[-0.3,.5,-0.6],min:-1,max:1,unit:"none",group:"Night"}),starDensity:t.number("How many stars fill a night sky",{default:.004,min:0,max:.1,unit:"fraction",group:"Night"}),seed:t.integer("Starting point for where the stars fall",{default:0,min:0,max:El,unit:"none",group:"Night"})}}),c("ApplyEnvironmentOptions",{title:"Sky and exposure",description:"The sky with how it lights the scene and how bright the picture looks.",extends:["EnvironmentOptions"],fields:{background:t.boolean("Show the sky behind the scene",true,{group:"Picture"}),backgroundBlurriness:t.number("Blur the sky behind the scene",{default:0,min:0,max:1,unit:"fraction",group:"Picture"}),environmentIntensity:t.number("How strongly the sky lights things",{default:1,min:0,max:20,unit:"times",group:"Picture"}),toneMapping:t.choice("The look of bright and dark areas",["none","linear","reinhard","aces","agx","neutral","cineon","custom"],"agx",{labels:{none:"Raw",linear:"Linear",reinhard:"Soft",aces:"Film",agx:"Natural",neutral:"Neutral",cineon:"Classic film",custom:"Custom"},group:"Picture"}),exposure:t.number("Picture brightness, each sky look picks its own when unset",{default:.5,min:0,max:10,unit:"times",group:"Picture"})}}),c("TransitionOptions",{title:"Transition",description:"How one shot changes into the next.",fields:{color:t.color("Colour faded through",0),direction:t.vector("Which way a wipe travels",{default:[1,0],min:-1,max:1,unit:"none",axes:["X","Y"]}),softness:t.number("How soft the wipe or iris edge is",{default:.05,min:0,max:1,unit:"fraction"}),center:t.vector("Where an iris opens and closes on screen",{default:[.5,.5],min:0,max:1,unit:"fraction",axes:["X","Y"]}),cellSize:t.number("Block size of a pixelate change",{default:48,min:2,max:512,unit:"px"}),noiseScale:t.number("Grain of a dissolve",{default:6,min:.1,max:100,unit:"none"}),edge:t.number("Width of the dissolve's glowing edge",{default:.08,min:0,max:1,unit:"fraction"})}}),c("CrossfadeOptions",{title:"Crossfade",description:"Blends the last picture of one shot into the next.",fields:{camera:t.thing("The camera that films the blend","camera"),cameraNode:t.wiring("The drawn view of that camera"),width:t.integer("Width of the held picture",{default:1280,min:16,max:8192,unit:"px",heavy:true}),height:t.integer("Height of the held picture",{default:720,min:16,max:8192,unit:"px",heavy:true}),fovDegrees:t.number("How wide the camera sees",{default:60,min:5,max:170,unit:"deg"}),near:t.number("Closest distance the camera shows",{default:.1,min:.001,max:100,unit:"m",scale:"log"}),aspect:t.number("Picture shape, width over height",{default:16/9,min:.1,max:10,unit:"none"}),layers:je("Which things appear in the held picture"),overlayLayer:je("The view the blend shows in")}}),c("PortLightOptions",{title:"Light",description:"A sun, lamp, spotlight, panel or sky light.",fields:{color:t.color("Light colour",Lo),intensity:t.number("Brightness",{default:1,min:0,max:1e4,unit:"times",scale:"linear"}),distance:t.number("How far a lamp reaches, 0 for no limit",{default:0,min:0,max:1e4,unit:"m"}),decay:t.number("How quickly a lamp fades with distance",{default:2,min:0,max:4,unit:"none"}),angle:t.number("Width of a spotlight's beam",{default:Math.PI/3,min:0,max:Math.PI/2,unit:"rad"}),penumbra:t.number("How soft a spotlight's edge is",{default:0,min:0,max:1,unit:"fraction"}),groundColor:t.color("Light bouncing up from the ground for a sky light",4473924),castShadow:t.boolean("Casts shadows",false,{heavy:true,group:"Shadows"}),shadowMapSize:t.integer("Shadow sharpness, 0 picks for the phone",{default:0,min:0,max:8192,unit:"px",heavy:true,group:"Shadows"}),width:t.number("Width of a panel light",{default:1,min:.01,max:1e3,unit:"m"}),height:t.number("Height of a panel light",{default:1,min:.01,max:1e3,unit:"m"})}})];var Po=[.2,.2,.2],Fo=.1,Uo=.2;var Bo="ThingPart",Go="ThingEffect",Y=50,Ho=180,Vt=.001,vl=J.map(r=>r.id),Tl=Object.fromEntries(J.map(r=>[r.id,r.label])),Wo=[c(Bo,{title:"Part",description:"One shape in a thing: what it is, where it sits, what it is made of and how it combines.",fields:{shape:t.choice("The shape",Sn,"box",{labels:{box:"Box",sphere:"Sphere",cylinder:"Cylinder",tube:"Tube",rounded:"Rounded"},group:"Shape"}),size:t.vector("Width, height and depth of a box or rounded box",{default:Po,min:Vt,max:Y,unit:"m",axes:["Width","Height","Depth"],group:"Shape"}),radius:t.number("Radius of a sphere, cylinder or tube, or the rounding of a rounded box",{default:Fo,min:Vt,max:Y,unit:"m",group:"Shape"}),length:t.number("Height of a cylinder or length of a tube",{default:Uo,min:Vt,max:Y,unit:"m",group:"Shape"}),at:t.vector("Where it sits in the thing",{default:[0,0,0],min:-Y,max:Y,unit:"m",group:"Placement"}),turn:t.vector("Which way it turns",{default:[0,0,0],min:-Ho,max:Ho,unit:"deg",group:"Placement"}),mirror:t.choice("A matching copy on the other side",Rn,"none",{labels:{none:"No copy",x:"Left and right",y:"Top and bottom",z:"Front and back"},group:"Placement"}),material:t.choice("What it is made of, which sets its weight, grip, bounce and whether it burns",vl,ht,{labels:Tl,group:"Made of"}),combine:t.choice("How it meets the parts before it",wn,"join",{labels:{join:"Join",cut:"Cut away",overlap:"Keep only the overlap"},group:"Combine"})}}),c(Go,{title:"Effect",description:"Fire, smoke, steam, sparks, confetti, water, rain, breaking apart or a sound that comes off a thing.",fields:{kind:t.choice("The effect",On,"smoke",{labels:{fire:"Fire",smoke:"Smoke",steam:"Steam",sparks:"Sparks",confetti:"Confetti",water:"Water",rain:"Rain",break:"Breaks apart",sound:"Sound"}}),startsAfter:t.number("Starts this long after it is set off",{default:0,min:0,max:600,unit:"s"}),lasts:t.number("How long it lasts, 0 to keep going",{default:0,min:0,max:600,unit:"s"}),color:t.color("Colour, for sparks and confetti",16777215),sound:t.asset("The sound it plays","sound"),at:t.vector("Where it comes off the thing",{default:[0,0,0],min:-Y,max:Y,unit:"m"}),size:t.number("How big it is",{default:.2,min:.01,max:10,unit:"m",heavy:true})}})];new TextEncoder;new TextDecoder;new TextEncoder;new TextDecoder;var $e=[1,3,8],qo=10,zo=.35,Ko=1.5,Xo=3,Yo=6,jo=24*1024*1024,$o=8,Qo=2,Zo=1024,Jo=50,ei=.3;var ti=2;var qt=4294967295,Qe=1024*1024,wl=8*Qe,Rl=[16e4,8e4,0],Ol=2e6,kl=1,Cl=1e3,Nl=$e[$e.length-1]*2,zt=()=>t.choice("Phone class the detail is planned for",["low","mid","high"],"mid",{labels:{low:"Cheaper phones",mid:"Most phones",high:"Newest phones"},heavy:true}),ni=[c("WorldColliderOptions",{title:"World collisions",description:"How solid ground and buildings are kept around moving things in a big world.",fields:{budget:t.integer("Collision pieces added or removed each step",{default:16,min:1,max:1024,heavy:true}),actors:t.integer("Moving things that keep the ground solid around them",{default:8,min:1,max:256}),stepSeconds:t.number("Time between collision updates",{default:1/60,min:1/240,max:1,unit:"s",advanced:true})}}),c("WorldStreamOptions",{title:"Big world",description:"A large place that loads around the camera as people move.",fields:{world:t.asset("The world's map","pack"),packs:t.wiring("Every part of the world loaded up front"),packPaths:t.list("Parts of the world loaded as the camera needs them",t.asset("A part of the world","pack"),{maxItems:4096}),assets:t.wiring("Reads the parts of the world"),materials:t.list("Surfaces the world's parts use",t.asset("A surface","material"),{maxItems:256}),tier:zt(),colliders:t.settings("How the ground stays solid around moving things","WorldColliderOptions")}}),c("WorldPrefetchOptions",{title:"World look-ahead",description:"Fetches the parts of a big world people are heading towards.",fields:{paths:t.list("Parts of the world, in order",t.asset("A part of the world","pack"),{maxItems:4096}),bytes:t.wiring("Size of each part"),name:t.text("Name of this look-ahead layer","world",64,{advanced:true})}}),c("SceneryLoadOptions",{title:"Captured scenery",description:"A real place captured from photos.",fields:{assets:t.wiring("Reads the captured place"),cacheBytes:t.integer("Memory kept for parts of the place already seen",{default:wl,min:Qe,max:512*Qe,unit:"bytes",heavy:true}),regions:t.wiring("Region names from the capture's bake report, so edits can name parts"),heroBudget:t.vector("Moving splats allowed on the newest, most and cheaper phones",{default:Rl,min:0,max:Ol,unit:"count",axes:["Newest phones","Most phones","Cheaper phones"],heavy:true}),standIn:t.wiring("Shown instead while a phone cannot afford this moving capture")}}),c("SceneryMotionOptions",{title:"Moving scenery",description:"A crowd behaviour that moves, turns and tints each splat of a captured place.",fields:{table:t.wiring("The crowd the behaviour runs over, one member per splat"),reach:t.number("Furthest any splat moves from where it was captured",{default:kl,min:0,max:Cl,unit:"m"}),offset:t.wiring("Crowd fields that move each splat"),rotation:t.wiring("Crowd fields that turn each splat"),colour:t.wiring("Crowd fields added to each splat's colour"),opacity:t.text("Crowd field added to each splat's opacity","",64),rest:t.wiring("Crowd fields filled with where each splat was captured")}}),c("SceneryDrapeOptions",{title:"Draped cloth",description:"Cloth that hangs from a captured body and carries its splats.",fields:{rest:t.wiring("The baked cloth's starting shape, taken from the cloth when left out")}}),c("SplatBodyOptions",{title:"Captured body",description:"A captured person or object that moves with a rigged model.",extends:["SceneryLoadOptions"],fields:{manifest:t.asset("The captured body","data"),rig:t.thing("The rigged model whose animation moves the body")}}),c("SplatTwinOptions",{title:"Product twin",description:"Shows each colour or finish of a product on one capture.",fields:{body:t.wiring("The captured product the looks are applied to"),variants:t.wiring("The product's variants from the catalogue"),looks:t.wiring("The edit each variant applies to the capture's regions"),selected:t.text("Variant shown first, the first available one when empty","",64)}}),c("TerrainRecipe",{title:"Landscape shape",description:"Hills, ridges, rock, snow and sand of a landscape.",fields:{base:t.number("Ground height before any hills",{default:0,min:-1e3,max:1e3,unit:"m"}),amplitude:t.number("Height of the tallest hills",{default:60,min:0,max:2e3,unit:"m"}),octaves:t.integer("Layers of detail, from mountains down to bumps",{default:7,min:1,max:12,heavy:true}),frequency:t.number("How close together hills are",{default:.004,min:1e-4,max:.1,unit:"none",scale:"log"}),lacunarity:t.number("How much finer each layer of detail is",{default:2,min:1,max:4,unit:"times"}),gain:t.number("How strong each finer layer is",{default:.5,min:0,max:1,unit:"fraction"}),seed:t.integer("Starting point for the landscape",{default:1,min:0,max:qt,unit:"none"}),ridged:t.number("Sharp mountain ridges instead of rounded hills",{default:0,min:0,max:1,unit:"fraction"}),warp:t.number("Twists the hills into winding shapes",{default:0,min:0,max:1,unit:"fraction"}),rockSlope:t.number("Steepness where bare rock shows",{default:.25,min:0,max:1,unit:"fraction",group:"Surfaces"}),snowHeight:t.number("Height where snow starts",{default:35,min:-1e3,max:5e3,unit:"m",group:"Surfaces"}),sandHeight:t.number("Height below which sand shows",{default:0,min:-1e3,max:5e3,unit:"m",group:"Surfaces"})}}),c("TerrainOptions",{title:"Landscape",description:"Ground you can sculpt, paint and walk on.",fields:{size:t.integer("Width of the landscape",{default:2048,min:64,max:65536,unit:"m",heavy:true}),spacing:t.number("Distance between height points",{default:1,min:.1,max:64,unit:"m",heavy:true}),center:t.vector("Middle of the landscape",{default:[0,0],min:-1e6,max:1e6,unit:"m",axes:["X","Z"]}),heightMin:t.number("Lowest ground",{default:-64,min:-1e4,max:1e4,unit:"m"}),heightRange:t.number("Height between the lowest and highest ground",{default:512,min:1,max:2e4,unit:"m"}),tier:zt(),recipe:t.settings("The shape of hills, rock, snow and sand","TerrainRecipe",{group:"Shape"}),pack:t.asset("A sculpted landscape saved earlier","pack")}}),c("GrassOptions",{title:"Grass",description:"Blades of grass that cover the ground and sway.",fields:{seed:t.integer("Starting point for where blades grow",{default:1,min:0,max:qt,unit:"none"}),density:t.number("Blades in each square metre",{default:96,min:1,max:1024,unit:"count",heavy:true}),height:t.vector("Shortest and tallest blades",{default:[.35,.8],min:.01,max:5,unit:"m",axes:["Shortest","Tallest"]}),width:t.vector("Thinnest and widest blades",{default:[.03,.06],min:.001,max:1,unit:"m",axes:["Thinnest","Widest"]}),radius:t.number("How far from the camera grass is drawn",{default:60,min:5,max:500,unit:"m",heavy:true}),maxSlope:t.number("Steepest ground grass grows on",{default:.35,min:0,max:1,unit:"fraction"}),layer:t.integer("Which painted ground layer grass grows on",{default:0,min:0,max:7,unit:"none"}),color:t.rgb("Blade colour",[.1,.22,.04]),tipBrightness:t.number("How much brighter the tips are",{default:3,min:0,max:10,unit:"times"})}}),c("LayerOptions",{title:"Ground paint",description:"A surface painted onto the landscape, such as grass, dirt or rock.",fields:{color:t.rgb("Surface colour",[.5,.45,.35]),roughness:t.number("How rough rather than shiny it looks",{default:.85,min:0,max:1,unit:"fraction"}),tiling:t.number("How often its pattern repeats",{default:4,min:.1,max:64,unit:"times"}),heightScale:t.number("Depth of its bumps",{default:1,min:0,max:4,unit:"times"}),variation:t.number("How much it varies across the ground",{default:.25,min:0,max:1,unit:"fraction"}),normalStrength:t.number("Strength of its fine surface detail",{default:1,min:0,max:4,unit:"times"})}}),c("PlanetOptions",{title:"Planet",description:"A whole round world you can fly around.",fields:{radius:t.number("Planet size from its centre to the ground",{default:6e3,min:10,max:1e7,unit:"m",scale:"log"}),levels:t.integer("Levels of detail as you get closer",{default:6,min:1,max:20,heavy:true}),amplitude:t.number("Height of the tallest mountains",{default:60,min:0,max:1e5,unit:"m"}),seed:t.integer("Starting point for the planet's shape",{default:1,min:0,max:qt,unit:"none"}),tier:zt()}}),c("PredictorOptions",{title:"Look-ahead",description:"Guesses where people are heading so what they need next is already there.",fields:{horizons:t.list("How far ahead to look",t.number("Seconds ahead",{default:1,min:.1,max:120,unit:"s"}),{maxItems:8,default:$e}),maxSpeed:t.number("Fastest people are expected to move",{default:qo,min:.1,max:1e3,unit:"m/s"}),spread:t.number("How much the guess widens with distance",{default:zo,min:0,max:5,unit:"none"}),minSpread:t.number("Narrowest the guess gets",{default:Ko,min:.01,max:100,unit:"m"}),turnPenalty:t.number("How unlikely sharp turns are",{default:Xo,min:1,max:20,unit:"times"}),interval:t.integer("Frames between new guesses",{default:Yo,min:1,max:120}),budgetBytes:t.integer("Most data fetched ahead of need",{default:jo,min:0,max:1024*Qe,unit:"bytes",heavy:true}),maxPending:t.integer("Most fetches at once",{default:$o,min:1,max:64}),maxSpeculative:t.integer("Most fetches on a hunch",{default:Qo,min:1,max:64}),releaseSeconds:t.number("How long unused things stay before they are let go",{default:Nl,min:.1,max:600,unit:"s"}),capacity:t.integer("Most things tracked",{default:Zo,min:1,max:65536,advanced:true}),teleport:t.number("A jump this far counts as a teleport and starts over",{default:Jo,min:1,max:1e5,unit:"m"}),smoothing:t.number("How much movement is smoothed before guessing",{default:ei,min:.001,max:1,unit:"fraction"}),saturationSeconds:t.number("How long a busy connection waits before new fetches",{default:ti,min:.01,max:60,unit:"s"}),reach:t.wiring("Where things can be reached from")}}),c("PrefetchStreamOptions",{title:"Look-ahead stream",description:"Look-ahead tied to the parts of a Production.",extends:["PredictorOptions"],fields:{stalled:t.wiring("Reports when play is waiting on data"),assets:t.wiring("Where the parts are fetched from")}}),c("CompileSceneOptions",{title:"Scene layout",description:"The kinds of things a laid-out scene can place.",fields:{catalogue:t.wiring("Sizes and anchors of every kind of thing")}}),c("SlotSceneOptions",{title:"Template scene",description:"Turns a laid-out scene into a template's scene slot.",fields:{area:t.vector("Size of the scene",{default:[20,20],min:0,max:1e5,unit:"m",axes:["Width","Depth"]}),points:t.wiring("Named points in the scene"),roles:t.wiring("Which template role each group or point plays"),catalogue:t.wiring("Sizes of every kind of thing")}}),c("RemixOptions",{title:"Remix",description:"Where a remix came from and what it was made from.",fields:{parent:t.wiring("The Production this remix came from"),sources:t.wiring("The parts the remix was made from")}}),c("AssignOptions",{title:"Fill template",description:"Fills a template's slots.",fields:{base:t.wiring("Slot values to start from"),readFile:t.wiring("Reads files the slots name")}})];var Kt=new Ce([...ho,...Wo,...Oo,...To,...vr,...Do,...so,...Tr,...Xn,...$r,...ni,...zr,...Rr,...xr,...pr,...go]);var Ll=["spawn_point","waypoint"],Ml=[.5,.5],Dl=[{kind:"shopper",label:"Shoppers"},{kind:"trader",label:"Traders"},{kind:"walker",label:"Walkers"},{kind:"porter",label:"Porters"},{kind:"child",label:"Children"}];function Pl(r){let e=r.split("_").join(" ");return e.length===0?e:e[0].toUpperCase()+e.slice(1)}function ri(r=Ee){let e=[];for(let[o,i]of Object.entries(r))Ll.includes(o)||e.push({kind:o,label:Pl(o),layer:"prop",footprint:i.footprint});let n=Dl.map(o=>({kind:o.kind,label:o.label,layer:"person",footprint:r[o.kind]?.footprint??Ml}));return {placeables:e,people:n}}var oi="CimplifyStudioKernel",Fl=H|ue,Ul=["low","mid","high"],Hl={low:"cheaper phones",mid:"most phones",high:"newer phones"},Bl={ground:"the ground",roads:"roads",buildings:"buildings",props:"stalls and props",crowds:"people",lights:"lights",sounds:"sounds"};function j(r){try{return JSON.parse(r)}catch{return null}}function Gl(r){let e={};for(let n of r){if(!Kt.has(n))continue;let o=Kt.resolve(n),i={};for(let s of o.fields)i[s.name]={...s.setting,group:s.group};e[n]={name:n,title:o.schema.title,description:o.schema.description,order:o.fields.map(s=>s.name),fields:i};}return e}function Wl(){return J.map(r=>({id:r.id,label:r.label,color:r.look.color,breaks:r.breaks}))}function Vl(r){try{let e=Cn(r),n=e.levels[0].mesh;return {ok:!0,reason:null,cost:e.cost,mass_kg:e.mass.mass,breaks:gn(r.parts.map(o=>o.material)),levels:e.levels.map(o=>({name:o.name,triangles:o.mesh.triangles,dropped:o.dropped})),mesh:{positions:Array.from(n.positions),normals:Array.from(n.normals),indices:Array.from(n.indices),groups:n.groups}}}catch(e){if(e instanceof ee)return {ok:false,reason:e.message};throw e}}function ql(r){return r.length<=1?r.join(""):`${r.slice(0,-1).join(", ")} and ${r[r.length-1]}`}function zl(r){let e=ql(r.layers.map(n=>Bl[n.layer]));return `${Kl(Hl[r.tier])} stay heavy even with no people: ${e} weigh too much on their own.`}function Kl(r){return r.length===0?r:r[0].toUpperCase()+r.slice(1)}function Xl(r,e){let n=fn(e,r.crowdCaps??{});if(n===null)return null;let o={};for(let i of Ul){let s=n.caps[i];typeof s=="number"&&(o[i]=s);}return {crowd_caps:o,fixes:n.fixes.map(i=>({tier:i.tier,from:i.from,to:i.to})),still_heavy:n.stillHeavy.map(i=>({tier:i.tier,without_people:i.withoutPeople,budget:i.budget,layers:i.layers.map(s=>({layer:s.layer,cost:s.cost,share:s.share})),summary:zl(i)}))}}function Yl(r){let e=_n(r),n=Array.from(e.grid.cells,o=>o&Fl);return {grid:{columns:e.grid.columns,rows:e.grid.rows,cell:e.grid.cell,cells:n},placements:e.placements,people:e.people,weight:{total:e.weight.total,layers:e.weight.layers,tiers:e.weight.tiers,tier_totals:e.weight.tierTotals,tier_people:e.weight.tierPeople},checks:e.checks.map(o=>({id:o.id,ok:o.ok,summary:o.summary})),fewer_people:Xl(r,e.weight)}}var jl=JSON.stringify({ok:false,reason:"That could not be read."}),ii=["low","mid","high"];function $l(r){if(typeof r!="object"||r===null)return false;let e=r;return typeof e.label=="string"&&typeof e.bytes=="number"&&Number.isFinite(e.bytes)&&typeof e.beforePlay=="boolean"&&(e.tier===null||e.tier===void 0||ii.includes(e.tier))}function Ql(r){if(typeof r!="object"||r===null)return null;let e=r;return typeof e.tier=="string"&&ii.includes(e.tier)&&typeof e.frames=="object"&&typeof e.memory=="object"&&typeof e.heat=="object"?e:null}function si(){return {schemas(r){let e=j(r),n=Array.isArray(e)?e.filter(o=>typeof o=="string"):[];return JSON.stringify(Gl(n))},materials(){return JSON.stringify(Wl())},catalogue(){return JSON.stringify(ri())},compileThing(r){let e=j(r);return e===null||!Array.isArray(e.parts)?jl:JSON.stringify(Vl({...e,effects:e.effects??[]}))},buildPlace(r){let e=j(r);if(e===null||!Array.isArray(e.size))return "null";try{return JSON.stringify(Yl(e))}catch{return "null"}},outcome(r,e){let n=j(r);return Array.isArray(n)?JSON.stringify(Un(n.filter($l),Ql(j(e)))):"null"},simplifyRoad(r,e){let n=j(r),o=j(e);return Array.isArray(n)?JSON.stringify(ln(n,typeof o=="number"&&o>0?o:0)):"[]"}}}globalThis[oi]=si();})();