@wildshard/shard-format 0.0.1 → 0.4.5
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.
- package/corpus/brasscap-mesa/blobs/bin/02da0052111419cdff3a29f1c6d0ff0d223e0b53a956c16c65ed63d87928b3b9.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/068a121cd780a2a9164416f6e4fde44834f2d2f3a5ed65c174e480b7a2d3f627.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/07d5a061cd338618e528747d61eb2b17709510550ef0ba40a58b67761b200f3f.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/086e3706070555baca863f6ecf9dbca09c084afa501d92d4246d896b09546f36.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/08b1b9ab7c732d7dbe8f961f1fc40e84042d1fe42544f55c9ee89f04dffe3d5e.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/18bdbdc704cb8aac93435d208dfe0e9a44374efb73afa3bc58c631650e0a2995.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/1a210fcddcb9749ecb1c244837e8e37ea69b038faae191dee6bbbde228d31a18.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/264ab9ede386504a5ff9814b0a620b879cb29f3f45a80bcfc0c80b8ee236e364.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/2b6fbea4c846a23cf4802ebdb1804e128896c8dd87e5d23509db6729e5b1be4e.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/2d755cc635dee90b0f3958272855a821e2dd605a189a5ffcd480a325155fe84f.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/2d76c6829fe77fb55cc2541e4aca5ce5d18b68508dcdf3fa957fe4a83b9c887a.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/32c15d55a4548501740593807c5007217c72dbc10a21f4613ef5e0cee0b90d1d.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/3539b362cf3a61a79e92e113ebf8f255d0b25ec2d2edd816498879de831fa912.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/3af38a2377bc89f6c6c82ee1e83df674efa2793db932b50a23bbce7ec9cd7941.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/3c176a7a0d0850fdcee790ed2641216fc3d1cba025928de3d7784262bb9b6f4a.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/3fb37e488aa81a64c997b3dd09794e988994c6ee3476c6d653ced1670888dd8e.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/424dcc7b320317bf3f2c62c8f19bc80564035127eb38ab811e460934d57ea38c.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/45cea35fab6bb06051a3286fca2307944850c7f9ed7aa89b7c24fafef28efda6.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/499cc7863851f97d79dbfc64e76f9e6978894199184a0d80ebdca13066a8fa78.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/4b7217644763b00c6ee6ae3f176c726914966fb791654a385c0638bb998b6dd2.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/4cf11c7177bb082f335e5bc7a037ef00d09355c5ad8263e284a96a92630ff9ae.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/536b37cab5a1edd6a68a71d122aab6898e44c68a5470a4ca8a9a72c57c02e034.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/55d3628b27e0fcea383df86c434a69761439f51a013359f0829675b07ee2b616.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/5652ba90fbd8146edaf42660329cc81798752f2f60b8d03956714460d5ba75ef.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/57459ab5e2ac6cec65ef5e59789dd82b9666d8573df41c4a398df603f1fa456f.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/5915b6aed21bba49b841b45574f44f60d26b44810bd68ac70b22f3f3b0dab072.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/5c4a5c7a8e99253561105c5fa3faf14326cf0c23adc32bfe7f8aea4dbf4b05f9.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/61822a412cfd461f4f7ae50bc13f242a0fca6c5c58fca72247b596ab037a1c85.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/673b7712908966718341508469b39cd49e6461f690ca3c23d4621ea7eba0cc30.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/69394a49520f84f6dccc1655f1c89eedc913ac53a7e48ac5dc1bff4141639bb4.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/6e58a53a6c2acd50f9f80fd270ca034c54421df8a587e181101b4b75b952ac5d.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/75dc9f23ee71e11a3a0c67eb77275d741a281c3398808fb42efd52b9973d5d04.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/76c6a403293a68ed3d6ad14e9dd27b555c3a1ef4a3cae12a2bd2ab3e67c5ad02.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/82b73ce3a18e47092840fc029177861887aa2867b007248ac79ffa20895a4491.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/8430d9bbfb4e2b678c54595ad95555c3c73d0e1b144a4d6e29664ccb4371baf0.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/848d4492508689f5c4a224079dca8809e872e33b8f2635c9f16da5dc21beed16.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/84941ac387a0d245ea20bd663ff4ee78c5315bedfa058ada0961765aff61acaf.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/859b7bbcf048a4525db0548b8f5afef83bfc4870914767153f44c05e83436ec5.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/87b68b45680a57c796eed9183211b03335a6ad6737372b3ef476c2cf42efa631.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/8cef94308af8d09670e4c99a3b6c3d9280b7a27d386653a3bd7d482b2cdf2b65.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/8e564bce3f352c2186ae09ed7fbca9739c10abc46fd5f6893c68cb47178bd2b4.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/8f89e79d0fb9b04d48c7b5719e1d024161c6a2119835b18dcb193ff51123a9be.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/8fe511ad48656a0b10801100b9100edab1be605a8a182dc5c834d298bf0d9166.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/900bda6562d06fafda54c495e325d57dbb7931813178ee207449c5519d89d537.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/997b1b7d9210bfa77dc71f16a57c6bd66bc7c648686dc2a2666044c95042978a.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/a111bb4c6cec536bcf57dddc744b871ac9f3d094ce459c16243adca19020db77.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/a2208bf899e6c84942eef9fbab569d597f574551afae5864f1953c6a517af068.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/a302ddb2598a72ece53780094b64ad861dc68e6913d8a1ea08f5d141736e2986.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/afcbc671326d0dac14e460662c1f793335877ba53cc965f67c0306833b087e7c.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/b657159e6a28c801a211024f96a7ef60e388ce928a7b41ae3d7555a6f8fd2e3e.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/be6bbc6cd15ba525790075252ba0ed0b28dae5cfbfa118c00dfb9ea1ab95e668.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/c1360e3cbe6b3dc8894bc66c359853854c2e5adeac9c7cd5ba63f5db448be601.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/c7983018dbf8e384ddf73191f526075bd0b29907061ab17642ecdc18ea7b9897.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/cea66f27ca60ea173ee0a2bcd91964dc2638eb5657250fe3aa5bd3e41faf8730.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/d052be571a0f3ab69926951f3a4c9d63f05da2ca6d91e5963dd63e04ecb515de.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/d162a993a60dd682c8c21dd111429d84d8d30413a000cf481cf98d06ca83e706.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/d238c3d3d054911714ebe30dafc99e6ad13925b7a600ba9f8d532d0f515f3f5a.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/d9a98cfe2865a9bb0e94f35c735a570b0625b58f890a6b1f6e14fab2401f0af2.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/dc27ae954b7b8a13a9459d6ca6ef2997f662715ff5f5453ea0da169f141748b8.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/e3ff1fd41cf76668b8e1927c0c2e4056b63a293ebbd300a8f1b1d27d87786271.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/e45b7344d373b3ef4a94f560cf4e17b1eb3b8cd89d1e552fc9be11d6b7b546f0.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/eb14eb898224d5d81d1012bec54f2b79f9377dc60fa1d01e49b4c3e148292d77.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/ed0e0101a3d91a3a615f9e78ef36f7deb8bb0eab0f133241d621925d0b596599.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/f722e3a3b1f0a3d7b9f7d7c66c46d8c87245de5f8eece055daf95c7086f8c267.bin +0 -0
- package/corpus/brasscap-mesa/blobs/bin/f76013aedfd810f136fa689a151024bcb942687ef42ae7edf1fd3513ac4e22c7.bin +0 -0
- package/corpus/brasscap-mesa/blobs/glb/0547e63693282614673b13bade4c08eb772020757b131b7c80f2077873aab70e.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/0cf89e9b1824440d213c8e9e33fb357734b7241b4c7eedaba3df7f8306e05425.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/0e01060e3a507ffff6461c50b5c565c71380a6a67d9760cdd7a09afd3e30b584.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/0ef326c5cf5292cd15b48b851460ee8156f51e0a5b62457c8f1f3c53c41665a3.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/1112ff4a3f69db3b62c6d2d6ae021e7c43ce0ca1feb1d3130376881decb3c6b0.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/11357cb8a0670fdc9a03780dd79a31e0aa7a0537786cbf66491bae1722d6feb3.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/11dbecc73bd343c375bd4b79db8dbda2272e76a6b8426ac29e90f2b1272ccfc2.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/133f639cfa837bc5da7915121c71fd32281660c2aaa0248bd59bde47e7faf8bc.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/16812a090136b6678633aa4db03e4187920ae0aca776ad6da373c600cd341972.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/17e63980d7934cfe1d2823d78652af338fe9f0c2170106cd4506a2c4e7f4716f.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/199224cafc86904bdefec8f01d131d7ca3e076a22b689bfc6a26dd20373cf286.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/1a5c8cf223a2f64715ea5eaf14d97a0131f9ebdef4388dc4823dcfa57817724c.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/1b0ec09ad6718149d7ca514136cee09b04c96425f03af0559fd097112aa0daa5.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/1e5024bbb1284b2ed39bbca2d0ade3acb5be2a2c6ba643291f269b76098c7f79.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/1e7635972e13468ffcbb1608f1d12559b066b4533912be2c35e3db07fd4a679d.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/1f03db3a38a21b8d4d02f8ede30e1303cd8d4c426815326a88f45a268b17a492.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/2624abb7bf45618be40f8c3221445179fca44f7321baff415fdf7ddd5e0afc6f.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/27fc3bad6db6e2b5ade5d242867d882362482ddf19c647edef821afc27d52dc2.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/29959bdb5b04a9180e88ec1ed976bae55424d3dc50985f13c0f85bae11ae79ee.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/308cbce2b1b6360f9a2dc275d0bc28be1966fc3ff5e0a58844405ba867f3f668.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/3674d7be969755aaffa368e57b8d1bb743bc98e766a57948859d54fdc7d2c066.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/3736ca95c9c40b30e21302ae6c89148d8ac09264dfbb7e5764b08c265a73ba3c.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/3bc90e1dc9411d249697e4ec352baa4886f91cacfe4940ac43aed879f60966c9.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/3f519c7c7482307cae908b27602dcb7716e2da4b651eff39c4c37103998d18fa.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/4767636d5554b60c94b447b87b77fc1456a2b9af42bfe08585389d27f306dd5e.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/4a3242773b3a73a73ee746a0cdf30c8d6d904bb4406dfdf9822dcd535d6ae308.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/4c7bf3788cba151442d85c3f76553c2e356edf8566ae8243d0a535c9bcde51d0.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/4f3b9f4c818ed6d375947e9603dd058c539e14ff05aa193fb5054d899dbb82a2.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/4fdf7ee67d12de1cd30c3c2bbd9409032dcab5feb3a7d3977b92c50b1d161afe.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/5821f33aa00e9acd2f4c0a29129978ee7006a879d163ce1463ae476031bfabcf.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/5a986c3e44fc686a2efe7648c3945bb7b51cf303918381383f21f898dd312cad.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/5c32fc1de6d198ed606d3e8c3264319acdd950dab18e8b723fc6332bf2f56aea.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/602ce4e8b00a0afbc1a894b65641e48d362ec834a559b9d97a4801473bb01da7.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/6180f9f96167522d8cab4de1d52598cecee8d7ee042f48e41669c98cf61c19c3.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/6205973ba63f7a554662ba05010d25131bed2d9656de422e2067ca54709d5b3c.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/693e556f2165232e8a38b1b2d68676f235ece5705c564992cfa7731426f4d376.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/6a46175438bec5527c281b577bd220b6badedf3c74266b997d39e596f83b8853.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/6ca1bcad7ea053a259b7f9fc5a7ec388a4cd29d44391d93386ea8b1143d94c21.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/6f9bc99656b611890d6acc76ee416f6222ca2d5f62167840b4216a21e020a4c8.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/6fb1e7857996662233ab5314fc13f8aa30703f91c04542e352ec17f9dc4fc054.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/7028ec39712143a7e9d09d2e1477282b654d0470102ca9d272ac82b23604cb21.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/73af65ac86efa61099178f3e7075dcd26d389ee9b9aa3546c18dede10c3dfda1.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/73b992b71bd3165ff7701ab1430c075cb5ba9b74e6363d24640377b1011ddc93.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/7471261d4df59979ba41a622d93779b66ebecd50353ad433862e603ee65f8748.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/76e9a3fcca962c2f900cf79dc1a0851840bd405dc11231f629f784adbcb69d23.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/79d2d29e8cd8b642386b5f31429b39bc4d6f13e53107dda00ebc463abf80c79d.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/7de66fcfffe4ff108510cbe6bebec44e28ab4b78e98e9c1a38466db5b81881f7.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/811fa798cb81ea99488db98e3d3ddea815aac8f6e7493ad04d0176f603978678.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/89b277f1636be220ff5658ff1f1c62efe14079d6e1f42efb373fbf0246801533.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/905c5fe666d9f6174e987382e47d3f325c5696cf8792d7a4a1dd120a438b8270.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/90efe3e05370ee853c0130b98ee82f00b86f7c7104e96b094715187fa49ac16f.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/968a7c5cb13014bce00a29d43b344bd6943ff00ae2908abbc6b40a994f1172a1.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/9a955b4e69dfa5b38f071099053c1a3684cf85ec2d346420de2853c61768f8cc.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/9da2781216a2e482dd8a6ada5ebb43bcf48e0169430e787ac277559cb2ade19a.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/9db02aab14a3b52463deadefbf4ba771809941e7fcb137c905955bdc80ec23bd.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/a3fe1788cf5d7f260249c722f0e0695a4d55744d1b14be44122377147a296256.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/a5c75af8f090d3c95fa46d2be49be5031138d7cd1bae234ae028edf717bf299e.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/a771abd40bd337a464c1bd19f841b62e290124faa89b19ec50e85ab36bc740a5.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/a94a2ad2ed463a47cdda117df25b06b3cf6be37ddac08594bc5f5d76c7237730.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/ad434e4a6490e495994b25f7574a5847a9f7d9c2ca5a2b229a9dfdd2e5e2bb72.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/aeae7b05404b852008a7897689e58aacef44a2c3bc0e87d2519ecdb4cb1e3ff5.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/b0c0c8a4985f92be3b358a8e703c67957427501882aeee05b4ccd3c7880930d4.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/b25174c3cd13eea6e1d9c3104ee5197dc6330129b2f0f7676e8a429900999d9b.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/b3eecdec571df96338edf690443394ff859383b4c94f4cf33d42c240006f8543.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/b7aa0c61ff9e7411535c7b7b8e587849a92bad00d431171ab16ad47d55db0a53.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/b9deef944c22331bc05220d1d6e46412e3cb1246ef041a4405d0cbbd90c2d624.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/ba9376e4ac39b809133ab717edb4c88b5219118766db492d7c97534ce119c2ec.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/baf338e9c272158b905fb58a712e29410c657a45be2764f1c6c43ca87fd1db48.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/bd442ac9fbe52b9f2e4ba586670017c3f2d9fedf1cbdec77ef24e9f8b3a183c8.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/c142adcf253be43b66f23ede8cea1e8fcfa256ebf53054a1068ace04745718a6.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/c6d7cbdc4b2ee9d416edf4d736a4f374f08aea98ca395ad371a50a1853744cfc.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/cfb165a7675d15cee2c490b31095a58f73bace50ccc1e0fdf2c8dc4400f1df27.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/d40f2ee59612473e9f687f17a0e203fdb4ba54c7185b05a8d81a433b04f24134.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/d50ce95411156a6b6cf386aefa5ee58db659811813f74be74f323e7c5795056f.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/d6af418bbde39b4fc7d22a61401d416be7a3fc1214ea2d3f42b4549c392d22ca.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/de7222ceeb1f72693dfb7fd1f343798659e03772d77f2b498fd8ebece2d5550a.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/e26975b198127ac3b6b4f5c4bc08ad47d6691398feee777743285391cd36d502.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/ea428490cd5f2672676a2776a598b819b08246871e76de94b7196f9643144986.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/eb96567a266d24be188cb5b08021112f2fad311cbead939d53c5565da11f6265.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/ecf66230bf7b68050c0827c2e4caf3de90e46859d291b794faa0dd3816d9dac6.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/ed8f067763a4a8adb83d80c8324b2a9668f1061f5f5352f21295e6cc5132386f.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/ee507a38772865467736d370791fe73c6aa4d83fe3e7ff4baa156b9cb2894c1c.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/eedc5b62dc6f27d4a089e9f5b282f626129236d3f1689b001e04f8748bf8859c.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/f4119b9c6c23435619682b5d247743459e76584b9b0d6c5cb689d8e156906695.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/f576047267a0bf9bd4bfc47072ea3d11066345b839953546292da678d1cb4722.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/f8cdfb11997d4ccabea88bcdd3924cc8b621b33618b18fe5fbfd286edfc1d87e.glb +0 -0
- package/corpus/brasscap-mesa/blobs/glb/fce95ecc5db24c903bd46f338e366e2715411465a5efac180e2f0f46397e59de.glb +0 -0
- package/corpus/brasscap-mesa/blobs/image/0579557f9344df6f2c4b1225e6252e53ab86d417a4c9b504b5c714a08a388e47.jpg +0 -0
- package/corpus/brasscap-mesa/blobs/image/9e18816a2ec16fbbb1f00f4a39c73ac2cbf6a8cdc17b4c96b1eba4cc9a754dc7.jpg +0 -0
- package/corpus/brasscap-mesa/blobs/image/eb453c71cfb1f9441eb00b32281f98e226e49d9dcf75c231455575fcdc652222.jpg +0 -0
- package/corpus/brasscap-mesa/blobs/json/e0072ed82115c519b891f53a194ea3b28fff7d3826d8ddf23460d6f21b7728d9.json +1 -0
- package/corpus/brasscap-mesa/blobs/json/ffb0e08eaaa7188db1f55931c9b6330937316091cc7463ed2eff6767bbfa33de.json +1 -0
- package/corpus/brasscap-mesa/blobs/wasm/1d6ace79610c4d510b60ad0c52915e42b57797d91f1ef292f60d8a3daec03dd6.wasm +0 -0
- package/corpus/brasscap-mesa/blobs/wasm/24a4d4c1292677b1c984b5c0d3497ae2929528bf511df475f80cc20945bb08ec.wasm +0 -0
- package/corpus/brasscap-mesa/blobs/wasm/b86d8afcc269fb063ebf64768fc3787635b65a7409a571115b07be2e4da39733.wasm +0 -0
- package/corpus/brasscap-mesa/cook.json +1 -0
- package/corpus/brasscap-mesa/mounts/shardfiles/brasscap-mesa/discovery.json +1 -0
- package/corpus/brasscap-mesa/sections/actors/creatures.json +1 -0
- package/corpus/brasscap-mesa/sections/actors/crowds.json +1 -0
- package/corpus/brasscap-mesa/sections/actors/species.json +1 -0
- package/corpus/brasscap-mesa/sections/audio/audio.json +1 -0
- package/corpus/brasscap-mesa/sections/combat/encounters.json +1 -0
- package/corpus/brasscap-mesa/sections/combat/items.json +1 -0
- package/corpus/brasscap-mesa/sections/combat/strikes.json +1 -0
- package/corpus/brasscap-mesa/sections/economy/ledger.json +1 -0
- package/corpus/brasscap-mesa/sections/economy/loot.json +1 -0
- package/corpus/brasscap-mesa/sections/look/look.json +1 -0
- package/corpus/brasscap-mesa/sections/look/materials.json +1 -0
- package/corpus/brasscap-mesa/sections/quests/quests.json +1 -0
- package/corpus/brasscap-mesa/sections/sim/client-scripts.json +1 -0
- package/corpus/brasscap-mesa/sections/sim/hooks.json +1 -0
- package/corpus/brasscap-mesa/sections/sim/plumbing.json +1 -0
- package/corpus/brasscap-mesa/sections/sim/scripts.json +1 -0
- package/corpus/brasscap-mesa/sections/sim/sim.json +1 -0
- package/corpus/brasscap-mesa/sections/state/migrations.json +1 -0
- package/corpus/brasscap-mesa/sections/state/state.json +1 -0
- package/corpus/brasscap-mesa/sections/ui/card.json +1 -0
- package/corpus/brasscap-mesa/sections/ui/compendium.json +1 -0
- package/corpus/brasscap-mesa/sections/ui/level.json +1 -0
- package/corpus/brasscap-mesa/sections/ui/ui.json +1 -0
- package/corpus/brasscap-mesa/sections/world/collision.json +1 -0
- package/corpus/brasscap-mesa/sections/world/days.json +1 -0
- package/corpus/brasscap-mesa/sections/world/edge.json +1 -0
- package/corpus/brasscap-mesa/sections/world/movers.json +1 -0
- package/corpus/brasscap-mesa/sections/world/navigation.json +1 -0
- package/corpus/brasscap-mesa/sections/world/props.json +1 -0
- package/corpus/brasscap-mesa/sections/world/spawn.json +1 -0
- package/corpus/brasscap-mesa/sections/world/terrain.json +1 -0
- package/corpus/brasscap-mesa/sections/world/tiles.json +1 -0
- package/corpus/brasscap-mesa/sections/world/traversal.json +1 -0
- package/corpus/brasscap-mesa/sections/world/water.json +1 -0
- package/corpus/brasscap-mesa/sections/world/weather.json +1 -0
- package/corpus/brasscap-mesa/shard.json +1 -0
- package/corpus/brasscap-mesa/validation.json +1 -0
- package/corpus/handwritten/blobs/bin/027822f6ae9c374ce1ced851f2227cb9acb03077e5cc6b7fecb245c31f021abd.bin +0 -0
- package/corpus/handwritten/blobs/bin/0377ce182bd604bcf4d501f14bf954c434ea64ad856ad9d71c502d1045612703.bin +0 -0
- package/corpus/handwritten/blobs/bin/05ad93d239eeeb5d9afa09b00d90c56098d88e8850e5b5e691fcaa7520dec3cd.bin +0 -0
- package/corpus/handwritten/blobs/bin/0c8980141e6e394ea473df1eb11c347ba617a1a9a4b39b3fa1871b5d15b97d87.bin +0 -0
- package/corpus/handwritten/blobs/bin/14eb11f8d809320e0a68b1edea7837d7a5b4a3da71f1ce4f54068e0afe0b039b.bin +0 -0
- package/corpus/handwritten/blobs/bin/16590066c039ac71e5038a9866a53ccb95e21af13db29cb655b379c4fcfef7bb.bin +0 -0
- package/corpus/handwritten/blobs/bin/1795b5147ad52482445d2414ee22823b947c43a917b6e96fd9ec017f17000912.bin +0 -0
- package/corpus/handwritten/blobs/bin/18f2e24ecc1ed1b1d12ae1c89732a5a1a618ab6e973d4ff0332cf9ecc4e4f4a6.bin +0 -0
- package/corpus/handwritten/blobs/bin/1a18ade01095f1a9ebe75650127861ef27dda0bb17c2b91bde057ec88ef2e98a.bin +0 -0
- package/corpus/handwritten/blobs/bin/1dba017cddb874bc147efb00c55418846ffa344a696f4df702bbabeea55034d0.bin +0 -0
- package/corpus/handwritten/blobs/bin/248c703537e4687ddd2b69a40d1ef3936da718626289d6867ce0a6866f562ba4.bin +0 -0
- package/corpus/handwritten/blobs/bin/2612d9fd4727f8c349f2dbfb7b1650bb7a752d0798a4966ac22cf2b6cdd9fcef.bin +0 -0
- package/corpus/handwritten/blobs/bin/28c54c766e90e3b046a2377b9fa015b0ce45cf3da4420f2b10553251f86c06aa.bin +0 -0
- package/corpus/handwritten/blobs/bin/30866b4807b12579f50218f6525c3db00919fbd43c97921daf47b3244b25dca6.bin +0 -0
- package/corpus/handwritten/blobs/bin/3d14fae85d77406a9b8c59f2e973cdae9587d49108ea92fb460679ca860196b8.bin +0 -0
- package/corpus/handwritten/blobs/bin/3f2201a53c441abcfb52089fe9bbb01f26fac8744099d3fb6668452885c2fa11.bin +0 -0
- package/corpus/handwritten/blobs/bin/42f270a99367fc4cc901518ccaa344ab595e265f113be944510da745c11f69d1.bin +0 -0
- package/corpus/handwritten/blobs/bin/43fd4327fedd51a586684ac611bcad4a8b9d62e51e03967de71fb42c9bf0f6e1.bin +0 -0
- package/corpus/handwritten/blobs/bin/484adda0898a881b6f095dad447f6a619bf0933f65efe940b72f1ab7f3630c22.bin +0 -0
- package/corpus/handwritten/blobs/bin/4a38cd49e8797429ce76265c3d8972195d5b0a02a35fc05fc513eab11240f415.bin +0 -0
- package/corpus/handwritten/blobs/bin/4fe636237bbbd4f836b0816bc61702f4c224d4cb91fbd94f244c731e24a1b945.bin +0 -0
- package/corpus/handwritten/blobs/bin/51b1cff782dc7ebb382bc429ee965023d4cdb52c7b3e37d6ffff5ef55c1c2813.bin +0 -0
- package/corpus/handwritten/blobs/bin/52561f02071ecaa98432fab5e8ece407a8e8f733a01f8eb7c543d1efe02614da.bin +0 -0
- package/corpus/handwritten/blobs/bin/556d6333923afea9641c4738741a41d6a46ae28a508288b9a49a749a344c1398.bin +0 -0
- package/corpus/handwritten/blobs/bin/5caeb97f32c7f31e1029eebdf31131f879f781bb5e3a225206a646710d83fd75.bin +0 -0
- package/corpus/handwritten/blobs/bin/5d1131e42a045083225105b640ff72e02c7f353ee6285545ac264d01bea26b1b.bin +0 -0
- package/corpus/handwritten/blobs/bin/5d80b30eee9f8342a92f6756fd0d84fb9d2d2ce994d222627641e584ad45d2a8.bin +0 -0
- package/corpus/handwritten/blobs/bin/5e0f9f7f2a85abe11a0a61ede853c9b9942b4494c3eb9943785cf6ae221e40e3.bin +0 -0
- package/corpus/handwritten/blobs/bin/5fdc5485343bba8201185c9bae862ad8618498ab5ce63b53514e4e0226fa7bdb.bin +0 -0
- package/corpus/handwritten/blobs/bin/6623dcb0b31c9ca0be342f6dca6b9e607ec3c12ff82068fa6030c142c2df77f7.bin +0 -0
- package/corpus/handwritten/blobs/bin/6887131a04175edbd1989aa95e8749d1703e7f2d0b8464e85f6bad28d6964125.bin +0 -0
- package/corpus/handwritten/blobs/bin/6cf89771d998486cad9049e6f4fc177d742a18ad79fafa4596814ff9d3cf1952.bin +0 -0
- package/corpus/handwritten/blobs/bin/74bbb0fc219e8476cd5550014a357ee18abc981ff3fe787ae3e60d4593705ec5.bin +0 -0
- package/corpus/handwritten/blobs/bin/76784a7f519ac43ce113a0c9365881839b75f66f96aa009fe8d3c8ab539ef283.bin +0 -0
- package/corpus/handwritten/blobs/bin/79a2f693ee2da546bb551f8b641b9c3affd2b8bfb5632ed7f417daba9d900af9.bin +0 -0
- package/corpus/handwritten/blobs/bin/7b593b0f9eefb957fb9d58b316d9836971203038d7c8127284bba44ccb3090bb.bin +0 -0
- package/corpus/handwritten/blobs/bin/7bb8e518ca5606de78972a6c648b57623f8bc12d7e06b4bbf43c60ac419a9bbd.bin +0 -0
- package/corpus/handwritten/blobs/bin/7c6133f3350147257fa501f41269cb77cb11d8ed96d351e873333b079cee524a.bin +0 -0
- package/corpus/handwritten/blobs/bin/7f5acf1893828995256f5b2c54948f80ba21e53de72db26ea72ce2479f5b0682.bin +0 -0
- package/corpus/handwritten/blobs/bin/836516253cf0f3e6e79537609fdbe6331c8c5c974f9ec4d3fbe4a7db48cf123d.bin +0 -0
- package/corpus/handwritten/blobs/bin/89900344f82d5c1474d2a163f8d29903447bac64e9c9775123ef499be70c2380.bin +0 -0
- package/corpus/handwritten/blobs/bin/95d76a9273c3edd98b3643c54e2e7989800bdcaf6f815230ef09f601e760330f.bin +0 -0
- package/corpus/handwritten/blobs/bin/a7b5a5fe053a38c93eed899bde5051cddd80e0a3f3c82b6fd814869097f0944b.bin +0 -0
- package/corpus/handwritten/blobs/bin/b29be84df0bfd1bc97a1464fd5ea068130947bfed3328e167640c81326eb45d7.bin +0 -0
- package/corpus/handwritten/blobs/bin/b6518dc352be03332a256f1cd9d1149da262fe6829e87ba43364f19c687ca7c9.bin +0 -0
- package/corpus/handwritten/blobs/bin/b7edb8095beeb158adb61ae3caa1653773757afbcd8fb2764c94b975a43fe9e2.bin +0 -0
- package/corpus/handwritten/blobs/bin/b86d617ae7fa397df51ff7af87cd89fa113ac19abd3840ea8f3a086d6c82905c.bin +0 -0
- package/corpus/handwritten/blobs/bin/bb860b5c67ee7f2fafd67588822152228d6f6c9de1231123eeafa4844732b18b.bin +0 -0
- package/corpus/handwritten/blobs/bin/bf8c3971bbb224075d488ffa9cfc20e322c61f9ca0c59c356838415f6778014b.bin +0 -0
- package/corpus/handwritten/blobs/bin/c2edd52ee14ebdc9fcc01d38c15d6ab3379df7a20098c260c546551898959cd1.bin +0 -0
- package/corpus/handwritten/blobs/bin/c3de13c551c5b45270143dcbb9fc9a31651f6012355823c0709c2fe6cafda940.bin +0 -0
- package/corpus/handwritten/blobs/bin/c57a8d9da18b1289afd16de00dd1ec75027048b8dcf7dd218da36bc3276ff035.bin +0 -0
- package/corpus/handwritten/blobs/bin/cc2975c9dea4c31b1bf380623a8f44059423004653f9cae4f603d374174323b7.bin +0 -0
- package/corpus/handwritten/blobs/bin/d476abba2e1c63ad3c7527617559173484ee837a5be2744d968466d5527c286b.bin +0 -0
- package/corpus/handwritten/blobs/bin/db242f89115c878cf0c3b976a1647e9cdeb6a1a51813b1dacaf1188715603294.bin +0 -0
- package/corpus/handwritten/blobs/bin/dcc4b9b3bc4ca777d11c494ae5478f17ad7cf2efa18dcba30def872d55355bc3.bin +0 -0
- package/corpus/handwritten/blobs/bin/dd99da483f385327d6b8319d6e2e9000b580280069353718aa0fda2230707e8b.bin +0 -0
- package/corpus/handwritten/blobs/bin/dfc139dba26f1789e16f72602e654636f2d99bcd41e3f10454da74b3a6a64dda.bin +0 -0
- package/corpus/handwritten/blobs/bin/e15ab3cc9f60657321cfe8d9751e086f025734f4e7068271e0baf6066a686f18.bin +0 -0
- package/corpus/handwritten/blobs/bin/e16a83a71213db6f804ce1d53981a2308062752c85c440022d9eeb7605fd37c8.bin +0 -0
- package/corpus/handwritten/blobs/bin/e7355876487f660ac9f25c9d9dfcd66eaf432e1e1669eb89d12ce8267a8d3e86.bin +0 -0
- package/corpus/handwritten/blobs/bin/e81a632e2da0f6a4d801f18aadfe2c6e640401cc1178935a9099ebb8e3af6cc1.bin +0 -0
- package/corpus/handwritten/blobs/bin/f0721c60d0b1046579d8c587fac8482a70822f0b39a85f9acc0cfc31f82b7dd2.bin +0 -0
- package/corpus/handwritten/blobs/bin/f301cf574de6d84030f839098ca44705dca115f9d3e4ee848e0b35fff3deaf77.bin +0 -0
- package/corpus/handwritten/blobs/bin/f7797f295a7570c437bf7020a1ddf208fea2a7aab595333320a6396c1608d360.bin +0 -0
- package/corpus/handwritten/blobs/glb/08de0bb2439ac812adef528b4b073bdb954bbeada972a2f3afb1757bd0540396.glb +0 -0
- package/corpus/handwritten/blobs/glb/153681171c35d2898569324e21ebe734b8418d4122833618a1e64ea326be1e5e.glb +0 -0
- package/corpus/handwritten/blobs/glb/1df5ce0b6cae72ec4cf3c41510681ba70ebb474f9745d536ebd4f03e8fc82de9.glb +0 -0
- package/corpus/handwritten/blobs/glb/262031e2fa710bd8d586eafce1019ca1434a2170e407567741aac1d99fc9c5ab.glb +0 -0
- package/corpus/handwritten/blobs/glb/27466efb180fb5b5074b40e424bd0b8d78f7ff0f5f3663748e014daeeeb5bedd.glb +0 -0
- package/corpus/handwritten/blobs/glb/2d2f6d00a14c89a4efb7f679b371118f564f258797ed8b8b42baf4ae60902ea6.glb +0 -0
- package/corpus/handwritten/blobs/glb/31f327d215ed7ef422e2169172f3869769e9816c9da979616844081e74f2eb09.glb +0 -0
- package/corpus/handwritten/blobs/glb/3bfe0e9ca18077ffee9c284ef40fed9f2fc354f7495612c785a6f980b5966559.glb +0 -0
- package/corpus/handwritten/blobs/glb/3db43042b3eeb1dee7ce9de1cc00322cefc348aa18c37d168b0858e6af6ca7a4.glb +0 -0
- package/corpus/handwritten/blobs/glb/46460a50da44fb8e792b48a646ec9ce025bb309d315dbcf67d2e9598591750de.glb +0 -0
- package/corpus/handwritten/blobs/glb/4902213556fedaf269fba6f0f195e424b2e49973ab45dcb8b69e34d253d9d8ff.glb +0 -0
- package/corpus/handwritten/blobs/glb/4dda463c9cd4bf339e5611871d4ba2fe16fe1487389a88b2888e96bc55e45d93.glb +0 -0
- package/corpus/handwritten/blobs/glb/4ed23469bd2b6b73183564cfc80a1ebcd0ffe2666a90a556752af0ca147fd2f7.glb +0 -0
- package/corpus/handwritten/blobs/glb/4fe74a1bed6b67129885b90cfcae01b5ca82e23e6d40507e280f02fca7fda54f.glb +0 -0
- package/corpus/handwritten/blobs/glb/50521bb3a50cc7199d324a0b25bc167c2e9d69770cb500490428efefc81ce3ea.glb +0 -0
- package/corpus/handwritten/blobs/glb/5ecca36d1e503edc092af0ef42f139cdcad99b8c2008318eb6ad337023d57296.glb +0 -0
- package/corpus/handwritten/blobs/glb/60fc036925852568cdb1b9fb85218dc43a8bf2ed86d3971a221ad942ece203a7.glb +0 -0
- package/corpus/handwritten/blobs/glb/611633cee0e5822b744486e6dff5414ad5b159eaabffe1c0ba0bb68be794bfa1.glb +0 -0
- package/corpus/handwritten/blobs/glb/67c7f983a0bcb9f84425378acac121a53f30795dce3181643bc1b763d0ae80b5.glb +0 -0
- package/corpus/handwritten/blobs/glb/6ecc0d307030943727484b49b1872643479c55ccc92252fca06e9e3cbe98fa90.glb +0 -0
- package/corpus/handwritten/blobs/glb/774b366df4de56cb6f9e3c904f02ec98016ac2ec489dc9e214b09220fca2f8e5.glb +0 -0
- package/corpus/handwritten/blobs/glb/785bae514ffc029e611d602259db7d37cbef589409a0814b9d37175d8b6c0a45.glb +0 -0
- package/corpus/handwritten/blobs/glb/79e79524efb2830e90af3c945c5b36ef07c1a38f2da2958112203a99eac52a16.glb +0 -0
- package/corpus/handwritten/blobs/glb/7bebdcdaf0be30d9f8d21bde72af68c32d825d12dc668f48109223ed7ff71c9f.glb +0 -0
- package/corpus/handwritten/blobs/glb/7d8b5ec9326a11362b3f9fa3409cb59d11b99f549cc304319c63c1ec55cbf5ab.glb +0 -0
- package/corpus/handwritten/blobs/glb/82e886f826315e4bf962363165fadadd3d93f85132c1909095045e0a7ccc0b34.glb +0 -0
- package/corpus/handwritten/blobs/glb/84b4ef190c3994ae7ca1b1f7a936526d1d20ad7deac13f949e3fe6bb7ba139ed.glb +0 -0
- package/corpus/handwritten/blobs/glb/85b7153e943fbe8c659bd6e4b323511dc6f6e2c7a3a1185e7a9a29ea6ddfdfa6.glb +0 -0
- package/corpus/handwritten/blobs/glb/85cf2d2be91cedbaf454ca42ad53c0c17b311088528d274695dbcea490d6c684.glb +0 -0
- package/corpus/handwritten/blobs/glb/8662b4cdc626c61a45e63f71dc866746c083cd0d4644b817a373105f936a7047.glb +0 -0
- package/corpus/handwritten/blobs/glb/8a4d33bfbb17d865e5deb0a0bdf3de67fc2312950a7568ed2635c22fbe4b1ecf.glb +0 -0
- package/corpus/handwritten/blobs/glb/8b11171d41c9027411ca8b87797d9ec70355471bdd3a247c114c49b8b781bbd9.glb +0 -0
- package/corpus/handwritten/blobs/glb/9026e1c4f0250832b69a989e69fe3071e5cad72adfe9c22ce11c409b18bb3357.glb +0 -0
- package/corpus/handwritten/blobs/glb/945b946f17b6393ea040230641c3083678bb6ab42e1d7239aeb9c950d0e7d5bb.glb +0 -0
- package/corpus/handwritten/blobs/glb/9afab455d603f1f8a38074c5a6cbed26d7d7f2cfd8a531820bd165d4b37399ee.glb +0 -0
- package/corpus/handwritten/blobs/glb/a6d702fb1be1095517625bfb2a2383f5f9638775059fd7e0d093d2044651b848.glb +0 -0
- package/corpus/handwritten/blobs/glb/aae479c2f99848998a1b499bbcad815d971349c2442bc363786aef63baad4337.glb +0 -0
- package/corpus/handwritten/blobs/glb/b155bd41f260d5303e293d691b657e0fb9b9c8b2f8aa589a0187061baa033eb7.glb +0 -0
- package/corpus/handwritten/blobs/glb/b1e8b770d99e8ca4396f21fd512f632c587149fc13db69deba388f702a46982f.glb +0 -0
- package/corpus/handwritten/blobs/glb/b382c318a5baac35da59a7b99ebaad6992e30c4bac327e85851ce0b2f89aa58b.glb +0 -0
- package/corpus/handwritten/blobs/glb/ba4478198696802808262af9bbfc224fe37e24e3f8c13de91debc87d3e1a9d41.glb +0 -0
- package/corpus/handwritten/blobs/glb/baf02cd967d1bf3c6a2ae878f4ca4ed34d0c39302ca2b8b6e3560a4e87b5c16f.glb +0 -0
- package/corpus/handwritten/blobs/glb/bc14dd152815ea6ed39458dcf89f2d69173d61d6e2b57be99d31ce2da64ccf67.glb +0 -0
- package/corpus/handwritten/blobs/glb/bc4e4d3bcf7ace855183efec0fbf242d444a32714d8b2fd8a45fa7b539ef2c73.glb +0 -0
- package/corpus/handwritten/blobs/glb/bc53475e2aa2fc9c2c0574b36a449fd57259c462d771e2b360def5c338d37c26.glb +0 -0
- package/corpus/handwritten/blobs/glb/c35d9e50f392c29f2587e3a6eb4f21143ba08e48d76a53b9de62d3b5be46c1a5.glb +0 -0
- package/corpus/handwritten/blobs/glb/c6911e059d3ac6aea75bc0ad3dd8b220704bfbba8ba98b57705e7aa3ecbe0050.glb +0 -0
- package/corpus/handwritten/blobs/glb/c84d88b6ed878490bcf9fa985b5e6a7a683de8ee7808ee4151a3b6a898fbe4f2.glb +0 -0
- package/corpus/handwritten/blobs/glb/c9d5d02ef0e38ac2898d3e6ecbc2ea0a6d2bd04531118550ab54b5e83293d7ec.glb +0 -0
- package/corpus/handwritten/blobs/glb/cd9d04e361e4c3d0aeb82f8682d71114ff8318b8fc4980bccee3c5e5c16afc27.glb +0 -0
- package/corpus/handwritten/blobs/glb/d32499928422a0cd1a32b1afaeacc31d2d84d74876f6805b36218dc04402a921.glb +0 -0
- package/corpus/handwritten/blobs/glb/dc7ea629fcddeba445599d73a5d721f4d5004e056c3c140baa3e6817393c6462.glb +0 -0
- package/corpus/handwritten/blobs/glb/dce79b59c85ca5a7f9fc25e585d253b15558f8f5d8497a76923c9071601de8b1.glb +0 -0
- package/corpus/handwritten/blobs/glb/e7fa1b02bae6c8d19ace0e8db44810beab9a1be9f8172d5816324760267d6d11.glb +0 -0
- package/corpus/handwritten/blobs/glb/eb664feed0fdcc3ac73cecbe737109994fe5dfad8a33997de88598965fa936ba.glb +0 -0
- package/corpus/handwritten/blobs/glb/ec6a771ca852b0b69e55a12df9d347384d01e611c8c6151ea771910f1601605d.glb +0 -0
- package/corpus/handwritten/blobs/glb/ede05013f575b4216d2b4b3f8a14d611ef28756f952f702bb169529c8ab02eff.glb +0 -0
- package/corpus/handwritten/blobs/glb/fec21fa96950340a1a031b31b37407468361ab0a7645c683e0d7773c18591a26.glb +0 -0
- package/corpus/handwritten/blobs/glb/ff21ea082bb00b01006900e7dbbb85220f31f45c144405c840a70872f9e09cb9.glb +0 -0
- package/corpus/handwritten/blobs/image/248fe9601e921305ffb35421414bc5f03e9f1b3dba15bf9b5c3387d8f255da17.png +0 -0
- package/corpus/handwritten/blobs/image/4b47420aff1ded28c9c6cf1eb92d6e2d7b01d057f2654654405445ff8d562e55.webp +0 -0
- package/corpus/handwritten/blobs/image/5dbc818ed0be692e6ba3df87898fd623280a2686eed5a538333e1325764b238d.png +0 -0
- package/corpus/handwritten/blobs/image/d5ae692911bbc2b60b5fdde239b70aad4ce9be0d7665c4a91b438de6077e21e3.jpg +0 -0
- package/corpus/handwritten/blobs/ktx2/df0dd2e8adc1d9479148bb198cb750471df454680cf0c9ffd6dc85d6262ed676.ktx2 +0 -0
- package/corpus/handwritten/blobs/wasm/ecc886d8bbebcf190298ff9162b6bb364f2125606f5bdc8cc220ea28044f96ea.wasm +0 -0
- package/corpus/handwritten/cook.json +1 -0
- package/corpus/handwritten/mounts/shardfiles/blender-template/discovery.json +1 -0
- package/corpus/handwritten/sections/actors/creatures.json +1 -0
- package/corpus/handwritten/sections/actors/crowds.json +1 -0
- package/corpus/handwritten/sections/actors/species.json +1 -0
- package/corpus/handwritten/sections/audio/audio.json +1 -0
- package/corpus/handwritten/sections/client/plan.json +1 -0
- package/corpus/handwritten/sections/combat/encounters.json +1 -0
- package/corpus/handwritten/sections/combat/items.json +1 -0
- package/corpus/handwritten/sections/combat/strikes.json +1 -0
- package/corpus/handwritten/sections/economy/ledger.json +1 -0
- package/corpus/handwritten/sections/economy/loot.json +1 -0
- package/corpus/handwritten/sections/look/look.json +1 -0
- package/corpus/handwritten/sections/look/map.json +1 -0
- package/corpus/handwritten/sections/look/materials.json +1 -0
- package/corpus/handwritten/sections/quests/quests.json +1 -0
- package/corpus/handwritten/sections/sim/client-scripts.json +1 -0
- package/corpus/handwritten/sections/sim/hooks.json +1 -0
- package/corpus/handwritten/sections/sim/plumbing.json +1 -0
- package/corpus/handwritten/sections/sim/sim.json +1 -0
- package/corpus/handwritten/sections/state/migrations.json +1 -0
- package/corpus/handwritten/sections/state/state.json +1 -0
- package/corpus/handwritten/sections/ui/card.json +1 -0
- package/corpus/handwritten/sections/ui/compendium.json +1 -0
- package/corpus/handwritten/sections/ui/level.json +1 -0
- package/corpus/handwritten/sections/ui/ui.json +1 -0
- package/corpus/handwritten/sections/world/collision.json +1 -0
- package/corpus/handwritten/sections/world/days.json +1 -0
- package/corpus/handwritten/sections/world/edge.json +1 -0
- package/corpus/handwritten/sections/world/movers.json +1 -0
- package/corpus/handwritten/sections/world/navigation.json +1 -0
- package/corpus/handwritten/sections/world/props.json +1 -0
- package/corpus/handwritten/sections/world/spawn.json +1 -0
- package/corpus/handwritten/sections/world/terrain.json +1 -0
- package/corpus/handwritten/sections/world/tiles.json +1 -0
- package/corpus/handwritten/sections/world/traversal.json +1 -0
- package/corpus/handwritten/sections/world/water.json +1 -0
- package/corpus/handwritten/sections/world/weather.json +1 -0
- package/corpus/handwritten/shard.json +1 -0
- package/corpus/handwritten/validation.json +1 -0
- package/package.json +504 -2
- package/packages/wire/src/net-command.ts +150 -0
- package/src/cli/bin.mjs +9 -0
- package/src/cli/main.ts +148 -0
- package/src/cli/pack.ts +262 -0
- package/src/cli/validate.ts +210 -0
- package/src/cli/version.ts +13 -0
- package/src/format/aacIndex.ts +160 -0
- package/src/format/accent.ts +35 -0
- package/src/format/achievementCounters.ts +22 -0
- package/src/format/actorMoves.ts +615 -0
- package/src/format/actorProjectionV2.ts +93 -0
- package/src/format/admissionControl.ts +66 -0
- package/src/format/admissionLate.ts +22 -0
- package/src/format/admissionLimits.ts +11 -0
- package/src/format/admissionServer.ts +30 -0
- package/src/format/ambientLife.ts +123 -0
- package/src/format/arenaRoomDocument.ts +114 -0
- package/src/format/arenaScriptRows.ts +107 -0
- package/src/format/arenaView.ts +30 -0
- package/src/format/assetAdmission.ts +279 -0
- package/src/format/audio-measure.ts +184 -0
- package/src/format/audio-mp4.ts +234 -0
- package/src/format/audio-rules.ts +271 -0
- package/src/format/audio-waiver.ts +55 -0
- package/src/format/audio.ts +463 -0
- package/src/format/audioBank.ts +37 -0
- package/src/format/audioProfiles.ts +501 -0
- package/src/format/audioRouting.ts +67 -0
- package/src/format/audioScene.ts +342 -0
- package/src/format/bakedTerrainBytes.ts +35 -0
- package/src/format/bakedTerrainSampling.ts +66 -0
- package/src/format/bakedTiles.ts +407 -0
- package/src/format/binarySource.ts +32 -0
- package/src/format/bodySlots.ts +90 -0
- package/src/format/bossEncounter.ts +354 -0
- package/src/format/bossProfiles.ts +709 -0
- package/src/format/bossSocketRig.ts +92 -0
- package/src/format/bowVariantRows.ts +68 -0
- package/src/format/brains.ts +252 -0
- package/src/format/budget.ts +214 -0
- package/src/format/buildings.ts +496 -0
- package/src/format/builtIndexes.ts +26 -0
- package/src/format/catalogueEconomy.ts +65 -0
- package/src/format/caveInterior.ts +225 -0
- package/src/format/cellBounds.ts +47 -0
- package/src/format/cellField.ts +98 -0
- package/src/format/chapterDirector.ts +193 -0
- package/src/format/clientChannels.ts +450 -0
- package/src/format/clientCues.ts +34 -0
- package/src/format/clientNative.ts +358 -0
- package/src/format/clientOwnership.ts +43 -0
- package/src/format/clientPlan.ts +306 -0
- package/src/format/clientScripts.ts +116 -0
- package/src/format/clientState.ts +273 -0
- package/src/format/clientTrails.ts +56 -0
- package/src/format/collectionDisplay.ts +232 -0
- package/src/format/colourFunction.ts +44 -0
- package/src/format/colourLut.ts +4 -0
- package/src/format/commonsCosts.ts +28 -0
- package/src/format/compendiumRows.ts +151 -0
- package/src/format/compendiumSketches.ts +23 -0
- package/src/format/completion.ts +83 -0
- package/src/format/contentBounds.ts +76 -0
- package/src/format/contentCost.ts +50 -0
- package/src/format/contracts.ts +305 -0
- package/src/format/cook-data.ts +148 -0
- package/src/format/cook-preparation.ts +241 -0
- package/src/format/coverAppearance.ts +53 -0
- package/src/format/creatures.ts +175 -0
- package/src/format/crowdPresentation.ts +87 -0
- package/src/format/crowds.ts +46 -0
- package/src/format/cueDirector.ts +134 -0
- package/src/format/dayCycle.ts +28 -0
- package/src/format/dayLook.ts +44 -0
- package/src/format/decisionBindings.ts +80 -0
- package/src/format/decisionPublication.ts +35 -0
- package/src/format/decisionScripts.ts +327 -0
- package/src/format/declaredQuestPage.ts +101 -0
- package/src/format/deviceMemoryCost.ts +50 -0
- package/src/format/director.ts +52 -0
- package/src/format/directorProduct.ts +27 -0
- package/src/format/directorStages.ts +165 -0
- package/src/format/directorWhen.ts +78 -0
- package/src/format/discoveryValues.ts +416 -0
- package/src/format/easedFields.ts +48 -0
- package/src/format/edgeProfiles.ts +40 -0
- package/src/format/eliteContinuation.ts +110 -0
- package/src/format/eliteEntryRows.ts +351 -0
- package/src/format/eliteFeature.ts +605 -0
- package/src/format/eliteScripts.ts +60 -0
- package/src/format/encounterRows.ts +1030 -0
- package/src/format/encounters.ts +65 -0
- package/src/format/engine-music.ts +42 -0
- package/src/format/entryClearance.ts +86 -0
- package/src/format/entryCoverage.ts +61 -0
- package/src/format/entryGeometry.ts +56 -0
- package/src/format/entryLanding.ts +83 -0
- package/src/format/entryReads.ts +45 -0
- package/src/format/entrywayAssets.ts +33 -0
- package/src/format/entryways.ts +58 -0
- package/src/format/exchange.ts +25 -0
- package/src/format/explorerCatalogue.ts +312 -0
- package/src/format/feature-sides.ts +233 -0
- package/src/format/fieldPresentation.ts +62 -0
- package/src/format/figures.ts +437 -0
- package/src/format/findsCatalogue.ts +67 -0
- package/src/format/fixedDraws.ts +24 -0
- package/src/format/flyers.ts +226 -0
- package/src/format/forestNativeInputs.ts +37 -0
- package/src/format/forestPage.ts +285 -0
- package/src/format/forestWeather.ts +333 -0
- package/src/format/geometryPack.ts +136 -0
- package/src/format/glbBuffers.ts +77 -0
- package/src/format/glbCost.ts +212 -0
- package/src/format/glbImages.ts +95 -0
- package/src/format/glbTriangles.ts +95 -0
- package/src/format/graphArmsRows.ts +200 -0
- package/src/format/grapple.ts +123 -0
- package/src/format/grazers.ts +164 -0
- package/src/format/grid-catalogue.ts +247 -0
- package/src/format/gridReadiness.ts +49 -0
- package/src/format/groupBrains.ts +249 -0
- package/src/format/heldArms.ts +576 -0
- package/src/format/heldEquipment.ts +78 -0
- package/src/format/heldFinishes.ts +415 -0
- package/src/format/heldGear.ts +68 -0
- package/src/format/heldJianDocument.ts +75 -0
- package/src/format/heldMelee.ts +866 -0
- package/src/format/heldView.ts +26 -0
- package/src/format/heldWeaponDocuments.ts +36 -0
- package/src/format/herdShelter.ts +58 -0
- package/src/format/hooks.ts +45 -0
- package/src/format/immutable.ts +59 -0
- package/src/format/inputDeclarations.ts +157 -0
- package/src/format/islandLibrary.ts +51 -0
- package/src/format/items.ts +229 -0
- package/src/format/json.ts +143 -0
- package/src/format/keyedSky.ts +314 -0
- package/src/format/kitFigure.ts +68 -0
- package/src/format/ktx2Cost.ts +47 -0
- package/src/format/ledger.ts +56 -0
- package/src/format/liftApproach.ts +75 -0
- package/src/format/liftRider.ts +10 -0
- package/src/format/lightEmitters.ts +105 -0
- package/src/format/lights.ts +135 -0
- package/src/format/limbCollision.ts +136 -0
- package/src/format/limbPopulation.ts +33 -0
- package/src/format/limbRig.ts +202 -0
- package/src/format/loadout.ts +156 -0
- package/src/format/look-light.ts +153 -0
- package/src/format/lootBag.ts +145 -0
- package/src/format/lootEconomy.ts +235 -0
- package/src/format/materialFamilies.ts +565 -0
- package/src/format/materialGraph.ts +1220 -0
- package/src/format/materials.ts +449 -0
- package/src/format/memoryAdmission.ts +84 -0
- package/src/format/memoryGates.json +7 -0
- package/src/format/meshCollision.ts +56 -0
- package/src/format/meshCollisionAssets.ts +19 -0
- package/src/format/meshCollisionBytes.ts +102 -0
- package/src/format/meshEntryways.ts +54 -0
- package/src/format/meshopt-decoder.wasm +0 -0
- package/src/format/meshopt-module.ts +177 -0
- package/src/format/meshopt-static.mjs +11 -0
- package/src/format/meshopt-wasm.ts +61 -0
- package/src/format/migrations.ts +209 -0
- package/src/format/minimap.ts +1052 -0
- package/src/format/mixedPopulation.ts +222 -0
- package/src/format/modes.ts +304 -0
- package/src/format/mountedSpecimenRows.ts +64 -0
- package/src/format/moverLifecycle.ts +34 -0
- package/src/format/moverMotion.ts +271 -0
- package/src/format/movers.ts +224 -0
- package/src/format/namedJsonContracts.ts +423 -0
- package/src/format/nativeActors.ts +45 -0
- package/src/format/nativeAssembly.ts +141 -0
- package/src/format/nativeGround.ts +37 -0
- package/src/format/nativeGroundAssets.ts +35 -0
- package/src/format/nativeItems.ts +184 -0
- package/src/format/nativePhysics.ts +140 -0
- package/src/format/nativeQuestComposition.ts +398 -0
- package/src/format/nativeRiding.ts +103 -0
- package/src/format/nativeRuntimePlan.ts +89 -0
- package/src/format/navigation.ts +99 -0
- package/src/format/navigationBytes.ts +111 -0
- package/src/format/nearPlaceholder.ts +111 -0
- package/src/format/nearPlaceholderAssets.ts +23 -0
- package/src/format/netCommand.ts +11 -0
- package/src/format/npcs.ts +546 -0
- package/src/format/outputAddress.ts +11 -0
- package/src/format/outputDownload.ts +34 -0
- package/src/format/outputFields.ts +123 -0
- package/src/format/outputIndex.ts +352 -0
- package/src/format/overdraw.ts +41 -0
- package/src/format/pageLife.ts +303 -0
- package/src/format/pagePreparation.ts +60 -0
- package/src/format/paintedLook.ts +55 -0
- package/src/format/paintedResources.ts +158 -0
- package/src/format/panelTemplate.ts +139 -0
- package/src/format/placeholderSource.ts +209 -0
- package/src/format/platformDataSections.ts +146 -0
- package/src/format/platformFileFamilies.ts +299 -0
- package/src/format/plumbing.ts +165 -0
- package/src/format/populationEnvironment.ts +210 -0
- package/src/format/populationKeeper.ts +163 -0
- package/src/format/populationProjection.ts +496 -0
- package/src/format/populationRespawn.ts +48 -0
- package/src/format/populationRoster.ts +158 -0
- package/src/format/portalFloor.ts +56 -0
- package/src/format/portalLink.ts +112 -0
- package/src/format/portalLinkAssets.ts +42 -0
- package/src/format/portalRide.ts +22 -0
- package/src/format/postGraphDocument.ts +36 -0
- package/src/format/postGraphLook.ts +477 -0
- package/src/format/postStack.ts +114 -0
- package/src/format/practiceCourseRows.ts +466 -0
- package/src/format/preflight.ts +155 -0
- package/src/format/presentation.ts +33 -0
- package/src/format/product-audio.ts +76 -0
- package/src/format/product-reads.ts +178 -0
- package/src/format/product-stream-admit.ts +100 -0
- package/src/format/product-stream-assets.ts +493 -0
- package/src/format/product-stream-facts.ts +208 -0
- package/src/format/product-stream-miss.ts +12 -0
- package/src/format/product-stream-node.ts +47 -0
- package/src/format/product-stream-packs.ts +242 -0
- package/src/format/product-stream-rows.ts +202 -0
- package/src/format/product-stream-tar.ts +192 -0
- package/src/format/product-stream.ts +284 -0
- package/src/format/product.ts +358 -0
- package/src/format/productValidation.ts +205 -0
- package/src/format/propMaterials.ts +254 -0
- package/src/format/props.ts +137 -0
- package/src/format/questContinuation.ts +42 -0
- package/src/format/questFigures.ts +227 -0
- package/src/format/questGraph.ts +30 -0
- package/src/format/questHost.ts +314 -0
- package/src/format/questInteractionSource.ts +57 -0
- package/src/format/questInteractions.ts +642 -0
- package/src/format/questPageComposition.ts +92 -0
- package/src/format/questPageFacets.ts +121 -0
- package/src/format/questRuntime.ts +118 -0
- package/src/format/questSteps.ts +182 -0
- package/src/format/questStory.ts +512 -0
- package/src/format/questStoryBindings.ts +43 -0
- package/src/format/questWorld.ts +36 -0
- package/src/format/quests.ts +333 -0
- package/src/format/rainPresentation.ts +131 -0
- package/src/format/rangedPage.ts +117 -0
- package/src/format/receipt-cost.ts +71 -0
- package/src/format/registeredJson.ts +530 -0
- package/src/format/returnProgramDocument.ts +40 -0
- package/src/format/returnProjectionV2.ts +84 -0
- package/src/format/riding.ts +377 -0
- package/src/format/riggedHulls.ts +160 -0
- package/src/format/roamingBossProjection.ts +178 -0
- package/src/format/roamingCombat.ts +22 -0
- package/src/format/ropeDeckSite.ts +148 -0
- package/src/format/rows.ts +86 -0
- package/src/format/runtime.ts +38 -0
- package/src/format/runtimeBinds.ts +49 -0
- package/src/format/runtimeCost.ts +80 -0
- package/src/format/runtimeSpawns.ts +73 -0
- package/src/format/scalarChannel.ts +38 -0
- package/src/format/scaledPost.ts +27 -0
- package/src/format/scaledPostContract.ts +51 -0
- package/src/format/sceneBuffers.ts +122 -0
- package/src/format/sceneDraws.ts +89 -0
- package/src/format/sceneDressing.ts +247 -0
- package/src/format/sceneInstances.ts +192 -0
- package/src/format/sceneMotion.ts +122 -0
- package/src/format/sceneRefs.ts +71 -0
- package/src/format/sceneSources.ts +730 -0
- package/src/format/script-side-grandfather.ts +62 -0
- package/src/format/script-sides.ts +289 -0
- package/src/format/scriptAbi.ts +14 -0
- package/src/format/scriptAbiV1.ts +56 -0
- package/src/format/scriptActionsV2.ts +101 -0
- package/src/format/scriptAdmission.ts +165 -0
- package/src/format/scriptAdmissionV2.ts +126 -0
- package/src/format/scriptContract.ts +170 -0
- package/src/format/scriptFuelV2.ts +124 -0
- package/src/format/scriptGroupBankV2.ts +54 -0
- package/src/format/scriptGroupStepV2.ts +165 -0
- package/src/format/scriptInputStateV2.ts +52 -0
- package/src/format/scriptLimits.ts +5 -0
- package/src/format/scriptMemoryV2.ts +17 -0
- package/src/format/scriptModuleV2.ts +116 -0
- package/src/format/scriptObservationColumnsV2.ts +226 -0
- package/src/format/scriptQueriesV2.ts +164 -0
- package/src/format/scriptQueryStateV2.ts +40 -0
- package/src/format/scriptRngV2.ts +52 -0
- package/src/format/scriptWireV2.ts +106 -0
- package/src/format/scripts.ts +31 -0
- package/src/format/sections.ts +140 -0
- package/src/format/shardSchema.ts +632 -0
- package/src/format/shardSections.ts +383 -0
- package/src/format/sketch.ts +79 -0
- package/src/format/skin-materials.ts +172 -0
- package/src/format/skinAssets.ts +107 -0
- package/src/format/skinData.ts +110 -0
- package/src/format/skinLayers.ts +90 -0
- package/src/format/skins.ts +37 -0
- package/src/format/socketLift.ts +58 -0
- package/src/format/socketLiftAssets.ts +81 -0
- package/src/format/socketRigCreature.ts +66 -0
- package/src/format/sourceResidency.ts +16 -0
- package/src/format/spawnCombat.ts +26 -0
- package/src/format/spawnScriptV2.ts +145 -0
- package/src/format/spawnScripts.ts +229 -0
- package/src/format/spawnTables.ts +46 -0
- package/src/format/spawnView.ts +26 -0
- package/src/format/speciesActorsFile.ts +86 -0
- package/src/format/speciesBookRows.ts +84 -0
- package/src/format/speciesBrain.ts +96 -0
- package/src/format/speciesLooks.ts +1021 -0
- package/src/format/speciesPrograms.ts +97 -0
- package/src/format/speciesScripts.ts +45 -0
- package/src/format/specimenCatalogue.ts +94 -0
- package/src/format/splatTerrain.ts +192 -0
- package/src/format/standalone-catalogue.ts +144 -0
- package/src/format/standaloneControl.ts +44 -0
- package/src/format/state.ts +61 -0
- package/src/format/stateLineage.ts +71 -0
- package/src/format/stealth.ts +106 -0
- package/src/format/stillImage.ts +135 -0
- package/src/format/streamedCover.ts +105 -0
- package/src/format/surfaceLooks.ts +50 -0
- package/src/format/tar-fields.ts +54 -0
- package/src/format/tar-paths.ts +103 -0
- package/src/format/tar-source.ts +13 -0
- package/src/format/tar-write.ts +152 -0
- package/src/format/tar.ts +203 -0
- package/src/format/targets.ts +217 -0
- package/src/format/terrain.ts +241 -0
- package/src/format/terrainTileBytes.ts +104 -0
- package/src/format/tierSelection.ts +195 -0
- package/src/format/toonLighting.ts +32 -0
- package/src/format/toonLook.ts +332 -0
- package/src/format/trail.ts +17 -0
- package/src/format/traversal.ts +13 -0
- package/src/format/treeSetRows.ts +93 -0
- package/src/format/ui.ts +90 -0
- package/src/format/uiStrings.ts +17 -0
- package/src/format/uniformRows.ts +31 -0
- package/src/format/upload-wire.ts +184 -0
- package/src/format/validationReceipt.ts +142 -0
- package/src/format/version.ts +9 -0
- package/src/format/vertexWear.ts +45 -0
- package/src/format/viewProgram.ts +329 -0
- package/src/format/voicePatches.ts +47 -0
- package/src/format/water.ts +247 -0
- package/src/format/waterWaves.ts +7 -0
- package/src/format/waterWorld.ts +34 -0
- package/src/format/weaponProfiles.ts +1315 -0
- package/src/format/weatherBundle.ts +36 -0
- package/src/format/weatherEffects.ts +78 -0
- package/src/format/weatherProgram.ts +422 -0
- package/src/format/wildlifePopulation.ts +210 -0
- package/src/format/wireLimits.ts +9 -0
- package/src/format/worldAssembly.ts +104 -0
- package/src/format/worldEntry.ts +151 -0
- package/src/format/worldPhysics.ts +292 -0
- package/src/format/worldSceneBatch.ts +106 -0
- package/src/format/worldSceneModels.ts +79 -0
- package/src/format/worldScenePages.ts +89 -0
- package/src/format/worldScenePlacement.ts +191 -0
- package/src/format/worldSceneSlabs.ts +43 -0
- package/src/format/worldSceneSurface.ts +113 -0
- package/src/format/worldSceneWeld.ts +702 -0
- package/src/format/worldScenes.ts +184 -0
- package/src/format/worldTargets.ts +111 -0
- package/src/format/worldUpdates.ts +229 -0
- package/src/hook/format-hook.d.mts +2 -0
- package/src/hook/format-hook.mjs +47 -0
- package/README.md +0 -8
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
|
|
3
|
+
const id = v.pipe(v.string(), v.regex(/^[a-z][a-z0-9.:-]*$/u), v.maxLength(128));
|
|
4
|
+
const label = v.pipe(v.string(), v.minLength(1), v.maxLength(128));
|
|
5
|
+
const finite = v.pipe(v.number(), v.finite());
|
|
6
|
+
const coord = v.pipe(finite, v.minValue(-250), v.maxValue(250));
|
|
7
|
+
const point = v.tuple([coord, coord, coord]);
|
|
8
|
+
const positive = v.pipe(finite, v.minValue(0.001), v.maxValue(500));
|
|
9
|
+
const duration = v.pipe(finite, v.minValue(0), v.maxValue(60));
|
|
10
|
+
const phase = v.strictObject({ at: v.pipe(finite, v.minValue(0.001), v.maxValue(1)), name: label, caption: label, speed: v.pipe(finite, v.minValue(0), v.maxValue(15)), stopDistance: v.pipe(finite, v.minValue(0), v.maxValue(50)), turnRate: v.pipe(finite, v.minValue(0), v.maxValue(30)) });
|
|
11
|
+
const encounter = v.pipe(v.strictObject({ id, entity: id, kind: v.picklist(['elite', 'boss']), panel: v.nullable(id), name: label, title: label, retry: label,
|
|
12
|
+
arena: v.strictObject({ at: point, radius: positive }), intro: duration, introShort: duration,
|
|
13
|
+
respawn: v.strictObject({ at: point, yaw: finite }), phases: v.pipe(v.array(phase), v.minLength(1), v.maxLength(16)) }),
|
|
14
|
+
v.check((e) => e.phases[0]?.at === 1 && e.phases.every((p, i) => i === 0 || p.at < (e.phases[i - 1]?.at ?? 0)), 'descending phase thresholds starting at 1'));
|
|
15
|
+
/** Elite/boss phase tables with checkpoints/retry, neutral steering data and declared panel references. */
|
|
16
|
+
export const EncountersSchema: v.GenericSchema<ShardEncountersInput, ShardEncounters> = v.pipe(v.array(encounter), v.maxLength(64), v.check((rows) => new Set(rows.map((e) => e.id)).size === rows.length && new Set(rows.map((e) => e.entity)).size === rows.length, 'unique encounter ids and actors'));
|
|
17
|
+
/** Validated data-only encounter tables. */
|
|
18
|
+
|
|
19
|
+
/** Full-loader references: declared actor spawn and the existing SF7f boss panel (if any). */
|
|
20
|
+
export function encounterRules(rows: ShardEncounters, entities: readonly string[], panels: readonly { id: string; encounter: string }[]): string[] {
|
|
21
|
+
const errors: string[] = [];
|
|
22
|
+
for (const row of rows) {
|
|
23
|
+
if (!entities.includes(row.entity)) errors.push('declared encounter actor');
|
|
24
|
+
if (row.panel !== null && !panels.some((p) => p.id === row.panel && p.encounter === row.id)) errors.push('declared matching boss panel');
|
|
25
|
+
}
|
|
26
|
+
return [...new Set(errors)];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Admitted data contracts, independent of validator implementation metadata. */
|
|
30
|
+
export type ShardEncountersInput = ShardEncounters;
|
|
31
|
+
export type ShardEncounters = ({
|
|
32
|
+
id: string;
|
|
33
|
+
entity: string;
|
|
34
|
+
kind: 'elite' | 'boss';
|
|
35
|
+
panel: (string) | null;
|
|
36
|
+
name: string;
|
|
37
|
+
title: string;
|
|
38
|
+
retry: string;
|
|
39
|
+
arena: {
|
|
40
|
+
at: [
|
|
41
|
+
number,
|
|
42
|
+
number,
|
|
43
|
+
number
|
|
44
|
+
];
|
|
45
|
+
radius: number;
|
|
46
|
+
};
|
|
47
|
+
intro: number;
|
|
48
|
+
introShort: number;
|
|
49
|
+
respawn: {
|
|
50
|
+
at: [
|
|
51
|
+
number,
|
|
52
|
+
number,
|
|
53
|
+
number
|
|
54
|
+
];
|
|
55
|
+
yaw: number;
|
|
56
|
+
};
|
|
57
|
+
phases: ({
|
|
58
|
+
at: number;
|
|
59
|
+
name: string;
|
|
60
|
+
caption: string;
|
|
61
|
+
speed: number;
|
|
62
|
+
stopDistance: number;
|
|
63
|
+
turnRate: number;
|
|
64
|
+
})[];
|
|
65
|
+
})[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** AUDIO AU18 (J304): one music style per shard. The engine ships one style (piano), and its manifest has these slots
|
|
2
|
+
* beside `title`. A score names the engine music it plays by slot, and the engine cook derives the hashed files from
|
|
3
|
+
* these names, so an engine re-encode never needs a new shard revision. */
|
|
4
|
+
const ENGINE_MUSIC_SLOTS: readonly string[] = ['island', 'pine']
|
|
5
|
+
const ENGINE_SLOTS_MESSAGE =
|
|
6
|
+
'a slot played from the engine style (set base, or unset) is title, island or pine (J304)'
|
|
7
|
+
|
|
8
|
+
/** The score rows that name engine music. */
|
|
9
|
+
interface EngineMusicRows {
|
|
10
|
+
readonly slots: readonly string[]
|
|
11
|
+
readonly bootSlots: readonly string[]
|
|
12
|
+
readonly sets: Readonly<Record<string, string>>
|
|
13
|
+
readonly setCatalogue?: unknown
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** The engine slots a score plays: `title` when it boots one, and each slot whose set is `base` (unset means `base`).
|
|
17
|
+
* A set-catalogue score plays only its own `source` beside the title. */
|
|
18
|
+
function engineMusicSlots(music: Readonly<EngineMusicRows>): string[] {
|
|
19
|
+
const base =
|
|
20
|
+
music.setCatalogue === undefined
|
|
21
|
+
? music.slots.filter(
|
|
22
|
+
(slot): boolean => (music.sets[slot] ?? 'base') === 'base',
|
|
23
|
+
)
|
|
24
|
+
: []
|
|
25
|
+
const title = music.bootSlots.includes('title') ? ['title'] : []
|
|
26
|
+
return [...new Set([...title, ...base])]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Every engine slot the score plays is one the engine's style has. */
|
|
30
|
+
function engineSlotsKnown(music: Readonly<EngineMusicRows>): boolean {
|
|
31
|
+
return engineMusicSlots(music).every(
|
|
32
|
+
(slot): boolean => slot === 'title' || ENGINE_MUSIC_SLOTS.includes(slot),
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export {
|
|
37
|
+
ENGINE_MUSIC_SLOTS,
|
|
38
|
+
ENGINE_SLOTS_MESSAGE,
|
|
39
|
+
engineMusicSlots,
|
|
40
|
+
engineSlotsKnown,
|
|
41
|
+
}
|
|
42
|
+
export type { EngineMusicRows }
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { ShardEntryways } from './entryways.ts';
|
|
2
|
+
import type { ShardProps } from './props.ts';
|
|
3
|
+
import type { ShardWater } from './water.ts';
|
|
4
|
+
import { entryFootprints, clipEntryPolygon, obstructsEntry, type EntryVertex, type EntryFootprint } from './entryGeometry.ts';
|
|
5
|
+
import { PropExtent, visitGlbTriangles } from './product.ts';
|
|
6
|
+
import { glbPoint, glbTransform } from './glbTriangles.ts';
|
|
7
|
+
import { WAVES } from './waterWaves.ts';
|
|
8
|
+
|
|
9
|
+
type Box = Extract<ShardProps['colliders'][number]['shapes'][number], { kind: 'box' }>;
|
|
10
|
+
function boxTriangles(box: Box, visit: (triangle: readonly EntryVertex[]) => void): void {
|
|
11
|
+
const q = box.rot ?? { x: 0, y: Math.sin((box.yaw ?? 0) / 2), z: 0, w: Math.cos((box.yaw ?? 0) / 2) };
|
|
12
|
+
const matrix = glbTransform({ translation: [box.x, box.y, box.z], rotation: [q.x, q.y, q.z, q.w] });
|
|
13
|
+
const points = Array.from({ length: 8 }, (_, i) => glbPoint(matrix, { x: (i & 1) === 0 ? -box.hx : box.hx, y: (i & 2) === 0 ? -box.hy : box.hy, z: (i & 4) === 0 ? -box.hz : box.hz }));
|
|
14
|
+
for (const face of [[0, 1, 3, 2], [4, 6, 7, 5], [0, 4, 5, 1], [2, 3, 7, 6], [0, 2, 6, 4], [1, 5, 7, 3]]) {
|
|
15
|
+
const vertices = face.map((i) => { const p = points[i]; if (p === undefined) throw new Error('Missing box vertex'); return p; });
|
|
16
|
+
const a = vertices[0], b = vertices[1], c = vertices[2], d = vertices[3]; if (a === undefined || b === undefined || c === undefined || d === undefined) throw new Error('Missing box face');
|
|
17
|
+
visit([a, b, c]); visit([a, c, d]);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function circleIntersects(x: number, z: number, radius: number, rect: EntryFootprint): boolean {
|
|
21
|
+
return Math.hypot(x - Math.max(rect.minX, Math.min(rect.maxX, x)), z - Math.max(rect.minZ, Math.min(rect.maxZ, z))) < radius;
|
|
22
|
+
}
|
|
23
|
+
function segmentIntersects(a: EntryVertex, b: EntryVertex, radius: number, rect: EntryFootprint): boolean {
|
|
24
|
+
if (clipEntryPolygon([a, b], rect).length > 0) return true;
|
|
25
|
+
if (circleIntersects(a.x, a.z, radius, rect) || circleIntersects(b.x, b.z, radius, rect)) return true;
|
|
26
|
+
const dx = b.x - a.x, dz = b.z - a.z, n = dx * dx + dz * dz;
|
|
27
|
+
return [[rect.minX, rect.minZ], [rect.maxX, rect.minZ], [rect.maxX, rect.maxZ], [rect.minX, rect.maxZ]].some(([x, z]) => {
|
|
28
|
+
if (x === undefined || z === undefined) throw new Error('Missing rectangle corner');
|
|
29
|
+
const t = n === 0 ? 0 : Math.max(0, Math.min(1, ((x - a.x) * dx + (z - a.z) * dz) / n));
|
|
30
|
+
return Math.hypot(x - a.x - t * dx, z - a.z - t * dz) < radius;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** Refuse declared props, potential collision states and water throughout each socket before allocating a world. */
|
|
34
|
+
export function validateEntrywayClearance(source: { entryways: ShardEntryways; props: ShardProps | null; water: ShardWater }, assets: ReadonlyMap<string, Uint8Array>, extents?: Map<string, PropExtent>): void {
|
|
35
|
+
const rectangles = entryFootprints(source.entryways);
|
|
36
|
+
const inspect = (triangle: readonly EntryVertex[]) => {
|
|
37
|
+
if (rectangles.some((rect) => obstructsEntry(triangle, rect))) throw new Error('illegal shard: entryway footprint must be clear of props and colliders above road height');
|
|
38
|
+
};
|
|
39
|
+
if (source.props !== null) {
|
|
40
|
+
const props = source.props;
|
|
41
|
+
// Library models are reusable local assets, not placed objects. All actual tiles, far proxies and panels are placed.
|
|
42
|
+
const hashes = new Set([...props.tiles.map((tile) => tile.file), ...props.panels.map((panel) => panel.file), ...(props.far === null ? [] : [props.far])]);
|
|
43
|
+
for (const hash of hashes) {
|
|
44
|
+
const bytes = assets.get(hash); if (bytes === undefined) throw new Error('Missing entryway prop asset');
|
|
45
|
+
if (extents === undefined) { visitGlbTriangles(bytes, inspect); continue; }
|
|
46
|
+
// CI6: the same visit records the extents validatePropDrawBounds reads (kept only for a completed visit)
|
|
47
|
+
const extent = new PropExtent();
|
|
48
|
+
visitGlbTriangles(bytes, triangle => { inspect(triangle); extent.add(triangle); });
|
|
49
|
+
extents.set(hash, extent);
|
|
50
|
+
}
|
|
51
|
+
// Hidden/inactive panels can become active, so their authored shapes still count.
|
|
52
|
+
for (const row of props.colliders) for (const shape of row.shapes) {
|
|
53
|
+
if (shape.kind === 'box') boxTriangles(shape, inspect);
|
|
54
|
+
else {
|
|
55
|
+
const dx = shape.to.x - shape.from.x, dz = shape.to.z - shape.from.z, run = Math.hypot(dx, dz) / shape.count, rise = (shape.to.y - shape.from.y) / shape.count;
|
|
56
|
+
for (let i = 0; i < shape.count; i++) {
|
|
57
|
+
const f = (i + 0.5) / shape.count, hy = Math.max(0.01, rise * (i + 1) / 2);
|
|
58
|
+
boxTriangles({ kind: 'box', x: shape.from.x + dx * f, y: shape.from.y + hy, z: shape.from.z + dz * f, hx: shape.width / 2, hy, hz: run / 2, yaw: Math.atan2(dx, dz) }, inspect);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
for (const water of source.water) for (const [index, rect] of rectangles.entries()) {
|
|
64
|
+
const entry = source.entryways[index]; if (entry === undefined) throw new Error('Missing water entryway');
|
|
65
|
+
if (water.dryEntries?.includes(entry.edge)) continue;
|
|
66
|
+
const socket = entry.kind === 'socketOverWater' || entry.kind === 'socketLift' || entry.kind === 'portalLink';
|
|
67
|
+
let wet = false;
|
|
68
|
+
// Sum of absolute amplitudes bounds every swell phase; a below-road sea is safe only below that crest.
|
|
69
|
+
if (water.kind === 'sea') wet = socket || water.level + (water.waves ? WAVES.reduce((sum, wave) => sum + Math.abs(wave[2]), 0) : 0) >= 0;
|
|
70
|
+
else if (water.kind === 'pool' && (socket || water.level >= 0)) {
|
|
71
|
+
const shape = water.shape;
|
|
72
|
+
wet = shape.kind === 'circle' ? circleIntersects(shape.x, shape.z, shape.radius, rect)
|
|
73
|
+
: clipEntryPolygon(shape.points.map(([x, z]) => ({ x, y: water.level, z })), rect).length > 0;
|
|
74
|
+
} else if (water.kind === 'stream') {
|
|
75
|
+
for (let i = 1; i < water.points.length; i++) {
|
|
76
|
+
const a = water.points[i - 1], b = water.points[i]; if (a === undefined || b === undefined || (!socket && Math.max(a.level, b.level) < 0)) continue;
|
|
77
|
+
if (socket) { wet ||= segmentIntersects({ x: a.x, y: 0, z: a.z }, { x: b.x, y: 0, z: b.z }, water.width / 2, rect); continue; }
|
|
78
|
+
const t = a.level === b.level ? 0 : Math.max(0, Math.min(1, -a.level / (b.level - a.level)));
|
|
79
|
+
const at = { x: a.x + (b.x - a.x) * t, y: 0, z: a.z + (b.z - a.z) * t };
|
|
80
|
+
const start = a.level < 0 ? at : { x: a.x, y: a.level, z: a.z }, end = b.level < 0 ? at : { x: b.x, y: b.level, z: b.z };
|
|
81
|
+
wet ||= segmentIntersects(start, end, water.width / 2, rect);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (wet) throw new Error('illegal shard: entryway footprint must be dry');
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { EntryVertex } from './entryGeometry.ts';
|
|
2
|
+
|
|
3
|
+
const cross = (a: EntryVertex, b: EntryVertex, p: EntryVertex): number => (b.x - a.x) * (p.z - a.z) - (b.z - a.z) * (p.x - a.x);
|
|
4
|
+
function area(vertices: readonly EntryVertex[]): number {
|
|
5
|
+
let value = 0;
|
|
6
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
7
|
+
const a = vertices[i], b = vertices[(i + 1) % vertices.length];
|
|
8
|
+
if (a !== undefined && b !== undefined) value += a.x * b.z - b.x * a.z;
|
|
9
|
+
}
|
|
10
|
+
return value / 2;
|
|
11
|
+
}
|
|
12
|
+
function clip(vertices: readonly EntryVertex[], a: EntryVertex, b: EntryVertex, inside: boolean): EntryVertex[] {
|
|
13
|
+
const result: EntryVertex[] = [], direction = inside ? 1 : -1;
|
|
14
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
15
|
+
const p = vertices[i], q = vertices[(i + 1) % vertices.length]; if (p === undefined || q === undefined) continue;
|
|
16
|
+
const dp = cross(a, b, p) * direction, dq = cross(a, b, q) * direction;
|
|
17
|
+
if (dp >= 0) result.push(p);
|
|
18
|
+
if ((dp < 0) !== (dq < 0)) { const t = dp / (dp - dq); result.push({ x: p.x + (q.x - p.x) * t, y: 0, z: p.z + (q.z - p.z) * t }); }
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
/** Canonical counter-clockwise hull in the footprint plane; vertical and line intersections have no area. */
|
|
23
|
+
export function convexEntryHull(vertices: readonly EntryVertex[]): EntryVertex[] {
|
|
24
|
+
const sorted = [...vertices].sort((a, b) => a.x - b.x || a.z - b.z), lower: EntryVertex[] = [], upper: EntryVertex[] = [];
|
|
25
|
+
const add = (part: EntryVertex[], point: EntryVertex): void => {
|
|
26
|
+
while (part.length >= 2) {
|
|
27
|
+
const a = part[part.length - 2], b = part[part.length - 1];
|
|
28
|
+
if (a === undefined || b === undefined || cross(a, b, point) > 0) break;
|
|
29
|
+
part.pop();
|
|
30
|
+
}
|
|
31
|
+
part.push(point);
|
|
32
|
+
};
|
|
33
|
+
for (const point of sorted) add(lower, point);
|
|
34
|
+
for (const point of [...sorted].reverse()) add(upper, point);
|
|
35
|
+
lower.pop(); upper.pop(); return [...lower, ...upper];
|
|
36
|
+
}
|
|
37
|
+
/** Exact convex-polygon subtraction proves area coverage rather than sparse height/raycast samples. */
|
|
38
|
+
export function entryCoverage(surfaces: readonly EntryVertex[][]): (polygon: EntryVertex[], message: string) => void {
|
|
39
|
+
let operations = 0;
|
|
40
|
+
return (polygon, message) => {
|
|
41
|
+
let remaining = [polygon];
|
|
42
|
+
for (const surface of surfaces) {
|
|
43
|
+
if (surface.length < 3 || Math.abs(area(surface)) <= 1e-12) continue;
|
|
44
|
+
const next: EntryVertex[][] = [];
|
|
45
|
+
for (const piece of remaining) {
|
|
46
|
+
if (++operations > 100_000) throw new Error('Entry geometry work bound');
|
|
47
|
+
let inside = piece;
|
|
48
|
+
for (let i = 0; i < surface.length; i++) {
|
|
49
|
+
const a = surface[i], b = surface[(i + 1) % surface.length]; if (a === undefined || b === undefined) continue;
|
|
50
|
+
const outside = clip(inside, a, b, false);
|
|
51
|
+
if (Math.abs(area(outside)) > 1e-12) next.push(outside);
|
|
52
|
+
inside = clip(inside, a, b, true); if (inside.length < 3) break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
remaining = next;
|
|
56
|
+
if (remaining.length === 0) return;
|
|
57
|
+
if (remaining.length > 4096) throw new Error('Entry geometry fragment bound');
|
|
58
|
+
}
|
|
59
|
+
if (remaining.some(piece => Math.abs(area(piece)) > 1e-12)) throw new Error(message);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ENTRY_ASPHALT } from './contentBounds.ts';
|
|
2
|
+
import type { ShardEntryways } from './entryways.ts';
|
|
3
|
+
|
|
4
|
+
/** Shard-local, closed road approach rectangle; its depth comes from the platform contract. */
|
|
5
|
+
export interface EntryFootprint { minX: number; maxX: number; minZ: number; maxZ: number }
|
|
6
|
+
/** A point on an admitted collision or visual triangle, independent of a renderer or physics world. */
|
|
7
|
+
export interface EntryVertex { x: number; y: number; z: number }
|
|
8
|
+
/** The authored ground under the platform socket, with north on positive z. */
|
|
9
|
+
export function entryFootprints(entries: readonly Pick<ShardEntryways[number], 'edge' | 'width'>[]): EntryFootprint[] {
|
|
10
|
+
return entries.map((entry) => {
|
|
11
|
+
const half = entry.width / 2;
|
|
12
|
+
switch (entry.edge) {
|
|
13
|
+
case 'north': return { minX: -half, maxX: half, minZ: 250 - ENTRY_ASPHALT, maxZ: 250 };
|
|
14
|
+
case 'south': return { minX: -half, maxX: half, minZ: -250, maxZ: -250 + ENTRY_ASPHALT };
|
|
15
|
+
case 'east': return { minX: 250 - ENTRY_ASPHALT, maxX: 250, minZ: -half, maxZ: half };
|
|
16
|
+
case 'west': return { minX: -250, maxX: -250 + ENTRY_ASPHALT, minZ: -half, maxZ: half };
|
|
17
|
+
default: throw new Error('Invalid entryway edge');
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/** Clip actual triangles to a footprint, preserving height at every intersection; no sampling gaps. */
|
|
22
|
+
export function clipEntryPolygon(vertices: readonly EntryVertex[], rect: EntryFootprint): EntryVertex[] {
|
|
23
|
+
let polygon = [...vertices];
|
|
24
|
+
for (const [axis, limit, direction] of [['x', rect.minX, 1], ['x', rect.maxX, -1], ['z', rect.minZ, 1], ['z', rect.maxZ, -1]] as const) {
|
|
25
|
+
const input = polygon; polygon = [];
|
|
26
|
+
for (let i = 0; i < input.length; i++) {
|
|
27
|
+
const a = input[i], b = input[(i + 1) % input.length]; if (a === undefined || b === undefined) continue;
|
|
28
|
+
const da = (a[axis] - limit) * direction, db = (b[axis] - limit) * direction;
|
|
29
|
+
if (da >= 0) polygon.push(a);
|
|
30
|
+
if ((da < 0) !== (db < 0)) {
|
|
31
|
+
const t = da / (da - db);
|
|
32
|
+
polygon.push({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t, z: a.z + (b.z - a.z) * t });
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return polygon;
|
|
37
|
+
}
|
|
38
|
+
/** Does any triangle surface rise above the road inside its open clearance rectangle? Touching a side wall is legal. */
|
|
39
|
+
export function obstructsEntry(vertices: readonly EntryVertex[], rect: EntryFootprint): boolean {
|
|
40
|
+
// CI6: a shape wholly past one side of the footprint clips to nothing (no vertex kept, no crossing): the same false
|
|
41
|
+
// without the four clipping passes. Footprints are edge strips, so nearly every prop triangle of a shard takes this exit.
|
|
42
|
+
if (vertices.length > 0) {
|
|
43
|
+
let left = true, right = true, near = true, far = true;
|
|
44
|
+
for (const v of vertices) { if (!(v.x < rect.minX)) left = false; if (!(v.x > rect.maxX)) right = false; if (!(v.z < rect.minZ)) near = false; if (!(v.z > rect.maxZ)) far = false; }
|
|
45
|
+
if (left || right || near || far) return false;
|
|
46
|
+
}
|
|
47
|
+
const clipped = clipEntryPolygon(vertices, rect), above: EntryVertex[] = [];
|
|
48
|
+
for (let i = 0; i < clipped.length; i++) {
|
|
49
|
+
const a = clipped[i], b = clipped[(i + 1) % clipped.length]; if (a === undefined || b === undefined) continue;
|
|
50
|
+
if (a.y >= 0) above.push(a);
|
|
51
|
+
if ((a.y < 0) !== (b.y < 0)) { const t = a.y / (a.y - b.y); above.push({ x: a.x + (b.x - a.x) * t, y: 0, z: a.z + (b.z - a.z) * t }); }
|
|
52
|
+
}
|
|
53
|
+
if (!above.some((point) => point.y > 0)) return false;
|
|
54
|
+
const x = above.reduce((sum, p) => sum + p.x, 0) / above.length, z = above.reduce((sum, p) => sum + p.z, 0) / above.length;
|
|
55
|
+
return x > rect.minX && x < rect.maxX && z > rect.minZ && z < rect.maxZ;
|
|
56
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { decodeTerrainTile } from './terrainTileBytes.ts';
|
|
2
|
+
import type { ShardEntryways } from './entryways.ts';
|
|
3
|
+
import type { ShardProps } from './props.ts';
|
|
4
|
+
import { entryFootprints, clipEntryPolygon, type EntryFootprint, type EntryVertex } from './entryGeometry.ts';
|
|
5
|
+
import { glbPoint, glbTransform } from './glbTriangles.ts';
|
|
6
|
+
import type { ShardMeshCollision } from './meshCollision.ts';
|
|
7
|
+
import { visitMeshTriangles } from './meshEntryways.ts';
|
|
8
|
+
|
|
9
|
+
type Box = Extract<ShardProps['colliders'][number]['shapes'][number], { kind: 'box' }>;
|
|
10
|
+
function boxTop(box: Box): EntryVertex[][] {
|
|
11
|
+
const q = box.rot ?? { x: 0, y: Math.sin((box.yaw ?? 0) / 2), z: 0, w: Math.cos((box.yaw ?? 0) / 2) };
|
|
12
|
+
const matrix = glbTransform({ translation: [box.x, box.y, box.z], rotation: [q.x, q.y, q.z, q.w] });
|
|
13
|
+
const at = (x: number, z: number) => glbPoint(matrix, { x, y: box.hy, z });
|
|
14
|
+
const a = at(-box.hx, -box.hz), b = at(box.hx, -box.hz), c = at(-box.hx, box.hz), d = at(box.hx, box.hz);
|
|
15
|
+
return [[a, b, c], [d, c, b]];
|
|
16
|
+
}
|
|
17
|
+
function farLine(edge: ShardEntryways[number]['edge'], footprint: EntryFootprint): EntryFootprint {
|
|
18
|
+
switch (edge) {
|
|
19
|
+
case 'north': return { ...footprint, maxZ: footprint.minZ };
|
|
20
|
+
case 'south': return { ...footprint, minZ: footprint.maxZ };
|
|
21
|
+
case 'east': return { ...footprint, maxX: footprint.minX };
|
|
22
|
+
case 'west': return { ...footprint, minX: footprint.maxX };
|
|
23
|
+
default: throw new Error('Invalid entryway edge');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Socket floors may bridge below-road ground only when actual collision surfaces meet their entire shard-side edge. */
|
|
28
|
+
export function validateSocketLandings(source: { entryways: ShardEntryways; terrain: { collider: string; form?: 'render' | 'query' } | null; props: ShardProps | null; meshCollision?: ShardMeshCollision | null }, assets: ReadonlyMap<string, Uint8Array>): void {
|
|
29
|
+
const sockets = source.entryways.filter((entry) => entry.kind === 'socketOverWater');
|
|
30
|
+
if (sockets.length === 0) return;
|
|
31
|
+
// Placement queries do not install collision, even when their samples happen to lie at road height.
|
|
32
|
+
const collisionTerrain = source.terrain?.form === 'query' ? null : source.terrain;
|
|
33
|
+
const terrainBytes = collisionTerrain === null ? undefined : assets.get(collisionTerrain.collider);
|
|
34
|
+
if (collisionTerrain !== null && terrainBytes === undefined) throw new Error('Missing socket landing terrain');
|
|
35
|
+
const terrain = terrainBytes === undefined ? undefined : decodeTerrainTile(terrainBytes);
|
|
36
|
+
const decks: EntryVertex[][] = [];
|
|
37
|
+
for (const row of source.props?.colliders ?? []) {
|
|
38
|
+
// Potential future / moving collision states and visible-only GLBs cannot prove a permanent walk surface.
|
|
39
|
+
if (!row.initialActive || row.panel !== null) continue;
|
|
40
|
+
for (const shape of row.shapes) {
|
|
41
|
+
if (shape.kind === 'box') decks.push(...boxTop(shape));
|
|
42
|
+
else {
|
|
43
|
+
const dx = shape.to.x - shape.from.x, dz = shape.to.z - shape.from.z, run = Math.hypot(dx, dz) / shape.count, rise = (shape.to.y - shape.from.y) / shape.count;
|
|
44
|
+
for (let i = 0; i < shape.count; i++) {
|
|
45
|
+
const f = (i + 0.5) / shape.count, hy = Math.max(0.01, rise * (i + 1) / 2);
|
|
46
|
+
decks.push(...boxTop({ kind: 'box', x: shape.from.x + dx * f, y: shape.from.y + hy, z: shape.from.z + dz * f, hx: shape.width / 2, hy, hz: run / 2, yaw: Math.atan2(dx, dz) }));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
for (const entry of sockets) {
|
|
52
|
+
const footprint = entryFootprints([entry])[0]; if (footprint === undefined) throw new Error('Missing socket footprint');
|
|
53
|
+
const line = farLine(entry.edge, footprint), axis = line.minX === line.maxX ? 'z' : 'x', intervals: [number, number][] = [];
|
|
54
|
+
const inspect = (triangle: readonly EntryVertex[]): void => {
|
|
55
|
+
const clipped = clipEntryPolygon(triangle, line);
|
|
56
|
+
if (clipped.length === 0 || clipped.some((point) => point.y !== 0)) return;
|
|
57
|
+
const values = clipped.map((point) => point[axis]); intervals.push([Math.min(...values), Math.max(...values)]);
|
|
58
|
+
};
|
|
59
|
+
for (const triangle of decks) inspect(triangle);
|
|
60
|
+
// Interactive mesh panels may disappear; only permanent static chunks prove a landing.
|
|
61
|
+
for (const row of source.meshCollision?.tiles ?? []) visitMeshTriangles(row.file, assets, inspect);
|
|
62
|
+
if (terrain !== undefined) {
|
|
63
|
+
const n = terrain.resolution - 1, stride = terrain.size / n;
|
|
64
|
+
const vertex = (x: number, z: number): EntryVertex => {
|
|
65
|
+
const y = terrain.heights[z * terrain.resolution + x]; if (y === undefined) throw new Error('Missing landing terrain sample');
|
|
66
|
+
return { x: terrain.x + x * stride, y, z: terrain.z + z * stride };
|
|
67
|
+
};
|
|
68
|
+
const x0 = Math.max(0, Math.floor((line.minX - terrain.x) / stride)), x1 = Math.min(n - 1, Math.floor((line.maxX - terrain.x) / stride));
|
|
69
|
+
const z0 = Math.max(0, Math.floor((line.minZ - terrain.z) / stride)), z1 = Math.min(n - 1, Math.floor((line.maxZ - terrain.z) / stride));
|
|
70
|
+
for (let z = z0; z <= z1; z++) for (let x = x0; x <= x1; x++) {
|
|
71
|
+
const a = vertex(x, z), b = vertex(x + 1, z), c = vertex(x, z + 1), d = vertex(x + 1, z + 1);
|
|
72
|
+
inspect([a, b, c]); inspect([d, c, b]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const min = axis === 'x' ? line.minX : line.minZ, max = axis === 'x' ? line.maxX : line.maxZ;
|
|
76
|
+
let reached = min;
|
|
77
|
+
for (const [start, end] of intervals.sort((a, b) => a[0] - b[0])) {
|
|
78
|
+
if (start > reached) break;
|
|
79
|
+
reached = Math.max(reached, end);
|
|
80
|
+
}
|
|
81
|
+
if (reached < max) throw new Error('illegal shard: socket entryway requires a full-width collision landing at road height y=0');
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { SHARDFILE_ADMISSION_LIMITS } from './admissionLimits.ts';
|
|
3
|
+
|
|
4
|
+
/** A same-product path or immutable public asset URL; no origin, fragment, escaped separator or parent traversal crosses
|
|
5
|
+
* a prefetch boundary. The one query is a build's version token (`?v=<hex>`): the HTTP cache keys a read by its whole URL. */
|
|
6
|
+
export const EntryReadUrlSchema: v.GenericSchema<string> = v.pipe(v.string(), v.minLength(1), v.maxLength(512),
|
|
7
|
+
v.regex(/^(?:\/(?:assets|shardfiles)\/)?[a-zA-Z0-9_-][a-zA-Z0-9_./-]*(?:\?v=[a-f0-9]{6,64})?$/u),
|
|
8
|
+
v.check(url => { const path = url.split('?')[0] ?? ''; return path.split('/').every((part, index) => index === 0 && path.startsWith('/') || part !== '' && part !== '.' && part !== '..'); }, 'Canonical entry read URL'));
|
|
9
|
+
const hash = v.pipe(v.string(), v.regex(/^[a-f0-9]{64}$/u));
|
|
10
|
+
const coordinate = v.pipe(v.number(), v.finite(), v.minValue(-250), v.maxValue(250));
|
|
11
|
+
export interface EntryRead {
|
|
12
|
+
readonly url: string;
|
|
13
|
+
readonly hash: string;
|
|
14
|
+
readonly bytes: number;
|
|
15
|
+
}
|
|
16
|
+
/** First-demand order from one entry crawl. This is read-ahead metadata, never
|
|
17
|
+
* an admission root, a visited marker, a constructor or a readiness claim. */
|
|
18
|
+
export interface RegionEntryReads {
|
|
19
|
+
readonly region: string;
|
|
20
|
+
readonly tier: 'phone' | 'desktop';
|
|
21
|
+
readonly at: readonly [number, number];
|
|
22
|
+
readonly reads: readonly EntryRead[];
|
|
23
|
+
}
|
|
24
|
+
export type EntryReadSet = readonly RegionEntryReads[];
|
|
25
|
+
export const EntryReadSetSchema: v.GenericSchema<EntryReadSet> = v.pipe(v.array(v.strictObject({
|
|
26
|
+
region: v.pipe(v.string(), v.minLength(1), v.maxLength(96), v.regex(/^[a-zA-Z0-9][a-zA-Z0-9_.-]*$/u)),
|
|
27
|
+
tier: v.picklist(['phone', 'desktop']), at: v.tuple([coordinate, coordinate]),
|
|
28
|
+
reads: v.pipe(v.array(v.strictObject({ url: EntryReadUrlSchema, hash,
|
|
29
|
+
bytes: v.pipe(v.number(), v.safeInteger(), v.minValue(0), v.maxValue(SHARDFILE_ADMISSION_LIMITS.wireBytes)) })),
|
|
30
|
+
v.maxLength(8192), v.check(reads => new Set(reads.map(read => read.url)).size === reads.length, 'Entry URLs are unique')),
|
|
31
|
+
})), v.maxLength(128), v.check(rows => new Set(rows.map(row => `${row.region}:${row.tier}`)).size === rows.length, 'Entry tier rows are unique'));
|
|
32
|
+
/** Intrinsic format validation, also used before a build starts its entry walk. */
|
|
33
|
+
export function parseEntryReadSet(input: unknown): EntryReadSet { return v.parse(EntryReadSetSchema, input); }
|
|
34
|
+
|
|
35
|
+
/** Pick the closest declared entry in cell-local coordinates; equal distances
|
|
36
|
+
* keep declaration order and the read order within that entry stays untouched. */
|
|
37
|
+
export function nearestEntryReads(rows: EntryReadSet, tier: RegionEntryReads['tier'], at: { readonly x: number; readonly z: number }): RegionEntryReads | undefined {
|
|
38
|
+
if (!Number.isFinite(at.x) || !Number.isFinite(at.z)) throw new Error('Finite entry approach position required');
|
|
39
|
+
let nearest: RegionEntryReads | undefined, distance = Infinity;
|
|
40
|
+
for (const row of rows) if (row.tier === tier) {
|
|
41
|
+
const next = Math.hypot(row.at[0] - at.x, row.at[1] - at.z);
|
|
42
|
+
if (next < distance) { distance = next; nearest = row; }
|
|
43
|
+
}
|
|
44
|
+
return nearest;
|
|
45
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { decodeTerrainTile } from './terrainTileBytes.ts';
|
|
2
|
+
import { clipEntryPolygon, entryFootprints } from './entryGeometry.ts';
|
|
3
|
+
import type { ShardEntryways } from './entryways.ts';
|
|
4
|
+
|
|
5
|
+
/** Verify every native collision triangle across the full 8×15 m approach before platform floors exist. */
|
|
6
|
+
export function validateEntrywayTerrain(source: { entryways: ShardEntryways; terrain: { collider: string } | null }, assets: ReadonlyMap<string, Uint8Array>): void {
|
|
7
|
+
// The ordinary non-terrain loader supplies its full-cell implicit y=0 ground, independently of entry sockets.
|
|
8
|
+
if (source.terrain === null) return;
|
|
9
|
+
const bytes = assets.get(source.terrain.collider); if (bytes === undefined) throw new Error('Missing entryway terrain');
|
|
10
|
+
const terrain = decodeTerrainTile(bytes);
|
|
11
|
+
validateEntrywayGrid(source.entryways, terrain);
|
|
12
|
+
}
|
|
13
|
+
/** Inspect the original collision lattice, including fractional footprint boundaries; no resampling or socket floor is credited. */
|
|
14
|
+
export function validateEntrywayGrid(entryways: ShardEntryways, terrain: { resolution: number; x: number; z: number; size: number; heights: Float32Array }): void {
|
|
15
|
+
const n = terrain.resolution - 1, stride = terrain.size / n;
|
|
16
|
+
for (const [index, rect] of entryFootprints(entryways).entries()) {
|
|
17
|
+
const kind = entryways[index]?.kind, socket = kind === 'socketOverWater' || kind === 'socketLift' || kind === 'portalLink';
|
|
18
|
+
if (rect.minX < terrain.x || rect.maxX > terrain.x + terrain.size || rect.minZ < terrain.z || rect.maxZ > terrain.z + terrain.size) throw new Error('illegal shard: missing entryway ground footprint');
|
|
19
|
+
const vertex = (x: number, z: number) => {
|
|
20
|
+
const y = terrain.heights[z * terrain.resolution + x]; if (y === undefined) throw new Error('Missing terrain sample');
|
|
21
|
+
return { x: terrain.x + x * stride, y, z: terrain.z + z * stride };
|
|
22
|
+
};
|
|
23
|
+
const x0 = Math.max(0, Math.floor((rect.minX - terrain.x) / stride)), x1 = Math.min(n - 1, Math.floor((rect.maxX - terrain.x) / stride));
|
|
24
|
+
const z0 = Math.max(0, Math.floor((rect.minZ - terrain.z) / stride)), z1 = Math.min(n - 1, Math.floor((rect.maxZ - terrain.z) / stride));
|
|
25
|
+
for (let z = z0; z <= z1; z++) for (let x = x0; x <= x1; x++) {
|
|
26
|
+
const a = vertex(x, z), b = vertex(x + 1, z), c = vertex(x, z + 1), d = vertex(x + 1, z + 1);
|
|
27
|
+
// Same diagonal as the baked Rapier heightfield, including fractional rectangle boundaries.
|
|
28
|
+
for (const triangle of [[a, b, c], [d, c, b]]) if (clipEntryPolygon(triangle, rect).some((p) => socket ? p.y > 0 : p.y !== 0)) throw new Error(socket
|
|
29
|
+
? 'illegal shard: socket entryway terrain cannot rise above road height'
|
|
30
|
+
: 'illegal shard: baked entryway footprint must be flat at road height y=0');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
import { WIRE_CELL } from './wireLimits.ts';
|
|
3
|
+
import { SocketLiftSchema } from './socketLift.ts';
|
|
4
|
+
import { PortalLinkSchema } from './portalLink.ts';
|
|
5
|
+
|
|
6
|
+
const ENTRY_WIDTH: typeof WIRE_CELL.entryWidth = WIRE_CELL.entryWidth;
|
|
7
|
+
const finite = v.pipe(v.number(), v.finite());
|
|
8
|
+
const points = { north: [0, 0, 250], south: [0, 0, -250], east: [250, 0, 0], west: [-250, 0, 0] } as const;
|
|
9
|
+
/** A legal 500 m cube has exactly one opening at each edge midpoint, meeting the highway at y=0. */
|
|
10
|
+
export const EntrywaysSchema: v.GenericSchema<ShardEntrywaysInput, ShardEntryways> = v.pipe(v.array(v.strictObject({ edge: v.picklist(['north', 'east', 'south', 'west']), at: v.tuple([finite, finite, finite]),
|
|
11
|
+
kind: v.optional(v.picklist(['ground', 'socketOverWater', 'socketLift', 'portalLink'])), lift: v.exactOptional(SocketLiftSchema), portal: v.exactOptional(PortalLinkSchema),
|
|
12
|
+
width: v.literal(ENTRY_WIDTH, 'illegal shard: entryways must be 8 metres wide') }), 'illegal shard: four midpoint entryways are required'),
|
|
13
|
+
v.length(4, 'illegal shard: exactly four midpoint entryways are required'),
|
|
14
|
+
v.check((rows) => new Set(rows.map((row) => row.edge)).size === 4 && rows.every((row) => row.at.every((coordinate, axis) => coordinate === points[row.edge][axis])),
|
|
15
|
+
'illegal shard: entryways must be unique edge midpoints at road height y=0'),
|
|
16
|
+
v.check(rows => rows.every(row => (row.kind === 'socketLift') === (row.lift !== undefined)), 'illegal shard: only socketLift entries require a lift declaration'),
|
|
17
|
+
v.check(rows => rows.every(row => (row.kind === 'portalLink') === (row.portal !== undefined)), 'illegal shard: only portalLink entries require a portal declaration'));
|
|
18
|
+
/** Width is the full opening in metres along the boundary; it never overrides authored terrain. */
|
|
19
|
+
|
|
20
|
+
function flatOpening(samples: readonly number[], width: number): boolean {
|
|
21
|
+
const stride = 500 / (samples.length - 1), positions = [-width / 2, width / 2];
|
|
22
|
+
for (let i = 0; i < samples.length; i++) { const position = -250 + i * stride; if (Math.abs(position) <= width / 2) positions.push(position); }
|
|
23
|
+
return positions.every((position) => {
|
|
24
|
+
const at = (position + 250) / stride, index = Math.min(samples.length - 2, Math.floor(at)), fraction = at - index;
|
|
25
|
+
const a = samples[index], b = samples[index + 1]; return a !== undefined && b !== undefined && a + (b - a) * fraction === 0;
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Declared boundary rows must be flat at road height across each opening's full width. */
|
|
29
|
+
export function entrywayRules(source: { entryways: ShardEntryways; edge: Record<ShardEntryways[number]['edge'], { heights: readonly number[]; roadHeight: number }> }): string[] {
|
|
30
|
+
return source.entryways.some((row) => source.edge[row.edge].roadHeight !== 0 || ((row.kind ?? 'ground') === 'ground' && !flatOpening(source.edge[row.edge].heights, row.width)))
|
|
31
|
+
? ['illegal shard: entryway opening must meet road height y=0 across its width'] : [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Admitted data contracts, independent of validator implementation metadata. */
|
|
35
|
+
export type ShardEntrywaysInput = ({
|
|
36
|
+
edge: 'north' | 'east' | 'south' | 'west';
|
|
37
|
+
at: [
|
|
38
|
+
number,
|
|
39
|
+
number,
|
|
40
|
+
number
|
|
41
|
+
];
|
|
42
|
+
kind?: 'ground' | 'socketOverWater' | 'socketLift' | 'portalLink' | undefined;
|
|
43
|
+
lift?: v.InferInput<typeof SocketLiftSchema>;
|
|
44
|
+
portal?: v.InferInput<typeof PortalLinkSchema>;
|
|
45
|
+
width: (typeof ENTRY_WIDTH);
|
|
46
|
+
})[];
|
|
47
|
+
export type ShardEntryways = ({
|
|
48
|
+
edge: 'north' | 'east' | 'south' | 'west';
|
|
49
|
+
at: [
|
|
50
|
+
number,
|
|
51
|
+
number,
|
|
52
|
+
number
|
|
53
|
+
];
|
|
54
|
+
kind?: 'ground' | 'socketOverWater' | 'socketLift' | 'portalLink' | undefined;
|
|
55
|
+
lift?: v.InferOutput<typeof SocketLiftSchema>;
|
|
56
|
+
portal?: v.InferOutput<typeof PortalLinkSchema>;
|
|
57
|
+
width: (typeof ENTRY_WIDTH);
|
|
58
|
+
})[];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as v from 'valibot';
|
|
2
|
+
|
|
3
|
+
const text = v.pipe(v.string(), v.minLength(1), v.maxLength(512));
|
|
4
|
+
const number = v.pipe(v.number(), v.finite(), v.safeInteger(), v.minValue(0));
|
|
5
|
+
const method = v.strictObject({ owner: text, path: v.pipe(v.array(text), v.minLength(1), v.maxLength(16)) });
|
|
6
|
+
const call = v.strictObject({ ...method.entries,
|
|
7
|
+
args: v.pipe(v.array(v.union([text, number, v.boolean()])), v.maxLength(8)),
|
|
8
|
+
required: v.exactOptional(v.boolean()) });
|
|
9
|
+
interface ExchangeMethod { owner:string;path:string[] }
|
|
10
|
+
interface ExchangeCall extends ExchangeMethod { args:(string|number|boolean)[];required?:boolean }
|
|
11
|
+
/** Detached data; no executable affordability or payout policy enters a product. */
|
|
12
|
+
export interface ExchangeRows {
|
|
13
|
+
count:ExchangeMethod;owns:ExchangeMethod;room?:ExchangeMethod;
|
|
14
|
+
goods:{id:string;owns?:string;needs?:string;capacity?:{item:string;n:number};
|
|
15
|
+
costs:{item:string;n:number;text?:string}[];payments:ExchangeCall[];grants:ExchangeCall[]}[];
|
|
16
|
+
}
|
|
17
|
+
/** Bounded exchange decisions and ordered calls into lent inventory, purse and grant owners. */
|
|
18
|
+
export const ExchangeSchema:v.GenericSchema<ExchangeRows> = v.strictObject({
|
|
19
|
+
count: method, owns: method, room: v.exactOptional(method),
|
|
20
|
+
goods: v.pipe(v.array(v.strictObject({ id: text, owns: v.exactOptional(text), needs: v.exactOptional(text),
|
|
21
|
+
capacity: v.exactOptional(v.strictObject({ item: text, n: number })),
|
|
22
|
+
costs: v.pipe(v.array(v.strictObject({ item: text, n: number, text: v.exactOptional(text) })), v.maxLength(3)),
|
|
23
|
+
payments: v.pipe(v.array(call), v.maxLength(3)), grants: v.pipe(v.array(call), v.minLength(1), v.maxLength(3)),
|
|
24
|
+
})), v.minLength(1), v.maxLength(64)),
|
|
25
|
+
});
|