@adatechnology/game-weapons-three 0.1.0 → 0.2.0

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../game-weapons/src/data/calibers.json","../../game-weapons/src/data/weapons.json","../../game-weapons/src/locale.ts","../../game-weapons/src/rng.ts","../../game-weapons/src/weapon.ts","../../game-weapons/src/arsenal.ts","../src/audio.ts","../src/props.ts","../src/fx.ts","../src/area.ts"],"sourcesContent":["/**\n * @adatechnology/game-weapons-three: the three.js side of @adatechnology/game-weapons. Low-poly weapon models, the weapon in the hands with\n * fire and reload motion, ejected casings and dropped magazines, synthesized sounds, and the weapons test area as a `TestableModule`\n * (any host of @adatechnology/game-contracts, like the test room, loads it with `loadModule`).\n */\nexport { createWeaponsTestModule, weaponsLayout, WEAPON_ITEM_PREFIX, COUNTER_ITEM_ID } from './area'\nexport type { WeaponsTestModuleOptions } from './area'\nexport { createWeaponFx } from './fx'\nexport type { WeaponFx, WeaponFxOptions } from './fx'\nexport { createWeaponAudio } from './audio'\nexport type { WeaponAudio } from './audio'\nexport { buildWeaponModel, buildProp, weaponProp, BODY_ACTIONS } from './props'\nexport type { WeaponProp } from './props'\n","[\n {\n \"id\": \"22lr\",\n \"label\": \".22 LR\",\n \"diameter\": 5.7,\n \"bulletGrams\": 2.6,\n \"muzzleSpeed\": 350,\n \"dragPer100m\": 0.15,\n \"kind\": \"rimfire\"\n },\n {\n \"id\": \"9x19\",\n \"label\": \"9×19 mm\",\n \"diameter\": 9,\n \"bulletGrams\": 7.5,\n \"muzzleSpeed\": 365,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"38spl\",\n \"label\": \".38 Special\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 247,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"357mag\",\n \"label\": \".357 Magnum\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 396,\n \"dragPer100m\": 0.18,\n \"kind\": \"hp\"\n },\n {\n \"id\": \"40sw\",\n \"label\": \".40 S&W\",\n \"diameter\": 10.2,\n \"bulletGrams\": 11.7,\n \"muzzleSpeed\": 310,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"45acp\",\n \"label\": \".45 ACP\",\n \"diameter\": 11.5,\n \"bulletGrams\": 14.9,\n \"muzzleSpeed\": 254,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"380acp\",\n \"label\": \".380 ACP\",\n \"diameter\": 9,\n \"bulletGrams\": 6.2,\n \"muzzleSpeed\": 295,\n \"dragPer100m\": 0.22,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"5_56x45\",\n \"label\": \"5.56×45 mm\",\n \"diameter\": 5.7,\n \"bulletGrams\": 4,\n \"muzzleSpeed\": 935,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"7_62x39\",\n \"label\": \"7.62×39 mm\",\n \"diameter\": 7.9,\n \"bulletGrams\": 8,\n \"muzzleSpeed\": 725,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"7_62x51\",\n \"label\": \"7.62×51 mm (.308)\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 850,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"338lapua\",\n \"label\": \".338 Lapua Magnum\",\n \"diameter\": 8.6,\n \"bulletGrams\": 16.2,\n \"muzzleSpeed\": 903,\n \"dragPer100m\": 0.06,\n \"kind\": \"fmj\"\n },\n {\n \"id\": \"50bmg\",\n \"label\": \".50 BMG\",\n \"diameter\": 12.7,\n \"bulletGrams\": 42,\n \"muzzleSpeed\": 925,\n \"dragPer100m\": 0.05,\n \"kind\": \"ap\"\n },\n {\n \"id\": \"12ga_00buck\",\n \"label\": \"12 ga 00 buck\",\n \"diameter\": 8.4,\n \"bulletGrams\": 3.5,\n \"muzzleSpeed\": 414,\n \"pellets\": 9,\n \"dragPer100m\": 0.45,\n \"kind\": \"buck\"\n },\n {\n \"id\": \"12ga_slug\",\n \"label\": \"12 ga slug\",\n \"diameter\": 18.5,\n \"bulletGrams\": 28,\n \"muzzleSpeed\": 463,\n \"dragPer100m\": 0.3,\n \"kind\": \"slug\"\n },\n {\n \"id\": \"12ga_birdshot\",\n \"label\": \"12 ga birdshot\",\n \"diameter\": 2.4,\n \"bulletGrams\": 0.2,\n \"muzzleSpeed\": 400,\n \"pellets\": 90,\n \"dragPer100m\": 0.6,\n \"kind\": \"birdshot\"\n },\n {\n \"id\": \"20ga_buck\",\n \"label\": \"20 ga buck\",\n \"diameter\": 6.9,\n \"bulletGrams\": 1.3,\n \"muzzleSpeed\": 400,\n \"pellets\": 20,\n \"dragPer100m\": 0.5,\n \"kind\": \"buck\"\n },\n {\n \"id\": \"arrow\",\n \"label\": \"Arrow (compound bow)\",\n \"diameter\": 7,\n \"bulletGrams\": 25,\n \"muzzleSpeed\": 90,\n \"dragPer100m\": 0.12,\n \"kind\": \"arrow\"\n },\n {\n \"id\": \"crossbow_bolt\",\n \"label\": \"Crossbow bolt\",\n \"diameter\": 8,\n \"bulletGrams\": 20,\n \"muzzleSpeed\": 122,\n \"dragPer100m\": 0.12,\n \"kind\": \"bolt\"\n }\n]\n","[\n {\n \"id\": \"hand\",\n \"name\": \"Hand\",\n \"category\": \"hand\",\n \"action\": {\n \"kind\": \"hand\",\n \"reach\": 2\n },\n \"mass\": 0,\n \"tags\": [\n \"grab\"\n ]\n },\n {\n \"id\": \"kick\",\n \"name\": \"Kick\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 1.1,\n \"rpm\": 60,\n \"noise\": 8\n },\n \"mass\": 0\n },\n {\n \"id\": \"shove\",\n \"name\": \"Shove\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 80,\n \"radius\": 0.1,\n \"reach\": 1.5,\n \"rpm\": 90,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"pistol_9mm\",\n \"name\": \"9 mm service pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 2,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.2,\n 0.4\n ],\n \"range\": 50,\n \"noise\": 150\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_45\",\n \"name\": \".45 ACP pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 280,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"reload\": 2.2,\n \"barrel\": 1,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.8,\n 0.6\n ],\n \"range\": 50,\n \"noise\": 160\n },\n \"mass\": 1.1,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_22\",\n \"name\": \".22 LR pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 360,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 1.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.5,\n 0.2\n ],\n \"range\": 40,\n \"noise\": 90\n },\n \"mass\": 0.7,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_357\",\n \"name\": \".357 Magnum revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.9\n ],\n \"range\": 60,\n \"noise\": 220\n },\n \"mass\": 1.2,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_38\",\n \"name\": \".38 Special revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"38spl\",\n \"rpm\": 160,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 3.8,\n \"barrel\": 0.95,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.7,\n \"recoveryDegPerS\": 3.5,\n \"recoil\": [\n 1.6,\n 0.5\n ],\n \"range\": 45,\n \"noise\": 170\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"smg_9mm\",\n \"name\": \"9 mm submachine gun\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.4,\n \"barrel\": 1.1,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.9,\n 0.5\n ],\n \"range\": 80,\n \"noise\": 180\n },\n \"mass\": 2.6,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"carbine_22\",\n \"name\": \".22 LR carbine\",\n \"category\": \"carbine\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.2,\n \"barrel\": 1.4,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.4,\n 0.15\n ],\n \"range\": 80,\n \"noise\": 100\n },\n \"mass\": 2.4,\n \"tags\": [\n \"small_game\"\n ]\n },\n {\n \"id\": \"rifle_5_56\",\n \"name\": \"5.56 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"noise\": 300\n },\n \"mass\": 3.4,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_7_62x39\",\n \"name\": \"7.62×39 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.5,\n 0.8\n ],\n \"range\": 350,\n \"noise\": 320\n },\n \"mass\": 3.8,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_bolt_308\",\n \"name\": \".308 bolt-action rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 40,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.5\n ],\n \"range\": 800,\n \"noise\": 350\n },\n \"mass\": 4,\n \"tags\": [\n \"hunting\"\n ]\n },\n {\n \"id\": \"sniper_338\",\n \"name\": \".338 Lapua sniper rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 35,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.5,\n 0.7\n ],\n \"range\": 1500,\n \"noise\": 450\n },\n \"mass\": 6.5,\n \"tags\": [\n \"long_range\"\n ]\n },\n {\n \"id\": \"anti_materiel_50\",\n \"name\": \".50 BMG anti-materiel rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 30,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 4.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 7,\n 1.2\n ],\n \"range\": 1800,\n \"noise\": 600\n },\n \"mass\": 12.5,\n \"tags\": [\n \"long_range\",\n \"heavy\"\n ]\n },\n {\n \"id\": \"shotgun_pump_12\",\n \"name\": \"12 gauge pump-action shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 60,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 6,\n \"reload\": 0.6,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4,\n 1\n ],\n \"range\": 40,\n \"noise\": 400\n },\n \"mass\": 3.2,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_double_12\",\n \"name\": \"12 gauge double-barrel shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"break\"\n ],\n \"magazine\": 2,\n \"reload\": 3.5,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.5,\n 1.2\n ],\n \"range\": 35,\n \"noise\": 400\n },\n \"mass\": 3,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_semi_12\",\n \"name\": \"12 gauge semi-automatic shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.4,\n 1\n ],\n \"range\": 40,\n \"noise\": 400\n },\n \"mass\": 3.4,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"bow_compound\",\n \"name\": \"Compound bow\",\n \"category\": \"bow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"arrow\",\n \"rpm\": 20,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 1.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.4,\n \"bloomDeg\": 0.4,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.3,\n 0.1\n ],\n \"range\": 60,\n \"noise\": 20\n },\n \"mass\": 1.8,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"crossbow\",\n \"name\": \"Crossbow\",\n \"category\": \"crossbow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"crossbow_bolt\",\n \"rpm\": 8,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 4,\n \"barrel\": 1,\n \"spreadDeg\": 0.3,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.5,\n 0.1\n ],\n \"range\": 70,\n \"noise\": 25\n },\n \"mass\": 3,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"hammer\",\n \"name\": \"Hammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 60,\n \"radius\": 0.08,\n \"reach\": 0.7,\n \"rpm\": 70,\n \"noise\": 6\n },\n \"mass\": 1\n },\n {\n \"id\": \"sledgehammer\",\n \"name\": \"Sledgehammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 300,\n \"radius\": 0.15,\n \"reach\": 1.1,\n \"rpm\": 30,\n \"noise\": 8\n },\n \"mass\": 5.5,\n \"tags\": [\n \"heavy\"\n ]\n },\n {\n \"id\": \"baseball_bat\",\n \"name\": \"Baseball bat\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 150,\n \"radius\": 0.1,\n \"reach\": 1,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 0.9\n },\n {\n \"id\": \"crowbar\",\n \"name\": \"Crowbar\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 120,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 2,\n \"tags\": [\n \"pry\"\n ]\n },\n {\n \"id\": \"machete\",\n \"name\": \"Machete\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 140,\n \"radius\": 0.06,\n \"reach\": 0.8,\n \"rpm\": 80,\n \"noise\": 6\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"axe\",\n \"name\": \"Axe\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 45,\n \"noise\": 8\n },\n \"mass\": 1.6\n },\n {\n \"id\": \"knife\",\n \"name\": \"Knife\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 40,\n \"radius\": 0.03,\n \"reach\": 0.4,\n \"rpm\": 100,\n \"noise\": 5\n },\n \"mass\": 0.2\n },\n {\n \"id\": \"fists\",\n \"name\": \"Fists\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 25,\n \"radius\": 0.1,\n \"reach\": 0.6,\n \"rpm\": 120,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"lighter\",\n \"name\": \"Lighter\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 400,\n \"radius\": 0.03,\n \"range\": 0.15,\n \"fuelPerSecond\": 0.02,\n \"fuel\": 60,\n \"noise\": 0\n },\n \"mass\": 0.05,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"flamethrower\",\n \"name\": \"Flamethrower\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 6,\n \"fuelPerSecond\": 1,\n \"fuel\": 20,\n \"cone\": true,\n \"noise\": 20\n },\n \"mass\": 15,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"molotov\",\n \"name\": \"Molotov cocktail\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"energy\": 500,\n \"radius\": 1.5,\n \"fuse\": 0,\n \"throwSpeed\": 12,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.5,\n \"seconds\": 12\n },\n \"noise\": 60\n },\n \"mass\": 0.8,\n \"tags\": [\n \"fire\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"cutting_torch\",\n \"name\": \"Oxy-fuel cutting torch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 3000,\n \"radius\": 0.02,\n \"range\": 0.25,\n \"fuelPerSecond\": 0.05,\n \"fuel\": 30,\n \"noise\": 15\n },\n \"mass\": 4,\n \"tags\": [\n \"fire\",\n \"cutting\"\n ]\n },\n {\n \"id\": \"blowtorch\",\n \"name\": \"Blowtorch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 1300,\n \"radius\": 0.04,\n \"range\": 0.3,\n \"fuelPerSecond\": 0.04,\n \"fuel\": 30,\n \"noise\": 10\n },\n \"mass\": 0.6,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"frag_grenade\",\n \"name\": \"Fragmentation grenade\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"energy\": 200000,\n \"radius\": 6,\n \"fuse\": 4,\n \"throwSpeed\": 15,\n \"noise\": 400\n },\n \"mass\": 0.45,\n \"tags\": [\n \"explosive\"\n ]\n },\n {\n \"id\": \"pipe_bomb\",\n \"name\": \"Pipe bomb\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"energy\": 100000,\n \"radius\": 4,\n \"fuse\": 3,\n \"throwSpeed\": 13,\n \"noise\": 350\n },\n \"mass\": 0.7,\n \"tags\": [\n \"explosive\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"screwdriver\",\n \"name\": \"Screwdriver\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"screwdriver\",\n \"reach\": 0.5,\n \"noise\": 5\n },\n \"mass\": 0.15\n },\n {\n \"id\": \"wrench\",\n \"name\": \"Wrench\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"wrench\",\n \"reach\": 0.6,\n \"noise\": 6\n },\n \"mass\": 0.5\n },\n {\n \"id\": \"pry_bar\",\n \"name\": \"Pry bar\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"pry_bar\",\n \"reach\": 0.8,\n \"noise\": 8\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"hacksaw\",\n \"name\": \"Hacksaw\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"saw\",\n \"reach\": 0.7,\n \"noise\": 10\n },\n \"mass\": 0.6\n },\n {\n \"id\": \"utility_knife\",\n \"name\": \"Utility knife\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"knife\",\n \"reach\": 0.3,\n \"noise\": 3\n },\n \"mass\": 0.1\n },\n {\n \"id\": \"claw_hammer\",\n \"name\": \"Claw hammer\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"hammer\",\n \"reach\": 0.5,\n \"noise\": 8\n },\n \"mass\": 0.7\n },\n {\n \"id\": \"extinguisher\",\n \"name\": \"Fire extinguisher\",\n \"category\": \"extinguisher\",\n \"action\": {\n \"kind\": \"extinguisher\",\n \"range\": 4,\n \"coolC\": 300,\n \"charge\": 12,\n \"noise\": 25\n },\n \"mass\": 5,\n \"tags\": [\n \"safety\"\n ]\n }\n]\n","/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type WeaponsLocale = 'en' | 'pt-BR'\n\nexport interface WeaponsStrings {\n /** Display name of each weapon id. */\n weapons: Record<string, string>\n /** Display name of each fire mode. */\n modes: Record<string, string>\n /** Display name of each weapon category. */\n categories: Record<string, string>\n}\n\nconst modesEn = { single: 'single action', semi: 'semi-automatic', burst: 'burst', auto: 'automatic', pump: 'pump action', bolt: 'bolt action', lever: 'lever action', break: 'break action' }\nconst categoriesEn = {\n pistol: 'pistol', revolver: 'revolver', smg: 'submachine gun', rifle: 'rifle', carbine: 'carbine', sniper: 'sniper rifle', shotgun: 'shotgun',\n bow: 'bow', crossbow: 'crossbow', melee_blunt: 'blunt melee', melee_blade: 'bladed melee', flame: 'flame', heat: 'heat', throwable: 'throwable',\n tool: 'tool', extinguisher: 'extinguisher', hand: 'hand',\n}\n\nexport const locales: Record<WeaponsLocale, WeaponsStrings> = {\n en: {\n weapons: {\n hand: 'Hand', kick: 'Kick', shove: 'Shove', pistol_9mm: '9 mm service pistol', pistol_45: '.45 ACP pistol', pistol_22: '.22 LR pistol', revolver_357: '.357 Magnum revolver',\n revolver_38: '.38 Special revolver', smg_9mm: '9 mm submachine gun', carbine_22: '.22 LR carbine', rifle_5_56: '5.56 mm assault rifle',\n rifle_7_62x39: '7.62×39 mm assault rifle', rifle_bolt_308: '.308 bolt-action rifle', sniper_338: '.338 Lapua sniper rifle',\n anti_materiel_50: '.50 BMG anti-materiel rifle', shotgun_pump_12: '12 gauge pump-action shotgun', shotgun_double_12: '12 gauge double-barrel shotgun',\n shotgun_semi_12: '12 gauge semi-automatic shotgun', bow_compound: 'Compound bow', crossbow: 'Crossbow', hammer: 'Hammer', sledgehammer: 'Sledgehammer',\n baseball_bat: 'Baseball bat', crowbar: 'Crowbar', machete: 'Machete', axe: 'Axe', knife: 'Knife', fists: 'Fists', lighter: 'Lighter',\n flamethrower: 'Flamethrower', molotov: 'Molotov cocktail', cutting_torch: 'Oxy-fuel cutting torch', blowtorch: 'Blowtorch',\n frag_grenade: 'Fragmentation grenade', pipe_bomb: 'Pipe bomb', screwdriver: 'Screwdriver', wrench: 'Wrench', pry_bar: 'Pry bar', hacksaw: 'Hacksaw',\n utility_knife: 'Utility knife', claw_hammer: 'Claw hammer', extinguisher: 'Fire extinguisher',\n },\n modes: modesEn,\n categories: categoriesEn,\n },\n 'pt-BR': {\n weapons: {\n hand: 'mão', kick: 'chute', shove: 'empurrão', pistol_9mm: 'pistola 9 mm', pistol_45: 'pistola .45', pistol_22: 'pistola .22', revolver_357: 'revólver .357', revolver_38: 'revólver .38',\n smg_9mm: 'submetralhadora 9 mm', carbine_22: 'carabina .22', rifle_5_56: 'fuzil 5,56', rifle_7_62x39: 'fuzil 7,62×39', rifle_bolt_308: 'fuzil de ferrolho .308',\n sniper_338: 'fuzil de precisão .338', anti_materiel_50: 'fuzil antimaterial .50', shotgun_pump_12: 'espingarda de repetição calibre 12',\n shotgun_double_12: 'espingarda de dois canos calibre 12', shotgun_semi_12: 'espingarda semiautomática calibre 12', bow_compound: 'arco composto',\n crossbow: 'besta', hammer: 'martelo', sledgehammer: 'marreta', baseball_bat: 'taco de beisebol', crowbar: 'pé de cabra', machete: 'facão', axe: 'machado',\n knife: 'faca', fists: 'punhos', lighter: 'isqueiro', flamethrower: 'lança-chamas', molotov: 'coquetel molotov', cutting_torch: 'maçarico de corte',\n blowtorch: 'maçarico', frag_grenade: 'granada de fragmentação', pipe_bomb: 'bomba caseira', screwdriver: 'chave de fenda', wrench: 'chave inglesa',\n pry_bar: 'alavanca', hacksaw: 'serra de arco', utility_knife: 'estilete', claw_hammer: 'martelo de unha', extinguisher: 'extintor',\n },\n modes: { single: 'tiro único', semi: 'semiautomático', burst: 'rajada', auto: 'automático', pump: 'repetição', bolt: 'ferrolho', lever: 'alavanca', break: 'basculante' },\n categories: {\n pistol: 'pistola', revolver: 'revólver', smg: 'submetralhadora', rifle: 'fuzil', carbine: 'carabina', sniper: 'fuzil de precisão', shotgun: 'espingarda',\n bow: 'arco', crossbow: 'besta', melee_blunt: 'corpo a corpo contundente', melee_blade: 'corpo a corpo cortante', flame: 'chama', heat: 'calor',\n throwable: 'arremessável', tool: 'ferramenta', extinguisher: 'extintor', hand: 'mão',\n },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined): WeaponsStrings => locales[(locale as WeaponsLocale) ?? 'en'] ?? locales.en\n","import type { Vec3 } from './types'\n\n/** Deterministic mulberry32 generator; returns floats in [0, 1). */\nexport const createRng = (seed: number): (() => number) => {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nexport const normalize = (v: Vec3): Vec3 => {\n const l = Math.hypot(v[0], v[1], v[2])\n return l > 1e-12 ? [v[0] / l, v[1] / l, v[2] / l] : [0, 0, -1]\n}\n\nconst cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\n\n/** Uniform direction inside a cone of half-angle `deg` around the unit vector `dir` (uniform over the solid angle). */\nexport const sampleCone = (dir: Vec3, deg: number, rng: () => number): Vec3 => {\n if (deg <= 0) return dir\n const cosMax = Math.cos((deg * Math.PI) / 180)\n const cosT = 1 - rng() * (1 - cosMax)\n const sinT = Math.sqrt(Math.max(0, 1 - cosT * cosT))\n const phi = rng() * Math.PI * 2\n const helper: Vec3 = Math.abs(dir[1]) < 0.9 ? [0, 1, 0] : [1, 0, 0]\n const u = normalize(cross(helper, dir))\n const v = cross(dir, u)\n const cx = Math.cos(phi) * sinT\n const cy = Math.sin(phi) * sinT\n return normalize([\n u[0] * cx + v[0] * cy + dir[0] * cosT,\n u[1] * cx + v[1] * cy + dir[1] * cosT,\n u[2] * cx + v[2] * cy + dir[2] * cosT,\n ])\n}\n","import { createRng, normalize, sampleCone } from './rng'\nimport type {\n CaliberDef,\n FireMode,\n Shot,\n TriggerResult,\n Use,\n Vec3,\n WeaponAction,\n WeaponDef,\n WeaponState,\n} from './types'\n\nconst EPS = 1e-9\nconst DEFAULT_THROWABLES = 3\n/** Total spread (base + bloom) never exceeds this many times the base spread. */\nexport const BLOOM_CAP = 4\n/** Fraction of the throw speed added upwards so a throw arcs. */\nconst THROW_LIFT = 0.15\n\n/** Muzzle energy in joules of ONE projectile (a bullet, or one pellet): 0.5 × mass × speed², speed scaled by the barrel factor. */\nexport const muzzleEnergy = (caliber: CaliberDef, barrel = 1): number => {\n const v = caliber.muzzleSpeed * barrel\n return 0.5 * (caliber.bulletGrams / 1000) * v * v\n}\n\nexport interface WeaponStateInit {\n def: WeaponDef\n caliber: CaliberDef | null\n seed: number\n reserve?: number\n}\n\nconst result = (status: TriggerResult['status'], extra: Partial<TriggerResult> = {}): TriggerResult => ({\n shots: [],\n uses: [],\n status,\n recoil: [0, 0],\n noise: 0,\n ...extra,\n})\n\n/** Runtime of one weapon. See `WeaponState` for the contract. */\nexport class WeaponRuntime implements WeaponState {\n readonly def: WeaponDef\n readonly caliber: CaliberDef | null\n reserve: number\n mode: FireMode\n private _ammo: number\n private readonly _capacity: number\n private readonly action: WeaponAction\n private readonly rng: () => number\n private readonly initialReserve: number\n\n private clock = 0\n /** Time already advanced by the other of update / trigger in the same frame (so calling both does not count `dt` twice). */\n private pend: { src: 'update' | 'trigger'; amt: number } | null = null\n private readyAt = 0\n private latched = false\n\n private _reloading = false\n private reloadEnd = 0\n\n /** Bloom degrees at `extraClock`. */\n private extra = 0\n private extraClock = 0\n\n constructor(init: WeaponStateInit) {\n this.def = init.def\n this.caliber = init.caliber\n this.action = init.def.action\n this.rng = createRng(init.seed)\n const a = this.action\n this.mode = a.kind === 'firearm' ? a.modes[0] ?? 'single' : 'single'\n switch (a.kind) {\n case 'firearm':\n this._capacity = a.magazine\n break\n case 'flame':\n case 'heat':\n this._capacity = a.fuel\n break\n case 'extinguisher':\n this._capacity = a.charge\n break\n case 'throwable':\n this._capacity = a.count ?? DEFAULT_THROWABLES\n break\n default:\n this._capacity = 0\n }\n this._ammo = this._capacity\n this.initialReserve = init.reserve ?? (a.kind === 'firearm' ? a.magazine * 3 : 0)\n this.reserve = this.initialReserve\n }\n\n get ammo(): number {\n return this._ammo\n }\n get capacity(): number {\n return this._capacity\n }\n get reloading(): boolean {\n return this._reloading\n }\n get spread(): number {\n if (this.action.kind !== 'firearm') return 0\n return this.action.spreadDeg + this.extraAt(this.clock)\n }\n\n private extraAt(t: number): number {\n if (this.action.kind !== 'firearm') return 0\n const rec = this.action.recoveryDegPerS ?? 4\n return Math.max(0, this.extra - rec * Math.max(0, t - this.extraClock))\n }\n\n // --- time -----------------------------------------------------------------------------------------------------------------------\n\n update(dt: number): void {\n const d = Math.max(0, dt)\n let eff = d\n if (this.pend && this.pend.src === 'trigger') {\n eff = Math.max(0, d - this.pend.amt)\n this.pend = null\n } else {\n this.pend = { src: 'update', amt: d }\n }\n this.clock += eff\n this.settle(this.clock)\n }\n\n /** Complete the reload steps that finish at or before `t`. */\n private settle(t: number): void {\n const a = this.action\n if (a.kind !== 'firearm') return\n while (this._reloading && this.reloadEnd <= t + EPS) {\n if (a.perRound) {\n if (this.reserve > 0 && this._ammo < this._capacity) {\n this._ammo += 1\n this.reserve -= 1\n }\n if (this._ammo >= this._capacity || this.reserve <= 0) this._reloading = false\n else this.reloadEnd += a.reload\n } else {\n const take = Math.min(this._capacity - this._ammo, this.reserve)\n this._ammo += take\n this.reserve -= take\n this._reloading = false\n }\n }\n }\n\n // --- commands -------------------------------------------------------------------------------------------------------------------\n\n release(): void {\n this.latched = false\n }\n\n reload(): boolean {\n const a = this.action\n if (a.kind === 'throwable') {\n if (this._ammo >= this._capacity || this.reserve <= 0) return false\n this._ammo += 1\n this.reserve -= 1\n return true\n }\n if (a.kind !== 'firearm' || this._reloading) return false\n if (this._ammo >= this._capacity || this.reserve <= 0) return false\n this._reloading = true\n this.reloadEnd = this.clock + a.reload\n return true\n }\n\n cycleMode(): FireMode {\n if (this.action.kind !== 'firearm') return this.mode\n const modes = this.action.modes\n const i = modes.indexOf(this.mode)\n this.mode = modes[(i + 1) % modes.length] ?? this.mode\n return this.mode\n }\n\n refill(): void {\n this._ammo = this._capacity\n this.reserve = this.initialReserve\n this._reloading = false\n this.readyAt = this.clock\n this.latched = false\n this.extra = 0\n }\n\n // --- trigger --------------------------------------------------------------------------------------------------------------------\n\n trigger(origin: Vec3, direction: Vec3, dt: number, held = false, source?: string): TriggerResult {\n const d = Math.max(0, dt)\n let overlap = 0\n if (this.pend && this.pend.src === 'update') {\n overlap = Math.min(this.pend.amt, d)\n this.pend = null\n } else {\n this.pend = { src: 'trigger', amt: d }\n }\n const start = this.clock - overlap\n const end = start + d\n this.settle(start)\n\n const dir = normalize(direction)\n let res: TriggerResult\n const a = this.action\n switch (a.kind) {\n case 'firearm':\n res = this.fireFirearm(a, origin, dir, start, end, held, source)\n break\n case 'melee':\n res = this.fireMelee(a, origin, dir, start, end)\n break\n case 'flame':\n case 'heat':\n res = this.fireFuel(a, origin, dir, d)\n break\n case 'extinguisher':\n res = this.fireExtinguisher(a, origin, dir, d)\n break\n case 'throwable':\n res = this.fireThrowable(a, origin, dir, held)\n break\n case 'tool':\n res = d > 0 ? result('ok', { uses: [{ kind: 'tool', tool: a.tool, reach: a.reach, duration: d, origin, direction: dir }], noise: a.noise }) : result('ok')\n break\n case 'hand':\n res = this.oncePerPull(held)\n ? result('ok', { uses: [{ kind: 'hand', reach: a.reach, origin, direction: dir }] })\n : result('cooldown')\n break\n }\n this.clock = Math.max(this.clock, end)\n this.settle(this.clock)\n return res\n }\n\n /** Semi-style gating: a held trigger that already fired does nothing until `release()` or a new pull (`held` false). */\n private oncePerPull(held: boolean): boolean {\n if (!held) this.latched = false\n if (this.latched) return false\n this.latched = true\n return true\n }\n\n private fireFirearm(a: Extract<WeaponAction, { kind: 'firearm' }>, origin: Vec3, dir: Vec3, start: number, end: number, held: boolean, source?: string): TriggerResult {\n if (this._reloading) {\n if (a.perRound && this._ammo > 0) this._reloading = false // a tube reload is interrupted by the trigger\n else return result('reloading')\n }\n const auto = this.mode === 'auto'\n if (!auto && !this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) return result('empty')\n\n const iv = 60 / a.rpm\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n\n const res = result('ok')\n const fire = (t: number): void => {\n this.fireOne(a, origin, dir, t, res, source)\n }\n if (auto) {\n for (let t = t0, n = 0; this._ammo > 0 && (n === 0 ? t <= end + EPS : t < end - EPS); t += iv, n++) fire(t)\n } else if (this.mode === 'burst') {\n const count = Math.min(a.burst ?? 3, this._ammo)\n for (let k = 0; k < count; k++) fire(t0 + k * iv)\n } else {\n fire(t0)\n }\n return res\n }\n\n private fireOne(a: Extract<WeaponAction, { kind: 'firearm' }>, origin: Vec3, dir: Vec3, t: number, res: TriggerResult, source?: string): void {\n const cal = this.caliber as CaliberDef\n const barrel = a.barrel ?? 1\n const speed = cal.muzzleSpeed * barrel\n const energy = muzzleEnergy(cal, barrel)\n const drag = cal.dragPer100m ?? 0.1\n const energyAt = (distance: number): number => {\n const f = Math.pow(1 - drag, Math.max(0, distance) / 100)\n return energy * f * f\n }\n const bloomNow = this.extraAt(t)\n const spread = a.spreadDeg + bloomNow\n const aim = sampleCone(dir, spread, this.rng)\n const pellets = cal.pellets ?? 1\n const pelletSpread = pellets > 1 ? a.pelletSpreadDeg ?? 3 : 0\n for (let p = 0; p < pellets; p++) {\n const shot: Shot = {\n origin: [origin[0], origin[1], origin[2]],\n direction: sampleCone(aim, pelletSpread, this.rng),\n energy,\n caliber: cal.diameter,\n caliberId: cal.id,\n speed,\n energyAt,\n pellet: p,\n weapon: this.def.id,\n }\n if (source !== undefined) shot.source = source\n res.shots.push(shot)\n }\n this._ammo -= 1\n this.readyAt = t + 60 / a.rpm\n this.extra = Math.min(bloomNow + (a.bloomDeg ?? 0), a.spreadDeg * (BLOOM_CAP - 1))\n this.extraClock = t\n res.recoil = [res.recoil[0] + a.recoil[0], res.recoil[1] + (this.rng() * 2 - 1) * a.recoil[1]]\n res.noise = a.noise\n }\n\n private fireMelee(a: Extract<WeaponAction, { kind: 'melee' }>, origin: Vec3, dir: Vec3, start: number, end: number): TriggerResult {\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n this.readyAt = t0 + 60 / a.rpm\n const use: Use = { kind: 'melee', damage: a.damage, energy: a.energy, radius: a.radius, reach: a.reach, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n private fireFuel(a: Extract<WeaponAction, { kind: 'flame' | 'heat' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const need = a.fuelPerSecond * dt\n let duration = dt\n if (need > this._ammo) {\n duration = dt * (this._ammo / need)\n this._ammo = 0\n } else {\n this._ammo -= need\n }\n const use: Use =\n a.kind === 'flame'\n ? { kind: 'flame', temperature: a.temperature, radius: a.radius, range: a.range, cone: a.cone ?? false, duration, origin, direction: dir }\n : { kind: 'heat', temperature: a.temperature, radius: a.radius, range: a.range, duration, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n private fireExtinguisher(a: Extract<WeaponAction, { kind: 'extinguisher' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const duration = Math.min(dt, this._ammo)\n this._ammo -= duration\n return result('ok', { uses: [{ kind: 'extinguish', range: a.range, coolC: a.coolC, duration, origin, direction: dir }], noise: a.noise })\n }\n\n private fireThrowable(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, held: boolean): TriggerResult {\n if (!this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) return result('empty')\n this._ammo -= 1\n const velocity: Vec3 = [dir[0] * a.throwSpeed, dir[1] * a.throwSpeed + a.throwSpeed * THROW_LIFT, dir[2] * a.throwSpeed]\n const use: Use = { kind: 'throw', energy: a.energy, radius: a.radius, fuse: a.fuse, velocity, origin }\n if (a.fire) use.fire = { ...a.fire }\n return result('ok', { uses: [use], noise: a.noise })\n }\n}\n","import calibersJson from './data/calibers.json'\nimport weaponsJson from './data/weapons.json'\nimport { resolveStrings } from './locale'\nimport type { Arsenal, ArsenalOptions, CaliberDef, CaliberId, WeaponCategory, WeaponDef, WeaponId, WeaponState } from './types'\nimport { muzzleEnergy, WeaponRuntime } from './weapon'\n\nexport const CALIBERS = calibersJson as unknown as CaliberDef[]\nexport const WEAPONS = weaponsJson as unknown as WeaponDef[]\n\n/** A reasonable starting kit for a test room or a sandbox. */\nexport const DEFAULT_LOADOUT: WeaponId[] = [\n 'hand', 'kick', 'shove', 'pistol_9mm', 'revolver_357', 'shotgun_pump_12', 'rifle_5_56', 'rifle_bolt_308', 'hammer', 'axe', 'machete', 'utility_knife', 'crowbar', 'lighter', 'flamethrower',\n 'cutting_torch', 'molotov', 'frag_grenade', 'screwdriver', 'wrench', 'pry_bar', 'hacksaw', 'extinguisher',\n]\n\nexport { muzzleEnergy }\n\n/** Create an arsenal: the built-in calibres and weapons merged (by id) with the ones in `options`. */\nexport const createArsenal = (options: ArsenalOptions = {}): Arsenal => {\n const calibers = new Map<CaliberId, CaliberDef>()\n for (const c of [...CALIBERS, ...(options.calibers ?? [])]) calibers.set(c.id, c)\n const weapons = new Map<WeaponId, WeaponDef>()\n for (const w of [...WEAPONS, ...(options.weapons ?? [])]) weapons.set(w.id, w)\n const strings = resolveStrings(options.locale)\n const baseSeed = options.seed ?? 1\n let counter = 0\n\n const create = (id: WeaponId, opts: { seed?: number; reserve?: number } = {}): WeaponState => {\n const def = weapons.get(id)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${id}\"`)\n let caliber: CaliberDef | null = null\n if (def.action.kind === 'firearm') {\n caliber = calibers.get(def.action.caliber) ?? null\n if (!caliber) throw new Error(`game-weapons: weapon \"${id}\" uses unknown calibre \"${def.action.caliber}\"`)\n }\n counter += 1\n const seed = opts.seed ?? (baseSeed + Math.imul(counter, 0x9e3779b1)) >>> 0\n return new WeaponRuntime({ def, caliber, seed, reserve: opts.reserve })\n }\n\n return {\n calibers,\n weapons,\n create,\n muzzleEnergy(caliber, barrel = 1) {\n const c = calibers.get(caliber)\n if (!c) throw new Error(`game-weapons: unknown calibre \"${caliber}\"`)\n return muzzleEnergy(c, barrel)\n },\n name(id) {\n const w = weapons.get(id)\n if (w) return strings.weapons[id] ?? w.name ?? id\n return strings.modes[id] ?? strings.categories[id] ?? calibers.get(id)?.label ?? id\n },\n list(category?: WeaponCategory) {\n const all = [...weapons.values()]\n return category ? all.filter((w) => w.category === category) : all\n },\n }\n}\n","// Weapon sounds synthesized with WebAudio: no sound files, so the kit stays offline and small. Every call is a no-op where there is no\n// AudioContext (tests, workers), and the context is only created on the first sound, which comes from a click or a key (browsers allow it).\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: louder and longer the more muzzle energy (joules). */\n shot(energyJ: number, category: string): void\n /** Dry click of an empty weapon. */\n click(): void\n /** Magazine out, or the first shell in. */\n reloadStart(category: string): void\n /** Magazine seated and the action racked. */\n reloadEnd(category: string): void\n /** The pump or lever cycling after a shot. */\n cycle(): void\n /** A casing bouncing on the floor. */\n clink(): void\n /** A magazine landing on the floor. */\n thud(): void\n /** Master volume, 0 to 1. */\n setVolume(volume: number): void\n dispose(): void\n}\n\ntype AudioContextCtor = new () => AudioContext\n\nconst NOISE_SECONDS = 0.6\n\nexport function createWeaponAudio(volume = 0.6): WeaponAudio {\n const Ctor = (globalThis as { AudioContext?: AudioContextCtor; webkitAudioContext?: AudioContextCtor }).AudioContext ?? (globalThis as { webkitAudioContext?: AudioContextCtor }).webkitAudioContext\n let ctx: AudioContext | null = null\n let master: GainNode | null = null\n let noise: AudioBuffer | null = null\n let level = volume\n\n const ready = (): AudioContext | null => {\n if (!Ctor) return null\n if (!ctx) {\n ctx = new Ctor()\n master = ctx.createGain()\n master.gain.value = level\n master.connect(ctx.destination)\n noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate)\n const data = noise.getChannelData(0)\n for (let i = 0; i < data.length; i++) data[i] = Math.random() * 2 - 1\n }\n if (ctx.state === 'suspended') void ctx.resume()\n return ctx\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (options: { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + (options.at ?? 0)\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = options.filter\n filter.frequency.value = options.frequency\n filter.Q.value = options.q ?? 0.8\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(options.gain, start + 0.004)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + options.seconds)\n source.connect(filter).connect(gain).connect(master)\n source.start(start)\n source.stop(start + options.seconds + 0.05)\n }\n\n const tone = (options: { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }): void => {\n const audio = ready()\n if (!audio || !master) return\n const start = audio.currentTime + (options.at ?? 0)\n const osc = audio.createOscillator()\n osc.type = options.type ?? 'sine'\n osc.frequency.setValueAtTime(options.frequency, start)\n if (options.to) osc.frequency.exponentialRampToValueAtTime(options.to, start + options.seconds)\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(options.gain, start + 0.003)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + options.seconds)\n osc.connect(gain).connect(master)\n osc.start(start)\n osc.stop(start + options.seconds + 0.05)\n }\n\n const metal = (at: number, frequency: number, gain: number): void => {\n burst({ at, seconds: 0.05, gain, filter: 'highpass', frequency, q: 2 })\n tone({ at, seconds: 0.04, gain: gain * 0.6, frequency: frequency * 0.6, type: 'square' })\n }\n\n return {\n shot(energyJ, category) {\n // 200 J (.22) to 15 000 J (.50 BMG) mapped to 0..1\n const k = Math.min(1, Math.max(0, Math.log10(Math.max(energyJ, 50) / 50) / 2.5))\n const shotgun = category === 'shotgun'\n burst({ seconds: 0.12 + k * 0.35 + (shotgun ? 0.1 : 0), gain: 0.5 + k * 0.5, filter: 'lowpass', frequency: 4200 - k * 2600 })\n burst({ seconds: 0.03, gain: 0.6, filter: 'highpass', frequency: 3000 })\n tone({ seconds: 0.14 + k * 0.2, gain: 0.35 + k * 0.4, frequency: 140 - k * 70, to: 40 })\n },\n click() {\n metal(0, 2600, 0.25)\n },\n reloadStart(category) {\n metal(0, 1500, 0.35)\n if (category !== 'shotgun' && category !== 'revolver') metal(0.12, 900, 0.2)\n },\n reloadEnd(category) {\n metal(0, 1100, 0.45)\n if (category !== 'revolver') metal(0.18, 1900, 0.4)\n },\n cycle() {\n metal(0.22, 900, 0.35)\n metal(0.36, 1300, 0.35)\n },\n clink() {\n const f = 3200 + Math.random() * 2000\n tone({ seconds: 0.09, gain: 0.12, frequency: f })\n tone({ seconds: 0.06, gain: 0.06, frequency: f * 2.7 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n level = Math.max(0, Math.min(1, next))\n if (master) master.gain.value = level\n },\n dispose() {\n void ctx?.close()\n ctx = null\n master = null\n noise = null\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\n\n/** A low-poly prop: its destruction spec (box parts only) and one colour per part. */\nexport interface WeaponProp {\n spec: DestructibleSpec\n colors: Record<string, number>\n}\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind']): JointSpec => ({ a, b, kind })\n\n// A grip and a body lying flat end to end, long axis along +x, the muzzle or head at +x. One thickness for both parts so the prop lies flat,\n// and the parts touch without overlapping: overlapping parts are pushed apart by the physics and the prop slides away.\nconst handled = (name: string, handle: [string, Vec3], head: [string, Vec3]): WeaponProp => {\n const [handleMaterial, rawHandle] = handle\n const [headMaterial, rawHead] = head\n const thickness = Math.max(rawHandle[1], rawHead[1])\n const handleSize: Vec3 = [rawHandle[0], thickness, rawHandle[2]]\n const headSize: Vec3 = [rawHead[0], thickness, rawHead[2]]\n const shift = (handleSize[0] - headSize[0]) / 2\n return {\n spec: {\n name,\n parts: [box('handle', handleMaterial, handleSize, [-handleSize[0] / 2 + shift, thickness / 2, 0]), box('head', headMaterial, headSize, [headSize[0] / 2 + shift, thickness / 2, 0])],\n joints: [joint('handle', 'head', 'screw')],\n tags: ['weapon'],\n },\n colors: { handle: handleMaterial === 'steel' ? 0x3a3d42 : handleMaterial === 'plastic' ? 0x2b2d30 : 0x7a5530, head: headMaterial === 'steel' ? 0x8f969e : headMaterial === 'copper' ? 0xb87333 : 0x6b4a2a },\n }\n}\nconst solid = (name: string, material: string, size: Vec3, color: number): WeaponProp => ({\n spec: { name, parts: [box('body', material, size, [0, size[1] / 2, 0])], joints: [], tags: ['weapon'] },\n colors: { body: color },\n})\n\nconst SHAPES: Record<string, (name: string, id: string) => WeaponProp> = {\n pistol: (n) => handled(n, ['plastic', [0.06, 0.03, 0.11]], ['steel', [0.2, 0.03, 0.04]]),\n revolver: (n) => handled(n, ['wood_soft', [0.06, 0.035, 0.11]], ['steel', [0.24, 0.04, 0.05]]),\n smg: (n) => handled(n, ['plastic', [0.2, 0.05, 0.14]], ['steel', [0.45, 0.05, 0.06]]),\n carbine: (n) => handled(n, ['wood_soft', [0.35, 0.05, 0.12]], ['steel', [0.6, 0.04, 0.05]]),\n rifle: (n) => handled(n, ['wood_soft', [0.35, 0.06, 0.13]], ['steel', [0.75, 0.05, 0.07]]),\n sniper: (n) => handled(n, ['plastic', [0.4, 0.06, 0.14]], ['steel', [0.95, 0.06, 0.08]]),\n shotgun: (n) => handled(n, ['wood_soft', [0.38, 0.06, 0.13]], ['steel', [0.7, 0.05, 0.06]]),\n bow: (n) => solid(n, 'wood_soft', [0.95, 0.03, 0.22], 0x5a3d22),\n crossbow: (n) => handled(n, ['wood_soft', [0.6, 0.06, 0.08]], ['steel', [0.12, 0.04, 0.26]]),\n melee_blunt: (n, id) =>\n id === 'baseball_bat'\n ? solid(n, 'wood_soft', [0.84, 0.06, 0.06], 0xb08550)\n : handled(n, ['wood_soft', [id === 'sledgehammer' ? 0.8 : 0.32, 0.03, 0.03]], ['steel', id === 'sledgehammer' ? [0.08, 0.08, 0.2] : [0.06, 0.04, 0.12]]),\n melee_blade: (n, id) => handled(n, ['wood_soft', [0.13, 0.03, 0.03]], ['steel', id === 'axe' ? [0.5, 0.03, 0.16] : id === 'knife' ? [0.16, 0.01, 0.03] : [0.45, 0.01, 0.05]]),\n tool: (n) => handled(n, ['plastic', [0.12, 0.025, 0.03]], ['steel', [0.16, 0.02, 0.03]]),\n flame: (n, id) => (id === 'flamethrower' ? handled(n, ['steel', [0.3, 0.14, 0.14]], ['steel', [0.6, 0.05, 0.05]]) : solid(n, 'plastic', [0.08, 0.02, 0.04], 0xd9482b)),\n heat: (n) => handled(n, ['steel', [0.2, 0.08, 0.08]], ['copper', [0.25, 0.03, 0.03]]),\n throwable: (n, id) => (id === 'molotov' ? solid(n, 'glass', [0.25, 0.07, 0.07], 0x7fd6b0) : solid(n, 'steel', [id === 'pipe_bomb' ? 0.25 : 0.1, 0.06, 0.06], 0x4c5a3a)),\n extinguisher: (n) => solid(n, 'steel', [0.5, 0.15, 0.15], 0xc0392b),\n}\n\n/** Body actions of the arsenal: nothing to hold or lay on a counter. */\nexport const BODY_ACTIONS: ReadonlySet<string> = new Set(['hand', 'kick', 'shove', 'fists'])\n\n// Real weights from the arsenal data: solid steel boxes would weigh several times more, go past a carry limit and stop being props.\nconst withMass = (prop: WeaponProp, kg: number): WeaponProp => {\n const volumes = prop.spec.parts.map((part) => (part.shape.kind === 'box' ? part.shape.size[0] * part.shape.size[1] * part.shape.size[2] : 0))\n const total = volumes.reduce((sum, volume) => sum + volume, 0) || 1\n return { ...prop, spec: { ...prop.spec, parts: prop.spec.parts.map((part, index) => ({ ...part, mass: (kg * volumes[index]) / total })) } }\n}\n\n/** The prop of a weapon: low-poly parts by category, the real mass of the weapon spread over them. */\nexport function weaponProp(def: Pick<WeaponDef, 'id' | 'category' | 'mass'>, name = def.id): WeaponProp {\n const shape = SHAPES[def.category] ?? SHAPES.tool\n return withMass(shape(name, def.id), def.mass)\n}\n\n/** One mesh per box part, named after the part (what destruction renderers bind to), in a group with its origin on the floor. */\nexport function buildProp(THREE: typeof THREE_NS, prop: WeaponProp): THREE_NS.Group {\n const group = new THREE.Group()\n group.name = prop.spec.name ?? 'weapon'\n for (const part of prop.spec.parts) {\n if (part.shape.kind !== 'box') continue\n const [w, h, d] = part.shape.size\n const material = new THREE.MeshStandardMaterial({ color: prop.colors[part.id] ?? 0x777777, roughness: 0.6, metalness: part.material === 'steel' ? 0.6 : 0.05 })\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material)\n mesh.name = part.id\n mesh.position.set(part.position[0], part.position[1], part.position[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n return group\n}\n\n/** The model of a weapon for the hands or a shelf: the same prop the counters show. */\nexport function buildWeaponModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id' | 'category' | 'mass'>): THREE_NS.Group {\n return buildProp(THREE, weaponProp(def))\n}\n","import type * as THREE_NS from 'three'\nimport type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponAudio } from './audio'\nimport { BODY_ACTIONS, buildWeaponModel } from './props'\n\nexport interface WeaponFxOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n /** Height things rest on at (x, z): casings and magazines land there. */\n groundAt: (x: number, z: number) => number\n /** Sounds (`createWeaponAudio`); null or absent: silent. */\n audio?: WeaponAudio | null\n}\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface WeaponFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/** Weapons that throw the spent case out on every shot. Revolvers keep them in the cylinder; break-actions open on reload. */\nconst EJECTS_ON_SHOT = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper', 'shotgun'])\n/** Weapons whose reload drops a magazine. */\nconst DROPS_MAGAZINE = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper'])\n/** Manual actions that cycle (pump, bolt) after each shot: the sound of the cycle. */\nconst CYCLES = new Set(['shotgun_pump_12', 'rifle_bolt_308'])\nconst MAX_CASINGS = 120\nconst MAX_MAGAZINES = 12\nconst LIFETIME_S = 25\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst GRAVITY = 9.81\n\ninterface Body {\n mesh: THREE_NS.Mesh\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n radius: number\n age: number\n resting: boolean\n bounces: number\n kind: 'casing' | 'magazine'\n}\n\nexport function createWeaponFx(options: WeaponFxOptions): WeaponFx {\n const { THREE, scene, camera, arsenal, groundAt } = options\n const audio = options.audio ?? null\n const bodies: Body[] = []\n const brass = new THREE.MeshStandardMaterial({ color: 0xc9a24a, metalness: 0.8, roughness: 0.35 })\n const shell = new THREE.MeshStandardMaterial({ color: 0xa8322b, roughness: 0.6 })\n const steel = new THREE.MeshStandardMaterial({ color: 0x2f3237, metalness: 0.5, roughness: 0.5 })\n const hand = new THREE.Group()\n hand.name = 'weapon-in-hand'\n scene.add(hand)\n let model: THREE_NS.Object3D | null = null\n let inHand: string | null = null\n let def: WeaponDef | null = null\n let kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const q = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\n\n const equip = (weapon: string): void => {\n if (model) hand.remove(model)\n model = null\n inHand = null\n def = arsenal.weapons.get(weapon) ?? null\n if (!def || BODY_ACTIONS.has(def.id)) return\n model = buildWeaponModel(THREE, def)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n // long guns are drawn smaller so they do not fill the view\n model.scale.setScalar(length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n }\n\n // a point on the gun in camera space, turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 =>\n out.set(HAND_OFFSET[0] + x, HAND_OFFSET[1] + y, HAND_OFFSET[2] + z).applyQuaternion(camera.quaternion).add(camera.position)\n\n const throwBody = (kind: Body['kind'], mesh: THREE_NS.Mesh, from: THREE_NS.Vector3, velocity: THREE_NS.Vector3, radius: number): void => {\n const limit = kind === 'casing' ? MAX_CASINGS : MAX_MAGAZINES\n const same = bodies.filter((b) => b.kind === kind)\n if (same.length >= limit) removeBody(same[0])\n mesh.position.copy(from)\n mesh.castShadow = true\n scene.add(mesh)\n bodies.push({ mesh, velocity, spin: new THREE.Vector3(Math.random() * 20 - 10, Math.random() * 30 - 15, Math.random() * 20 - 10), radius, age: 0, resting: false, bounces: 0, kind })\n }\n\n const ejectCasing = (caliberMm: number, isShell: boolean, downward: boolean): void => {\n const radius = isShell ? 0.0105 : Math.max(0.003, (caliberMm / 1000) * 0.6)\n const length = isShell ? 0.068 : Math.min(0.07, Math.max(0.015, (caliberMm / 1000) * 2.6))\n const mesh = new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, 8), isShell ? shell : brass)\n mesh.name = 'casing'\n const from = handPoint(0.03, 0.03, 0.05, new THREE.Vector3())\n const right = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion)\n const up = new THREE.Vector3(0, 1, 0)\n const velocity = downward\n ? up.clone().multiplyScalar(-0.5).addScaledVector(right, (Math.random() - 0.5) * 0.4)\n : right.multiplyScalar(1.6 + Math.random() * 0.8).addScaledVector(up, 1.4 + Math.random() * 0.8)\n throwBody('casing', mesh, from, velocity, radius)\n }\n\n const dropMagazine = (category: string): void => {\n const long = category === 'rifle' || category === 'sniper' || category === 'carbine'\n const size: [number, number, number] = long ? [0.03, 0.17, 0.07] : [0.025, 0.11, 0.035]\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(...size), steel)\n mesh.name = 'magazine'\n const from = handPoint(0, -0.06, 0, new THREE.Vector3())\n throwBody('magazine', mesh, from, new THREE.Vector3(0, -0.4, 0), size[1] / 2)\n audio?.reloadStart(category)\n }\n\n const caliberOf = (weapon: WeaponDef): number => {\n if (weapon.action.kind !== 'firearm') return 9\n return arsenal.calibers.get(weapon.action.caliber)?.diameter ?? 9\n }\n\n function removeBody(body: Body): void {\n body.mesh.removeFromParent()\n body.mesh.geometry.dispose()\n bodies.splice(bodies.indexOf(body), 1)\n }\n\n const onShot = (weapon: WeaponDef): void => {\n kick = 1\n const caliber = weapon.action.kind === 'firearm' ? arsenal.calibers.get(weapon.action.caliber) : undefined\n const energy = caliber ? 0.5 * (caliber.bulletGrams / 1000) * caliber.muzzleSpeed ** 2 * (caliber.pellets ?? 1) : 300\n audio?.shot(energy, weapon.category)\n if (CYCLES.has(weapon.id)) audio?.cycle()\n if (EJECTS_ON_SHOT.has(weapon.category) && weapon.id !== 'shotgun_double_12') ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', false)\n }\n\n const onReloadStart = (weapon: WeaponDef, tool: HostTool): void => {\n if (DROPS_MAGAZINE.has(weapon.category)) dropMagazine(weapon.category)\n else audio?.reloadStart(weapon.category)\n // revolvers and break-action shotguns dump their spent cases when opened\n if (weapon.category === 'revolver' || weapon.id === 'shotgun_double_12') {\n const spent = Math.max(1, tool.capacity - tool.ammo)\n for (let i = 0; i < spent; i++) ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', true)\n }\n }\n\n const stepBody = (body: Body, dt: number): void => {\n body.age += dt\n if (body.resting) return\n body.velocity.y -= GRAVITY * dt\n body.mesh.position.addScaledVector(body.velocity, dt)\n body.mesh.rotation.x += body.spin.x * dt\n body.mesh.rotation.y += body.spin.y * dt\n body.mesh.rotation.z += body.spin.z * dt\n const floor = groundAt(body.mesh.position.x, body.mesh.position.z) + body.radius\n if (body.mesh.position.y > floor) return\n body.mesh.position.y = floor\n if (Math.abs(body.velocity.y) > 0.7 && body.bounces < 4) {\n body.bounces++\n body.velocity.y = -body.velocity.y * 0.35\n body.velocity.x *= 0.55\n body.velocity.z *= 0.55\n body.spin.multiplyScalar(0.5)\n if (body.kind === 'casing') audio?.clink()\n else audio?.thud()\n return\n }\n if (body.kind === 'magazine' && body.bounces === 0) audio?.thud()\n body.resting = true\n body.mesh.rotation.x = Math.PI / 2\n body.mesh.rotation.z = 0\n }\n\n return {\n handle(event, tool) {\n const weapon = arsenal.weapons.get(event.weapon)\n if (event.type === 'tool') equip(event.weapon)\n if (!weapon) return\n if (event.type === 'shot') onShot(weapon)\n else if (event.type === 'empty') audio?.click()\n else if (event.type === 'reload' && event.phase === 'start') onReloadStart(weapon, tool)\n else if (event.type === 'reload' && event.phase === 'end') audio?.reloadEnd(weapon.category)\n reloading = tool.reloading\n },\n update(dt) {\n kick *= Math.exp(-dt * 14)\n dip += ((reloading ? 1 : 0) - dip) * Math.min(1, dt * 8)\n if (inHand) {\n handPoint(0, -0.12 * dip, 0.05 * kick, hand.position)\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.copy(camera.quaternion).multiply(q)\n }\n for (const body of [...bodies]) {\n stepBody(body, dt)\n if (body.age > LIFETIME_S) removeBody(body)\n }\n },\n get inHand() {\n return inHand\n },\n get casings() {\n return bodies.filter((b) => b.kind === 'casing').length\n },\n get magazines() {\n return bodies.filter((b) => b.kind === 'magazine').length\n },\n dispose() {\n for (const body of [...bodies]) removeBody(body)\n hand.removeFromParent()\n brass.dispose()\n shell.dispose()\n steel.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { AreaPlacement, DestructibleSpec, ModuleArea, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal } from '@adatechnology/game-weapons'\nimport { createWeaponAudio } from './audio'\nimport type { WeaponAudio } from './audio'\nimport { createWeaponFx } from './fx'\nimport type { WeaponFx } from './fx'\nimport { BODY_ACTIONS, buildProp, weaponProp } from './props'\nimport type { WeaponProp } from './props'\n\nexport interface WeaponsTestModuleOptions {\n /** `en` or `pt-BR` (default). */\n locale?: string\n /** The arsenal to lay out (default `createArsenal` with the locale). */\n arsenal?: Arsenal\n /** Play sounds (default true; silent anyway where there is no AudioContext). */\n sound?: boolean\n}\n\n/** Prefix of the item ids of the weapon props (`weapon_pistol_9mm`). */\nexport const WEAPON_ITEM_PREFIX = 'weapon_'\n// must not start with WEAPON_ITEM_PREFIX: hosts and tests tell the props apart by it\nexport const COUNTER_ITEM_ID = 'counter_weapons'\n\nconst COUNTER = { length: 4.8, depth: 1.6, height: 0.9 }\nconst COUNTER_X = [-6.5, -9, -11.5]\nconst COUNTER_Z = -1\n// props closer than this to a counter end have nothing next to them on one side\nconst END_MARGIN = 0.6\nconst SLOT_GAP = 0.3\n// targets in front of the brick wall of the room, at shooting distances\nconst TARGETS: Array<{ id: string; at: Vec3 }> = [\n { id: 'target_steel_plate', at: [-1.5, 0, -7] },\n { id: 'target_plywood', at: [0, 0, -7] },\n { id: 'target_concrete', at: [1.5, 0, -7] },\n]\n\nconst TEXT: Record<string, { group: string; name: string; counter: string; targets: Record<string, string>; reloadStart: string; reloadEnd: string }> = {\n en: {\n group: 'Weapons',\n name: 'Weapons area',\n counter: 'Weapon counter',\n targets: { target_steel_plate: 'Steel plate target', target_plywood: 'Plywood target', target_concrete: 'Concrete block target' },\n reloadStart: 'Reload started: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Reload done: {weapon} ({ammo}/{capacity})',\n },\n 'pt-BR': {\n group: 'Armas',\n name: 'Área de armas',\n counter: 'Balcão de armas',\n targets: { target_steel_plate: 'Alvo: chapa de aço', target_plywood: 'Alvo: compensado', target_concrete: 'Alvo: bloco de concreto' },\n reloadStart: 'Recarga iniciada: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Recarga completa: {weapon} ({ammo}/{capacity})',\n },\n}\nconst textOf = (locale: string): (typeof TEXT)['en'] => TEXT[locale] ?? TEXT.en\nconst fill = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n\nconst counterProp = (name: string): WeaponProp => {\n const { length, depth, height } = COUNTER\n return {\n spec: {\n name,\n parts: [\n { id: 'top', material: 'wood_soft', shape: { kind: 'box', size: [depth, 0.05, length] }, position: [0, height - 0.025, 0] },\n { id: 'side_a', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, -length / 2 + 0.05], anchored: true },\n { id: 'side_b', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, length / 2 - 0.05], anchored: true },\n ],\n joints: [\n { a: 'top', b: 'side_a', kind: 'screw' },\n { a: 'top', b: 'side_b', kind: 'screw' },\n ],\n tags: ['furniture'],\n },\n colors: { top: 0x8a5a30, side_a: 0x6b4426, side_b: 0x6b4426 },\n }\n}\n\nconst targetProp = (id: string, name: string): WeaponProp => {\n const face: Record<string, [string, Vec3, number]> = {\n target_steel_plate: ['steel', [0.5, 0.5, 0.01], 0xb5bcc4],\n target_plywood: ['plywood', [0.6, 0.8, 0.018], 0xc9a26b],\n target_concrete: ['concrete', [0.4, 0.2, 0.2], 0x9a9a94],\n }\n const [material, size, color] = face[id]\n const spec: DestructibleSpec = {\n name,\n parts: [\n { id: 'post', material: 'steel', shape: { kind: 'box', size: [0.05, 1.1, 0.05] }, position: [0, 0.55, -0.05], anchored: true },\n { id: 'face', material, shape: { kind: 'box', size }, position: [0, 1.1 + size[1] / 2, 0] },\n ],\n joints: [{ a: 'post', b: 'face', kind: 'bolt' }],\n tags: ['target'],\n }\n return { spec, colors: { post: 0x3a3d42, face: color } }\n}\n\nconst asItem = (id: string, name: string, prop: WeaponProp, extra: Partial<TestableItem> = {}): TestableItem => ({\n id,\n name,\n build: (THREE: unknown) => buildProp(THREE as typeof THREE_NS, prop),\n spec: prop.spec,\n ...extra,\n})\n\n/** Where the counters go and where each weapon lies on them: three counters on the free left side of the room, props across them. */\nexport function weaponsLayout(weaponItemIds: string[]): AreaPlacement[] {\n const perCounter = Math.floor((COUNTER.length - 2 * END_MARGIN) / SLOT_GAP) + 1\n const counters = COUNTER_X.slice(0, Math.max(1, Math.ceil(weaponItemIds.length / perCounter)))\n const placements: AreaPlacement[] = counters.map((x) => ({ item: COUNTER_ITEM_ID, position: [x, 0, COUNTER_Z], surface: { halfSize: [COUNTER.depth / 2, COUNTER.length / 2], height: COUNTER.height } }))\n weaponItemIds.forEach((item, index) => {\n const x = counters[Math.min(counters.length - 1, Math.floor(index / perCounter))]\n const z = COUNTER_Z - COUNTER.length / 2 + END_MARGIN + (index % perCounter) * SLOT_GAP\n // long props side by side overlap in the gentle piece separation of the renderer: asleep, they stay until grabbed\n placements.push({ item, position: [x, COUNTER.height + 0.01, z], asleep: true })\n })\n for (const target of TARGETS) placements.push({ item: target.id, position: target.at })\n return placements\n}\n\n/**\n * The weapons test area as a `TestableModule` of @adatechnology/game-contracts: one prop per weapon of the arsenal on counters (aim at one and\n * press H to equip it), targets at shooting distance, and, through `attach`, the weapon in the hands with its fire and reload motion,\n * ejected casings, dropped magazines and sounds, driven by the host's tool events.\n */\nexport function createWeaponsTestModule(options: WeaponsTestModuleOptions = {}): TestableModule & { readonly audio: WeaponAudio | null; readonly fx: WeaponFx | null } {\n const locale = options.locale ?? 'pt-BR'\n const arsenal = options.arsenal ?? createArsenal({ locale })\n const text = textOf(locale)\n const audio = options.sound === false ? null : createWeaponAudio()\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id))\n const weaponIds = weaponDefs.map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`)\n let fx: WeaponFx | null = null\n return {\n id: 'weapons_area',\n name: text.name,\n group: text.group,\n audio,\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => asItem(`${WEAPON_ITEM_PREFIX}${def.id}`, arsenal.name(def.id), weaponProp(def, arsenal.name(def.id)), { weapon: def.id, movable: true })),\n asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),\n ...TARGETS.map((target) => asItem(target.id, text.targets[target.id], targetProp(target.id, text.targets[target.id]), { movable: false })),\n ],\n area: (): ModuleArea => ({ placements: weaponsLayout(weaponIds), view: { eye: [-3.4, 1.7, 2.6], target: [-9, 0.9, -1.2] } }),\n attach(host) {\n const created = createWeaponFx({\n THREE: host.THREE as typeof THREE_NS,\n scene: host.scene as THREE_NS.Scene,\n camera: host.camera as THREE_NS.Camera,\n arsenal,\n groundAt: host.groundAt,\n audio,\n })\n fx = created\n const offEvents = host.on((event) => {\n const tool = host.tool()\n created.handle(event, tool)\n if (event.type === 'reload') host.log(fill(event.phase === 'start' ? text.reloadStart : text.reloadEnd, { weapon: arsenal.name(event.weapon), ammo: tool.ammo, capacity: tool.capacity }), { weapon: event.weapon, phase: event.phase })\n })\n const offFrame = host.onFrame((dt) => created.update(dt))\n created.handle({ type: 'tool', weapon: host.tool().weapon }, host.tool())\n return () => {\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n }\n },\n }\n}\n"],"mappings":"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Z,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QAC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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../../game-weapons/src/rng.ts","../../game-weapons/src/data/archetypes.json","../../game-weapons/src/data/calibers.json","../../game-weapons/src/data/explosives.json","../../game-weapons/src/data/explosive-weapons.json","../../game-weapons/src/data/firearms.json","../../game-weapons/src/data/launchers.json","../../game-weapons/src/check-arsenal.ts","../../game-weapons/src/merge.ts","../../game-weapons/src/locale.ts","../../game-weapons/src/fuse.ts","../../game-weapons/src/registry.ts","../../game-weapons/src/rules.ts","../../game-weapons/src/vec.ts","../../game-weapons/src/explosive-body.ts","../../game-weapons/src/explosive-use.ts","../../game-weapons/src/heat.ts","../../game-weapons/src/reload-stages.ts","../../game-weapons/src/reload.ts","../../game-weapons/src/faults.ts","../../game-weapons/src/fire.ts","../../game-weapons/src/weapon-shared.ts","../../game-weapons/src/weapon-core.ts","../../game-weapons/src/weapon-commands.ts","../../game-weapons/src/weapon-firearm.ts","../../game-weapons/src/weapon.ts","../../game-weapons/src/arsenal.ts","../../game-weapons/src/explosive-effect.ts","../src/audio/mechanical-sounds.ts","../src/audio/shot-sound.ts","../src/audio.ts","../src/fx/layers.ts","../src/merge-by-material.ts","../src/data/models.json","../src/models/rounded-box.ts","../src/models/kit.ts","../src/models/break-action.ts","../src/models/details.ts","../src/models/bullpup.ts","../src/models/launcher-flame.ts","../src/models/launcher-rounds.ts","../src/models/launcher-rocket.ts","../src/models/launcher.ts","../src/models/m2.ts","../src/models/p90.ts","../src/models/part-registry.ts","../src/models/pistol-slide.ts","../src/models/pistol-style.ts","../src/models/pistol.ts","../src/models/revolver.ts","../src/models/rifle-fittings.ts","../src/models/rifle-forend.ts","../src/models/rifle-controls.ts","../src/models/rifle-stock.ts","../src/models/rifle.ts","../src/models/index.ts","../src/props.ts","../src/box-fx.ts","../../game-contracts/src/impact.ts","../../game-contracts/src/spec.ts","../../game-contracts/src/weapons.ts","../../game-contracts/src/animation.ts","../../game-contracts/src/tool-animation.ts","../../game-contracts/src/bench.ts","../src/animation/clip-builder.ts","../src/animation/magazine-clips.ts","../src/animation/context.ts","../src/animation/cycle-clips.ts","../src/animation/reload-clips.ts","../src/animation/shot-clips.ts","../src/animation/clip-set.ts","../src/audio/host-events.ts","../src/models/condition.ts","../src/models/cartridge.ts","../src/fx/effects.ts","../src/fx/heavy.ts","../src/fx/particles.ts","../src/fx/rig.ts","../src/fx/session.ts","../src/fx/viewmodel-events.ts","../src/fx/viewmodel.ts","../src/fx.ts","../src/world-explosives.ts","../src/area.ts"],"sourcesContent":["/**\n * @adatechnology/game-weapons-three: the three.js side of @adatechnology/game-weapons. Low-poly weapon models, the weapon in the hands with\n * fire and reload motion, ejected casings and dropped magazines, synthesized sounds, and the weapons test area as a `TestableModule`\n * (any host of @adatechnology/game-contracts, like the test room, loads it with `loadModule`).\n */\nexport { createWeaponsTestModule, weaponsLayout, WEAPON_ITEM_PREFIX, COUNTER_ITEM_ID } from './area'\nexport type { WeaponsTestModuleOptions } from './area'\nexport { WORLD_EXPLOSIVE_IDS, WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from './world-explosives'\nexport { createWeaponFx } from './fx'\nexport type { FxLayers, WeaponFx, WeaponFxOptions } from './fx'\nexport {\n createWeaponAudio,\n computeShotSound,\n mechanicalSoundOf,\n MECHANICAL_SOUNDS,\n GAME_SOUND_CLASSES,\n GAME_DISTANCE_CURVE,\n DEFAULT_ENERGY_CURVE,\n CLASS_REFERENCE_ENERGY,\n} from './audio'\nexport type {\n WeaponAudio,\n WeaponAudioOptions,\n ShotExtras,\n ShotSound,\n ShotSoundInput,\n ShotSoundOptions,\n ShotSoundClass,\n SoundClassDef,\n DistanceCurve,\n EnergyCurve,\n MechanicalSoundId,\n SoundStep,\n} from './audio'\nexport { buildWeaponModel, buildProp, weaponProp, BODY_ACTIONS } from './props'\nexport type { WeaponProp } from './props'\nexport { MODEL_ENTRIES, ARCHETYPE_MODELS, buildWeaponModelById, hasWeaponModel } from './models'\nexport type { ModelEntry, ModelFamily, ModelOptions, ModelParts, WeaponModel } from './models'\nexport { buildCartridge, buildCasing, buildRound, cartridgeShape } from './models/cartridge'\nexport { applyCondition } from './models/condition'\nexport { partRegistry } from './models/part-registry'\nexport { buildToolClips } from './animation/clip-set'\nexport type { ClipContext } from './animation/context'\nexport type { CartridgeShape } from './models/cartridge'\nexport { modelKit } from './models/kit'\nexport type { ModelKit, ModelMaterials } from './models/kit'\n","import type { Vec3 } from './types'\n\n/** Deterministic mulberry32 generator; returns floats in [0, 1). */\nexport const createRng = (seed: number): (() => number) => {\n let a = seed >>> 0\n return () => {\n a = (a + 0x6d2b79f5) >>> 0\n let t = a\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n}\n\nexport const normalize = (v: Vec3): Vec3 => {\n const l = Math.hypot(v[0], v[1], v[2])\n return l > 1e-12 ? [v[0] / l, v[1] / l, v[2] / l] : [0, 0, -1]\n}\n\nconst cross = (a: Vec3, b: Vec3): Vec3 => [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]\n\n/** Uniform direction inside a cone of half-angle `deg` around the unit vector `dir` (uniform over the solid angle). */\nexport const sampleCone = (dir: Vec3, deg: number, rng: () => number): Vec3 => {\n if (deg <= 0) return dir\n const cosMax = Math.cos((deg * Math.PI) / 180)\n const cosT = 1 - rng() * (1 - cosMax)\n const sinT = Math.sqrt(Math.max(0, 1 - cosT * cosT))\n const phi = rng() * Math.PI * 2\n const helper: Vec3 = Math.abs(dir[1]) < 0.9 ? [0, 1, 0] : [1, 0, 0]\n const u = normalize(cross(helper, dir))\n const v = cross(dir, u)\n const cx = Math.cos(phi) * sinT\n const cy = Math.sin(phi) * sinT\n return normalize([\n u[0] * cx + v[0] * cy + dir[0] * cosT,\n u[1] * cx + v[1] * cy + dir[1] * cosT,\n u[2] * cx + v[2] * cy + dir[2] * cosT,\n ])\n}\n","[\n {\n \"id\": \"hand\",\n \"name\": \"Hand\",\n \"category\": \"hand\",\n \"action\": {\n \"kind\": \"hand\",\n \"reach\": 2\n },\n \"mass\": 0,\n \"tags\": [\n \"grab\"\n ]\n },\n {\n \"id\": \"kick\",\n \"name\": \"Kick\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 1.1,\n \"rpm\": 60,\n \"noise\": 8\n },\n \"mass\": 0\n },\n {\n \"id\": \"shove\",\n \"name\": \"Shove\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 80,\n \"radius\": 0.1,\n \"reach\": 1.5,\n \"rpm\": 90,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"pistol_9mm\",\n \"name\": \"9 mm service pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 2,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.2,\n 0.4\n ],\n \"range\": 50\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_45\",\n \"name\": \".45 ACP pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 280,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"reload\": 2.2,\n \"barrel\": 1,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.8,\n 0.6\n ],\n \"range\": 50\n },\n \"mass\": 1.1,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"pistol_22\",\n \"name\": \".22 LR pistol\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 360,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 1.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.5,\n 0.2\n ],\n \"range\": 40\n },\n \"mass\": 0.7,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_357\",\n \"name\": \".357 Magnum revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.9\n ],\n \"range\": 60\n },\n \"mass\": 1.2,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"revolver_38\",\n \"name\": \".38 Special revolver\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"38spl\",\n \"rpm\": 160,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 3.8,\n \"barrel\": 0.95,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.7,\n \"recoveryDegPerS\": 3.5,\n \"recoil\": [\n 1.6,\n 0.5\n ],\n \"range\": 45\n },\n \"mass\": 0.9,\n \"tags\": [\n \"sidearm\"\n ]\n },\n {\n \"id\": \"smg_9mm\",\n \"name\": \"9 mm submachine gun\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.4,\n \"barrel\": 1.1,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.9,\n 0.5\n ],\n \"range\": 80\n },\n \"mass\": 2.6,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"carbine_22\",\n \"name\": \".22 LR carbine\",\n \"category\": \"carbine\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.2,\n \"barrel\": 1.4,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.4,\n 0.15\n ],\n \"range\": 80\n },\n \"mass\": 2.4,\n \"tags\": [\n \"small_game\"\n ]\n },\n {\n \"id\": \"rifle_5_56\",\n \"name\": \"5.56 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"burst\",\n \"semi\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400\n },\n \"mass\": 3.4,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_7_62x39\",\n \"name\": \"7.62×39 mm assault rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.8,\n \"barrel\": 1,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.5,\n 0.8\n ],\n \"range\": 350\n },\n \"mass\": 3.8,\n \"tags\": [\n \"automatic\"\n ]\n },\n {\n \"id\": \"rifle_bolt_308\",\n \"name\": \".308 bolt-action rifle\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 40,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3,\n 0.5\n ],\n \"range\": 800\n },\n \"mass\": 4,\n \"tags\": [\n \"hunting\"\n ]\n },\n {\n \"id\": \"sniper_338\",\n \"name\": \".338 Lapua sniper rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 35,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 4,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.5,\n 0.7\n ],\n \"range\": 1500\n },\n \"mass\": 6.5,\n \"tags\": [\n \"long_range\"\n ]\n },\n {\n \"id\": \"anti_materiel_50\",\n \"name\": \".50 BMG anti-materiel rifle\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 30,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 4.5,\n \"barrel\": 1.05,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 7,\n 1.2\n ],\n \"range\": 1800\n },\n \"mass\": 12.5,\n \"tags\": [\n \"long_range\",\n \"heavy\"\n ]\n },\n {\n \"id\": \"shotgun_pump_12\",\n \"name\": \"12 gauge pump-action shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 60,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 6,\n \"reload\": 0.6,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4,\n 1\n ],\n \"range\": 40\n },\n \"mass\": 3.2,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_double_12\",\n \"name\": \"12 gauge double-barrel shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"break\"\n ],\n \"magazine\": 2,\n \"reload\": 3.5,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.5,\n 1.2\n ],\n \"range\": 35\n },\n \"mass\": 3,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"shotgun_semi_12\",\n \"name\": \"12 gauge semi-automatic shotgun\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"barrel\": 1,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.4,\n 1\n ],\n \"range\": 40\n },\n \"mass\": 3.4,\n \"tags\": [\n \"shotgun\"\n ]\n },\n {\n \"id\": \"bow_compound\",\n \"name\": \"Compound bow\",\n \"category\": \"bow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"arrow\",\n \"rpm\": 20,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 1.5,\n \"barrel\": 1,\n \"spreadDeg\": 0.4,\n \"bloomDeg\": 0.4,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.3,\n 0.1\n ],\n \"range\": 60\n },\n \"mass\": 1.8,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"crossbow\",\n \"name\": \"Crossbow\",\n \"category\": \"crossbow\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"crossbow_bolt\",\n \"rpm\": 8,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 1,\n \"reload\": 4,\n \"barrel\": 1,\n \"spreadDeg\": 0.3,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 0.5,\n 0.1\n ],\n \"range\": 70\n },\n \"mass\": 3,\n \"tags\": [\n \"silent\"\n ]\n },\n {\n \"id\": \"hammer\",\n \"name\": \"Hammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 60,\n \"radius\": 0.08,\n \"reach\": 0.7,\n \"rpm\": 70,\n \"noise\": 6\n },\n \"mass\": 1\n },\n {\n \"id\": \"sledgehammer\",\n \"name\": \"Sledgehammer\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 300,\n \"radius\": 0.15,\n \"reach\": 1.1,\n \"rpm\": 30,\n \"noise\": 8\n },\n \"mass\": 5.5,\n \"tags\": [\n \"heavy\"\n ]\n },\n {\n \"id\": \"baseball_bat\",\n \"name\": \"Baseball bat\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 150,\n \"radius\": 0.1,\n \"reach\": 1,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 0.9\n },\n {\n \"id\": \"crowbar\",\n \"name\": \"Crowbar\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 120,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 60,\n \"noise\": 7\n },\n \"mass\": 2,\n \"tags\": [\n \"pry\"\n ]\n },\n {\n \"id\": \"machete\",\n \"name\": \"Machete\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 140,\n \"radius\": 0.06,\n \"reach\": 0.8,\n \"rpm\": 80,\n \"noise\": 6\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"axe\",\n \"name\": \"Axe\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 250,\n \"radius\": 0.08,\n \"reach\": 0.9,\n \"rpm\": 45,\n \"noise\": 8\n },\n \"mass\": 1.6\n },\n {\n \"id\": \"knife\",\n \"name\": \"Knife\",\n \"category\": \"melee_blade\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"slash\",\n \"energy\": 40,\n \"radius\": 0.03,\n \"reach\": 0.4,\n \"rpm\": 100,\n \"noise\": 5\n },\n \"mass\": 0.2\n },\n {\n \"id\": \"fists\",\n \"name\": \"Fists\",\n \"category\": \"melee_blunt\",\n \"action\": {\n \"kind\": \"melee\",\n \"damage\": \"blunt\",\n \"energy\": 25,\n \"radius\": 0.1,\n \"reach\": 0.6,\n \"rpm\": 120,\n \"noise\": 5\n },\n \"mass\": 0\n },\n {\n \"id\": \"lighter\",\n \"name\": \"Lighter\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 400,\n \"radius\": 0.03,\n \"range\": 0.15,\n \"fuelPerSecond\": 0.02,\n \"fuel\": 60,\n \"noise\": 0\n },\n \"mass\": 0.05,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"flamethrower\",\n \"name\": \"Flamethrower\",\n \"category\": \"flame\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 6,\n \"fuelPerSecond\": 1,\n \"fuel\": 20,\n \"cone\": true,\n \"noise\": 20\n },\n \"mass\": 15,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"molotov\",\n \"name\": \"Molotov cocktail\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"molotov\",\n \"energy\": 500,\n \"radius\": 1.5,\n \"fuse\": 0,\n \"throwSpeed\": 12,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.5,\n \"seconds\": 12\n },\n \"noise\": 40\n },\n \"mass\": 0.8,\n \"tags\": [\n \"fire\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"cutting_torch\",\n \"name\": \"Oxy-fuel cutting torch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 3000,\n \"radius\": 0.02,\n \"range\": 0.25,\n \"fuelPerSecond\": 0.05,\n \"fuel\": 30,\n \"noise\": 15\n },\n \"mass\": 4,\n \"tags\": [\n \"fire\",\n \"cutting\"\n ]\n },\n {\n \"id\": \"blowtorch\",\n \"name\": \"Blowtorch\",\n \"category\": \"heat\",\n \"action\": {\n \"kind\": \"heat\",\n \"temperature\": 1300,\n \"radius\": 0.04,\n \"range\": 0.3,\n \"fuelPerSecond\": 0.04,\n \"fuel\": 30,\n \"noise\": 10\n },\n \"mass\": 0.6,\n \"tags\": [\n \"fire\"\n ]\n },\n {\n \"id\": \"frag_grenade\",\n \"name\": \"Fragmentation grenade\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"m67\",\n \"energy\": 200000,\n \"radius\": 5,\n \"fuse\": 4,\n \"throwSpeed\": 15,\n \"noise\": 500\n },\n \"mass\": 0.45,\n \"tags\": [\n \"explosive\"\n ]\n },\n {\n \"id\": \"pipe_bomb\",\n \"name\": \"Pipe bomb\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"pipe_bomb\",\n \"energy\": 43200,\n \"radius\": 3,\n \"fuse\": 3,\n \"throwSpeed\": 13,\n \"noise\": 450\n },\n \"mass\": 0.7,\n \"tags\": [\n \"explosive\",\n \"improvised\"\n ]\n },\n {\n \"id\": \"screwdriver\",\n \"name\": \"Screwdriver\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"screwdriver\",\n \"reach\": 0.5,\n \"noise\": 5\n },\n \"mass\": 0.15\n },\n {\n \"id\": \"wrench\",\n \"name\": \"Wrench\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"wrench\",\n \"reach\": 0.6,\n \"noise\": 6\n },\n \"mass\": 0.5\n },\n {\n \"id\": \"pry_bar\",\n \"name\": \"Pry bar\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"pry_bar\",\n \"reach\": 0.8,\n \"noise\": 8\n },\n \"mass\": 0.8\n },\n {\n \"id\": \"hacksaw\",\n \"name\": \"Hacksaw\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"saw\",\n \"reach\": 0.7,\n \"noise\": 10\n },\n \"mass\": 0.6\n },\n {\n \"id\": \"utility_knife\",\n \"name\": \"Utility knife\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"knife\",\n \"reach\": 0.3,\n \"noise\": 3\n },\n \"mass\": 0.1\n },\n {\n \"id\": \"claw_hammer\",\n \"name\": \"Claw hammer\",\n \"category\": \"tool\",\n \"action\": {\n \"kind\": \"tool\",\n \"tool\": \"hammer\",\n \"reach\": 0.5,\n \"noise\": 8\n },\n \"mass\": 0.7\n },\n {\n \"id\": \"extinguisher\",\n \"name\": \"Fire extinguisher\",\n \"category\": \"extinguisher\",\n \"action\": {\n \"kind\": \"extinguisher\",\n \"range\": 4,\n \"coolC\": 300,\n \"charge\": 12,\n \"noise\": 25\n },\n \"mass\": 5,\n \"tags\": [\n \"safety\"\n ]\n }\n]\n","[\n {\n \"id\": \"22lr\",\n \"label\": \".22 LR\",\n \"diameter\": 5.7,\n \"bulletGrams\": 2.6,\n \"muzzleSpeed\": 350,\n \"dragPer100m\": 0.15,\n \"kind\": \"rimfire\",\n \"noise\": 60,\n \"caseType\": \"tiny\",\n \"rim\": \"rimfire\",\n \"cartridge\": {\n \"caseDiameter\": 5.7,\n \"overallLength\": 25.4,\n \"caseLength\": 15.6,\n \"projectileDiameter\": 5.7\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"380acp\",\n \"label\": \".380 ACP\",\n \"diameter\": 9,\n \"bulletGrams\": 6.2,\n \"muzzleSpeed\": 295,\n \"dragPer100m\": 0.22,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 9.5,\n \"overallLength\": 25,\n \"caseLength\": 17.3,\n \"projectileDiameter\": 9\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"9x18\",\n \"label\": \"9×18 mm Makarov\",\n \"diameter\": 9.3,\n \"bulletGrams\": 6.1,\n \"muzzleSpeed\": 315,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 9.9,\n \"overallLength\": 25.3,\n \"caseLength\": 18,\n \"projectileDiameter\": 9.3\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"9x19\",\n \"label\": \"9×19 mm\",\n \"diameter\": 9,\n \"bulletGrams\": 7.5,\n \"muzzleSpeed\": 365,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 9.9,\n \"overallLength\": 29.7,\n \"caseLength\": 19.15,\n \"projectileDiameter\": 9\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"40sw\",\n \"label\": \".40 S&W\",\n \"diameter\": 10.2,\n \"bulletGrams\": 11.7,\n \"muzzleSpeed\": 310,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 10.8,\n \"overallLength\": 28.6,\n \"caseLength\": 21.6,\n \"projectileDiameter\": 10.2\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"45acp\",\n \"label\": \".45 ACP\",\n \"diameter\": 11.5,\n \"bulletGrams\": 14.9,\n \"muzzleSpeed\": 254,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 12,\n \"overallLength\": 32.4,\n \"caseLength\": 22.8,\n \"projectileDiameter\": 11.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"5_7x28\",\n \"label\": \"5.7×28 mm\",\n \"diameter\": 5.7,\n \"bulletGrams\": 2,\n \"muzzleSpeed\": 715,\n \"dragPer100m\": 0.12,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimless\",\n \"cartridge\": {\n \"caseDiameter\": 7.9,\n \"overallLength\": 40.5,\n \"caseLength\": 28.9,\n \"projectileDiameter\": 5.7\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"38spl\",\n \"label\": \".38 Special\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 247,\n \"dragPer100m\": 0.2,\n \"kind\": \"fmj\",\n \"noise\": 150,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 9.6,\n \"overallLength\": 39.4,\n \"caseLength\": 29.3,\n \"projectileDiameter\": 9.1\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"357mag\",\n \"label\": \".357 Magnum\",\n \"diameter\": 9.1,\n \"bulletGrams\": 10.2,\n \"muzzleSpeed\": 396,\n \"dragPer100m\": 0.18,\n \"kind\": \"hp\",\n \"noise\": 300,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 9.6,\n \"overallLength\": 40,\n \"caseLength\": 33,\n \"projectileDiameter\": 9.1\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"44mag\",\n \"label\": \".44 Magnum\",\n \"diameter\": 10.9,\n \"bulletGrams\": 15.6,\n \"muzzleSpeed\": 440,\n \"dragPer100m\": 0.18,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"pistol\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 11.6,\n \"overallLength\": 40.9,\n \"caseLength\": 32.6,\n \"projectileDiameter\": 10.9\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"50ae\",\n \"label\": \".50 AE\",\n \"diameter\": 12.7,\n \"bulletGrams\": 19.4,\n \"muzzleSpeed\": 470,\n \"dragPer100m\": 0.18,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"pistol\",\n \"cartridge\": {\n \"caseDiameter\": 13.9,\n \"overallLength\": 40.9,\n \"caseLength\": 32.6,\n \"projectileDiameter\": 12.7\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"12ga_00buck\",\n \"label\": \"12 ga 00 buck\",\n \"diameter\": 8.4,\n \"bulletGrams\": 3.5,\n \"muzzleSpeed\": 414,\n \"pellets\": 9,\n \"dragPer100m\": 0.45,\n \"kind\": \"buck\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"cartridge\": {\n \"caseDiameter\": 20,\n \"overallLength\": 70,\n \"caseLength\": 70,\n \"projectileDiameter\": 18.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"12ga_slug\",\n \"label\": \"12 ga slug\",\n \"diameter\": 18.5,\n \"bulletGrams\": 28,\n \"muzzleSpeed\": 463,\n \"dragPer100m\": 0.3,\n \"kind\": \"slug\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"cartridge\": {\n \"caseDiameter\": 20,\n \"overallLength\": 70,\n \"caseLength\": 70,\n \"projectileDiameter\": 18.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"12ga_birdshot\",\n \"label\": \"12 ga birdshot\",\n \"diameter\": 2.4,\n \"bulletGrams\": 0.2,\n \"muzzleSpeed\": 400,\n \"pellets\": 90,\n \"dragPer100m\": 0.6,\n \"kind\": \"birdshot\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"cartridge\": {\n \"caseDiameter\": 20,\n \"overallLength\": 70,\n \"caseLength\": 70,\n \"projectileDiameter\": 18.5\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"20ga_buck\",\n \"label\": \"20 ga buck\",\n \"diameter\": 6.9,\n \"bulletGrams\": 1.3,\n \"muzzleSpeed\": 400,\n \"pellets\": 20,\n \"dragPer100m\": 0.5,\n \"kind\": \"buck\",\n \"noise\": 350,\n \"caseType\": \"shell\",\n \"rim\": \"shell\",\n \"sources\": [\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"5_56x45\",\n \"label\": \"5.56×45 mm\",\n \"diameter\": 5.7,\n \"bulletGrams\": 4,\n \"muzzleSpeed\": 935,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 9.6,\n \"overallLength\": 57.4,\n \"caseLength\": 44.7,\n \"projectileDiameter\": 5.7\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"5_45x39\",\n \"label\": \"5.45×39 mm\",\n \"diameter\": 5.6,\n \"bulletGrams\": 3.4,\n \"muzzleSpeed\": 900,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 10,\n \"overallLength\": 57,\n \"caseLength\": 39.8,\n \"projectileDiameter\": 5.6\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"7_62x39\",\n \"label\": \"7.62×39 mm\",\n \"diameter\": 7.9,\n \"bulletGrams\": 8,\n \"muzzleSpeed\": 725,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 11.3,\n \"overallLength\": 56,\n \"caseLength\": 38.7,\n \"projectileDiameter\": 7.9\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"30_30\",\n \"label\": \".30-30 Winchester\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 670,\n \"dragPer100m\": 0.1,\n \"kind\": \"fmj\",\n \"noise\": 300,\n \"caseType\": \"rifle\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 10.7,\n \"overallLength\": 64.8,\n \"caseLength\": 51.8,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"7_62x51\",\n \"label\": \"7.62×51 mm (.308)\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 850,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 12,\n \"overallLength\": 71.1,\n \"caseLength\": 51.2,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"7_62x54r\",\n \"label\": \"7.62×54R\",\n \"diameter\": 7.9,\n \"bulletGrams\": 9.6,\n \"muzzleSpeed\": 865,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"rifle\",\n \"rim\": \"rimmed\",\n \"cartridge\": {\n \"caseDiameter\": 12.4,\n \"overallLength\": 77.2,\n \"caseLength\": 53.7,\n \"projectileDiameter\": 7.9\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"30_06\",\n \"label\": \".30-06 Springfield\",\n \"diameter\": 7.8,\n \"bulletGrams\": 9.7,\n \"muzzleSpeed\": 880,\n \"dragPer100m\": 0.08,\n \"kind\": \"fmj\",\n \"noise\": 420,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 12,\n \"overallLength\": 84.8,\n \"caseLength\": 63.3,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"300wm\",\n \"label\": \".300 Winchester Magnum\",\n \"diameter\": 7.8,\n \"bulletGrams\": 11.7,\n \"muzzleSpeed\": 900,\n \"dragPer100m\": 0.07,\n \"kind\": \"fmj\",\n \"noise\": 600,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 13,\n \"overallLength\": 84.8,\n \"caseLength\": 66.5,\n \"projectileDiameter\": 7.8\n },\n \"sources\": [\n \"reference\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"338lapua\",\n \"label\": \".338 Lapua Magnum\",\n \"diameter\": 8.6,\n \"bulletGrams\": 16.2,\n \"muzzleSpeed\": 903,\n \"dragPer100m\": 0.06,\n \"kind\": \"fmj\",\n \"noise\": 600,\n \"caseType\": \"rifle\",\n \"cartridge\": {\n \"caseDiameter\": 14.9,\n \"overallLength\": 93.5,\n \"caseLength\": 69.2,\n \"projectileDiameter\": 8.6\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"408cheytac\",\n \"label\": \".408 CheyTac\",\n \"diameter\": 10.4,\n \"bulletGrams\": 27.2,\n \"muzzleSpeed\": 900,\n \"dragPer100m\": 0.05,\n \"kind\": \"fmj\",\n \"noise\": 600,\n \"caseType\": \"big\",\n \"cartridge\": {\n \"caseDiameter\": 16,\n \"overallLength\": 115.6,\n \"caseLength\": 77,\n \"projectileDiameter\": 10.36\n },\n \"sources\": [\n \"reference\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"50bmg\",\n \"label\": \".50 BMG\",\n \"diameter\": 12.7,\n \"bulletGrams\": 42,\n \"muzzleSpeed\": 925,\n \"dragPer100m\": 0.05,\n \"kind\": \"ap\",\n \"noise\": 600,\n \"caseType\": \"big\",\n \"cartridge\": {\n \"caseDiameter\": 20.4,\n \"overallLength\": 138,\n \"caseLength\": 99,\n \"projectileDiameter\": 12.7\n },\n \"sources\": [\n \"sdk\",\n \"gallery\",\n \"arsenal\"\n ]\n },\n {\n \"id\": \"arrow\",\n \"label\": \"Arrow (compound bow)\",\n \"diameter\": 7,\n \"bulletGrams\": 25,\n \"muzzleSpeed\": 90,\n \"dragPer100m\": 0.12,\n \"kind\": \"arrow\",\n \"noise\": 20,\n \"sources\": [\n \"sdk\"\n ]\n },\n {\n \"id\": \"crossbow_bolt\",\n \"label\": \"Crossbow bolt\",\n \"diameter\": 8,\n \"bulletGrams\": 20,\n \"muzzleSpeed\": 122,\n \"dragPer100m\": 0.12,\n \"kind\": \"bolt\",\n \"noise\": 25,\n \"sources\": [\n \"sdk\"\n ]\n }\n]\n","[\n {\n \"id\": \"m67\",\n \"name\": \"M67 fragmentation grenade\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 15,\n \"energy\": 200000,\n \"destructionLevel\": 2,\n \"noise\": 500,\n \"fuse\": 4,\n \"triggers\": [\n \"timer\"\n ],\n \"mass\": 0.4,\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"game\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"molotov\",\n \"name\": \"Molotov cocktail\",\n \"kind\": \"incendiary\",\n \"lethalRadius\": 0,\n \"injuryRadius\": 4,\n \"energy\": 500,\n \"destructionLevel\": 0,\n \"noise\": 40,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 4,\n \"seconds\": 9\n },\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"game\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"pipe_bomb\",\n \"name\": \"Pipe bomb\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 3,\n \"injuryRadius\": 10,\n \"energy\": 43200,\n \"destructionLevel\": 2,\n \"noise\": 450,\n \"fuse\": 3,\n \"triggers\": [\n \"timer\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"propane_p13\",\n \"name\": \"P13 propane cylinder\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 14,\n \"energy\": 200000,\n \"destructionLevel\": 2,\n \"noise\": 550,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.4,\n \"seconds\": 7\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": 1.4,\n \"fire\": 1.4,\n \"explosion\": [\n 0.25,\n 0.6\n ]\n },\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"game\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"dynamite\",\n \"name\": \"Dynamite\",\n \"kind\": \"blast\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 3,\n \"noise\": 600,\n \"fuseLength\": 0.03,\n \"burnRate\": 131,\n \"burnTolerance\": 0.1,\n \"triggers\": [\n \"timer\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\",\n \"reference\"\n ]\n },\n {\n \"id\": \"c4\",\n \"name\": \"C4 charge\",\n \"kind\": \"blast\",\n \"lethalRadius\": 6,\n \"injuryRadius\": 18,\n \"energy\": 345600,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"triggers\": [\n \"remote\"\n ],\n \"mass\": 0.57,\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"claymore\",\n \"name\": \"Claymore mine\",\n \"kind\": \"directional\",\n \"lethalRadius\": 15,\n \"injuryRadius\": 50,\n \"cone\": {\n \"halfAngleDeg\": 30,\n \"length\": 50\n },\n \"energy\": 102400,\n \"destructionLevel\": 1,\n \"noise\": 500,\n \"triggers\": [\n \"wire\"\n ],\n \"tripwire\": {\n \"length\": 10,\n \"angleDeg\": 0,\n \"height\": 0.15\n },\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"flashbang\",\n \"name\": \"Flashbang\",\n \"kind\": \"flash\",\n \"lethalRadius\": 0,\n \"injuryRadius\": 10,\n \"energy\": 0,\n \"destructionLevel\": 0,\n \"noise\": 400,\n \"fuseRange\": [\n 1,\n 2.3\n ],\n \"stunSeconds\": 4,\n \"triggers\": [\n \"timer\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\",\n \"reference\"\n ]\n },\n {\n \"id\": \"m79_40mm\",\n \"name\": \"40 mm grenade\",\n \"kind\": \"fragmentation\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 2,\n \"noise\": 450,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"m72_66mm\",\n \"name\": \"66 mm HEAT rocket\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 15,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"at4_84mm\",\n \"name\": \"84 mm HEAT rocket\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 16,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 750,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"pg7v\",\n \"name\": \"PG-7V rocket\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 16,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 750,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"gallery\"\n ]\n },\n {\n \"id\": \"carl_gustaf_84mm\",\n \"name\": \"84 mm HE/HEAT round\",\n \"kind\": \"shaped_charge\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 16,\n \"energy\": 200000,\n \"destructionLevel\": 3,\n \"noise\": 750,\n \"triggers\": [\n \"impact\"\n ],\n \"sources\": [\n \"lab\",\n \"gallery\",\n \"derived\"\n ]\n },\n {\n \"id\": \"fuel_barrel\",\n \"name\": \"Fuel barrel\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 2,\n \"noise\": 550,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 2,\n \"seconds\": 12\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": 1.2,\n \"fire\": 1.2,\n \"explosion\": [\n 0.2,\n 0.4\n ]\n },\n \"sources\": [\n \"lab\",\n \"game\",\n \"derived\"\n ]\n },\n {\n \"id\": \"car_fuel_tank\",\n \"name\": \"Car fuel tank\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 5,\n \"injuryRadius\": 14,\n \"energy\": 200000,\n \"destructionLevel\": 2,\n \"noise\": 550,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 2.2,\n \"seconds\": 30\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": [\n 3,\n 8\n ],\n \"fire\": [\n 3,\n 8\n ],\n \"explosion\": 0.6,\n \"shotDamageFraction\": 0.5\n },\n \"sources\": [\n \"lab\",\n \"game\",\n \"derived\"\n ]\n },\n {\n \"id\": \"fuel_pump\",\n \"name\": \"Fuel pump\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 4,\n \"injuryRadius\": 12,\n \"energy\": 102400,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 1.1,\n \"seconds\": 14\n },\n \"triggers\": [\n \"shot\",\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"shot\": 1,\n \"fire\": 1,\n \"explosion\": 0.4\n },\n \"sources\": [\n \"lab\",\n \"derived\"\n ]\n },\n {\n \"id\": \"fuel_station_tank\",\n \"name\": \"Fuel station tank\",\n \"kind\": \"fuel\",\n \"lethalRadius\": 12,\n \"injuryRadius\": 30,\n \"energy\": 2764800,\n \"destructionLevel\": 3,\n \"noise\": 700,\n \"fire\": {\n \"temperature\": 700,\n \"radius\": 3.2,\n \"seconds\": 20\n },\n \"triggers\": [\n \"fire\",\n \"explosion\"\n ],\n \"chain\": {\n \"fire\": 2,\n \"explosion\": 2\n },\n \"sources\": [\n \"lab\",\n \"derived\"\n ]\n }\n]\n","[\n {\n \"id\": \"flashbang\",\n \"name\": \"Flashbang\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"flashbang\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 15,\n \"noise\": 0\n },\n \"mass\": 0.23,\n \"tags\": [\n \"explosive\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"dynamite\",\n \"name\": \"Dynamite\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"dynamite\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 15,\n \"noise\": 0\n },\n \"mass\": 0.5,\n \"tags\": [\n \"explosive\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"c4\",\n \"name\": \"C4 charge\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"c4\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 0,\n \"noise\": 0\n },\n \"mass\": 0.57,\n \"tags\": [\n \"explosive\",\n \"placed\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\"\n ]\n },\n {\n \"id\": \"claymore\",\n \"name\": \"Claymore mine\",\n \"category\": \"throwable\",\n \"action\": {\n \"kind\": \"throwable\",\n \"explosive\": \"claymore\",\n \"energy\": 0,\n \"radius\": 0,\n \"fuse\": 0,\n \"throwSpeed\": 0,\n \"noise\": 0\n },\n \"mass\": 1.6,\n \"tags\": [\n \"explosive\",\n \"placed\"\n ],\n \"archetype\": \"frag_grenade\",\n \"sources\": [\n \"arsenal\",\n \"lab\",\n \"reference\"\n ]\n }\n]\n","[\n {\n \"id\": \"glock_17\",\n \"name\": \"Glock 17\",\n \"maker\": \"Glock\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 17,\n \"reload\": 1.8,\n \"muzzleSpeed\": 375,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.63,\n 0.54\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.7,\n \"moa\": 4\n },\n \"mass\": 0.7,\n \"dimensions\": {\n \"length\": 0.202,\n \"barrel\": 0.114,\n \"emptyMass\": 0.63\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"glock_18\",\n \"name\": \"Glock 18\",\n \"maker\": \"Glock\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 1200,\n \"modes\": [\n \"semi\",\n \"auto\"\n ],\n \"magazine\": 17,\n \"magazineOptions\": [\n 33\n ],\n \"reload\": 1.8,\n \"muzzleSpeed\": 375,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.63,\n 0.54\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 4\n },\n \"mass\": 0.7,\n \"dimensions\": {\n \"length\": 0.202,\n \"barrel\": 0.114,\n \"emptyMass\": 0.62\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"glock_19\",\n \"name\": \"Glock 19\",\n \"maker\": \"Glock\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 1.7,\n \"muzzleSpeed\": 360,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.75,\n 0.58\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.7,\n \"moa\": 4\n },\n \"mass\": 0.6,\n \"dimensions\": {\n \"length\": 0.185,\n \"barrel\": 0.102,\n \"emptyMass\": 0.6\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"taurus_g2c\",\n \"name\": \"Taurus G2C\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 12,\n \"reload\": 1.7,\n \"muzzleSpeed\": 340,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.56,\n 0.52\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.5,\n \"moa\": 5\n },\n \"mass\": 0.6,\n \"dimensions\": {\n \"length\": 0.159,\n \"barrel\": 0.081,\n \"emptyMass\": 0.62\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"taurus_ts9\",\n \"name\": \"Taurus TS9\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 17,\n \"reload\": 1.8,\n \"muzzleSpeed\": 360,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.5,\n 0.5\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.2,\n \"moa\": 4\n },\n \"mass\": 0.7,\n \"dimensions\": {\n \"length\": 0.194,\n \"barrel\": 0.104,\n \"emptyMass\": 0.68\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"beretta_92fs\",\n \"name\": \"Beretta 92FS\",\n \"maker\": \"Beretta\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 1.9,\n \"muzzleSpeed\": 381,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.24,\n 0.41\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 3\n },\n \"mass\": 0.95,\n \"dimensions\": {\n \"length\": 0.217,\n \"barrel\": 0.125,\n \"emptyMass\": 0.95\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"sig_sauer_p226\",\n \"name\": \"SIG Sauer P226\",\n \"maker\": \"SIG Sauer\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 15,\n \"reload\": 1.9,\n \"muzzleSpeed\": 350,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.03,\n 0.34\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.8,\n \"moa\": 3\n },\n \"mass\": 0.96,\n \"dimensions\": {\n \"length\": 0.196,\n \"barrel\": 0.112,\n \"emptyMass\": 0.96\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"cz_75\",\n \"name\": \"CZ 75\",\n \"maker\": \"CZ\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 16,\n \"reload\": 1.9,\n \"muzzleSpeed\": 370,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.11,\n 0.37\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 3\n },\n \"mass\": 1,\n \"dimensions\": {\n \"length\": 0.206,\n \"barrel\": 0.12,\n \"emptyMass\": 1\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"taurus_pt100\",\n \"name\": \"Taurus PT100\",\n \"maker\": \"Taurus\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"40sw\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 11,\n \"reload\": 1.9,\n \"muzzleSpeed\": 300,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.14,\n 0.38\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.2,\n \"moa\": 4\n },\n \"mass\": 1,\n \"dimensions\": {\n \"length\": 0.216,\n \"barrel\": 0.127,\n \"emptyMass\": 1\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"colt_m1911\",\n \"name\": \"Colt M1911\",\n \"maker\": \"Colt\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 7,\n \"reload\": 1.8,\n \"muzzleSpeed\": 253,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.79,\n 0.6\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.1,\n \"moa\": 3\n },\n \"mass\": 1.1,\n \"dimensions\": {\n \"length\": 0.216,\n \"barrel\": 0.127,\n \"emptyMass\": 1.1\n },\n \"archetype\": \"pistol_45\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"makarov_pm\",\n \"name\": \"Makarov PM\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x18\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"reload\": 1.7,\n \"muzzleSpeed\": 315,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 0.9,\n 0.3\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.7,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.8,\n \"moa\": 5\n },\n \"mass\": 0.73,\n \"dimensions\": {\n \"length\": 0.161,\n \"barrel\": 0.094,\n \"emptyMass\": 0.73\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"fn_five_seven\",\n \"name\": \"FN Five-seveN\",\n \"maker\": \"FN\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_7x28\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 1.8,\n \"muzzleSpeed\": 650,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.6,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 1.5,\n 0.5\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.9,\n \"moa\": 3\n },\n \"mass\": 0.61,\n \"dimensions\": {\n \"length\": 0.208,\n \"barrel\": 0.122,\n \"emptyMass\": 0.61\n },\n \"archetype\": \"pistol_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"desert_eagle_mark_xix\",\n \"name\": \"Desert Eagle Mark XIX\",\n \"category\": \"pistol\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50ae\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 7,\n \"reload\": 2,\n \"muzzleSpeed\": 470,\n \"spreadDeg\": 1.1,\n \"bloomDeg\": 0.8,\n \"recoveryDegPerS\": 4,\n \"recoil\": [\n 4.41,\n 1.47\n ],\n \"range\": 50,\n \"family\": \"pistol\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.8,\n \"moa\": 3\n },\n \"mass\": 2,\n \"dimensions\": {\n \"length\": 0.27,\n \"barrel\": 0.152,\n \"emptyMass\": 1.99\n },\n \"archetype\": \"pistol_45\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"taurus_82\",\n \"name\": \"Taurus 82\",\n \"maker\": \"Taurus\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"38spl\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 2.2,\n \"muzzleSpeed\": 260,\n \"spreadDeg\": 0.9,\n \"bloomDeg\": 0.7,\n \"recoveryDegPerS\": 3.5,\n \"recoil\": [\n 1.96,\n 0.61\n ],\n \"range\": 45,\n \"family\": \"revolver\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.2,\n \"perRound\": 1,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 0.9,\n \"dimensions\": {\n \"length\": 0.24,\n \"barrel\": 0.102,\n \"emptyMass\": 0.95\n },\n \"archetype\": \"revolver_38\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"sw_686\",\n \"name\": \"S&W 686\",\n \"maker\": \"S&W\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 7,\n \"reload\": 2.4,\n \"muzzleSpeed\": 430,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3.21,\n 0.96\n ],\n \"range\": 60,\n \"family\": \"revolver\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"perRound\": 1,\n \"clear\": 1.2\n },\n \"moa\": 3,\n \"acceptsCalibers\": [\n \"38spl\"\n ]\n },\n \"mass\": 1.2,\n \"dimensions\": {\n \"length\": 0.244,\n \"barrel\": 0.102,\n \"emptyMass\": 1.14\n },\n \"archetype\": \"revolver_357\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"sw_model_29\",\n \"name\": \"S&W Model 29\",\n \"maker\": \"S&W\",\n \"category\": \"revolver\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"44mag\",\n \"rpm\": 150,\n \"modes\": [\n \"single\"\n ],\n \"magazine\": 6,\n \"reload\": 2.6,\n \"muzzleSpeed\": 440,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 1,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 4.4,\n 1.32\n ],\n \"range\": 60,\n \"family\": \"revolver\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"perRound\": 1,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 1.4,\n \"dimensions\": {\n \"length\": 0.302,\n \"barrel\": 0.165,\n \"emptyMass\": 1.4\n },\n \"archetype\": \"revolver_357\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"hk_mp5a3\",\n \"name\": \"HK MP5A3\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.8,\n 0.44\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 2.9,\n \"dimensions\": {\n \"length\": 0.7,\n \"barrel\": 0.225,\n \"emptyMass\": 2.54,\n \"lengthCollapsed\": 0.55\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"taurus_smt9\",\n \"name\": \"Taurus SMT9\",\n \"maker\": \"Taurus\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.5,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.78,\n 0.43\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.66,\n \"barrel\": 0.2,\n \"emptyMass\": 2.5,\n \"lengthCollapsed\": 0.45\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"hk_ump_45\",\n \"name\": \"HK UMP-45\",\n \"maker\": \"HK\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 25,\n \"reload\": 2.7,\n \"muzzleSpeed\": 285,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 1.02,\n 0.57\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.3,\n \"dimensions\": {\n \"length\": 0.69,\n \"barrel\": 0.2,\n \"emptyMass\": 2.3,\n \"lengthCollapsed\": 0.45\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"uzi\",\n \"name\": \"Uzi\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 32,\n \"reload\": 2.4,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.66,\n 0.37\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"clear\": 1.2\n },\n \"moa\": 6\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 0.65,\n \"barrel\": 0.26,\n \"emptyMass\": 3.5,\n \"lengthCollapsed\": 0.47\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"fn_p90\",\n \"name\": \"FN P90\",\n \"maker\": \"FN\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_7x28\",\n \"rpm\": 900,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 50,\n \"reload\": 3,\n \"muzzleSpeed\": 715,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.76,\n 0.42\n ],\n \"range\": 80,\n \"family\": \"top_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 2.6,\n \"dimensions\": {\n \"length\": 0.5,\n \"barrel\": 0.264,\n \"emptyMass\": 2.6\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"kriss_vector\",\n \"name\": \"Kriss Vector\",\n \"maker\": \"Kriss\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 1100,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 25,\n \"reload\": 2.5,\n \"muzzleSpeed\": 290,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.9,\n 0.5\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.622,\n \"barrel\": 0.14,\n \"emptyMass\": 2.7,\n \"lengthCollapsed\": 0.406\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"thompson_m1a1\",\n \"name\": \"Thompson M1A1\",\n \"maker\": \"Thompson\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.9,\n \"muzzleSpeed\": 285,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.49,\n 0.27\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.9,\n \"clear\": 1.2\n },\n \"moa\": 5\n },\n \"mass\": 4.8,\n \"dimensions\": {\n \"length\": 0.813,\n \"barrel\": 0.267,\n \"emptyMass\": 4.8\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"cz_scorpion_evo_3\",\n \"name\": \"CZ Scorpion EVO 3\",\n \"maker\": \"CZ\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"9x19\",\n \"rpm\": 1150,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 370,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.71,\n 0.39\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 2.8,\n \"dimensions\": {\n \"length\": 0.67,\n \"barrel\": 0.196,\n \"emptyMass\": 2.77,\n \"lengthCollapsed\": 0.41\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"mac_10\",\n \"name\": \"MAC-10\",\n \"category\": \"smg\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"45acp\",\n \"rpm\": 1090,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.2,\n \"muzzleSpeed\": 280,\n \"spreadDeg\": 1.5,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 6,\n \"recoil\": [\n 0.81,\n 0.45\n ],\n \"range\": 80,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.2,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.4,\n \"moa\": 8\n },\n \"mass\": 2.8,\n \"dimensions\": {\n \"length\": 0.548,\n \"barrel\": 0.146,\n \"emptyMass\": 2.84,\n \"lengthCollapsed\": 0.296\n },\n \"archetype\": \"smg_9mm\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"remington_870\",\n \"name\": \"Remington 870\",\n \"maker\": \"Remington\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 6,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.32,\n 0.83\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.99,\n \"barrel\": 0.47,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"mossberg_500\",\n \"name\": \"Mossberg 500\",\n \"maker\": \"Mossberg\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 5,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.73,\n 0.93\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.2,\n \"dimensions\": {\n \"length\": 0.99,\n \"barrel\": 0.47,\n \"emptyMass\": 3.2\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"cbc_pump_military_3_0\",\n \"name\": \"CBC Pump Military 3.0\",\n \"maker\": \"CBC\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 7,\n \"chamber\": 1,\n \"reload\": 0.6,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.41,\n 0.85\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.6,\n \"perRound\": 0.6,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.48,\n \"emptyMass\": 3.4\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"benelli_m4\",\n \"name\": \"Benelli M4\",\n \"maker\": \"Benelli\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 7,\n \"chamber\": 1,\n \"reload\": 0.5,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 2.84,\n 0.84\n ],\n \"range\": 40,\n \"family\": \"tube_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.5,\n \"perRound\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.8,\n \"dimensions\": {\n \"length\": 1.01,\n \"barrel\": 0.47,\n \"emptyMass\": 3.82\n },\n \"archetype\": \"shotgun_semi_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"franchi_spas_12\",\n \"name\": \"Franchi SPAS-12\",\n \"maker\": \"Franchi\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\",\n \"semi\"\n ],\n \"magazine\": 8,\n \"chamber\": 1,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 2.72,\n 0.68\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 55\n },\n \"mass\": 4.4,\n \"dimensions\": {\n \"length\": 1.041,\n \"barrel\": 0.546,\n \"emptyMass\": 4.4\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"kel_tec_ksg\",\n \"name\": \"Kel-Tec KSG\",\n \"maker\": \"Kel-Tec\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 120,\n \"modes\": [\n \"pump\"\n ],\n \"magazine\": 14,\n \"chamber\": 1,\n \"tubes\": 2,\n \"reload\": 0.55,\n \"perRound\": true,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3.85,\n 0.96\n ],\n \"range\": 40,\n \"family\": \"pump\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.55,\n \"perRound\": 0.55,\n \"cycle\": 0.5,\n \"clear\": 1.2\n },\n \"patternCm\": 60\n },\n \"mass\": 3.1,\n \"dimensions\": {\n \"length\": 0.66,\n \"barrel\": 0.47,\n \"emptyMass\": 3.1\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"saiga_12\",\n \"name\": \"Saiga-12\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 8,\n \"magazineOptions\": [\n 20\n ],\n \"reload\": 2.8,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 3,\n 0.88\n ],\n \"range\": 40,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.8,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.3,\n \"patternCm\": 65\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.43,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"shotgun_semi_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"aa_12\",\n \"name\": \"AA-12\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 300,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 8,\n \"magazineOptions\": [\n 20\n ],\n \"reload\": 3,\n \"muzzleSpeed\": 400,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 2.08,\n 0.61\n ],\n \"range\": 40,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3,\n \"clear\": 1.2\n },\n \"patternCm\": 65\n },\n \"mass\": 5.2,\n \"dimensions\": {\n \"length\": 0.966,\n \"barrel\": 0.457,\n \"emptyMass\": 5.2\n },\n \"archetype\": \"shotgun_semi_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"boito_double_barrel\",\n \"name\": \"Boito double-barrel\",\n \"category\": \"shotgun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"12ga_00buck\",\n \"rpm\": 180,\n \"modes\": [\n \"break\",\n \"volley\"\n ],\n \"magazine\": 2,\n \"reload\": 2,\n \"muzzleSpeed\": 410,\n \"spreadDeg\": 1,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 3,\n \"pelletSpreadDeg\": 3,\n \"recoil\": [\n 4.14,\n 1.1\n ],\n \"range\": 35,\n \"family\": \"break\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"patternCm\": 45\n },\n \"mass\": 3.2,\n \"dimensions\": {\n \"length\": 1.13,\n \"barrel\": 0.71,\n \"emptyMass\": 3.2\n },\n \"archetype\": \"shotgun_double_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"ak_47\",\n \"name\": \"AK-47\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 715,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.29,\n 0.69\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.4,\n \"moa\": 4\n },\n \"mass\": 4.3,\n \"dimensions\": {\n \"length\": 0.88,\n \"barrel\": 0.415,\n \"emptyMass\": 4.3\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"akm\",\n \"name\": \"AKM\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 715,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.54,\n 0.82\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.45,\n \"moa\": 4\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.88,\n \"barrel\": 0.415,\n \"emptyMass\": 3.1\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"ak_74\",\n \"name\": \"AK-74\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_45x39\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.6,\n \"muzzleSpeed\": 900,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.81,\n 0.49\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3.3,\n \"dimensions\": {\n \"length\": 0.943,\n \"barrel\": 0.415,\n \"emptyMass\": 3.3\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"ak_12\",\n \"name\": \"AK-12\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_45x39\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.5,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.73,\n 0.44\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.5,\n \"reloadEmpty\": 3.3,\n \"clear\": 1.2\n },\n \"moa\": 2.5\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 0.945,\n \"barrel\": 0.415,\n \"emptyMass\": 3.5,\n \"lengthCollapsed\": 0.725\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"imbel_ia2\",\n \"name\": \"IMBEL IA2\",\n \"maker\": \"IMBEL\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 700,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 860,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.85,\n 0.51\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3.4,\n \"dimensions\": {\n \"length\": 0.85,\n \"barrel\": 0.33,\n \"emptyMass\": 3.4\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"taurus_t4\",\n \"name\": \"Taurus T4\",\n \"maker\": \"Taurus\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 750,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.84,\n \"barrel\": 0.368,\n \"emptyMass\": 3\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"colt_m4a1\",\n \"name\": \"Colt M4A1\",\n \"maker\": \"Colt\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 800,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.3,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1,\n 0.6\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.84,\n \"barrel\": 0.368,\n \"emptyMass\": 2.9,\n \"lengthCollapsed\": 0.757\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"colt_m16a2\",\n \"name\": \"Colt M16A2\",\n \"maker\": \"Colt\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 800,\n \"modes\": [\n \"semi\",\n \"burst\"\n ],\n \"burst\": 3,\n \"magazine\": 30,\n \"reload\": 2.4,\n \"muzzleSpeed\": 948,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1.03,\n 0.62\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"reloadEmpty\": 3.1,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3.4,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.508,\n \"emptyMass\": 3.4\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"hk416\",\n \"name\": \"HK416\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.3,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.86,\n 0.52\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.3,\n \"reloadEmpty\": 3,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 3.5,\n \"dimensions\": {\n \"length\": 0.9,\n \"barrel\": 0.368,\n \"emptyMass\": 3.5,\n \"lengthCollapsed\": 0.8\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"steyr_aug_a1\",\n \"name\": \"Steyr AUG A1\",\n \"maker\": \"Steyr\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 680,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 30,\n \"reload\": 2.8,\n \"muzzleSpeed\": 970,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 1.02,\n 0.61\n ],\n \"range\": 400,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.8,\n \"reloadEmpty\": 3.4,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.79,\n \"barrel\": 0.508,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"fn_fal\",\n \"name\": \"FN FAL\",\n \"maker\": \"FN\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 840,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 2.16,\n 1.15\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.5,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 4.3,\n \"dimensions\": {\n \"length\": 1.09,\n \"barrel\": 0.533,\n \"emptyMass\": 4.3\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"hk_g3a3\",\n \"name\": \"HK G3A3\",\n \"maker\": \"HK\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 550,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 800,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.91,\n 1.02\n ],\n \"range\": 350,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.6,\n \"clear\": 1.2\n },\n \"moa\": 2.5\n },\n \"mass\": 4.4,\n \"dimensions\": {\n \"length\": 1.025,\n \"barrel\": 0.45,\n \"emptyMass\": 4.4\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"sks\",\n \"name\": \"SKS\",\n \"category\": \"rifle\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x39\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.2,\n \"muzzleSpeed\": 735,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.54,\n 0.82\n ],\n \"range\": 350,\n \"family\": \"top_load_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.2,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3.8,\n \"dimensions\": {\n \"length\": 1.02,\n \"barrel\": 0.52,\n \"emptyMass\": 3.85\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"m14_ebr\",\n \"name\": \"M14 EBR\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.8,\n \"muzzleSpeed\": 850,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.13,\n 0.36\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.8,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 5.1,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.457,\n \"emptyMass\": 5.1\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"svd_dragunov\",\n \"name\": \"SVD Dragunov\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x54r\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 2.9,\n \"muzzleSpeed\": 830,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.39,\n 0.4\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.9,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 4.3,\n \"dimensions\": {\n \"length\": 1.225,\n \"barrel\": 0.62,\n \"emptyMass\": 4.3\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"fn_scar_h\",\n \"name\": \"FN SCAR-H\",\n \"maker\": \"FN\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 600,\n \"modes\": [\n \"auto\",\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.6,\n \"muzzleSpeed\": 770,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.48,\n 0.41\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.6,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 0.965,\n \"barrel\": 0.4,\n \"emptyMass\": 3.6,\n \"lengthCollapsed\": 0.71\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"knights_sr_25_mk11\",\n \"name\": \"Knight's SR-25 (Mk 11)\",\n \"maker\": \"Knight's\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 20,\n \"reload\": 2.7,\n \"muzzleSpeed\": 800,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.14,\n 0.36\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"clear\": 1.2\n },\n \"moa\": 1\n },\n \"mass\": 4.5,\n \"dimensions\": {\n \"length\": 1.156,\n \"barrel\": 0.508,\n \"emptyMass\": 4.5\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"hk_psg_1\",\n \"name\": \"HK PSG-1\",\n \"maker\": \"HK\",\n \"category\": \"dmr\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 120,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 5,\n \"magazineOptions\": [\n 20\n ],\n \"reload\": 2.7,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 1.51,\n 0.25\n ],\n \"range\": 800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.7,\n \"reloadEmpty\": 3.6,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.7\n },\n \"mass\": 7.2,\n \"dimensions\": {\n \"length\": 1.208,\n \"barrel\": 0.65,\n \"emptyMass\": 7.2\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"steyr_ssg_69\",\n \"name\": \"Steyr SSG 69\",\n \"maker\": \"Steyr\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.79,\n 0.47\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"faultFactor\": 0.6\n },\n \"mass\": 3.9,\n \"dimensions\": {\n \"length\": 1.14,\n \"barrel\": 0.65,\n \"emptyMass\": 3.9\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"barrett_mrad\",\n \"name\": \"Barrett MRAD\",\n \"maker\": \"Barrett\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 10,\n \"reload\": 3.2,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 3.85,\n 0.6\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3.2,\n \"cycle\": 0.82,\n \"clear\": 1.2\n }\n },\n \"mass\": 6.9,\n \"dimensions\": {\n \"length\": 1.26,\n \"barrel\": 0.686,\n \"emptyMass\": 6.9\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"cheytac_m200\",\n \"name\": \"CheyTac M200\",\n \"maker\": \"CheyTac\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"408cheytac\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 7,\n \"reload\": 3.2,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 3.16,\n 0.49\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3.2,\n \"cycle\": 0.82,\n \"clear\": 1.2\n }\n },\n \"mass\": 14,\n \"dimensions\": {\n \"length\": 1.397,\n \"barrel\": 0.737,\n \"emptyMass\": 14\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"remington_700\",\n \"name\": \"Remington 700\",\n \"maker\": \"Remington\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 4,\n \"reload\": 0.7,\n \"perRound\": true,\n \"muzzleSpeed\": 790,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.35,\n 0.39\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.1,\n \"barrel\": 0.61,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"m24_sws\",\n \"name\": \"M24 SWS\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 0.7,\n \"perRound\": true,\n \"muzzleSpeed\": 790,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 1.74,\n 0.29\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 0.75\n },\n \"mass\": 5.4,\n \"dimensions\": {\n \"length\": 1.092,\n \"barrel\": 0.61,\n \"emptyMass\": 5.4\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"mosin_nagant_91_30\",\n \"name\": \"Mosin-Nagant 91/30\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x54r\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 2.4,\n \"muzzleSpeed\": 865,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.79,\n 0.46\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2.4,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 2.5\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.232,\n \"barrel\": 0.73,\n \"emptyMass\": 4\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"accuracy_awm\",\n \"name\": \"Accuracy AWM\",\n \"maker\": \"Accuracy\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3.2,\n \"muzzleSpeed\": 936,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.13,\n 0.64\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3.2,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 0.5\n },\n \"mass\": 6.9,\n \"dimensions\": {\n \"length\": 1.23,\n \"barrel\": 0.686,\n \"emptyMass\": 6.9\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"sako_trg_42\",\n \"name\": \"Sako TRG-42\",\n \"maker\": \"Sako\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"338lapua\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 5,\n \"reload\": 3,\n \"muzzleSpeed\": 900,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 5.17,\n 0.8\n ],\n \"range\": 1500,\n \"family\": \"bolt_magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 3,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 0.5\n },\n \"mass\": 5.1,\n \"dimensions\": {\n \"length\": 1.2,\n \"barrel\": 0.69,\n \"emptyMass\": 5.1\n },\n \"archetype\": \"sniper_338\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"barrett_m82a1\",\n \"name\": \"Barrett M82A1\",\n \"maker\": \"Barrett\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 30,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 4,\n \"muzzleSpeed\": 853,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 4.82,\n 0.83\n ],\n \"range\": 1800,\n \"family\": \"magazine\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 4,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 14,\n \"dimensions\": {\n \"length\": 1.448,\n \"barrel\": 0.737,\n \"emptyMass\": 14\n },\n \"archetype\": \"anti_materiel_50\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"ruger_10_22\",\n \"name\": \"Ruger 10/22\",\n \"maker\": \"Ruger\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"magazineOptions\": [\n 25\n ],\n \"reload\": 1.9,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.25,\n 0.09\n ],\n \"range\": 80,\n \"family\": \"top_load_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 2.3,\n \"dimensions\": {\n \"length\": 0.94,\n \"barrel\": 0.47,\n \"emptyMass\": 2.3\n },\n \"archetype\": \"carbine_22\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"cbc_7022\",\n \"name\": \"CBC 7022\",\n \"maker\": \"CBC\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 300,\n \"modes\": [\n \"semi\"\n ],\n \"magazine\": 10,\n \"reload\": 1.9,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.29,\n 0.11\n ],\n \"range\": 80,\n \"family\": \"top_load_semi\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 2,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.53,\n \"emptyMass\": 2\n },\n \"archetype\": \"carbine_22\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"cbc_122\",\n \"name\": \"CBC 122\",\n \"maker\": \"CBC\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"22lr\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 10,\n \"reload\": 1.9,\n \"muzzleSpeed\": 380,\n \"spreadDeg\": 0.5,\n \"bloomDeg\": 0.15,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.24,\n 0.09\n ],\n \"range\": 80,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.9,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 2.4,\n \"dimensions\": {\n \"length\": 1.03,\n \"barrel\": 0.59,\n \"emptyMass\": 2.4\n },\n \"archetype\": \"carbine_22\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"winchester_1894\",\n \"name\": \"Winchester 1894\",\n \"maker\": \"Winchester\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"30_30\",\n \"rpm\": 109.09,\n \"modes\": [\n \"lever\"\n ],\n \"magazine\": 7,\n \"reload\": 0.6,\n \"perRound\": true,\n \"muzzleSpeed\": 670,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 2.25,\n 0.38\n ],\n \"range\": 800,\n \"family\": \"lever\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.6,\n \"perRound\": 0.6,\n \"cycle\": 0.55,\n \"clear\": 1.2\n },\n \"moa\": 3\n },\n \"mass\": 3,\n \"dimensions\": {\n \"length\": 0.965,\n \"barrel\": 0.508,\n \"emptyMass\": 3\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"rossi_puma\",\n \"name\": \"Rossi Puma\",\n \"maker\": \"Rossi\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"357mag\",\n \"rpm\": 109.09,\n \"modes\": [\n \"lever\"\n ],\n \"magazine\": 10,\n \"reload\": 0.5,\n \"perRound\": true,\n \"muzzleSpeed\": 500,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 1.47,\n 0.24\n ],\n \"range\": 800,\n \"family\": \"lever\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.5,\n \"perRound\": 0.5,\n \"cycle\": 0.55,\n \"clear\": 1.2\n },\n \"moa\": 3,\n \"acceptsCalibers\": [\n \"38spl\"\n ]\n },\n \"mass\": 2.7,\n \"dimensions\": {\n \"length\": 0.95,\n \"barrel\": 0.508,\n \"emptyMass\": 2.7\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"hunting_rifle_30_06\",\n \"name\": \".30-06 hunting rifle\",\n \"category\": \"hunting\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"30_06\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 4,\n \"reload\": 0.7,\n \"perRound\": true,\n \"muzzleSpeed\": 880,\n \"spreadDeg\": 0.25,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 3,\n \"recoil\": [\n 3.24,\n 0.54\n ],\n \"range\": 800,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1.5\n },\n \"mass\": 3.6,\n \"dimensions\": {\n \"length\": 1.1,\n \"barrel\": 0.56,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"rifle_bolt_308\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"fn_minimi\",\n \"name\": \"FN Minimi\",\n \"maker\": \"FN\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"5_56x45\",\n \"rpm\": 850,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 200,\n \"reload\": 7.5,\n \"muzzleSpeed\": 915,\n \"spreadDeg\": 0.6,\n \"bloomDeg\": 0.25,\n \"recoveryDegPerS\": 5,\n \"recoil\": [\n 0.46,\n 0.28\n ],\n \"range\": 400,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 7.5,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 7.1,\n \"dimensions\": {\n \"length\": 1.04,\n \"barrel\": 0.465,\n \"emptyMass\": 7.1\n },\n \"archetype\": \"rifle_5_56\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"pkm\",\n \"name\": \"PKM\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x54r\",\n \"rpm\": 650,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 8,\n \"muzzleSpeed\": 825,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 1.18,\n 0.63\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8,\n \"clear\": 1.2\n },\n \"moa\": 4\n },\n \"mass\": 7.5,\n \"dimensions\": {\n \"length\": 1.173,\n \"barrel\": 0.658,\n \"emptyMass\": 7.5\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"m60\",\n \"name\": \"M60\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"7_62x51\",\n \"rpm\": 550,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 8.5,\n \"muzzleSpeed\": 853,\n \"spreadDeg\": 0.8,\n \"bloomDeg\": 0.35,\n \"recoveryDegPerS\": 4.5,\n \"recoil\": [\n 0.91,\n 0.49\n ],\n \"range\": 350,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 8.5,\n \"clear\": 1.2\n },\n \"faultFactor\": 1.3,\n \"moa\": 4\n },\n \"mass\": 10.5,\n \"dimensions\": {\n \"length\": 1.105,\n \"barrel\": 0.56,\n \"emptyMass\": 10.5\n },\n \"archetype\": \"rifle_7_62x39\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"browning_m2\",\n \"name\": \"Browning M2 .50\",\n \"maker\": \"Browning\",\n \"category\": \"machine_gun\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"50bmg\",\n \"rpm\": 550,\n \"modes\": [\n \"auto\"\n ],\n \"magazine\": 100,\n \"reload\": 10,\n \"muzzleSpeed\": 890,\n \"spreadDeg\": 0.15,\n \"bloomDeg\": 0.5,\n \"recoveryDegPerS\": 2,\n \"recoil\": [\n 1.93,\n 0.33\n ],\n \"range\": 1800,\n \"family\": \"belt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 10,\n \"clear\": 1.2\n },\n \"moa\": 2\n },\n \"mass\": 38,\n \"dimensions\": {\n \"length\": 1.65,\n \"barrel\": 1.14,\n \"emptyMass\": 38\n },\n \"archetype\": \"anti_materiel_50\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\"\n ]\n },\n {\n \"id\": \"remington_700_300wm\",\n \"name\": \"Remington 700 (.300 WM)\",\n \"maker\": \"Remington\",\n \"category\": \"sniper\",\n \"action\": {\n \"kind\": \"firearm\",\n \"caliber\": \"300wm\",\n \"rpm\": 73.17,\n \"modes\": [\n \"bolt\"\n ],\n \"magazine\": 3,\n \"reload\": 0.7,\n \"perRound\": true,\n \"spreadDeg\": 0.1,\n \"bloomDeg\": 0.3,\n \"recoveryDegPerS\": 2.5,\n \"recoil\": [\n 4.76,\n 0.74\n ],\n \"range\": 1500,\n \"family\": \"bolt\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 0.7,\n \"perRound\": 0.7,\n \"cycle\": 0.82,\n \"clear\": 1.2\n },\n \"moa\": 1\n },\n \"mass\": 4,\n \"dimensions\": {\n \"length\": 1.1,\n \"barrel\": 0.61,\n \"emptyMass\": 3.6\n },\n \"archetype\": \"sniper_338\",\n \"variantOf\": \"remington_700\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"m79\",\n \"name\": \"M79 grenade launcher\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"m79_40mm\",\n \"magazine\": 1,\n \"reload\": 2,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 2,\n \"clear\": 1.2\n },\n \"family\": \"break\",\n \"speed\": 76,\n \"minArmDistance\": 10,\n \"backblast\": 0,\n \"recoil\": [\n 4.5,\n 1.2\n ]\n },\n \"mass\": 2.93,\n \"dimensions\": {\n \"length\": 0.73,\n \"barrel\": 0.356,\n \"emptyMass\": 2.7\n },\n \"archetype\": \"shotgun_double_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n }\n]\n","[\n {\n \"id\": \"rpg_7\",\n \"name\": \"RPG-7\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"pg7v\",\n \"magazine\": 1,\n \"reload\": 4.5,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 4.5,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"speed\": 117,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 4,\n 1\n ]\n },\n \"mass\": 6.3,\n \"dimensions\": {\n \"length\": 0.95,\n \"barrel\": 0.95,\n \"emptyMass\": 6.3\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"arsenal\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"m72_law\",\n \"name\": \"M72 LAW\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"m72_66mm\",\n \"magazine\": 1,\n \"reload\": 1.15,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.15,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"disposable\": true,\n \"speed\": 145,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 2.75,\n 0.69\n ]\n },\n \"mass\": 2.5,\n \"dimensions\": {\n \"length\": 0.881,\n \"barrel\": 0.881,\n \"emptyMass\": 2.5\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"at4\",\n \"name\": \"AT4\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"at4_84mm\",\n \"magazine\": 1,\n \"reload\": 1.15,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.15,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"disposable\": true,\n \"speed\": 285,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 3.25,\n 0.81\n ]\n },\n \"mass\": 6.7,\n \"dimensions\": {\n \"length\": 1.02,\n \"barrel\": 1.02,\n \"emptyMass\": 6.7\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"carl_gustaf_m4\",\n \"name\": \"Carl Gustaf M4\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"launcher\",\n \"projectile\": \"carl_gustaf_84mm\",\n \"magazine\": 1,\n \"reload\": 1.05,\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.05,\n \"clear\": 1.2\n },\n \"family\": \"rocket\",\n \"speed\": 255,\n \"minArmDistance\": 10,\n \"backblast\": 5,\n \"backblastHalfAngleDeg\": 19,\n \"recoil\": [\n 3.5,\n 0.87\n ]\n },\n \"mass\": 6.6,\n \"dimensions\": {\n \"length\": 0.95,\n \"barrel\": 0.95,\n \"emptyMass\": 6.6\n },\n \"archetype\": \"shotgun_pump_12\",\n \"sources\": [\n \"gallery\",\n \"reference\",\n \"derived\"\n ]\n },\n {\n \"id\": \"m2_flamethrower\",\n \"name\": \"M2 flamethrower\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 6,\n \"fuelPerSecond\": 1,\n \"fuel\": 9,\n \"cone\": true,\n \"noise\": 20,\n \"family\": \"flame\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.1,\n \"clear\": 1.2\n }\n },\n \"mass\": 32,\n \"dimensions\": {\n \"length\": 1,\n \"barrel\": 0.62,\n \"emptyMass\": 32\n },\n \"archetype\": \"flamethrower\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n },\n {\n \"id\": \"improvised_flamethrower\",\n \"name\": \"Improvised flamethrower\",\n \"category\": \"launcher\",\n \"action\": {\n \"kind\": \"flame\",\n \"temperature\": 900,\n \"radius\": 0.6,\n \"range\": 3.6,\n \"fuelPerSecond\": 1,\n \"fuel\": 5,\n \"cone\": true,\n \"noise\": 20,\n \"family\": \"flame\",\n \"timings\": {\n \"draw\": 0.35,\n \"reload\": 1.1,\n \"clear\": 1.2\n }\n },\n \"mass\": 6,\n \"dimensions\": {\n \"length\": 0.8,\n \"barrel\": 0.66,\n \"emptyMass\": 6\n },\n \"archetype\": \"flamethrower\",\n \"sources\": [\n \"gallery\",\n \"sdk\",\n \"derived\"\n ]\n }\n]\n","import type { CaliberDef, CaliberId, ExplosiveDef, ExplosiveId, WeaponDef, WeaponId, WeaponRules } from './types'\n\nexport interface ArsenalParts {\n readonly weapons: ReadonlyMap<WeaponId, WeaponDef>\n readonly calibers: ReadonlyMap<CaliberId, CaliberDef>\n readonly explosives: ReadonlyMap<ExplosiveId, ExplosiveDef>\n /** When given, the default condition and ammunition quality must be ones the rules define. */\n readonly rules?: Pick<WeaponRules, 'conditions' | 'defaultCondition' | 'ammoQualities' | 'defaultAmmoQuality'>\n}\n\n/** Ids that appear more than once in a list a game passed in. */\nexport const findDuplicateIds = (kind: string, entries: readonly { readonly id: string }[] | undefined): string[] => {\n const seen = new Set<string>()\n const problems: string[] = []\n for (const { id } of entries ?? []) {\n if (seen.has(id)) problems.push(`${kind} \"${id}\" is listed more than once`)\n seen.add(id)\n }\n return problems\n}\n\nconst checkFirearm = (def: WeaponDef, calibers: ArsenalParts['calibers']): string[] => {\n if (def.action.kind !== 'firearm') return []\n const problems: string[] = []\n for (const caliber of [def.action.caliber, ...(def.action.acceptsCalibers ?? [])]) {\n if (!calibers.has(caliber)) problems.push(`weapon \"${def.id}\" uses unknown calibre \"${caliber}\"`)\n }\n if (def.action.modes.length === 0) problems.push(`weapon \"${def.id}\" has no fire modes`)\n if (!(def.action.rpm > 0)) problems.push(`weapon \"${def.id}\" has a rate of fire of ${def.action.rpm} rpm`)\n if (!(def.action.reload > 0)) problems.push(`weapon \"${def.id}\" has a reload time of ${def.action.reload} s`)\n return problems\n}\n\nconst checkTimings = (def: WeaponDef): string[] => {\n const timings = 'timings' in def.action ? def.action.timings : undefined\n return Object.entries(timings ?? {})\n .filter(([, seconds]) => typeof seconds === 'number' && !(seconds > 0))\n .map(([name, seconds]) => `weapon \"${def.id}\" has a ${name} time of ${seconds} s`)\n}\n\nconst checkExplosiveReference = (def: WeaponDef, explosives: ArsenalParts['explosives']): string[] => {\n const id = def.action.kind === 'launcher' ? def.action.projectile : def.action.kind === 'throwable' ? def.action.explosive : undefined\n return id !== undefined && !explosives.has(id) ? [`weapon \"${def.id}\" uses unknown explosive \"${id}\"`] : []\n}\n\nconst checkExplosiveNumbers = (explosive: ExplosiveDef): string[] => {\n const problems: string[] = []\n const [low, high] = explosive.fuseRange ?? [1, 1]\n if (!(low > 0 && high >= low)) problems.push(`explosive \"${explosive.id}\" has a fuse range of ${low} to ${high} s`)\n if (explosive.fuseLength !== undefined && !(explosive.fuseLength > 0)) problems.push(`explosive \"${explosive.id}\" has a fuse length of ${explosive.fuseLength} m`)\n if (explosive.burnRate !== undefined && !(explosive.burnRate > 0)) problems.push(`explosive \"${explosive.id}\" has a burn rate of ${explosive.burnRate} s/m`)\n if (explosive.burnTolerance !== undefined && !(explosive.burnTolerance >= 0 && explosive.burnTolerance < 1)) problems.push(`explosive \"${explosive.id}\" has a burn tolerance of ${explosive.burnTolerance}`)\n if (explosive.tripwire && !(explosive.tripwire.length > 0)) problems.push(`explosive \"${explosive.id}\" has a trip wire of ${explosive.tripwire.length} m`)\n return problems\n}\n\nconst checkRuleDefaults = (rules: ArsenalParts['rules']): string[] => {\n if (!rules) return []\n const problems: string[] = []\n if (!rules.conditions.some((condition) => condition.id === rules.defaultCondition)) problems.push(`the default condition \"${rules.defaultCondition}\" is not one of the conditions`)\n if (!rules.ammoQualities.some((quality) => quality.id === rules.defaultAmmoQuality)) problems.push(`the default ammunition quality \"${rules.defaultAmmoQuality}\" is not one of the qualities`)\n return problems\n}\n\n/** Every problem found in an arsenal, so a game sees them all at once instead of one per run. Empty when it is consistent. */\nexport const checkArsenal = ({ weapons, calibers, explosives, rules }: ArsenalParts): string[] => [\n ...[...weapons.values()].flatMap((def) => [...checkFirearm(def, calibers), ...checkTimings(def), ...checkExplosiveReference(def, explosives)]),\n ...[...explosives.values()].flatMap(checkExplosiveNumbers),\n ...checkRuleDefaults(rules),\n]\n","type PlainObject = Record<string, unknown>\n\n/** Keys that would reach the prototype of the result when a patch comes from parsed JSON. */\nconst UNSAFE_KEYS: ReadonlySet<string> = new Set(['__proto__', 'constructor', 'prototype'])\n\nconst isPlainObject = (value: unknown): value is PlainObject =>\n typeof value === 'object' && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype\n\n/** Merges `patch` over `base`: plain objects merge field by field, arrays, functions and primitives replace. `undefined` in the patch is ignored. */\nexport const deepMerge = <TBase extends object>(base: TBase, patch: object | undefined): TBase => {\n if (!patch) return base\n const result: PlainObject = { ...(base as PlainObject) }\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined || UNSAFE_KEYS.has(key)) continue\n const current = result[key]\n result[key] = isPlainObject(current) && isPlainObject(value) ? deepMerge(current, value) : value\n }\n return result as TBase\n}\n","import { deepMerge } from './merge'\nimport type { DeepPartial } from './types'\n\n/** Locales shipped with the package. Unknown locales fall back to `en`. */\nexport type WeaponsLocale = 'en' | 'pt-BR'\n\nexport interface WeaponsStrings {\n /** Display name of each weapon id. */\n weapons: Record<string, string>\n /** Display name of each fire mode. */\n modes: Record<string, string>\n /** Display name of each weapon category. */\n categories: Record<string, string>\n /** Display name of each explosive id. */\n explosives: Record<string, string>\n /** Display name of each weapon fault. */\n faults: Record<string, string>\n /** Display name of each weapon condition. */\n conditions: Record<string, string>\n}\n\nconst modesEn = { single: 'single action', semi: 'semi-automatic', burst: 'burst', auto: 'automatic', pump: 'pump action', bolt: 'bolt action', lever: 'lever action', break: 'break action', volley: 'volley' }\nconst categoriesEn = {\n pistol: 'pistol', revolver: 'revolver', smg: 'submachine gun', rifle: 'rifle', carbine: 'carbine', sniper: 'sniper rifle', shotgun: 'shotgun',\n bow: 'bow', crossbow: 'crossbow', melee_blunt: 'blunt melee', melee_blade: 'bladed melee', flame: 'flame', heat: 'heat', throwable: 'throwable',\n tool: 'tool', extinguisher: 'extinguisher', hand: 'hand', dmr: 'marksman rifle', hunting: 'hunting rifle', machine_gun: 'machine gun', launcher: 'launcher',\n}\nconst faultsEn = { misfire: 'misfire', stovepipe: 'stovepipe', double_feed: 'double feed', failure_to_extract: 'failure to extract' }\nconst conditionsEn = { new: 'new', used: 'used', worn: 'worn', rusty: 'rusty' }\n\nexport const locales: Record<WeaponsLocale, WeaponsStrings> = {\n en: {\n weapons: {\n hand: 'Hand', kick: 'Kick', shove: 'Shove', pistol_9mm: '9 mm service pistol', pistol_45: '.45 ACP pistol', pistol_22: '.22 LR pistol', revolver_357: '.357 Magnum revolver',\n revolver_38: '.38 Special revolver', smg_9mm: '9 mm submachine gun', carbine_22: '.22 LR carbine', rifle_5_56: '5.56 mm assault rifle',\n rifle_7_62x39: '7.62×39 mm assault rifle', rifle_bolt_308: '.308 bolt-action rifle', sniper_338: '.338 Lapua sniper rifle',\n anti_materiel_50: '.50 BMG anti-materiel rifle', shotgun_pump_12: '12 gauge pump-action shotgun', shotgun_double_12: '12 gauge double-barrel shotgun',\n shotgun_semi_12: '12 gauge semi-automatic shotgun', bow_compound: 'Compound bow', crossbow: 'Crossbow', hammer: 'Hammer', sledgehammer: 'Sledgehammer',\n baseball_bat: 'Baseball bat', crowbar: 'Crowbar', machete: 'Machete', axe: 'Axe', knife: 'Knife', fists: 'Fists', lighter: 'Lighter',\n flamethrower: 'Flamethrower', molotov: 'Molotov cocktail', cutting_torch: 'Oxy-fuel cutting torch', blowtorch: 'Blowtorch',\n frag_grenade: 'Fragmentation grenade', pipe_bomb: 'Pipe bomb', screwdriver: 'Screwdriver', wrench: 'Wrench', pry_bar: 'Pry bar', hacksaw: 'Hacksaw',\n utility_knife: 'Utility knife', claw_hammer: 'Claw hammer', extinguisher: 'Fire extinguisher',\n },\n modes: modesEn,\n categories: categoriesEn,\n explosives: {},\n faults: faultsEn,\n conditions: conditionsEn,\n },\n 'pt-BR': {\n weapons: {\n hand: 'mão', kick: 'chute', shove: 'empurrão', pistol_9mm: 'pistola 9 mm', pistol_45: 'pistola .45', pistol_22: 'pistola .22', revolver_357: 'revólver .357', revolver_38: 'revólver .38',\n smg_9mm: 'submetralhadora 9 mm', carbine_22: 'carabina .22', rifle_5_56: 'fuzil 5,56', rifle_7_62x39: 'fuzil 7,62×39', rifle_bolt_308: 'fuzil de ferrolho .308',\n sniper_338: 'fuzil de precisão .338', anti_materiel_50: 'fuzil antimaterial .50', shotgun_pump_12: 'espingarda de repetição calibre 12',\n shotgun_double_12: 'espingarda de dois canos calibre 12', shotgun_semi_12: 'espingarda semiautomática calibre 12', bow_compound: 'arco composto',\n crossbow: 'besta', hammer: 'martelo', sledgehammer: 'marreta', baseball_bat: 'taco de beisebol', crowbar: 'pé de cabra', machete: 'facão', axe: 'machado',\n knife: 'faca', fists: 'punhos', lighter: 'isqueiro', flamethrower: 'lança-chamas', molotov: 'coquetel molotov', cutting_torch: 'maçarico de corte',\n blowtorch: 'maçarico', frag_grenade: 'granada de fragmentação', pipe_bomb: 'bomba caseira', screwdriver: 'chave de fenda', wrench: 'chave inglesa',\n pry_bar: 'alavanca', hacksaw: 'serra de arco', utility_knife: 'estilete', claw_hammer: 'martelo de unha', extinguisher: 'extintor',\n boito_double_barrel: 'Boito (2 canos)', hunting_rifle_30_06: 'Rifle de caça .30-06', m2_flamethrower: 'Lança-chamas M2', improvised_flamethrower: 'Lança-chamas caseiro',\n m79: 'Lança-granadas M79',\n },\n modes: { single: 'tiro único', semi: 'semiautomático', burst: 'rajada', auto: 'automático', pump: 'repetição', bolt: 'ferrolho', lever: 'alavanca', break: 'basculante', volley: 'salva' },\n categories: {\n pistol: 'pistola', revolver: 'revólver', smg: 'submetralhadora', rifle: 'fuzil', carbine: 'carabina', sniper: 'fuzil de precisão', shotgun: 'espingarda',\n bow: 'arco', crossbow: 'besta', melee_blunt: 'corpo a corpo contundente', melee_blade: 'corpo a corpo cortante', flame: 'chama', heat: 'calor',\n throwable: 'arremessável', tool: 'ferramenta', extinguisher: 'extintor', hand: 'mão', dmr: 'fuzil de precisão semiautomático', hunting: 'arma de caça',\n machine_gun: 'metralhadora', launcher: 'lançador',\n },\n explosives: {\n m67: 'Granada M67', molotov: 'Coquetel molotov', pipe_bomb: 'Bomba caseira', propane_p13: 'Botijão de gás P13', dynamite: 'Dinamite', c4: 'C4 com detonador',\n claymore: 'Mina Claymore', flashbang: 'Granada de luz', m79_40mm: 'Granada de 40 mm', m72_66mm: 'Foguete HEAT de 66 mm', at4_84mm: 'Foguete HEAT de 84 mm',\n pg7v: 'Foguete PG-7V', carl_gustaf_84mm: 'Projétil de 84 mm (HE/HEAT)', fuel_barrel: 'Barril de combustível', car_fuel_tank: 'Tanque de combustível do carro',\n fuel_pump: 'Bomba de combustível', fuel_station_tank: 'Tanque do posto de gasolina',\n },\n faults: { misfire: 'nega', stovepipe: 'chaminé', double_feed: 'dupla alimentação', failure_to_extract: 'falha de extração' },\n conditions: { new: 'nova', used: 'usada', worn: 'gasta', rusty: 'enferrujada' },\n },\n}\n\nexport const resolveStrings = (locale: string | undefined, overrides?: DeepPartial<WeaponsStrings>): WeaponsStrings =>\n deepMerge(locales[(locale as WeaponsLocale) ?? 'en'] ?? locales.en, overrides)\n","import type { ExplosiveDef } from './explosive-types'\n\n/** The fuse of an explosive with no randomness: a fixed `fuse`, the burn of a safety fuse (length times rate), or the middle of `fuseRange`. */\nexport const nominalFuse = (explosive: ExplosiveDef, fuseLength?: number): number | undefined => {\n const length = fuseLength ?? explosive.fuseLength\n if (length !== undefined && explosive.burnRate !== undefined) return length * explosive.burnRate\n if (explosive.fuseRange) return (explosive.fuseRange[0] + explosive.fuseRange[1]) / 2\n return explosive.fuse\n}\n\n/**\n * The fuse of one throw. A safety fuse burns `fuseLength × burnRate` seconds, scattered by `burnTolerance` (a fraction, ±); `fuseRange` picks a time\n * between its two ends; a fixed `fuse` is returned as is. Draws from `random` only when the explosive is not fixed, so fixed ones leave the stream alone.\n */\nexport const sampleFuse = (explosive: ExplosiveDef, random: () => number, fuseLength?: number): number | undefined => {\n const length = fuseLength ?? explosive.fuseLength\n if (length !== undefined && explosive.burnRate !== undefined) {\n const tolerance = explosive.burnTolerance ?? 0\n return length * explosive.burnRate * (tolerance > 0 ? 1 + tolerance * (2 * random() - 1) : 1)\n }\n if (explosive.fuseRange) return explosive.fuseRange[0] + (explosive.fuseRange[1] - explosive.fuseRange[0]) * random()\n return explosive.fuse\n}\n","import { nominalFuse } from './fuse'\nimport { deepMerge } from './merge'\nimport type { DeepPartial, ExplosiveDef, WeaponDef } from './types'\n\ntype Entry = { readonly id: string }\n\n/** The shipped entries with the ones from `extra` added or, when the id exists, replaced. */\nexport const mergeById = <TEntry extends Entry>(shipped: readonly TEntry[], extra: readonly TEntry[] | undefined): Map<string, TEntry> => {\n const entries = new Map<string, TEntry>()\n for (const entry of [...shipped, ...(extra ?? [])]) entries.set(entry.id, entry)\n return entries\n}\n\n/** Applies `patch` by id; a patch for an id that does not exist is ignored. */\nexport const applyPatches = <TEntry extends Entry>(entries: Map<string, TEntry>, patches: Readonly<Record<string, DeepPartial<TEntry> | Partial<TEntry>>> | undefined): void => {\n for (const [id, patch] of Object.entries(patches ?? {})) {\n const entry = entries.get(id)\n if (entry) entries.set(id, deepMerge(entry, patch))\n }\n}\n\nexport const removeIds = (entries: Map<string, unknown>, ids: readonly string[] | undefined): void => {\n for (const id of ids ?? []) entries.delete(id)\n}\n\n/** A throwable that names an explosive takes its energy, noise, lethal radius, fuse (the nominal one, when it is sampled per throw) and fire from it, so changing the explosive changes the throwable. */\nexport const resolveThrowables = (weapons: Map<string, WeaponDef>, explosives: ReadonlyMap<string, ExplosiveDef>): void => {\n for (const [id, def] of weapons) {\n if (def.action.kind !== 'throwable' || def.action.explosive === undefined) continue\n const explosive = explosives.get(def.action.explosive)\n if (!explosive) continue\n const radius = explosive.lethalRadius > 0 ? explosive.lethalRadius : def.action.radius\n const fire = explosive.fire ? { ...explosive.fire } : def.action.fire\n weapons.set(id, { ...def, action: { ...def.action, energy: explosive.energy, noise: explosive.noise, radius, fuse: nominalFuse(explosive) ?? def.action.fuse, ...(fire ? { fire } : {}) } })\n }\n}\n","import type { FaultContext, WeaponRules } from './types'\n\nconst DEFAULT_HEAT: WeaponRules['heat'] = {\n cap: 140,\n displayMax: 120,\n decayBase: 1.6,\n decayPerPoint: 0.03,\n faultFrom: 60,\n faultSpan: 40,\n perShot: { shell: 6, big: 9, tiny: 1.2, pistol: 3, rifle: 4.5 },\n perRocket: 35,\n}\n\n/** Chance of a fault for one round: the wear of the weapon, scaled by its reliability and by how hot it is. */\nconst defaultFaultChance = (context: FaultContext): number => {\n const factor = context.def.action.kind === 'firearm' ? context.def.action.faultFactor ?? 1 : 1\n const overheat = 1 + Math.max(0, context.heat - DEFAULT_HEAT.faultFrom) / DEFAULT_HEAT.faultSpan\n return context.condition.faultChance * factor * overheat\n}\n\n/** The rules the kit ships with; a game overrides any of them through `ArsenalOptions.rules`. */\nexport const DEFAULT_RULES: WeaponRules = {\n faults: true,\n conditions: [\n { id: 'new', faultChance: 0.003 },\n { id: 'used', faultChance: 0.015 },\n { id: 'worn', faultChance: 0.05 },\n { id: 'rusty', faultChance: 0.12 },\n ],\n defaultCondition: 'new',\n ammoQualities: [\n { id: 'factory', faultChance: 0 },\n { id: 'reloaded', faultChance: 0.08 },\n ],\n defaultAmmoQuality: 'factory',\n faultChance: defaultFaultChance,\n heat: DEFAULT_HEAT,\n noiseBurst: { step: 0.05, window: 3, cap: 0.5 },\n // jogo.js (Jogo) explosionsUpdate 68300-68312: vy -= 9,8·dt; chão vy·-0,35 e vx,vz·0,6; parede v·-0,4\n explosives: { gravity: 9.8, groundRestitution: 0.35, groundFriction: 0.6, wallRestitution: 0.4, placeFuseFrom: 10, tripwire: { length: 10, angleDeg: 0, height: 0.15 } },\n draw: 0.35,\n clear: 1.2,\n startSafe: false,\n}\n","import type { Vec3 } from './types'\n\nexport const subtract = (a: Vec3, b: Vec3): Vec3 => [a[0] - b[0], a[1] - b[1], a[2] - b[2]]\n\nexport const dot = (a: Vec3, b: Vec3): number => a[0] * b[0] + a[1] * b[1] + a[2] * b[2]\n\nexport const length = (v: Vec3): number => Math.hypot(v[0], v[1], v[2])\n\nexport const distance = (a: Vec3, b: Vec3): number => length(subtract(a, b))\n\n/** `v` rotated 180° about the origin: the direction pointing away. */\nexport const negate = (v: Vec3): Vec3 => [0 - v[0], 0 - v[1], 0 - v[2]]\n","import { normalize } from './rng'\nimport type { ExplosiveDef, ExplosiveId, ExplosiveTrigger, Use, Vec3, WeaponRules } from './types'\nimport { distance, dot, length } from './vec'\n\nconst EPS = 1e-9\n\n/** Everything a host needs to apply a blast: where, how big, in which direction, and what else it does. */\nexport interface Detonation {\n readonly explosive: ExplosiveId\n readonly cause: ExplosiveTrigger\n readonly point: Vec3\n /** The way a directional charge faces; for everything else the direction the body was moving (or facing when placed). */\n readonly direction: Vec3\n /** Seconds on the clock of the body. */\n readonly at: number\n readonly energy: number\n readonly lethalRadius: number\n readonly injuryRadius: number\n readonly noise: number\n readonly destructionLevel: ExplosiveDef['destructionLevel']\n readonly cone?: ExplosiveDef['cone']\n readonly stunSeconds?: number\n readonly fire?: ExplosiveDef['fire']\n}\n\nexport type ExplosiveEvent =\n | { type: 'armed'; at: number; distance: number }\n | { type: 'impact'; at: number; point: Vec3; armed: boolean }\n /** Hit something before it was armed: it does not explode. */\n | { type: 'dud'; at: number; point: Vec3 }\n | { type: 'detonate'; at: number; detonation: Detonation }\n\n/** The first surface the segment `from` to `to` crosses: where, its normal and whether it is ground (default: normal pointing up). */\nexport type SurfaceProbe = (from: Vec3, to: Vec3) => { point: Vec3; normal: Vec3; ground?: boolean } | null\n\nexport interface ExplosiveBodyInit {\n readonly explosive: ExplosiveDef\n readonly origin: Vec3\n /** Initial velocity in m/s; absent for something set down. */\n readonly velocity?: Vec3\n /** Facing of a placed charge (the cone of a mine). */\n readonly direction?: Vec3\n /** `timer`: explodes `fuse` seconds after it leaves the hand; `impact`: explodes on the first hit once armed; `wire`/`remote`: waits for `trigger()`. */\n readonly triggers: readonly ExplosiveTrigger[]\n readonly fuse?: number\n /** Metres to fly before an impact sets it off (rockets); 0 arms it at once. */\n readonly armDistance?: number\n readonly rules: WeaponRules['explosives']\n}\n\nconst bounce = (velocity: Vec3, normal: Vec3, ground: boolean, rules: WeaponRules['explosives']): Vec3 => {\n const along = dot(velocity, normal)\n if (along >= 0) return velocity\n const restitution = ground ? rules.groundRestitution : rules.wallRestitution\n const friction = ground ? rules.groundFriction : 1\n const normalPart: Vec3 = [normal[0] * along, normal[1] * along, normal[2] * along]\n return [\n (velocity[0] - normalPart[0]) * friction - normalPart[0] * restitution,\n (velocity[1] - normalPart[1]) * friction - normalPart[1] * restitution,\n (velocity[2] - normalPart[2]) * friction - normalPart[2] * restitution,\n ]\n}\n\n/**\n * One explosive in flight or set down. `step` flies it (gravity, bounces off what `probe` finds) and counts the fuse; `trigger` sets off what waits\n * for a wire, a remote detonator, a bullet, fire or a nearby blast. Same inputs, same events: there is no randomness.\n */\nexport class ExplosiveBody {\n position: Vec3\n velocity: Vec3\n readonly explosive: ExplosiveDef\n private readonly triggers: ReadonlySet<ExplosiveTrigger>\n private readonly armDistance: number\n private readonly rules: WeaponRules['explosives']\n private facing: Vec3\n private clock = 0\n private flown = 0\n private fuseLeft: number | undefined\n private isArmed: boolean\n private isDone = false\n private isDud = false\n\n constructor(init: ExplosiveBodyInit) {\n this.explosive = init.explosive\n this.position = [init.origin[0], init.origin[1], init.origin[2]]\n this.velocity = init.velocity ? [init.velocity[0], init.velocity[1], init.velocity[2]] : [0, 0, 0]\n this.facing = normalize(init.direction ?? (init.velocity ? init.velocity : [0, 0, -1]))\n this.triggers = new Set(init.triggers)\n this.armDistance = init.armDistance ?? 0\n this.isArmed = this.armDistance <= 0\n this.fuseLeft = this.triggers.has('timer') ? init.fuse : undefined\n this.rules = init.rules\n }\n\n get age(): number {\n return this.clock\n }\n /** Metres flown so far. */\n get travelled(): number {\n return this.flown\n }\n get armed(): boolean {\n return this.isArmed\n }\n /** Exploded or turned out a dud: nothing more happens. */\n get done(): boolean {\n return this.isDone\n }\n get dud(): boolean {\n return this.isDud\n }\n /** Seconds until the timer sets it off, or undefined without one. */\n get fuseRemaining(): number | undefined {\n return this.fuseLeft\n }\n\n step(dt: number, probe?: SurfaceProbe): ExplosiveEvent[] {\n const events: ExplosiveEvent[] = []\n if (this.isDone) return events\n const seconds = Math.max(0, dt)\n const slice = this.fuseLeft === undefined ? seconds : Math.min(seconds, this.fuseLeft)\n this.fly(slice, probe, events)\n if (this.isDone) return events\n if (this.fuseLeft !== undefined) {\n this.fuseLeft -= slice\n if (this.fuseLeft <= EPS) events.push(this.detonate('timer'))\n }\n return events\n }\n\n /** Sets it off from outside; undefined when this explosive does not answer to `cause` or is already done. */\n trigger(cause: ExplosiveTrigger): ExplosiveEvent | undefined {\n if (this.isDone || !this.triggers.has(cause)) return undefined\n if (cause === 'impact' && !this.isArmed) return undefined\n return this.detonate(cause)\n }\n\n private moves(): boolean {\n return length(this.velocity) > EPS\n }\n\n private fly(seconds: number, probe: SurfaceProbe | undefined, events: ExplosiveEvent[]): void {\n if (seconds <= 0 || !this.moves()) {\n this.clock += Math.max(0, seconds)\n return\n }\n this.velocity = [this.velocity[0], this.velocity[1] - this.rules.gravity * seconds, this.velocity[2]]\n const next: Vec3 = [this.position[0] + this.velocity[0] * seconds, this.position[1] + this.velocity[1] * seconds, this.position[2] + this.velocity[2] * seconds]\n const hit = probe?.(this.position, next) ?? null\n const target = hit ? hit.point : next\n const moved = distance(this.position, target)\n const planned = distance(this.position, next)\n this.flown += moved\n this.position = [target[0], target[1], target[2]]\n const hitAt = this.clock + (hit && planned > EPS ? seconds * Math.min(1, moved / planned) : seconds)\n this.clock += seconds\n if (length(this.velocity) > EPS) this.facing = normalize(this.velocity)\n this.checkArmed(events)\n if (hit) this.onImpact(hit, hitAt, events)\n }\n\n private checkArmed(events: ExplosiveEvent[]): void {\n if (this.isArmed || this.flown < this.armDistance) return\n this.isArmed = true\n events.push({ type: 'armed', at: this.clock, distance: this.flown })\n }\n\n private onImpact(hit: NonNullable<ReturnType<SurfaceProbe>>, at: number, events: ExplosiveEvent[]): void {\n events.push({ type: 'impact', at, point: hit.point, armed: this.isArmed })\n if (this.triggers.has('impact')) {\n if (this.isArmed) events.push(this.detonate('impact', at))\n else {\n this.isDone = true\n this.isDud = true\n events.push({ type: 'dud', at, point: hit.point })\n }\n return\n }\n this.velocity = bounce(this.velocity, hit.normal, hit.ground ?? hit.normal[1] > 0.7, this.rules)\n }\n\n private detonate(cause: ExplosiveTrigger, at = this.clock): ExplosiveEvent {\n this.isDone = true\n const def = this.explosive\n const detonation: Detonation = {\n explosive: def.id,\n cause,\n point: [this.position[0], this.position[1], this.position[2]],\n direction: this.facing,\n at,\n energy: def.energy,\n lethalRadius: def.lethalRadius,\n injuryRadius: def.injuryRadius,\n noise: def.noise,\n destructionLevel: def.destructionLevel,\n ...(def.cone ? { cone: def.cone } : {}),\n ...(def.stunSeconds !== undefined ? { stunSeconds: def.stunSeconds } : {}),\n ...(def.fire ? { fire: def.fire } : {}),\n }\n return { type: 'detonate', at, detonation }\n }\n}\n\n/** The body of the explosive a `throw` or `place` use carries; undefined for any other use or an unknown explosive id. */\nexport const createExplosiveBody = (use: Use, explosives: ReadonlyMap<ExplosiveId, ExplosiveDef>, rules: WeaponRules['explosives']): ExplosiveBody | undefined => {\n if (use.kind === 'throw' && use.explosive !== undefined) {\n const explosive = explosives.get(use.explosive)\n if (!explosive) return undefined\n return new ExplosiveBody({\n explosive,\n origin: use.origin,\n velocity: use.velocity,\n triggers: [use.trigger ?? (use.fuse > 0 ? 'timer' : 'impact')],\n fuse: use.fuse,\n ...(use.armDistance !== undefined ? { armDistance: use.armDistance } : {}),\n rules,\n })\n }\n if (use.kind !== 'place') return undefined\n const explosive = explosives.get(use.explosive)\n if (!explosive) return undefined\n return new ExplosiveBody({ explosive, origin: use.origin, direction: use.direction, triggers: use.triggers, ...(use.fuse !== undefined ? { fuse: use.fuse } : {}), rules })\n}\n","import type { ExplosiveDef, Use, Vec3, WeaponAction, WeaponRules } from './types'\nimport { negate } from './vec'\n\ntype LauncherAction = Extract<WeaponAction, { kind: 'launcher' }>\ntype ThrowableAction = Extract<WeaponAction, { kind: 'throwable' }>\n\n/** Fraction of the throw speed added upwards so a throw arcs. */\nconst THROW_LIFT = 0.15\n\nconst PLACED_TRIGGERS: ReadonlySet<string> = new Set(['wire', 'remote'])\n\nconst blastNumbers = (explosive: ExplosiveDef): Pick<Extract<Use, { kind: 'throw' }>, 'energy' | 'injuryRadius'> => ({\n energy: explosive.energy,\n injuryRadius: explosive.injuryRadius,\n})\n\n/** The rocket or grenade a launcher fires, plus the blast behind the tube when the launcher has one. */\nexport const launcherUses = (action: LauncherAction, explosive: ExplosiveDef | null, origin: Vec3, direction: Vec3): Use[] => {\n const velocity: Vec3 = [direction[0] * action.speed, direction[1] * action.speed, direction[2] * action.speed]\n const projectile: Use = {\n kind: 'throw',\n energy: explosive?.energy ?? 0,\n radius: explosive?.lethalRadius ?? 0,\n fuse: 0,\n velocity,\n origin,\n explosive: action.projectile,\n trigger: 'impact',\n armDistance: action.minArmDistance,\n ...(explosive ? { injuryRadius: explosive.injuryRadius } : {}),\n }\n if (action.backblast <= 0) return [projectile]\n return [projectile, { kind: 'backblast', radius: action.backblast, halfAngleDeg: action.backblastHalfAngleDeg ?? 180, origin, direction: negate(direction) }]\n}\n\nconst TIMER_TRIGGERS: ReadonlySet<string> = new Set(['timer', ...PLACED_TRIGGERS])\n\n/** Whether the explosive is set down instead of thrown: it waits for a trip wire or a detonator, or its fuse is so long that holding it makes no sense. */\nexport const isPlaced = (explosive: ExplosiveDef | null, fuse: number, rules: Pick<WeaponRules['explosives'], 'placeFuseFrom'>): boolean => {\n if (!explosive) return false\n if (explosive.triggers?.some((trigger) => PLACED_TRIGGERS.has(trigger))) return true\n return (explosive.triggers?.includes('timer') ?? false) && fuse >= rules.placeFuseFrom\n}\n\nexport type ThrowableUseParams = {\n readonly action: ThrowableAction\n readonly explosive: ExplosiveDef | null\n readonly origin: Vec3\n readonly direction: Vec3\n /** Seconds of fuse of this throw (sampled, or what is left after cooking). */\n readonly fuse: number\n /** Seconds the thrower held it after pulling the pin. */\n readonly cooked?: number\n /** Set off in the hand: no throw, the fuse is spent. */\n readonly inHand?: boolean\n readonly rules: Pick<WeaponRules['explosives'], 'placeFuseFrom' | 'tripwire'>\n}\n\nconst placedUse = ({ action, explosive, origin, direction, fuse, rules }: ThrowableUseParams & { explosive: ExplosiveDef }): Use => ({\n kind: 'place',\n explosive: explosive.id,\n triggers: (explosive.triggers ?? []).filter((trigger): trigger is 'timer' | 'wire' | 'remote' => TIMER_TRIGGERS.has(trigger)),\n energy: explosive.energy,\n radius: explosive.lethalRadius,\n injuryRadius: explosive.injuryRadius,\n ...(explosive.cone ? { cone: { halfAngleDeg: explosive.cone.halfAngleDeg, length: explosive.cone.length } } : {}),\n ...(explosive.triggers?.includes('wire') ? { tripwire: { ...rules.tripwire, ...explosive.tripwire } } : {}),\n ...(fuse > 0 && action.fuse > 0 ? { fuse } : {}),\n origin,\n direction,\n})\n\n/** One throw (or one charge set down) of a throwable: a fuse that counts from the throw, or an impact trigger when the fuse is 0. */\nexport const throwableUse = (params: ThrowableUseParams): Use => {\n const { action, explosive, origin, direction, fuse, cooked, inHand } = params\n if (explosive && isPlaced(explosive, fuse, params.rules)) return placedUse({ ...params, explosive })\n const velocity: Vec3 = inHand ? [0, 0, 0] : [direction[0] * action.throwSpeed, direction[1] * action.throwSpeed + action.throwSpeed * THROW_LIFT, direction[2] * action.throwSpeed]\n const use: Extract<Use, { kind: 'throw' }> = { kind: 'throw', energy: action.energy, radius: action.radius, fuse, velocity, origin }\n if (cooked !== undefined) use.cooked = cooked\n if (inHand) use.inHand = true\n if (action.fire) use.fire = { ...action.fire }\n if (!explosive) return use\n return {\n ...use,\n ...blastNumbers(explosive),\n radius: action.radius,\n explosive: explosive.id,\n trigger: fuse > 0 || inHand ? 'timer' : 'impact',\n armDistance: 0,\n ...(explosive.stunSeconds !== undefined ? { stunSeconds: explosive.stunSeconds } : {}),\n }\n}\n","import type { CaliberDef, WeaponAction, WeaponRules } from './types'\n\nconst SUBSTEP_SECONDS = 1 / 60\n\n/** Cools a barrel: each step loses `decayBase + heat × decayPerPoint` per second (explicit Euler, in steps of at most 1/60 s). */\nexport const decayHeat = (heat: number, seconds: number, rules: WeaponRules['heat']): number => {\n const steps = Math.max(1, Math.ceil(seconds / SUBSTEP_SECONDS - 1e-9))\n const step = seconds / steps\n let current = heat\n for (let i = 0; i < steps && current > 0; i++) current = Math.max(0, current - step * (rules.decayBase + current * rules.decayPerPoint))\n return current\n}\n\n/** Heat one round adds: by the cartridge case, or a fixed amount for a rocket. A bow has no cartridge and adds none. */\nexport const heatPerRound = (action: WeaponAction, caliber: CaliberDef | null, rules: WeaponRules['heat']): number => {\n if (action.kind === 'launcher') return rules.perRocket\n return caliber?.caseType ? rules.perShot[caliber.caseType] : 0\n}\n\n/** Each shot in the last few seconds makes the next one louder, up to a cap. */\nexport const burstNoise = (base: number, recentShots: number, rules: WeaponRules['noiseBurst']): number => base * (1 + Math.min(rules.cap, rules.step * recentShots))\n","import type { ReloadFamily, ReloadKind, ReloadStage } from './types'\n\ntype StageTable = Readonly<Record<ReloadKind, readonly ReloadStage[]>>\n\nconst magazineOut = { stage: 'magazine_out', at: 0 } as const\n// 0.45 s of the 0.82 s magazine swap in the gallery\nconst magazineIn = { stage: 'magazine_in', at: 0.549 } as const\n\nconst byMagazine = (chargeAt: number): StageTable => ({\n tactical: [magazineOut, magazineIn],\n empty: [magazineOut, magazineIn, { stage: 'charge', at: chargeAt }],\n one_by_one: [magazineOut, magazineIn],\n})\n\n// A reload that loads rounds one at a time: `round_in` opens the loading and the closing stage comes after the last round.\nconst byTube = (closing: ReloadStage | undefined): StageTable => ({\n tactical: [{ stage: 'round_in', at: 0 }],\n empty: closing ? [{ stage: 'round_in', at: 0 }, closing] : [{ stage: 'round_in', at: 0 }],\n one_by_one: [{ stage: 'round_in', at: 0 }],\n})\n\nconst revolverOpen = { stage: 'cylinder_open', at: 0 } as const\nconst revolverEject = { stage: 'cylinder_eject', at: 0.246 } as const\nconst revolverClose = { stage: 'cylinder_close', at: 0.808 } as const\nconst revolverJet: readonly ReloadStage[] = [revolverOpen, revolverEject, { stage: 'cylinder_load', at: 0.538 }, revolverClose]\nconst revolverRounds: readonly ReloadStage[] = [revolverOpen, revolverEject, revolverClose]\n\nconst breechSwing: readonly ReloadStage[] = [\n { stage: 'barrels_open', at: 0 },\n { stage: 'casings_eject', at: 0.208 },\n { stage: 'rounds_in', at: 0.542 },\n { stage: 'barrels_close', at: 0.833 },\n]\n\nconst beltSwap: readonly ReloadStage[] = [\n { stage: 'cover_open', at: 0 },\n { stage: 'belt_swap', at: 0.129 },\n { stage: 'cover_close', at: 0.581 },\n { stage: 'charge', at: 0.742 },\n]\n\n/** Where each step of a reload falls, as a fraction of its duration, from the key frames of the gallery animations. The runtime scales them to the duration of the weapon. */\nexport const RELOAD_STAGES: Readonly<Record<ReloadFamily, StageTable>> = {\n pistol: byMagazine(0.872),\n magazine: byMagazine(0.701),\n top_magazine: byMagazine(0.701),\n top_load_semi: byTube({ stage: 'charge', at: 0.893 }),\n tube_semi: byTube({ stage: 'charge', at: 0.88 }),\n pump: byTube({ stage: 'pump_cycle', at: 0.88 }),\n lever: byTube({ stage: 'lever_cycle', at: 0.873 }),\n bolt: {\n tactical: [{ stage: 'bolt_open', at: 0 }, { stage: 'round_in', at: 0.14 }, { stage: 'bolt_close', at: 0.86 }],\n empty: [{ stage: 'bolt_open', at: 0 }, { stage: 'round_in', at: 0.14 }, { stage: 'bolt_close', at: 0.86 }],\n one_by_one: [{ stage: 'bolt_open', at: 0 }, { stage: 'round_in', at: 0.14 }, { stage: 'bolt_close', at: 0.86 }],\n },\n bolt_magazine: {\n tactical: [magazineOut, magazineIn, { stage: 'bolt_open', at: 0.599 }, { stage: 'bolt_close', at: 0.89 }],\n empty: [magazineOut, magazineIn, { stage: 'bolt_open', at: 0.599 }, { stage: 'bolt_close', at: 0.89 }],\n one_by_one: [magazineOut, magazineIn],\n },\n belt: { tactical: beltSwap, empty: beltSwap, one_by_one: beltSwap },\n revolver: { tactical: revolverJet, empty: revolverJet, one_by_one: revolverRounds },\n break: { tactical: breechSwing, empty: breechSwing, one_by_one: breechSwing },\n // tactical: reusable launcher takes a rocket; empty: disposable tube is dropped and a new one seated; one_by_one: breech-loaded grenade\n rocket: {\n tactical: [{ stage: 'rocket_seat', at: 0 }],\n empty: [{ stage: 'tube_drop', at: 0 }, { stage: 'tube_seat', at: 0.522 }],\n one_by_one: [\n { stage: 'breech_open', at: 0 },\n { stage: 'round_in', at: 0.305 },\n { stage: 'breech_close', at: 0.724 },\n ],\n },\n flame: {\n tactical: [{ stage: 'tank_swap', at: 0 }],\n empty: [{ stage: 'tank_swap', at: 0 }],\n one_by_one: [{ stage: 'tank_swap', at: 0 }],\n },\n}\n","import { RELOAD_STAGES } from './reload-stages'\nimport type { ReloadKind, ReloadRequest, ReloadStageId, WeaponAction } from './types'\n\nexport type ReloadableAction = Extract<WeaponAction, { kind: 'firearm' | 'launcher' }>\n\nexport interface ReloadPlan {\n readonly kind: ReloadKind\n /** Seconds per round when the weapon loads one at a time, null when the whole magazine goes in at once. */\n readonly step: number | null\n /** Seconds until the first round (or the whole magazine) is in. */\n readonly first: number\n /** Seconds of the whole reload; the stages are placed along it. */\n readonly total: number\n}\n\nexport const isReloadable = (action: WeaponAction): action is ReloadableAction => action.kind === 'firearm' || action.kind === 'launcher'\n\nconst baseSeconds = (action: ReloadableAction): number => action.timings?.reload ?? action.reload\n\nconst secondsPerRound = (action: ReloadableAction): number | undefined => {\n if (action.kind !== 'firearm') return undefined\n return action.timings?.perRound ?? (action.perRound ? baseSeconds(action) : undefined)\n}\n\nconst pickKind = (action: ReloadableAction, ammo: number, oneAtATime: boolean, request: ReloadRequest): ReloadKind => {\n if (action.kind === 'launcher') return action.disposable ? 'empty' : 'tactical'\n if (request === 'one_by_one' && oneAtATime) return 'one_by_one'\n if (request === 'full') return ammo === 0 ? 'empty' : 'tactical'\n if (oneAtATime && (action.family === 'revolver' || ammo > 0)) return 'one_by_one'\n return ammo === 0 ? 'empty' : 'tactical'\n}\n\n/** How a reload goes: tactical (a magazine swap), empty (with the action to work after) or one by one; `full` loads a revolver all at once with a speed loader. */\nexport const planReload = (action: ReloadableAction, ammo: number, capacity: number, reserve: number, request: ReloadRequest): ReloadPlan => {\n const perRound = secondsPerRound(action)\n const oneAtATime = perRound !== undefined && request !== 'full'\n const kind = pickKind(action, ammo, oneAtATime, request)\n if (kind === 'one_by_one' && perRound !== undefined) {\n const rounds = Math.max(1, Math.min(capacity - ammo, reserve))\n return { kind, step: perRound, first: perRound, total: rounds * perRound }\n }\n const seconds = kind === 'empty' ? action.timings?.reloadEmpty ?? baseSeconds(action) : baseSeconds(action)\n return { kind, step: null, first: seconds, total: seconds }\n}\n\n/** The steps of a reload with the time they happen, scaled to the duration of this weapon's reload. */\nexport const reloadStages = (action: ReloadableAction, plan: ReloadPlan, startAt: number): { stage: ReloadStageId; at: number }[] => {\n if (!action.family) return []\n return RELOAD_STAGES[action.family][plan.kind].map((entry) => ({ stage: entry.stage, at: startAt + entry.at * plan.total }))\n}\n","import type { AmmoQualityDef, CaliberDef, ConditionDef, FaultId, ReloadFamily, WeaponDef, WeaponRules } from './types'\n\nconst MISFIRE_ONLY: ReadonlySet<ReloadFamily | undefined> = new Set(['revolver', 'break'])\nconst MANUAL: ReadonlySet<ReloadFamily | undefined> = new Set(['pump', 'bolt', 'bolt_magazine', 'lever'])\nconst MISFIRE_SHARE = 0.35\nconst STOVEPIPE_UPTO = 0.8\n\nexport interface FaultRoll {\n readonly def: WeaponDef\n readonly caliber: CaliberDef | null\n readonly condition: ConditionDef\n readonly ammoQuality: AmmoQualityDef\n readonly heat: number\n readonly rules: WeaponRules\n readonly random: () => number\n}\n\n/** Whether the round about to fire jams, and how. Only a weapon that fires cartridges can. */\nexport const rollFault = (roll: FaultRoll): FaultId | null => {\n const action = roll.def.action\n if (!roll.rules.faults || action.kind !== 'firearm' || !roll.caliber?.caseType) return null\n if (roll.random() < roll.rules.faultChance({ def: roll.def, condition: roll.condition, heat: roll.heat })) {\n const kind = roll.random()\n if (MISFIRE_ONLY.has(action.family) || kind < MISFIRE_SHARE) return 'misfire'\n if (MANUAL.has(action.family)) return 'failure_to_extract'\n return kind < STOVEPIPE_UPTO ? 'stovepipe' : 'double_feed'\n }\n return roll.ammoQuality.faultChance > 0 && roll.random() < roll.ammoQuality.faultChance ? 'misfire' : null\n}\n\n/** A dud in a revolver or a break-action just spends the round; anywhere else the round stays in the chamber and the weapon jams. */\nexport const isDudWithoutJam = (action: WeaponDef['action'], fault: FaultId): boolean => fault === 'misfire' && action.kind === 'firearm' && MISFIRE_ONLY.has(action.family)\n","import type { CaliberDef, FireMode, FirearmAction, WeaponAction, WeaponRules, WeaponTimings } from './types'\n\nconst EPS = 1e-9\nconst MANUAL_MODES: ReadonlySet<FireMode> = new Set(['pump', 'bolt', 'lever'])\n\nexport const weaponSpeed = (action: FirearmAction, caliber: CaliberDef): number => action.muzzleSpeed ?? caliber.muzzleSpeed * (action.barrel ?? 1)\n\nexport const weaponNoise = (action: FirearmAction, caliber: CaliberDef): number => action.noise ?? caliber.noise ?? 0\n\nexport const timingsOf = (action: WeaponAction): WeaponTimings | undefined => ('timings' in action ? action.timings : undefined)\n\nexport const drawSeconds = (action: WeaponAction, rules: WeaponRules): number => timingsOf(action)?.draw ?? rules.draw\n\nexport const clearSeconds = (action: WeaponAction, rules: WeaponRules): number => timingsOf(action)?.clear ?? rules.clear\n\n/** Seconds a manual action (pump, bolt, lever) needs to cycle after a shot; 0 for every other mode. */\nexport const manualCycleSeconds = (action: FirearmAction, mode: FireMode): number => (MANUAL_MODES.has(mode) ? action.timings?.cycle ?? 0 : 0)\n\n/** When each round of one pull leaves the barrel: a held auto trigger fires through the frame, a burst at the cyclic rate, a volley all at once. */\nexport const planRounds = (action: FirearmAction, mode: FireMode, ammo: number, firstAt: number, frameEnd: number): number[] => {\n const interval = 60 / action.rpm\n const times: number[] = []\n if (mode === 'auto') {\n for (let t = firstAt; times.length < ammo && (times.length === 0 ? t <= frameEnd + EPS : t < frameEnd - EPS); t += interval) times.push(t)\n return times\n }\n if (mode === 'burst') {\n const count = Math.min(action.burst ?? 3, ammo)\n for (let k = 0; k < count; k++) times.push(firstAt + k * interval)\n return times\n }\n if (mode === 'volley') return Array.from({ length: Math.min(action.magazine, ammo) }, () => firstAt)\n return [firstAt]\n}\n","import type {\n CaliberDef,\n ExplosiveDef,\n TriggerResult,\n WeaponDef,\n WeaponEvent,\n WeaponRules,\n} from './types'\n\nexport const EPS = 1e-9\n/** Total spread (base + bloom) never exceeds this many times the base spread. */\nexport const BLOOM_CAP = 4\n\n/** Muzzle energy in joules of ONE projectile (a bullet, or one pellet): 0.5 × mass × speed², speed scaled by the barrel factor. */\nexport const muzzleEnergy = (caliber: CaliberDef, barrel = 1): number => {\n const v = caliber.muzzleSpeed * barrel\n return 0.5 * (caliber.bulletGrams / 1000) * v * v\n}\n\nexport interface WeaponStateInit {\n def: WeaponDef\n caliber: CaliberDef | null\n seed: number\n reserve?: number\n rules: WeaponRules\n /** What a launcher shoots, or the explosive a throwable carries. */\n explosive?: ExplosiveDef | null\n condition?: string\n ammoQuality?: string\n}\n\n/** Something that happens at a later time of the weapon clock. */\nexport interface Scheduled {\n readonly at: number\n readonly tag?: 'reload'\n readonly event: WeaponEvent\n readonly apply?: () => void\n}\n\nexport const FAULT_RNG_SALT = 0x6a09e667\n/** Stream of the fuse sampling: separate from the spread and the faults, so a sampled fuse never shifts a shot. */\nexport const FUSE_RNG_SALT = 0xbb67ae85\n\nexport const findById = <TEntry extends { readonly id: string }>(entries: readonly TEntry[], id: string, label: string): TEntry => {\n const found = entries.find((entry) => entry.id === id)\n if (!found) throw new Error(`game-weapons: unknown ${label} \"${id}\"`)\n return found\n}\n\nexport const result = (status: TriggerResult['status'], extra: Partial<TriggerResult> = {}): TriggerResult => ({\n shots: [],\n uses: [],\n status,\n recoil: [0, 0],\n noise: 0,\n rounds: 0,\n roundTimes: [],\n ...extra,\n})\n\n/** Runtime of one weapon. See `WeaponState` for the contract. */\n","import { decayHeat } from './heat'\nimport { isReloadable } from './reload'\nimport { createRng } from './rng'\nimport type { AmmoQualityDef, CaliberDef, ConditionDef, ExplosiveDef, FaultId, FireMode, ReloadKind, Vec3, WeaponAction, WeaponDef, WeaponEvent, WeaponPhase, WeaponRules } from './types'\nimport { EPS, FAULT_RNG_SALT, FUSE_RNG_SALT, findById } from './weapon-shared'\nimport type { Scheduled, WeaponStateInit } from './weapon-shared'\n\nconst DEFAULT_THROWABLES = 3\n\n/** State and clock of one weapon: ammunition, phases, scheduled events and reload settling. Commands and firing are layered on top. */\nexport abstract class WeaponCore {\n readonly def: WeaponDef\n readonly caliber: CaliberDef | null\n reserve: number\n mode: FireMode\n protected _ammo: number\n protected readonly _capacity: number\n protected readonly action: WeaponAction\n protected readonly rng: () => number\n protected readonly initialReserve: number\n protected readonly rules: WeaponRules\n protected readonly faultRng: () => number\n protected readonly fuseRng: () => number\n /** Metres of safety fuse set by the host; replaces the `fuseLength` of the explosive. */\n protected fuseLengthOverride: number | undefined\n protected readonly explosive: ExplosiveDef | null\n\n protected clock = 0\n /** Time already advanced by the other of update / trigger in the same frame (so calling both does not count `dt` twice). */\n protected pend: { src: 'update' | 'trigger'; amt: number } | null = null\n protected readyAt = 0\n protected latched = false\n /** A throwable whose pin is pulled: the clock it started at, its whole fuse and the aim of the last frame it was held. */\n protected cook: { readonly start: number; readonly fuse: number; origin: Vec3; direction: Vec3 } | null = null\n\n protected _reloading = false\n protected reloadEnd = 0\n /** Seconds per round while a one-by-one reload runs; null when the magazine goes in at once. */\n protected loadStep: number | null = null\n protected _locked = false\n protected reloadKind: ReloadKind = 'tactical'\n protected drawEnd = 0\n protected _phase: WeaponPhase | null = null\n protected _fault: FaultId | null = null\n protected _clearing = false\n protected _safety: boolean\n protected _heat = 0\n protected _condition: ConditionDef\n protected _ammoQuality: AmmoQualityDef\n /** Times of the shots that still count for the noise of a burst. */\n protected recentShots: number[] = []\n protected events: WeaponEvent[] = []\n protected scheduled: Scheduled[] = []\n\n /** Bloom degrees at `extraClock`. */\n protected extra = 0\n protected extraClock = 0\n\n constructor(init: WeaponStateInit) {\n this.def = init.def\n this.caliber = init.caliber\n this.action = init.def.action\n this.rules = init.rules\n this.rng = createRng(init.seed)\n this.faultRng = createRng((init.seed ^ FAULT_RNG_SALT) >>> 0)\n this.fuseRng = createRng((init.seed ^ FUSE_RNG_SALT) >>> 0)\n this.explosive = init.explosive ?? null\n this._safety = init.rules.startSafe\n this._condition = findById(init.rules.conditions, init.condition ?? init.rules.defaultCondition, 'condition')\n this._ammoQuality = findById(init.rules.ammoQualities, init.ammoQuality ?? init.rules.defaultAmmoQuality, 'ammo quality')\n const a = this.action\n this.mode = a.kind === 'firearm' ? a.modes[0] ?? 'single' : 'single'\n switch (a.kind) {\n case 'firearm':\n case 'launcher':\n this._capacity = a.magazine\n break\n case 'flame':\n case 'heat':\n this._capacity = a.fuel\n break\n case 'extinguisher':\n this._capacity = a.charge\n break\n case 'throwable':\n this._capacity = a.count ?? DEFAULT_THROWABLES\n break\n default:\n this._capacity = 0\n }\n this._ammo = this._capacity\n this.initialReserve = init.reserve ?? (isReloadable(a) ? a.magazine * 3 : 0)\n this.reserve = this.initialReserve\n }\n\n get ammo(): number {\n return this._ammo\n }\n get capacity(): number {\n return this._capacity\n }\n /** True while a throwable's pin is pulled and the trigger is held. */\n get cooking(): boolean {\n return this.cook !== null\n }\n get reloading(): boolean {\n return this._reloading\n }\n get locked(): boolean {\n return this._locked\n }\n get phase(): WeaponPhase | null {\n const phase = this._phase\n return phase && this.clock < phase.end - EPS ? phase : null\n }\n get fault(): FaultId | null {\n return this._fault\n }\n get clearing(): boolean {\n return this._clearing\n }\n get safety(): boolean {\n return this._safety\n }\n get heat(): number {\n return this._heat\n }\n get heatLevel(): number {\n return Math.min(1, this._heat / this.rules.heat.displayMax)\n }\n get condition(): string {\n return this._condition.id\n }\n get ammoQuality(): string {\n return this._ammoQuality.id\n }\n get spread(): number {\n if (this.action.kind !== 'firearm') return 0\n return this.action.spreadDeg + this.extraAt(this.clock)\n }\n\n protected extraAt(t: number): number {\n if (this.action.kind !== 'firearm') return 0\n const rec = this.action.recoveryDegPerS ?? 4\n return Math.max(0, this.extra - rec * Math.max(0, t - this.extraClock))\n }\n\n // --- time -----------------------------------------------------------------------------------------------------------------------\n\n update(dt: number): void {\n const d = Math.max(0, dt)\n let eff = d\n if (this.pend && this.pend.src === 'trigger') {\n eff = Math.max(0, d - this.pend.amt)\n this.pend = null\n } else {\n this.pend = { src: 'update', amt: d }\n }\n this.advance(eff)\n this.settle(this.clock)\n }\n\n protected emit(event: WeaponEvent): void {\n this.events.push(event)\n }\n\n protected schedule(item: Scheduled): void {\n const index = this.scheduled.findIndex((other) => other.at > item.at)\n if (index < 0) this.scheduled.push(item)\n else this.scheduled.splice(index, 0, item)\n }\n\n drain(): WeaponEvent[] {\n const drained = this.events.sort((a, b) => a.at - b.at)\n this.events = []\n return drained\n }\n\n protected advance(seconds: number): void {\n if (seconds <= 0) return\n this._heat = decayHeat(this._heat, seconds, this.rules.heat)\n this.clock += seconds\n }\n\n /** Complete what falls at or before `t`: scheduled events and the reload steps. */\n protected settle(t: number): void {\n while (this.scheduled[0] && this.scheduled[0].at <= t + EPS) {\n const item = this.scheduled.shift() as Scheduled\n item.apply?.()\n this.emit(item.event)\n }\n const a = this.action\n if (!isReloadable(a)) return\n while (this._reloading && this.reloadEnd <= t + EPS) {\n const doneAt = this.reloadEnd\n if (this.loadStep !== null) {\n if (this.reserve > 0 && this._ammo < this._capacity) {\n this._ammo += 1\n this.reserve -= 1\n this.emit({ type: 'feed', at: doneAt })\n }\n if (this._ammo >= this._capacity || this.reserve <= 0) this.finishReload(doneAt)\n else this.reloadEnd += this.loadStep\n } else {\n const take = Math.min(this._capacity - this._ammo, this.reserve)\n this._ammo += take\n this.reserve -= take\n this.finishReload(doneAt)\n }\n }\n }\n\n protected finishReload(at: number): void {\n this._reloading = false\n this._locked = false\n this.emit({ type: 'reload', phase: 'end', kind: this.reloadKind, at })\n }\n\n protected stopReload(at: number): void {\n this._reloading = false\n this._phase = null\n this.scheduled = this.scheduled.filter((item) => item.tag !== 'reload')\n this.emit({ type: 'reload', phase: 'end', kind: this.reloadKind, at })\n }\n\n release(): void {\n this.latched = false\n }\n}\n","import { clearSeconds, drawSeconds } from './fire'\nimport { isReloadable, planReload, reloadStages } from './reload'\nimport type { FireMode, ReloadRequest } from './types'\nimport { WeaponCore } from './weapon-core'\nimport { EPS, findById } from './weapon-shared'\n\n/** Commands that change the state of a weapon: safety, fault clearing, condition, draw, reload, fire mode and refill. */\nexport abstract class WeaponCommands extends WeaponCore {\n setSafety(on: boolean): boolean {\n if (!isReloadable(this.action) || on === this._safety) return this._safety\n this._safety = on\n this.emit({ type: 'safety', on, at: this.clock })\n return on\n }\n\n clearFault(): boolean {\n const fault = this._fault\n if (!fault || this._clearing) return false\n const endAt = this.clock + clearSeconds(this.action, this.rules)\n this._clearing = true\n this._phase = { id: 'clear', start: this.clock, end: endAt }\n this.emit({ type: 'clear', fault, phase: 'start', at: this.clock })\n const finish = (): void => {\n this._fault = null\n this._clearing = false\n if (fault === 'misfire') this._ammo = Math.max(0, this._ammo - 1) // the dud is ejected\n }\n this.schedule({ at: endAt, event: { type: 'clear', fault, phase: 'end', at: endAt }, apply: finish })\n return true\n }\n\n setCondition(id: string): void {\n this._condition = findById(this.rules.conditions, id, 'condition')\n }\n\n setAmmoQuality(id: string): void {\n this._ammoQuality = findById(this.rules.ammoQualities, id, 'ammo quality')\n }\n\n setFuseLength(metres: number | undefined): void {\n this.fuseLengthOverride = metres\n }\n\n draw(): void {\n const seconds = drawSeconds(this.action, this.rules)\n this.drawEnd = this.clock + seconds\n this._phase = { id: 'draw', start: this.clock, end: this.drawEnd }\n this.emit({ type: 'draw', phase: 'start', at: this.clock })\n this.schedule({ at: this.drawEnd, event: { type: 'draw', phase: 'end', at: this.drawEnd } })\n }\n\n reload(request: ReloadRequest = 'auto'): boolean {\n const a = this.action\n if (a.kind === 'throwable') {\n if (this._ammo >= this._capacity || this.reserve <= 0) return false\n this._ammo += 1\n this.reserve -= 1\n return true\n }\n if (!isReloadable(a) || this._reloading || this._fault || this._clearing || this.clock < this.drawEnd - EPS) return false\n if ((this._ammo >= this._capacity && !this._locked) || this.reserve <= 0) return false\n const plan = planReload(a, this._ammo, this._capacity, this.reserve, request)\n this._reloading = true\n this.loadStep = plan.step\n this.reloadKind = plan.kind\n this.reloadEnd = this.clock + plan.first\n this._phase = { id: 'reload', start: this.clock, end: this.clock + plan.total }\n this.emit({ type: 'reload', phase: 'start', kind: plan.kind, at: this.clock })\n for (const { stage, at } of reloadStages(a, plan, this.clock)) this.schedule({ at, tag: 'reload', event: { type: 'reload_stage', stage, at } })\n return true\n }\n\n cycleMode(): FireMode {\n if (this.action.kind !== 'firearm') return this.mode\n const modes = this.action.modes\n const i = modes.indexOf(this.mode)\n this.mode = modes[(i + 1) % modes.length] ?? this.mode\n this.emit({ type: 'mode', mode: this.mode, at: this.clock })\n return this.mode\n }\n\n refill(): void {\n this._ammo = this._capacity\n this.reserve = this.initialReserve\n this._reloading = false\n this._locked = false\n this._fault = null\n this._clearing = false\n this._phase = null\n this.scheduled = []\n this.readyAt = this.clock\n this.latched = false\n this.cook = null\n this.extra = 0\n }\n}\n","import { isDudWithoutJam, rollFault } from './faults'\nimport { manualCycleSeconds, planRounds, weaponNoise, weaponSpeed } from './fire'\nimport { burstNoise, heatPerRound } from './heat'\nimport { sampleCone } from './rng'\nimport type { CaliberDef, FaultId, FirearmAction, Shot, TriggerResult, Vec3 } from './types'\nimport { WeaponCommands } from './weapon-commands'\nimport { BLOOM_CAP, EPS, result } from './weapon-shared'\n\n/** Pulling the trigger of a firearm: rounds, faults, heat, bloom and noise. */\nexport abstract class WeaponFirearm extends WeaponCommands {\n /** Semi-style gating: a held trigger that already fired does nothing until `release()` or a new pull (`held` false). */\n protected oncePerPull(held: boolean): boolean {\n if (!held) this.latched = false\n if (this.latched) return false\n this.latched = true\n return true\n }\n\n protected fireFirearm(a: FirearmAction, origin: Vec3, dir: Vec3, start: number, end: number, held: boolean, source?: string): TriggerResult {\n if (this._reloading) {\n if (this.loadStep !== null && this._ammo > 0) this.stopReload(start) // a tube reload is interrupted by the trigger\n else return result('reloading')\n }\n if (this.mode !== 'auto' && !this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) {\n this.emit({ type: 'empty', at: start })\n return result('empty')\n }\n\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n\n const res = result('ok')\n const times = planRounds(a, this.mode, this._ammo, t0, end)\n let lastAt = t0\n for (const t of times) {\n const fault = rollFault({ def: this.def, caliber: this.caliber, condition: this._condition, ammoQuality: this._ammoQuality, heat: this._heat, rules: this.rules, random: this.faultRng })\n if (fault === 'misfire') {\n this.misfire(a, t, start, res)\n lastAt = t\n break\n }\n this.fireOne(a, origin, dir, t, res, source)\n res.roundTimes.push(t - start)\n res.rounds += 1\n lastAt = t\n if (fault) {\n this.jam(fault, t, res)\n break\n }\n }\n if (res.shots.length === 0) res.status = res.fault ? 'fault' : 'misfire'\n else this.emit({ type: 'shot', shots: res.shots.length, rounds: res.rounds, mode: this.mode, at: t0 })\n if (res.rounds > 0) this.afterRounds(a, lastAt)\n return res\n }\n\n protected jam(fault: FaultId, at: number, res: TriggerResult): void {\n this._fault = fault\n res.fault = fault\n this.emit({ type: 'fault', fault, at })\n }\n\n protected misfire(a: FirearmAction, at: number, start: number, res: TriggerResult): void {\n if (!isDudWithoutJam(a, 'misfire')) {\n this.jam('misfire', at, res)\n return\n }\n this._ammo -= 1\n res.rounds += 1\n res.roundTimes.push(at - start)\n this.emit({ type: 'misfire', at })\n }\n\n /** Cooldown, the cycle of a manual action and the pistol slide that stays back on the last round. */\n protected afterRounds(a: FirearmAction, lastAt: number): void {\n const cycle = manualCycleSeconds(a, this.mode)\n if (cycle > 0) {\n this.readyAt = Math.max(this.readyAt, lastAt + cycle)\n this._phase = { id: 'cycle', start: lastAt, end: lastAt + cycle }\n this.emit({ type: 'cycle', phase: 'start', at: lastAt })\n this.schedule({ at: lastAt + cycle, event: { type: 'cycle', phase: 'end', at: lastAt + cycle } })\n }\n if (this._ammo === 0 && a.family === 'pistol') this._locked = true\n }\n\n protected fireOne(a: FirearmAction, origin: Vec3, dir: Vec3, t: number, res: TriggerResult, source?: string): void {\n const cal = this.caliber as CaliberDef\n const speed = weaponSpeed(a, cal)\n const energy = 0.5 * (cal.bulletGrams / 1000) * speed * speed\n const drag = cal.dragPer100m ?? 0.1\n const energyAt = (distance: number): number => {\n const f = Math.pow(1 - drag, Math.max(0, distance) / 100)\n return energy * f * f\n }\n const bloomNow = this.extraAt(t)\n const spread = a.spreadDeg + bloomNow\n const aim = sampleCone(dir, spread, this.rng)\n const pellets = cal.pellets ?? 1\n const pelletSpread = pellets > 1 ? a.pelletSpreadDeg ?? 3 : 0\n for (let p = 0; p < pellets; p++) {\n const shot: Shot = {\n origin: [origin[0], origin[1], origin[2]],\n direction: sampleCone(aim, pelletSpread, this.rng),\n energy,\n caliber: cal.diameter,\n caliberId: cal.id,\n speed,\n energyAt,\n pellet: p,\n weapon: this.def.id,\n }\n if (source !== undefined) shot.source = source\n res.shots.push(shot)\n }\n this._ammo -= 1\n this._heat = Math.min(this.rules.heat.cap, this._heat + heatPerRound(a, cal, this.rules.heat))\n this.readyAt = t + 60 / a.rpm\n this.extra = Math.min(bloomNow + (a.bloomDeg ?? 0), a.spreadDeg * (BLOOM_CAP - 1))\n this.extraClock = t\n res.recoil = [res.recoil[0] + a.recoil[0], res.recoil[1] + (this.rng() * 2 - 1) * a.recoil[1]]\n const { window } = this.rules.noiseBurst\n this.recentShots = this.recentShots.filter((shotAt) => shotAt > t - window)\n res.noise = burstNoise(weaponNoise(a, cal), this.recentShots.length, this.rules.noiseBurst)\n this.recentShots.push(t)\n }\n\n}\n","import { isPlaced, launcherUses, throwableUse } from './explosive-use'\nimport { sampleFuse } from './fuse'\nimport { heatPerRound } from './heat'\nimport { isReloadable } from './reload'\nimport { normalize } from './rng'\nimport type { TriggerResult, Use, Vec3, WeaponAction, WeaponState } from './types'\nimport { WeaponFirearm } from './weapon-firearm'\nimport type { WeaponCore } from './weapon-core'\nimport { EPS, result } from './weapon-shared'\n\nexport { BLOOM_CAP, muzzleEnergy } from './weapon-shared'\nexport type { WeaponStateInit } from './weapon-shared'\n\n/** Runtime of one weapon. See `WeaponState` for the contract. */\nexport class WeaponRuntime extends WeaponFirearm implements WeaponState {\n trigger(origin: Vec3, direction: Vec3, dt: number, held = false, source?: string): TriggerResult {\n const d = Math.max(0, dt)\n let overlap = 0\n if (this.pend && this.pend.src === 'update') {\n overlap = Math.min(this.pend.amt, d)\n this.pend = null\n } else {\n this.pend = { src: 'trigger', amt: d }\n }\n const start = this.clock - overlap\n const end = start + d\n this.settle(start)\n const dir = normalize(direction)\n let res: TriggerResult\n const a = this.action\n const gate = this.gateStatus(start)\n if (gate) res = gate\n else switch (a.kind) {\n case 'firearm':\n res = this.fireFirearm(a, origin, dir, start, end, held, source)\n break\n case 'melee':\n res = this.fireMelee(a, origin, dir, start, end)\n break\n case 'flame':\n case 'heat':\n res = this.fireFuel(a, origin, dir, d)\n break\n case 'extinguisher':\n res = this.fireExtinguisher(a, origin, dir, d)\n break\n case 'throwable':\n res = this.fireThrowable(a, origin, dir, held, start, end)\n break\n case 'launcher':\n res = this.fireLauncher(a, origin, dir, start, held)\n break\n case 'tool':\n res = d > 0 ? result('ok', { uses: [{ kind: 'tool', tool: a.tool, reach: a.reach, duration: d, origin, direction: dir }], noise: a.noise }) : result('ok')\n break\n case 'hand':\n res = this.oncePerPull(held)\n ? result('ok', { uses: [{ kind: 'hand', reach: a.reach, origin, direction: dir }] })\n : result('cooldown')\n break\n }\n this.advance(Math.max(0, end - this.clock))\n this.settle(this.clock)\n return res\n }\n\n /** Why the trigger does nothing before the action even looks at it. */\n protected gateStatus(start: number): TriggerResult | null {\n if (start < this.drawEnd - EPS) return result('drawing')\n if (!isReloadable(this.action)) return null\n if (this._safety) return result('safe')\n if (this._clearing) return result('clearing')\n if (this._fault) return result('fault', { fault: this._fault })\n return null\n }\n\n protected fireLauncher(a: Extract<WeaponAction, { kind: 'launcher' }>, origin: Vec3, dir: Vec3, start: number, held: boolean): TriggerResult {\n if (this._reloading) return result('reloading')\n if (!this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) {\n this.emit({ type: 'empty', at: start })\n return result('empty')\n }\n const t = Math.max(start, this.readyAt)\n this._ammo -= 1\n this._heat = Math.min(this.rules.heat.cap, this._heat + heatPerRound(a, null, this.rules.heat))\n this.emit({ type: 'shot', shots: 0, rounds: 1, mode: this.mode, at: t })\n return result('ok', { uses: launcherUses(a, this.explosive, origin, dir), recoil: [a.recoil[0], a.recoil[1]], noise: a.noise ?? 0, rounds: 1, roundTimes: [t - start] })\n }\n\n protected fireMelee(a: Extract<WeaponAction, { kind: 'melee' }>, origin: Vec3, dir: Vec3, start: number, end: number): TriggerResult {\n const t0 = Math.max(start, this.readyAt)\n if (t0 > end + EPS) return result('cooldown')\n this.readyAt = t0 + 60 / a.rpm\n const use: Use = { kind: 'melee', damage: a.damage, energy: a.energy, radius: a.radius, reach: a.reach, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n protected fireFuel(a: Extract<WeaponAction, { kind: 'flame' | 'heat' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const need = a.fuelPerSecond * dt\n let duration = dt\n if (need > this._ammo) {\n duration = dt * (this._ammo / need)\n this._ammo = 0\n } else {\n this._ammo -= need\n }\n const use: Use =\n a.kind === 'flame'\n ? { kind: 'flame', temperature: a.temperature, radius: a.radius, range: a.range, cone: a.cone ?? false, duration, origin, direction: dir }\n : { kind: 'heat', temperature: a.temperature, radius: a.radius, range: a.range, duration, origin, direction: dir }\n return result('ok', { uses: [use], noise: a.noise })\n }\n\n protected fireExtinguisher(a: Extract<WeaponAction, { kind: 'extinguisher' }>, origin: Vec3, dir: Vec3, dt: number): TriggerResult {\n if (this._ammo <= EPS) return result('no_fuel')\n if (dt <= 0) return result('ok')\n const duration = Math.min(dt, this._ammo)\n this._ammo -= duration\n return result('ok', { uses: [{ kind: 'extinguish', range: a.range, coolC: a.coolC, duration, origin, direction: dir }], noise: a.noise })\n }\n\n /** The fuse of this throw: sampled from the explosive when it has a range or a burn, else the fixed one of the action. */\n protected sampleThrowFuse(a: Extract<WeaponAction, { kind: 'throwable' }>): number {\n return (this.explosive ? sampleFuse(this.explosive, this.fuseRng, this.fuseLengthOverride) : undefined) ?? a.fuse\n }\n\n protected throwUse(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, fuse: number, extra: { cooked?: number; inHand?: boolean } = {}): TriggerResult {\n return result('ok', { uses: [throwableUse({ action: a, explosive: this.explosive, origin, direction: dir, fuse, rules: this.rules.explosives, ...extra })], noise: a.noise })\n }\n\n /** A timer throwable is cooked from the pull; impact, remote and wire ones (and a long fuse that sets down) act at once. */\n protected fireThrowable(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, held: boolean, start: number, end: number): TriggerResult {\n if (this.cook) return this.cookStep(a, origin, dir, end)\n if (!this.oncePerPull(held)) return result('cooldown')\n if (this._ammo <= 0) return result('empty')\n const fuse = this.sampleThrowFuse(a)\n if (fuse <= 0 || isPlaced(this.explosive, fuse, this.rules.explosives)) {\n this._ammo -= 1\n return this.throwUse(a, origin, dir, fuse)\n }\n this.cook = { start, fuse, origin, direction: dir }\n this.emit({ type: 'cook', phase: 'start', fuse, at: start })\n return this.cookStep(a, origin, dir, end)\n }\n\n /** The trigger stays down on a cooked throwable: nothing happens until the fuse runs out in the hand. */\n protected cookStep(a: Extract<WeaponAction, { kind: 'throwable' }>, origin: Vec3, dir: Vec3, now: number): TriggerResult {\n const cook = this.cook as NonNullable<WeaponCore['cook']>\n cook.origin = origin\n cook.direction = dir\n if (now - cook.start < cook.fuse - EPS) return result('ok')\n return this.burstInHand(a, cook, origin, dir)\n }\n\n protected burstInHand(a: Extract<WeaponAction, { kind: 'throwable' }>, cook: NonNullable<WeaponCore['cook']>, origin: Vec3, dir: Vec3): TriggerResult {\n this.cook = null\n this._ammo -= 1\n this.emit({ type: 'cook', phase: 'burst', fuse: 0, at: cook.start + cook.fuse })\n return this.throwUse(a, origin, dir, 0, { cooked: cook.fuse, inHand: true })\n }\n\n release(origin?: Vec3, direction?: Vec3): TriggerResult | null {\n super.release()\n const cook = this.cook\n const a = this.action\n if (!cook || a.kind !== 'throwable') return null\n const from = origin ?? cook.origin\n const dir = direction ? normalize(direction) : cook.direction\n const held = this.clock - cook.start\n if (held >= cook.fuse - EPS) return this.burstInHand(a, cook, from, dir)\n this.cook = null\n this._ammo -= 1\n const remaining = cook.fuse - held\n this.emit({ type: 'cook', phase: 'throw', fuse: remaining, at: this.clock })\n return this.throwUse(a, from, dir, remaining, { cooked: held })\n }\n}\n","import archetypesJson from './data/archetypes.json'\nimport calibersJson from './data/calibers.json'\nimport explosivesJson from './data/explosives.json'\nimport explosiveWeaponsJson from './data/explosive-weapons.json'\nimport firearmsJson from './data/firearms.json'\nimport launchersJson from './data/launchers.json'\nimport { checkArsenal, findDuplicateIds } from './check-arsenal'\nimport { resolveStrings } from './locale'\nimport { deepMerge } from './merge'\nimport { applyPatches, mergeById, removeIds, resolveThrowables } from './registry'\nimport { DEFAULT_RULES } from './rules'\nimport type { Arsenal, ArsenalOptions, CaliberDef, CaliberId, ExplosiveDef, WeaponCategory, WeaponDef, WeaponId, WeaponState } from './types'\nimport { createExplosiveBody } from './explosive-body'\nimport { muzzleEnergy, WeaponRuntime } from './weapon'\n\nexport const CALIBERS = calibersJson as unknown as CaliberDef[]\nexport const EXPLOSIVES = explosivesJson as unknown as ExplosiveDef[]\n/** The generic weapons: handling numbers (spread, bloom, range, recoil) by type, which the real models point to through `archetype`. */\nconst ARCHETYPES = archetypesJson as unknown as WeaponDef[]\nexport const ARCHETYPE_IDS: readonly WeaponId[] = ARCHETYPES.map((def) => def.id)\nexport const WEAPONS: WeaponDef[] = [...ARCHETYPES, ...(firearmsJson as unknown as WeaponDef[]), ...(launchersJson as unknown as WeaponDef[]), ...(explosiveWeaponsJson as unknown as WeaponDef[])]\n\n/** A reasonable starting kit for a test room or a sandbox. */\nexport const DEFAULT_LOADOUT: WeaponId[] = [\n 'hand', 'kick', 'shove', 'pistol_9mm', 'revolver_357', 'shotgun_pump_12', 'rifle_5_56', 'rifle_bolt_308', 'hammer', 'axe', 'machete', 'utility_knife', 'crowbar', 'lighter', 'flamethrower',\n 'cutting_torch', 'molotov', 'frag_grenade', 'screwdriver', 'wrench', 'pry_bar', 'hacksaw', 'extinguisher',\n]\n\nexport { muzzleEnergy, checkArsenal }\n\nconst explosiveOf = (def: WeaponDef, explosives: ReadonlyMap<string, ExplosiveDef>): ExplosiveDef | null => {\n const id = def.action.kind === 'launcher' ? def.action.projectile : def.action.kind === 'throwable' ? def.action.explosive : undefined\n return id === undefined ? null : explosives.get(id) ?? null\n}\n\nconst energyOf = (def: WeaponDef, calibers: ReadonlyMap<CaliberId, CaliberDef>, explosives: ReadonlyMap<string, ExplosiveDef>): number => {\n const action = def.action\n if (action.kind === 'firearm') {\n const caliber = calibers.get(action.caliber)\n const speed = action.muzzleSpeed ?? (caliber?.muzzleSpeed ?? 0) * (action.barrel ?? 1)\n return 0.5 * ((caliber?.bulletGrams ?? 0) / 1000) * speed * speed\n }\n if (action.kind === 'launcher') return explosives.get(action.projectile)?.energy ?? 0\n return action.kind === 'throwable' || action.kind === 'melee' ? action.energy : 0\n}\n\n/**\n * Create an arsenal. Order: the shipped entries, then `calibers`/`weapons`/`explosives` (added or replaced by id), then `patch`, then `remove`, then `include`;\n * a throwable that names an explosive follows that explosive. Every inconsistency found is reported in one error.\n */\nexport const createArsenal = (options: ArsenalOptions = {}): Arsenal => {\n const calibers = mergeById(CALIBERS, options.calibers)\n const explosives = mergeById(EXPLOSIVES, options.explosives)\n const weapons = mergeById(WEAPONS, options.weapons)\n applyPatches(calibers, options.patch?.calibers)\n applyPatches(explosives, options.patch?.explosives)\n resolveThrowables(weapons, explosives)\n applyPatches(weapons, options.patch?.weapons)\n removeIds(calibers, options.remove?.calibers)\n removeIds(explosives, options.remove?.explosives)\n removeIds(weapons, options.remove?.weapons)\n if (options.include) for (const [id, def] of weapons) if (!options.include(def)) weapons.delete(id)\n\n const rules = deepMerge(DEFAULT_RULES, options.rules)\n const problems = [\n ...findDuplicateIds('calibre', options.calibers),\n ...findDuplicateIds('weapon', options.weapons),\n ...findDuplicateIds('explosive', options.explosives),\n ...checkArsenal({ weapons, calibers, explosives, rules }),\n ]\n if (problems.length > 0) throw new Error(`game-weapons: the arsenal is not consistent:\\n${problems.map((problem) => ` - ${problem}`).join('\\n')}`)\n\n const strings = resolveStrings(options.locale, options.strings)\n const baseSeed = options.seed ?? 1\n let counter = 0\n\n const create = (id: WeaponId, opts: { seed?: number; reserve?: number; condition?: string; ammoQuality?: string } = {}): WeaponState => {\n const def = weapons.get(id)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${id}\"`)\n const caliber = def.action.kind === 'firearm' ? calibers.get(def.action.caliber) ?? null : null\n counter += 1\n const seed = opts.seed ?? (baseSeed + Math.imul(counter, 0x9e3779b1)) >>> 0\n const explosive = explosiveOf(def, explosives)\n return new WeaponRuntime({ def, caliber, seed, reserve: opts.reserve, rules, explosive, condition: opts.condition, ammoQuality: opts.ammoQuality })\n }\n\n return {\n calibers,\n weapons,\n explosives,\n rules,\n create,\n muzzleEnergy(caliber, barrel = 1) {\n const c = calibers.get(caliber)\n if (!c) throw new Error(`game-weapons: unknown calibre \"${caliber}\"`)\n return muzzleEnergy(c, barrel)\n },\n explosiveBody(use) {\n return createExplosiveBody(use, explosives, rules.explosives)\n },\n energy(id) {\n const def = weapons.get(id)\n if (!def) throw new Error(`game-weapons: unknown weapon \"${id}\"`)\n return energyOf(def, calibers, explosives)\n },\n name(id) {\n const weapon = weapons.get(id)\n if (weapon) return strings.weapons[id] ?? weapon.name ?? id\n return strings.explosives[id] ?? explosives.get(id)?.name ?? strings.modes[id] ?? strings.categories[id] ?? strings.faults[id] ?? strings.conditions[id] ?? calibers.get(id)?.label ?? id\n },\n list(category?: WeaponCategory) {\n const all = [...weapons.values()]\n return category ? all.filter((w) => w.category === category) : all\n },\n }\n}\n","import type { Detonation } from './explosive-body'\nimport { normalize } from './rng'\nimport type { Use, Vec3 } from './types'\nimport { dot, length, subtract } from './vec'\n\nexport interface BlastEffect {\n /** `lethal` kills and dismembers, `injury` wounds, `none` is out of reach (or behind a directional charge). */\n readonly zone: 'lethal' | 'injury' | 'none'\n readonly distance: number\n /** 1 in the lethal zone, falling linearly to 0 at the edge of the injury zone. */\n readonly falloff: number\n /** Seconds of stun for whoever is in reach (flashbang). */\n readonly stunSeconds: number\n}\n\nconst OUT_OF_REACH: BlastEffect = { zone: 'none', distance: Infinity, falloff: 0, stunSeconds: 0 }\n\nconst insideCone = (offset: Vec3, facing: Vec3, halfAngleDeg: number): boolean => {\n const distance = length(offset)\n if (distance <= 1e-9) return true\n return dot(offset, normalize(facing)) / distance >= Math.cos((halfAngleDeg * Math.PI) / 180)\n}\n\n/** What a detonation does to something at `target`: the zone, how hard, and the stun. A directional charge only reaches inside its cone. */\nexport const blastEffect = (detonation: Detonation, target: Vec3): BlastEffect => {\n const offset = subtract(target, detonation.point)\n const distance = length(offset)\n const { lethalRadius, injuryRadius, cone } = detonation\n const reach = cone ? Math.min(injuryRadius, cone.length) : injuryRadius\n if (distance > reach) return OUT_OF_REACH\n if (cone && !insideCone(offset, detonation.direction, cone.halfAngleDeg)) return OUT_OF_REACH\n const stunSeconds = detonation.stunSeconds ?? 0\n if (distance <= lethalRadius) return { zone: 'lethal', distance, falloff: 1, stunSeconds }\n const span = reach - lethalRadius\n return { zone: 'injury', distance, falloff: span > 0 ? 1 - (distance - lethalRadius) / span : 1, stunSeconds }\n}\n\n/** How much of the blast behind a launcher reaches `target`: 0 outside the cone or the radius, falling linearly from 1 at the tube. */\nexport const backblastEffect = (use: Extract<Use, { kind: 'backblast' }>, target: Vec3): number => {\n const offset = subtract(target, use.origin)\n const distance = length(offset)\n if (distance > use.radius || !insideCone(offset, use.direction, use.halfAngleDeg)) return 0\n return 1 - distance / use.radius\n}\n\nexport interface TripwireSegment {\n readonly from: Vec3\n readonly to: Vec3\n}\n\n/**\n * Where the wire of a charge set down with `use` runs: from the charge, `length` metres along the horizontal facing turned by `angleDeg`\n * (counter-clockwise seen from above), `height` metres above it. Null for a charge with no wire.\n */\nexport const tripwireSegment = (use: Extract<Use, { kind: 'place' }>): TripwireSegment | null => {\n const wire = use.tripwire\n if (!wire) return null\n const facing = normalize([use.direction[0], 0, use.direction[2]])\n const angle = (wire.angleDeg * Math.PI) / 180\n const dx = facing[0] * Math.cos(angle) + facing[2] * Math.sin(angle)\n const dz = -facing[0] * Math.sin(angle) + facing[2] * Math.cos(angle)\n const from: Vec3 = [use.origin[0], use.origin[1] + wire.height, use.origin[2]]\n return { from, to: [from[0] + dx * wire.length, from[1], from[2] + dz * wire.length] }\n}\n","import type { ReloadStageId, WeaponEvent } from '@adatechnology/game-weapons'\n\nimport type { GAME_SOUND_CLASSES } from './shot-sound'\n\n/** One layer of a mechanical sound; `at` is seconds after the start. */\nexport type SoundStep =\n /** Metal click: a short high noise plus a square tone at 0.6 × the frequency (the SDK synth, as before). */\n | { readonly layer: 'metal'; readonly at: number; readonly frequency: number; readonly gain: number }\n /** A sound class of the game (`recarga`, `vazio`...) played at a volume. */\n | { readonly layer: 'class'; readonly at: number; readonly soundClass: keyof typeof GAME_SOUND_CLASSES; readonly volume: number }\n /** Dull landing: lowpass noise. */\n | { readonly layer: 'thud'; readonly at: number; readonly gain: number; readonly frequency: number }\n\nexport type MechanicalSoundId =\n | ReloadStageId\n | 'dry_fire'\n | 'misfire'\n | 'feed'\n | 'cycle'\n | 'mode'\n | 'safety_on'\n | 'safety_off'\n | 'jam'\n | 'clear_start'\n | 'clear_end'\n\nconst metal = (at: number, frequency: number, gain: number): SoundStep => ({ layer: 'metal', at, frequency, gain })\nconst sound = (at: number, soundClass: keyof typeof GAME_SOUND_CLASSES, volume: number): SoundStep => ({ layer: 'class', at, soundClass, volume })\nconst thud = (at: number, gain: number, frequency: number): SoundStep => ({ layer: 'thud', at, gain, frequency })\n\nconst slide = [metal(0, 900, 0.35), metal(0.14, 1300, 0.35)]\nconst seat = [metal(0, 1100, 0.45), sound(0, 'reload', 0.8)]\n\n/**\n * Sounds keyed by the rule: the `reload_stage` ids of `RELOAD_STAGES`, plus the other weapon events. The click of an empty weapon and the generic\n * reload tick are the game's `vazio` and `recarga` classes (jogo.js L62101-L62104; played at L68644-L68662); the gallery (sources/armas-itens__galeria-3d-arsenal.js)\n * has no sound, so the metal layers are the SDK synth (the same `metal` used since the first version).\n */\nexport const MECHANICAL_SOUNDS: Readonly<Record<MechanicalSoundId, readonly SoundStep[]>> = {\n dry_fire: [sound(0, 'empty', 1), metal(0, 2600, 0.25)],\n misfire: [sound(0, 'empty', 0.8), metal(0, 2200, 0.2)],\n feed: [metal(0, 1900, 0.2)],\n cycle: [metal(0.22, 900, 0.35), metal(0.36, 1300, 0.35)],\n mode: [metal(0, 2000, 0.15)],\n safety_on: [metal(0, 2200, 0.22)],\n safety_off: [metal(0, 1800, 0.22)],\n jam: [metal(0, 700, 0.4), metal(0.08, 500, 0.35)],\n clear_start: [metal(0, 1000, 0.3)],\n clear_end: [metal(0, 1300, 0.35)],\n magazine_out: [metal(0, 1500, 0.35), sound(0, 'reload', 0.6)],\n magazine_in: seat,\n charge: slide,\n bolt_open: [metal(0, 900, 0.35)],\n round_in: [metal(0, 2000, 0.2), sound(0, 'reload', 0.6)],\n bolt_close: [metal(0, 1300, 0.35)],\n pump_cycle: slide,\n lever_cycle: [metal(0, 1000, 0.35), metal(0.12, 1500, 0.35)],\n cylinder_open: [metal(0, 1500, 0.3)],\n cylinder_eject: [metal(0, 2400, 0.25), metal(0.05, 2800, 0.2)],\n cylinder_load: [metal(0, 2000, 0.2)],\n cylinder_close: seat,\n barrels_open: [metal(0, 1000, 0.4)],\n casings_eject: [metal(0, 2600, 0.25)],\n rounds_in: [metal(0, 2000, 0.25), sound(0, 'reload', 0.6)],\n barrels_close: seat,\n cover_open: [metal(0, 800, 0.4)],\n belt_swap: [metal(0, 1400, 0.3), metal(0.08, 1800, 0.25)],\n cover_close: [metal(0, 1000, 0.45)],\n tank_swap: [thud(0, 0.4, 500), metal(0.05, 600, 0.3)],\n tube_drop: [thud(0, 0.35, 380)],\n tube_seat: seat,\n rocket_seat: [metal(0, 900, 0.45), sound(0, 'reload', 0.8)],\n breech_open: [metal(0, 1000, 0.35)],\n breech_close: seat,\n}\n\n/** Which mechanical sound a weapon event asks for, if any (`shot`, `draw` and `reload` start/end have their own handling). */\nexport const mechanicalSoundOf = (event: WeaponEvent): MechanicalSoundId | undefined => {\n switch (event.type) {\n case 'reload_stage':\n return event.stage\n case 'empty':\n return 'dry_fire'\n case 'misfire':\n return 'misfire'\n case 'feed':\n return 'feed'\n case 'cycle':\n return event.phase === 'start' ? 'cycle' : undefined\n case 'mode':\n return 'mode'\n case 'safety':\n return event.on ? 'safety_on' : 'safety_off'\n case 'fault':\n return 'jam'\n case 'clear':\n return event.phase === 'start' ? 'clear_start' : 'clear_end'\n default:\n return undefined\n }\n}\n","import { muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { CaliberDef } from '@adatechnology/game-weapons'\n\n/** One sound of the game: [lowpass cutoff Hz, gain, seconds]. Literal from the `P` table of `sfx` in the game (jogo.js L62101-L62104). */\nexport type SoundClassDef = readonly [cutoff: number, gain: number, seconds: number]\n\n/** The game names are pistola, escopeta, fuzil, rifle, impacto, carne, passo, vidro, madeira, recarga, vazio and explosao. */\nexport const GAME_SOUND_CLASSES = {\n pistol: [1800, 0.9, 0.18],\n shotgun: [900, 1.2, 0.35],\n rifle: [1400, 1.1, 0.28],\n long_rifle: [1100, 1.3, 0.45],\n impact: [2500, 0.25, 0.05],\n flesh: [600, 0.35, 0.08],\n step: [400, 0.08, 0.05],\n glass: [5000, 0.5, 0.3],\n wood: [700, 0.5, 0.2],\n reload: [3000, 0.15, 0.06],\n empty: [4000, 0.12, 0.03],\n explosion: [200, 1.6, 1.4],\n} as const satisfies Record<string, SoundClassDef>\n\n/** `|| [1000, 0.5, 0.1]` of the game (jogo.js L62104), for a class name that is not in the table. */\nexport const FALLBACK_SOUND_CLASS: SoundClassDef = [1000, 0.5, 0.1]\n\n/** The four classes a shot can have: the game picks one by calibre (jogo.js L68697). */\nexport type ShotSoundClass = 'pistol' | 'shotgun' | 'rifle' | 'long_rifle'\n\n/** Distance muffling of the game (jogo.js L62092, L62105): `gain / (1 + d² × gainFalloff)`, `cutoff / (1 + d × cutoffFalloff)`, silent under `minGain`. */\nexport type DistanceCurve = { readonly gainFalloff: number; readonly cutoffFalloff: number; readonly minGain: number }\nexport const GAME_DISTANCE_CURVE: DistanceCurve = { gainFalloff: 0.004, cutoffFalloff: 0.01, minGain: 0.01 }\n\n/**\n * The calibre energy (joules) scales loudness, length and brightness around the class: each factor is `base + span × k`, where k goes from 0 (50 J)\n * to 1 (50 J × 10^spanDecades) on a log scale, divided by the same factor at the class reference energy. So the game calibres sound exactly as in\n * the game, and a lighter or heavier calibre of the same class is quieter and brighter, or louder and duller.\n */\nexport type EnergyCurve = {\n readonly floorJ: number\n readonly spanDecades: number\n readonly gain: readonly [base: number, span: number]\n readonly duration: readonly [base: number, span: number]\n readonly cutoff: readonly [base: number, span: number]\n /** The muzzle crack (high noise) and the body (low thump) follow the energy alone. */\n readonly crackGain: readonly [base: number, span: number]\n readonly bodyGain: readonly [base: number, span: number]\n readonly bodyDuration: readonly [base: number, span: number]\n readonly bodyFrequency: readonly [base: number, span: number]\n}\n\nexport const DEFAULT_ENERGY_CURVE: EnergyCurve = {\n floorJ: 50,\n spanDecades: 2.5,\n gain: [0.7, 0.6],\n duration: [0.75, 0.5],\n cutoff: [1.15, -0.3],\n crackGain: [0.3, 0.4],\n bodyGain: [0.35, 0.4],\n bodyDuration: [0.14, 0.2],\n bodyFrequency: [140, -70],\n}\n\n/** Muzzle energy of the game calibres in the SDK (9x19, 12ga_00buck × pellets, 7_62x39, 7_62x51): where a class sounds exactly as in the game. */\nexport const CLASS_REFERENCE_ENERGY: Readonly<Record<ShotSoundClass, number>> = { pistol: 500, shotgun: 2700, rifle: 2100, long_rifle: 3500 }\n\nexport type ShotSoundOptions = {\n /** Replaces or adds sound classes (the game table is the default). */\n readonly classes?: Readonly<Record<string, SoundClassDef>>\n readonly distance?: Partial<DistanceCurve>\n readonly energy?: Partial<EnergyCurve>\n readonly referenceEnergy?: Partial<Record<ShotSoundClass, number>>\n /** Picks the class of a shot; the default follows the game (shotgun by shell, handguns by category, then by energy). */\n readonly classOf?: (input: ShotSoundInput, energyJ: number) => ShotSoundClass\n /** Class bands by energy (J): below `handgunBelowJ` a pistol, below `rifleBelowJ` a rifle, above that a long rifle. */\n readonly bands?: { readonly handgunBelowJ: number; readonly rifleBelowJ: number }\n readonly suppressor?: { readonly gain: number; readonly cutoff: number; readonly crack: number; readonly body: number }\n readonly indoors?: { readonly duration: number; readonly cutoff: number }\n}\n\nexport type ShotSoundInput = {\n /** The calibre; its energy (× pellets) is used unless `energyJ` is given. */\n readonly caliber?: CaliberDef\n readonly energyJ?: number\n readonly category?: string\n /** Metres from the listener, default 0. */\n readonly distance?: number\n /** Master gain of the game `sfx` (its `vol`), default 1. */\n readonly volume?: number\n readonly suppressed?: boolean\n readonly indoors?: boolean\n}\n\nexport type ShotSound = {\n readonly soundClass: ShotSoundClass\n readonly energyJ: number\n /** False when the shot is under the game's `minGain` at this distance: nothing is played. */\n readonly audible: boolean\n /** The main noise burst: lowpass cutoff Hz, starting gain and the seconds of the exponential tail (to 0.001). */\n readonly cutoff: number\n readonly gain: number\n readonly duration: number\n /** High noise burst of the muzzle. */\n readonly crack: { readonly gain: number; readonly cutoff: number; readonly duration: number }\n /** Low thump that sweeps from `frequency` to `to`. */\n readonly body: { readonly gain: number; readonly frequency: number; readonly to: number; readonly duration: number }\n}\n\nconst HANDGUN_CATEGORIES: ReadonlySet<string> = new Set(['pistol', 'revolver', 'smg'])\nconst SHELL_KINDS: ReadonlySet<string> = new Set(['buck', 'slug', 'birdshot'])\nconst DEFAULT_BANDS = { handgunBelowJ: 1000, rifleBelowJ: 3000 }\nconst DEFAULT_SUPPRESSOR = { gain: 0.3, cutoff: 0.6, crack: 0, body: 0.5 }\nconst DEFAULT_INDOORS = { duration: 1.5, cutoff: 0.85 }\nconst CRACK_CUTOFF = 3000\nconst CRACK_SECONDS = 0.03\nconst BODY_TO_FREQUENCY = 40\n\nconst linear = ([base, span]: readonly [number, number], k: number): number => base + span * k\n\nconst energyPosition = (energyJ: number, curve: EnergyCurve): number =>\n Math.min(1, Math.max(0, Math.log10(Math.max(energyJ, curve.floorJ) / curve.floorJ) / curve.spanDecades))\n\nexport const energyOfShot = (input: ShotSoundInput): number => {\n if (input.energyJ !== undefined) return input.energyJ\n if (!input.caliber) return 0\n return muzzleEnergy(input.caliber) * (input.caliber.pellets ?? 1)\n}\n\nconst defaultClassOf = (input: ShotSoundInput, energyJ: number, bands: { handgunBelowJ: number; rifleBelowJ: number }): ShotSoundClass => {\n if (input.category === 'shotgun' || (input.caliber?.pellets ?? 1) > 1 || SHELL_KINDS.has(input.caliber?.kind ?? '')) return 'shotgun'\n if (input.category && HANDGUN_CATEGORIES.has(input.category)) return 'pistol'\n if (energyJ < bands.handgunBelowJ) return 'pistol'\n return energyJ < bands.rifleBelowJ ? 'rifle' : 'long_rifle'\n}\n\n/**\n * The parameters of a gunshot, without WebAudio: the sound class and the distance muffling of the game (S2) with the calibre energy of the SDK.\n * Pure and deterministic; the playback layer only turns it into nodes.\n */\nexport const computeShotSound = (input: ShotSoundInput, options: ShotSoundOptions = {}): ShotSound => {\n const curve: EnergyCurve = { ...DEFAULT_ENERGY_CURVE, ...options.energy }\n const distanceCurve: DistanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance }\n const energyJ = energyOfShot(input)\n const soundClass = options.classOf ? options.classOf(input, energyJ) : defaultClassOf(input, energyJ, options.bands ?? DEFAULT_BANDS)\n const table: Readonly<Record<string, SoundClassDef>> = { ...GAME_SOUND_CLASSES, ...options.classes }\n const [classCutoff, classGain, classSeconds] = table[soundClass] ?? FALLBACK_SOUND_CLASS\n const referenceEnergy = options.referenceEnergy?.[soundClass] ?? CLASS_REFERENCE_ENERGY[soundClass] ?? energyJ\n\n const k = energyPosition(energyJ, curve)\n const referenceK = energyPosition(referenceEnergy, curve)\n const distance = Math.max(0, input.distance ?? 0)\n const attenuation = (input.volume ?? 1) / (1 + distance * distance * distanceCurve.gainFalloff)\n const muffling = 1 / (1 + distance * distanceCurve.cutoffFalloff)\n\n const suppressor = input.suppressed ? { ...DEFAULT_SUPPRESSOR, ...options.suppressor } : { gain: 1, cutoff: 1, crack: 1, body: 1 }\n const indoors = input.indoors ? { ...DEFAULT_INDOORS, ...options.indoors } : { duration: 1, cutoff: 1 }\n\n const gain = classGain * attenuation * (linear(curve.gain, k) / linear(curve.gain, referenceK)) * suppressor.gain\n const duration = classSeconds * (linear(curve.duration, k) / linear(curve.duration, referenceK)) * indoors.duration\n const cutoff = classCutoff * muffling * (linear(curve.cutoff, k) / linear(curve.cutoff, referenceK)) * suppressor.cutoff * indoors.cutoff\n\n return {\n soundClass,\n energyJ,\n audible: attenuation >= distanceCurve.minGain,\n cutoff,\n gain,\n duration,\n crack: { gain: linear(curve.crackGain, k) * attenuation * suppressor.crack, cutoff: CRACK_CUTOFF, duration: CRACK_SECONDS },\n body: {\n gain: linear(curve.bodyGain, k) * attenuation * suppressor.body,\n frequency: linear(curve.bodyFrequency, k),\n to: BODY_TO_FREQUENCY,\n duration: linear(curve.bodyDuration, k) * indoors.duration,\n },\n }\n}\n","// Weapon sounds synthesized with WebAudio: no sound files, so the kit stays offline and small. Every call is a no-op where there is no\n// AudioContext (tests, workers), and the context is only created on the first sound, which comes from a click or a key (browsers allow it).\n// The numbers live in ./audio/*: `computeShotSound` is pure and this file only turns its result into nodes.\nimport { createRng } from '@adatechnology/game-weapons'\nimport type { WeaponEvent } from '@adatechnology/game-weapons'\n\nimport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nimport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\nimport { computeShotSound, FALLBACK_SOUND_CLASS, GAME_DISTANCE_CURVE, GAME_SOUND_CLASSES } from './audio/shot-sound'\nimport type { ShotSound, ShotSoundInput, ShotSoundOptions, SoundClassDef } from './audio/shot-sound'\n\nexport { computeShotSound, GAME_SOUND_CLASSES, GAME_DISTANCE_CURVE, DEFAULT_ENERGY_CURVE, CLASS_REFERENCE_ENERGY } from './audio/shot-sound'\nexport type { ShotSound, ShotSoundInput, ShotSoundOptions, ShotSoundClass, SoundClassDef, DistanceCurve, EnergyCurve } from './audio/shot-sound'\nexport { MECHANICAL_SOUNDS, mechanicalSoundOf } from './audio/mechanical-sounds'\nexport type { MechanicalSoundId, SoundStep } from './audio/mechanical-sounds'\n\n/** What a shot adds to the energy and the category: where the listener is and how the weapon is set. */\nexport type ShotExtras = Pick<ShotSoundInput, 'caliber' | 'distance' | 'volume' | 'suppressed' | 'indoors'>\n\nexport interface WeaponAudioOptions extends ShotSoundOptions {\n /** Seed of the noise buffer, of the start point in it and of the casing pitch: same seed, same sound. Default 1. */\n readonly seed?: number\n /** Replaces or adds mechanical sounds by id. */\n readonly mechanical?: Readonly<Partial<Record<MechanicalSoundId, readonly SoundStep[]>>>\n /** Where the AudioContext comes from (default: the global one); lets a host or a test lend its own. */\n readonly createContext?: () => AudioContext\n}\n\n/** Sounds the weapon presentation plays. */\nexport interface WeaponAudio {\n /** A shot: class and distance muffling of the game, loudness and body from the muzzle energy (joules). */\n shot(energyJ: number, category: string, extras?: ShotExtras): void\n /** The parameters `shot` would play (pure). */\n shotSound(input: ShotSoundInput): ShotSound\n /** Dry click of an empty weapon. */\n click(): void\n /** A mechanical sound by id: a reload stage, `dry_fire`, `jam`, `safety_on`... */\n mechanical(id: MechanicalSoundId): void\n /** The mechanical sound of a weapon event, if it has one (reload stages, empty, misfire, fault, clear, safety, mode, feed). */\n event(event: WeaponEvent): void\n /** A sound class of the game by name (`impact`, `flesh`, `glass`...), with the game's distance muffling. */\n play(soundClass: string, volume?: number, distance?: number): void\n /** Magazine out, or the first shell in. */\n reloadStart(category: string): void\n /** Magazine seated and the action racked. */\n reloadEnd(category: string): void\n /** The pump or lever cycling after a shot. */\n cycle(): void\n /** A casing bouncing on the floor. */\n clink(): void\n /** A magazine landing on the floor. */\n thud(): void\n /** Master volume, 0 to 1. */\n setVolume(volume: number): void\n dispose(): void\n}\n\ntype AudioContextCtor = new () => AudioContext\n\nconst NOISE_SECONDS = 1.5\n\nconst globalContext = (): AudioContext | null => {\n const scope = globalThis as { AudioContext?: AudioContextCtor; webkitAudioContext?: AudioContextCtor }\n const Ctor = scope.AudioContext ?? scope.webkitAudioContext\n return Ctor ? new Ctor() : null\n}\n\nexport function createWeaponAudio(volume = 0.6, options: WeaponAudioOptions = {}): WeaponAudio {\n const makeContext = options.createContext ?? globalContext\n const rng = createRng(options.seed ?? 1)\n const classes: Readonly<Record<string, SoundClassDef>> = { ...GAME_SOUND_CLASSES, ...options.classes }\n const distanceCurve = { ...GAME_DISTANCE_CURVE, ...options.distance }\n const mechanicalTable = { ...MECHANICAL_SOUNDS, ...options.mechanical }\n let ctx: AudioContext | null = null\n let master: GainNode | null = null\n let noise: AudioBuffer | null = null\n let level = volume\n\n const ready = (): AudioContext | null => {\n if (!ctx) {\n const created = makeContext()\n if (!created) return null\n ctx = created\n master = ctx.createGain()\n master.gain.value = level\n master.connect(ctx.destination)\n noise = ctx.createBuffer(1, Math.floor(ctx.sampleRate * NOISE_SECONDS), ctx.sampleRate)\n const data = noise.getChannelData(0)\n for (let i = 0; i < data.length; i++) data[i] = rng() * 2 - 1\n }\n if (ctx.state === 'suspended') void ctx.resume()\n return ctx\n }\n\n // a filtered noise burst with a fast attack and an exponential tail\n const burst = (config: { at?: number; seconds: number; gain: number; filter: BiquadFilterType; frequency: number; q?: number }): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + (config.at ?? 0)\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = config.filter\n filter.frequency.value = config.frequency\n filter.Q.value = config.q ?? 0.8\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 0.0002), start + 0.004)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + config.seconds)\n source.connect(filter).connect(gain).connect(master)\n source.start(start, rng() * Math.max(0, NOISE_SECONDS - config.seconds))\n source.stop(start + config.seconds + 0.05)\n }\n\n // the game `sfx`: lowpass noise, gain set at once and an exponential fall to 0.001 (jogo.js L62097-L62110)\n const classBurst = (at: number, cutoff: number, gain: number, seconds: number): void => {\n const audio = ready()\n if (!audio || !noise || !master) return\n const start = audio.currentTime + at\n const source = audio.createBufferSource()\n source.buffer = noise\n const filter = audio.createBiquadFilter()\n filter.type = 'lowpass'\n filter.frequency.value = cutoff\n const envelope = audio.createGain()\n envelope.gain.setValueAtTime(gain, start)\n envelope.gain.exponentialRampToValueAtTime(0.001, start + seconds)\n source.connect(filter).connect(envelope).connect(master)\n source.start(start, rng() * Math.max(0, NOISE_SECONDS - seconds))\n source.stop(start + seconds + 0.05)\n }\n\n const tone = (config: { at?: number; seconds: number; gain: number; frequency: number; to?: number; type?: OscillatorType }): void => {\n const audio = ready()\n if (!audio || !master) return\n const start = audio.currentTime + (config.at ?? 0)\n const osc = audio.createOscillator()\n osc.type = config.type ?? 'sine'\n osc.frequency.setValueAtTime(config.frequency, start)\n if (config.to) osc.frequency.exponentialRampToValueAtTime(config.to, start + config.seconds)\n const gain = audio.createGain()\n gain.gain.setValueAtTime(0.0001, start)\n gain.gain.exponentialRampToValueAtTime(Math.max(config.gain, 0.0002), start + 0.003)\n gain.gain.exponentialRampToValueAtTime(0.0001, start + config.seconds)\n osc.connect(gain).connect(master)\n osc.start(start)\n osc.stop(start + config.seconds + 0.05)\n }\n\n const metal = (at: number, frequency: number, gain: number): void => {\n burst({ at, seconds: 0.05, gain, filter: 'highpass', frequency, q: 2 })\n tone({ at, seconds: 0.04, gain: gain * 0.6, frequency: frequency * 0.6, type: 'square' })\n }\n\n const play = (soundClass: string, classVolume = 1, distance = 0, at = 0): void => {\n const attenuation = classVolume / (1 + distance * distance * distanceCurve.gainFalloff)\n if (attenuation < distanceCurve.minGain) return\n const [cutoff, gain, seconds] = classes[soundClass] ?? FALLBACK_SOUND_CLASS\n classBurst(at, cutoff / (1 + distance * distanceCurve.cutoffFalloff), gain * attenuation, seconds)\n }\n\n const step = (entry: SoundStep): void => {\n if (entry.layer === 'metal') metal(entry.at, entry.frequency, entry.gain)\n else if (entry.layer === 'class') play(entry.soundClass, entry.volume, 0, entry.at)\n else burst({ at: entry.at, seconds: 0.09, gain: entry.gain, filter: 'lowpass', frequency: entry.frequency })\n }\n\n const mechanical = (id: MechanicalSoundId): void => {\n for (const entry of mechanicalTable[id] ?? []) step(entry)\n }\n\n const shotSound = (input: ShotSoundInput): ShotSound => computeShotSound(input, options)\n\n return {\n shot(energyJ, category, extras = {}) {\n const sound = shotSound({ ...extras, energyJ, category })\n if (!sound.audible) return\n classBurst(0, sound.cutoff, sound.gain, sound.duration)\n if (sound.crack.gain > 0) burst({ seconds: sound.crack.duration, gain: sound.crack.gain, filter: 'highpass', frequency: sound.crack.cutoff })\n tone({ seconds: sound.body.duration, gain: sound.body.gain, frequency: sound.body.frequency, to: sound.body.to })\n },\n shotSound,\n click() {\n mechanical('dry_fire')\n },\n mechanical,\n event(event) {\n const id = mechanicalSoundOf(event)\n if (id) mechanical(id)\n },\n play(soundClass, classVolume, distance) {\n play(soundClass, classVolume, distance)\n },\n reloadStart(category) {\n metal(0, 1500, 0.35)\n if (category !== 'shotgun' && category !== 'revolver') metal(0.12, 900, 0.2)\n },\n reloadEnd(category) {\n metal(0, 1100, 0.45)\n if (category !== 'revolver') metal(0.18, 1900, 0.4)\n },\n cycle() {\n mechanical('cycle')\n },\n clink() {\n const f = 3200 + rng() * 2000\n tone({ seconds: 0.09, gain: 0.12, frequency: f })\n tone({ seconds: 0.06, gain: 0.06, frequency: f * 2.7 })\n },\n thud() {\n burst({ seconds: 0.09, gain: 0.35, filter: 'lowpass', frequency: 380 })\n },\n setVolume(next) {\n level = Math.max(0, Math.min(1, next))\n if (master) master.gain.value = level\n },\n dispose() {\n void ctx?.close()\n ctx = null\n master = null\n noise = null\n },\n }\n}\n","/** What the bench turns on or off in the presentation of the weapon: the ejected casings, the dropped magazines and the muzzle flash. */\nexport interface FxLayers {\n casings: boolean\n magazines: boolean\n muzzleFlash: boolean\n}\n\nexport const createLayers = (): FxLayers => ({ casings: true, magazines: true, muzzleFlash: true })\n","import type * as THREE_NS from 'three'\n\nconst ATTRIBUTES = ['position', 'normal', 'uv'] as const\n\nconst isVisible = (object: THREE_NS.Object3D): boolean => {\n for (let node: THREE_NS.Object3D | null = object; node; node = node.parent) if (!node.visible) return false\n return true\n}\n\n/** A copy of the geometry with the matrix baked in, not indexed, keeping only what every model has (position, normal, uv), so that any two of them can be joined. */\nconst bake = (THREE: typeof THREE_NS, mesh: THREE_NS.Mesh, matrix: THREE_NS.Matrix4): THREE_NS.BufferGeometry => {\n const source = mesh.geometry.index ? mesh.geometry.toNonIndexed() : mesh.geometry.clone()\n const baked = new THREE.BufferGeometry()\n const count = source.getAttribute('position').count\n for (const name of ATTRIBUTES) {\n const attribute = source.getAttribute(name)\n baked.setAttribute(name, attribute ?? new THREE.BufferAttribute(new Float32Array(count * (name === 'uv' ? 2 : 3)), name === 'uv' ? 2 : 3))\n }\n source.dispose()\n return baked.applyMatrix4(matrix)\n}\n\n/** One non-indexed geometry out of several, in order (the port of `mergeGeometries` of three/addons for the three attributes above). */\nconst join = (THREE: typeof THREE_NS, geometries: readonly THREE_NS.BufferGeometry[]): THREE_NS.BufferGeometry => {\n const merged = new THREE.BufferGeometry()\n for (const name of ATTRIBUTES) {\n const size = (geometries[0]?.getAttribute(name) as THREE_NS.BufferAttribute).itemSize\n const total = geometries.reduce((sum, geometry) => sum + geometry.getAttribute(name).count, 0)\n const array = new Float32Array(total * size)\n let offset = 0\n for (const geometry of geometries) {\n array.set(geometry.getAttribute(name).array, offset)\n offset += geometry.getAttribute(name).count * size\n }\n merged.setAttribute(name, new THREE.BufferAttribute(array, size))\n }\n return merged\n}\n\n/**\n * Every visible mesh under `root` (whose world matrix must be up to date), baked into the space of `space` and joined by material: one mesh per material, no shadow cast.\n * Weapons lying on a counter are never animated, so the hundreds of meshes of a model cost one draw call per material instead.\n */\nexport function mergeByMaterial(THREE: typeof THREE_NS, root: THREE_NS.Object3D, space: THREE_NS.Object3D): THREE_NS.Mesh[] {\n const toSpace = space.matrixWorld.clone().invert()\n const byMaterial = new Map<THREE_NS.Material, THREE_NS.BufferGeometry[]>()\n root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh || Array.isArray(mesh.material) || !isVisible(mesh)) return\n const list = byMaterial.get(mesh.material) ?? []\n list.push(bake(THREE, mesh, new THREE.Matrix4().multiplyMatrices(toSpace, mesh.matrixWorld)))\n byMaterial.set(mesh.material, list)\n })\n return [...byMaterial].map(([material, geometries]) => {\n const merged = new THREE.Mesh(join(THREE, geometries), material)\n for (const geometry of geometries) geometry.dispose()\n merged.castShadow = false\n merged.receiveShadow = true\n return merged\n })\n}\n","{\n \"glock_17\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 202,\n \"barrel\": 114,\n \"options\": {\n \"st\": \"glock\",\n \"rel\": 0.7\n }\n },\n \"glock_18\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 202,\n \"barrel\": 114,\n \"options\": {\n \"st\": \"glock\",\n \"sel\": 1,\n \"rpm\": 1200,\n \"rel\": 0.9\n }\n },\n \"glock_19\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 185,\n \"barrel\": 102,\n \"options\": {\n \"st\": \"glock\",\n \"gl\": 0.095,\n \"rel\": 0.7\n }\n },\n \"taurus_g2c\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 159,\n \"barrel\": 81,\n \"options\": {\n \"st\": \"g2c\",\n \"gl\": 0.085,\n \"rel\": 1.5\n }\n },\n \"taurus_ts9\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 194,\n \"barrel\": 104,\n \"options\": {\n \"st\": \"taurus\",\n \"rel\": 1.2\n }\n },\n \"beretta_92fs\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 217,\n \"barrel\": 125,\n \"options\": {\n \"st\": \"beretta\",\n \"h\": 0.032,\n \"rel\": 0.9\n }\n },\n \"sig_sauer_p226\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 196,\n \"barrel\": 112,\n \"options\": {\n \"st\": \"sig\",\n \"h\": 0.034,\n \"rel\": 0.8\n }\n },\n \"cz_75\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×19\",\n \"length\": 206,\n \"barrel\": 120,\n \"options\": {\n \"st\": \"cz\",\n \"h\": 0.03,\n \"rel\": 0.9\n }\n },\n \"taurus_pt100\": {\n \"builder\": \"pistol\",\n \"caliber\": \".40 S&W\",\n \"length\": 216,\n \"barrel\": 127,\n \"options\": {\n \"st\": \"pt100\",\n \"stain\": 1,\n \"rel\": 1.2\n }\n },\n \"colt_m1911\": {\n \"builder\": \"pistol\",\n \"caliber\": \".45 ACP\",\n \"length\": 216,\n \"barrel\": 127,\n \"options\": {\n \"st\": \"m1911\",\n \"h\": 0.029,\n \"gl\": 0.1,\n \"rel\": 1.1\n }\n },\n \"makarov_pm\": {\n \"builder\": \"pistol\",\n \"caliber\": \"9×18\",\n \"length\": 161,\n \"barrel\": 94,\n \"options\": {\n \"st\": \"makarov\",\n \"h\": 0.028,\n \"gl\": 0.088,\n \"rel\": 0.8\n }\n },\n \"fn_five_seven\": {\n \"builder\": \"pistol\",\n \"caliber\": \"5,7×28\",\n \"length\": 208,\n \"barrel\": 122,\n \"options\": {\n \"st\": \"fiveseven\",\n \"gl\": 0.12,\n \"rel\": 0.9\n }\n },\n \"desert_eagle_mark_xix\": {\n \"builder\": \"pistol\",\n \"caliber\": \".50 AE\",\n \"length\": 270,\n \"barrel\": 152,\n \"options\": {\n \"st\": \"deagle\",\n \"h\": 0.04,\n \"gl\": 0.125,\n \"deagle\": 1,\n \"steel\": 1,\n \"rel\": 1.8\n }\n },\n \"taurus_82\": {\n \"builder\": \"revolver\",\n \"caliber\": \".38 SPL\",\n \"length\": 240,\n \"barrel\": 102,\n \"options\": {\n \"wood\": 1\n }\n },\n \"sw_686\": {\n \"builder\": \"revolver\",\n \"caliber\": \".357 Magnum\",\n \"length\": 244,\n \"barrel\": 102,\n \"options\": {\n \"steel\": 1,\n \"chambers\": 7\n }\n },\n \"sw_model_29\": {\n \"builder\": \"revolver\",\n \"caliber\": \".44 Magnum\",\n \"length\": 302,\n \"barrel\": 165,\n \"options\": {\n \"wood\": 1\n }\n },\n \"hk_mp5a3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 700,\n \"barrel\": 225,\n \"options\": {\n \"mag\": \"curved\",\n \"magLen\": 0.72,\n \"stock\": \"retract\",\n \"stockLen\": 0.22,\n \"hR\": 0.055,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"g3\": 1,\n \"rpm\": 800,\n \"sel\": 1\n }\n },\n \"taurus_smt9\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 660,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"box\",\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hg\": \"rail\",\n \"hgFrac\": 0.8,\n \"rail\": 1,\n \"rpm\": 750,\n \"sel\": 1\n }\n },\n \"hk_ump_45\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 690,\n \"barrel\": 200,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.22,\n \"hR\": 0.07,\n \"hg\": \"poly\",\n \"hgFrac\": 0.85,\n \"rpm\": 600,\n \"sel\": 1,\n \"rail\": 1\n }\n },\n \"uzi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 650,\n \"barrel\": 260,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.06,\n \"magLen\": 1.3,\n \"stock\": \"fold\",\n \"stockLen\": 0.2,\n \"hR\": 0.065,\n \"hg\": \"poly\",\n \"hgFrac\": 0.4,\n \"grip\": \"none\",\n \"rpm\": 600\n }\n },\n \"fn_p90\": {\n \"builder\": \"p90\",\n \"caliber\": \"5,7×28\",\n \"length\": 500,\n \"barrel\": 264,\n \"options\": {\n \"rpm\": 900\n }\n },\n \"kriss_vector\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 622,\n \"barrel\": 140,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.1,\n \"stock\": \"retract\",\n \"stockLen\": 0.2,\n \"hR\": 0.085,\n \"hg\": \"rail\",\n \"hgFrac\": 0.9,\n \"rail\": 1,\n \"scope\": 1,\n \"rpm\": 1100\n }\n },\n \"thompson_m1a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 813,\n \"barrel\": 267,\n \"options\": {\n \"wood\": 1,\n \"mag\": \"box\",\n \"magLen\": 1.2,\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"hg\": \"none\",\n \"hR\": 0.055,\n \"jacket\": 1,\n \"rpm\": 700,\n \"charge\": 1\n }\n },\n \"cz_scorpion_evo_3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"9×19\",\n \"length\": 670,\n \"barrel\": 196,\n \"options\": {\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.2,\n \"stock\": \"fold\",\n \"stockLen\": 0.22,\n \"hg\": \"rail\",\n \"hgFrac\": 0.85,\n \"rail\": 1,\n \"scope\": 1,\n \"rpm\": 1150\n }\n },\n \"mac_10\": {\n \"builder\": \"rifle\",\n \"caliber\": \".45 ACP\",\n \"length\": 548,\n \"barrel\": 146,\n \"options\": {\n \"mag\": \"box\",\n \"magAt\": 0.04,\n \"magLen\": 1.2,\n \"stock\": \"fold\",\n \"stockLen\": 0.22,\n \"hR\": 0.075,\n \"hg\": \"none\",\n \"grip\": \"none\",\n \"brake\": 2,\n \"rpm\": 1090,\n \"rel\": 1.4\n }\n },\n \"remington_870\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 990,\n \"barrel\": 470,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n }\n },\n \"mossberg_500\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 990,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"noFH\": 1\n }\n },\n \"cbc_pump_military_3_0\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1000,\n \"barrel\": 480,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"tubeLen\": 0.95,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.055,\n \"rail\": 1,\n \"noFH\": 1\n }\n },\n \"benelli_m4\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1010,\n \"barrel\": 470,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"br\": 0.0105,\n \"hR\": 0.06,\n \"rail\": 1,\n \"scope\": 1,\n \"noFH\": 1,\n \"charge\": 1\n }\n },\n \"franchi_spas_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1041,\n \"barrel\": 546,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"pump\": 1,\n \"hg\": \"none\",\n \"br\": 0.0105,\n \"hR\": 0.06,\n \"heat\": 1,\n \"noFH\": 1\n }\n },\n \"kel_tec_ksg\": {\n \"builder\": \"bullpup\",\n \"caliber\": \"12 ga\",\n \"length\": 660,\n \"barrel\": 470,\n \"options\": {\n \"shot\": 1\n }\n },\n \"saiga_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 1000,\n \"barrel\": 430,\n \"options\": {\n \"mag\": \"box\",\n \"magLen\": 1.15,\n \"stock\": \"fixed\",\n \"hg\": \"poly\",\n \"br\": 0.0105,\n \"hR\": 0.07,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rel\": 1.3\n }\n },\n \"aa_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"12 ga\",\n \"length\": 966,\n \"barrel\": 457,\n \"options\": {\n \"mag\": \"drum\",\n \"stock\": \"fixed\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.6,\n \"br\": 0.0105,\n \"hR\": 0.085,\n \"carry\": 1,\n \"rpm\": 300\n }\n },\n \"boito_double_barrel\": {\n \"builder\": \"break\",\n \"caliber\": \"12 ga\",\n \"length\": 1130,\n \"barrel\": 710,\n \"options\": {}\n },\n \"ak_47\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 880,\n \"barrel\": 415,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"bayo\": 1,\n \"rpm\": 600,\n \"rel\": 0.4\n }\n },\n \"akm\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 880,\n \"barrel\": 415,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"wood\",\n \"mag\": \"curved\",\n \"hg\": \"wood\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"rpm\": 600,\n \"magMat\": \"bakelite\",\n \"rel\": 0.45\n }\n },\n \"ak_74\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,45×39\",\n \"length\": 943,\n \"barrel\": 415,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"curved\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.42,\n \"gas\": 1,\n \"charge\": 1,\n \"brake\": 1,\n \"ak\": 1,\n \"rod\": 1,\n \"rpm\": 650,\n \"magMat\": \"bakelite\"\n }\n },\n \"ak_12\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,45×39\",\n \"length\": 945,\n \"barrel\": 415,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"curved\",\n \"hg\": \"rail\",\n \"hgFrac\": 0.5,\n \"rail\": 1,\n \"brake\": 1,\n \"scope\": 1,\n \"charge\": 1,\n \"ak\": 1,\n \"rpm\": 700,\n \"magMat\": \"poly\"\n }\n },\n \"imbel_ia2\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 850,\n \"barrel\": 330,\n \"options\": {\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.25,\n \"hg\": \"poly\",\n \"hgFrac\": 0.6,\n \"rail\": 1,\n \"charge\": 1,\n \"rpm\": 700\n }\n },\n \"taurus_t4\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 840,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 750\n }\n },\n \"colt_m4a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 840,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.6,\n \"rail\": 1,\n \"scope\": 2,\n \"ar\": 1,\n \"rpm\": 800\n }\n },\n \"colt_m16a2\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1000,\n \"barrel\": 508,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"carry\": 1,\n \"ar\": 1,\n \"rpm\": 800,\n \"burst\": 3\n }\n },\n \"hk416\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 900,\n \"barrel\": 368,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.3,\n \"hg\": \"rail\",\n \"hgFrac\": 0.75,\n \"rail\": 1,\n \"scope\": 1,\n \"ar\": 1,\n \"rpm\": 850\n }\n },\n \"steyr_aug_a1\": {\n \"builder\": \"bullpup\",\n \"caliber\": \"5,56×45\",\n \"length\": 790,\n \"barrel\": 508,\n \"options\": {\n \"rpm\": 680\n }\n },\n \"fn_fal\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1090,\n \"barrel\": 533,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.05,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.45,\n \"carry\": 1,\n \"brake\": 1,\n \"charge\": 1,\n \"rpm\": 650\n }\n },\n \"hk_g3a3\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1025,\n \"barrel\": 450,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"curve\": 0.07,\n \"magLen\": 1.05,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.058,\n \"g3\": 1,\n \"rpm\": 550\n }\n },\n \"sks\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×39\",\n \"length\": 1020,\n \"barrel\": 520,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"fore\": 0.55,\n \"gas\": 1,\n \"charge\": 1,\n \"bayo\": 1\n }\n },\n \"m14_ebr\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1000,\n \"barrel\": 457,\n \"options\": {\n \"stock\": \"retract\",\n \"mag\": \"box\",\n \"curve\": 0.035,\n \"magLen\": 1.05,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"rail\": 1,\n \"scope\": 3,\n \"olive\": 1,\n \"charge\": 1\n }\n },\n \"svd_dragunov\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1225,\n \"barrel\": 620,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.32,\n \"mag\": \"box\",\n \"curve\": 0.09,\n \"magLen\": 0.9,\n \"hg\": \"wood\",\n \"hgFrac\": 0.4,\n \"scope\": 4,\n \"brake\": 1,\n \"ak\": 1,\n \"charge\": 1\n }\n },\n \"fn_scar_h\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 965,\n \"barrel\": 400,\n \"options\": {\n \"tan\": 1,\n \"stock\": \"fold\",\n \"mag\": \"box\",\n \"magLen\": 1.05,\n \"hg\": \"rail\",\n \"hgFrac\": 0.7,\n \"hR\": 0.07,\n \"rail\": 1,\n \"scope\": 2,\n \"charge\": 1,\n \"rpm\": 600\n }\n },\n \"knights_sr_25_mk11\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1156,\n \"barrel\": 508,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"box\",\n \"magLen\": 1,\n \"hg\": \"rail\",\n \"hgFrac\": 0.75,\n \"rail\": 1,\n \"scope\": 3,\n \"bipod\": 1,\n \"ar\": 1\n }\n },\n \"hk_psg_1\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1208,\n \"barrel\": 650,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"curve\": 0.06,\n \"magLen\": 0.75,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.058,\n \"g3\": 1,\n \"scope\": 3,\n \"rel\": 0.7\n }\n },\n \"steyr_ssg_69\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1140,\n \"barrel\": 650,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1,\n \"rel\": 0.6\n }\n },\n \"barrett_mrad\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1260,\n \"barrel\": 686,\n \"options\": {\n \"tan\": 1,\n \"stock\": \"fold\",\n \"stockLen\": 0.33,\n \"mag\": \"box\",\n \"magLen\": 0.75,\n \"hg\": \"rail\",\n \"hgFrac\": 0.55,\n \"rail\": 1,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"cheytac_m200\": {\n \"builder\": \"rifle\",\n \"caliber\": \".408 CheyTac\",\n \"length\": 1397,\n \"barrel\": 737,\n \"options\": {\n \"stock\": \"retract\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"magLen\": 0.85,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.07,\n \"scope\": 4,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"remington_700\": {\n \"builder\": \"rifle\",\n \"caliber\": \".308\",\n \"length\": 1100,\n \"barrel\": 610,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"m24_sws\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1092,\n \"barrel\": 610,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"round\": 1\n }\n },\n \"mosin_nagant_91_30\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1232,\n \"barrel\": 730,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"fore\": 0.85,\n \"bolt\": 1,\n \"round\": 1,\n \"bands\": 1\n }\n },\n \"accuracy_awm\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1230,\n \"barrel\": 686,\n \"options\": {\n \"olive\": 1,\n \"stock\": \"skeleton\",\n \"stockLen\": 0.34,\n \"mag\": \"box\",\n \"magLen\": 0.6,\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"sako_trg_42\": {\n \"builder\": \"rifle\",\n \"caliber\": \".338 Lapua\",\n \"length\": 1200,\n \"barrel\": 690,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.33,\n \"mag\": \"box\",\n \"magLen\": 0.6,\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"scope\": 3,\n \"bolt\": 1,\n \"bipod\": 1,\n \"brake\": 1,\n \"round\": 1\n }\n },\n \"barrett_m82a1\": {\n \"builder\": \"rifle\",\n \"caliber\": \".50 BMG\",\n \"length\": 1448,\n \"barrel\": 737,\n \"options\": {\n \"stock\": \"fixed\",\n \"stockLen\": 0.3,\n \"mag\": \"box\",\n \"magLen\": 0.8,\n \"hg\": \"poly\",\n \"hgFrac\": 0.55,\n \"hR\": 0.1,\n \"wR\": 0.05,\n \"br\": 0.014,\n \"scope\": 3,\n \"bipod\": 1,\n \"brake\": 2,\n \"carry\": 1,\n \"charge\": 1\n }\n },\n \"ruger_10_22\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 940,\n \"barrel\": 470,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.05,\n \"br\": 0.007,\n \"charge\": 1\n }\n },\n \"cbc_7022\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 1000,\n \"barrel\": 530,\n \"options\": {\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.05,\n \"br\": 0.007,\n \"charge\": 1\n }\n },\n \"cbc_122\": {\n \"builder\": \"rifle\",\n \"caliber\": \".22 LR\",\n \"length\": 1030,\n \"barrel\": 590,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"hR\": 0.045,\n \"br\": 0.007,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"winchester_1894\": {\n \"builder\": \"rifle\",\n \"caliber\": \".30-30\",\n \"length\": 965,\n \"barrel\": 508,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"straight\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"lever\": 1,\n \"hR\": 0.05,\n \"fore\": 0,\n \"bands\": 1\n }\n },\n \"rossi_puma\": {\n \"builder\": \"rifle\",\n \"caliber\": \".38 SPL / .357\",\n \"length\": 950,\n \"barrel\": 508,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"straight\",\n \"mag\": \"none\",\n \"tube\": 1,\n \"lever\": 1,\n \"hR\": 0.048,\n \"fore\": 0\n }\n },\n \"hunting_rifle_30_06\": {\n \"builder\": \"rifle\",\n \"caliber\": \".30-06\",\n \"length\": 1100,\n \"barrel\": 560,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n }\n },\n \"fn_minimi\": {\n \"builder\": \"rifle\",\n \"caliber\": \"5,56×45\",\n \"length\": 1040,\n \"barrel\": 465,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.35,\n \"bipod\": 1,\n \"hR\": 0.08,\n \"carry\": 1,\n \"charge\": 1,\n \"rpm\": 850\n }\n },\n \"pkm\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×54R\",\n \"length\": 1173,\n \"barrel\": 658,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"skeleton\",\n \"mag\": \"belt\",\n \"hg\": \"none\",\n \"bipod\": 1,\n \"hR\": 0.08,\n \"br\": 0.01,\n \"charge\": 1,\n \"rpm\": 650\n }\n },\n \"m60\": {\n \"builder\": \"rifle\",\n \"caliber\": \"7,62×51\",\n \"length\": 1105,\n \"barrel\": 560,\n \"options\": {\n \"stock\": \"fixed\",\n \"mag\": \"belt\",\n \"hg\": \"poly\",\n \"hgFrac\": 0.3,\n \"bipod\": 1,\n \"hR\": 0.085,\n \"br\": 0.011,\n \"charge\": 1,\n \"rpm\": 550,\n \"rel\": 1.3\n }\n },\n \"rpg_7\": {\n \"builder\": \"launcher\",\n \"caliber\": \"PG-7V 40/85 mm\",\n \"length\": 950,\n \"barrel\": 950,\n \"options\": {\n \"lt\": \"rpg\"\n }\n },\n \"m72_law\": {\n \"builder\": \"launcher\",\n \"caliber\": \"66 mm HEAT\",\n \"length\": 881,\n \"barrel\": 881,\n \"options\": {\n \"lt\": \"m72\"\n }\n },\n \"at4\": {\n \"builder\": \"launcher\",\n \"caliber\": \"84 mm HEAT\",\n \"length\": 1020,\n \"barrel\": 1020,\n \"options\": {\n \"lt\": \"at4\"\n }\n },\n \"carl_gustaf_m4\": {\n \"builder\": \"launcher\",\n \"caliber\": \"84 mm (HE / HEAT)\",\n \"length\": 950,\n \"barrel\": 950,\n \"options\": {\n \"lt\": \"carl\"\n }\n },\n \"m2_flamethrower\": {\n \"builder\": \"launcher\",\n \"caliber\": \"Napalm / gasolina gel\",\n \"length\": 1000,\n \"barrel\": 620,\n \"options\": {\n \"lt\": \"flame\"\n }\n },\n \"improvised_flamethrower\": {\n \"builder\": \"launcher\",\n \"caliber\": \"Gasolina + extintor pressurizado\",\n \"length\": 800,\n \"barrel\": 660,\n \"options\": {\n \"lt\": \"flameDIY\"\n }\n },\n \"browning_m2\": {\n \"builder\": \"m2\",\n \"caliber\": \".50 BMG\",\n \"length\": 1650,\n \"barrel\": 1140,\n \"options\": {\n \"rpm\": 550\n }\n },\n \"remington_700_300wm\": {\n \"builder\": \"rifle\",\n \"caliber\": \".308\",\n \"length\": 1100,\n \"barrel\": 610,\n \"options\": {\n \"wood\": 1,\n \"stock\": \"trad\",\n \"mag\": \"internal\",\n \"scope\": 3,\n \"bolt\": 1,\n \"round\": 1\n },\n \"variantOf\": \"remington_700\"\n }\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\ntype Axis = 'x' | 'y' | 'z'\n\n// Port of three/examples/jsm/geometries/RoundedBoxGeometry (MIT, three.js authors) onto the host's THREE: the host lends its namespace, not the addon.\nconst uvAlong = (THREE: Three, faceDirection: THREE_NS.Vector3, normal: THREE_NS.Vector3, uvAxis: Axis, projectionAxis: Axis, radius: number, sideLength: number): number => {\n const arcLength = (2 * Math.PI * radius) / 4\n const centerLength = Math.max(sideLength - 2 * radius, 0)\n const halfArc = Math.PI / 4\n const projected = new THREE.Vector3().copy(normal)\n projected[projectionAxis] = 0\n projected.normalize()\n const arcUvRatio = (0.5 * arcLength) / (arcLength + centerLength)\n const arcAngleRatio = 1.0 - projected.angleTo(faceDirection) / halfArc\n if (Math.sign(projected[uvAxis]) === 1) return arcAngleRatio * arcUvRatio\n const centerUv = centerLength / (arcLength + centerLength)\n return centerUv + arcUvRatio + arcUvRatio * (1.0 - arcAngleRatio)\n}\n\ntype Face = { direction: [number, number, number]; u: [Axis, Axis, boolean]; v: [Axis, Axis, boolean] }\n\n// right, left, top, bottom, front, back: the axes each face reads its u and v from, and whether the value is mirrored\nconst FACES: readonly Face[] = [\n { direction: [1, 0, 0], u: ['z', 'y', false], v: ['y', 'z', true] },\n { direction: [-1, 0, 0], u: ['z', 'y', true], v: ['y', 'z', true] },\n { direction: [0, 1, 0], u: ['x', 'z', true], v: ['z', 'x', false] },\n { direction: [0, -1, 0], u: ['x', 'z', true], v: ['z', 'x', true] },\n { direction: [0, 0, 1], u: ['x', 'y', true], v: ['y', 'x', true] },\n { direction: [0, 0, -1], u: ['x', 'y', false], v: ['y', 'x', true] },\n]\n\n/** A box with rounded edges (`segments` per corner) made from the host's BoxGeometry, vertex for vertex like the three.js addon the gallery used. */\nexport function createRoundedBoxGeometry(THREE: Three, width: number, height: number, depth: number, segments: number, radius: number): THREE_NS.BufferGeometry {\n const count = segments * 2 + 1\n const rounding = Math.min(width / 2, height / 2, depth / 2, radius)\n const geometry = new THREE.BoxGeometry(1, 1, 1, count, count, count)\n const flat = geometry.toNonIndexed()\n geometry.setIndex(null)\n geometry.setAttribute('position', flat.attributes.position as THREE_NS.BufferAttribute)\n geometry.setAttribute('normal', flat.attributes.normal as THREE_NS.BufferAttribute)\n geometry.setAttribute('uv', flat.attributes.uv as THREE_NS.BufferAttribute)\n const position = new THREE.Vector3()\n const normal = new THREE.Vector3()\n const box = new THREE.Vector3(width, height, depth).divideScalar(2).subScalar(rounding)\n const positions = geometry.attributes.position.array as Float32Array\n const normals = geometry.attributes.normal.array as Float32Array\n const uvs = geometry.attributes.uv.array as Float32Array\n const faceTriangles = positions.length / 6\n const halfSegment = 0.5 / count\n const sides: Record<Axis, number> = { x: width, y: height, z: depth }\n for (let i = 0, j = 0; i < positions.length; i += 3, j += 2) {\n position.fromArray(positions, i)\n normal.copy(position)\n normal.x -= Math.sign(normal.x) * halfSegment\n normal.y -= Math.sign(normal.y) * halfSegment\n normal.z -= Math.sign(normal.z) * halfSegment\n normal.normalize()\n positions[i] = box.x * Math.sign(position.x) + normal.x * rounding\n positions[i + 1] = box.y * Math.sign(position.y) + normal.y * rounding\n positions[i + 2] = box.z * Math.sign(position.z) + normal.z * rounding\n normals[i] = normal.x\n normals[i + 1] = normal.y\n normals[i + 2] = normal.z\n const face = FACES[Math.floor(i / faceTriangles)]\n if (!face) continue\n const direction = new THREE.Vector3(...face.direction)\n for (const [offset, [uvAxis, projectionAxis, mirrored]] of [[0, face.u], [1, face.v]] as const) {\n const value = uvAlong(THREE, direction, normal, uvAxis, projectionAxis, rounding, sides[uvAxis])\n uvs[j + offset] = mirrored ? 1 - value : value\n }\n }\n return geometry\n}\n","import type * as THREE_NS from 'three'\nimport { createRoundedBoxGeometry } from './rounded-box'\n\ntype Three = typeof THREE_NS\ntype Material = THREE_NS.Material\nexport type Parent = THREE_NS.Object3D\n\nconst PI = Math.PI\n\nconst createMaterials = (THREE: Three) => {\n const standard = (color: number, roughness = 0.7, metalness = 0.2, extra: THREE_NS.MeshStandardMaterialParameters = {}): THREE_NS.MeshStandardMaterial =>\n new THREE.MeshStandardMaterial({ color, roughness, metalness, ...extra })\n const basic = (color: number, extra: THREE_NS.MeshBasicMaterialParameters = {}): THREE_NS.MeshBasicMaterial => new THREE.MeshBasicMaterial({ color, ...extra })\n const additive = { transparent: true, opacity: 0.95, blending: THREE.AdditiveBlending, depthWrite: false }\n return {\n metal: standard(0x34373a, 0.42, 0.75),\n steel: standard(0x6c6f72, 0.32, 0.85),\n steelL: standard(0x8a8d90, 0.28, 0.9),\n dark: standard(0x1a1c1d, 0.55, 0.5),\n poly: standard(0x242622, 0.8, 0.05),\n olive: standard(0x4b5231, 0.8, 0.05),\n tan: standard(0x9c8a63, 0.8, 0.05),\n wood: standard(0x4a2c17, 0.55, 0),\n woodL: standard(0x5e3a1f, 0.55, 0),\n brass: standard(0xc39a45, 0.28, 0.9),\n copper: standard(0xb06a3b, 0.3, 0.85),\n lead: standard(0x6d6f73, 0.5, 0.5),\n shell: standard(0xa3271c, 0.5, 0.05),\n glass: standard(0x7fa3a8, 0.05, 0.1, { transparent: true, opacity: 0.42 }),\n lens: standard(0x23465a, 0.05, 0.3, { transparent: true, opacity: 0.9, emissive: 0x061820 }),\n rubber: standard(0x151515, 0.85, 0),\n white: standard(0xcfc8b4, 0.8, 0),\n hole: standard(0x080807, 1, 0),\n bake: standard(0x5a3220, 0.55, 0),\n rust: standard(0x6b3a1e, 0.95, 0.3),\n rustD: standard(0x4a2a18, 0.95, 0.25),\n worn: standard(0x55585a, 0.6, 0.6),\n fire: basic(0xff7a22),\n fire2: basic(0xffcf5a),\n flashA: basic(0xffb347, additive),\n flashB: basic(0xfff1c0, additive),\n smokeP: standard(0x8a8a86, 1, 0, { transparent: true, opacity: 0.35, depthWrite: false }),\n /** Launcher paints. */\n yellow: standard(0xb08f22, 0.6, 0),\n red: standard(0x8e1c14, 0.45, 0.1),\n redPaint: standard(0xa3231a, 0.35, 0.2),\n tape: standard(0x8a8c88, 0.9, 0),\n pipe: standard(0x9a5a32, 0.35, 0.8),\n green: standard(0x3a4428, 0.75, 0.05),\n /** Magazine finishes named by the options. */\n bakelite: standard(0x6a2e1c, 0.6, 0),\n polyMag: standard(0x2a2a26, 0.85, 0),\n }\n}\nexport type ModelMaterials = ReturnType<typeof createMaterials>\n\n/**\n * The gallery's primitives on the host's three.js. Each takes the parent first and the position last as the page does (`box(parent, w, h, d, material, x, y, z, rz, ry, rx)`),\n * so that the builders read like the originals. `roundness` is the page's `RF`: how round the next boxes are, `null` for the default.\n */\nexport interface ModelKit {\n readonly THREE: Three\n readonly M: ModelMaterials\n roundness: number | null\n group(): THREE_NS.Group\n box(parent: Parent, w: number, h: number, d: number, material: Material, x: number, y: number, z: number, rz?: number, ry?: number, rx?: number): THREE_NS.Mesh\n /** Cylinders along x, y and z. `radiusEnd` makes a cone. */\n cylinderX(parent: Parent, radius: number, length: number, material: Material, x: number, y: number, z: number, segments?: number, radiusEnd?: number): THREE_NS.Mesh\n cylinderY(parent: Parent, radius: number, height: number, material: Material, x: number, y: number, z: number, segments?: number, radiusEnd?: number): THREE_NS.Mesh\n cylinderZ(parent: Parent, radius: number, length: number, material: Material, x: number, y: number, z: number, segments?: number): THREE_NS.Mesh\n sphere(parent: Parent, radius: number, material: Material, x: number, y: number, z: number, detail?: number): THREE_NS.Mesh\n torus(parent: Parent, geometry: THREE_NS.TorusGeometry, material: Material, x: number, y: number, z: number): THREE_NS.Mesh\n mark(parent: Parent, x: number, y: number, z: number): THREE_NS.Object3D\n pivot(parent: Parent, x?: number, y?: number, z?: number): THREE_NS.Group\n}\n\nconst kits = new WeakMap<Three, ModelKit>()\n\n/** One kit per three.js namespace: the materials and the geometry cache are shared by every model built with it. */\nexport function modelKit(THREE: Three): ModelKit {\n const cached = kits.get(THREE)\n if (cached) return cached\n const geometries = new Map<string, THREE_NS.BufferGeometry>()\n const shadowed = <TObject extends THREE_NS.Mesh>(mesh: TObject): TObject => {\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n }\n const place = (parent: Parent, mesh: THREE_NS.Mesh, x: number, y: number, z: number): THREE_NS.Mesh => {\n mesh.position.set(x, y, z)\n parent.add(mesh)\n return mesh\n }\n const kit: ModelKit = {\n THREE,\n M: createMaterials(THREE),\n roundness: null,\n group: () => new THREE.Group(),\n box(parent, w, h, d, material, x, y, z, rz = 0, ry = 0, rx = 0) {\n const radius = Math.min(w, h, d) * (kit.roundness ?? 0.2)\n const key = `${w.toFixed(4)},${h.toFixed(4)},${d.toFixed(4)},${radius.toFixed(5)}`\n let geometry = geometries.get(key)\n if (!geometry) {\n geometry = radius > 0.00025 ? createRoundedBoxGeometry(THREE, w, h, d, 2, radius) : new THREE.BoxGeometry(w, h, d)\n geometries.set(key, geometry)\n }\n const mesh = place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z)\n mesh.rotation.set(rx, ry, rz)\n return mesh\n },\n cylinderX(parent, radius, length, material, x, y, z, segments = 16, radiusEnd) {\n const mesh = shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radiusEnd ?? radius, radius, length, segments), material))\n mesh.rotation.z = -PI / 2\n return place(parent, mesh, x, y, z)\n },\n cylinderY(parent, radius, height, material, x, y, z, segments = 16, radiusEnd) {\n return place(parent, shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radiusEnd ?? radius, radius, height, segments), material)), x, y, z)\n },\n cylinderZ(parent, radius, length, material, x, y, z, segments = 16) {\n const mesh = shadowed(new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, segments), material))\n mesh.rotation.x = PI / 2\n return place(parent, mesh, x, y, z)\n },\n sphere(parent, radius, material, x, y, z, detail = 1) {\n return place(parent, shadowed(new THREE.Mesh(new THREE.IcosahedronGeometry(radius, detail), material)), x, y, z)\n },\n torus: (parent, geometry, material, x, y, z) => place(parent, shadowed(new THREE.Mesh(geometry, material)), x, y, z),\n mark(parent, x, y, z) {\n const object = new THREE.Object3D()\n object.position.set(x, y, z)\n parent.add(object)\n return object\n },\n pivot(parent, x = 0, y = 0, z = 0) {\n const group = new THREE.Group()\n group.position.set(x, y, z)\n parent.add(group)\n return group\n },\n }\n kits.set(THREE, kit)\n return kit\n}\n\n/** Gives the mesh its own copy of the material, and lists it among the parts that glow with heat. */\nexport function heatify<TMesh extends THREE_NS.Mesh>(glow: THREE_NS.Mesh[], mesh: TMesh): TMesh {\n mesh.material = (mesh.material as Material).clone()\n glow.push(mesh)\n return mesh\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `shotgunBreak`: the double barrel, hinged at the action so that it opens to reload. */\nexport function buildBreakAction(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX, sphere } = kit\n const group = kit.group()\n const L = (options.L ?? 0) / 1000\n const barrel = (options.B ?? 0) / 1000\n const parts: ModelParts = { family: 'break', kick: 1.6, glow: [] }\n box(group, 0.09, 0.05, 0.042, M.steel, L - barrel - 0.04, -0.005, 0)\n for (let i = 0; i < 4; i++) box(group, 0.05, 0.002, 0.043, M.dark, L - barrel - 0.04, 0.01 - i * 0.008, 0)\n const barrels = kit.pivot(group, L - barrel, -0.01, 0)\n parts.barrels = barrels\n heatify(parts.glow, cylinderX(barrels, 0.0105, barrel, M.steel, barrel / 2, 0.01, 0.011, 18))\n heatify(parts.glow, cylinderX(barrels, 0.0105, barrel, M.steel, barrel / 2, 0.01, -0.011, 18))\n box(barrels, barrel, 0.004, 0.008, M.metal, barrel / 2, 0.022, 0)\n sphere(barrels, 0.002, M.white, barrel - 0.01, 0.026, 0, 1)\n cylinderX(barrels, 0.0075, 0.004, M.hole, barrel + 0.001, 0.01, 0.011, 12)\n cylinderX(barrels, 0.0075, 0.004, M.hole, barrel + 0.001, 0.01, -0.011, 12)\n box(barrels, 0.22, 0.03, 0.038, M.wood, 0.12, -0.01, 0)\n parts.breech = [kit.mark(barrels, 0.004, 0.01, 0.011), kit.mark(barrels, 0.004, 0.01, -0.011)]\n box(group, 0.12, 0.042, 0.032, M.wood, L - barrel - 0.14, -0.022, 0, 0.14)\n box(group, 0.28, 0.07, 0.036, M.wood, 0.15, -0.05, 0, 0.08)\n box(group, 0.012, 0.13, 0.04, M.rubber, 0.006, -0.06, 0)\n box(group, 0.004, 0.014, 0.004, M.dark, L - barrel - 0.05, -0.04, 0)\n parts.trigger = box(group, 0.004, 0.014, 0.004, M.dark, L - barrel - 0.035, -0.04, 0)\n box(group, 0.04, 0.004, 0.01, M.steel, L - barrel - 0.045, -0.05, 0)\n box(group, 0.012, 0.016, 0.006, M.dark, L - barrel - 0.08, 0.022, 0.012, 0.5)\n box(group, 0.012, 0.016, 0.006, M.dark, L - barrel - 0.08, 0.022, -0.012, 0.5)\n parts.safety = box(group, 0.02, 0.006, 0.008, M.steel, L - barrel - 0.07, 0.025, 0)\n parts.muzzle = kit.mark(barrels, barrel + 0.01, 0.01, 0)\n parts.eject = parts.breech[0]\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit, Parent } from './kit'\n\nconst PI = Math.PI\n\n/** A picatinny rail: a dark base and the cross slots, on a pivot so that it can lie on any side of the handguard. */\nexport function rail(kit: ModelKit, parent: Parent, x: number, length: number, y: number, z: number, width: number, rotationX = 0): THREE_NS.Group {\n const { M, box } = kit\n const pivot = kit.pivot(parent, 0, y, z)\n pivot.rotation.x = rotationX\n box(pivot, length, 0.005, width, M.dark, x + length / 2, 0, 0)\n const slots = Math.floor(length / 0.0095)\n for (let i = 0; i < slots; i++) box(pivot, 0.0052, 0.0035, width * 1.12, M.metal, x + 0.006 + i * 0.0095, 0.0035, 0)\n return pivot\n}\n\n/** Cooling slots along a handguard. */\nexport function vents(kit: ModelKit, parent: Parent, x: number, length: number, y: number, z: number, count: number, height: number): void {\n for (let i = 0; i < count; i++) kit.box(parent, (length / count) * 0.45, height, 0.003, kit.M.hole, x + ((i + 0.5) * length) / count, y, z)\n}\n\n/** An optic: 1 red dot, 2 short scope, 3 and 4 long scopes with their rings. */\nexport function scope(kit: ModelKit, parent: Parent, kind: number, cx: number, cy: number, cz = 0): void {\n const { M, box, cylinderX, cylinderY, cylinderZ, THREE } = kit\n if (kind === 1) {\n box(parent, 0.044, 0.01, 0.028, M.dark, cx, cy + 0.005, cz)\n cylinderX(parent, 0.0155, 0.034, M.dark, cx + 0.004, cy + 0.026, cz, 18)\n cylinderX(parent, 0.0125, 0.002, M.lens, cx + 0.022, cy + 0.026, cz, 18)\n cylinderY(parent, 0.004, 0.006, M.dark, cx + 0.004, cy + 0.044, cz, 10)\n return\n }\n if (kind === 2) {\n box(parent, 0.07, 0.012, 0.026, M.dark, cx, cy + 0.006, cz)\n cylinderX(parent, 0.016, 0.1, M.dark, cx - 0.01, cy + 0.032, cz, 18)\n cylinderX(parent, 0.016, 0.035, M.dark, cx + 0.055, cy + 0.032, cz, 18, 0.02)\n cylinderX(parent, 0.017, 0.002, M.lens, cx + 0.073, cy + 0.032, cz, 18)\n cylinderY(parent, 0.007, 0.012, M.dark, cx, cy + 0.052, cz, 12)\n box(parent, 0.03, 0.01, 0.012, M.dark, cx - 0.01, cy + 0.054, cz)\n return\n }\n const sleeve = kind === 4 ? 0.2 : 0.32\n cylinderX(parent, 0.0135, sleeve * 0.55, M.dark, cx, cy + 0.045, cz, 18)\n cylinderX(parent, 0.0135, sleeve * 0.25, M.dark, cx + sleeve * 0.36, cy + 0.045, cz, 18, 0.026)\n cylinderX(parent, 0.026, 0.05, M.dark, cx + sleeve * 0.5, cy + 0.045, cz, 18)\n cylinderX(parent, 0.024, 0.002, M.lens, cx + sleeve * 0.5 + 0.026, cy + 0.045, cz, 18)\n cylinderX(parent, 0.019, 0.06, M.dark, cx - sleeve * 0.38, cy + 0.045, cz, 18, 0.0135)\n cylinderX(parent, 0.019, 0.035, M.rubber, cx - sleeve * 0.38 - 0.045, cy + 0.045, cz, 18)\n cylinderX(parent, 0.017, 0.002, M.lens, cx - sleeve * 0.38 - 0.063, cy + 0.045, cz, 18)\n cylinderY(parent, 0.01, 0.022, M.dark, cx, cy + 0.066, cz, 14)\n cylinderY(parent, 0.011, 0.004, M.metal, cx, cy + 0.078, cz, 14)\n cylinderZ(parent, 0.01, 0.022, M.dark, cx, cy + 0.045, cz + 0.022, 14)\n for (const offset of [-0.07, 0.07]) {\n const ring = kit.torus(parent, new THREE.TorusGeometry(0.0155, 0.003, 8, 20), M.dark, cx + offset, cy + 0.045, cz)\n ring.rotation.y = PI / 2\n box(parent, 0.016, 0.03, 0.022, M.dark, cx + offset, cy + 0.018, cz)\n }\n}\n\nexport const buttpad = (kit: ModelKit, parent: Parent, x: number, y: number, height: number, width: number): void => void kit.box(parent, 0.012, height, width, kit.M.rubber, x, y, 0)\n\nexport const swivel = (kit: ModelKit, parent: Parent, x: number, y: number): void => void kit.torus(parent, new kit.THREE.TorusGeometry(0.006, 0.0015, 6, 12), kit.M.metal, x, y, 0)\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { rail, scope } from './details'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `bullpup`: the rifle (AUG) or, with `shot`, the twin-tube pump shotgun (KSG). */\nexport function buildBullpup(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const L = (options.L ?? 0) / 1000\n const barrel = (options.B ?? 0) / 1000\n const bodyLength = Math.max(0.32, L - barrel * 0.72)\n const body = options.shot ? M.poly : M.olive\n const parts: ModelParts = { family: options.shot ? 'pump' : 'rifle', stroke: 0.06, glow: [] }\n box(group, bodyLength, 0.075, 0.042, body, bodyLength / 2, 0, 0)\n box(group, bodyLength * 0.9, 0.02, 0.044, M.dark, bodyLength * 0.5, -0.02, 0)\n box(group, 0.032, 0.13, 0.044, M.rubber, 0.016, -0.025, 0)\n const gx = bodyLength * 0.8\n const grip = kit.pivot(group, gx, -0.085, 0)\n grip.rotation.z = -0.25\n box(grip, 0.03, 0.1, 0.03, M.poly, 0, 0, 0)\n box(group, 0.1, 0.006, 0.03, body, gx + 0.01, -0.06, 0)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, gx + 0.02, -0.05, 0, 0.15)\n heatify(parts.glow, cylinderX(group, options.shot ? 0.0105 : 0.0085, barrel, M.metal, L - barrel / 2, 0.012, 0, 16))\n cylinderX(group, 0.006, 0.004, M.hole, L + 0.001, 0.012, 0, 12)\n box(group, 0.05, 0.024, 0.004, M.hole, bodyLength * 0.25, 0.005, 0.0212)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.044, 0.02, 0.006, M.steelL, bodyLength * 0.25, 0.005, 0.02)\n if (options.shot) {\n cylinderX(group, 0.012, bodyLength * 0.75, M.metal, bodyLength * 0.55, -0.025, 0.014, 14)\n cylinderX(group, 0.012, bodyLength * 0.75, M.metal, bodyLength * 0.55, -0.025, -0.014, 14)\n const pump = kit.pivot(group)\n parts.pump = pump\n box(pump, 0.15, 0.045, 0.052, M.poly, bodyLength + 0.06, -0.015, 0)\n for (let i = 0; i < 6; i++) box(pump, 0.006, 0.047, 0.054, M.dark, bodyLength + 0.005 + i * 0.022, -0.015, 0)\n rail(kit, group, bodyLength * 0.15, bodyLength * 0.8, 0.04, 0, 0.02)\n parts.loadPort = kit.mark(group, bodyLength * 0.2, -0.04, 0)\n } else {\n const magazine = kit.pivot(group, gx - 0.11, -0.03, 0)\n magazine.rotation.z = 0.14\n parts.mag = magazine\n box(magazine, 0.05, 0.14, 0.026, M.glass, 0, -0.07, 0)\n for (let i = 0; i < 6; i++) cylinderX(magazine, 0.003, 0.04, M.brass, 0, -0.01 - i * 0.02, 0, 6)\n parts.magDrop = 0.18\n scope(kit, group, 2, bodyLength * 0.5, 0.04, 0)\n box(group, 0.2, 0.03, 0.02, body, bodyLength * 0.62, 0.048, 0)\n box(group, 0.026, 0.075, 0.026, body, bodyLength + 0.05, -0.05, 0, 0.1)\n }\n parts.muzzle = kit.mark(group, L + 0.01, 0.012, 0)\n parts.eject = kit.mark(group, bodyLength * 0.25, 0.005, 0.03)\n return { group, parts }\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { ModelParts } from './types'\n\ntype Point = [number, number, number]\n\nconst hose = (kit: ModelKit, group: THREE.Group, points: Point[], radius: number, material: THREE.Material): void => {\n const { THREE } = kit\n const curve = new THREE.CatmullRomCurve3(points.map((point) => new THREE.Vector3(...point)))\n const tube = new THREE.Mesh(new THREE.TubeGeometry(curve, 40, radius, 8, false), material)\n tube.castShadow = tube.receiveShadow = true\n group.add(tube)\n}\n\n/** The pilot light at the nozzle; its two flames carry `userData.flame` for the effect that flickers them. */\nconst pilot = (kit: ModelKit, group: THREE.Group, x: number, y: number): void => {\n const { M, cylinderX } = kit\n cylinderX(group, 0.006, 0.03, M.fire2, x + 0.015, y, 0, 6, 0).userData.flame = 1\n cylinderX(group, 0.004, 0.022, M.fire, x + 0.012, y, 0, 6, 0).userData.flame = 1\n}\n\n/** The M2 flamethrower: nozzle gun, hose and the two fuel tanks with the pressure bottle and its gauge. */\nexport function buildFlamethrower(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY, sphere } = kit\n parts.kick = 0.15\n heatify(parts.glow, cylinderX(group, 0.016, 0.62, M.steel, 0.42, 0, 0, 14))\n cylinderX(group, 0.022, 0.1, M.dark, 0.78, 0, 0, 14)\n heatify(parts.glow, cylinderX(group, 0.013, 0.1, M.steel, 0.88, 0, 0, 12, 0.009))\n cylinderX(group, 0.018, 0.02, M.metal, 0.73, 0, 0, 14)\n cylinderX(group, 0.012, 0.06, M.metal, 0.84, -0.025, 0, 10)\n pilot(kit, group, 0.92, -0.012)\n const foreGrip = kit.pivot(group, 0.6, -0.02, 0)\n foreGrip.rotation.z = -0.1\n box(foreGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const lever = kit.pivot(group, 0.62, -0.02, 0)\n parts.trigger = box(lever, 0.008, 0.05, 0.006, M.metal, 0.02, -0.03, 0, 0.3)\n const rearGrip = kit.pivot(group, 0.17, -0.02, 0)\n rearGrip.rotation.z = -0.28\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n box(group, 0.05, 0.004, 0.012, M.metal, 0.2, -0.035, 0)\n cylinderX(group, 0.02, 0.04, M.metal, 0.1, 0, 0, 12)\n hose(kit, group, [[0.08, 0, 0], [0, -0.04, 0], [-0.08, -0.2, 0.05], [-0.18, -0.32, 0.08], [-0.25, -0.33, 0.08]], 0.011, M.rubber)\n for (const z of [-0.1, 0.1]) {\n cylinderY(group, 0.085, 0.5, M.olive, -0.3, -0.05, z, 20)\n sphere(group, 0.085, M.olive, -0.3, 0.2, z, 2).scale.y = 0.45\n sphere(group, 0.085, M.olive, -0.3, -0.3, z, 2).scale.y = 0.45\n cylinderY(group, 0.03, 0.03, M.metal, -0.3, 0.24, z, 12)\n }\n sphere(group, 0.075, M.olive, -0.3, 0.1, 0, 2).position.x = -0.39\n box(group, 0.03, 0.6, 0.24, M.dark, -0.4, -0.05, 0)\n cylinderY(group, 0.03, 0.012, M.metal, -0.39, 0.18, 0, 14)\n const gauge = kit.pivot(group, -0.39, 0.18, 0.003)\n parts.gauge = gauge\n box(gauge, 0.002, 0.022, 0.002, M.red, 0, 0.008, 0.012)\n parts.muzzle = kit.pivot(group, 0.94, 0, 0)\n parts.rear = kit.pivot(group, 0.1, 0, 0)\n}\n\n/** The improvised flamethrower: a copper pipe, a fire extinguisher as the tank and a rubber hose. */\nexport function buildImprovisedFlamethrower(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY, sphere } = kit\n parts.kick = 0.12\n heatify(parts.glow, cylinderX(group, 0.011, 0.66, M.pipe, 0.38, 0, 0, 12))\n heatify(parts.glow, cylinderX(group, 0.015, 0.06, M.steel, 0.74, 0, 0, 12, 0.01))\n cylinderX(group, 0.006, 0.05, M.metal, 0.735, -0.02, 0, 8)\n pilot(kit, group, 0.77, -0.02)\n cylinderY(group, 0.012, 0.04, M.redPaint, 0.72, -0.055, 0, 10)\n box(group, 0.02, 0.03, 0.012, M.dark, 0.72, -0.085, 0)\n cylinderX(group, 0.06, 0.42, M.redPaint, 0.3, -0.09, 0, 22)\n sphere(group, 0.06, M.redPaint, 0.51, -0.09, 0, 2).scale.x = 0.5\n sphere(group, 0.06, M.redPaint, 0.09, -0.09, 0, 2).scale.x = 0.5\n cylinderX(group, 0.02, 0.04, M.dark, 0.04, -0.09, 0, 12)\n box(group, 0.02, 0.06, 0.005, M.white, 0.3, -0.09, 0.06)\n for (const x of [0.15, 0.3, 0.45]) cylinderX(group, 0.063, 0.03, M.tape, x, -0.09, 0, 22)\n cylinderX(group, 0.016, 0.03, M.tape, 0.3, 0, 0, 12)\n hose(kit, group, [[0.04, -0.09, 0], [-0.02, -0.06, 0.02], [0, 0, 0.02], [0.05, 0, 0]], 0.007, M.rubber)\n const rearGrip = kit.pivot(group, 0.12, -0.01, 0)\n rearGrip.rotation.z = -0.3\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const lever = kit.pivot(group, 0.17, -0.02, 0)\n parts.trigger = box(lever, 0.008, 0.04, 0.006, M.metal, 0, -0.02, 0, 0.2)\n parts.muzzle = kit.pivot(group, 0.78, 0, 0)\n parts.rear = kit.pivot(group, 0.05, 0, 0)\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\n\nconst PI = Math.PI\n\n/** The PG-7V grenade of the RPG-7: warhead, body and the booster. */\nexport function buildRocketGrenade(kit: ModelKit): THREE.Group {\n const { M, cylinderX } = kit\n const round = kit.group()\n cylinderX(round, 0.018, 0.15, M.olive, -0.05, 0, 0, 14)\n cylinderX(round, 0.02, 0.07, M.olive, 0.035, 0, 0, 18, 0.0425)\n cylinderX(round, 0.0425, 0.12, M.olive, 0.13, 0, 0, 20)\n cylinderX(round, 0.0428, 0.012, M.dark, 0.09, 0, 0, 20)\n cylinderX(round, 0.0425, 0.13, M.olive, 0.255, 0, 0, 20, 0.011)\n cylinderX(round, 0.011, 0.03, M.metal, 0.335, 0, 0, 10, 0.004)\n return round\n}\n\n/** The 84 mm round of the Carl Gustaf. */\nexport function buildRecoillessRound(kit: ModelKit): THREE.Group {\n const { M, cylinderX } = kit\n const round = kit.group()\n cylinderX(round, 0.041, 0.32, M.green, -0.16, 0, 0, 20)\n cylinderX(round, 0.0415, 0.02, M.yellow, -0.05, 0, 0, 20)\n cylinderX(round, 0.041, 0.12, M.green, 0.06, 0, 0, 20, 0.012)\n cylinderX(round, 0.043, 0.03, M.brass, -0.33, 0, 0, 20)\n return round\n}\n\n/** The rocket that flies off a disposable tube or a rocket launcher without a model of its own round. */\nexport function buildFlyingRocket(kit: ModelKit, launcherType: string | undefined): THREE.Group {\n const { M, box, cylinderX } = kit\n const rocket = kit.group()\n const diameter = launcherType === 'at4' || launcherType === 'carl' ? 0.041 : 0.032\n cylinderX(rocket, diameter * 0.5, 0.2, M.dark, -0.1, 0, 0, 10)\n cylinderX(rocket, diameter, 0.3, M.olive, 0.15, 0, 0, 18)\n cylinderX(rocket, diameter, 0.12, M.olive, 0.36, 0, 0, 18, diameter * 0.25)\n for (let i = 0; i < 4; i++) {\n const fin = box(rocket, 0.06, 0.002, diameter * 1.4, M.metal, -0.17, 0, 0)\n fin.rotation.x = (i * PI) / 4\n }\n return rocket\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { buildRecoillessRound, buildRocketGrenade } from './launcher-rounds'\nimport type { ModelParts } from './types'\n\n/** The RPG-7: tube, wooden heat shield, two grips, optic and the grenade in the muzzle. */\nfunction buildRpg(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.6\n cylinderX(group, 0.036, 0.13, M.dark, 0.065, 0, 0, 20, 0.021)\n cylinderX(group, 0.038, 0.012, M.metal, 0, 0, 0, 20)\n heatify(parts.glow, cylinderX(group, 0.021, 0.83, M.steel, 0.545, 0, 0, 18))\n cylinderX(group, 0.03, 0.3, M.wood, 0.47, 0, 0, 16)\n cylinderX(group, 0.031, 0.012, M.metal, 0.32, 0, 0, 16)\n cylinderX(group, 0.031, 0.012, M.metal, 0.62, 0, 0, 16)\n cylinderX(group, 0.024, 0.02, M.metal, 0.94, 0, 0, 16)\n box(group, 0.09, 0.03, 0.032, M.metal, 0.46, -0.028, 0)\n const frontGrip = kit.pivot(group, 0.4, -0.04, 0)\n frontGrip.rotation.z = -0.22\n box(frontGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n const rearGrip = kit.pivot(group, 0.5, -0.04, 0)\n rearGrip.rotation.z = -0.18\n box(rearGrip, 0.03, 0.1, 0.03, M.wood, 0, -0.05, 0)\n box(group, 0.06, 0.004, 0.012, M.metal, 0.53, -0.05, 0)\n box(group, 0.004, 0.025, 0.012, M.metal, 0.56, -0.04, 0)\n parts.trigger = box(group, 0.004, 0.018, 0.004, M.dark, 0.535, -0.045, 0, 0.15)\n const hammer = kit.pivot(group, 0.44, -0.012, 0)\n parts.hammer = hammer\n box(hammer, 0.012, 0.02, 0.01, M.dark, 0, 0, 0)\n box(group, 0.006, 0.03, 0.006, M.dark, 0.78, 0.032, 0)\n box(group, 0.02, 0.022, 0.014, M.dark, 0.46, 0.032, 0)\n box(group, 0.12, 0.042, 0.032, M.dark, 0.5, 0.04, -0.04)\n cylinderX(group, 0.013, 0.05, M.rubber, 0.42, 0.048, -0.04, 14)\n cylinderX(group, 0.016, 0.004, M.lens, 0.565, 0.048, -0.04, 14)\n box(group, 0.04, 0.012, 0.012, M.metal, 0.5, 0.016, -0.03)\n const round = buildRocketGrenade(kit)\n round.position.x = 0.95\n group.add(round)\n parts.round = round\n parts.roundRest = 0.95\n parts.makeRound = () => buildRocketGrenade(kit)\n parts.muzzle = kit.pivot(group, 0.95, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The M72 LAW: a disposable tube with its sight flaps and the firing pin. */\nfunction buildM72(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX, cylinderY } = kit\n parts.kick = 1.1\n parts.disposable = true\n heatify(parts.glow, cylinderX(group, 0.0365, 0.6, M.olive, 0.58, 0, 0, 20))\n cylinderX(group, 0.032, 0.32, M.olive, 0.16, 0, 0, 20)\n cylinderX(group, 0.039, 0.03, M.rubber, 0.866, 0, 0, 20)\n cylinderX(group, 0.035, 0.025, M.rubber, 0.012, 0, 0, 20)\n cylinderX(group, 0.037, 0.015, M.yellow, 0.8, 0, 0, 20)\n cylinderX(group, 0.037, 0.012, M.dark, 0.3, 0, 0, 20)\n box(group, 0.004, 0.05, 0.05, M.dark, 0.79, 0.055, 0)\n box(group, 0.004, 0.006, 0.04, M.dark, 0.79, 0.078, 0)\n box(group, 0.004, 0.035, 0.024, M.dark, 0.38, 0.05, 0)\n cylinderY(group, 0.004, 0.006, M.lens, 0.38, 0.064, 0, 8)\n parts.trigger = box(group, 0.05, 0.016, 0.024, M.rubber, 0.5, 0.042, 0)\n box(group, 0.1, 0.01, 0.03, M.dark, 0.47, 0.036, 0)\n box(group, 0.02, 0.03, 0.01, M.dark, 0.66, -0.035, 0.03)\n box(group, 0.008, 0.03, 0.008, M.metal, 0.25, -0.04, 0.03)\n parts.muzzle = kit.pivot(group, 0.881, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The AT4: a heavier disposable tube with the fire-control box and the front grip. */\nfunction buildAt4(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.3\n parts.disposable = true\n heatify(parts.glow, cylinderX(group, 0.05, 0.86, M.olive, 0.51, 0, 0, 24))\n cylinderX(group, 0.056, 0.08, M.dark, 0.98, 0, 0, 24)\n cylinderX(group, 0.058, 0.07, M.dark, 0.04, 0, 0, 24, 0.05)\n cylinderX(group, 0.051, 0.015, M.yellow, 0.86, 0, 0, 24)\n box(group, 0.16, 0.026, 0.05, M.dark, 0.42, 0.058, 0)\n box(group, 0.03, 0.012, 0.016, M.red, 0.47, 0.075, 0)\n parts.trigger = box(group, 0.022, 0.012, 0.018, M.rubber, 0.5, 0.074, 0)\n box(group, 0.012, 0.07, 0.02, M.dark, 0.35, 0.09, -0.035)\n box(group, 0.012, 0.05, 0.02, M.dark, 0.71, 0.08, -0.035)\n const grip = kit.pivot(group, 0.68, -0.05, 0)\n grip.rotation.z = -0.15\n box(grip, 0.035, 0.11, 0.032, M.dark, 0, -0.05, 0)\n box(group, 0.14, 0.035, 0.06, M.rubber, 0.32, -0.06, 0)\n box(group, 0.3, 0.012, 0.055, M.dark, 0.5, -0.05, 0)\n parts.muzzle = kit.pivot(group, 1.02, 0, 0)\n parts.rear = kit.pivot(group, 0, 0, 0)\n}\n\n/** The Carl Gustaf M4: a reusable recoilless rifle with a hinged breech that takes a round from behind. */\nfunction buildCarlGustaf(kit: ModelKit, group: THREE.Group, parts: ModelParts): void {\n const { M, box, cylinderX } = kit\n parts.kick = 1.4\n heatify(parts.glow, cylinderX(group, 0.045, 0.72, M.dark, 0.59, 0, 0, 24))\n cylinderX(group, 0.05, 0.04, M.rubber, 0.93, 0, 0, 24)\n const breech = kit.pivot(group, 0.21, 0, 0.05)\n parts.breech = [breech]\n cylinderX(breech, 0.06, 0.16, M.dark, -0.1, 0, -0.05, 24, 0.046)\n cylinderX(breech, 0.062, 0.015, M.metal, -0.18, 0, -0.05, 24)\n box(group, 0.025, 0.03, 0.02, M.metal, 0.22, 0, 0.052)\n const foreGrip = kit.pivot(group, 0.62, -0.05, 0)\n foreGrip.rotation.z = -0.2\n box(foreGrip, 0.035, 0.11, 0.034, M.dark, 0, -0.05, 0)\n parts.trigger = box(group, 0.004, 0.018, 0.004, M.dark, 0.66, -0.06, 0, 0.15)\n box(group, 0.06, 0.004, 0.012, M.metal, 0.66, -0.07, 0)\n const rearGrip = kit.pivot(group, 0.4, -0.05, 0)\n rearGrip.rotation.z = -0.25\n box(rearGrip, 0.035, 0.1, 0.034, M.dark, 0, -0.05, 0)\n box(group, 0.13, 0.04, 0.07, M.rubber, 0.28, -0.065, 0)\n box(group, 0.16, 0.05, 0.045, M.dark, 0.56, 0.07, -0.035)\n cylinderX(group, 0.016, 0.05, M.rubber, 0.46, 0.075, -0.035, 14)\n cylinderX(group, 0.02, 0.004, M.lens, 0.645, 0.075, -0.035, 14)\n box(group, 0.06, 0.02, 0.02, M.metal, 0.56, 0.04, -0.03)\n box(group, 0.22, 0.01, 0.02, M.dark, 0.6, 0.06, 0.03)\n box(group, 0.01, 0.03, 0.02, M.dark, 0.5, 0.05, 0.03)\n box(group, 0.01, 0.03, 0.02, M.dark, 0.7, 0.05, 0.03)\n parts.makeRound = () => buildRecoillessRound(kit)\n parts.muzzle = kit.pivot(group, 0.95, 0, 0)\n parts.rear = kit.pivot(group, 0.05, 0, 0)\n}\n\nexport const ROCKET_BUILDERS: Record<string, (kit: ModelKit, group: THREE.Group, parts: ModelParts) => void> = {\n rpg: buildRpg,\n m72: buildM72,\n at4: buildAt4,\n carl: buildCarlGustaf,\n}\n","import type { ModelKit } from './kit'\nimport { buildFlamethrower, buildImprovisedFlamethrower } from './launcher-flame'\nimport { ROCKET_BUILDERS } from './launcher-rocket'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\n/** Port of the gallery's `launcher`: the four rocket launchers and the two flamethrowers, picked by `lt`. */\nexport function buildLauncher(kit: ModelKit, options: ModelOptions): BuiltModel {\n const group = kit.group()\n const type = options.lt ?? ''\n const isFlame = type === 'flame' || type === 'flameDIY'\n const parts: ModelParts = { family: isFlame ? 'flame' : 'rocket', launcherType: type, glow: [] }\n if (type === 'flame') buildFlamethrower(kit, group, parts)\n else if (type === 'flameDIY') buildImprovisedFlamethrower(kit, group, parts)\n else ROCKET_BUILDERS[type]?.(kit, group, parts)\n parts.eject = parts.muzzle\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelParts } from './types'\n\n/** Port of the gallery's `m2`: the Browning .50 on its tripod, with the cover, the belt box and the bolt. */\nexport function buildM2(kit: ModelKit): BuiltModel {\n const { M, box, cylinderX, cylinderZ } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'belt', kick: 2.2, stroke: 0.08, glow: [] }\n box(group, 0.52, 0.13, 0.12, M.metal, 0.36, 0, 0)\n for (let i = 0; i < 5; i++) cylinderZ(group, 0.006, 0.124, M.dark, 0.15 + i * 0.1, -0.03, 0, 10)\n heatify(parts.glow, cylinderX(group, 0.016, 1.14, M.metal, 1.14, 0.01, 0, 16))\n cylinderX(group, 0.034, 0.24, M.dark, 0.74, 0.01, 0, 16)\n for (let i = 0; i < 6; i++) cylinderX(group, 0.036, 0.012, M.metal, 0.66 + i * 0.035, 0.01, 0, 16)\n cylinderX(group, 0.022, 0.05, M.dark, 1.69, 0.01, 0, 16)\n box(group, 0.04, 0.09, 0.03, M.wood, 0.05, -0.02, 0.05)\n box(group, 0.04, 0.09, 0.03, M.wood, 0.05, -0.02, -0.05)\n box(group, 0.06, 0.02, 0.12, M.metal, 0.09, -0.02, 0)\n const belt = kit.pivot(group, 0.38, -0.05, -0.12)\n parts.belt = belt\n box(belt, 0.16, 0.12, 0.09, M.olive, 0, 0, 0)\n for (let i = 0; i < 8; i++) cylinderX(belt, 0.006, 0.05, M.brass, -0.08 + i * 0.02, 0.08, 0.04, 8)\n const cover = kit.pivot(group, 0.12, 0.065, 0)\n parts.cover = cover\n box(cover, 0.4, 0.012, 0.12, M.metal, 0.2, 0.006, 0)\n box(group, 0.04, 0.05, 0.04, M.dark, 0.66, 0.1, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.03, 0.03, 0.02, M.metal, 0.5, 0, 0.07)\n const tripod = kit.group()\n tripod.position.set(0.42, -0.1, 0)\n group.add(tripod)\n box(tripod, 0.03, 0.06, 0.03, M.metal, 0, 0, 0)\n box(tripod, 0.012, 0.62, 0.012, M.metal, -0.2, -0.25, 0, 0.75)\n box(tripod, 0.012, 0.62, 0.012, M.metal, 0.22, -0.25, 0.16, -0.75, 0, 0.3)\n box(tripod, 0.012, 0.62, 0.012, M.metal, 0.22, -0.25, -0.16, -0.75, 0, -0.3)\n parts.muzzle = kit.mark(group, 1.72, 0.01, 0)\n parts.eject = kit.mark(group, 0.3, -0.07, 0)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport { scope } from './details'\nimport type { BuiltModel, ModelParts } from './types'\n\n/** Port of the gallery's `p90`: the bullpup with the horizontal magazine on top. */\nexport function buildP90(kit: ModelKit): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'p90', stroke: 0.04, kick: 0.6, glow: [] }\n box(group, 0.4, 0.07, 0.055, M.poly, 0.2, 0, 0)\n box(group, 0.12, 0.075, 0.05, M.poly, 0.2, -0.07, 0)\n box(group, 0.08, 0.04, 0.03, M.hole, 0.21, -0.06, 0)\n box(group, 0.06, 0.13, 0.056, M.poly, 0.03, -0.03, 0)\n box(group, 0.05, 0.03, 0.056, M.poly, 0.33, -0.04, 0)\n heatify(parts.glow, cylinderX(group, 0.008, 0.09, M.metal, 0.43, 0, 0, 16))\n const magazine = kit.pivot(group, 0.22, 0.047, 0)\n parts.mag = magazine\n parts.magDir = 1\n parts.magDrop = 0.08\n box(magazine, 0.3, 0.022, 0.05, M.glass, 0, 0, 0)\n for (let i = 0; i < 12; i++) cylinderX(magazine, 0.0028, 0.02, M.brass, -0.12 + i * 0.022, 0, 0, 6)\n scope(kit, group, 1, 0.24, 0.06, 0)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n box(bolt, 0.02, 0.012, 0.012, M.dark, 0.3, 0.02, 0.03)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, 0.24, -0.045, 0)\n parts.muzzle = kit.mark(group, 0.48, 0, 0)\n parts.eject = kit.mark(group, 0.2, -0.07, 0)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelParts } from './types'\n\nconst SINGLE_PARTS = ['slide', 'bolt', 'boltHandle', 'mag', 'trigger', 'hammer', 'lever', 'pump', 'belt', 'cover', 'crane', 'cylinder', 'barrels', 'safety', 'muzzle', 'eject', 'loadPort', 'topLoad', 'rear', 'round', 'gauge'] as const\n\n/** The parts of a model by the id the clips use: `slide`, `mag`, `trigger`..., `breech_0`, `chamber_3`. */\nexport function partRegistry(parts: ModelParts): Map<string, THREE_NS.Object3D> {\n const registry = new Map<string, THREE_NS.Object3D>()\n for (const key of SINGLE_PARTS) {\n const part = parts[key]\n if (part) registry.set(key, part)\n }\n parts.breech?.forEach((part, index) => registry.set(`breech_${index}`, part))\n parts.chambers?.forEach((part, index) => registry.set(`chamber_${index}`, part))\n return registry\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { Material, PistolSize, PistolStyle } from './pistol-style'\nimport type { ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** The slide: its body by style, serrations, ejection port, barrel tip, sights and the small controls that ride on it. */\nexport function buildSlide(kit: ModelKit, slide: THREE.Group, parts: ModelParts, options: ModelOptions, style: PistolStyle, size: PistolSize, metal: Material): void {\n const { M, box, cylinderX } = kit\n const { length: L, width: w } = size\n const slideHeight = style.inset ? size.height * 0.92 : size.height\n const slideWidth = style.inset ? w * 0.86 : w\n kit.roundness = style.rf\n if (style.tri) box(slide, L * 0.42, slideHeight, slideWidth, metal, L * 0.21, 0, 0)\n else if (style.open) {\n box(slide, L * 0.45, slideHeight, slideWidth, metal, L * 0.225, 0, 0)\n box(slide, L * 0.55, slideHeight * 0.62, slideWidth, metal, L * 0.72, -slideHeight * 0.19, 0)\n } else box(slide, L, slideHeight, slideWidth, metal, L / 2, 0, 0)\n if (style.slope) box(slide, L * 0.25, slideHeight * 0.5, slideWidth * 0.98, metal, L * 0.86, slideHeight * 0.35, 0, -0.22)\n kit.roundness = null\n for (let i = 0; i < (style.flush ? 9 : 7); i++) box(slide, 0.0022, slideHeight * 0.72, slideWidth + 0.0014, M.dark, 0.007 + i * 0.0052, -0.002, 0, 0)\n if (style.frontSer) for (let i = 0; i < 5; i++) box(slide, 0.0022, slideHeight * 0.6, slideWidth + 0.0014, M.dark, L * 0.76 + i * 0.0052, -0.003, 0)\n if (style.port) {\n box(slide, L * style.port, 0.004, slideWidth * 0.55, M.hole, L * 0.6, slideHeight / 2 - 0.001, slideWidth * 0.12)\n box(slide, L * style.port * 0.85, 0.003, slideWidth * 0.4, M.steelL, L * 0.6, slideHeight / 2 - 0.0004, slideWidth * 0.1)\n box(slide, 0.012, 0.004, 0.002, M.dark, L * 0.55, slideHeight * 0.15, slideWidth / 2 + 0.0008)\n }\n if (style.open) {\n heatify(parts.glow, cylinderX(slide, 0.0062, L * 0.56, M.steelL, L * 0.7, slideHeight * 0.12, 0, 18))\n box(slide, 0.03, 0.004, slideWidth * 0.6, M.hole, L * 0.48, slideHeight / 2 - 0.001, 0)\n }\n if (style.tri) {\n const tube = new kit.THREE.Mesh(new kit.THREE.CylinderGeometry(0.016, 0.016, L * 0.6, 3), metal)\n tube.castShadow = tube.receiveShadow = true\n tube.rotation.set(0, 0, -PI / 2)\n tube.rotateY(PI / 6)\n tube.position.set(L * 0.7, slideHeight * 0.08, 0)\n slide.add(tube)\n heatify(parts.glow, tube)\n box(slide, L * 0.6, 0.006, 0.012, metal, L * 0.7, slideHeight * 0.38, 0)\n for (let i = 0; i < 6; i++) box(slide, 0.008, 0.003, 0.013, M.hole, L * 0.45 + i * 0.04, slideHeight * 0.41, 0)\n }\n if (style.bushing) {\n heatify(parts.glow, cylinderX(slide, 0.0078, 0.006, M.steelL, L + 0.002, 0.001, 0, 18))\n cylinderX(slide, 0.0045, 0.004, M.steel, L + 0.002, -0.012, 0, 12)\n }\n const muzzleY = style.tri ? slideHeight * 0.08 : 0.002\n heatify(parts.glow, cylinderX(slide, style.tri ? 0.0072 : 0.0062, 0.004, M.dark, L + 0.0015, muzzleY, 0, 18))\n cylinderX(slide, 0.0034, 0.005, M.hole, L + 0.0025, muzzleY, 0, 12)\n const top = slideHeight / 2\n if (style.sight === 'u' || style.sight === '3dot') {\n box(slide, 0.004, 0.007, 0.004, M.dark, L - 0.008, top + 0.0035, 0)\n box(slide, 0.0022, 0.0022, 0.0046, M.white, L - 0.008, top + 0.0058, 0)\n box(slide, 0.008, 0.007, 0.016, M.dark, 0.009, top + 0.0035, 0)\n if (style.sight === 'u') box(slide, 0.004, 0.002, 0.0122, M.white, 0.009, top + 0.006, 0)\n else box(slide, 0.0022, 0.0022, 0.0166, M.white, 0.009, top + 0.0058, 0)\n } else {\n box(slide, 0.006, 0.004, 0.003, M.dark, L - 0.006, top + 0.002, 0)\n box(slide, 0.006, 0.004, 0.012, M.dark, 0.008, top + 0.002, 0)\n }\n if (style.decock === 'slide') {\n box(slide, 0.012, 0.008, 0.004, M.dark, 0.02, slideHeight * 0.15, slideWidth / 2 + 0.002, 0.3)\n box(slide, 0.012, 0.008, 0.004, M.dark, 0.02, slideHeight * 0.15, -slideWidth / 2 - 0.002, 0.3)\n }\n if (style.safety === 'slide') parts.safety = box(slide, 0.012, 0.008, 0.004, M.dark, 0.018, slideHeight * 0.1, -slideWidth / 2 - 0.002, 0.2)\n if (options.sel) {\n const selector = box(slide, 0.01, 0.008, 0.003, M.dark, 0.014, -slideHeight * 0.2, slideWidth / 2 + 0.0014)\n parts.safety ??= selector\n }\n}\n\n","import type * as THREE from 'three'\n\nexport interface PistolStyle {\n rf: number\n ga: number\n grip: 'finger' | 'panel' | 'wood' | 'rubber' | 'star' | 'chunky'\n guard: 'square' | 'round' | 'hook'\n rail?: number\n sight: 'u' | '3dot' | 'small'\n port: number\n slideM?: string\n frame: 'poly' | 'metal'\n frontSer?: number\n safety?: 'thumb' | 'slide'\n hammer?: 'spur' | 'ring' | 'big'\n open?: number\n decock?: 'slide' | 'frame'\n tall?: number\n inset?: number\n bushing?: number\n beaver?: number\n slideStop?: number\n flush?: number\n lanyard?: number\n slope?: number\n tri?: number\n}\n\nexport const STYLES: Record<string, PistolStyle> = {\n glock: { rf: 0.07, ga: -0.36, grip: 'finger', guard: 'square', rail: 1, sight: 'u', port: 0.2, slideM: 'metal', frame: 'poly' },\n taurus: { rf: 0.16, ga: -0.3, grip: 'panel', guard: 'square', rail: 1, sight: '3dot', port: 0.18, frontSer: 1, frame: 'poly' },\n g2c: { rf: 0.2, ga: -0.3, grip: 'panel', guard: 'round', rail: 0, sight: '3dot', port: 0.17, frame: 'poly', safety: 'thumb' },\n beretta: { rf: 0.28, ga: -0.27, grip: 'wood', guard: 'round', hammer: 'spur', sight: '3dot', open: 1, decock: 'slide', port: 0, frame: 'metal' },\n pt100: { rf: 0.25, ga: -0.27, grip: 'rubber', guard: 'round', hammer: 'spur', sight: '3dot', port: 0.17, decock: 'frame', frame: 'metal' },\n sig: { rf: 0.14, ga: -0.3, grip: 'rubber', guard: 'hook', hammer: 'spur', sight: '3dot', port: 0.19, decock: 'frame', rail: 1, tall: 1.12, frame: 'metal' },\n cz: { rf: 0.32, ga: -0.3, grip: 'rubber', guard: 'round', hammer: 'spur', sight: '3dot', port: 0.15, inset: 1, safety: 'thumb', frame: 'metal' },\n m1911: { rf: 0.24, ga: -0.2, grip: 'wood', guard: 'round', hammer: 'ring', sight: 'small', port: 0.12, bushing: 1, beaver: 1, safety: 'thumb', slideStop: 1, frame: 'metal' },\n makarov: { rf: 0.48, ga: -0.24, grip: 'star', guard: 'round', hammer: 'ring', sight: 'small', port: 0.14, flush: 1, safety: 'slide', lanyard: 1, frame: 'metal' },\n fiveseven: { rf: 0.2, ga: -0.4, grip: 'chunky', guard: 'square', rail: 1, sight: '3dot', port: 0.18, slope: 1, frame: 'poly' },\n deagle: { rf: 0.08, ga: -0.28, grip: 'rubber', guard: 'round', hammer: 'big', sight: 'small', port: 0.16, tri: 1, safety: 'slide', frame: 'metal' },\n}\n\nexport type Material = THREE.Material\n\nexport interface PistolSize {\n length: number\n height: number\n width: number\n}\n","import type * as THREE from 'three'\nimport type { ModelKit } from './kit'\nimport { buildSlide } from './pistol-slide'\nimport type { Material, PistolSize, PistolStyle } from './pistol-style'\nimport { STYLES } from './pistol-style'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** Frame, grip and magazine below the slide. Returns the grip x and the trigger guard line the guard is drawn from. */\nfunction buildFrame(kit: ModelKit, group: THREE.Group, parts: ModelParts, options: ModelOptions, style: PistolStyle, size: PistolSize, materials: { frame: Material; grip: Material }): { gx: number; ty: number } {\n const { M, box, cylinderZ, sphere } = kit\n const { length: L, height: h, width: w } = size\n const fm = materials.frame\n if (style.inset) {\n box(group, L * 0.9, h * 0.35, w * 0.12, fm, L * 0.47, -h * 0.32, w * 0.47)\n box(group, L * 0.9, h * 0.35, w * 0.12, fm, L * 0.47, -h * 0.32, -w * 0.47)\n }\n const frameLength = style.tri ? L * 0.66 : L * 0.8\n kit.roundness = style.rf\n box(group, frameLength, 0.016, w * 0.92, fm, frameLength / 2 + L * 0.06, -h / 2 - 0.008, 0)\n kit.roundness = null\n if (style.rail) for (let i = 0; i < (style.slope ? 5 : 3); i++) box(group, 0.004, 0.003, w * 0.96, M.dark, L * 0.62 + i * 0.009, -h / 2 - 0.017, 0)\n const isGlock = options.st === 'glock' || !options.st\n if (isGlock) {\n box(group, 0.008, 0.004, 0.003, M.dark, L * 0.5, -h / 2 - 0.003, -w / 2 - 0.0012)\n box(group, 0.008, 0.004, 0.003, M.dark, L * 0.5, -h / 2 - 0.003, w / 2 + 0.0012)\n }\n if (style.slideStop) {\n box(group, 0.03, 0.006, 0.003, M.dark, L * 0.42, -h / 2 - 0.002, -w / 2 - 0.0014)\n sphere(group, 0.0028, M.dark, L * 0.55, -h / 2 - 0.003, w / 2 + 0.001, 1)\n } else box(group, 0.012, 0.004, 0.003, M.dark, L * 0.45, -h / 2 - 0.003, -w / 2 - 0.0012)\n if (style.decock === 'frame') box(group, 0.01, 0.012, 0.003, M.dark, L * 0.38, -h / 2 - 0.012, -w / 2 - 0.0014, 0.6)\n if (style.safety === 'thumb') parts.safety = box(group, 0.014, 0.006, 0.004, M.dark, 0.02, -h / 2 - 0.002, -w / 2 - 0.0016)\n const gripLength = options.gl ?? 0.105\n const gx = 0.034 + (L - 0.2) * 0.15\n const gy = -h / 2 - gripLength / 2 + 0.006\n const grip = kit.pivot(group, gx, gy, 0)\n grip.rotation.z = style.ga\n const gripWidth = style.grip === 'chunky' ? w * 1.18 : w * 1.06\n const gripDepth = style.grip === 'chunky' ? 0.036 : 0.032\n kit.roundness = 0.3\n if (style.grip === 'wood' || style.grip === 'star') {\n box(grip, gripDepth * 0.86, gripLength, w * 0.9, fm, 0, 0, 0)\n box(grip, gripDepth * 0.8, gripLength * 0.86, 0.004, materials.grip, 0.001, -0.002, w * 0.47)\n box(grip, gripDepth * 0.8, gripLength * 0.86, 0.004, materials.grip, 0.001, -0.002, -w * 0.47)\n if (style.grip === 'wood') {\n for (let i = 0; i < 6; i++) for (let j = 0; j < 2; j++) box(grip, 0.003, 0.003, 0.0012, M.woodL, -0.006 + j * 0.012, -gripLength * 0.3 + i * 0.012, w * 0.495, 0, 0, 0)\n cylinderZ(grip, 0.0035, 0.0015, M.brass, 0, gripLength * 0.25, w * 0.5, 10)\n cylinderZ(grip, 0.0035, 0.0015, M.brass, 0, -gripLength * 0.3, w * 0.5, 10)\n } else cylinderZ(grip, 0.008, 0.0015, M.dark, 0, gripLength * 0.1, w * 0.5, 5)\n } else box(grip, gripDepth, gripLength, gripWidth, materials.grip, 0, 0, 0)\n kit.roundness = null\n if (style.grip === 'finger') {\n for (let i = 0; i < 3; i++) box(grip, 0.006, 0.012, gripWidth * 0.98, materials.grip, gripDepth / 2 + 0.002, gripLength * 0.18 - i * 0.022, 0)\n for (let i = 0; i < 5; i++) for (let j = 0; j < 3; j++) box(grip, 0.003, 0.003, 0.0012, M.dark, -0.008 + j * 0.008, -gripLength * 0.25 + i * 0.012, gripWidth / 2 + 0.0004)\n }\n if (style.grip === 'panel' || style.grip === 'rubber' || style.grip === 'chunky') for (let i = 0; i < 6; i++) box(grip, gripDepth * 0.75, 0.0025, gripWidth + 0.001, M.dark, 0.002, -gripLength / 2 + 0.018 + i * 0.013, 0)\n if (style.grip === 'chunky') box(grip, 0.008, gripLength * 0.8, gripWidth * 0.9, materials.grip, gripDepth / 2 + 0.002, -0.004, 0)\n if (style.beaver) {\n box(group, 0.026, 0.008, w * 0.9, fm, -0.004, -h / 2 - 0.004, 0, 0.25)\n box(grip, 0.006, gripLength * 0.55, w * 0.9, fm, -gripDepth * 0.5 - 0.002, gripLength * 0.18, 0)\n } else box(group, 0.02, 0.009, w * 0.9, fm, 0.004, -h / 2 - 0.006, 0)\n if (style.lanyard) {\n const ring = kit.torus(grip, new kit.THREE.TorusGeometry(0.005, 0.0013, 6, 12), M.dark, -0.012, -gripLength / 2 + 0.004, 0)\n ring.position.set(-0.012, -gripLength / 2 + 0.004, 0)\n }\n const magazine = kit.pivot(grip)\n parts.mag = magazine\n parts.magDrop = gripLength * 1.15\n box(magazine, 0.022, gripLength * 0.94, w * 0.72, M.dark, 0.003, -0.004, 0)\n if (style.grip === 'chunky') box(magazine, 0.04, 0.01, gripWidth * 1.02, M.poly, 0.003, -gripLength / 2 - 0.004, 0)\n else if (style.flush || style.grip === 'wood') box(magazine, 0.028, 0.004, w * 0.9, M.steel, 0.003, -gripLength / 2 - 0.001, 0)\n else box(magazine, 0.031, 0.006, gripWidth * 1.02, M.dark, 0.003, -gripLength / 2 - 0.002, 0)\n return { gx, ty: -h / 2 }\n}\n\n/** Port of the gallery's `pistol` (Galeria 3D do Arsenal): slide, frame, grip, magazine, trigger and hammer, in the order the page adds them. */\nexport function buildPistol(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box } = kit\n const style = { ...STYLES[options.st ?? 'glock'] } as PistolStyle\n const group = kit.group()\n const parts: ModelParts = { family: 'pistol', kick: options.deagle ? 1.8 : 0.6, glow: [] }\n const size: PistolSize = { length: ((options.L ?? 0) / 1000) * 0.97, height: (options.h ?? 0.031) * (style.tall ?? 1), width: options.deagle ? 0.032 : style.flush ? 0.024 : 0.025 }\n const { length: L, height: h, width: w } = size\n const slideMetal = options.steel ? M.steel : options.stain ? M.steelL : M.metal\n const frameMetal = style.frame === 'poly' ? M.poly : slideMetal\n const gripMaterial = style.grip === 'wood' ? M.wood : style.grip === 'star' ? M.bake : style.grip === 'rubber' ? M.rubber : M.poly\n const slide = kit.pivot(group)\n parts.slide = slide\n parts.stroke = L * 0.15\n buildSlide(kit, slide, parts, options, style, size, slideMetal)\n const { gx, ty } = buildFrame(kit, group, parts, options, style, size, { frame: frameMetal, grip: gripMaterial })\n if (style.guard === 'square') {\n box(group, 0.046, 0.004, 0.009, frameMetal, gx + 0.05, ty - 0.034, 0)\n box(group, 0.004, 0.03, 0.009, frameMetal, gx + 0.074, ty - 0.02, 0)\n box(group, 0.006, 0.004, 0.009, frameMetal, gx + 0.075, ty - 0.034, 0)\n } else if (style.guard === 'hook') {\n box(group, 0.046, 0.004, 0.009, frameMetal, gx + 0.05, ty - 0.034, 0)\n box(group, 0.004, 0.03, 0.009, frameMetal, gx + 0.073, ty - 0.02, 0, 0.2)\n box(group, 0.008, 0.006, 0.009, frameMetal, gx + 0.074, ty - 0.037, 0, 0.4)\n } else {\n const guard = kit.torus(group, new kit.THREE.TorusGeometry(0.019, 0.0022, 6, 16, PI), frameMetal, gx + 0.05, ty - 0.014, 0)\n guard.rotation.z = PI\n guard.scale.set(1.2, 1, 1)\n }\n const isGlock = options.st === 'glock' || !options.st\n parts.trigger = box(group, 0.004, 0.014, 0.004, isGlock ? M.dark : M.steel, gx + 0.042, ty - 0.022, 0, 0.2)\n if (isGlock) box(parts.trigger, 0.0015, 0.008, 0.0045, M.metal, 0, -0.001, 0)\n if (style.hammer) {\n const hammer = kit.pivot(group, 0.003, h / 2 - 0.008, 0)\n parts.hammer = hammer\n if (style.hammer === 'ring') {\n box(hammer, 0.006, 0.012, 0.006, M.dark, -0.002, 0.004, 0, 0.3)\n kit.torus(hammer, new kit.THREE.TorusGeometry(0.0045, 0.0016, 6, 12), M.dark, -0.004, 0.012, 0)\n } else if (style.hammer === 'big') box(hammer, 0.014, 0.02, 0.009, M.dark, -0.004, 0.007, 0, 0.35)\n else {\n box(hammer, 0.008, 0.016, 0.007, M.dark, -0.002, 0.006, 0, 0.3)\n box(hammer, 0.008, 0.004, 0.008, M.dark, -0.006, 0.013, 0, 0.3)\n }\n }\n parts.muzzle = kit.mark(group, L + 0.006, style.tri ? h * 0.08 : 0.002, 0)\n parts.eject = kit.mark(group, L * 0.6, h / 2, w * 0.25)\n return { group, parts }\n}\n","import type { ModelKit } from './kit'\nimport { heatify } from './kit'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\nconst DEFAULT_CHAMBERS = 6\n\n/** Port of the gallery's `revolver`: frame, swing-out crane with the cylinder (six chambers, or as many as the weapon holds), barrel, hammer, grip and trigger. */\nexport function buildRevolver(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M, box, cylinderX } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'revolver', kick: options.cal === '.44 Magnum' ? 1.5 : 0.9, glow: [] }\n const barrel = (options.B ?? 0) / 1000\n const chambers = options.chambers ?? DEFAULT_CHAMBERS\n const metal = options.steel ? M.steel : M.metal\n box(group, 0.08, 0.044, 0.024, metal, 0.07, 0, 0)\n box(group, 0.036, 0.012, 0.022, metal, 0.096, 0.022, 0)\n box(group, 0.024, 0.012, 0.004, M.dark, 0.055, 0.006, -0.013)\n const crane = kit.pivot(group, 0.077, -0.024, 0)\n parts.crane = crane\n const cylinder = kit.pivot(crane, 0, 0.022, 0)\n parts.cylinder = cylinder\n cylinderX(cylinder, 0.0215, 0.042, metal, 0, 0, 0, 24)\n for (let i = 0; i < chambers; i++) {\n const angle = (i * 2 * PI) / chambers\n box(cylinder, 0.026, 0.005, 0.005, M.dark, 0, Math.cos(angle) * 0.0205, Math.sin(angle) * 0.0205, 0, 0, angle)\n }\n parts.chambers = []\n for (let i = 0; i < chambers; i++) {\n const angle = (i * 2 * PI) / chambers + PI / chambers\n parts.chambers.push(kit.mark(cylinder, -0.022, Math.cos(angle) * 0.013, Math.sin(angle) * 0.013))\n cylinderX(cylinder, 0.0046, 0.002, M.brass, -0.0215, Math.cos(angle) * 0.013, Math.sin(angle) * 0.013, 12)\n }\n heatify(parts.glow, cylinderX(group, 0.0088, barrel, metal, 0.112 + barrel / 2, 0.009, 0, 18))\n box(group, barrel * 0.92, 0.015, 0.013, metal, 0.112 + barrel * 0.46, -0.005, 0)\n cylinderX(group, 0.004, 0.005, M.hole, 0.112 + barrel + 0.0015, 0.009, 0, 12)\n box(group, 0.012, 0.009, 0.004, M.dark, 0.112 + barrel - 0.008, 0.021, 0, -0.3)\n box(group, 0.012, 0.006, 0.012, M.dark, 0.105, 0.031, 0)\n const hammer = kit.pivot(group, 0.036, 0.018, 0)\n box(hammer, 0.01, 0.02, 0.008, M.dark, -0.004, 0.008, 0, 0.45)\n parts.hammer = hammer\n const grip = kit.pivot(group, 0.024, -0.062, 0)\n grip.rotation.z = -0.38\n box(grip, 0.034, 0.1, 0.031, options.wood ? M.wood : M.rubber, 0, 0, 0)\n if (!options.wood) for (let i = 0; i < 4; i++) box(grip, 0.006, 0.07, 0.033, M.dark, -0.012 + i * 0.008, 0, 0)\n box(group, 0.038, 0.004, 0.008, metal, 0.062, -0.036, 0)\n box(group, 0.004, 0.022, 0.008, metal, 0.08, -0.026, 0, 0.2)\n parts.trigger = box(group, 0.004, 0.015, 0.004, M.dark, 0.06, -0.027, 0, 0.2)\n parts.muzzle = kit.mark(group, 0.112 + barrel + 0.006, 0.009, 0)\n parts.eject = kit.mark(group, 0.077, 0, 0)\n return { group, parts }\n}\n","import { scope } from './details'\nimport type { RifleContext } from './rifle-context'\n\n/** What is bolted on after the stock: optic, carry handle, bipod, bolt handle, lever, magazine tube, pump, heat shield, bayonet lug and cleaning rod. */\nexport function buildFittings(context: RifleContext, gripX: number): void {\n const { kit, group, parts, options: o, furniture: furn, length: L, receiverStart: x0, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, barrelRadius: r, barrelY: by } = context\n const { M, box, cylinderX, cylinderZ, sphere } = kit\n const middle = (x0 + x1) / 2\n if (o.scope) scope(kit, group, o.scope, middle + 0.03, hR / 2 + (o.rail ? 0.006 : 0), o.scope === 4 ? -0.02 : 0)\n if (o.carry) {\n box(group, 0.15, 0.026, 0.014, M.metal, middle, hR / 2 + 0.03, 0)\n box(group, 0.012, 0.03, 0.014, M.metal, middle + 0.07, hR / 2 + 0.014, 0)\n box(group, 0.012, 0.03, 0.014, M.metal, middle - 0.07, hR / 2 + 0.014, 0)\n }\n if (o.bipod) {\n const bx = x1 + (L - x1) * 0.45\n cylinderX(group, 0.008, 0.02, M.dark, bx + 0.04, by - 0.012, 0, 12)\n for (const side of [-1, 1]) {\n const leg = kit.pivot(group, bx + 0.04, by - 0.012, side * 0.012)\n leg.rotation.set(side * 0.15, 0, -0.35)\n box(leg, 0.006, 0.2, 0.006, M.dark, 0, -0.1, 0)\n box(leg, 0.01, 0.006, 0.01, M.rubber, 0, -0.2, 0)\n }\n }\n if (o.bolt) {\n const handle = kit.pivot(group, x1 - 0.045, by, 0)\n parts.boltHandle = handle\n parts.boltHandleRest = handle.position.x\n cylinderZ(handle, 0.0042, 0.05, M.steelL, 0, 0, wR / 2 + 0.022, 12)\n sphere(handle, 0.0095, M.dark, 0, -0.004, wR / 2 + 0.048, 1)\n cylinderX(group, hR * 0.3, 0.03, M.steel, x0 + 0.005, by, 0, 16)\n }\n if (o.lever) {\n const lever = kit.pivot(group, gripX - 0.02, -hR / 2 - 0.01, 0)\n parts.lever = lever\n box(lever, 0.11, 0.006, 0.012, M.metal, 0.055, -0.052, 0)\n box(lever, 0.006, 0.05, 0.012, M.metal, 0.003, -0.028, 0)\n box(lever, 0.006, 0.05, 0.012, M.metal, 0.108, -0.028, 0)\n box(lever, 0.04, 0.006, 0.012, M.metal, 0.08, -0.002, 0)\n box(group, 0.03, 0.012, 0.003, M.dark, x1 - 0.04, by, wR / 2 + 0.001)\n }\n if (o.tube) {\n const tubeLength = (L - x1) * (o.tubeLen || 0.8)\n cylinderX(group, 0.0105, tubeLength, M.metal, x1 + tubeLength / 2, by - 0.023, 0, 16)\n cylinderX(group, 0.0125, 0.02, M.dark, x1 + tubeLength + 0.006, by - 0.023, 0, 16)\n }\n if (o.pump) {\n const pump = kit.pivot(group)\n parts.pump = pump\n box(pump, 0.17, 0.042, 0.046, furn, x1 + 0.14, by - 0.022, 0)\n for (let i = 0; i < 8; i++) box(pump, 0.006, 0.044, 0.048, M.dark, x1 + 0.07 + i * 0.02, by - 0.022, 0)\n }\n if (o.heat) {\n cylinderX(group, r * 1.75, (L - x1) * 0.7, M.dark, x1 + (L - x1) * 0.4, by, 0, 12)\n for (let i = 0; i < 10; i++) box(group, 0.008, r * 1.5, 0.004, M.hole, x1 + (L - x1) * (0.1 + i * 0.06), by + r * 0.8, r * 1.5)\n }\n if (o.bayo) box(group, 0.025, 0.008, 0.01, M.metal, L - 0.07, by - 0.016, 0)\n if (o.rod) cylinderX(group, 0.003, (L - x1) * 0.85, M.steel, x1 + (L - x1) * 0.45, by - 0.014, 0, 8)\n}\n","import { rail, vents } from './details'\nimport type { RifleContext } from './rifle-context'\n\nconst PI = Math.PI\n\n/** Handguard by kind and the front sight, which the page draws unless a long scope replaces it. */\nexport function buildForend(context: RifleContext): void {\n const { kit, group, options: o, furniture: furn, length: L, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, barrelRadius: r, barrelY: by } = context\n const { M, box } = kit\n const hasLongScope = (o.scope ?? 0) >= 3\n if (!context.isTraditional && o.hg !== 'none') {\n const handguardLength = (L - x1) * (o.hgFrac || 0.5)\n const hx = x1 + handguardLength / 2\n const hh = hR * 0.8\n if (o.hg === 'rail') {\n box(group, handguardLength, hh, wR * 1.04, M.dark, hx, by - 0.002, 0)\n rail(kit, group, x1, handguardLength, by + hh / 2, 0, wR * 0.66)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - 0.002, wR * 0.54, wR * 0.4, PI / 2)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - 0.002, -wR * 0.54, wR * 0.4, -PI / 2)\n rail(kit, group, x1 + 0.01, handguardLength - 0.02, by - hh / 2, 0, wR * 0.6, PI)\n } else {\n const material = o.hg === 'wood' ? M.wood : furn\n if (o.ak) {\n box(group, handguardLength, hh * 0.55, wR * 1.08, material, hx, by - hh * 0.22, 0)\n box(group, handguardLength * 0.75, hh * 0.35, wR * 0.7, material, hx - handguardLength * 0.1, by + r * 2.2, 0)\n } else {\n box(group, handguardLength, hh, wR * 1.08, material, hx, by - 0.002, 0)\n vents(kit, group, x1 + 0.01, handguardLength - 0.02, by + hh * 0.15, wR * 0.54 + 0.001, Math.round(handguardLength / 0.025), hh * 0.3)\n vents(kit, group, x1 + 0.01, handguardLength - 0.02, by + hh * 0.15, -wR * 0.54 - 0.001, Math.round(handguardLength / 0.025), hh * 0.3)\n }\n }\n if (!hasLongScope && !o.rail && o.ak) {\n box(group, 0.03, 0.016, wR * 0.6, M.metal, x1 + 0.02, by + r * 2.5 + 0.01, 0)\n box(group, 0.012, 0.004, wR * 0.5, M.dark, x1 + 0.03, by + r * 2.5 + 0.019, 0)\n }\n }\n if (hasLongScope) return\n const sightX = L - (o.ak ? 0.06 : 0.08)\n if (o.ak) {\n box(group, 0.022, 0.022, wR * 0.6, M.metal, sightX, by + 0.008, 0)\n box(group, 0.006, 0.024, 0.004, M.metal, sightX, by + 0.026, 0.008)\n box(group, 0.006, 0.024, 0.004, M.metal, sightX, by + 0.026, -0.008)\n box(group, 0.003, 0.016, 0.003, M.dark, sightX, by + 0.022, 0)\n } else if (!o.rail || o.carry) {\n box(group, 0.018, 0.014, wR * 0.55, M.dark, sightX, by + 0.008, 0)\n box(group, 0.012, 0.034, 0.008, M.dark, sightX, by + 0.03, 0, -0.25)\n } else box(group, 0.012, 0.024, 0.012, M.dark, sightX - 0.04, by + hR * 0.4 + 0.012, 0)\n}\n","import type * as THREE from 'three'\nimport type { RifleContext } from './rifle-context'\n\n/** Grip, trigger group and selector. Returns the x of the grip, which the magazine and the lever hang from. */\nexport function buildGrip(context: RifleContext): number {\n const { kit, group, parts, options: o, furniture: furn, receiverStart: x0, receiverHeight: hR, receiverWidth: wR } = context\n const { M, box } = kit\n const gx = x0 + (o.gripAt || 0.07)\n if (!context.isTraditional && o.grip !== 'none') {\n const grip = kit.pivot(group, gx - 0.012, -hR / 2 - 0.046, 0)\n grip.rotation.z = -0.3\n box(grip, 0.032, 0.105, 0.028, furn, 0, 0, 0)\n for (let i = 0; i < 3; i++) box(grip, 0.006, 0.012, 0.026, furn, 0.017, 0.022 - i * 0.02, 0)\n box(grip, 0.034, 0.008, 0.03, furn, 0, -0.052, 0)\n }\n box(group, 0.06, 0.004, 0.01, M.metal, gx + 0.03, -hR / 2 - 0.024, 0)\n box(group, 0.004, 0.022, 0.01, M.metal, gx + 0.06, -hR / 2 - 0.013, 0)\n parts.trigger = box(group, 0.004, 0.016, 0.004, M.dark, gx + 0.024, -hR / 2 - 0.012, 0, 0.15)\n if (o.sel) parts.safety = box(group, 0.016, 0.005, 0.003, M.dark, gx + 0.005, -hR * 0.15, -wR / 2 - 0.002, 0.4)\n return gx\n}\n\n/** The magazine of the kind the options name (curved, box, drum, internal, belt), and the cover and belt box of a belt-fed gun. Returns the x of the well. */\nexport function buildMagazine(context: RifleContext, gx: number): number {\n const { kit, group, parts, options: o, receiverStart: x0, receiverHeight: hR, receiverWidth: wR, receiverLength: RL } = context\n const { M, box, cylinderX, cylinderZ } = kit\n const mx = o.magAt != null ? x0 + o.magAt : gx + 0.075\n const scale = o.magLen || 1\n const magazine = kit.pivot(group, mx, -hR / 2, 0)\n parts.mag = magazine\n const finish: THREE.Material | undefined = o.magMat === 'bakelite' ? M.bakelite : o.magMat === 'poly' ? M.polyMag : undefined\n if (o.mag === 'curved') {\n let px = 0\n let py = 0\n const material = finish ?? M.metal\n for (const angle of [0.06, 0.22, 0.38]) {\n const length = 0.07 * scale\n const cx = px + (Math.sin(angle) * length) / 2\n const cy = py - (Math.cos(angle) * length) / 2\n box(magazine, 0.052, length + 0.004, 0.024, material, cx, cy, 0, angle)\n box(magazine, 0.04, length * 0.8, 0.026, M.dark, cx, cy, 0, angle)\n px += Math.sin(angle) * length\n py -= Math.cos(angle) * length\n }\n box(magazine, 0.058, 0.008, 0.028, material, px, py, 0, 0.38)\n parts.magDrop = 0.07 * scale * 3 + 0.04\n } else if (o.mag === 'box') {\n const length = 0.13 * scale\n const curve = o.curve || 0\n const segment = length / 3\n const material = finish ?? M.dark\n let px = 0\n let py = 0\n let angle = 0.08\n for (let i = 0; i < 3; i++) {\n angle = 0.08 + curve * i\n const cx = px + (Math.sin(angle) * segment) / 2\n const cy = py - (Math.cos(angle) * segment) / 2\n box(magazine, 0.05, segment + 0.004, 0.024, material, cx, cy, 0, angle)\n box(magazine, 0.04, 0.003, 0.026, M.metal, cx, cy, 0, angle)\n px += Math.sin(angle) * segment\n py -= Math.cos(angle) * segment\n }\n box(magazine, 0.056, 0.007, 0.028, material, px, py - 0.002, 0, angle)\n parts.magDrop = length + 0.03\n } else if (o.mag === 'drum') {\n cylinderZ(magazine, 0.075, 0.07, M.dark, 0.02, -0.085, 0, 22)\n cylinderZ(magazine, 0.05, 0.074, M.metal, 0.02, -0.085, 0, 18)\n box(magazine, 0.05, 0.04, 0.03, M.dark, 0, -0.02, 0)\n parts.magDrop = 0.2\n } else if (o.mag === 'internal') {\n box(group, 0.08, 0.025, 0.03, context.isTraditional ? context.furniture : M.metal, mx, -hR / 2 - 0.012, 0)\n parts.mag = null\n } else parts.mag = null\n if (o.mag === 'belt') {\n const belt = kit.pivot(group, mx + 0.02, -hR / 2 - 0.05, -0.045)\n parts.belt = belt\n box(belt, 0.11, 0.1, 0.08, M.olive, 0, 0, 0)\n box(belt, 0.112, 0.012, 0.082, M.dark, 0, 0.046, 0)\n for (let i = 0; i < 7; i++) {\n cylinderX(belt, 0.0042, 0.034, M.brass, -0.04 + i * 0.012, 0.07, 0.035, 10)\n box(belt, 0.006, 0.006, 0.012, M.metal, -0.04 + i * 0.012, 0.066, 0.035)\n }\n const cover = kit.pivot(group, x0 + 0.01, hR / 2, 0)\n parts.cover = cover\n box(cover, RL - 0.03, 0.014, wR * 1.05, M.metal, (RL - 0.03) / 2, 0.007, 0)\n box(cover, 0.02, 0.012, wR * 0.6, M.dark, RL - 0.04, 0.016, 0)\n }\n return mx\n}\n","import { buttpad, swivel } from './details'\nimport type { RifleContext } from './rifle-context'\n\n/** The stock by kind, in the order the page draws them. `magazineX` places the magazine well plate of the one-piece stock. */\nexport function buildStock(context: RifleContext, magazineX: number): void {\n const { kit, group, options: o, furniture: furn, length: L, stockLength: S, receiverStart: x0, receiverEnd: x1, receiverHeight: hR } = context\n const { M, box, cylinderX } = kit\n if (context.isTraditional) {\n buttpad(kit, group, 0.006, -0.04, 0.13, 0.038)\n box(group, 0.03, 0.13, 0.038, furn, 0.024, -0.04, 0)\n box(group, S, 0.055, 0.034, furn, S / 2, -0.012, 0, 0.06)\n box(group, 0.09, 0.05, 0.032, furn, x0 - 0.02, -0.035, 0, 0.25)\n const forendLength = x1 - x0 + (L - x1) * (o.fore ?? 0.62)\n if (forendLength > 0) box(group, forendLength, 0.045, 0.04, furn, x0 + forendLength / 2, -hR / 2 + 0.004, 0)\n if (o.stock === 'straight') box(group, 0.15, 0.04, 0.035, furn, x1 + 0.08, -hR / 2, 0)\n box(group, 0.04, 0.004, 0.03, M.metal, magazineX, -hR / 2 - 0.022, 0)\n swivel(kit, group, 0.2, -0.08)\n swivel(kit, group, x1 + (L - x1) * 0.45, -hR / 2 - 0.03)\n if (o.bands) for (const fraction of [0.35, 0.75]) cylinderX(group, 0.024, 0.008, M.metal, x1 + (L - x1) * fraction * (o.fore || 0.62), -0.004, 0, 16)\n } else if (o.stock === 'fixed' || o.stock === 'wood') {\n box(group, S, 0.05, 0.03, furn, S / 2, -0.008, 0, 0.05)\n box(group, 0.03, 0.13, 0.036, furn, 0.022, -0.035, 0)\n buttpad(kit, group, 0.004, -0.035, 0.13, 0.036)\n if (o.stock === 'wood') box(group, S * 0.6, 0.03, 0.028, furn, S * 0.55, -0.045, 0, 0.2)\n swivel(kit, group, 0.08, -0.09)\n } else if (o.stock === 'skeleton') {\n box(group, S, 0.014, 0.026, furn, S / 2, 0.012, 0, 0.03)\n box(group, S, 0.014, 0.026, furn, S / 2, -0.05, 0, -0.08)\n box(group, 0.03, 0.12, 0.034, furn, 0.02, -0.025, 0)\n buttpad(kit, group, 0.004, -0.025, 0.12, 0.034)\n } else if (o.stock === 'retract') {\n cylinderX(group, 0.013, S, M.metal, S / 2, 0, 0, 16)\n for (let i = 0; i < 5; i++) box(group, 0.003, 0.003, 0.008, M.dark, S * 0.2 + i * 0.015, -0.013, 0)\n box(group, 0.034, 0.11, 0.036, furn, 0.02, -0.025, 0)\n box(group, S * 0.55, 0.032, 0.03, furn, S * 0.35, 0, 0)\n buttpad(kit, group, 0.003, -0.025, 0.11, 0.036)\n } else if (o.stock === 'fold') {\n box(group, S, 0.006, 0.006, M.metal, S / 2, 0.01, 0.012)\n box(group, S, 0.006, 0.006, M.metal, S / 2, -0.04, 0.012, -0.12)\n box(group, 0.012, 0.1, 0.03, M.metal, 0.006, -0.02, 0.012)\n }\n}\n","import { heatify } from './kit'\nimport type { ModelKit } from './kit'\nimport { rail } from './details'\nimport { buildFittings } from './rifle-fittings'\nimport { buildForend } from './rifle-forend'\nimport { buildGrip, buildMagazine } from './rifle-controls'\nimport { buildStock } from './rifle-stock'\nimport type { RifleContext } from './rifle-context'\nimport type { BuiltModel, ModelFamily, ModelOptions, ModelParts } from './types'\n\nconst PI = Math.PI\n\n/** Receiver by kind (round, AR, plain), the AK and G3 extras, the ejection port, the bolt and its charging handle. */\nfunction buildReceiver(context: RifleContext): void {\n const { kit, group, parts, options: o, length: L, receiverStart: x0, receiverEnd: x1, receiverHeight: hR, receiverWidth: wR, receiverLength: RL, barrelY: by } = context\n const { M, box, cylinderX, cylinderY, cylinderZ, sphere } = kit\n const receiverMaterial = o.tan ? M.tan : M.metal\n const middle = (x0 + x1) / 2\n if (o.round) {\n cylinderX(group, hR * 0.36, RL, M.steel, middle, by, 0, 20)\n cylinderX(group, hR * 0.32, 0.05, M.steel, x0 - 0.01, by, 0, 18)\n } else if (o.ar) {\n box(group, RL, hR * 0.5, wR, receiverMaterial, middle, hR * 0.25, 0)\n box(group, RL * 0.92, hR * 0.52, wR * 0.96, receiverMaterial, middle - RL * 0.02, -hR * 0.24, 0)\n box(group, 0.05, 0.03, wR * 1.15, receiverMaterial, x0 + RL * 0.62, -hR * 0.5 - 0.01, 0)\n cylinderZ(group, 0.006, 0.012, M.metal, x1 - 0.03, hR * 0.28, wR / 2 + 0.006, 12)\n box(group, 0.012, 0.01, 0.012, M.metal, x1 - 0.05, hR * 0.12, wR / 2 + 0.006)\n box(group, 0.03, 0.008, 0.012, M.dark, x0 + 0.02, hR / 2 + 0.004, 0)\n box(group, 0.012, 0.006, 0.004, M.dark, x0 + RL * 0.55, -hR * 0.15, -wR / 2 - 0.002)\n } else box(group, RL, hR, wR, receiverMaterial, middle, 0, 0)\n if (o.ak) {\n box(group, RL * 0.86, hR * 0.28, wR * 0.95, M.metal, middle - 0.008, hR / 2 + 0.004, 0)\n for (let i = 0; i < 3; i++) box(group, 0.004, hR * 0.3, wR * 0.97, M.dark, x0 + RL * 0.25 + i * 0.02, hR / 2 + 0.004, 0)\n box(group, RL * 0.5, 0.012, 0.003, M.metal, x0 + RL * 0.55, -hR * 0.02, wR / 2 + 0.0015, -0.05)\n box(group, 0.012, 0.014, 0.003, M.dark, x0 + RL * 0.32, -hR * 0.05, wR / 2 + 0.002)\n }\n if (o.g3) {\n cylinderX(group, 0.009, (L - x1) * 0.6, M.metal, x1 + (L - x1) * 0.28, hR * 0.48, 0, 14)\n box(group, 0.012, 0.024, 0.008, M.dark, x1 + (L - x1) * 0.5, hR * 0.48, -0.012)\n cylinderY(group, 0.012, 0.016, M.dark, x0 + 0.03, hR / 2 + 0.008, 0, 12)\n }\n const ejectX = x1 - (o.ejectBack || 0.07)\n const ejectY = o.ar ? hR * 0.2 : by\n box(group, 0.05, hR * 0.36, 0.004, M.hole, ejectX, ejectY, wR / 2 - 0.0004)\n const bolt = kit.pivot(group)\n parts.bolt = bolt\n parts.stroke = Math.min(0.1, RL * 0.32)\n box(bolt, 0.044, hR * 0.26, 0.006, M.steelL, ejectX, ejectY, wR / 2 - 0.0012)\n if (o.charge) {\n box(bolt, 0.012, 0.01, 0.03, M.metal, ejectX + 0.04, ejectY + 0.004, wR / 2 + 0.012)\n sphere(bolt, 0.0065, M.metal, ejectX + 0.04, ejectY + 0.004, wR / 2 + 0.028, 1)\n }\n if (o.ar) box(group, 0.012, 0.016, 0.006, receiverMaterial, ejectX - 0.03, ejectY + 0.004, wR / 2 + 0.004)\n if (o.rail) rail(kit, group, x0 - 0.005, RL + 0.07, hR / 2 + (o.ar ? 0 : 0.003), 0, wR * 0.68)\n}\n\n/** Barrel with its jacket, gas tube and muzzle device. */\nfunction buildBarrel(context: RifleContext): void {\n const { kit, group, parts, options: o, length: L, barrelLength: Bl, receiverEnd: x1, barrelRadius: r, barrelY: by } = context\n const { M, box, cylinderX } = kit\n heatify(parts.glow, cylinderX(group, r, Bl, M.metal, L - Bl / 2, by, 0, 16))\n if (o.jacket) {\n cylinderX(group, r * 2, (L - x1) * 0.6, M.dark, x1 + (L - x1) * 0.3, by, 0, 16)\n for (let i = 0; i < 6; i++) cylinderX(group, r * 2.15, 0.004, M.metal, x1 + (L - x1) * (0.05 + i * 0.09), by, 0, 16)\n }\n if (o.gas) cylinderX(group, r * 0.75, (L - x1) * 0.55, M.metal, x1 + (L - x1) * 0.3, by + r * 2.2, 0, 14)\n if (o.brake) {\n const scale = o.brake === 2 ? 3.2 : 2.0\n const brakeLength = o.brake === 2 ? 0.12 : 0.06\n heatify(parts.glow, cylinderX(group, r * scale, brakeLength, M.dark, L - brakeLength / 2, by, 0, o.brake === 2 ? 8 : 16))\n for (let i = 0; i < 3; i++) box(group, brakeLength * 0.16, r * scale * 1.3, r * scale * 2.2, M.hole, L - brakeLength * 0.25 - i * brakeLength * 0.25, by, 0)\n } else if (!o.noFH) {\n heatify(parts.glow, cylinderX(group, r * 1.45, 0.042, M.dark, L - 0.021, by, 0, 16))\n for (let i = 0; i < 4; i++) {\n const angle = (i * PI) / 2 + PI / 4\n box(group, 0.026, 0.0025, 0.004, M.hole, L - 0.02, by + Math.cos(angle) * r * 1.42, Math.sin(angle) * r * 1.42, 0, 0, angle)\n }\n }\n cylinderX(group, r * 0.55, 0.004, M.hole, L + 0.0005, by, 0, 12)\n}\n\nconst familyOf = (o: ModelOptions): ModelFamily => {\n if (o.mag === 'belt') return 'belt'\n if (o.pump) return 'pump'\n if (o.lever) return 'lever'\n if (o.tube) return 'semi12'\n if (o.bolt) return o.mag === 'box' ? 'boltmag' : 'bolt'\n return o.mag === 'internal' ? 'semiint' : 'rifle'\n}\n\n/** Port of the gallery's `rifle`, the builder of 51 of the weapons: receiver, barrel, forend, grip, magazine, stock and what is fitted on them. */\nexport function buildRifle(kit: ModelKit, options: ModelOptions): BuiltModel {\n const { M } = kit\n const group = kit.group()\n const parts: ModelParts = { family: 'rifle', glow: [] }\n const length = (options.L ?? 0) / 1000\n const barrelLength = (options.B ?? 0) / 1000\n const isTraditional = options.stock === 'trad' || options.stock === 'straight'\n const stockLength = options.stock === 'none' ? 0 : options.stockLen || Math.min(0.36, Math.max(0.2, 0.3 * length))\n const receiverStart = stockLength\n const receiverEnd = Math.max(receiverStart + 0.12, length - barrelLength * 0.92)\n const receiverHeight = options.hR || 0.06\n const context: RifleContext = {\n kit,\n group,\n parts,\n options,\n furniture: options.wood ? M.wood : options.olive ? M.olive : options.tan ? M.tan : M.poly,\n isTraditional,\n length,\n barrelLength,\n stockLength,\n receiverStart,\n receiverEnd,\n receiverHeight,\n receiverWidth: options.wR || 0.034,\n barrelRadius: options.br || 0.0085,\n barrelY: receiverHeight * 0.15,\n receiverLength: receiverEnd - receiverStart,\n }\n buildReceiver(context)\n buildBarrel(context)\n buildForend(context)\n const gripX = buildGrip(context)\n const magazineX = buildMagazine(context, gripX)\n buildStock(context, magazineX)\n buildFittings(context, gripX)\n const { barrelY: by, receiverWidth: wR } = context\n const ejectX = receiverEnd - (options.ejectBack || 0.07)\n const ejectY = options.ar ? receiverHeight * 0.2 : by\n parts.muzzle = kit.mark(group, length + 0.01, by, 0)\n parts.eject = kit.mark(group, ejectX, ejectY, wR / 2 + 0.006)\n parts.loadPort = kit.mark(group, receiverEnd - 0.05, -receiverHeight / 2 - 0.004, 0)\n parts.topLoad = kit.mark(group, ejectX, receiverHeight / 2 + 0.004, 0)\n parts.family = familyOf(options)\n return { group, parts }\n}\n","import type * as THREE_NS from 'three'\nimport { WEAPONS } from '@adatechnology/game-weapons'\nimport data from '../data/models.json'\nimport { buildBreakAction } from './break-action'\nimport { buildBullpup } from './bullpup'\nimport { modelKit } from './kit'\nimport type { ModelKit } from './kit'\nimport { buildLauncher } from './launcher'\nimport { buildM2 } from './m2'\nimport { buildP90 } from './p90'\nimport { partRegistry } from './part-registry'\nimport { buildPistol } from './pistol'\nimport { buildRevolver } from './revolver'\nimport { buildRifle } from './rifle'\nimport type { BuiltModel, ModelOptions, ModelParts } from './types'\n\nexport type { ModelFamily, ModelOptions, ModelParts } from './types'\n\n/** One weapon of the gallery as `data/models.json` keeps it: the builder, the measures in mm and the builder's options. */\nexport interface ModelEntry {\n readonly builder: 'pistol' | 'revolver' | 'rifle' | 'bullpup' | 'p90' | 'break' | 'm2' | 'launcher'\n readonly caliber: string\n readonly length: number\n readonly barrel: number\n readonly options: ModelOptions\n readonly variantOf?: string\n}\n\nexport const MODEL_ENTRIES: Readonly<Record<string, ModelEntry>> = data as Record<string, ModelEntry>\n\n/**\n * The model each generic archetype wears: the one of the first brand weapon (lowest id) that points to it with `archetype` and fires the same way (a rocket launcher that points to\n * `shotgun_pump_12` does not lend its tube to the shotgun). An archetype nothing points to, the melee weapons and the bow keep their simple prop.\n */\nexport const ARCHETYPE_MODELS: Readonly<Record<string, string>> = (() => {\n const actionOf = new Map(WEAPONS.map((def) => [def.id, def.action.kind]))\n const chosen: Record<string, string> = {}\n for (const def of [...WEAPONS].sort((a, b) => (a.id < b.id ? -1 : 1))) {\n const { archetype } = def\n if (!archetype || !(def.id in MODEL_ENTRIES) || archetype in MODEL_ENTRIES || archetype in chosen) continue\n if (actionOf.get(archetype) === def.action.kind) chosen[archetype] = def.id\n }\n return chosen\n})()\n\n/** A weapon model: `root` (the page's `wr`) holds `inner` (what the builder made, fitted to the real length); `parts` are pivots and marks inside `inner`. */\nexport interface WeaponModel {\n readonly id: string\n readonly root: THREE_NS.Group\n readonly inner: THREE_NS.Group\n readonly parts: ModelParts\n}\n\nconst BUILDERS: Record<ModelEntry['builder'], (kit: ModelKit, options: ModelOptions) => BuiltModel> = {\n pistol: buildPistol,\n revolver: buildRevolver,\n rifle: buildRifle,\n bullpup: buildBullpup,\n p90: (kit) => buildP90(kit),\n break: buildBreakAction,\n m2: (kit) => buildM2(kit),\n launcher: buildLauncher,\n}\n\nconst nameParts = (parts: ModelParts): void => {\n for (const [name, part] of partRegistry(parts)) part.name = name\n}\n\n/** Stretches the model along x to the real length of the weapon (the page's `fitLength`) and puts its rear at the origin. */\nconst fitLength = (kit: ModelKit, inner: THREE_NS.Group, lengthMetres: number): THREE_NS.Group => {\n const box = new kit.THREE.Box3().setFromObject(inner)\n const factor = lengthMetres / (box.max.x - box.min.x)\n inner.scale.x = factor\n inner.position.x = -box.min.x * factor\n const root = kit.group()\n root.add(inner)\n return root\n}\n\nexport const hasWeaponModel = (id: string): boolean => id in MODEL_ENTRIES || id in ARCHETYPE_MODELS\n\n/** The gallery model of a weapon (or of the brand weapon an archetype wears, see `ARCHETYPE_MODELS`), long axis along +x, rear at the origin; undefined for melee, throwables and what nothing drew. */\nexport function buildWeaponModelById(THREE: typeof THREE_NS, id: string): WeaponModel | undefined {\n const entry = MODEL_ENTRIES[ARCHETYPE_MODELS[id] ?? id]\n if (!entry) return undefined\n const kit = modelKit(THREE)\n const options: ModelOptions = { L: entry.length, B: entry.barrel, cal: entry.caliber, ...entry.options }\n if (id in ARCHETYPE_MODELS) delete options.chambers // a generic weapon holds the default six, not the brand's capacity\n const built = BUILDERS[entry.builder](kit, options)\n nameParts(built.parts)\n let root: THREE_NS.Group\n if (entry.builder === 'launcher') {\n root = kit.group()\n root.add(built.group)\n built.group.position.x = -new THREE.Box3().setFromObject(built.group).min.x\n } else root = fitLength(kit, built.group, entry.length / 1000)\n root.name = id\n return { id, root, inner: built.group, parts: built.parts }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, JointSpec, PartSpec, Vec3 } from '@adatechnology/game-contracts'\nimport type { WeaponDef } from '@adatechnology/game-weapons'\nimport { mergeByMaterial } from './merge-by-material'\nimport { buildWeaponModelById } from './models'\n\n/** A low-poly prop: its destruction spec (box parts only) and one colour per part. */\nexport interface WeaponProp {\n spec: DestructibleSpec\n colors: Record<string, number>\n}\n\ntype Extra = Partial<Omit<PartSpec, 'id' | 'material' | 'shape' | 'position'>>\nconst box = (id: string, material: string, size: Vec3, position: Vec3, extra: Extra = {}): PartSpec => ({ id, material, shape: { kind: 'box', size }, position, ...extra })\nconst joint = (a: string, b: string, kind: JointSpec['kind']): JointSpec => ({ a, b, kind })\n\n// A grip and a body lying flat end to end, long axis along +x, the muzzle or head at +x. One thickness for both parts so the prop lies flat,\n// and the parts touch without overlapping: overlapping parts are pushed apart by the physics and the prop slides away.\nconst handled = (name: string, handle: [string, Vec3], head: [string, Vec3]): WeaponProp => {\n const [handleMaterial, rawHandle] = handle\n const [headMaterial, rawHead] = head\n const thickness = Math.max(rawHandle[1], rawHead[1])\n const handleSize: Vec3 = [rawHandle[0], thickness, rawHandle[2]]\n const headSize: Vec3 = [rawHead[0], thickness, rawHead[2]]\n const shift = (handleSize[0] - headSize[0]) / 2\n return {\n spec: {\n name,\n parts: [box('handle', handleMaterial, handleSize, [-handleSize[0] / 2 + shift, thickness / 2, 0]), box('head', headMaterial, headSize, [headSize[0] / 2 + shift, thickness / 2, 0])],\n joints: [joint('handle', 'head', 'screw')],\n tags: ['weapon'],\n },\n colors: { handle: handleMaterial === 'steel' ? 0x3a3d42 : handleMaterial === 'plastic' ? 0x2b2d30 : 0x7a5530, head: headMaterial === 'steel' ? 0x8f969e : headMaterial === 'copper' ? 0xb87333 : 0x6b4a2a },\n }\n}\nconst solid = (name: string, material: string, size: Vec3, color: number): WeaponProp => ({\n spec: { name, parts: [box('body', material, size, [0, size[1] / 2, 0])], joints: [], tags: ['weapon'] },\n colors: { body: color },\n})\n\nconst SHAPES: Record<string, (name: string, id: string) => WeaponProp> = {\n pistol: (n) => handled(n, ['plastic', [0.06, 0.03, 0.11]], ['steel', [0.2, 0.03, 0.04]]),\n revolver: (n) => handled(n, ['wood_soft', [0.06, 0.035, 0.11]], ['steel', [0.24, 0.04, 0.05]]),\n smg: (n) => handled(n, ['plastic', [0.2, 0.05, 0.14]], ['steel', [0.45, 0.05, 0.06]]),\n carbine: (n) => handled(n, ['wood_soft', [0.35, 0.05, 0.12]], ['steel', [0.6, 0.04, 0.05]]),\n rifle: (n) => handled(n, ['wood_soft', [0.35, 0.06, 0.13]], ['steel', [0.75, 0.05, 0.07]]),\n sniper: (n) => handled(n, ['plastic', [0.4, 0.06, 0.14]], ['steel', [0.95, 0.06, 0.08]]),\n shotgun: (n) => handled(n, ['wood_soft', [0.38, 0.06, 0.13]], ['steel', [0.7, 0.05, 0.06]]),\n bow: (n) => solid(n, 'wood_soft', [0.95, 0.03, 0.22], 0x5a3d22),\n crossbow: (n) => handled(n, ['wood_soft', [0.6, 0.06, 0.08]], ['steel', [0.12, 0.04, 0.26]]),\n melee_blunt: (n, id) =>\n id === 'baseball_bat'\n ? solid(n, 'wood_soft', [0.84, 0.06, 0.06], 0xb08550)\n : handled(n, ['wood_soft', [id === 'sledgehammer' ? 0.8 : 0.32, 0.03, 0.03]], ['steel', id === 'sledgehammer' ? [0.08, 0.08, 0.2] : [0.06, 0.04, 0.12]]),\n melee_blade: (n, id) => handled(n, ['wood_soft', [0.13, 0.03, 0.03]], ['steel', id === 'axe' ? [0.5, 0.03, 0.16] : id === 'knife' ? [0.16, 0.01, 0.03] : [0.45, 0.01, 0.05]]),\n tool: (n) => handled(n, ['plastic', [0.12, 0.025, 0.03]], ['steel', [0.16, 0.02, 0.03]]),\n flame: (n, id) => (id === 'flamethrower' ? handled(n, ['steel', [0.3, 0.14, 0.14]], ['steel', [0.6, 0.05, 0.05]]) : solid(n, 'plastic', [0.08, 0.02, 0.04], 0xd9482b)),\n heat: (n) => handled(n, ['steel', [0.2, 0.08, 0.08]], ['copper', [0.25, 0.03, 0.03]]),\n throwable: (n, id) => (id === 'molotov' ? solid(n, 'glass', [0.25, 0.07, 0.07], 0x7fd6b0) : solid(n, 'steel', [id === 'pipe_bomb' ? 0.25 : 0.1, 0.06, 0.06], 0x4c5a3a)),\n extinguisher: (n) => solid(n, 'steel', [0.5, 0.15, 0.15], 0xc0392b),\n}\n\n/** Body actions of the arsenal: nothing to hold or lay on a counter. */\nexport const BODY_ACTIONS: ReadonlySet<string> = new Set(['hand', 'kick', 'shove', 'fists'])\n\n// Real weights from the arsenal data: solid steel boxes would weigh several times more, go past a carry limit and stop being props.\nconst withMass = (prop: WeaponProp, kg: number): WeaponProp => {\n const volumes = prop.spec.parts.map((part) => (part.shape.kind === 'box' ? part.shape.size[0] * part.shape.size[1] * part.shape.size[2] : 0))\n const total = volumes.reduce((sum, volume) => sum + volume, 0) || 1\n return { ...prop, spec: { ...prop.spec, parts: prop.spec.parts.map((part, index) => ({ ...part, mass: (kg * volumes[index]) / total })) } }\n}\n\n/** The prop of a weapon: low-poly parts by category, the real mass of the weapon spread over them. */\nexport function weaponProp(def: Pick<WeaponDef, 'id' | 'category' | 'mass'>, name = def.id): WeaponProp {\n const shape = SHAPES[def.category] ?? SHAPES.tool\n return withMass(shape(name, def.id), def.mass)\n}\n\n/** One mesh per box part, named after the part (what destruction renderers bind to), in a group with its origin on the floor. */\nexport function buildProp(THREE: typeof THREE_NS, prop: WeaponProp): THREE_NS.Group {\n const group = new THREE.Group()\n group.name = prop.spec.name ?? 'weapon'\n for (const part of prop.spec.parts) {\n if (part.shape.kind !== 'box') continue\n const [w, h, d] = part.shape.size\n const material = new THREE.MeshStandardMaterial({ color: prop.colors[part.id] ?? 0x777777, roughness: 0.6, metalness: part.material === 'steel' ? 0.6 : 0.05 })\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(w, h, d), material)\n mesh.name = part.id\n mesh.position.set(part.position[0], part.position[1], part.position[2])\n mesh.castShadow = true\n mesh.receiveShadow = true\n group.add(mesh)\n }\n return group\n}\n\n/** The model of a weapon for the hands or a shelf: the same prop the counters show. */\nexport function buildWeaponModel(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id' | 'category' | 'mass'>): THREE_NS.Group {\n return buildProp(THREE, weaponProp(def))\n}\n\nconst MODEL_BODY = 'body'\n\n/**\n * The prop of a weapon the gallery drew, for a counter or the floor: its model lying on the side, centred on the footprint with its underside on the floor, joined into one mesh per\n * material (the hands keep the model with its pivots, `buildWeaponModelById`), every mesh naming the one rigid part (`body`) that moves it. The size of that part is left in\n * `userData.footprint` for `modeledPropSpec`.\n */\nexport function buildModeledProp(THREE: typeof THREE_NS, def: Pick<WeaponDef, 'id'>, name: string): THREE_NS.Group | undefined {\n const model = buildWeaponModelById(THREE, def.id)\n if (!model) return undefined\n const group = new THREE.Group()\n group.name = name\n const box = new THREE.Box3().setFromObject(model.root)\n const center = box.getCenter(new THREE.Vector3())\n model.root.position.set(-center.x, -box.min.y, -center.z)\n group.add(model.root)\n group.updateMatrixWorld(true)\n for (const mesh of mergeByMaterial(THREE, model.root, group)) {\n mesh.userData.destructionPart = MODEL_BODY\n group.add(mesh)\n }\n group.remove(model.root)\n const size = box.getSize(new THREE.Vector3())\n group.userData.footprint = [size.x, size.y, size.z]\n return group\n}\n\n/** The destruction spec of a modeled prop: one steel box of its measures, with the real mass of the weapon. */\nexport function modeledPropSpec(root: unknown, def: Pick<WeaponDef, 'mass'>, name: string): DestructibleSpec {\n const footprint = ((root as THREE_NS.Object3D).userData.footprint ?? [0.3, 0.1, 0.1]) as Vec3\n const size: Vec3 = [Math.max(0.02, footprint[0]), Math.max(0.02, footprint[1]), Math.max(0.02, footprint[2])]\n return { name, parts: [{ id: MODEL_BODY, material: 'steel', shape: { kind: 'box', size }, position: [0, size[1] / 2, 0], mass: def.mass }], joints: [], tags: ['weapon'] }\n}\n","import type * as THREE_NS from 'three'\nimport type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponAudio } from './audio'\nimport { createLayers } from './fx/layers'\nimport type { FxLayers } from './fx/layers'\nimport { BODY_ACTIONS, buildWeaponModel } from './props'\n\nexport interface WeaponFxOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n /** Height things rest on at (x, z): casings and magazines land there. */\n groundAt: (x: number, z: number) => number\n /** Sounds (`createWeaponAudio`); null or absent: silent. */\n audio?: WeaponAudio | null\n /** Seed of the scatter of the effects of the gallery models. */\n seed?: number\n /** The tool as it is now (barrel heat, fuel burning). */\n tool?: () => HostTool\n /** Wear of the weapon: `new`, `used`, `worn` or `rusty`. */\n condition?: string\n /** What is drawn: read at the moment of each event, so the bench can change it live. */\n layers?: FxLayers\n /** Metres between the shooter and the listener, for the distance muffling of the shot sound (default 0). */\n soundDistance?: () => number\n}\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface BoxFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Takes the weapon out of the hands. */\n unequip(): void\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/** Weapons that throw the spent case out on every shot. Revolvers keep them in the cylinder; break-actions open on reload. */\nconst EJECTS_ON_SHOT = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper', 'shotgun'])\n/** Weapons whose reload drops a magazine. */\nconst DROPS_MAGAZINE = new Set(['pistol', 'smg', 'carbine', 'rifle', 'sniper'])\n/** Manual actions that cycle (pump, bolt) after each shot: the sound of the cycle. */\nconst CYCLES = new Set(['shotgun_pump_12', 'rifle_bolt_308'])\n// a bow, a crossbow or a tool has no calibre: about a small handgun round\nconst FALLBACK_ENERGY = 300\nconst MAX_CASINGS = 120\nconst MAX_MAGAZINES = 12\nconst LIFETIME_S = 25\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst GRAVITY = 9.81\n\ninterface Body {\n mesh: THREE_NS.Mesh\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n radius: number\n age: number\n resting: boolean\n bounces: number\n kind: 'casing' | 'magazine'\n}\n\n/** The presentation of a weapon the gallery did not draw (the generic archetypes): a low-poly prop in the hands, a dip on reload and a casing per shot. */\nexport function createBoxFx(options: WeaponFxOptions): BoxFx {\n const { THREE, scene, camera, arsenal, groundAt } = options\n const audio = options.audio ?? null\n const random = createRng(options.seed ?? 1)\n const layers = options.layers ?? createLayers()\n const bodies: Body[] = []\n const brass = new THREE.MeshStandardMaterial({ color: 0xc9a24a, metalness: 0.8, roughness: 0.35 })\n const shell = new THREE.MeshStandardMaterial({ color: 0xa8322b, roughness: 0.6 })\n const steel = new THREE.MeshStandardMaterial({ color: 0x2f3237, metalness: 0.5, roughness: 0.5 })\n const hand = new THREE.Group()\n hand.name = 'weapon-in-hand'\n scene.add(hand)\n let model: THREE_NS.Object3D | null = null\n let inHand: string | null = null\n let def: WeaponDef | null = null\n let kick = 0\n let dip = 0\n let reloading = false\n const v = new THREE.Vector3()\n const q = new THREE.Quaternion()\n const pointForward = new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2)\n\n const equip = (weapon: string): void => {\n if (model) hand.remove(model)\n model = null\n inHand = null\n def = arsenal.weapons.get(weapon) ?? null\n if (!def || BODY_ACTIONS.has(def.id)) return\n model = buildWeaponModel(THREE, def)\n const length = new THREE.Box3().setFromObject(model).getSize(v).x\n // long guns are drawn smaller so they do not fill the view\n model.scale.setScalar(length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1)\n model.quaternion.copy(pointForward)\n hand.add(model)\n inHand = def.id\n }\n\n // a point on the gun in camera space, turned into the world\n const handPoint = (x: number, y: number, z: number, out: THREE_NS.Vector3): THREE_NS.Vector3 =>\n out.set(HAND_OFFSET[0] + x, HAND_OFFSET[1] + y, HAND_OFFSET[2] + z).applyQuaternion(camera.quaternion).add(camera.position)\n\n const throwBody = (kind: Body['kind'], mesh: THREE_NS.Mesh, from: THREE_NS.Vector3, velocity: THREE_NS.Vector3, radius: number): void => {\n if (!(kind === 'casing' ? layers.casings : layers.magazines)) {\n mesh.geometry.dispose()\n return\n }\n const limit = kind === 'casing' ? MAX_CASINGS : MAX_MAGAZINES\n const same = bodies.filter((b) => b.kind === kind)\n if (same.length >= limit) removeBody(same[0])\n mesh.position.copy(from)\n mesh.castShadow = true\n scene.add(mesh)\n bodies.push({ mesh, velocity, spin: new THREE.Vector3(random() * 20 - 10, random() * 30 - 15, random() * 20 - 10), radius, age: 0, resting: false, bounces: 0, kind })\n }\n\n const ejectCasing = (caliberMm: number, isShell: boolean, downward: boolean): void => {\n const radius = isShell ? 0.0105 : Math.max(0.003, (caliberMm / 1000) * 0.6)\n const length = isShell ? 0.068 : Math.min(0.07, Math.max(0.015, (caliberMm / 1000) * 2.6))\n const mesh = new THREE.Mesh(new THREE.CylinderGeometry(radius, radius, length, 8), isShell ? shell : brass)\n mesh.name = 'casing'\n const from = handPoint(0.03, 0.03, 0.05, new THREE.Vector3())\n const right = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion)\n const up = new THREE.Vector3(0, 1, 0)\n const velocity = downward\n ? up.clone().multiplyScalar(-0.5).addScaledVector(right, (random() - 0.5) * 0.4)\n : right.multiplyScalar(1.6 + random() * 0.8).addScaledVector(up, 1.4 + random() * 0.8)\n throwBody('casing', mesh, from, velocity, radius)\n }\n\n const dropMagazine = (category: string): void => {\n const long = category === 'rifle' || category === 'sniper' || category === 'carbine'\n const size: [number, number, number] = long ? [0.03, 0.17, 0.07] : [0.025, 0.11, 0.035]\n const mesh = new THREE.Mesh(new THREE.BoxGeometry(...size), steel)\n mesh.name = 'magazine'\n const from = handPoint(0, -0.06, 0, new THREE.Vector3())\n throwBody('magazine', mesh, from, new THREE.Vector3(0, -0.4, 0), size[1] / 2)\n audio?.reloadStart(category)\n }\n\n const caliberOf = (weapon: WeaponDef): number => {\n if (weapon.action.kind !== 'firearm') return 9\n return arsenal.calibers.get(weapon.action.caliber)?.diameter ?? 9\n }\n\n function removeBody(body: Body): void {\n body.mesh.removeFromParent()\n body.mesh.geometry.dispose()\n bodies.splice(bodies.indexOf(body), 1)\n }\n\n const onShot = (weapon: WeaponDef): void => {\n kick = 1\n const caliber = weapon.action.kind === 'firearm' ? arsenal.calibers.get(weapon.action.caliber) : undefined\n const energy = caliber ? muzzleEnergy(caliber) * (caliber.pellets ?? 1) : FALLBACK_ENERGY\n audio?.shot(energy, weapon.category, { ...(caliber ? { caliber } : {}), distance: options.soundDistance?.() ?? 0 })\n if (CYCLES.has(weapon.id)) audio?.cycle()\n if (EJECTS_ON_SHOT.has(weapon.category) && weapon.id !== 'shotgun_double_12') ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', false)\n }\n\n const onReloadStart = (weapon: WeaponDef, tool: HostTool): void => {\n if (DROPS_MAGAZINE.has(weapon.category)) dropMagazine(weapon.category)\n else audio?.reloadStart(weapon.category)\n // revolvers and break-action shotguns dump their spent cases when opened\n if (weapon.category === 'revolver' || weapon.id === 'shotgun_double_12') {\n const spent = Math.max(1, tool.capacity - tool.ammo)\n for (let i = 0; i < spent; i++) ejectCasing(caliberOf(weapon), weapon.category === 'shotgun', true)\n }\n }\n\n const stepBody = (body: Body, dt: number): void => {\n body.age += dt\n if (body.resting) return\n body.velocity.y -= GRAVITY * dt\n body.mesh.position.addScaledVector(body.velocity, dt)\n body.mesh.rotation.x += body.spin.x * dt\n body.mesh.rotation.y += body.spin.y * dt\n body.mesh.rotation.z += body.spin.z * dt\n const floor = groundAt(body.mesh.position.x, body.mesh.position.z) + body.radius\n if (body.mesh.position.y > floor) return\n body.mesh.position.y = floor\n if (Math.abs(body.velocity.y) > 0.7 && body.bounces < 4) {\n body.bounces++\n body.velocity.y = -body.velocity.y * 0.35\n body.velocity.x *= 0.55\n body.velocity.z *= 0.55\n body.spin.multiplyScalar(0.5)\n if (body.kind === 'casing') audio?.clink()\n else audio?.thud()\n return\n }\n if (body.kind === 'magazine' && body.bounces === 0) audio?.thud()\n body.resting = true\n body.mesh.rotation.x = Math.PI / 2\n body.mesh.rotation.z = 0\n }\n\n return {\n unequip() {\n if (model) hand.remove(model)\n model = null\n inHand = null\n },\n handle(event, tool) {\n if (event.type === 'explosion') return\n const weapon = arsenal.weapons.get(event.weapon)\n if (event.type === 'tool') equip(event.weapon)\n if (!weapon) return\n if (event.type === 'shot') onShot(weapon)\n else if (event.type === 'empty') audio?.click()\n else if (event.type === 'reload' && event.phase === 'start') onReloadStart(weapon, tool)\n else if (event.type === 'reload' && event.phase === 'end') audio?.reloadEnd(weapon.category)\n reloading = tool.reloading\n },\n update(dt) {\n kick *= Math.exp(-dt * 14)\n dip += ((reloading ? 1 : 0) - dip) * Math.min(1, dt * 8)\n if (inHand) {\n handPoint(0, -0.12 * dip, 0.05 * kick, hand.position)\n q.setFromEuler(new THREE.Euler(0.14 * kick - 0.25 * dip, 0, 0.6 * dip))\n hand.quaternion.copy(camera.quaternion).multiply(q)\n }\n for (const body of [...bodies]) {\n stepBody(body, dt)\n if (body.age > LIFETIME_S) removeBody(body)\n }\n },\n get inHand() {\n return inHand\n },\n get casings() {\n return bodies.filter((b) => b.kind === 'casing').length\n },\n get magazines() {\n return bodies.filter((b) => b.kind === 'magazine').length\n },\n dispose() {\n for (const body of [...bodies]) removeBody(body)\n hand.removeFromParent()\n brass.dispose()\n shell.dispose()\n steel.dispose()\n },\n }\n}\n","import type { DamageType, DestructibleSpec, DestructionEvent, Hit, JointSpec, ObjectState, ToolKind, Vec3 } from './destruction'\n\n/**\n * What a game module implements for an object whose behaviour it owns (a vehicle with its own panel deformation, a creature, a machine). The\n * world (`DestructionWorld.register`) hosts it next to its own objects: raycast, shoot, explode, hit, disassemble, extinguish, update, state,\n * reset and `on` all route to it.\n *\n * Space: the impl receives hits in WORLD space and returns events in WORLD space (it owns its transform; the transform given to `register` or\n * `setTransform` is only used by the world for raycasts and blast range). Every event must carry `object === id` and name parts listed by\n * `describe()`.\n */\nexport interface DestructibleImpl {\n readonly id: string\n readonly name?: string\n /** Parts, joints and structure in the impl's local space, for raycast, inspector and log. Called often: keep it cheap. */\n describe(): DestructibleSpec\n /** Apply one hit (see `IMPACT_CONTRACT` for the fields per type) and return the events it caused. */\n hit(hit: Hit): DestructionEvent[]\n /** Advance fire, melting, collapse and other timed behaviour. */\n update?(dt: number): DestructionEvent[]\n state(): ObjectState\n reset?(): void\n /** Same contract as `DestructionWorld.disassemble`: progress 0..1, or -1 when the tool cannot undo the joint. */\n disassemble?(jointId: string, tool: ToolKind, dt: number): number\n extinguish?(partId?: string): void\n /** Optional: an animation moved a part; `position` / `rotation` (Euler XYZ, radians) are object-local. Keep raycast and hit shapes in sync. */\n setPartPose?(partId: string, position: Vec3, rotation?: Vec3): void\n /** Plain JSON of the impl's own state, stored in `DestructionSnapshot.impls`. */\n serialize?(): unknown\n load?(data: unknown): void\n}\n\n/** The fields a weapon or hazard must put in a `Hit`, per damage type. THE impact contract. */\nexport interface ImpactContract {\n required: string[]\n optional: string[]\n note: string\n}\n\nexport const IMPACT_CONTRACT: Record<DamageType, ImpactContract> = {\n ballistic: { required: ['type', 'point', 'direction', 'energy', 'caliber'], optional: ['space', 'source'], note: 'bullets and pellets: joules and diameter in millimetres' },\n blunt: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'contact radius in metres (default 3 cm)' },\n slash: { required: ['type', 'point', 'energy'], optional: ['direction', 'radius', 'space', 'source'], note: 'axes, knives, machetes' },\n explosive: { required: ['type', 'point', 'energy', 'radius'], optional: ['space', 'source'], note: 'point is the centre of the blast, radius the range in metres' },\n fire: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'flame temperature in °C; duration in seconds (call every frame with `dt`)' },\n heat: { required: ['type', 'point', 'temperature', 'radius'], optional: ['duration', 'space', 'source'], note: 'heat without flame (cutting torch, hot plate)' },\n}\n\n/** Problems with a hit according to the impact contract (empty when it is valid). */\nexport const checkHit = (hit: Hit): string[] => {\n const c = IMPACT_CONTRACT[hit.type]\n if (!c) return [`unknown damage type \"${String(hit.type)}\"`]\n const out: string[] = []\n for (const f of c.required) {\n const v = (hit as unknown as Record<string, unknown>)[f]\n if (v === undefined || (Array.isArray(v) ? v.some((n) => !Number.isFinite(n)) : typeof v === 'number' && !Number.isFinite(v))) out.push(`${hit.type} hit needs \"${f}\"`)\n }\n return out\n}\n\nexport interface CheckOptions {\n /**\n * Ids of every material the impl may use (the contracts package does not know the materials of your world: pass the ids of\n * `world.materials`, or the built-in plus your own). When omitted, the material check is skipped.\n */\n materials?: Iterable<string>\n}\n\nconst finiteJson = (v: unknown, path: string, out: string[]) => {\n if (typeof v === 'number') {\n if (!Number.isFinite(v)) out.push(`${path} is not a finite number`)\n } else if (Array.isArray(v)) v.forEach((x, i) => finiteJson(x, `${path}[${i}]`, out))\n else if (v && typeof v === 'object') for (const [k, x] of Object.entries(v)) finiteJson(x, `${path}.${k}`, out)\n else if (typeof v === 'function' || typeof v === 'symbol' || typeof v === 'bigint') out.push(`${path} is not JSON`)\n}\n\n/**\n * Contract checker for the test room (it needs no world): `describe()` is valid, a 500 J ballistic hit at a part centre returns well-formed events of this impl, `state()`\n * matches `describe()`, hit points never go negative, `update(0.016)` returns an array and every event is JSON-serializable. It hits the impl\n * (and calls `reset()` afterwards when there is one).\n */\nexport const checkDestructible = (impl: DestructibleImpl, options: CheckOptions = {}): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const known = options.materials ? new Set(options.materials) : null\n let spec: DestructibleSpec | undefined\n try {\n spec = impl.describe()\n } catch (e) {\n return { ok: false, problems: [`describe() threw: ${String(e)}`] }\n }\n if (!spec || !Array.isArray(spec.parts) || spec.parts.length === 0) return { ok: false, problems: ['describe() must return at least one part'] }\n const ids = new Set<string>()\n for (const p of spec.parts) {\n if (ids.has(p.id)) problems.push(`duplicate part id \"${p.id}\"`)\n ids.add(p.id)\n if (known && !known.has(p.material)) problems.push(`part \"${p.id}\" has unknown material \"${p.material}\"`)\n if (!p.shape || !['box', 'cylinder', 'sphere'].includes(p.shape.kind)) problems.push(`part \"${p.id}\" has no valid shape`)\n if (!Array.isArray(p.position) || p.position.length !== 3) problems.push(`part \"${p.id}\" has no position`)\n }\n const jointIds = new Set<string>()\n for (const j of (spec.joints ?? []) as JointSpec[]) {\n if (!ids.has(j.a) || !ids.has(j.b)) problems.push(`joint \"${j.id ?? `${j.a}~${j.b}`}\" references an unknown part`)\n const jid = j.id ?? `${j.a}~${j.b}`\n if (jointIds.has(jid)) problems.push(`duplicate joint id \"${jid}\"`)\n jointIds.add(jid)\n }\n const checkState = (label: string) => {\n let st: ObjectState\n try {\n st = impl.state()\n } catch (e) {\n problems.push(`state() threw ${label}: ${String(e)}`)\n return\n }\n const sids = st.parts.map((p) => p.id).sort().join(',')\n if (sids !== [...ids].sort().join(',')) problems.push(`state() part ids do not match describe() ${label}`)\n for (const p of st.parts) if (!(p.hp >= 0)) problems.push(`part \"${p.id}\" has negative or invalid hp ${label}`)\n }\n const checkEvents = (events: unknown, label: string) => {\n if (!Array.isArray(events)) {\n problems.push(`${label} must return an array`)\n return\n }\n const evs = events as DestructionEvent[]\n evs.forEach((e, i) => {\n if (e.object !== impl.id) problems.push(`${label} event ${i} (${e.type}) has object \"${String(e.object)}\", expected \"${impl.id}\"`)\n const part = (e as { part?: string }).part\n if (part !== undefined && !ids.has(part)) problems.push(`${label} event ${i} (${e.type}) names unknown part \"${part}\"`)\n })\n const bad: string[] = []\n finiteJson(evs, 'events', bad)\n problems.push(...bad.map((b) => `${label}: ${b}`))\n try {\n const s = JSON.stringify(evs)\n if (JSON.stringify(JSON.parse(s)) !== s) problems.push(`${label} events do not survive a JSON round trip`)\n } catch (e) {\n problems.push(`${label} events are not JSON-serializable: ${String(e)}`)\n }\n }\n checkState('before the hit')\n const target = spec.parts[0]\n try {\n const hit: Hit = { type: 'ballistic', point: [target.position[0], target.position[1], target.position[2]], direction: [0, 0, -1], energy: 500, caliber: 9 }\n checkEvents(impl.hit(hit), 'hit()')\n } catch (e) {\n problems.push(`hit() threw: ${String(e)}`)\n }\n checkState('after the hit')\n if (impl.update) {\n try {\n checkEvents(impl.update(0.016), 'update()')\n } catch (e) {\n problems.push(`update() threw: ${String(e)}`)\n }\n checkState('after update')\n }\n try {\n impl.reset?.()\n } catch (e) {\n problems.push(`reset() threw: ${String(e)}`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import type { DestructibleSpec } from './destruction'\n\nexport interface CheckSpecOptions {\n /** Known material ids. When given, every part's material must be one of them. */\n materials?: Iterable<string>\n}\n\nexport interface SpecReport {\n /** False when there is at least one problem (warnings do not count). */\n ok: boolean\n problems: string[]\n /** Things that are legal but probably wrong, e.g. structural parts that cannot reach an anchored part. */\n warnings: string[]\n}\n\nconst STRUCTURE_ROLES = ['foundation', 'column', 'beam', 'slab', 'wall', 'partition', 'roof', 'stair', 'none']\nconst BEARS = [true, false, 'a_on_b', 'b_on_a']\n\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\nconst positive = (n: unknown): boolean => finite(n) && n > 0\nconst vec3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every(finite)\nconst nonNegative = (n: unknown): boolean => n === undefined || (finite(n) && n >= 0)\n\n/**\n * Static checks on a `DestructibleSpec` (no world needed), for items that give a `spec` instead of an `impl`: unique part ids, known materials\n * (when `options.materials` is given), joints that reference existing, different parts, finite positive sizes, non-negative mass / hp / capacity,\n * valid structure roles and `bears` directions. A structural part with no path of joints to an anchored part is a warning, not a problem: it\n * is allowed, it just falls.\n */\nexport const checkSpec = (spec: DestructibleSpec, options: CheckSpecOptions = {}): SpecReport => {\n const problems: string[] = []\n const warnings: string[] = []\n const materials = options.materials ? new Set(options.materials) : null\n const parts = Array.isArray(spec?.parts) ? spec.parts : []\n if (!Array.isArray(spec?.parts) || parts.length === 0) problems.push('the spec needs at least one part')\n const ids = new Set<string>()\n for (const p of parts) {\n const id = String(p?.id ?? '')\n const label = `part \"${id}\"`\n if (id === '') problems.push('a part has no id')\n else if (ids.has(id)) problems.push(`duplicate part id \"${id}\"`)\n ids.add(id)\n if (materials && !materials.has(p?.material)) problems.push(`${label} has unknown material \"${String(p?.material)}\"`)\n else if (typeof p?.material !== 'string' || p.material === '') problems.push(`${label} needs a material`)\n const s = p?.shape\n if (s?.kind === 'box') {\n if (!Array.isArray(s.size) || s.size.length !== 3 || !s.size.every(positive)) problems.push(`${label} box size must be three finite positive numbers`)\n } else if (s?.kind === 'cylinder') {\n if (!positive(s.radius) || !positive(s.height)) problems.push(`${label} cylinder radius and height must be finite and positive`)\n } else if (s?.kind === 'sphere') {\n if (!positive(s.radius)) problems.push(`${label} sphere radius must be finite and positive`)\n } else problems.push(`${label} has an unknown shape`)\n if (!vec3(p?.position)) problems.push(`${label} needs a finite position [x, y, z]`)\n if (p?.rotation !== undefined && !vec3(p.rotation)) problems.push(`${label} has an invalid rotation`)\n for (const f of ['mass', 'hp', 'thickness'] as const) if (!nonNegative(p?.[f])) problems.push(`${label} ${f} must be a finite number >= 0`)\n if (p?.fill !== undefined && !(finite(p.fill) && p.fill >= 0 && p.fill <= 1)) problems.push(`${label} fill must be between 0 and 1`)\n if (p?.structure) {\n if (!STRUCTURE_ROLES.includes(p.structure.role)) problems.push(`${label} has an invalid structure role \"${String(p.structure.role)}\"`)\n if (!nonNegative(p.structure.capacity)) problems.push(`${label} structure capacity must be a finite number >= 0`)\n }\n if (p?.contains && !nonNegative(p.contains.liters)) problems.push(`${label} contains.liters must be a finite number >= 0`)\n }\n\n const jointIds = new Set<string>()\n const edges: Array<[string, string]> = []\n for (const j of spec?.joints ?? []) {\n const id = j.id ?? `${j.a}~${j.b}`\n const label = `joint \"${id}\"`\n if (jointIds.has(id)) problems.push(`duplicate joint id \"${id}\"`)\n jointIds.add(id)\n if (!ids.has(j.a)) problems.push(`${label} references unknown part \"${String(j.a)}\"`)\n if (!ids.has(j.b)) problems.push(`${label} references unknown part \"${String(j.b)}\"`)\n if (j.a === j.b) problems.push(`${label} joins part \"${String(j.a)}\" to itself`)\n if (j.bears !== undefined && !BEARS.includes(j.bears)) problems.push(`${label} has an invalid bears \"${String(j.bears)}\"`)\n if (!nonNegative(j.strength)) problems.push(`${label} strength must be a finite number >= 0`)\n if (!nonNegative(j.seconds)) problems.push(`${label} seconds must be a finite number >= 0`)\n if (j.bears !== false && ids.has(j.a) && ids.has(j.b) && j.a !== j.b) edges.push([j.a, j.b])\n }\n\n // structural parts must reach an anchored part over the joints (only when the spec lists its joints: otherwise they are inferred later)\n const structural = parts.filter((p) => p?.structure && p.structure.role !== 'none')\n if (structural.length && spec.joints) {\n const anchored = parts.filter((p) => p.anchored || p.structure?.role === 'foundation').map((p) => p.id)\n const adj = new Map<string, string[]>()\n for (const [a, b] of edges) {\n adj.set(a, [...(adj.get(a) ?? []), b])\n adj.set(b, [...(adj.get(b) ?? []), a])\n }\n const seen = new Set(anchored)\n const queue = [...anchored]\n while (queue.length) {\n for (const n of adj.get(queue.pop()!) ?? []) {\n if (seen.has(n)) continue\n seen.add(n)\n queue.push(n)\n }\n }\n const lost = structural.filter((p) => !seen.has(p.id)).map((p) => p.id)\n if (lost.length) warnings.push(`structural part(s) ${lost.map((i) => `\"${i}\"`).join(', ')} cannot reach an anchored part, so they will fall`)\n }\n return { ok: problems.length === 0, problems, warnings }\n}\n","import type { Hit, Vec3 } from './destruction'\n\n/**\n * A ballistic shot (one per pellet) as a weapon module produces it. Plain data: any damage model can consume it (`shotToHit` makes the `Hit`).\n */\nexport interface Shot {\n origin: Vec3\n /** Unit vector. */\n direction: Vec3\n /** Muzzle energy in joules. */\n energy: number\n /** Bullet diameter in millimetres. */\n caliber: number\n /** snake_case calibre id, e.g. `9x19`. */\n caliberId: string\n /** Muzzle speed in m/s. */\n speed: number\n /** Energy at a distance in metres, with the calibre's drag. */\n energyAt(distance: number): number\n pellet: number\n /** snake_case weapon id. */\n weapon: string\n source?: string\n}\n\n/** One use of a non-firearm (melee swing, flame tick, heat tick, throw, tool tick, extinguisher tick). */\nexport type Use =\n | { kind: 'melee'; damage: 'blunt' | 'slash'; energy: number; radius: number; reach: number; origin: Vec3; direction: Vec3 }\n | { kind: 'flame'; temperature: number; radius: number; range: number; cone: boolean; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'heat'; temperature: number; radius: number; range: number; duration: number; origin: Vec3; direction: Vec3 }\n | {\n kind: 'throw'\n energy: number\n radius: number\n fuse: number\n velocity: Vec3\n origin: Vec3\n fire?: { temperature: number; radius: number; seconds: number }\n /** Explosive id (`m67`, `molotov`, `pg7v`...): the host looks the numbers up in the arsenal. Absent on a plain thrown object. */\n explosive?: string\n /** What sets it off: `timer` after `fuse` seconds, `impact` on the first hit once armed. */\n trigger?: 'timer' | 'impact'\n /** Metres the projectile must fly before an impact sets it off; closer, it hits without exploding (rocket launchers). */\n armDistance?: number\n /** Radius in metres of the wounding area (`radius` is the lethal one). */\n injuryRadius?: number\n /** Seconds the blast stuns whoever is inside the injury radius (flashbang). */\n stunSeconds?: number\n /** Seconds the thrower held it after pulling the pin: `fuse` is what was left of the full fuse when it left the hand. */\n cooked?: number\n /** Went off in the thrower's hand (held past the fuse): no velocity, `fuse` is 0 and the blast is at `origin`. */\n inHand?: boolean\n }\n /** An explosive set down where the trigger is pulled (mine, C4, charge): it waits for its trigger instead of flying. */\n | {\n kind: 'place'\n explosive: string\n /** `wire`: something trips it; `remote`: the player fires it; `timer`: after `fuse` seconds. */\n triggers: readonly ('timer' | 'wire' | 'remote')[]\n energy: number\n /** Lethal radius in metres. */\n radius: number\n injuryRadius: number\n /** Cone the blast goes through, in front of `direction` (mine); absent for a blast in every direction. */\n cone?: { halfAngleDeg: number; length: number }\n /** The wire a `wire` charge stretches from where it is set down: metres out, degrees from its facing (counter-clockwise from above) and metres above it. */\n tripwire?: { length: number; angleDeg: number; height: number }\n fuse?: number\n origin: Vec3\n direction: Vec3\n }\n /** The blast behind a rocket launcher: dangerous inside `radius` metres, in the cone around `direction` (pointing away from the target). */\n | { kind: 'backblast'; radius: number; halfAngleDeg: number; origin: Vec3; direction: Vec3 }\n | { kind: 'tool'; tool: string; reach: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'extinguish'; range: number; coolC: number; duration: number; origin: Vec3; direction: Vec3 }\n | { kind: 'hand'; reach: number; origin: Vec3; direction: Vec3 }\n\n/**\n * The `Hit` a ballistic shot makes at `point` (world space): the energy is what is left of the shot at that distance from its origin\n * (`shot.energyAt`), the direction and calibre come from the shot. `normal` (the surface normal at the point, when the caller knows it) does not\n * change the hit; it is accepted so that callers can pass what their raycast returned and so that a stricter implementation could use it.\n */\nexport const shotToHit = (shot: Shot, point: Vec3, normal?: Vec3): Hit => {\n void normal\n const dx = point[0] - shot.origin[0]\n const dy = point[1] - shot.origin[1]\n const dz = point[2] - shot.origin[2]\n const distance = Math.hypot(dx, dy, dz)\n return {\n type: 'ballistic',\n point: [point[0], point[1], point[2]],\n direction: [shot.direction[0], shot.direction[1], shot.direction[2]],\n energy: shot.energyAt(distance),\n caliber: shot.caliber,\n source: shot.source ?? shot.weapon,\n }\n}\n","import type { Vec3 } from './destruction'\n\n/** Pose of one part (or of the whole item) at a key: position offset in metres and Euler XYZ rotation in radians, both relative to the rest pose. */\nexport interface AnimationPose {\n position?: Vec3\n rotation?: Vec3\n}\n\nexport interface AnimationKey {\n /** Seconds from the start of the clip. */\n t: number\n /** Pose of the item's root. */\n position?: Vec3\n rotation?: Vec3\n /** Poses of named parts: the key is a destruction part id (a pistol `reload` moves `mag`; a car door `open` rotates `door_l`). */\n parts?: Record<string, AnimationPose>\n}\n\nexport interface AnimationEventSpec {\n /** Seconds from the start of the clip. */\n t: number\n /** snake_case type the host maps (`sound`, `eject_casing`, `door_latch`...). */\n type: string\n data?: Record<string, unknown>\n}\n\n/** A use animation a module brings with its item. Poses between keys are interpolated by the player (the test room does it linearly). */\nexport interface AnimationClipSpec {\n /** snake_case: `reload`, `open`, `drink`... Unique within the item. */\n id: string\n /** Seconds. */\n duration: number\n keys: AnimationKey[]\n events?: AnimationEventSpec[]\n}\n\n/** What an item exposes when it brings its own animations. */\nexport interface ItemAnimationContract {\n animations: AnimationClipSpec[]\n}\n\nconst finite3 = (v: unknown): boolean => Array.isArray(v) && v.length === 3 && v.every((n) => typeof n === 'number' && Number.isFinite(n))\n\n/**\n * Problems with a clip (empty when it is valid): a snake_case id, a positive finite duration, at least one key, key and event times inside\n * `[0, duration]` and not going backwards, finite vectors, every named part one of `partIds`, event types that are non-empty strings and\n * JSON-serializable event data.\n */\nexport const checkAnimation = (clip: AnimationClipSpec, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const problems: string[] = []\n const parts = new Set(partIds)\n const id = String(clip?.id ?? '')\n if (!/^[a-z][a-z0-9_]*$/.test(id)) problems.push(`clip id \"${id}\" must be snake_case`)\n const label = `clip \"${id}\"`\n if (!(typeof clip?.duration === 'number' && Number.isFinite(clip.duration) && clip.duration > 0)) problems.push(`${label} needs a positive finite duration`)\n const dur = typeof clip?.duration === 'number' && clip.duration > 0 ? clip.duration : Infinity\n if (!Array.isArray(clip?.keys) || clip.keys.length === 0) {\n problems.push(`${label} needs at least one key`)\n return { ok: false, problems }\n }\n let prev = -Infinity\n clip.keys.forEach((k, i) => {\n if (!(typeof k.t === 'number' && Number.isFinite(k.t)) || k.t < 0 || k.t > dur + 1e-9) problems.push(`${label} key ${i} has t=${String(k.t)} outside 0..${dur}`)\n else if (k.t < prev) problems.push(`${label} key ${i} goes back in time (${k.t} < ${prev})`)\n else prev = k.t\n for (const f of ['position', 'rotation'] as const) if (k[f] !== undefined && !finite3(k[f])) problems.push(`${label} key ${i} has an invalid ${f}`)\n for (const [pid, pose] of Object.entries(k.parts ?? {})) {\n if (!parts.has(pid)) problems.push(`${label} key ${i} moves unknown part \"${pid}\"`)\n for (const f of ['position', 'rotation'] as const) if (pose?.[f] !== undefined && !finite3(pose[f])) problems.push(`${label} key ${i} part \"${pid}\" has an invalid ${f}`)\n }\n })\n let prevEv = -Infinity\n ;(clip.events ?? []).forEach((e, i) => {\n if (!(typeof e.t === 'number' && Number.isFinite(e.t)) || e.t < 0 || e.t > dur + 1e-9) problems.push(`${label} event ${i} has t=${String(e.t)} outside 0..${dur}`)\n else if (e.t < prevEv) problems.push(`${label} event ${i} goes back in time`)\n else prevEv = e.t\n if (typeof e.type !== 'string' || e.type === '') problems.push(`${label} event ${i} needs a type`)\n try {\n JSON.stringify(e.data ?? {})\n } catch {\n problems.push(`${label} event ${i} data is not JSON`)\n }\n })\n return { ok: problems.length === 0, problems }\n}\n","import type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from './animation'\nimport { checkAnimation } from './animation'\nimport type { HostEvent } from './module'\n\n/** Clips a tool can bring, one per move of its cycle. A tool brings the ones it has; a missing clip is simply not played. */\nexport const TOOL_CLIP = {\n DRAW: 'draw',\n SHOT: 'shot',\n MISFIRE: 'misfire',\n EMPTY: 'empty',\n CYCLE: 'cycle',\n RELOAD: 'reload',\n FEED: 'feed',\n FAULT: 'fault',\n CLEAR: 'clear',\n SAFETY_ON: 'safety_on',\n SAFETY_OFF: 'safety_off',\n MODE: 'mode',\n /** A throwable with the pin out, held until it is thrown. */\n COOK: 'cook',\n} as const\nexport type ToolClipId = (typeof TOOL_CLIP)[keyof typeof TOOL_CLIP]\n\n/** What a renderer does when a rule event arrives. `variant` picks `<clip>_<variant>` when the tool has it, else `<clip>`. */\nexport type ToolAnimationStep =\n | { readonly type: 'play'; readonly clip: ToolClipId; readonly variant?: string; readonly duration?: number; readonly repeat?: number }\n /** Move the clip that is playing to the marker (a clip event `stage` with `data.stage`) the rule just reached. */\n | { readonly type: 'sync'; readonly stage: string }\n /** The rule says the phase is over: the clip jumps to its end if it is still running. */\n | { readonly type: 'finish'; readonly clip: ToolClipId }\n\n/** The move a host event asks of the tool in hand, or null when it has no motion. */\nexport const toolAnimationStep = (event: HostEvent): ToolAnimationStep | null => {\n switch (event.type) {\n case 'tool':\n return { type: 'play', clip: TOOL_CLIP.DRAW, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'shot':\n return { type: 'play', clip: TOOL_CLIP.SHOT, repeat: Math.max(1, event.rounds ?? 1) }\n case 'misfire':\n return { type: 'play', clip: TOOL_CLIP.MISFIRE }\n case 'empty':\n return { type: 'play', clip: TOOL_CLIP.EMPTY }\n case 'mode':\n return { type: 'play', clip: TOOL_CLIP.MODE, variant: event.mode }\n case 'fault':\n return { type: 'play', clip: TOOL_CLIP.FAULT, variant: event.fault }\n case 'clear':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CLEAR }\n return { type: 'play', clip: TOOL_CLIP.CLEAR, variant: event.fault, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'safety':\n return { type: 'play', clip: event.on ? TOOL_CLIP.SAFETY_ON : TOOL_CLIP.SAFETY_OFF }\n case 'cycle':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.CYCLE }\n return { type: 'play', clip: TOOL_CLIP.CYCLE, ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'reload':\n if (event.phase === 'end') return { type: 'finish', clip: TOOL_CLIP.RELOAD }\n return { type: 'play', clip: TOOL_CLIP.RELOAD, ...(event.kind === undefined ? {} : { variant: event.kind }), ...(event.duration === undefined ? {} : { duration: event.duration }) }\n case 'stage':\n return { type: 'sync', stage: event.stage }\n case 'feed':\n return { type: 'play', clip: TOOL_CLIP.FEED }\n case 'cook':\n if (event.phase === 'start') return { type: 'play', clip: TOOL_CLIP.COOK, duration: event.fuse }\n return { type: 'finish', clip: TOOL_CLIP.COOK }\n default:\n return null\n }\n}\n\n/** Where a renderer puts the poses: every part of the tool by id (the ids the clips move), and the whole tool. Poses are offsets from rest. */\nexport interface ToolRig {\n setPartPose(partId: string, pose: AnimationPose): void\n setRootPose?(pose: AnimationPose): void\n}\n\n/** Clips by id, with the variants as `<clip>_<variant>`. */\nexport type ToolClipSet = Readonly<Record<string, AnimationClipSpec>>\n\n/** A renderer's tool animator: feed it the host events and the frame time. */\nexport interface ToolAnimator {\n handle(event: HostEvent): void\n update(dt: number): void\n /** Ids of the clips playing now. */\n readonly playing: readonly string[]\n dispose(): void\n}\n\nexport const STAGE_EVENT = 'stage'\n\n/** The clip with its times (keys and events) scaled so that it lasts `duration` seconds. */\nexport const scaleClip = (clip: AnimationClipSpec, duration: number): AnimationClipSpec => {\n const factor = clip.duration > 0 ? duration / clip.duration : 1\n return {\n ...clip,\n duration,\n keys: clip.keys.map((key) => ({ ...key, t: key.t * factor })),\n ...(clip.events ? { events: clip.events.map((event) => ({ ...event, t: event.t * factor })) } : {}),\n }\n}\n\nconst ZERO: [number, number, number] = [0, 0, 0]\nconst mix = (from: readonly number[], to: readonly number[], fraction: number): [number, number, number] => [\n (from[0] ?? 0) + ((to[0] ?? 0) - (from[0] ?? 0)) * fraction,\n (from[1] ?? 0) + ((to[1] ?? 0) - (from[1] ?? 0)) * fraction,\n (from[2] ?? 0) + ((to[2] ?? 0) - (from[2] ?? 0)) * fraction,\n]\n\n/** Pose of the whole tool (`partId` undefined) or of one part at `time`, linear between keys; a key that does not name it means rest. */\nexport const sampleClip = (clip: AnimationClipSpec, partId: string | undefined, time: number): { position: [number, number, number]; rotation: [number, number, number] } => {\n const points = clip.keys.map((key) => {\n const pose = partId === undefined ? key : key.parts?.[partId]\n return { t: key.t, position: pose?.position ?? ZERO, rotation: pose?.rotation ?? ZERO }\n })\n const first = points[0]\n if (!first || first.t > 0) points.unshift({ t: 0, position: ZERO, rotation: ZERO })\n const last = points[points.length - 1]\n if (!last) return { position: ZERO, rotation: ZERO }\n if (time >= last.t) return { position: mix(last.position, last.position, 0), rotation: mix(last.rotation, last.rotation, 0) }\n const index = Math.max(0, points.findIndex((point, i) => time >= point.t && time < (points[i + 1]?.t ?? Infinity)))\n const from = points[index]\n const to = points[index + 1]\n if (!from || !to) return { position: ZERO, rotation: ZERO }\n const fraction = to.t > from.t ? (time - from.t) / (to.t - from.t) : 0\n return { position: mix(from.position, to.position, fraction), rotation: mix(from.rotation, to.rotation, fraction) }\n}\n\n/** Problems with a clip set (empty when valid): each key is the clip id (or `<clip>_<variant>`), every clip passes `checkAnimation`, and a `stage` event names its stage. */\nexport const checkToolClips = (clips: ToolClipSet, partIds: Iterable<string>): { ok: boolean; problems: string[] } => {\n const parts = [...partIds]\n const problems: string[] = []\n for (const [key, clip] of Object.entries(clips)) {\n if (clip.id !== key) problems.push(`clip \"${key}\" has the id \"${clip.id}\"`)\n if (!(clip.duration > 0)) problems.push(`clip \"${key}\" has no duration`)\n problems.push(...checkAnimation(clip, parts).problems)\n for (const event of clip.events ?? []) if (event.type === STAGE_EVENT && typeof event.data?.stage !== 'string') problems.push(`clip \"${key}\" has a stage event without data.stage`)\n }\n return { ok: problems.length === 0, problems }\n}\n\ninterface Instance {\n readonly name: string\n readonly clip: AnimationClipSpec\n time: number\n delay: number\n fired: number\n}\n\nexport interface ToolClipPlayerOptions {\n clips: ToolClipSet\n rig: ToolRig\n /** Called for each clip event as its time passes (`eject_casing`, `drop_magazine`, `stage`...). */\n onEvent?(event: AnimationEventSpec, clip: string): void\n /** Seconds between the rounds of a `repeat` (a burst): default 0.1. */\n repeatInterval?(): number\n}\n\n/** The default player of a tool's clips: runs the steps of `toolAnimationStep` against a rig, scaled to the duration the rule gives. */\nexport interface ToolClipPlayer {\n apply(step: ToolAnimationStep): void\n update(dt: number): void\n readonly playing: readonly string[]\n}\n\nexport const createToolClipPlayer = (options: ToolClipPlayerOptions): ToolClipPlayer => {\n const { clips, rig, onEvent } = options\n let instances: Instance[] = []\n\n const find = (clip: string, variant?: string): { name: string; clip: AnimationClipSpec } | undefined => {\n const name = variant !== undefined && clips[`${clip}_${variant}`] ? `${clip}_${variant}` : clip\n const found = clips[name]\n return found ? { name, clip: found } : undefined\n }\n\n const render = (instance: Instance): void => {\n const time = Math.min(instance.time, instance.clip.duration)\n const root = sampleClip(instance.clip, undefined, time)\n if (instance.clip.keys.some((key) => key.position || key.rotation)) rig.setRootPose?.(root)\n const touched = new Set(instance.clip.keys.flatMap((key) => Object.keys(key.parts ?? {})))\n for (const id of touched) rig.setPartPose(id, sampleClip(instance.clip, id, time))\n }\n\n const fireEvents = (instance: Instance, upTo: number): void => {\n const events = instance.clip.events ?? []\n while (instance.fired < events.length && (events[instance.fired]?.t ?? Infinity) <= upTo + 1e-9) {\n const event = events[instance.fired]\n instance.fired += 1\n if (event) onEvent?.(event, instance.name)\n }\n }\n\n return {\n apply(step) {\n if (step.type === 'sync') {\n for (const instance of instances) {\n const marker = (instance.clip.events ?? []).find((event) => event.type === STAGE_EVENT && event.data?.stage === step.stage)\n if (marker && instance.time < marker.t) instance.time = marker.t\n }\n return\n }\n if (step.type === 'finish') {\n for (const instance of instances) {\n if (instance.name !== step.clip && !instance.name.startsWith(`${step.clip}_`)) continue\n fireEvents(instance, instance.clip.duration)\n instance.time = instance.clip.duration\n }\n return\n }\n const found = find(step.clip, step.variant)\n if (!found) return\n const clip = step.duration && step.duration > 0 ? scaleClip(found.clip, step.duration) : found.clip\n const interval = options.repeatInterval?.() ?? 0.1\n instances = instances.filter((existing) => existing.name !== found.name || existing.delay > 0)\n for (let round = 0; round < (step.repeat ?? 1); round++) {\n instances.push({ name: found.name, clip, time: 0, delay: round * interval, fired: 0 })\n }\n },\n update(dt) {\n for (const instance of instances) {\n const carried = instance.delay > 0 ? dt - instance.delay : dt\n if (instance.delay > 0) {\n instance.delay = Math.max(0, instance.delay - dt)\n if (instance.delay > 0) continue\n }\n instance.time += carried\n fireEvents(instance, instance.time)\n render(instance)\n }\n instances = instances.filter((instance) => instance.delay > 0 || instance.time < instance.clip.duration)\n },\n get playing() {\n return instances.map((instance) => instance.name)\n },\n }\n}\n","import type { Vec3 } from './destruction'\n\n/**\n * The bench of a module: controls, layers and counters it declares as data. The host keeps the values, draws them in a generic way and hands\n * every change back through `ModuleHost.bench`. Nothing here is specific to a kind of module.\n */\nexport type ControlValue = number | boolean | string\n\nexport interface ChoiceOption {\n readonly id: string\n readonly name: string\n}\n\ninterface ControlBase {\n /** snake_case, unique across the module's controls, layers and metrics. */\n readonly id: string\n /** Display name, already translated for the locale the host asked for. */\n readonly name: string\n readonly hint?: string\n readonly hidden?: boolean\n}\n\nexport interface NumberControl extends ControlBase {\n readonly kind: 'number'\n readonly min: number\n readonly max: number\n readonly step?: number\n readonly unit?: string\n readonly default: number\n}\n\nexport interface BooleanControl extends ControlBase {\n readonly kind: 'boolean'\n readonly default: boolean\n}\n\nexport interface ChoiceControl extends ControlBase {\n readonly kind: 'choice'\n readonly options: readonly ChoiceOption[]\n readonly default: string\n}\n\n/** A button: no value, only the press. */\nexport interface ActionControl extends ControlBase {\n readonly kind: 'action'\n}\n\nexport type ModuleControl = NumberControl | BooleanControl | ChoiceControl | ActionControl\n\n/** Something of the module the viewer turns on or off (smoke, flash, casings). */\nexport interface ModuleLayer {\n readonly id: string\n readonly name: string\n /** On unless `false`. */\n readonly default?: boolean\n}\n\n/** Pulled: the room calls read only when it samples (~4 Hz, or on TestRoom.metrics()). */\nexport interface ModuleMetric {\n readonly id: string\n readonly name: string\n readonly unit?: string\n /** Budget: the host shows a bar and warns past it. */\n readonly max?: number\n readonly digits?: number\n read(): number | string\n}\n\nexport type BenchChange =\n | { readonly kind: 'control'; readonly id: string; readonly value: ControlValue }\n | { readonly kind: 'layer'; readonly id: string; readonly on: boolean }\n | { readonly kind: 'action'; readonly id: string }\n\nexport interface ControlPatch {\n readonly hidden?: boolean\n readonly disabled?: boolean\n readonly options?: readonly ChoiceOption[]\n readonly value?: ControlValue\n}\n\n/** What the host lends a module that declares a bench: the current values and the changes. */\nexport interface ModuleBench {\n value(id: string): ControlValue | undefined\n layer(id: string): boolean\n /** Right after attach returns, the host sends one change per control (not actions) and per layer, in declaration order. */\n onChange(listener: (change: BenchChange) => void): () => void\n /** `value` sets without emitting (no echo loops); `options` falls back to the first option if the value is no longer offered. */\n patch(id: string, patch: ControlPatch): void\n /** Move the host camera (a near / middle / far choice). */\n look(eye: Vec3, target: Vec3): void\n}\n\nexport interface BenchReport {\n readonly ok: boolean\n readonly problems: readonly string[]\n}\n\nexport interface BenchDeclaration {\n readonly controls?: readonly ModuleControl[]\n readonly layers?: readonly ModuleLayer[]\n readonly metrics?: readonly ModuleMetric[]\n}\n\nconst SNAKE_CASE = /^[a-z][a-z0-9_]*$/\nconst finite = (n: unknown): n is number => typeof n === 'number' && Number.isFinite(n)\n\nfunction checkControl(control: ModuleControl, problems: string[]): void {\n const label = `control \"${control.id}\"`\n if (control.kind === 'number') {\n if (!finite(control.min) || !finite(control.max) || control.min >= control.max) problems.push(`${label} needs min < max`)\n if (control.step !== undefined && !(finite(control.step) && control.step > 0)) problems.push(`${label} needs a step > 0`)\n if (!finite(control.default) || control.default < control.min || control.default > control.max) problems.push(`${label} default ${String(control.default)} is outside ${control.min}..${control.max}`)\n return\n }\n if (control.kind !== 'choice') return\n if (control.options.length === 0) {\n problems.push(`${label} needs at least one option`)\n return\n }\n const seen = new Set<string>()\n for (const option of control.options) {\n if (seen.has(option.id)) problems.push(`${label} repeats option \"${option.id}\"`)\n seen.add(option.id)\n }\n if (!seen.has(control.default)) problems.push(`${label} default \"${control.default}\" is not among its options`)\n}\n\n/** snake_case ids unique across controls, layers and metrics; min < max; step > 0; default in range; options non-empty, unique, default among them; metric max > 0. */\nexport function checkBench(declared: BenchDeclaration): BenchReport {\n const problems: string[] = []\n const ids = new Set<string>()\n const claim = (kind: string, id: string): void => {\n if (!SNAKE_CASE.test(id)) problems.push(`${kind} id \"${id}\" must be snake_case`)\n if (ids.has(id)) problems.push(`duplicate id \"${id}\" across controls, layers and metrics`)\n ids.add(id)\n }\n for (const control of declared.controls ?? []) {\n claim('control', control.id)\n checkControl(control, problems)\n }\n for (const layer of declared.layers ?? []) claim('layer', layer.id)\n for (const metric of declared.metrics ?? []) {\n claim('metric', metric.id)\n if (metric.max !== undefined && !(finite(metric.max) && metric.max > 0)) problems.push(`metric \"${metric.id}\" needs a max > 0`)\n }\n return { ok: problems.length === 0, problems }\n}\n","import { STAGE_EVENT } from '@adatechnology/game-contracts'\nimport type { AnimationClipSpec, AnimationEventSpec, AnimationPose } from '@adatechnology/game-contracts'\n\nexport type Axis = 'x' | 'y' | 'z'\ntype Channel = 'position' | 'rotation'\n\n/** The gallery's `tw(delay, duration, e => part.property = from + (to - from) * e)`: one axis of one part, eased, then held at `to`. */\nexport interface Tween {\n readonly part: string\n readonly channel: Channel\n readonly axis: Axis\n readonly start: number\n readonly duration: number\n readonly from: number\n readonly to: number\n}\n\n/** The part id of the whole weapon in a clip's tweens. */\nexport const ROOT = 'root'\n\nconst AXIS_INDEX: Record<Axis, number> = { x: 0, y: 1, z: 2 }\n// the gallery eases with this curve; keys are linear, so each tween is sampled at this many steps (largest error 0.4% of the move)\nconst EASE_STEPS = 10\n\nexport const ease = (progress: number): number => (progress < 0.5 ? 2 * progress * progress : 1 - (-2 * progress + 2) ** 2 / 2)\n\nexport const move = (part: string, axis: Axis, start: number, duration: number, from: number, to: number): Tween => ({ part, channel: 'position', axis, start, duration, from, to })\nexport const turn = (part: string, axis: Axis, start: number, duration: number, from: number, to: number): Tween => ({ part, channel: 'rotation', axis, start, duration, from, to })\n\n/** A step of the clip at `t` the host maps (`muzzle_flash`, `eject_casing`, `drop_magazine`...). */\nexport const cue = (t: number, type: string, data?: Record<string, unknown>): AnimationEventSpec => ({ t, type, ...(data ? { data } : {}) })\n\nexport const stage = (id: string, t: number): AnimationEventSpec => ({ t, type: STAGE_EVENT, data: { stage: id } })\n\nconst valueAt = (tweens: readonly Tween[], t: number, includeInstants: boolean): number => {\n let value = 0\n for (const tween of tweens) {\n if (tween.start > t || (tween.duration === 0 && (tween.start === t ? !includeInstants : false))) continue\n if (tween.duration === 0 || t >= tween.start + tween.duration) value = tween.to\n else value = tween.from + (tween.to - tween.from) * ease((t - tween.start) / tween.duration)\n }\n return value\n}\n\nconst round = (value: number): number => Math.round(value * 1e6) / 1e6\n\n/** Builds a clip from tweens and cue events: one key at every start, end and sample of a tween, and a step (two keys at one time) for an instant set. */\nexport function composeClip(id: string, tweens: readonly Tween[], events: readonly AnimationEventSpec[] = [], minDuration = 0): AnimationClipSpec {\n const ordered = [...tweens].sort((a, b) => a.start - b.start)\n const duration = Math.max(minDuration, 0.001, ...ordered.map((tween) => tween.start + tween.duration), ...events.map((event) => event.t))\n const times = new Set<number>([0, duration])\n for (const tween of ordered) {\n times.add(round(tween.start))\n if (tween.duration > 0) for (let step = 1; step <= EASE_STEPS; step++) times.add(round(tween.start + (tween.duration * step) / EASE_STEPS))\n }\n const instants = new Set(ordered.filter((tween) => tween.duration === 0).map((tween) => round(tween.start)))\n const channels = new Map<string, Tween[]>()\n for (const tween of ordered) {\n const key = `${tween.part}|${tween.channel}|${tween.axis}`\n channels.set(key, [...(channels.get(key) ?? []), tween])\n }\n const sampleKey = (t: number, includeInstants: boolean): AnimationClipSpec['keys'][number] => {\n const poses = new Map<string, { position: [number, number, number]; rotation: [number, number, number] }>()\n for (const [key, list] of channels) {\n const [part, channel, axis] = key.split('|') as [string, Channel, Axis]\n const pose = poses.get(part) ?? { position: [0, 0, 0], rotation: [0, 0, 0] }\n pose[channel][AXIS_INDEX[axis]] = round(valueAt(list, t, includeInstants))\n poses.set(part, pose)\n }\n const root = poses.get(ROOT)\n poses.delete(ROOT)\n const parts: Record<string, AnimationPose> = {}\n for (const [part, pose] of poses) parts[part] = pose\n return { t, ...(root ? { position: root.position, rotation: root.rotation } : {}), ...(poses.size ? { parts } : {}) }\n }\n const keys: AnimationClipSpec['keys'] = []\n for (const t of [...times].sort((a, b) => a - b)) {\n if (instants.has(t)) keys.push(sampleKey(t, false))\n keys.push(sampleKey(t, true))\n }\n const sorted = [...events].sort((a, b) => a.t - b.t)\n return { id, duration, keys, ...(sorted.length ? { events: sorted } : {}) }\n}\n\n/** The same clip under another id (the clip set keys are the ids). */\nexport const renamed = (clip: AnimationClipSpec, id: string): AnimationClipSpec => ({ ...clip, id })\n","import type { AnimationEventSpec } from '@adatechnology/game-contracts'\nimport type { ModelParts } from '../models/types'\nimport { cue, move } from './clip-builder'\nimport type { Tween } from './clip-builder'\n\n/** The magazine goes out, drops away, and a new one rises into the well: the page's `magSwap`, which takes 0.82 s. */\nexport const MAGAZINE_SWAP_SECONDS = 0.82\n/** The new magazine starts to rise here (the `magazine_in` stage). */\nexport const MAGAZINE_IN_AT = 0.45\n\nexport function magazineSwap(parts: ModelParts, start: number): { tweens: Tween[]; events: AnimationEventSpec[]; end: number } {\n const direction = parts.magDir || -1\n const drop = parts.magDrop || 0.15\n return {\n tweens: [\n move('mag', 'y', start, 0.16, 0, direction * drop * 0.6),\n move('mag', 'y', start + 0.16, 0, 0, direction * drop * 2.2),\n move('mag', 'y', start + MAGAZINE_IN_AT, 0.3, direction * drop * 2.2, 0),\n ],\n events: [cue(start + 0.16, 'drop_magazine', { up: direction > 0 })],\n end: start + MAGAZINE_SWAP_SECONDS,\n }\n}\n","import type { CaseType, ReloadFamily } from '@adatechnology/game-weapons'\nimport type { ModelFamily, ModelParts } from '../models/types'\n\n/** What the clips of a weapon are written from: its model (parts and mechanism), its calibre's case and how its rule reloads it. */\nexport interface ClipContext {\n readonly parts: ModelParts\n readonly family: ModelFamily\n readonly caseType: CaseType\n readonly reloadFamily: ReloadFamily | undefined\n}\n\n/** Recoil strength by case size, when the model has none of its own (the page's `kickOf`). */\nexport const KICK_BY_CASE: Record<CaseType, number> = { shell: 1.6, big: 2.4, tiny: 0.3, pistol: 0.7, rifle: 1.1 }\n\nexport const kickOf = (context: ClipContext): number => context.parts.kick ?? KICK_BY_CASE[context.caseType]\n\n/** Families whose slide or bolt blows back with each shot. */\nexport const BLOWBACK: ReadonlySet<ModelFamily> = new Set(['pistol', 'rifle', 'semiint', 'semi12', 'p90', 'belt'])\nexport const HAS_CYCLE: ReadonlySet<ModelFamily> = new Set(['pump', 'bolt', 'boltmag', 'lever'])\n// the gallery's travel of the pump, of the bolt and of the lever, and the bolt handle's turn (page values)\nexport const PUMP_TRAVEL = -0.075\nexport const BOLT_TRAVEL = -0.07\nexport const BOLT_TURN = -1.15\nexport const LEVER_TURN = -0.85\n\n/** How far the slide or bolt travels back (the page's `-(P.stroke || .06)`). */\nexport const strokeOf = (parts: ModelParts): number => -(parts.stroke || 0.06)\n\n/** The part that blows back: the slide of a pistol, the bolt of the rest. */\nexport const blowbackPart = (context: ClipContext): 'slide' | 'bolt' => (context.family === 'pistol' ? 'slide' : 'bolt')\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { composeClip, cue, move, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { magazineSwap } from './magazine-clips'\nimport { BOLT_TRAVEL, BOLT_TURN, LEVER_TURN, PUMP_TRAVEL, blowbackPart, strokeOf } from './context'\nimport type { ClipContext } from './context'\n\n/** The bolt handle turns up, the bolt runs back and forth with the handle, and the handle turns down: the page's `cycleBolt` from `start`. */\nexport function boltStroke(start: number, hold = 0): Tween[] {\n return [\n turn('boltHandle', 'x', start, 0.09, 0, BOLT_TURN),\n move('boltHandle', 'x', start + 0.1, 0.12, 0, BOLT_TRAVEL),\n move('bolt', 'x', start + 0.1, 0.12, 0, BOLT_TRAVEL),\n move('boltHandle', 'x', start + 0.26 + hold, 0.12, BOLT_TRAVEL, 0),\n move('bolt', 'x', start + 0.26 + hold, 0.12, BOLT_TRAVEL, 0),\n turn('boltHandle', 'x', start + 0.4 + hold, 0.09, BOLT_TURN, 0),\n ]\n}\n\n/** The manual action after each shot: the pump slides, the bolt cycles or the lever works. The gallery's times (0.5, 0.82 and 0.55 s) are the rule's `timings.cycle`. */\nexport function cycleClip(context: ClipContext): AnimationClipSpec | undefined {\n const { parts, family } = context\n if (family === 'pump' && parts.pump) return composeClip('cycle', [move('pump', 'x', 0.22, 0.11, 0, PUMP_TRAVEL), move('pump', 'x', 0.36, 0.11, PUMP_TRAVEL, 0)], [cue(0.3, 'eject_casing', { down: false })], 0.5)\n if ((family === 'bolt' || family === 'boltmag') && parts.bolt && parts.boltHandle) return composeClip('cycle', boltStroke(0.3), [cue(0.5, 'eject_casing', { down: false })], 0.82)\n if (family === 'lever' && parts.lever) return composeClip('cycle', [turn('lever', 'z', 0.22, 0.13, 0, LEVER_TURN), turn('lever', 'z', 0.38, 0.13, LEVER_TURN, 0)], [cue(0.3, 'eject_casing', { down: false })], 0.55)\n return undefined\n}\n\n// where the slide sits when a fault is cleared, as a fraction of its travel, and what is thrown out\nconst STUCK_AT: Record<string, number> = { stovepipe: 0.35, double_feed: 0.6, misfire: 0, failure_to_extract: 0 }\n// the page's clear of a bolt gun holds the bolt back 0.04 s longer than its cycle (eject at 0.22, handle down at 0.44)\nconst CLEAR_HOLD = 0.04\n\n/** Clearing a jam on a mechanism that blows back: the slide goes all the way back, throws out what was stuck and returns. */\nfunction clearBlowback(context: ClipContext, fault: string): AnimationClipSpec {\n const { parts, family } = context\n const part = blowbackPart(context)\n const travel = strokeOf(parts)\n const stuck = travel * (STUCK_AT[fault] ?? 0)\n const swap = fault === 'double_feed' && parts.mag ? magazineSwap(parts, 0) : undefined\n const start = swap?.end ?? 0\n const tweens: Tween[] = [...(swap?.tweens ?? [])]\n const events = [...(swap?.events ?? [])]\n if (family === 'belt' && parts.cover) {\n tweens.push(turn('cover', 'z', start, 0.18, 0, 0.9), turn('cover', 'z', start + 0.3, 0.15, 0.9, 0))\n return composeClip(`clear_${fault}`, [...tweens, ...slideOut(part, stuck, travel, start + 0.5)], [...events, cue(start + 0.5 + 0.1, 'fly_jam', { jam: fault })])\n }\n return composeClip(`clear_${fault}`, [...tweens, ...slideOut(part, stuck, travel, start)], [...events, cue(start + 0.1, 'fly_jam', { jam: fault })])\n}\n\nconst slideOut = (part: 'slide' | 'bolt', from: number, travel: number, start: number): Tween[] => [move(part, 'x', start, 0.12, from, travel), move(part, 'x', start + 0.2, 0.07, travel, 0)]\n\n/** Clearing on a manual action: the same stroke as a cycle, throwing out what was stuck halfway through. */\nfunction clearManual(context: ClipContext, fault: string): AnimationClipSpec | undefined {\n const { parts, family } = context\n const fly = (t: number) => [cue(t, 'fly_jam', { jam: fault })]\n if (family === 'pump' && parts.pump) return composeClip(`clear_${fault}`, [move('pump', 'x', 0, 0.12, 0, PUMP_TRAVEL), move('pump', 'x', 0.2, 0.12, PUMP_TRAVEL, 0)], fly(0.12), 0.4)\n if ((family === 'bolt' || family === 'boltmag') && parts.bolt && parts.boltHandle) return composeClip(`clear_${fault}`, boltStroke(0, CLEAR_HOLD), fly(0.22), 0.6)\n if (family === 'lever' && parts.lever) return composeClip(`clear_${fault}`, [turn('lever', 'z', 0, 0.13, 0, LEVER_TURN), turn('lever', 'z', 0.16, 0.13, LEVER_TURN, 0)], fly(0.1), 0.35)\n return undefined\n}\n\n/** One clear clip per fault the rule can raise. Mechanisms without a bolt or slide (revolver, break, launcher) only throw out what was stuck. */\nexport function clearClips(context: ClipContext): AnimationClipSpec[] {\n return ['misfire', 'stovepipe', 'double_feed', 'failure_to_extract'].map((fault) => {\n const manual = clearManual(context, fault)\n if (manual) return manual\n const part = blowbackPart(context)\n if (context.parts[part] && ['pistol', 'rifle', 'semiint', 'semi12', 'p90', 'belt'].includes(context.family)) return clearBlowback(context, fault)\n return composeClip(`clear_${fault}`, [], [cue(0, 'fly_jam', { jam: fault })], 0.1)\n })\n}\n","import type { AnimationClipSpec, AnimationEventSpec } from '@adatechnology/game-contracts'\nimport { RELOAD_STAGES } from '@adatechnology/game-weapons'\nimport type { ReloadKind } from '@adatechnology/game-weapons'\nimport { ROOT, composeClip, cue, move, renamed, stage, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { BOLT_TRAVEL, BOLT_TURN, LEVER_TURN, PUMP_TRAVEL, strokeOf } from './context'\nimport type { ClipContext } from './context'\nimport { boltStroke } from './cycle-clips'\nimport { magazineSwap } from './magazine-clips'\n\nconst KINDS: readonly ReloadKind[] = ['tactical', 'empty', 'one_by_one']\n\n/** Charging handle pulled and released (the page's `charge`): the bolt goes back 0.12 s, then forward 0.06 s, from `start`. */\nconst charge = (context: ClipContext, start: number): Tween[] => {\n const travel = strokeOf(context.parts)\n return [move('bolt', 'x', start, 0.12, 0, travel), move('bolt', 'x', start + 0.18, 0.06, travel, 0)]\n}\n\ninterface Draft {\n tweens: Tween[]\n events: AnimationEventSpec[]\n end: number\n}\n\nconst cycleWithoutEject = (start: number): Draft => ({ tweens: boltStroke(start), events: [], end: start + 0.55 })\n\n/** Reloads that take a magazine: swap it (0.82 s), then what the mechanism needs. `kind` `empty` also works the action. */\nfunction magazineReload(context: ClipContext, kind: ReloadKind): Draft {\n const { parts, family } = context\n const swap = magazineSwap(parts, 0)\n const draft: Draft = { tweens: [...swap.tweens], events: [...swap.events], end: swap.end }\n if (family === 'pistol') {\n if (kind === 'empty' && parts.slide) {\n draft.tweens.push(move('slide', 'x', 0, 0, 0, strokeOf(parts)), move('slide', 'x', swap.end, 0.05, strokeOf(parts), 0))\n draft.end += 0.12\n }\n } else if (family === 'boltmag') {\n const stroke = cycleWithoutEject(swap.end)\n draft.tweens.push(...stroke.tweens)\n draft.end = stroke.end\n } else if (kind === 'empty' && parts.bolt) {\n draft.tweens.push(...charge(context, swap.end))\n draft.end += 0.35\n }\n return draft\n}\n\n/** Revolver: crane opens, spent cases fall, rounds go in (all at once with a speed loader), crane closes: 1.3 s. */\nfunction revolverReload(kind: ReloadKind): Draft {\n const events = [cue(0.32, 'eject_casing', { from: 'chambers', down: false })]\n if (kind !== 'one_by_one') events.push(cue(0.7, 'move_in', { from: 'chambers' }))\n return { tweens: [turn('crane', 'x', 0, 0.22, 0, -1.25), turn('crane', 'x', 1.05, 0.2, -1.25, 0)], events, end: 1.3 }\n}\n\n/** Break action: the barrels fold down, both cases drop, two shells go in and the barrels close: 1.2 s. */\nconst breakReload = (): Draft => ({\n tweens: [turn('barrels', 'z', 0, 0.2, 0, -0.5), turn('barrels', 'z', 1.0, 0.15, -0.5, 0)],\n events: [cue(0.25, 'eject_casing', { from: 'breech', down: false }), cue(0.65, 'move_in', { from: 'breech' })],\n end: 1.2,\n})\n\n/** Belt: the cover lifts, the belt box swaps, the cover closes and the bolt is charged: 1.55 s. */\nconst beltReload = (context: ClipContext): Draft => ({\n tweens: [turn('cover', 'z', 0, 0.2, 0, 0.9), move('belt', 'z', 0.2, 0.25, 0, -0.3), move('belt', 'z', 0.55, 0.3, -0.3, 0), turn('cover', 'z', 0.9, 0.18, 0.9, 0), ...charge(context, 1.15)],\n events: [],\n end: 1.55,\n})\n\n// loading round by round has no fixed length (the rule sets it by the rounds), so these are written over one unit and stretched to the rule's duration\nconst UNIT = 1\n\nfunction tubeReload(context: ClipContext, kind: ReloadKind): Draft {\n const { parts, family } = context\n const draft: Draft = { tweens: [], events: [], end: UNIT }\n if (kind !== 'empty') return draft\n if (family === 'pump' && parts.pump) draft.tweens.push(move('pump', 'x', 0.88, 0.05, 0, PUMP_TRAVEL), move('pump', 'x', 0.94, 0.05, PUMP_TRAVEL, 0))\n else if (family === 'lever' && parts.lever) draft.tweens.push(turn('lever', 'z', 0.87, 0.06, 0, LEVER_TURN), turn('lever', 'z', 0.94, 0.06, LEVER_TURN, 0))\n else if (parts.bolt) draft.tweens.push(move('bolt', 'x', 0.88, 0.07, 0, strokeOf(parts)), move('bolt', 'x', 0.95, 0.04, strokeOf(parts), 0))\n return draft\n}\n\n/** Bolt action loaded from the top: the bolt opens, rounds go in one by one, the bolt closes. */\nfunction boltReload(context: ClipContext): Draft {\n if (!context.parts.boltHandle || !context.parts.bolt) return { tweens: [], events: [], end: UNIT }\n return {\n tweens: [\n turn('boltHandle', 'x', 0, 0.05, 0, BOLT_TURN),\n move('boltHandle', 'x', 0.05, 0.07, 0, BOLT_TRAVEL),\n move('bolt', 'x', 0.05, 0.07, 0, BOLT_TRAVEL),\n move('boltHandle', 'x', 0.86, 0.07, BOLT_TRAVEL, 0),\n move('bolt', 'x', 0.86, 0.07, BOLT_TRAVEL, 0),\n turn('boltHandle', 'x', 0.93, 0.05, BOLT_TURN, 0),\n ],\n events: [],\n end: UNIT,\n }\n}\n\n/** A semi-automatic with an internal magazine: the bolt back, rounds in from the top, the bolt forward. */\nfunction internalMagazineReload(context: ClipContext): Draft {\n const travel = strokeOf(context.parts)\n return { tweens: context.parts.bolt ? [move('bolt', 'x', 0, 0.04, 0, travel), move('bolt', 'x', 0.89, 0.04, travel, 0)] : [], events: [], end: UNIT }\n}\n\n/** The rocket launchers and flamethrowers: a round slid in, a disposable tube dropped and a new one seated, a hinged breech, or a tank swapped (needle sweeps). */\nfunction heavyReload(context: ClipContext): Draft {\n const { parts, family } = context\n if (family === 'flame') return { tweens: parts.gauge ? [turn('gauge', 'z', 0, 1, -2.4, 0)] : [], events: [], end: 1.1 }\n if (parts.disposable) {\n return {\n tweens: [move(ROOT, 'y', 0.6, 0, 0, -0.6), move(ROOT, 'y', 0.6, 0.5, -0.6, 0)],\n events: [cue(0, 'drop_tube'), cue(0.6, 'seat_tube')],\n end: 1.15,\n }\n }\n if (parts.round) {\n return {\n tweens: [move('round', 'x', 0, 0.55, 0.45, 0), move('round', 'y', 0, 0.55, 0.12, 0)],\n events: [cue(0, 'show_round')],\n end: 0.6,\n }\n }\n return {\n tweens: [turn('breech_0', 'y', 0, 0.25, 0, -1.6), turn('breech_0', 'y', 0.76, 0.22, -1.6, 0)],\n events: [cue(0.3, 'breech_round')],\n end: 1.05,\n }\n}\n\nconst isTube = (context: ClipContext): boolean => ['pump', 'semi12', 'lever'].includes(context.family)\n\nfunction draftFor(context: ClipContext, kind: ReloadKind): Draft | undefined {\n const { parts, family } = context\n if (family === 'rocket' || family === 'flame') return heavyReload(context)\n if (parts.mag) return magazineReload(context, kind)\n if (family === 'revolver' && parts.crane) return revolverReload(kind)\n if (family === 'break' && parts.barrels) return breakReload()\n if (family === 'belt' && parts.cover && parts.belt) return beltReload(context)\n if (isTube(context)) return tubeReload(context, kind)\n if (family === 'bolt') return boltReload(context)\n if (family === 'semiint') return internalMagazineReload(context)\n return undefined\n}\n\n/** The stages of the rule's reload as markers of the clip, at the fractions the rule puts them. */\nconst markers = (context: ClipContext, kind: ReloadKind, duration: number): AnimationEventSpec[] =>\n context.reloadFamily ? RELOAD_STAGES[context.reloadFamily][kind].map((entry) => stage(entry.stage, entry.at * duration)) : []\n\n/** `reload` (a magazine swap or the like), `reload_empty` and `reload_one_by_one`, each only when it differs from the first. */\nexport function reloadClips(context: ClipContext): AnimationClipSpec[] {\n const clips: AnimationClipSpec[] = []\n let first: AnimationClipSpec | undefined\n for (const kind of KINDS) {\n const draft = draftFor(context, kind)\n if (!draft) return []\n const clip = composeClip(kind === 'tactical' ? 'reload' : `reload_${kind}`, draft.tweens, [...draft.events, ...markers(context, kind, draft.end)], draft.end)\n if (!first) first = clip\n else if (JSON.stringify({ ...clip, id: first.id }) === JSON.stringify(first)) continue\n clips.push(clip)\n }\n return clips.length > 0 ? clips : first ? [renamed(first, 'reload')] : []\n}\n\n/** One more round goes in while a tube, a top-loaded or a revolver loads round by round. */\nexport function feedClip(context: ClipContext): AnimationClipSpec | undefined {\n const { family } = context\n if (family === 'revolver') return composeClip('feed', [], [cue(0, 'move_in', { from: 'chambers', next: true })], 0.24)\n if (family === 'bolt' || family === 'semiint') return composeClip('feed', [], [cue(0, 'move_in', { from: 'topLoad' })], 0.24)\n if (isTube(context)) return composeClip('feed', [], [cue(0, 'move_in', { from: 'loadPort' })], 0.24)\n return undefined\n}\n","import type { AnimationClipSpec } from '@adatechnology/game-contracts'\nimport { ROOT, composeClip, cue, move, turn } from './clip-builder'\nimport type { Tween } from './clip-builder'\nimport { BLOWBACK, blowbackPart, kickOf, strokeOf } from './context'\nimport type { ClipContext } from './context'\n\n// how far the slide stays back for each fault, as a fraction of its travel: the page's `k` (stovepipe .35, double feed .6)\nconst FAULT_SLIDE_BACK: Record<string, number> = { stovepipe: 0.35, double_feed: 0.6 }\n\n/** The trigger finger: the trigger turns back 0.35 rad and returns (the page's `pull`). */\nconst pullTrigger = (context: ClipContext): Tween[] => (context.parts.trigger ? [turn('trigger', 'z', 0, 0.04, 0, 0.35), turn('trigger', 'z', 0.06, 0.08, 0.35, 0)] : [])\n\n/** The whole weapon kicks back and tilts up, then settles (the page's `recoil`). */\nconst recoil = (context: ClipContext): Tween[] => {\n const kick = kickOf(context)\n return [\n move(ROOT, 'x', 0, 0.03, 0, -0.014 * kick),\n turn(ROOT, 'z', 0, 0.03, 0, 0.045 * kick),\n move(ROOT, 'x', 0.03, 0.18, -0.014 * kick, 0),\n turn(ROOT, 'z', 0.03, 0.18, 0.045 * kick, 0),\n ]\n}\n\nconst hammerFall = (context: ClipContext): Tween[] => (context.parts.hammer && context.family !== 'revolver' ? [turn('hammer', 'z', 0, 0.02, 0, -0.5), turn('hammer', 'z', 0.05, 0.06, -0.5, 0)] : [])\n\n/** What every shot does, then what the mechanism does by family. `locked` leaves the pistol slide back, as after the last round. */\nfunction shotClip(id: string, context: ClipContext, locked: boolean): AnimationClipSpec {\n const { parts, family } = context\n const tweens = [...pullTrigger(context), ...recoil(context), ...hammerFall(context)]\n const events = [cue(0, 'muzzle_flash')]\n if (BLOWBACK.has(family)) {\n const part = blowbackPart(context)\n const travel = strokeOf(parts)\n if (parts[part]) {\n tweens.push(move(part, 'x', 0, 0.025, 0, travel))\n if (!locked) tweens.push(move(part, 'x', 0.025, 0.045, travel, 0))\n }\n events.push(cue(0.012, 'eject_casing', { down: family === 'p90' || family === 'belt' }))\n } else if (family === 'revolver' && parts.cylinder && parts.hammer) {\n tweens.push(turn('cylinder', 'x', 0, 0.05, 0, Math.PI / 3), turn('hammer', 'z', 0, 0.05, 0, 0.5), turn('hammer', 'z', 0.05, 0.03, 0.5, -0.5), turn('hammer', 'z', 0.12, 0.08, -0.5, 0))\n }\n return composeClip(id, tweens, events)\n}\n\n/** A weapon with a mechanism that moves between shots (pump, bolt, lever) leaves that to the `cycle` clip, which the rule times. */\nexport function shotClips(context: ClipContext): AnimationClipSpec[] {\n const clips = [shotClip('shot', context, false)]\n if (context.family === 'pistol') clips.push(shotClip('shot_last', context, true))\n return clips\n}\n\n/** The trigger pulls and the hammer falls on a round that does not fire. */\nconst dudTweens = (context: ClipContext): Tween[] => [...pullTrigger(context), ...(context.parts.hammer ? [turn('hammer', 'z', 0, 0.03, 0, -0.5)] : [])]\n\n/** A dud that does not stop the weapon (revolver, break action): the cylinder of a revolver still turns. */\nexport function misfireClip(context: ClipContext): AnimationClipSpec {\n const tweens = dudTweens(context)\n if (context.family === 'revolver' && context.parts.cylinder) tweens.push(turn('cylinder', 'x', 0, 0.07, 0, Math.PI / 3))\n return composeClip('misfire', tweens)\n}\n\nexport const emptyClip = (context: ClipContext): AnimationClipSpec => composeClip('empty', pullTrigger(context))\n\n/**\n * A jam after the shot: the slide is stopped part of the way back (`FAULT_SLIDE_BACK`) and the case sticks in the port of a stovepipe. The clip lasts as long\n * as the shot's, so that it holds the slide where the shot would have returned it.\n */\nexport function faultClips(context: ClipContext): AnimationClipSpec[] {\n const { parts, family } = context\n const misfire = composeClip('fault_misfire', dudTweens(context))\n const part = blowbackPart(context)\n if (!BLOWBACK.has(family) || !parts[part]) return [misfire]\n const travel = strokeOf(parts)\n const stopped = Object.entries(FAULT_SLIDE_BACK).map(([fault, back]) =>\n composeClip(`fault_${fault}`, [move(part, 'x', 0, 0.025, 0, travel), move(part, 'x', 0.025, 0.04, travel, travel * back)], fault === 'stovepipe' ? [cue(0.03, 'stuck_case')] : [], 0.25),\n )\n return [misfire, ...stopped]\n}\n\n/** The selector or safety lever flicks over: on turns it down, off brings it back. The gallery draws the lever and does not move it. */\nexport function safetyClips(context: ClipContext): AnimationClipSpec[] {\n if (!context.parts.safety) return []\n return [composeClip('safety_on', [turn('safety', 'z', 0, 0.12, 0, -0.6)]), composeClip('safety_off', [turn('safety', 'z', 0, 0.12, -0.6, 0)]), composeClip('mode', [turn('safety', 'z', 0, 0.07, 0, 0.4), turn('safety', 'z', 0.07, 0.07, 0.4, 0)])]\n}\n\n/** Raising the weapon: it comes up from low with the muzzle down. The gallery shows no hands, so this is the SDK's own motion. */\nexport const drawClip = (): AnimationClipSpec => composeClip('draw', [move(ROOT, 'y', 0, 0.35, -0.1, 0), turn(ROOT, 'z', 0, 0.35, -0.6, 0)])\n","import type { AnimationClipSpec, ToolClipSet } from '@adatechnology/game-contracts'\nimport type { ClipContext } from './context'\nimport { clearClips, cycleClip } from './cycle-clips'\nimport { feedClip, reloadClips } from './reload-clips'\nimport { drawClip, emptyClip, faultClips, misfireClip, safetyClips, shotClips } from './shot-clips'\n\n/** Every clip a weapon model brings, by the ids `toolAnimationStep` asks for (`shot`, `cycle`, `reload`, `reload_empty`, `fault_<id>`, `clear_<id>`...). */\nexport function buildToolClips(context: ClipContext): ToolClipSet {\n const clips: Array<AnimationClipSpec | undefined> = [\n ...shotClips(context),\n misfireClip(context),\n emptyClip(context),\n cycleClip(context),\n ...reloadClips(context),\n feedClip(context),\n ...faultClips(context),\n ...clearClips(context),\n ...safetyClips(context),\n drawClip(),\n ]\n const set: Record<string, AnimationClipSpec> = {}\n for (const clip of clips) if (clip) set[clip.id] = clip\n return set\n}\n","import type { FaultId, FireMode, ReloadStageId, WeaponEvent } from '@adatechnology/game-weapons'\nimport type { HostEvent } from '@adatechnology/game-contracts'\n\n/**\n * The weapon event a host event stands for, so `mechanicalSoundOf` can pick its sound: reload stages, cycle, dry fire and misfire, jam, clear, safety, mode and feed.\n * Shots that fired a projectile have their own sound (`computeShotSound`), so they are not here.\n */\nexport const weaponEventOf = (event: HostEvent): WeaponEvent | undefined => {\n switch (event.type) {\n case 'misfire':\n return { type: 'misfire', at: 0 }\n case 'stage':\n return { type: 'reload_stage', stage: event.stage as ReloadStageId, at: 0 }\n case 'empty':\n case 'feed':\n return { type: event.type, at: 0 }\n case 'cycle':\n return { type: 'cycle', phase: event.phase, at: 0 }\n case 'mode':\n return { type: 'mode', mode: event.mode as FireMode, at: 0 }\n case 'fault':\n return { type: 'fault', fault: event.fault as FaultId, at: 0 }\n case 'clear':\n return { type: 'clear', fault: event.fault as FaultId, phase: event.phase, at: 0 }\n case 'safety':\n return { type: 'safety', on: event.on, at: 0 }\n default:\n return undefined\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from './kit'\nimport type { WeaponModel } from './index'\n\ntype Substitution = ReadonlyMap<THREE_NS.Material, THREE_NS.Material>\n\n/** The paint of worn metal by the rule's condition id (`new` and `used` keep the factory finish): the page's `applyQuality`, with its four steps named like the rule's. */\nconst substitutions = (kit: ModelKit, condition: string): Substitution | null => {\n const { M } = kit\n if (condition === 'rusty')\n return new Map<THREE_NS.Material, THREE_NS.Material>([\n [M.metal, M.rust],\n [M.dark, M.rustD],\n [M.steel, M.rust],\n [M.steelL, M.rust],\n ])\n if (condition === 'worn')\n return new Map<THREE_NS.Material, THREE_NS.Material>([\n [M.metal, M.worn],\n [M.dark, M.worn],\n ])\n return null\n}\n\n/** Dresses the model for how worn the weapon is. The first call keeps the finish each mesh came with, so any condition can be put back. */\nexport function applyCondition(kit: ModelKit, model: WeaponModel, condition: string): void {\n const replacement = substitutions(kit, condition)\n const glowing = new Set<THREE_NS.Object3D>(model.parts.glow)\n const paint = condition === 'rusty' ? kit.M.rust.color : condition === 'worn' ? kit.M.worn.color : undefined\n model.root.traverse((object) => {\n const mesh = object as THREE_NS.Mesh\n if (!mesh.isMesh) return\n mesh.userData.baseMaterial ??= mesh.material\n const base = mesh.userData.baseMaterial as THREE_NS.Material\n if (glowing.has(mesh)) {\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n mesh.userData.baseColor ??= material.color.clone()\n material.color.copy(paint ?? (mesh.userData.baseColor as THREE_NS.Color))\n return\n }\n mesh.material = replacement?.get(base) ?? base\n })\n}\n","import type * as THREE from 'three'\nimport type { CaliberDef, CartridgeDims } from '@adatechnology/game-weapons'\nimport type { ModelKit } from './kit'\n\n/** The shapes the gallery draws: rimfire, straight rimless (`p`), straight rimmed (`rimp`), bottleneck rimless (`r`), bottleneck rimmed (`rr`) and shotgun shell. */\nexport type CartridgeShape = 'shell' | 'rim' | 'p' | 'rimp' | 'r' | 'rr'\n\n// a bottleneck case narrows to less than this fraction of its diameter at the bullet\nconst BOTTLENECK_RATIO = 0.8\n\n/** The gallery's cartridge type of a calibre, from its case type, rim and dimensions. */\nexport function cartridgeShape(caliber: Pick<CaliberDef, 'caseType' | 'rim'>, dims: CartridgeDims): CartridgeShape {\n if (caliber.caseType === 'shell' || caliber.rim === 'shell') return 'shell'\n if (caliber.rim === 'rimfire') return 'rim'\n const isRimmed = caliber.rim === 'rimmed'\n const isBottleneck = dims.projectileDiameter / dims.caseDiameter < BOTTLENECK_RATIO\n if (isBottleneck) return isRimmed ? 'rr' : 'r'\n return isRimmed ? 'rimp' : 'p'\n}\n\n/** Port of the gallery's `cartridge`: the round standing on its base, in millimetres (the gallery shows it enlarged), brass case and copper or lead bullet. */\nexport function buildCartridge(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): THREE.Group {\n const { M, cylinderY } = kit\n const group = kit.group()\n const radius = dims.caseDiameter / 2\n const bulletRadius = dims.projectileDiameter / 2\n const caseLength = dims.caseLength\n if (shape === 'shell') {\n cylinderY(group, radius, caseLength * 0.8, M.shell, 0, caseLength * 0.6, 0, 14)\n cylinderY(group, radius * 1.03, caseLength * 0.22, M.brass, 0, caseLength * 0.11, 0, 14)\n cylinderY(group, radius * 1.08, 1.2, M.brass, 0, 0.6, 0, 14)\n return group\n }\n if (shape === 'rim' || shape === 'rimp' || shape === 'rr') cylinderY(group, radius * 1.15, 1.2, M.brass, 0, 0.6, 0, 14)\n const extra = dims.overallLength - caseLength\n if (shape === 'r' || shape === 'rr') {\n const bodyHeight = caseLength * 0.78\n const shoulder = caseLength * 0.08\n const neck = caseLength - bodyHeight - shoulder\n const neckRadius = bulletRadius + 0.35\n cylinderY(group, radius, bodyHeight, M.brass, 0, bodyHeight / 2, 0, 14)\n cylinderY(group, neckRadius, shoulder, M.brass, 0, bodyHeight + shoulder / 2, 0, 14, radius)\n cylinderY(group, neckRadius, neck, M.brass, 0, bodyHeight + shoulder + neck / 2, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.3, M.copper, 0, caseLength + extra * 0.15, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.7, M.copper, 0, caseLength + extra * 0.3 + extra * 0.35, 0, 14, bulletRadius * 0.12)\n return group\n }\n const bullet = shape === 'rim' || shape === 'rimp' ? M.lead : M.copper\n cylinderY(group, radius, caseLength, M.brass, 0, caseLength / 2, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.45, bullet, 0, caseLength + extra * 0.225, 0, 14)\n cylinderY(group, bulletRadius, extra * 0.55, bullet, 0, caseLength + extra * 0.45 + extra * 0.275, 0, 14, bulletRadius * 0.45)\n return group\n}\n\n/** An empty case in metres, lying along x with the base at the origin: the brass the weapon throws out. */\nexport function buildCasing(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): { group: THREE.Group; radius: number; length: number } {\n const { M, cylinderX } = kit\n const group = kit.group()\n const radius = dims.caseDiameter / 2000\n const length = dims.caseLength / 1000\n if (shape === 'shell') {\n const scale = length / 0.07\n cylinderX(group, 0.0105 * scale, 0.05 * scale, M.shell, 0.008 * scale, 0, 0, 14)\n cylinderX(group, 0.011 * scale, 0.016 * scale, M.brass, -0.025 * scale, 0, 0, 14)\n return { group, radius: 0.0105 * scale, length }\n }\n if (shape === 'r' || shape === 'rr') {\n cylinderX(group, radius, length * 0.75, M.brass, -length * 0.12, 0, 0, 12)\n cylinderX(group, radius * 0.62, length * 0.25, M.brass, length * 0.37, 0, 0, 12, radius * 0.55)\n } else cylinderX(group, radius, length, M.brass, 0, 0, 0, 12)\n return { group, radius, length }\n}\n\n/** A live round in metres, lying along x with the base at the origin: what is loaded into a weapon and what a clear throws out. */\nexport function buildRound(kit: ModelKit, dims: CartridgeDims, shape: CartridgeShape): { group: THREE.Group; radius: number } {\n const group = kit.group()\n const cartridge = buildCartridge(kit, dims, shape)\n cartridge.scale.setScalar(0.001)\n cartridge.rotation.z = -Math.PI / 2\n group.add(cartridge)\n return { group, radius: dims.caseDiameter / 2000 }\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from '../models/kit'\nimport type { Particles } from './particles'\n\nconst PI = Math.PI\n\n/** Flash size by case: shells flash biggest, rimfire smallest (the page's `flashK`). */\nexport const FLASH_BY_CASE = { shell: 1.6, big: 2.6, tiny: 0.5, pistol: 0.8, rifle: 1.2 } as const\n\nexport interface Effects {\n /** The muzzle flash at `position` pointing along `orientation`, with six puffs of smoke. */\n muzzleFlash(position: THREE_NS.Vector3, orientation: THREE_NS.Quaternion, size: number): void\n /** A puff that rises, grows and fades. */\n smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void\n update(dt: number): void\n dispose(): void\n}\n\nconst FLASH_SECONDS = 0.055\n\n/** The gallery's muzzle flash: a cone, four small cones and a core, additive, over 55 ms, with a short light. */\nexport function createEffects(kit: ModelKit, scene: THREE_NS.Object3D, particles: Particles, random: () => number): Effects {\n const { THREE, M } = kit\n const light = new THREE.PointLight(0xffb060, 0, 3, 2)\n scene.add(light)\n let flash: { group: THREE_NS.Group; age: number } | null = null\n\n const buildFlash = (size: number): THREE_NS.Group => {\n const group = new THREE.Group()\n const cone = new THREE.Mesh(new THREE.ConeGeometry(0.013 * size, 0.085 * size, 10, 1, true), M.flashA)\n cone.rotation.z = -PI / 2\n cone.position.x = 0.042 * size\n group.add(cone)\n for (let i = 0; i < 4; i++) {\n const angle = (i * PI) / 2 + random() * 0.6\n const spike = new THREE.Mesh(new THREE.ConeGeometry(0.005 * size, 0.04 * size, 6), M.flashA)\n spike.position.set(0.012 * size, Math.cos(angle) * 0.016 * size, Math.sin(angle) * 0.016 * size)\n spike.rotation.set(angle, 0, 0)\n spike.rotateZ(-PI / 2)\n group.add(spike)\n }\n const core = new THREE.Mesh(new THREE.SphereGeometry(0.016 * size, 12, 8), M.flashB)\n core.position.x = 0.008 * size\n group.add(core)\n return group\n }\n\n const endFlash = (): void => {\n if (!flash) return\n flash.group.removeFromParent()\n flash.group.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n flash = null\n light.intensity = 0\n }\n\n const effects: Effects = {\n muzzleFlash(position, orientation, size) {\n endFlash()\n const group = buildFlash(size)\n group.position.copy(position)\n group.quaternion.copy(orientation)\n group.rotateX(random() * PI)\n scene.add(group)\n flash = { group, age: 0 }\n light.position.copy(position)\n light.intensity = 4 * size\n light.distance = 2 * size\n for (let i = 0; i < 6; i++) {\n const velocity = new THREE.Vector3(0.15 + random() * 0.35, 0.03 + random() * 0.12, (random() - 0.5) * 0.14).applyQuaternion(orientation)\n effects.smoke(position, velocity, 0.013 * size, 1.3 + random() * 0.6, 0.45)\n }\n },\n smoke(position, velocity, size, life, opacity) {\n const puff = new THREE.Mesh(new THREE.SphereGeometry(size, 10, 8), M.smokeP.clone())\n puff.position.copy(position)\n particles.spawn(puff, velocity, { gravity: -0.08, life, fadeFrom: opacity, grow: 2.1, drag: 2.2, radius: -1, ownsGeometry: true })\n },\n update(dt) {\n if (!flash) return\n flash.age += dt\n flash.group.scale.setScalar(0.6 + Math.min(1, flash.age / FLASH_SECONDS) * 0.9)\n if (flash.age >= FLASH_SECONDS) endFlash()\n },\n dispose() {\n endFlash()\n light.removeFromParent()\n light.dispose()\n },\n }\n return effects\n}\n","import type * as THREE_NS from 'three'\nimport type { ModelKit } from '../models/kit'\nimport type { ModelParts } from '../models/types'\nimport { buildFlyingRocket } from '../models/launcher-rounds'\nimport type { Effects } from './effects'\nimport type { Particles } from './particles'\n\nconst PI = Math.PI\n\n/** What the launchers' and flamethrowers' effects need from the viewmodel. */\nexport interface HeavyContext {\n kit: ModelKit\n scene: THREE_NS.Object3D\n particles: Particles\n effects: Effects\n random: () => number\n parts: ModelParts\n /** Weapon forward in the world, and the world position of a part. */\n forward(): THREE_NS.Vector3\n positionOf(part: THREE_NS.Object3D): THREE_NS.Vector3\n orientation(): THREE_NS.Quaternion\n /** Runs `step(progress)` every frame for `seconds`, then `done`. */\n every(seconds: number, step: (progress: number, dt: number) => void, done?: () => void): void\n groundAt(x: number, z: number): number\n}\n\nconst flameMaterials = (kit: ModelKit): THREE_NS.MeshBasicMaterial[] => {\n const { THREE } = kit\n return [\n new THREE.MeshBasicMaterial({ color: 0xff7a22, transparent: true, opacity: 0.9, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xc8361a, transparent: true, opacity: 0.8, depthWrite: false }),\n new THREE.MeshBasicMaterial({ color: 0xfff0b0, transparent: true, opacity: 0.9, blending: THREE.AdditiveBlending, depthWrite: false }),\n ]\n}\n\nconst spread = (context: HeavyContext, x: number, y: number, z: number): THREE_NS.Vector3 =>\n new context.kit.THREE.Vector3((context.random() - 0.5) * x, (context.random() - 0.5) * y, (context.random() - 0.5) * z)\n\n/** The gallery's `flameBit` and `smokeBit`, which the rocket's backblast and the flame jet share. */\nfunction createBits(context: HeavyContext): { flame(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number): void; smoke(position: THREE_NS.Vector3, velocity: THREE_NS.Vector3, size: number, life: number, opacity: number): void; dispose(): void } {\n const { kit, particles, random } = context\n const { THREE } = kit\n const palette = flameMaterials(kit)\n return {\n flame(position, velocity, size, life) {\n const bit = new THREE.Mesh(new THREE.IcosahedronGeometry(size, 1), (palette[Math.floor(random() * 4)] as THREE_NS.Material).clone())\n bit.position.copy(position)\n bit.rotation.set(random() * 3, random() * 3, 0)\n particles.spawn(bit, velocity, { gravity: -1.4, life, fadeFrom: 0.9, grow: 2.2, drag: 1.4, radius: -1, spin: new THREE.Vector3(3, 4, 2), ownsGeometry: true })\n },\n smoke(position, velocity, size, life, opacity) {\n context.effects.smoke(position, velocity, size, life, opacity)\n },\n dispose: () => palette.forEach((material) => material.dispose()),\n }\n}\n\n/** A rocket leaving the tube: backblast smoke and fire at the rear, then the round flying out along the barrel, gaining speed, with a trail. */\nexport function launchRocket(context: HeavyContext): void {\n const { kit, scene, parts, random } = context\n const { THREE } = kit\n const bits = createBits(context)\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n const rear = context.positionOf(parts.rear as THREE_NS.Object3D)\n for (let i = 0; i < 26; i++) bits.smoke(rear.clone(), forward.clone().multiplyScalar(-(1.5 + random() * 3)).add(spread(context, 1.4, 0.8, 1.4)), 0.03 + random() * 0.03, 1.8 + random() * 1.4, 0.5)\n for (let i = 0; i < 14; i++) bits.flame(rear.clone(), forward.clone().multiplyScalar(-(2 + random() * 2)).add(spread(context, 1, 0.6, 1)), 0.02, 0.25)\n const rocket = parts.makeRound ? parts.makeRound() : buildFlyingRocket(kit, parts.launcherType)\n if (parts.round) parts.round.visible = false\n rocket.quaternion.copy(context.orientation())\n rocket.position.copy(muzzle)\n scene.add(rocket)\n const exhaust = new THREE.Mesh(new THREE.ConeGeometry(0.018, 0.12, 8, 1, true), new THREE.MeshBasicMaterial({ color: 0xffc040, transparent: true, opacity: 0.9, depthWrite: false }))\n exhaust.rotation.z = PI / 2\n exhaust.position.x = -0.08\n rocket.add(exhaust)\n const light = new THREE.PointLight(0xff9a40, 3, 2.5)\n rocket.add(light)\n context.every(\n 1.6,\n (progress, dt) => {\n const flight = progress * 1.6\n const distance = 1.2 * flight + (flight > 0.25 ? 9 * (flight - 0.25) ** 2 : 0)\n rocket.position.copy(muzzle).addScaledVector(forward, distance)\n rocket.rotation.x += 0.25 * dt * 60\n exhaust.scale.set(1, 0.6 + random() * 0.8, 1)\n if (random() < 0.9) bits.smoke(rocket.position.clone().addScaledVector(forward, -0.12), spread(context, 0.1, 0, 0.1).setY(0.05), 0.02 + random() * 0.015, 2.2, 0.5)\n },\n () => {\n rocket.removeFromParent()\n exhaust.geometry.dispose()\n ;(exhaust.material as THREE_NS.Material).dispose()\n light.dispose()\n bits.dispose()\n },\n )\n}\n\n/** A second of flame from the nozzle: bits of fire thrown forward and up, smoke downwind and burning droplets that light the ground where they land. */\nexport function flameJet(context: HeavyContext, dt: number, scale: number): void {\n const { kit, particles, random, parts } = context\n const { THREE } = kit\n const bits = createBits(context)\n const forward = context.forward()\n const muzzle = context.positionOf(parts.muzzle as THREE_NS.Object3D)\n const count = Math.floor(dt * 420 * scale)\n for (let i = 0; i < count; i++) {\n const speed = (2.2 + random() * 1.1) * scale\n bits.flame(muzzle.clone().addScaledVector(forward, random() * speed * Math.min(dt, 0.3)), forward.clone().multiplyScalar(speed).add(new THREE.Vector3((random() - 0.5) * 0.35, (random() - 0.3) * 0.3, (random() - 0.5) * 0.35)), 0.02 + random() * 0.022, 0.4 + random() * 0.35)\n }\n if (random() < 0.5) bits.smoke(muzzle.clone().addScaledVector(forward, 1.1 * scale + random() * 0.4), new THREE.Vector3(forward.x * 0.6, 0.35, forward.z * 0.6), 0.03, 1.6, 0.4)\n if (random() < 0.18) {\n const droplet = new THREE.Mesh(new THREE.SphereGeometry(0.006, 6, 4), new THREE.MeshBasicMaterial({ color: 0xff7a22 }))\n droplet.position.copy(muzzle).addScaledVector(forward, 0.3 + random() * 0.5)\n particles.spawn(droplet, forward.clone().multiplyScalar(1.2 * scale).add(new THREE.Vector3(0, 0.2, 0)), { life: 3, radius: 0.003, ownsGeometry: true, onGround: (position) => groundFire(context, bits, position) })\n }\n bits.dispose()\n}\n\n/** Three small flames where a burning droplet landed, flickering for four seconds and smoking. */\nfunction groundFire(context: HeavyContext, bits: ReturnType<typeof createBits>, position: THREE_NS.Vector3): void {\n const { kit, scene, random } = context\n const { THREE } = kit\n const fire = new THREE.Group()\n fire.position.set(position.x, context.groundAt(position.x, position.z) + 0.005, position.z)\n scene.add(fire)\n const materials = flameMaterials(kit)\n const flames = [0, 1, 2].map((index) => {\n const flame = new THREE.Mesh(new THREE.ConeGeometry(0.02, 0.07, 6), (materials[index % 2] as THREE_NS.Material).clone())\n flame.position.set((random() - 0.5) * 0.04, 0.035, (random() - 0.5) * 0.04)\n fire.add(flame)\n return flame\n })\n let clock = 0\n context.every(\n 4,\n (progress, dt) => {\n clock += dt\n flames.forEach((flame, index) => flame.scale.set(1 - progress * 0.7, (0.6 + Math.sin(clock * 20 + index * 2) * 0.35) * (1 - progress), 1 - progress * 0.7))\n if (random() < 0.08) bits.smoke(fire.position.clone().add(new THREE.Vector3(0, 0.08, 0)), new THREE.Vector3(0, 0.15, 0), 0.015, 1.2, 0.25)\n },\n () => {\n fire.removeFromParent()\n flames.forEach((flame) => {\n flame.geometry.dispose()\n ;(flame.material as THREE_NS.Material).dispose()\n })\n materials.forEach((material) => material.dispose())\n },\n )\n}\n","import type * as THREE_NS from 'three'\n\ntype Three = typeof THREE_NS\n\nexport type ParticleKind = 'casing' | 'magazine' | 'round' | 'other'\n\nexport interface ParticleOptions {\n kind?: ParticleKind\n /** Seconds before it is removed (default 2). */\n life?: number\n /** Gravity (default 9.8; negative lets smoke rise). */\n gravity?: number\n bounce?: number\n /** Fraction of the speed lost per second. */\n drag?: number\n /** Floor contact radius; negative: no contact (smoke, flames). */\n radius?: number\n spin?: THREE_NS.Vector3\n /** Opacity at birth: it fades to zero over its life. */\n fadeFrom?: number\n /** Growth per second as a fraction of the size. */\n grow?: number\n /** Called when it comes to rest on the floor. */\n onRest?: (object: THREE_NS.Object3D) => void\n /** Called instead of bouncing when it reaches the floor; the particle is removed. */\n onGround?: (position: THREE_NS.Vector3) => void\n /** The geometry of the object is its own (not shared with a model) and goes with it. */\n ownsGeometry?: boolean\n}\n\ninterface Particle extends Required<Pick<ParticleOptions, 'life' | 'gravity' | 'bounce' | 'drag' | 'radius' | 'grow' | 'kind'>> {\n object: THREE_NS.Object3D\n velocity: THREE_NS.Vector3\n spin: THREE_NS.Vector3\n age: number\n resting: boolean\n fadeFrom: number | undefined\n onRest: ParticleOptions['onRest']\n onGround: ParticleOptions['onGround']\n ownsGeometry: boolean\n bounces: number\n}\n\nconst MAX_PARTICLES = 900\nconst FLOOR_FRICTION = 0.45\n\n/** The gallery's particles (casings, magazines, smoke, flames): thrown with a velocity and a spin, bouncing on the floor under them until they rest or die. */\nexport interface Particles {\n spawn(object: THREE_NS.Object3D, velocity: THREE_NS.Vector3, options?: ParticleOptions): void\n update(dt: number): void\n count(kind: ParticleKind): number\n /** Called when something bounces: `casing` or `magazine` (for the sound). */\n onBounce?: (kind: ParticleKind) => void\n dispose(): void\n}\n\nconst disposeOwned = (object: THREE_NS.Object3D): void => {\n object.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n}\n\nexport function createParticles(THREE: Three, scene: THREE_NS.Object3D, groundAt: (x: number, z: number) => number): Particles {\n let list: Particle[] = []\n const remove = (particle: Particle): void => {\n particle.object.removeFromParent()\n if (particle.ownsGeometry) disposeOwned(particle.object)\n if (particle.fadeFrom !== undefined) ((particle.object as THREE_NS.Mesh).material as THREE_NS.Material).dispose()\n list = list.filter((other) => other !== particle)\n }\n const api: Particles = {\n spawn(object, velocity, options = {}) {\n scene.add(object)\n list.push({\n object,\n velocity,\n spin: options.spin ?? new THREE.Vector3(),\n age: 0,\n resting: false,\n life: options.life ?? 2,\n gravity: options.gravity ?? 9.8,\n bounce: options.bounce ?? 0.3,\n drag: options.drag ?? 0,\n radius: options.radius ?? 0.003,\n grow: options.grow ?? 0,\n kind: options.kind ?? 'other',\n fadeFrom: options.fadeFrom,\n onRest: options.onRest,\n onGround: options.onGround,\n ownsGeometry: options.ownsGeometry ?? false,\n bounces: 0,\n })\n const oldest = list[0]\n if (list.length > MAX_PARTICLES && oldest) remove(oldest)\n },\n update(dt) {\n for (const particle of [...list]) {\n particle.age += dt\n if (particle.age > particle.life) {\n remove(particle)\n continue\n }\n const { object } = particle\n if (particle.fadeFrom !== undefined) ((object as THREE_NS.Mesh).material as THREE_NS.Material).opacity = Math.max(0, particle.fadeFrom * (1 - particle.age / particle.life))\n if (particle.resting) continue\n particle.velocity.y -= particle.gravity * dt\n if (particle.drag) particle.velocity.multiplyScalar(Math.max(0, 1 - particle.drag * dt))\n object.position.addScaledVector(particle.velocity, dt)\n object.rotation.x += particle.spin.x * dt\n object.rotation.y += particle.spin.y * dt\n object.rotation.z += particle.spin.z * dt\n if (particle.grow) object.scale.multiplyScalar(1 + particle.grow * dt)\n if (particle.radius < 0) continue\n const floor = groundAt(object.position.x, object.position.z) + particle.radius\n if (object.position.y >= floor || particle.velocity.y >= 0) continue\n if (particle.onGround) {\n particle.onGround(object.position.clone())\n remove(particle)\n continue\n }\n object.position.y = floor\n particle.velocity.y *= -particle.bounce\n particle.velocity.x *= FLOOR_FRICTION\n particle.velocity.z *= FLOOR_FRICTION\n particle.spin.multiplyScalar(FLOOR_FRICTION)\n if (particle.bounces++ < 4 && Math.abs(particle.velocity.y) >= 0.18) api.onBounce?.(particle.kind)\n if (Math.abs(particle.velocity.y) < 0.18) {\n particle.resting = true\n particle.onRest?.(object)\n }\n }\n },\n count: (kind) => list.filter((particle) => particle.kind === kind).length,\n dispose() {\n for (const particle of [...list]) remove(particle)\n },\n }\n return api\n}\n","import type * as THREE_NS from 'three'\nimport type { AnimationPose, ToolRig } from '@adatechnology/game-contracts'\nimport { partRegistry } from '../models/part-registry'\nimport type { WeaponModel } from '../models'\n\n/** The rig of a model: clip poses are offsets from the rest the parts had when the rig was made, as the contract says. */\nexport function createModelRig(model: WeaponModel): ToolRig {\n const registry = partRegistry(model.parts)\n const rest = new Map<THREE_NS.Object3D, { position: THREE_NS.Vector3; rotation: THREE_NS.Euler }>()\n for (const part of [...registry.values(), model.root]) rest.set(part, { position: part.position.clone(), rotation: part.rotation.clone() })\n const apply = (object: THREE_NS.Object3D, pose: AnimationPose): void => {\n const base = rest.get(object)\n if (!base) return\n const [dx, dy, dz] = pose.position ?? [0, 0, 0]\n const [rx, ry, rz] = pose.rotation ?? [0, 0, 0]\n object.position.set(base.position.x + dx, base.position.y + dy, base.position.z + dz)\n object.rotation.set(base.rotation.x + rx, base.rotation.y + ry, base.rotation.z + rz)\n }\n return {\n setPartPose(partId, pose) {\n const part = registry.get(partId)\n if (part) apply(part, pose)\n },\n setRootPose: (pose) => apply(model.root, pose),\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { CartridgeDims, CaseType, WeaponDef } from '@adatechnology/game-weapons'\nimport type { WeaponModel } from '../models'\nimport type { CartridgeShape } from '../models/cartridge'\nimport type { ModelKit } from '../models/kit'\nimport type { Effects } from './effects'\nimport type { Particles } from './particles'\nimport type { WeaponAudio } from '../audio'\nimport type { FxLayers } from './layers'\n\n/** What the viewmodel shares with the handlers of the clip events. */\nexport interface FxWorld {\n readonly kit: ModelKit\n readonly scene: THREE_NS.Object3D\n readonly particles: Particles\n readonly effects: Effects\n readonly random: () => number\n readonly audio: WeaponAudio | null\n readonly layers: FxLayers\n groundAt(x: number, z: number): number\n /** Runs `step(e)` for `seconds` from `delay` seconds on, with `e` the eased progress, then `done`. */\n schedule(delay: number, seconds: number, step: (eased: number) => void, done?: () => void): void\n}\n\n/** The weapon in the hands: the model, how it is held and what its calibre makes (the case and the round, in metres). */\nexport interface Session {\n readonly id: string\n readonly def: WeaponDef\n readonly model: WeaponModel\n /** How much the model is scaled down to sit in the hands. */\n readonly holderScale: number\n readonly lengthMetres: number\n readonly caseType: CaseType\n readonly kit: ModelKit\n readonly cartridge: { dims: CartridgeDims; shape: CartridgeShape } | null\n stuckCase: THREE_NS.Object3D | null\n nextChamber: number\n}\n\n/** World position of a part of the model. */\nexport const worldPositionOf = (session: Session, part: THREE_NS.Object3D, out: THREE_NS.Vector3): THREE_NS.Vector3 => {\n session.model.root.updateWorldMatrix(true, true)\n return part.getWorldPosition(out)\n}\n\n/** A direction or offset written in the weapon's own axes (x along the barrel, y up, z to the right) in the world; `scaled` follows the model's size. */\nexport const toWorld = (session: Session, vector: THREE_NS.Vector3, scaled = false): THREE_NS.Vector3 => {\n const quaternion = session.model.root.getWorldQuaternion(new session.kit.THREE.Quaternion())\n const world = vector.clone().applyQuaternion(quaternion)\n return scaled ? world.multiplyScalar(session.holderScale) : world\n}\n","import type * as THREE_NS from 'three'\nimport type { AnimationEventSpec } from '@adatechnology/game-contracts'\nimport { buildCasing, buildRound } from '../models/cartridge'\nimport { FLASH_BY_CASE } from './effects'\nimport { toWorld, worldPositionOf } from './session'\nimport type { FxWorld, Session } from './session'\n\nconst PI = Math.PI\n\nconst restFlat = (object: THREE_NS.Object3D): void => {\n object.rotation.x = 0\n object.rotation.z = 0\n}\n\n/** The handlers of the events a clip carries (`muzzle_flash`, `eject_casing`, `drop_magazine`, `move_in`...): the effects the page spawns around the moving parts. */\nexport function createClipEventHandler(world: FxWorld, session: Session): (event: AnimationEventSpec) => void {\n const { kit, particles, effects, random } = world\n const { THREE } = kit\n const { parts, root } = session.model\n const vector = (x: number, y: number, z: number): THREE_NS.Vector3 => new THREE.Vector3(x, y, z)\n const positionOf = (part: THREE_NS.Object3D): THREE_NS.Vector3 => worldPositionOf(session, part, new THREE.Vector3())\n const reach = Math.max(0.55, Math.min(1.2, session.lengthMetres))\n\n const throwCase = (mark: THREE_NS.Object3D, velocity: THREE_NS.Vector3, spin: THREE_NS.Vector3, tilt = 0): void => {\n if (!session.cartridge || !world.layers.casings) return\n const casing = buildCasing(kit, session.cartridge.dims, session.cartridge.shape)\n casing.group.position.copy(positionOf(mark))\n casing.group.rotation.set(0, random() * 0.6 - 0.3, tilt)\n particles.spawn(casing.group, velocity, { kind: 'casing', life: 25, radius: casing.radius, bounce: 0.35, spin, onRest: restFlat, ownsGeometry: true })\n }\n\n const ejectFromPort = (down: boolean): void => {\n if (!parts.eject) return\n const local = down ? vector((random() - 0.5) * 0.3, -0.4, (random() - 0.5) * 0.3) : vector(-0.2 - random() * 0.4, (0.9 + random() * 0.5) * reach, (1 + random() * 0.6) * reach)\n throwCase(parts.eject, toWorld(session, local), vector(random() * 30, random() * 30, random() * 30))\n }\n\n const ejectAll = (marks: THREE_NS.Object3D[] | undefined, spent: (index: number) => { velocity: THREE_NS.Vector3; spin: THREE_NS.Vector3; tilt: number }): void => {\n marks?.forEach((mark, index) => {\n const { velocity, spin, tilt } = spent(index)\n throwCase(mark, toWorld(session, velocity), spin, tilt)\n })\n }\n\n /** A round slides from `from` to `to` (world points) in a quarter of a second, in the weapon's own space so that it follows the weapon. */\n const moveIn = (from: THREE_NS.Vector3, to: THREE_NS.Vector3, tilt: number): void => {\n if (!session.cartridge) return\n const { group } = buildRound(kit, session.cartridge.dims, session.cartridge.shape)\n const start = root.worldToLocal(from.clone())\n const end = root.worldToLocal(to.clone())\n group.rotation.z = tilt\n group.position.copy(start)\n root.add(group)\n world.schedule(0, 0.24, (eased) => group.position.lerpVectors(start, end, eased), () => {\n group.removeFromParent()\n group.traverse((child) => {\n const mesh = child as THREE_NS.Mesh\n if (mesh.isMesh) mesh.geometry.dispose()\n })\n })\n }\n\n const offsetFrom = (point: THREE_NS.Vector3, x: number, y: number, z: number): THREE_NS.Vector3 => point.clone().add(toWorld(session, vector(x, y, z), true))\n\n const feedRound = (from: string, next: boolean): void => {\n if (from === 'loadPort' && parts.loadPort) {\n const port = positionOf(parts.loadPort)\n moveIn(offsetFrom(port, -0.03, -0.08, 0.07), port, 0.25)\n } else if (from === 'topLoad' && parts.topLoad) {\n const point = positionOf(parts.topLoad)\n moveIn(offsetFrom(point, 0, 0.07, 0), point, 0)\n } else if (from === 'chambers' && parts.chambers) {\n const marks = next ? [parts.chambers[session.nextChamber++ % parts.chambers.length]] : parts.chambers\n for (const mark of marks) {\n if (!mark) continue\n const point = positionOf(mark)\n moveIn(offsetFrom(point, -0.07, 0, 0), offsetFrom(point, 0.006, 0, 0), 0)\n }\n } else if (from === 'breech' && parts.breech) {\n for (const mark of parts.breech) {\n const point = positionOf(mark)\n moveIn(offsetFrom(point, -0.09, 0.05, 0), offsetFrom(point, 0.02, -0.01, 0), -0.5)\n }\n }\n }\n\n const dropMagazine = (up: boolean): void => {\n if (!parts.mag || !world.layers.magazines) return\n root.updateWorldMatrix(true, true)\n const copy = parts.mag.clone(true)\n parts.mag.matrixWorld.decompose(copy.position, copy.quaternion, copy.scale)\n particles.spawn(copy, toWorld(session, vector(up ? -0.25 : 0.05, up ? 0.9 : -0.3, 0.18)), { kind: 'magazine', life: 25, radius: 0.014, bounce: 0.15, spin: vector(1.5, 0.5, 2.5), onRest: (object) => object.rotation.set(0, object.rotation.y, PI / 2) })\n }\n\n const stuckCase = (): void => {\n if (!session.cartridge || !parts.eject) return\n const casing = buildCasing(kit, session.cartridge.dims, session.cartridge.shape)\n const at = root.worldToLocal(offsetFrom(positionOf(parts.eject), 0, casing.length * 0.35, 0))\n casing.group.position.copy(at)\n casing.group.rotation.set(0, 0, PI / 2 - 0.25)\n root.add(casing.group)\n session.stuckCase = casing.group\n }\n\n const flyJam = (jam: string): void => {\n const stuck = session.stuckCase\n session.stuckCase = null\n if (stuck) {\n root.updateWorldMatrix(true, true)\n stuck.updateWorldMatrix(true, false)\n stuck.matrixWorld.decompose(stuck.position, stuck.quaternion, stuck.scale)\n particles.spawn(stuck, toWorld(session, vector(-0.2, 1.2, 1.3)), { kind: 'casing', life: 25, radius: 0.006, bounce: 0.3, spin: vector(9, 14, 7), onRest: restFlat, ownsGeometry: true })\n } else if (jam === 'misfire' && session.cartridge && parts.eject) {\n const round = buildRound(kit, session.cartridge.dims, session.cartridge.shape)\n round.group.position.copy(positionOf(parts.eject))\n particles.spawn(round.group, toWorld(session, vector(-0.2, 1.1, 1.2)), { kind: 'round', life: 25, radius: round.radius, bounce: 0.3, spin: vector(8, 12, 6), onRest: restFlat, ownsGeometry: true })\n } else ejectFromPort(false)\n }\n\n return (event) => {\n const data = event.data ?? {}\n switch (event.type) {\n case 'muzzle_flash':\n if (parts.muzzle && world.layers.muzzleFlash) effects.muzzleFlash(positionOf(parts.muzzle), root.getWorldQuaternion(new THREE.Quaternion()), session.def.action.kind === 'launcher' ? 2.2 : FLASH_BY_CASE[session.caseType])\n break\n case 'eject_casing':\n if (data.from === 'chambers') ejectAll(parts.chambers, () => ({ velocity: vector(-0.5 - random() * 0.3, -0.1 + random() * 0.3, (random() - 0.5) * 0.25), spin: vector(10, 20, 5), tilt: 0 }))\n else if (data.from === 'breech') ejectAll(parts.breech, () => ({ velocity: vector(-1, 0.9, (random() - 0.5) * 0.2), spin: vector(3, 8, 12), tilt: -0.5 }))\n else ejectFromPort(data.down === true)\n break\n case 'drop_magazine':\n dropMagazine(data.up === true)\n break\n case 'move_in':\n feedRound(String(data.from), data.next === true)\n break\n case 'stuck_case':\n stuckCase()\n break\n case 'fly_jam':\n flyJam(String(data.jam))\n break\n case 'show_round':\n if (parts.round) parts.round.visible = true\n break\n case 'drop_tube':\n dropTube()\n break\n case 'seat_tube':\n root.visible = true\n break\n case 'breech_round':\n breechRound()\n break\n default:\n break\n }\n }\n\n function dropTube(): void {\n root.updateWorldMatrix(true, true)\n const old = root.clone(true)\n root.matrixWorld.decompose(old.position, old.quaternion, old.scale)\n root.visible = false\n particles.spawn(old, toWorld(session, vector(0.2, 0.4, 0.6)), { life: 8, radius: 0.05, bounce: 0.2, spin: vector(0, 0.8, 2.5) })\n }\n\n function breechRound(): void {\n const make = parts.makeRound\n if (!make) return\n const shell = make()\n session.model.inner.add(shell)\n shell.position.set(-0.25, 0, 0)\n world.schedule(0.02, 0.4, (eased) => (shell.position.x = -0.25 + 0.6 * eased), () => {\n shell.removeFromParent()\n })\n }\n}\n","import type * as THREE_NS from 'three'\nimport { createToolClipPlayer, toolAnimationStep } from '@adatechnology/game-contracts'\nimport type { HostEvent, HostTool, ToolClipPlayer } from '@adatechnology/game-contracts'\nimport { createRng, muzzleEnergy } from '@adatechnology/game-weapons'\nimport type { Arsenal, CaliberDef, WeaponDef } from '@adatechnology/game-weapons'\nimport { ease } from '../animation/clip-builder'\nimport { buildToolClips } from '../animation/clip-set'\nimport type { WeaponAudio } from '../audio'\nimport { weaponEventOf } from '../audio/host-events'\nimport { buildWeaponModelById } from '../models'\nimport { applyCondition } from '../models/condition'\nimport { cartridgeShape } from '../models/cartridge'\nimport { modelKit } from '../models/kit'\nimport { createEffects } from './effects'\nimport { createLayers } from './layers'\nimport type { FxLayers } from './layers'\nimport { flameJet, launchRocket } from './heavy'\nimport type { HeavyContext } from './heavy'\nimport { createParticles } from './particles'\nimport { createModelRig } from './rig'\nimport type { FxWorld, Session } from './session'\nimport { toWorld, worldPositionOf } from './session'\nimport { createClipEventHandler } from './viewmodel-events'\n\nconst PI = Math.PI\n// where the weapon sits against the camera: right, down and ahead; long guns are drawn smaller so they do not fill the view\nconst HAND_OFFSET: [number, number, number] = [0.2, -0.2, -0.42]\nconst HEAT_DISPLAY_MAX_FALLBACK = 120\n// the launcher has no calibre: its shot is the game's `explosao` class, at the volume of a mid-sized blast\nconst LAUNCH_VOLUME = 0.6\n\nexport interface ViewmodelOptions {\n THREE: typeof THREE_NS\n scene: THREE_NS.Scene\n camera: THREE_NS.Camera\n arsenal: Arsenal\n groundAt: (x: number, z: number) => number\n audio: WeaponAudio | null\n /** Seed of the scatter of casings, smoke and sparks. */\n seed?: number\n /** The tool as it is now, for what no event announces: the barrel heat and the fuel burning. */\n tool?: () => HostTool\n /** Wear of the weapon (`new`, `used`, `worn`, `rusty`). */\n condition?: string\n /** What is drawn: read at the moment of each event, so the bench can change it live. */\n layers?: FxLayers\n /** Metres between the shooter and the listener, for the distance muffling of the shot sound (default 0). */\n soundDistance?: () => number\n}\n\n/** The weapon in the hands for the models the gallery drew: it follows the camera, plays the clips of the rule's events, and throws casings, magazines and smoke. */\nexport interface Viewmodel {\n /** Puts the weapon in the hands; false (and the hands stay as they were) when the gallery has no model for it. */\n equip(weapon: string): boolean\n /** Takes the weapon out of the hands. */\n unequip(): void\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n setCondition(condition: string): void\n readonly inHand: string | null\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\ninterface Task {\n delay: number\n seconds: number\n elapsed: number\n step: (progress: number, dt: number) => void\n done: (() => void) | undefined\n}\n\nconst caliberOf = (arsenal: Arsenal, def: WeaponDef): CaliberDef | undefined => (def.action.kind === 'firearm' ? arsenal.calibers.get(def.action.caliber) : undefined)\n\nexport function createViewmodel(options: ViewmodelOptions): Viewmodel {\n const { THREE, scene, camera, arsenal, groundAt, audio } = options\n const kit = modelKit(THREE)\n const random = createRng(options.seed ?? 1)\n const layers = options.layers ?? createLayers()\n const distance = (): number => options.soundDistance?.() ?? 0\n const particles = createParticles(THREE, scene, groundAt)\n particles.onBounce = (kind) => (kind === 'casing' ? audio?.clink() : kind === 'magazine' ? audio?.thud() : undefined)\n const effects = createEffects(kit, scene, particles, random)\n const hand = new THREE.Group()\n hand.name = 'weapon-viewmodel'\n scene.add(hand)\n const holder = new THREE.Group()\n holder.quaternion.setFromAxisAngle(new THREE.Vector3(0, 1, 0), PI / 2)\n hand.add(holder)\n let tasks: Task[] = []\n let session: Session | null = null\n let player: ToolClipPlayer | null = null\n let condition = options.condition ?? 'new'\n let lastAmmo = 0\n let smokeDebt = 0\n\n const world: FxWorld = {\n kit,\n scene,\n particles,\n effects,\n random,\n audio,\n layers,\n groundAt,\n schedule: (delay, seconds, step, done) => void tasks.push({ delay, seconds, elapsed: 0, step: (progress) => step(ease(progress)), done }),\n }\n\n const heatMax = arsenal.rules.heat.displayMax || HEAT_DISPLAY_MAX_FALLBACK\n\n const release = (): void => {\n if (!session) return\n session.model.root.removeFromParent()\n player = null\n session = null\n tasks = []\n }\n\n const heavy = (current: Session): HeavyContext => ({\n kit,\n scene,\n particles,\n effects,\n random,\n parts: current.model.parts,\n forward: () => toWorld(current, new THREE.Vector3(1, 0, 0)).normalize(),\n positionOf: (part) => worldPositionOf(current, part, new THREE.Vector3()),\n orientation: () => current.model.root.getWorldQuaternion(new THREE.Quaternion()),\n every: (seconds, step, done) => void tasks.push({ delay: 0, seconds, elapsed: 0, step, done }),\n groundAt,\n })\n\n const equip = (weapon: string): boolean => {\n const def = arsenal.weapons.get(weapon)\n const model = def ? buildWeaponModelById(THREE, weapon) : undefined\n if (!def || !model) return false\n release()\n const length = new THREE.Box3().setFromObject(model.root).getSize(new THREE.Vector3()).x\n const scale = length > 0.8 ? 0.55 : length > 0.4 ? 0.75 : 1\n holder.scale.setScalar(scale)\n holder.position.set(0, 0, Math.min(0.25, 0.25 * length * scale))\n holder.add(model.root)\n const caliber = caliberOf(arsenal, def)\n const dims = caliber?.cartridge\n session = {\n id: weapon,\n def,\n model,\n holderScale: scale,\n lengthMetres: length,\n caseType: caliber?.caseType ?? 'rifle',\n kit,\n cartridge: caliber && dims ? { dims, shape: cartridgeShape(caliber, dims) } : null,\n stuckCase: null,\n nextChamber: 0,\n }\n const action = def.action\n const reloadFamily = action.kind === 'firearm' || action.kind === 'flame' || action.kind === 'launcher' ? action.family : undefined\n const rpm = action.kind === 'firearm' ? action.rpm : 0\n player = createToolClipPlayer({\n clips: buildToolClips({ parts: model.parts, family: model.parts.family, caseType: session.caseType, reloadFamily }),\n rig: createModelRig(model),\n onEvent: createClipEventHandler(world, session),\n repeatInterval: () => (rpm > 0 ? 60 / rpm : 0.1),\n })\n applyCondition(kit, model, condition)\n lastAmmo = options.tool?.().ammo ?? 0\n return true\n }\n\n const place = (): void => {\n const [x, y, z] = HAND_OFFSET\n hand.position.set(x, y, z).applyQuaternion(camera.quaternion).add(camera.position)\n hand.quaternion.copy(camera.quaternion)\n hand.updateMatrixWorld(true)\n }\n\n const glow = (tool: HostTool | undefined): void => {\n if (!session) return\n const heat = (tool?.heat ?? 0) * heatMax\n const level = Math.max(0, Math.min(1, (heat - 50) / 50))\n for (const mesh of session.model.parts.glow) {\n const material = mesh.material as THREE_NS.MeshStandardMaterial\n material.emissive.setRGB(level, 0.2 * level * level, 0.02 * level * level)\n material.emissiveIntensity = 2.2 * level\n }\n }\n\n const handleShot = (current: Session): void => {\n const action = current.def.action\n if (action.kind === 'launcher') {\n launchRocket(heavy(current))\n audio?.play('explosion', LAUNCH_VOLUME, distance())\n }\n if (action.kind !== 'firearm') return\n const caliber = caliberOf(arsenal, current.def)\n if (!caliber) return\n audio?.shot(muzzleEnergy(caliber) * (caliber.pellets ?? 1), current.def.category, { caliber, distance: distance() })\n }\n\n return {\n equip,\n unequip: release,\n handle(event, tool) {\n if (event.type === 'explosion') return\n if (event.type === 'tool') equip(event.weapon)\n if (!session || !player || event.weapon !== session.id) return\n const current = session\n if (event.type === 'shot') handleShot(current)\n else if (event.type === 'reload' && event.phase === 'start') current.nextChamber = 0\n else if (event.type === 'clear' && event.phase === 'end') current.stuckCase = null\n const mechanical = weaponEventOf(event)\n if (mechanical) audio?.event(mechanical)\n const step = toolAnimationStep(event)\n if (!step) return\n const last = step.type === 'play' && step.clip === 'shot' && current.model.parts.family === 'pistol' && tool.ammo === 0\n player.apply(last ? { ...step, variant: 'last' } : step)\n },\n update(dt) {\n if (session) {\n place()\n player?.update(dt)\n const tool = options.tool?.()\n glow(tool)\n if (tool && session.def.action.kind === 'flame') {\n if (tool.ammo < lastAmmo) flameJet(heavy(session), dt, session.model.parts.launcherType === 'flame' ? 1 : 0.6)\n lastAmmo = tool.ammo\n }\n if (tool && tool.heat !== undefined && tool.heat * heatMax > 10 && session.model.parts.muzzle) {\n smokeDebt += dt * tool.heat * heatMax * 0.1\n while (smokeDebt > 1) {\n smokeDebt -= 1\n const k = 0.5 + (tool.heat * heatMax) / 60\n effects.smoke(worldPositionOf(session, session.model.parts.muzzle, new THREE.Vector3()), new THREE.Vector3((random() - 0.5) * 0.03, 0.07 + random() * 0.08, (random() - 0.5) * 0.03), 0.007 * k, 1.6 + random(), Math.min(0.42, 0.14 + k * 0.1))\n }\n }\n }\n for (const task of [...tasks]) {\n task.elapsed += dt\n if (task.elapsed < task.delay) continue\n const progress = task.seconds > 0 ? Math.min(1, (task.elapsed - task.delay) / task.seconds) : 1\n task.step(progress, dt)\n if (progress >= 1) {\n task.done?.()\n tasks = tasks.filter((other) => other !== task)\n }\n }\n effects.update(dt)\n particles.update(dt)\n },\n setCondition(next) {\n condition = next\n if (session) applyCondition(kit, session.model, condition)\n },\n get inHand() {\n return session?.id ?? null\n },\n get casings() {\n return particles.count('casing')\n },\n get magazines() {\n return particles.count('magazine')\n },\n dispose() {\n release()\n particles.dispose()\n effects.dispose()\n hand.removeFromParent()\n },\n }\n}\n","import type { HostEvent, HostTool } from '@adatechnology/game-contracts'\nimport { createBoxFx } from './box-fx'\nimport type { WeaponFxOptions } from './box-fx'\nimport { hasWeaponModel } from './models'\nimport { createLayers } from './fx/layers'\nimport type { FxLayers } from './fx/layers'\nimport { createViewmodel } from './fx/viewmodel'\n\nexport type { WeaponFxOptions } from './box-fx'\nexport type { FxLayers } from './fx/layers'\n\n/** The weapon in the hands, its fire and reload motion, ejected casings and dropped magazines, and their sounds. */\nexport interface WeaponFx {\n /** Feed every tool event of the host, with the tool as it is after the event. */\n handle(event: HostEvent, tool: HostTool): void\n update(dt: number): void\n /** Dresses the weapon for its wear (`new`, `used`, `worn`, `rusty`); the gallery models show it in their metal. */\n setCondition(condition: string): void\n /** What is drawn (casings, magazines, muzzle flash): change a field and the next event follows it. */\n readonly layers: FxLayers\n /** Weapon shown in the hands, or null. */\n readonly inHand: string | null\n /** Casings and magazines currently on the floor or in the air. */\n readonly casings: number\n readonly magazines: number\n dispose(): void\n}\n\n/**\n * The presentation of the tool in the hands. The weapons the gallery drew (`MODEL_ENTRIES`) get their model and the clips the rule's events call for\n * (fire, cycle, jam, clear, safety, the seven reloads); the generic archetypes keep their low-poly prop.\n */\nexport function createWeaponFx(options: WeaponFxOptions): WeaponFx {\n const layers = options.layers ?? createLayers()\n const box = createBoxFx({ ...options, layers })\n const model = createViewmodel({\n layers,\n ...(options.soundDistance ? { soundDistance: options.soundDistance } : {}),\n THREE: options.THREE,\n scene: options.scene,\n camera: options.camera,\n arsenal: options.arsenal,\n groundAt: options.groundAt,\n audio: options.audio ?? null,\n ...(options.seed === undefined ? {} : { seed: options.seed }),\n ...(options.tool ? { tool: options.tool } : {}),\n ...(options.condition ? { condition: options.condition } : {}),\n })\n return {\n handle(event, tool) {\n if (event.type === 'explosion') return\n if (event.type === 'tool') {\n if (hasWeaponModel(event.weapon)) box.unequip()\n else model.unequip()\n }\n if (model.inHand !== null || (event.type === 'tool' && hasWeaponModel(event.weapon))) model.handle(event, tool)\n else box.handle(event, tool)\n },\n update(dt) {\n box.update(dt)\n model.update(dt)\n },\n setCondition: (condition) => model.setCondition(condition),\n layers,\n get inHand() {\n return model.inHand ?? box.inHand\n },\n get casings() {\n return box.casings + model.casings\n },\n get magazines() {\n return box.magazines + model.magazines\n },\n dispose() {\n box.dispose()\n model.dispose()\n },\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { DestructibleSpec, PartShape, PartSpec, TestableItem, Vec3 } from '@adatechnology/game-contracts'\nimport type { ExplosiveDef } from '@adatechnology/game-weapons'\n\n/** Prefix of the item ids of the explosives that sit in the world (`world_fuel_barrel`). */\nexport const WORLD_EXPLOSIVE_PREFIX = 'world_'\n\ninterface WorldShape {\n readonly shape: PartShape\n readonly position: Vec3\n readonly color: number\n}\n\n// The game's drum (jogo.js addExplo 68141: radius 0.3, height 0.9); the P13 cylinder and the car tank are real measures.\nconst SHAPES: Readonly<Record<string, WorldShape>> = {\n fuel_barrel: { shape: { kind: 'cylinder', radius: 0.3, height: 0.9 }, position: [0, 0.45, 0], color: 0x2f5f9a },\n propane_p13: { shape: { kind: 'cylinder', radius: 0.15, height: 0.48 }, position: [0, 0.24, 0], color: 0xcfd3d8 },\n car_fuel_tank: { shape: { kind: 'box', size: [0.9, 0.25, 0.5] }, position: [0, 0.4, 0], color: 0x4b4f55 },\n}\n\n/** The ids of the explosives of the arsenal that the area puts in the world. */\nexport const WORLD_EXPLOSIVE_IDS: readonly string[] = Object.keys(SHAPES)\n\n// A hollow steel shell: thin and light, so a bullet or a blast breaks it (the weight of a solid steel part would hold it together).\nconst SHELL = { thickness: 0.001, fill: 0.03 }\n\n/** The part of a world explosive: the energy, the reach and the chain of the explosive def, which is what `explosivePart` of game-destruction builds. */\nconst explosivePart = (def: ExplosiveDef, shape: WorldShape): PartSpec => ({\n id: 'tank',\n material: 'steel',\n shape: shape.shape,\n position: shape.position,\n ...SHELL,\n explodes: { energy: def.energy, radius: def.injuryRadius, ...(def.chain ? { chain: { ...def.chain } } : {}) },\n})\n\nconst meshOf = (THREE: typeof THREE_NS, shape: WorldShape): THREE_NS.Mesh => {\n const geometry = shape.shape.kind === 'cylinder' ? new THREE.CylinderGeometry(shape.shape.radius, shape.shape.radius, shape.shape.height, 16) : shape.shape.kind === 'box' ? new THREE.BoxGeometry(...shape.shape.size) : new THREE.SphereGeometry(0.2)\n const mesh = new THREE.Mesh(geometry, new THREE.MeshStandardMaterial({ color: shape.color, roughness: 0.55, metalness: 0.5 }))\n mesh.name = 'tank'\n mesh.userData.destructionPart = 'tank'\n mesh.position.set(...shape.position)\n mesh.castShadow = true\n mesh.receiveShadow = true\n return mesh\n}\n\n/** An explosive of the arsenal standing in the world: it goes off by a bullet, fire or another blast, after the delay its `chain` gives. */\nexport const worldExplosiveItem = (def: ExplosiveDef, name: string): TestableItem | undefined => {\n const shape = SHAPES[def.id]\n if (!shape) return undefined\n const spec: DestructibleSpec = { name, parts: [explosivePart(def, shape)], joints: [], tags: ['explosive'] }\n return {\n id: `${WORLD_EXPLOSIVE_PREFIX}${def.id}`,\n name,\n build: (THREE: unknown) => {\n const group = new (THREE as typeof THREE_NS).Group()\n group.add(meshOf(THREE as typeof THREE_NS, shape))\n return group\n },\n spec,\n }\n}\n","import type * as THREE_NS from 'three'\nimport type { AreaPlacement, BenchChange, DestructibleSpec, ModuleArea, ModuleControl, ModuleHost, ModuleLayer, ModuleMetric, TestableItem, TestableModule, Vec3 } from '@adatechnology/game-contracts'\nimport { createArsenal } from '@adatechnology/game-weapons'\nimport type { Arsenal, WeaponDef } from '@adatechnology/game-weapons'\nimport { createWeaponAudio } from './audio'\nimport type { WeaponAudio } from './audio'\nimport { createWeaponFx } from './fx'\nimport type { WeaponFx } from './fx'\nimport { ARCHETYPE_MODELS, hasWeaponModel } from './models'\nimport { BODY_ACTIONS, buildModeledProp, buildProp, modeledPropSpec, weaponProp } from './props'\nimport type { WeaponProp } from './props'\nimport { WORLD_EXPLOSIVE_IDS, WORLD_EXPLOSIVE_PREFIX, worldExplosiveItem } from './world-explosives'\n\nexport interface WeaponsTestModuleOptions {\n /** `en` or `pt-BR` (default). */\n locale?: string\n /** The arsenal to lay out (default `createArsenal` with the locale). */\n arsenal?: Arsenal\n /** Play sounds (default true; silent anyway where there is no AudioContext). */\n sound?: boolean\n /** Wear of the weapon in the hands, which the gallery models show in their metal: `new` (default), `used`, `worn` or `rusty`. */\n condition?: string\n /** Seed of the scatter of casings and smoke (default 1). */\n seed?: number\n}\n\n/** Prefix of the item ids of the weapon props (`weapon_pistol_9mm`). */\nexport const WEAPON_ITEM_PREFIX = 'weapon_'\n// must not start with WEAPON_ITEM_PREFIX: hosts and tests tell the props apart by it\nexport const COUNTER_ITEM_ID = 'counter_weapons'\n\n// how loud an explosion is: a base plus what its reach adds (the game's `explosao` class is at full volume for a blast of 15 m or more)\nconst EXPLOSION_VOLUME_BASE = 0.4\nconst EXPLOSION_VOLUME_PER_METRE = 0.04\nconst SOUND_DISTANCE_MAX = 200\n/** Longest safety fuse the bench offers, metres: one metre burns 131 s, enough to see a delayed trap. */\nconst FUSE_LENGTH_MAX = 1\nconst DEFAULT_FUSE_LENGTH = 0.03\nconst COUNTER = { length: 4.8, depth: 1.6, height: 0.9 }\n// three columns on the free left side of the room, in two rows: counters fill in this order\nconst COUNTER_X = [-6.5, -9, -11.5]\nconst COUNTER_Z = [-1, 5.5]\n// props closer than this to a counter end have nothing next to them on one side\nconst END_MARGIN = 0.5\n// the strip of counter a weapon lying across it takes: most are slim, a few are wide (a tripod, two fuel tanks, a bow limb)\nconst DEFAULT_PITCH = 0.16\nconst PITCH_BY_ID: Readonly<Record<string, number>> = { browning_m2: 0.5, m2_flamethrower: 0.45, bow: 0.3, crossbow: 0.3 }\n// the explosives of the world stand together in the far corner (the player is at the other end, 17 m away): a bullet, fire or blast starts the chain reaction\nconst WORLD_EXPLOSIVES: Array<{ id: string; at: Vec3 }> = [\n { id: 'fuel_barrel', at: [10, 0, -8] },\n { id: 'fuel_barrel', at: [11.2, 0, -8] },\n { id: 'propane_p13', at: [10.6, 0, -9.3] },\n { id: 'car_fuel_tank', at: [8.6, 0, -9.3] },\n]\n// targets in front of the brick wall of the room, at shooting distances\nconst TARGETS: Array<{ id: string; at: Vec3 }> = [\n { id: 'target_steel_plate', at: [-1.5, 0, -7] },\n { id: 'target_plywood', at: [0, 0, -7] },\n { id: 'target_concrete', at: [1.5, 0, -7] },\n]\n\ninterface Text {\n group: string\n name: string\n counter: string\n targets: Record<string, string>\n reloadStart: string\n reloadEnd: string\n worldExplosives: Record<string, string>\n condition: string\n conditionHint: string\n conditions: Record<string, string>\n ammoQuality: string\n ammoQualityHint: string\n ammoQualities: Record<string, string>\n soundDistance: string\n soundDistanceHint: string\n fuseLength: string\n fuseLengthHint: string\n layers: Record<'muzzle_flash' | 'casings' | 'magazines', string>\n metrics: Record<'casings_live' | 'magazines_live' | 'heat', string>\n}\n\nconst TEXT: Record<string, Text> = {\n en: {\n group: 'Weapons',\n name: 'Weapons area',\n counter: 'Weapon counter',\n targets: { target_steel_plate: 'Steel plate target', target_plywood: 'Plywood target', target_concrete: 'Concrete block target' },\n reloadStart: 'Reload started: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Reload done: {weapon} ({ammo}/{capacity})',\n worldExplosives: { fuel_barrel: 'Fuel barrel', propane_p13: 'Propane cylinder (P13)', car_fuel_tank: 'Car fuel tank' },\n condition: 'Weapon condition',\n conditionHint: 'Wear of the weapon: it jams more and the metal shows it',\n conditions: { new: 'New', used: 'Used', worn: 'Worn', rusty: 'Rusty' },\n ammoQuality: 'Ammunition',\n ammoQualityHint: 'Reloaded rounds misfire more often',\n ammoQualities: { factory: 'Factory', reloaded: 'Reloaded' },\n soundDistance: 'Sound distance',\n soundDistanceHint: 'How far the listener is from the shot: farther is quieter and duller',\n fuseLength: 'Dynamite fuse length',\n fuseLengthHint: 'Metres of safety fuse (131 s per metre): a long one is set down lit, for a delayed trap',\n layers: { muzzle_flash: 'Muzzle flash', casings: 'Ejected casings', magazines: 'Dropped magazines' },\n metrics: { casings_live: 'Casings in the scene', magazines_live: 'Magazines in the scene', heat: 'Barrel heat' },\n },\n 'pt-BR': {\n group: 'Armas',\n name: 'Área de armas',\n counter: 'Balcão de armas',\n targets: { target_steel_plate: 'Alvo: chapa de aço', target_plywood: 'Alvo: compensado', target_concrete: 'Alvo: bloco de concreto' },\n reloadStart: 'Recarga iniciada: {weapon} ({ammo}/{capacity})',\n reloadEnd: 'Recarga completa: {weapon} ({ammo}/{capacity})',\n worldExplosives: { fuel_barrel: 'Barril de combustível', propane_p13: 'Botijão de gás (P13)', car_fuel_tank: 'Tanque de combustível do carro' },\n condition: 'Estado da arma',\n conditionHint: 'Desgaste da arma: trava mais e o metal mostra',\n conditions: { new: 'Nova', used: 'Usada', worn: 'Gasta', rusty: 'Enferrujada' },\n ammoQuality: 'Munição',\n ammoQualityHint: 'Munição recarregada falha mais',\n ammoQualities: { factory: 'De fábrica', reloaded: 'Recarregada' },\n soundDistance: 'Distância do som',\n soundDistanceHint: 'Quão longe o ouvinte está do tiro: mais longe soa mais baixo e abafado',\n fuseLength: 'Pavio da dinamite',\n fuseLengthHint: 'Metros de pavio de segurança (131 s por metro): um longo é posto no chão aceso, para armadilha com atraso',\n layers: { muzzle_flash: 'Clarão do cano', casings: 'Cápsulas ejetadas', magazines: 'Pentes que caem' },\n metrics: { casings_live: 'Cápsulas na cena', magazines_live: 'Pentes na cena', heat: 'Calor do cano' },\n },\n}\nconst textOf = (locale: string): Text => TEXT[locale] ?? (TEXT.en as Text)\nconst fill = (template: string, vars: Record<string, string | number>): string => template.replace(/\\{(\\w+)\\}/g, (_, key: string) => String(vars[key] ?? ''))\n\nconst counterProp = (name: string): WeaponProp => {\n const { length, depth, height } = COUNTER\n return {\n spec: {\n name,\n parts: [\n { id: 'top', material: 'wood_soft', shape: { kind: 'box', size: [depth, 0.05, length] }, position: [0, height - 0.025, 0] },\n { id: 'side_a', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, -length / 2 + 0.05], anchored: true },\n { id: 'side_b', material: 'plywood', shape: { kind: 'box', size: [depth - 0.1, height - 0.05, 0.05] }, position: [0, (height - 0.05) / 2, length / 2 - 0.05], anchored: true },\n ],\n joints: [\n { a: 'top', b: 'side_a', kind: 'screw' },\n { a: 'top', b: 'side_b', kind: 'screw' },\n ],\n tags: ['furniture'],\n },\n colors: { top: 0x8a5a30, side_a: 0x6b4426, side_b: 0x6b4426 },\n }\n}\n\nconst targetProp = (id: string, name: string): WeaponProp => {\n const face: Record<string, [string, Vec3, number]> = {\n target_steel_plate: ['steel', [0.5, 0.5, 0.01], 0xb5bcc4],\n target_plywood: ['plywood', [0.6, 0.8, 0.018], 0xc9a26b],\n target_concrete: ['concrete', [0.4, 0.2, 0.2], 0x9a9a94],\n }\n const [material, size, color] = face[id]\n const spec: DestructibleSpec = {\n name,\n parts: [\n { id: 'post', material: 'steel', shape: { kind: 'box', size: [0.05, 1.1, 0.05] }, position: [0, 0.55, -0.05], anchored: true },\n { id: 'face', material, shape: { kind: 'box', size }, position: [0, 1.1 + size[1] / 2, 0] },\n ],\n joints: [{ a: 'post', b: 'face', kind: 'bolt' }],\n tags: ['target'],\n }\n return { spec, colors: { post: 0x3a3d42, face: color } }\n}\n\n/** A weapon on the counters: the gallery model when it drew one (one rigid body of its measures), the low-poly prop of its category when it did not. */\nconst weaponItem = (def: WeaponDef, name: string): TestableItem => {\n const id = `${WEAPON_ITEM_PREFIX}${def.id}`\n if (!hasWeaponModel(def.id)) return asItem(id, name, weaponProp(def, name), { weapon: def.id, movable: true })\n return {\n id,\n name,\n build: (THREE: unknown) => buildModeledProp(THREE as typeof THREE_NS, def, name) as THREE_NS.Group,\n spec: (root: unknown) => modeledPropSpec(root, def, name),\n weapon: def.id,\n movable: true,\n }\n}\n\nconst asItem = (id: string, name: string, prop: WeaponProp, extra: Partial<TestableItem> = {}): TestableItem => ({\n id,\n name,\n build: (THREE: unknown) => buildProp(THREE as typeof THREE_NS, prop),\n spec: prop.spec,\n ...extra,\n})\n\n/** Where the counters go and where each weapon lies on them: weapons side by side across the counters in order, each taking its strip, until the counter is full. */\nexport function weaponsLayout(weaponItemIds: string[], pitchOf: (itemId: string) => number = () => DEFAULT_PITCH): AreaPlacement[] {\n const usable = COUNTER.length - 2 * END_MARGIN\n const slots = COUNTER_Z.flatMap((z) => COUNTER_X.map((x) => ({ x, z })))\n const counterOf: Array<{ x: number; z: number; used: number }> = []\n const placements: AreaPlacement[] = []\n for (const item of weaponItemIds) {\n const pitch = pitchOf(item)\n let counter = counterOf[counterOf.length - 1]\n if (!counter || counter.used + pitch > usable + 1e-9) {\n const slot = slots[counterOf.length]\n if (!slot) throw new Error(`weapons area: ${weaponItemIds.length} weapons do not fit on ${slots.length} counters of ${usable.toFixed(2)} m`)\n if (pitch > usable + 1e-9) throw new Error(`weapons area: \"${item}\" takes ${pitch} m and a counter holds ${usable.toFixed(2)} m`)\n counter = { ...slot, used: 0 }\n counterOf.push(counter)\n }\n placements.push({ item, position: [counter.x, COUNTER.height + 0.01, counter.z - COUNTER.length / 2 + END_MARGIN + counter.used + pitch / 2], asleep: true })\n counter.used += pitch\n }\n const counters: AreaPlacement[] = counterOf.map(({ x, z }) => ({ item: COUNTER_ITEM_ID, position: [x, 0, z], surface: { halfSize: [COUNTER.depth / 2, COUNTER.length / 2], height: COUNTER.height } }))\n const targets: AreaPlacement[] = TARGETS.map((target) => ({ item: target.id, position: target.at }))\n const explosives: AreaPlacement[] = WORLD_EXPLOSIVES.map((explosive) => ({ item: `${WORLD_EXPLOSIVE_PREFIX}${explosive.id}`, position: explosive.at }))\n return [...counters, ...placements, ...targets, ...explosives]\n}\n\n/**\n * The weapons test area as a `TestableModule` of @adatechnology/game-contracts: every weapon of the arsenal on counters, the real model of each one the gallery drew (aim at one and\n * press H to equip it), targets at shooting distance, and, through `attach`, the weapon in the hands with its fire and reload motion,\n * ejected casings, dropped magazines and sounds, driven by the host's tool events.\n */\nexport function createWeaponsTestModule(options: WeaponsTestModuleOptions = {}): TestableModule & { readonly audio: WeaponAudio | null; readonly fx: WeaponFx | null } {\n const locale = options.locale ?? 'pt-BR'\n const arsenal = options.arsenal ?? createArsenal({ locale })\n const text = textOf(locale)\n const audio = options.sound === false ? null : createWeaponAudio(undefined, options.seed === undefined ? {} : { seed: options.seed })\n const weaponDefs = [...arsenal.weapons.values()].filter((def) => !BODY_ACTIONS.has(def.id))\n // An archetype wearing the model of a brand weapon is the same thing twice on the counters: it stays in the catalogue (the hands still take it) but is not laid out.\n const weaponIds = weaponDefs.filter((def) => !(def.id in ARCHETYPE_MODELS)).map((def) => `${WEAPON_ITEM_PREFIX}${def.id}`)\n const pitchOf = (itemId: string): number => PITCH_BY_ID[itemId.slice(WEAPON_ITEM_PREFIX.length)] ?? DEFAULT_PITCH\n const worldExplosives = WORLD_EXPLOSIVE_IDS.flatMap((id) => {\n const def = arsenal.explosives.get(id)\n const item = def ? worldExplosiveItem(def, text.worldExplosives[id] ?? id) : undefined\n return item ? [item] : []\n })\n const worldExplosiveIds = new Set(worldExplosives.map((item) => item.id))\n let fx: WeaponFx | null = null\n let host: ModuleHost | null = null\n let soundDistance = 0\n const heatPercent = (): number => Math.min(100, (host?.tool().heat ?? 0) * 100)\n return {\n id: 'weapons_area',\n name: text.name,\n group: text.group,\n audio,\n get fx() {\n return fx\n },\n items: () => [\n ...weaponDefs.map((def) => weaponItem(def, arsenal.name(def.id))),\n asItem(COUNTER_ITEM_ID, text.counter, counterProp(text.counter), { movable: false }),\n ...TARGETS.map((target) => asItem(target.id, text.targets[target.id] ?? target.id, targetProp(target.id, text.targets[target.id] ?? target.id), { movable: false })),\n ...worldExplosives,\n ],\n area: (): ModuleArea => ({\n placements: weaponsLayout(weaponIds, pitchOf).filter((placement) => !placement.item.startsWith(WORLD_EXPLOSIVE_PREFIX) || worldExplosiveIds.has(placement.item)),\n view: { eye: [-3.4, 1.9, 9.2], target: [-9, 0.9, 1.6] },\n }),\n controls: (): ModuleControl[] => [\n {\n kind: 'choice',\n id: 'condition',\n name: text.condition,\n hint: text.conditionHint,\n options: arsenal.rules.conditions.map((entry) => ({ id: entry.id, name: text.conditions[entry.id] ?? entry.id })),\n default: options.condition ?? arsenal.rules.defaultCondition,\n },\n {\n kind: 'choice',\n id: 'ammo_quality',\n name: text.ammoQuality,\n hint: text.ammoQualityHint,\n options: arsenal.rules.ammoQualities.map((entry) => ({ id: entry.id, name: text.ammoQualities[entry.id] ?? entry.id })),\n default: arsenal.rules.defaultAmmoQuality,\n },\n { kind: 'number', id: 'sound_distance', name: text.soundDistance, hint: text.soundDistanceHint, unit: 'm', min: 0, max: SOUND_DISTANCE_MAX, step: 5, default: 0 },\n { kind: 'number', id: 'fuse_length', name: text.fuseLength, hint: text.fuseLengthHint, unit: 'm', min: 0.01, max: FUSE_LENGTH_MAX, step: 0.01, default: arsenal.explosives.get('dynamite')?.fuseLength ?? DEFAULT_FUSE_LENGTH },\n ],\n layers: (): ModuleLayer[] => (['muzzle_flash', 'casings', 'magazines'] as const).map((id) => ({ id, name: text.layers[id] })),\n metrics: (): ModuleMetric[] => [\n { id: 'casings_live', name: text.metrics.casings_live, read: () => fx?.casings ?? 0 },\n { id: 'magazines_live', name: text.metrics.magazines_live, read: () => fx?.magazines ?? 0 },\n { id: 'heat', name: text.metrics.heat, unit: '%', max: 100, digits: 0, read: heatPercent },\n ],\n attach(lent) {\n host = lent\n const created = createWeaponFx({\n THREE: lent.THREE as typeof THREE_NS,\n scene: lent.scene as THREE_NS.Scene,\n camera: lent.camera as THREE_NS.Camera,\n arsenal,\n groundAt: lent.groundAt,\n audio,\n tool: lent.tool,\n soundDistance: () => soundDistance,\n ...(options.condition ? { condition: options.condition } : {}),\n ...(options.seed === undefined ? {} : { seed: options.seed }),\n })\n fx = created\n const camera = lent.camera as THREE_NS.Camera\n const offBench = lent.bench?.onChange((change: BenchChange) => {\n if (change.kind === 'layer') {\n if (change.id === 'muzzle_flash') created.layers.muzzleFlash = change.on\n else if (change.id === 'casings') created.layers.casings = change.on\n else if (change.id === 'magazines') created.layers.magazines = change.on\n } else if (change.kind === 'control' && typeof change.value === 'string') {\n if (change.id === 'condition') {\n created.setCondition(change.value)\n lent.configureTool?.({ condition: change.value })\n } else if (change.id === 'ammo_quality') lent.configureTool?.({ ammo_quality: change.value })\n } else if (change.kind === 'control' && change.id === 'sound_distance' && typeof change.value === 'number') soundDistance = change.value\n else if (change.kind === 'control' && change.id === 'fuse_length' && typeof change.value === 'number') lent.configureTool?.({ fuse_length: String(change.value) })\n })\n const offEvents = lent.on((event) => {\n if (event.type === 'explosion') {\n const away = Math.hypot(event.point[0] - camera.position.x, event.point[1] - camera.position.y, event.point[2] - camera.position.z)\n audio?.play('explosion', Math.min(1, EXPLOSION_VOLUME_BASE + event.radius * EXPLOSION_VOLUME_PER_METRE), away)\n return\n }\n const tool = lent.tool()\n created.handle(event, tool)\n if (event.type === 'reload') lent.log(fill(event.phase === 'start' ? text.reloadStart : text.reloadEnd, { weapon: arsenal.name(event.weapon), ammo: tool.ammo, capacity: tool.capacity }), { weapon: event.weapon, phase: event.phase })\n })\n const offFrame = lent.onFrame((dt) => created.update(dt))\n created.handle({ type: 'tool', weapon: lent.tool().weapon }, lent.tool())\n return () => {\n offBench?.()\n offEvents()\n offFrame()\n created.dispose()\n audio?.dispose()\n fx = null\n host = null\n }\n },\n }\n}\n"],"mappings":"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CF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;QACA;MACF;IA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Z,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,SAAW;MACX,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,SAAW;MACX,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,SAAW;MACX,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,KAAO;MACP,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,WAAa;QACX,cAAgB;QAChB,eAAiB;QACjB,YAAc;QACd,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,SAAW;QACT;MACF;IACF;IACA;MACE,IAAM;MACN,OAAS;MACT,UAAY;MACZ,aAAe;MACf,aAAe;MACf,aAAe;MACf,MAAQ;MACR,OAAS;MACT,SAAW;QACT;MACF;IACF;EACF;AC/lBA,MAAA,qBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;MACR,UAAY;QACV;MACF;MACA,MAAQ;MACR,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;MACR,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,MAAQ;QACR,WAAa;UACX;UACA;QACF;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,YAAc;MACd,UAAY;MACZ,eAAiB;MACjB,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,MAAQ;MACR,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,MAAQ;QACN,cAAgB;QAChB,QAAU;MACZ;MACA,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,UAAY;QACV,QAAU;QACV,UAAY;QACZ,QAAU;MACZ;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,WAAa;QACX;QACA;MACF;MACA,aAAe;MACf,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,UAAY;QACV;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,MAAQ;QACR,WAAa;UACX;UACA;QACF;MACF;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;UACN;UACA;QACF;QACA,MAAQ;UACN;UACA;QACF;QACA,WAAa;QACb,oBAAsB;MACxB;MACA,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,MAAQ;QACR,WAAa;MACf;MACA,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,MAAQ;MACR,cAAgB;MAChB,cAAgB;MAChB,QAAU;MACV,kBAAoB;MACpB,OAAS;MACT,MAAQ;QACN,aAAe;QACf,QAAU;QACV,SAAW;MACb;MACA,UAAY;QACV;QACA;MACF;MACA,OAAS;QACP,MAAQ;QACR,WAAa;MACf;MACA,SAAW;QACT;QACA;MACF;IACF;EACF;ACvZA,MAAA,4BAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;QACA;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,WAAa;QACb,QAAU;QACV,QAAU;QACV,MAAQ;QACR,YAAc;QACd,OAAS;MACX;MACA,MAAQ;MACR,MAAQ;QACN;QACA;MACF;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;EACF;ACpGA,MAAA,mBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,KAAO;QACP,iBAAmB;UACjB;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,SAAW;QACX,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,SAAW;QACX,OAAS;QACT,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,WAAa;MACf;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,OAAS;QACT,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;UACA;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;QACb,iBAAmB;MACrB;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,aAAe;UACf,OAAS;QACX;QACA,aAAe;MACjB;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,aAAe;MACjB;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,iBAAmB;UACjB;QACF;QACA,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;QACP,iBAAmB;UACjB;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,aAAe;QACf,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,aAAe;QACf,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,OAAS;MACT,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,SAAW;QACX,KAAO;QACP,OAAS;UACP;QACF;QACA,UAAY;QACZ,QAAU;QACV,UAAY;QACZ,WAAa;QACb,UAAY;QACZ,iBAAmB;QACnB,QAAU;UACR;UACA;QACF;QACA,OAAS;QACT,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,UAAY;UACZ,OAAS;UACT,OAAS;QACX;QACA,KAAO;MACT;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;EACF;ACtwGA,MAAA,oBAAA;IACE;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,YAAc;QACd,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;UACV,OAAS;QACX;QACA,QAAU;QACV,YAAc;QACd,OAAS;QACT,gBAAkB;QAClB,WAAa;QACb,uBAAyB;QACzB,QAAU;UACR;UACA;QACF;MACF;MACA,MAAQ;MACR,YAAc;QACZ,QAAU;QACV,QAAU;QACV,WAAa;MACf;MACA,WAAa;MACb,SAAW;QACT;QACA;QACA;MACF;IACF;IACA;MACE,IAAM;MACN,MAAQ;MACR,UAAY;MACZ,QAAU;QACR,MAAQ;QACR,YAAc;QACd,UAAY;QACZ,QAAU;QACV,SAAW;UACT,MAAQ;UACR,QAAU;U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","names":["result","length","explosive","EPS","stage","distance","spread","distance","scope","metal","distance","sound","box","length","box","PI","length","box","box","box","PI","round","box","box","round","box","box","PI","slide","metal","box","PI","box","slide","PI","box","metal","box","PI","box","box","length","box","PI","box","length","box","box","length","caliberOf","round","length","PI","PI","distance","PI","round","PI","HAND_OFFSET","distance","length","box","SHAPES","length"]}